From b26ee8d4543a94f3d65ecc35333f36b5e5d30782 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:15:51 -0600 Subject: [PATCH 01/24] Remove py_env_lib entity, environment, grid, and location classes --- entity.py | 92 -------------------------------------- environment.py | 66 --------------------------- grid.py | 119 ------------------------------------------------- location.py | 49 -------------------- 4 files changed, 326 deletions(-) delete mode 100644 entity.py delete mode 100644 environment.py delete mode 100644 grid.py delete mode 100644 location.py diff --git a/entity.py b/entity.py deleted file mode 100644 index 4f2c81d..0000000 --- a/entity.py +++ /dev/null @@ -1,92 +0,0 @@ -# Copyright (c) 2022 Preponderous Software -# MIT License -import datetime -import uuid - - -# @author Daniel McCoy Stephenson -# @since July 1st, 2022 -class Entity(object): - - def __init__(self, name, energy, living, edibleEntityTypes): - self.id = uuid.uuid4() - self.name = name - self.energy = energy - self.living = living - self.edibleEntityTypes = edibleEntityTypes - self.targetEnergy = energy - self.creationDate = datetime.datetime.now() - self.environmentID = -1 - self.gridID = -1 - self.locationID = -1 - - def getID(self): - return self.id - - def getName(self): - return self.name - - def getEnvironmentID(self): - return self.environmentID - - def getCreationDate(self): - return self.creationDate - - def getEnvironmentID(self): - return self.environmentID - - def getGridID(self): - return self.gridID - - def getLocationID(self): - return self.locationID - - def setID(self, id): - self.id = id - - def setName(self, name): - self.name = name - - def setEnvironmentID(self, environmentID): - self.environmentID = environmentID - - def setCreationDate(self, creationDate): - self.creationDate = creationDate - - def setGridID(self, gridID): - self.gridID = gridID - - def setLocationID(self, locationID): - self.locationID = locationID - - def printInfo(self): - print("--------------") - print(self.name) - print("--------------") - print("ID: ", self.getID()) - print("Creation Date: ", self.getCreationDate()) - print("Environment ID: ", self.getEnvironmentID()) - print("Grid ID: ", self.getGridID()) - print("Location ID: ", self.getLocationID()) - print("\n") - - def getEnergy(self): - return self.energy - - def addEnergy(self, amount): - self.energy += amount - - def removeEnergy(self, amount): - self.energy -= amount - - def needsEnergy(self): - return self.energy < self.targetEnergy - - def canEat(self, entity): - for entityType in self.edibleEntityTypes: - if type(entity) is entityType: - return True - return False - - def isLiving(self): - return self.living \ No newline at end of file diff --git a/environment.py b/environment.py deleted file mode 100644 index cfd4920..0000000 --- a/environment.py +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright (c) 2022 Preponderous Software -# MIT License -import datetime -import uuid -from entity import Entity -from grid import Grid - - -# @author Daniel McCoy Stephenson -# @since July 1st, 2022 -class Environment(object): - - def __init__(self, name, size): - self.id = uuid.uuid4() - self.name = name - self.grid = Grid(size, size) - self.creationDate = datetime.datetime.now() - - def getID(self): - return self.id - - def getName(self): - return self.name - - def getCreationDate(self): - return self.creationDate - - def getGrid(self): - return self.grid - - def setID(self, id): - self.id = id - - def setName(self, name): - self.name = name - - def setGrid(self, grid): - self.grid = grid - - def addEntity(self, entity: Entity): - entity.setEnvironmentID(self.getID()) - self.grid.addEntity(entity) - - def addEntityToLocation(self, entity: Entity, location): - entity.setEnvironmentID(self.getID()) - self.grid.addEntityToLocation(entity, location) - - def removeEntity(self, entity: Entity): - self.grid.removeEntity(entity) - - def isEntityPresent(self, entity: Entity): - return self.grid.isEntityPresent(entity) - - def getNumEntities(self): - return self.getGrid().getNumEntities() - - def printInfo(self): - print("--------------") - print(self.name) - print("--------------") - print("Num entities: ", self.getNumEntities()) - print("Num locations: ", self.getGrid().getSize()) - print("Creation Date: ", self.getCreationDate()) - print("ID: ", self.getID()) - print("Grid ID: ", self.getGrid().getID()) - print("\n") \ No newline at end of file diff --git a/grid.py b/grid.py deleted file mode 100644 index efa5bc4..0000000 --- a/grid.py +++ /dev/null @@ -1,119 +0,0 @@ -# Copyright (c) 2022 Preponderous Software -# MIT License - - -# @author Daniel McCoy Stephenson -# @since July 1st, 2022 -import random -import uuid - -from entity import Entity -from location import Location - - -class Grid(object): - - def __init__(self, columns, rows): - self.id = uuid.uuid4() - self.columns = columns - self.rows = rows - self.locations = [] - self.generateLocations() - - def getID(self): - return self.id - - def getColumns(self): - return self.columns - - def getRows(self): - return self.rows - - def getLocations(self): - return self.locations - - def getFirstLocation(self): - return self.locations[0] - - def getSize(self): - return len(self.locations) - - def getLocations(self): - return self.locations - - def getNumEntities(self): - count = 0 - for location in self.locations: - count += location.getNumEntities() - return count - - def setID(self, id): - self.id = id - - def setColumns(self, columns): - self.columns = columns - - def setRows(self, rows): - self.rows = rows - - def setLocations(self, locations): - self.locations = locations - - def addLocation(self, location: Location): - self.locationss.append(location) - - def removeLocation(self, location: Location): - self.locations.remove(location) - - def addEntity(self, entity: Entity): - entity.setGridID(self.getID()) - self.getRandomLocation().addEntity(entity) - - def addEntityToLocation(self, entity: Entity, location): - entity.setGridID(self.getID) - self.getLocation(location.getID()).addEntity(entity) - - def removeEntity(self, entity: Entity): - for location in self.grid.getLocations(): - if location.isEntityPresent(entity): - location.removeEntity(entity) - return - - def isEntityPresent(self, entity: Entity): - for location in self.grid.getLocations(): - if location.isEntityPresent(entity): - return True - - def generateLocations(self): - for x in range(self.getColumns()): - for y in range(self.getRows()): - location = Location(x, y) - self.locations.append(location) - - def getLocation(self, id): - for location in self.locations: - if location.getID() == id: - return location - return -1 - - def getRandomLocation(self): - index = random.randrange(0, len(self.locations)) - return self.locations[index] - - def getLocationByCoordinates(self, x, y): - for location in self.locations: - if location.getX() == x and location.getY() == y: - return location - return -1 - - def getUp(self, location: Location): - return self.getLocationByCoordinates(location.getX(), location.getY() - 1) - - def getRight(self, location: Location): - return self.getLocationByCoordinates(location.getX() + 1, location.getY()) - - def getDown(self, location: Location): - return self.getLocationByCoordinates(location.getX(), location.getY() + 1) - - def getLeft(self, location: Location): - return self.getLocationByCoordinates(location.getX() - 1, location.getY()) diff --git a/location.py b/location.py deleted file mode 100644 index c9544fc..0000000 --- a/location.py +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (c) 2022 Preponderous Software -# MIT License - - -# @author Daniel McCoy Stephenson -# @since July 1st, 2022 -import uuid - -from entity import Entity - - -class Location(object): - - def __init__(self, x, y): - self.id = uuid.uuid4() - self.x = x - self.y = y - self.entities = [] - - def getID(self): - return self.id - - def getX(self): - return self.x - - def getY(self): - return self.y - - def getNumEntities(self): - return len(self.entities) - - def addEntity(self, entity: Entity): - if not self.isEntityPresent(entity): - self.entities.append(entity) - entity.setLocationID(self.getID()) - else: - print("Warning: An entity was already present when attempting to add it to a location.") - - def removeEntity(self, entity: Entity): - if self.isEntityPresent(entity): - self.entities.remove(entity) - else: - print("Warning: An entity was not present when attempting to remove it from a location.") - - def isEntityPresent(self, entity: Entity): - return entity in self.entities - - def getEntities(self): - return self.entities \ No newline at end of file From be548cdefcec818b1ff4340582d3adfbafdaac98 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:17:30 -0600 Subject: [PATCH 02/24] Add Viron classes - Location, Grid, Entity, Environment, and their respective services --- entity.py | 38 +++++++++++++ entityService.py | 114 +++++++++++++++++++++++++++++++++++++++ environment.py | 38 +++++++++++++ environmentService.py | 45 ++++++++++++++++ grid.py | 29 ++++++++++ gridService.py | 106 +++++++++++++++++++++++++++++++++++++ location.py | 29 ++++++++++ locationService.py | 120 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 519 insertions(+) create mode 100644 entity.py create mode 100644 entityService.py create mode 100644 environment.py create mode 100644 environmentService.py create mode 100644 grid.py create mode 100644 gridService.py create mode 100644 location.py create mode 100644 locationService.py diff --git a/entity.py b/entity.py new file mode 100644 index 0000000..682a836 --- /dev/null +++ b/entity.py @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Preponderous Software +# MIT License + +import re + + +class Entity: + def __init__(self, entityId: int, name: str, creationDate: str): + self.setEntityId(entityId) + self.setName(name) + self.setCreationDate(creationDate) + + def getEntityId(self) -> int: + return self.entityId + + def setEntityId(self, entityId: int): + if not isinstance(entityId, int): + raise TypeError("entityId must be an integer") + self.entityId = entityId + + def getName(self) -> str: + return self.name + + def setName(self, name: str): + if not isinstance(name, str): + raise TypeError("name must be a string") + self.name = name + + def getCreationDate(self) -> str: + return self.creationDate + + def setCreationDate(self, creationDate: str): + if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): + raise ValueError("creationDate must be in the format YYYY-MM-DD") + self.creationDate = creationDate + + def __str__(self): + return f"Entity{{entityId={self.entityId}, name={self.name}, creationDate={self.creationDate}}}" diff --git a/entityService.py b/entityService.py new file mode 100644 index 0000000..1be5d2a --- /dev/null +++ b/entityService.py @@ -0,0 +1,114 @@ +import logging +from typing import List, Optional +import requests + +from src.main.python.preponderous.viron.models.entity import Entity + +logger = logging.getLogger(__name__) + + +class EntityServiceException(Exception): + def __init__(self, message: str, cause: Exception = None): + super().__init__(message) + self.cause = cause + + +class EntityService: + def __init__(self, viron_host: str, viron_port: int): + """Initialize EntityService with host and port""" + self.viron_host = viron_host + self.viron_port = viron_port + + def get_base_url(self) -> str: + """Get the base URL for the API""" + return f"{self.viron_host}:{self.viron_port}/api/v1/entities" + + def get_all_entities(self) -> List[Entity]: + try: + response = requests.get(self.get_base_url()) + response.raise_for_status() + data = response.json() + return [Entity(**entity) for entity in data] if data else [] + except Exception as e: + logger.error(f"Failed to fetch all entities: {str(e)}") + raise EntityServiceException("Error retrieving entities", e) + + def get_entity_by_id(self, entity_id: int) -> Optional[Entity]: + try: + response = requests.get(f"{self.get_base_url()}/{entity_id}") + response.raise_for_status() + data = response.json() + return Entity(**data) if data else None + except Exception as e: + logger.error(f"Failed to fetch entity with id {entity_id}: {str(e)}") + raise EntityServiceException("Error retrieving entity", e) + + def get_entities_in_environment(self, environment_id: int) -> List[Entity]: + try: + response = requests.get(f"{self.get_base_url()}/environment/{environment_id}") + response.raise_for_status() + data = response.json() + return [Entity(**entity) for entity in data] if data else [] + except Exception as e: + logger.error(f"Failed to fetch entities in environment {environment_id}: {str(e)}") + raise EntityServiceException("Error retrieving entities in environment", e) + + def get_entities_in_grid(self, grid_id: int) -> List[Entity]: + try: + response = requests.get(f"{self.get_base_url()}/grid/{grid_id}") + response.raise_for_status() + data = response.json() + return [Entity(**entity) for entity in data] if data else [] + except Exception as e: + logger.error(f"Failed to fetch entities in grid {grid_id}: {str(e)}") + raise EntityServiceException("Error retrieving entities in grid", e) + + def get_entities_in_location(self, location_id: int) -> List[Entity]: + try: + response = requests.get(f"{self.get_base_url()}/location/{location_id}") + response.raise_for_status() + data = response.json() + return [Entity(**entity) for entity in data] if data else [] + except Exception as e: + logger.error(f"Failed to fetch entities in location {location_id}: {str(e)}") + raise EntityServiceException("Error retrieving entities in location", e) + + def get_entities_not_in_any_location(self) -> List[Entity]: + try: + response = requests.get(f"{self.get_base_url()}/unassigned") + response.raise_for_status() + data = response.json() + return [Entity(**entity) for entity in data] if data else [] + except Exception as e: + logger.error(f"Failed to fetch unassigned entities: {str(e)}") + raise EntityServiceException("Error retrieving unassigned entities", e) + + def create_entity(self, name: str) -> Entity: + try: + response = requests.post(f"{self.get_base_url()}/{name}") + response.raise_for_status() + data = response.json() + if not data: + raise EntityServiceException("Created entity response was null") + return Entity(**data) + except Exception as e: + logger.error(f"Failed to create entity with name {name}: {str(e)}") + raise EntityServiceException("Error creating entity", e) + + def delete_entity(self, entity_id: int) -> bool: + try: + response = requests.delete(f"{self.get_base_url()}/{entity_id}") + response.raise_for_status() + return True + except Exception as e: + logger.error(f"Failed to delete entity {entity_id}: {str(e)}") + raise EntityServiceException("Error deleting entity", e) + + def update_entity_name(self, entity_id: int, name: str) -> bool: + try: + response = requests.patch(f"{self.get_base_url()}/{entity_id}/name/{name}") + response.raise_for_status() + return True + except Exception as e: + logger.error(f"Failed to update name for entity {entity_id}: {str(e)}") + raise EntityServiceException("Error updating entity name", e) diff --git a/environment.py b/environment.py new file mode 100644 index 0000000..42a62cb --- /dev/null +++ b/environment.py @@ -0,0 +1,38 @@ +# Copyright (c) 2024 Preponderous Software +# MIT License + +import re + + +class Environment: + def __init__(self, environmentId: int, name: str, creationDate: str): + self.setEnvironmentId(environmentId) + self.setName(name) + self.setCreationDate(creationDate) + + def getEnvironmentId(self) -> int: + return self.environmentId + + def setEnvironmentId(self, environmentId: int): + if not isinstance(environmentId, int): + raise TypeError("environmentId must be an integer") + self.environmentId = environmentId + + def getName(self) -> str: + return self.name + + def setName(self, name: str): + if not isinstance(name, str): + raise TypeError("name must be a string") + self.name = name + + def getCreationDate(self) -> str: + return self.creationDate + + def setCreationDate(self, creationDate: str): + if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): + raise ValueError("creationDate must be in the format YYYY-MM-DD") + self.creationDate = creationDate + + def __str__(self): + return f"Environment{{environmentId={self.environmentId}, name={self.name}, creationDate={self.creationDate}}}" \ No newline at end of file diff --git a/environmentService.py b/environmentService.py new file mode 100644 index 0000000..ab449c9 --- /dev/null +++ b/environmentService.py @@ -0,0 +1,45 @@ + +# Copyright (c) 2024 Preponderous Software +# MIT License + +import requests +from src.main.python.preponderous.viron.models.environment import Environment + +class EnvironmentService: + def __init__(self, base_url): + self.base_url = f"{base_url}/api/v1/environments" + + def get_all_environments(self) -> list[Environment]: + response = requests.get(f"{self.base_url}") + response.raise_for_status() + return [Environment(**env) for env in response.json()] + + def get_environment_by_id(self, environment_id: int) -> Environment: + response = requests.get(f"{self.base_url}/{environment_id}") + response.raise_for_status() + return Environment(**response.json()) + + def get_environment_by_name(self, name: str) -> Environment: + response = requests.get(f"{self.base_url}/name/{name}") + response.raise_for_status() + return Environment(**response.json()) + + def get_environment_of_entity(self, entity_id: int) -> Environment: + response = requests.get(f"{self.base_url}/entity/{entity_id}") + response.raise_for_status() + return Environment(**response.json()) + + def create_environment(self, name: str, num_grids: int, grid_size: int) -> Environment: + response = requests.post(f"{self.base_url}/{name}/{num_grids}/{grid_size}") + response.raise_for_status() + return Environment(**response.json()) + + def delete_environment(self, environment_id: int) -> bool: + response = requests.delete(f"{self.base_url}/{environment_id}") + response.raise_for_status() + return response.status_code == 200 + + def update_environment_name(self, environment_id: int, name: str) -> bool: + response = requests.patch(f"{self.base_url}/{environment_id}/name/{name}") + response.raise_for_status() + return response.status_code == 200 \ No newline at end of file diff --git a/grid.py b/grid.py new file mode 100644 index 0000000..36a9cd6 --- /dev/null +++ b/grid.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Preponderous Software +# MIT License + +class Grid: + def __init__(self, grid_id: int, rows: int, columns: int): + self.grid_id = grid_id + self.rows = rows + self.columns = columns + + def get_grid_id(self) -> int: + return self.grid_id + + def set_grid_id(self, grid_id: int): + self.grid_id = grid_id + + def get_rows(self) -> int: + return self.rows + + def set_rows(self, rows: int): + self.rows = rows + + def get_columns(self) -> int: + return self.columns + + def set_columns(self, columns: int): + self.columns = columns + + def __str__(self) -> str: + return f"Grid{{grid_id={self.grid_id}, rows={self.rows}, columns={self.columns}}}" \ No newline at end of file diff --git a/gridService.py b/gridService.py new file mode 100644 index 0000000..7a585bb --- /dev/null +++ b/gridService.py @@ -0,0 +1,106 @@ +# Copyright (c) 2024 Preponderous Software +# MIT License + +import logging +from typing import List, Optional +import requests +from requests.exceptions import HTTPError +from src.main.python.preponderous.viron.models.grid import Grid + +logger = logging.getLogger(__name__) + +class GridService: + def __init__(self, base_url: str): + """Initialize GridService with base URL. + + Args: + base_url (str): Base URL of the service + """ + self.base_url = f"{base_url}/api/v1/grids" + + def get_all_grids(self) -> List[Grid]: + """Get all grids. + + Returns: + List[Grid]: List of all grids + + Raises: + RuntimeError: If there is an error fetching the grids + """ + try: + response = requests.get(self.base_url) + response.raise_for_status() + return [Grid(**grid) for grid in response.json()] + except Exception as e: + logger.error(f"Error getting all grids: {str(e)}") + raise RuntimeError("Failed to fetch all grids") from e + + def get_grid_by_id(self, grid_id: int) -> Optional[Grid]: + """Get grid by ID. + + Args: + grid_id (int): ID of the grid to fetch + + Returns: + Optional[Grid]: Grid if found, None if not found + + Raises: + RuntimeError: If there is an error fetching the grid + """ + try: + response = requests.get(f"{self.base_url}/{grid_id}") + response.raise_for_status() + return Grid(**response.json()) + except HTTPError as e: + if e.response.status_code == 404: + return None + logger.error(f"Error getting grid by id {grid_id}: {str(e)}") + raise RuntimeError(f"Failed to fetch grid by id: {grid_id}") from e + except Exception as e: + logger.error(f"Error getting grid by id {grid_id}: {str(e)}") + raise RuntimeError(f"Failed to fetch grid by id: {grid_id}") from e + + def get_grids_in_environment(self, environment_id: int) -> List[Grid]: + """Get all grids in an environment. + + Args: + environment_id (int): ID of the environment + + Returns: + List[Grid]: List of grids in the environment + + Raises: + RuntimeError: If there is an error fetching the grids + """ + try: + response = requests.get(f"{self.base_url}/environment/{environment_id}") + response.raise_for_status() + return [Grid(**grid) for grid in response.json()] + except Exception as e: + logger.error(f"Error getting grids in environment {environment_id}: {str(e)}") + raise RuntimeError(f"Failed to fetch grids in environment: {environment_id}") from e + + def get_grid_of_entity(self, entity_id: int) -> Optional[Grid]: + """Get grid of an entity. + + Args: + entity_id (int): ID of the entity + + Returns: + Optional[Grid]: Grid if found, None if not found + + Raises: + RuntimeError: If there is an error fetching the grid + """ + try: + response = requests.get(f"{self.base_url}/entity/{entity_id}") + response.raise_for_status() + return Grid(**response.json()) + except HTTPError as e: + if e.response.status_code == 404: + return None + logger.error(f"Error getting grid for entity {entity_id}: {str(e)}") + raise RuntimeError(f"Failed to fetch grid for entity: {entity_id}") from e + except Exception as e: + logger.error(f"Error getting grid for entity {entity_id}: {str(e)}") + raise RuntimeError(f"Failed to fetch grid for entity: {entity_id}") from e \ No newline at end of file diff --git a/location.py b/location.py new file mode 100644 index 0000000..9d6fd53 --- /dev/null +++ b/location.py @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Preponderous Software +# MIT License + +class Location: + def __init__(self, location_id: int, x: int, y: int): + self.location_id = location_id + self.x = x + self.y = y + + def get_location_id(self) -> int: + return self.location_id + + def set_location_id(self, location_id: int): + self.location_id = location_id + + def get_x(self) -> int: + return self.x + + def set_x(self, x: int): + self.x = x + + def get_y(self) -> int: + return self.y + + def set_y(self, y: int): + self.y = y + + def __str__(self) -> str: + return f"Location{{location_id={self.location_id}, x={self.x}, y={self.y}}}" \ No newline at end of file diff --git a/locationService.py b/locationService.py new file mode 100644 index 0000000..ee44b20 --- /dev/null +++ b/locationService.py @@ -0,0 +1,120 @@ +from typing import List, Optional +import logging +import requests +from dataclasses import dataclass + +# Exception classes +class NotFoundException(Exception): + pass + +class ServiceException(Exception): + def __init__(self, message: str, cause: Exception = None): + super().__init__(message) + self.cause = cause + +# Location model +@dataclass +class Location: + id: int + # Add other fields as needed + +# Service configuration +@dataclass +class ServiceConfig: + viron_host: str + viron_port: int + +# Location Service +class LocationService: + def __init__(self, service_config: ServiceConfig): + self.logger = logging.getLogger(__name__) + self.base_url = f"{service_config.viron_host}:{service_config.viron_port}/api/v1/locations" + + def get_all_locations(self) -> List[Location]: + try: + response = requests.get(self.base_url) + response.raise_for_status() + return response.json() + except Exception as e: + self.logger.error(f"Error getting locations: {str(e)}") + raise ServiceException("Error getting locations", e) + + def get_location_by_id(self, id: int) -> Location: + try: + response = requests.get(f"{self.base_url}/{id}") + if response.status_code == 404: + raise NotFoundException(f"Location not found with id: {id}") + response.raise_for_status() + return response.json() + except NotFoundException as e: + raise e + except Exception as e: + self.logger.error(f"Error getting location by id {id}: {str(e)}") + raise ServiceException(f"Error getting location by id: {id}", e) + + def get_locations_in_environment(self, environment_id: int) -> List[Location]: + try: + response = requests.get(f"{self.base_url}/environment/{environment_id}") + response.raise_for_status() + return response.json() + except Exception as e: + self.logger.error(f"Error getting locations in environment {environment_id}: {str(e)}") + raise ServiceException(f"Error getting locations in environment: {environment_id}", e) + + def get_locations_in_grid(self, grid_id: int) -> List[Location]: + try: + response = requests.get(f"{self.base_url}/grid/{grid_id}") + response.raise_for_status() + return response.json() + except Exception as e: + self.logger.error(f"Error getting locations in grid {grid_id}: {str(e)}") + raise ServiceException(f"Error getting locations in grid: {grid_id}", e) + + def get_location_of_entity(self, entity_id: int) -> Location: + try: + response = requests.get(f"{self.base_url}/entity/{entity_id}") + if response.status_code == 404: + raise NotFoundException(f"Location not found for entity: {entity_id}") + response.raise_for_status() + return response.json() + except NotFoundException as e: + raise e + except Exception as e: + self.logger.error(f"Error getting location of entity {entity_id}: {str(e)}") + raise ServiceException(f"Error getting location of entity: {entity_id}", e) + + def add_entity_to_location(self, entity_id: int, location_id: int) -> None: + try: + response = requests.put(f"{self.base_url}/{location_id}/entity/{entity_id}") + if response.status_code == 404: + raise NotFoundException("Location or entity not found") + response.raise_for_status() + except NotFoundException as e: + raise e + except Exception as e: + self.logger.error(f"Error adding entity {entity_id} to location {location_id}: {str(e)}") + raise ServiceException("Error adding entity to location", e) + + def remove_entity_from_location(self, entity_id: int, location_id: int) -> None: + try: + response = requests.delete(f"{self.base_url}/{location_id}/entity/{entity_id}") + if response.status_code == 404: + raise NotFoundException("Location or entity not found") + response.raise_for_status() + except NotFoundException as e: + raise e + except Exception as e: + self.logger.error(f"Error removing entity {entity_id} from location {location_id}: {str(e)}") + raise ServiceException("Error removing entity from location", e) + + def remove_entity_from_current_location(self, entity_id: int) -> None: + try: + response = requests.delete(f"{self.base_url}/entity/{entity_id}") + if response.status_code == 404: + raise NotFoundException("Entity not found") + response.raise_for_status() + except NotFoundException as e: + raise e + except Exception as e: + self.logger.error(f"Error removing entity {entity_id} from current location: {str(e)}") + raise ServiceException("Error removing entity from current location", e) \ No newline at end of file From 3a21df7b63731d43244fcabcc5861f7eb6e20912 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:25:56 -0600 Subject: [PATCH 03/24] Refactor import statements in service files to use direct module imports --- entityService.py | 2 +- environmentService.py | 2 +- gridService.py | 2 +- locationService.py | 7 +------ 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/entityService.py b/entityService.py index 1be5d2a..148a957 100644 --- a/entityService.py +++ b/entityService.py @@ -2,7 +2,7 @@ from typing import List, Optional import requests -from src.main.python.preponderous.viron.models.entity import Entity +from entity import Entity logger = logging.getLogger(__name__) diff --git a/environmentService.py b/environmentService.py index ab449c9..c1628c8 100644 --- a/environmentService.py +++ b/environmentService.py @@ -3,7 +3,7 @@ # MIT License import requests -from src.main.python.preponderous.viron.models.environment import Environment +from environment import Environment class EnvironmentService: def __init__(self, base_url): diff --git a/gridService.py b/gridService.py index 7a585bb..10419e9 100644 --- a/gridService.py +++ b/gridService.py @@ -5,7 +5,7 @@ from typing import List, Optional import requests from requests.exceptions import HTTPError -from src.main.python.preponderous.viron.models.grid import Grid +from grid import Grid logger = logging.getLogger(__name__) diff --git a/locationService.py b/locationService.py index ee44b20..890b560 100644 --- a/locationService.py +++ b/locationService.py @@ -2,6 +2,7 @@ import logging import requests from dataclasses import dataclass +from location import Location # Exception classes class NotFoundException(Exception): @@ -12,12 +13,6 @@ def __init__(self, message: str, cause: Exception = None): super().__init__(message) self.cause = cause -# Location model -@dataclass -class Location: - id: int - # Add other fields as needed - # Service configuration @dataclass class ServiceConfig: From 8287c94a36e5eb99cba59481b1d317af0056fdb6 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:47:03 -0600 Subject: [PATCH 04/24] Add Viron submodule for project integration --- .gitmodules | 3 +++ Viron | 1 + 2 files changed, 4 insertions(+) create mode 100644 .gitmodules create mode 160000 Viron diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..a3c0b4a --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "Viron"] + path = Viron + url = https://www.github.com/Preponderous-Software/Viron diff --git a/Viron b/Viron new file mode 160000 index 0000000..de391ce --- /dev/null +++ b/Viron @@ -0,0 +1 @@ +Subproject commit de391ce706324deea97d109a97054bc580c5d990 From 74e9e89f49493e14ff95924b5f65ac2de11264c5 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:47:09 -0600 Subject: [PATCH 05/24] Comment out validation for creationDate format in Environment class --- environment.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/environment.py b/environment.py index 42a62cb..5a248c1 100644 --- a/environment.py +++ b/environment.py @@ -30,8 +30,8 @@ def getCreationDate(self) -> str: return self.creationDate def setCreationDate(self, creationDate: str): - if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): - raise ValueError("creationDate must be in the format YYYY-MM-DD") + # if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): + # raise ValueError("creationDate must be in the format YYYY-MM-DD") self.creationDate = creationDate def __str__(self): From 5b1bc3e22e641dd5a042c330bdd2910d7cba43de Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:47:24 -0600 Subject: [PATCH 06/24] Integrate location and environment services, update drawEnvironment function, and adjust grid size --- main.py | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index f716caf..a4c0be2 100644 --- a/main.py +++ b/main.py @@ -2,7 +2,11 @@ import random import pygame from environment import Environment +from environmentService import EnvironmentService from graphik import Graphik +from locationService import ServiceConfig +from locationService import LocationService +from location import Location black = (0,0,0) @@ -11,25 +15,41 @@ displayWidth = 600 displayHeight = 600 -gridSize = 50 +gridSize = 10 -def drawEnvironment(environment, graphik, locationWidth, locationHeight): - for location in environment.getGrid().getLocations(): +url = "http://localhost" +port = 9999 + +locationServiceConfig = ServiceConfig(viron_host=url, viron_port=port) +locationService = LocationService(locationServiceConfig) + +environmentServiceBaseUrl = f"{url}:{port}" +environmentService = EnvironmentService(environmentServiceBaseUrl) + +def log(message): + print(message) + +def drawEnvironment(locations, graphik, locationWidth, locationHeight): + for location in locations: + location = Location(location_id=location['locationId'], x=location['x'], y=location['y']) red = random.randrange(50, 200) green = random.randrange(50, 200) blue = random.randrange(50, 200) - graphik.drawRectangle(location.getX() * locationWidth, location.getY() * locationHeight, locationWidth, locationHeight, (red,green,blue)) + graphik.drawRectangle(location.get_x() * locationWidth, location.get_y() * locationHeight, locationWidth, locationHeight, (red,green,blue)) def main(): pygame.init() gameDisplay = pygame.display.set_mode((displayWidth, displayHeight)) graphik = Graphik(gameDisplay) pygame.display.set_caption("Visualizing Environment With Random Colors") + + log("Creating environment...") + environment = environmentService.create_environment("Test", gridSize, gridSize) - environment = Environment("Test", gridSize) - - locationWidth = displayWidth/environment.getGrid().getRows() - locationHeight = displayHeight/environment.getGrid().getColumns() + locationWidth = displayWidth/gridSize + locationHeight = displayHeight/gridSize + + locationsCache = {} running = True @@ -38,9 +58,13 @@ def main(): if event.type == pygame.QUIT: pygame.quit() quit() + + if locationsCache == {}: + log("Fetching locations from service...") + locationsCache = locationService.get_locations_in_environment(environment.getEnvironmentId()) gameDisplay.fill(white) - drawEnvironment(environment, graphik, locationWidth, locationHeight) + drawEnvironment(locationsCache, graphik, locationWidth, locationHeight) pygame.display.update() main() \ No newline at end of file From 5c4d7cebfa1988d402b785641232475fffe2cb39 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:50:52 -0600 Subject: [PATCH 07/24] Specify num grids and modify environment creation log message --- main.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index a4c0be2..fdc43f3 100644 --- a/main.py +++ b/main.py @@ -15,7 +15,8 @@ displayWidth = 600 displayHeight = 600 -gridSize = 10 +numGrids = 1 +gridSize = 20 url = "http://localhost" port = 9999 @@ -43,8 +44,8 @@ def main(): graphik = Graphik(gameDisplay) pygame.display.set_caption("Visualizing Environment With Random Colors") - log("Creating environment...") - environment = environmentService.create_environment("Test", gridSize, gridSize) + log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) + environment = environmentService.create_environment("Test", numGrids, gridSize) locationWidth = displayWidth/gridSize locationHeight = displayHeight/gridSize From 82b707da11969cbb1559b373ba121c22f5b488ab Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 10:52:15 -0600 Subject: [PATCH 08/24] Increase grid size from 20 to 50 --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index fdc43f3..839f070 100644 --- a/main.py +++ b/main.py @@ -16,7 +16,7 @@ displayHeight = 600 numGrids = 1 -gridSize = 20 +gridSize = 50 url = "http://localhost" port = 9999 From 5dcd478c4a24f1dfbf5cc4593fae698f669e3fea Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:23:33 -0600 Subject: [PATCH 09/24] Refactor project structure: remove model & service classes and update imports in main.py --- Viron | 2 +- __init__.py | 15 ++++++ entity.py | 38 -------------- entityService.py | 114 ----------------------------------------- environment.py | 38 -------------- environmentService.py | 45 ----------------- grid.py | 29 ----------- gridService.py | 106 -------------------------------------- location.py | 29 ----------- locationService.py | 115 ------------------------------------------ main.py | 15 ++---- 11 files changed, 21 insertions(+), 525 deletions(-) create mode 100644 __init__.py delete mode 100644 entity.py delete mode 100644 entityService.py delete mode 100644 environment.py delete mode 100644 environmentService.py delete mode 100644 grid.py delete mode 100644 gridService.py delete mode 100644 location.py delete mode 100644 locationService.py diff --git a/Viron b/Viron index de391ce..25214aa 160000 --- a/Viron +++ b/Viron @@ -1 +1 @@ -Subproject commit de391ce706324deea97d109a97054bc580c5d990 +Subproject commit 25214aa37a0d34383c296d6ae35f6401a13969d0 diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..92f6afc --- /dev/null +++ b/__init__.py @@ -0,0 +1,15 @@ +import os +import importlib + +package_dir = os.path.dirname(__file__) + +for root, dirs, files in os.walk(package_dir): + for file in files: + if file.endswith('.py') and file != '__init__.py': + rel_dir = os.path.relpath(root, package_dir) + module_name = file[:-3] + if rel_dir == '.': + import_path = f".{module_name}" + else: + import_path = "." + ".".join(rel_dir.split(os.sep)) + f".{module_name}" + importlib.import_module(import_path, package=__package__) \ No newline at end of file diff --git a/entity.py b/entity.py deleted file mode 100644 index 682a836..0000000 --- a/entity.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2024 Preponderous Software -# MIT License - -import re - - -class Entity: - def __init__(self, entityId: int, name: str, creationDate: str): - self.setEntityId(entityId) - self.setName(name) - self.setCreationDate(creationDate) - - def getEntityId(self) -> int: - return self.entityId - - def setEntityId(self, entityId: int): - if not isinstance(entityId, int): - raise TypeError("entityId must be an integer") - self.entityId = entityId - - def getName(self) -> str: - return self.name - - def setName(self, name: str): - if not isinstance(name, str): - raise TypeError("name must be a string") - self.name = name - - def getCreationDate(self) -> str: - return self.creationDate - - def setCreationDate(self, creationDate: str): - if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): - raise ValueError("creationDate must be in the format YYYY-MM-DD") - self.creationDate = creationDate - - def __str__(self): - return f"Entity{{entityId={self.entityId}, name={self.name}, creationDate={self.creationDate}}}" diff --git a/entityService.py b/entityService.py deleted file mode 100644 index 148a957..0000000 --- a/entityService.py +++ /dev/null @@ -1,114 +0,0 @@ -import logging -from typing import List, Optional -import requests - -from entity import Entity - -logger = logging.getLogger(__name__) - - -class EntityServiceException(Exception): - def __init__(self, message: str, cause: Exception = None): - super().__init__(message) - self.cause = cause - - -class EntityService: - def __init__(self, viron_host: str, viron_port: int): - """Initialize EntityService with host and port""" - self.viron_host = viron_host - self.viron_port = viron_port - - def get_base_url(self) -> str: - """Get the base URL for the API""" - return f"{self.viron_host}:{self.viron_port}/api/v1/entities" - - def get_all_entities(self) -> List[Entity]: - try: - response = requests.get(self.get_base_url()) - response.raise_for_status() - data = response.json() - return [Entity(**entity) for entity in data] if data else [] - except Exception as e: - logger.error(f"Failed to fetch all entities: {str(e)}") - raise EntityServiceException("Error retrieving entities", e) - - def get_entity_by_id(self, entity_id: int) -> Optional[Entity]: - try: - response = requests.get(f"{self.get_base_url()}/{entity_id}") - response.raise_for_status() - data = response.json() - return Entity(**data) if data else None - except Exception as e: - logger.error(f"Failed to fetch entity with id {entity_id}: {str(e)}") - raise EntityServiceException("Error retrieving entity", e) - - def get_entities_in_environment(self, environment_id: int) -> List[Entity]: - try: - response = requests.get(f"{self.get_base_url()}/environment/{environment_id}") - response.raise_for_status() - data = response.json() - return [Entity(**entity) for entity in data] if data else [] - except Exception as e: - logger.error(f"Failed to fetch entities in environment {environment_id}: {str(e)}") - raise EntityServiceException("Error retrieving entities in environment", e) - - def get_entities_in_grid(self, grid_id: int) -> List[Entity]: - try: - response = requests.get(f"{self.get_base_url()}/grid/{grid_id}") - response.raise_for_status() - data = response.json() - return [Entity(**entity) for entity in data] if data else [] - except Exception as e: - logger.error(f"Failed to fetch entities in grid {grid_id}: {str(e)}") - raise EntityServiceException("Error retrieving entities in grid", e) - - def get_entities_in_location(self, location_id: int) -> List[Entity]: - try: - response = requests.get(f"{self.get_base_url()}/location/{location_id}") - response.raise_for_status() - data = response.json() - return [Entity(**entity) for entity in data] if data else [] - except Exception as e: - logger.error(f"Failed to fetch entities in location {location_id}: {str(e)}") - raise EntityServiceException("Error retrieving entities in location", e) - - def get_entities_not_in_any_location(self) -> List[Entity]: - try: - response = requests.get(f"{self.get_base_url()}/unassigned") - response.raise_for_status() - data = response.json() - return [Entity(**entity) for entity in data] if data else [] - except Exception as e: - logger.error(f"Failed to fetch unassigned entities: {str(e)}") - raise EntityServiceException("Error retrieving unassigned entities", e) - - def create_entity(self, name: str) -> Entity: - try: - response = requests.post(f"{self.get_base_url()}/{name}") - response.raise_for_status() - data = response.json() - if not data: - raise EntityServiceException("Created entity response was null") - return Entity(**data) - except Exception as e: - logger.error(f"Failed to create entity with name {name}: {str(e)}") - raise EntityServiceException("Error creating entity", e) - - def delete_entity(self, entity_id: int) -> bool: - try: - response = requests.delete(f"{self.get_base_url()}/{entity_id}") - response.raise_for_status() - return True - except Exception as e: - logger.error(f"Failed to delete entity {entity_id}: {str(e)}") - raise EntityServiceException("Error deleting entity", e) - - def update_entity_name(self, entity_id: int, name: str) -> bool: - try: - response = requests.patch(f"{self.get_base_url()}/{entity_id}/name/{name}") - response.raise_for_status() - return True - except Exception as e: - logger.error(f"Failed to update name for entity {entity_id}: {str(e)}") - raise EntityServiceException("Error updating entity name", e) diff --git a/environment.py b/environment.py deleted file mode 100644 index 5a248c1..0000000 --- a/environment.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2024 Preponderous Software -# MIT License - -import re - - -class Environment: - def __init__(self, environmentId: int, name: str, creationDate: str): - self.setEnvironmentId(environmentId) - self.setName(name) - self.setCreationDate(creationDate) - - def getEnvironmentId(self) -> int: - return self.environmentId - - def setEnvironmentId(self, environmentId: int): - if not isinstance(environmentId, int): - raise TypeError("environmentId must be an integer") - self.environmentId = environmentId - - def getName(self) -> str: - return self.name - - def setName(self, name: str): - if not isinstance(name, str): - raise TypeError("name must be a string") - self.name = name - - def getCreationDate(self) -> str: - return self.creationDate - - def setCreationDate(self, creationDate: str): - # if not re.match(r"\d{4}-\d{2}-\d{2}", creationDate): - # raise ValueError("creationDate must be in the format YYYY-MM-DD") - self.creationDate = creationDate - - def __str__(self): - return f"Environment{{environmentId={self.environmentId}, name={self.name}, creationDate={self.creationDate}}}" \ No newline at end of file diff --git a/environmentService.py b/environmentService.py deleted file mode 100644 index c1628c8..0000000 --- a/environmentService.py +++ /dev/null @@ -1,45 +0,0 @@ - -# Copyright (c) 2024 Preponderous Software -# MIT License - -import requests -from environment import Environment - -class EnvironmentService: - def __init__(self, base_url): - self.base_url = f"{base_url}/api/v1/environments" - - def get_all_environments(self) -> list[Environment]: - response = requests.get(f"{self.base_url}") - response.raise_for_status() - return [Environment(**env) for env in response.json()] - - def get_environment_by_id(self, environment_id: int) -> Environment: - response = requests.get(f"{self.base_url}/{environment_id}") - response.raise_for_status() - return Environment(**response.json()) - - def get_environment_by_name(self, name: str) -> Environment: - response = requests.get(f"{self.base_url}/name/{name}") - response.raise_for_status() - return Environment(**response.json()) - - def get_environment_of_entity(self, entity_id: int) -> Environment: - response = requests.get(f"{self.base_url}/entity/{entity_id}") - response.raise_for_status() - return Environment(**response.json()) - - def create_environment(self, name: str, num_grids: int, grid_size: int) -> Environment: - response = requests.post(f"{self.base_url}/{name}/{num_grids}/{grid_size}") - response.raise_for_status() - return Environment(**response.json()) - - def delete_environment(self, environment_id: int) -> bool: - response = requests.delete(f"{self.base_url}/{environment_id}") - response.raise_for_status() - return response.status_code == 200 - - def update_environment_name(self, environment_id: int, name: str) -> bool: - response = requests.patch(f"{self.base_url}/{environment_id}/name/{name}") - response.raise_for_status() - return response.status_code == 200 \ No newline at end of file diff --git a/grid.py b/grid.py deleted file mode 100644 index 36a9cd6..0000000 --- a/grid.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2024 Preponderous Software -# MIT License - -class Grid: - def __init__(self, grid_id: int, rows: int, columns: int): - self.grid_id = grid_id - self.rows = rows - self.columns = columns - - def get_grid_id(self) -> int: - return self.grid_id - - def set_grid_id(self, grid_id: int): - self.grid_id = grid_id - - def get_rows(self) -> int: - return self.rows - - def set_rows(self, rows: int): - self.rows = rows - - def get_columns(self) -> int: - return self.columns - - def set_columns(self, columns: int): - self.columns = columns - - def __str__(self) -> str: - return f"Grid{{grid_id={self.grid_id}, rows={self.rows}, columns={self.columns}}}" \ No newline at end of file diff --git a/gridService.py b/gridService.py deleted file mode 100644 index 10419e9..0000000 --- a/gridService.py +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (c) 2024 Preponderous Software -# MIT License - -import logging -from typing import List, Optional -import requests -from requests.exceptions import HTTPError -from grid import Grid - -logger = logging.getLogger(__name__) - -class GridService: - def __init__(self, base_url: str): - """Initialize GridService with base URL. - - Args: - base_url (str): Base URL of the service - """ - self.base_url = f"{base_url}/api/v1/grids" - - def get_all_grids(self) -> List[Grid]: - """Get all grids. - - Returns: - List[Grid]: List of all grids - - Raises: - RuntimeError: If there is an error fetching the grids - """ - try: - response = requests.get(self.base_url) - response.raise_for_status() - return [Grid(**grid) for grid in response.json()] - except Exception as e: - logger.error(f"Error getting all grids: {str(e)}") - raise RuntimeError("Failed to fetch all grids") from e - - def get_grid_by_id(self, grid_id: int) -> Optional[Grid]: - """Get grid by ID. - - Args: - grid_id (int): ID of the grid to fetch - - Returns: - Optional[Grid]: Grid if found, None if not found - - Raises: - RuntimeError: If there is an error fetching the grid - """ - try: - response = requests.get(f"{self.base_url}/{grid_id}") - response.raise_for_status() - return Grid(**response.json()) - except HTTPError as e: - if e.response.status_code == 404: - return None - logger.error(f"Error getting grid by id {grid_id}: {str(e)}") - raise RuntimeError(f"Failed to fetch grid by id: {grid_id}") from e - except Exception as e: - logger.error(f"Error getting grid by id {grid_id}: {str(e)}") - raise RuntimeError(f"Failed to fetch grid by id: {grid_id}") from e - - def get_grids_in_environment(self, environment_id: int) -> List[Grid]: - """Get all grids in an environment. - - Args: - environment_id (int): ID of the environment - - Returns: - List[Grid]: List of grids in the environment - - Raises: - RuntimeError: If there is an error fetching the grids - """ - try: - response = requests.get(f"{self.base_url}/environment/{environment_id}") - response.raise_for_status() - return [Grid(**grid) for grid in response.json()] - except Exception as e: - logger.error(f"Error getting grids in environment {environment_id}: {str(e)}") - raise RuntimeError(f"Failed to fetch grids in environment: {environment_id}") from e - - def get_grid_of_entity(self, entity_id: int) -> Optional[Grid]: - """Get grid of an entity. - - Args: - entity_id (int): ID of the entity - - Returns: - Optional[Grid]: Grid if found, None if not found - - Raises: - RuntimeError: If there is an error fetching the grid - """ - try: - response = requests.get(f"{self.base_url}/entity/{entity_id}") - response.raise_for_status() - return Grid(**response.json()) - except HTTPError as e: - if e.response.status_code == 404: - return None - logger.error(f"Error getting grid for entity {entity_id}: {str(e)}") - raise RuntimeError(f"Failed to fetch grid for entity: {entity_id}") from e - except Exception as e: - logger.error(f"Error getting grid for entity {entity_id}: {str(e)}") - raise RuntimeError(f"Failed to fetch grid for entity: {entity_id}") from e \ No newline at end of file diff --git a/location.py b/location.py deleted file mode 100644 index 9d6fd53..0000000 --- a/location.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2024 Preponderous Software -# MIT License - -class Location: - def __init__(self, location_id: int, x: int, y: int): - self.location_id = location_id - self.x = x - self.y = y - - def get_location_id(self) -> int: - return self.location_id - - def set_location_id(self, location_id: int): - self.location_id = location_id - - def get_x(self) -> int: - return self.x - - def set_x(self, x: int): - self.x = x - - def get_y(self) -> int: - return self.y - - def set_y(self, y: int): - self.y = y - - def __str__(self) -> str: - return f"Location{{location_id={self.location_id}, x={self.x}, y={self.y}}}" \ No newline at end of file diff --git a/locationService.py b/locationService.py deleted file mode 100644 index 890b560..0000000 --- a/locationService.py +++ /dev/null @@ -1,115 +0,0 @@ -from typing import List, Optional -import logging -import requests -from dataclasses import dataclass -from location import Location - -# Exception classes -class NotFoundException(Exception): - pass - -class ServiceException(Exception): - def __init__(self, message: str, cause: Exception = None): - super().__init__(message) - self.cause = cause - -# Service configuration -@dataclass -class ServiceConfig: - viron_host: str - viron_port: int - -# Location Service -class LocationService: - def __init__(self, service_config: ServiceConfig): - self.logger = logging.getLogger(__name__) - self.base_url = f"{service_config.viron_host}:{service_config.viron_port}/api/v1/locations" - - def get_all_locations(self) -> List[Location]: - try: - response = requests.get(self.base_url) - response.raise_for_status() - return response.json() - except Exception as e: - self.logger.error(f"Error getting locations: {str(e)}") - raise ServiceException("Error getting locations", e) - - def get_location_by_id(self, id: int) -> Location: - try: - response = requests.get(f"{self.base_url}/{id}") - if response.status_code == 404: - raise NotFoundException(f"Location not found with id: {id}") - response.raise_for_status() - return response.json() - except NotFoundException as e: - raise e - except Exception as e: - self.logger.error(f"Error getting location by id {id}: {str(e)}") - raise ServiceException(f"Error getting location by id: {id}", e) - - def get_locations_in_environment(self, environment_id: int) -> List[Location]: - try: - response = requests.get(f"{self.base_url}/environment/{environment_id}") - response.raise_for_status() - return response.json() - except Exception as e: - self.logger.error(f"Error getting locations in environment {environment_id}: {str(e)}") - raise ServiceException(f"Error getting locations in environment: {environment_id}", e) - - def get_locations_in_grid(self, grid_id: int) -> List[Location]: - try: - response = requests.get(f"{self.base_url}/grid/{grid_id}") - response.raise_for_status() - return response.json() - except Exception as e: - self.logger.error(f"Error getting locations in grid {grid_id}: {str(e)}") - raise ServiceException(f"Error getting locations in grid: {grid_id}", e) - - def get_location_of_entity(self, entity_id: int) -> Location: - try: - response = requests.get(f"{self.base_url}/entity/{entity_id}") - if response.status_code == 404: - raise NotFoundException(f"Location not found for entity: {entity_id}") - response.raise_for_status() - return response.json() - except NotFoundException as e: - raise e - except Exception as e: - self.logger.error(f"Error getting location of entity {entity_id}: {str(e)}") - raise ServiceException(f"Error getting location of entity: {entity_id}", e) - - def add_entity_to_location(self, entity_id: int, location_id: int) -> None: - try: - response = requests.put(f"{self.base_url}/{location_id}/entity/{entity_id}") - if response.status_code == 404: - raise NotFoundException("Location or entity not found") - response.raise_for_status() - except NotFoundException as e: - raise e - except Exception as e: - self.logger.error(f"Error adding entity {entity_id} to location {location_id}: {str(e)}") - raise ServiceException("Error adding entity to location", e) - - def remove_entity_from_location(self, entity_id: int, location_id: int) -> None: - try: - response = requests.delete(f"{self.base_url}/{location_id}/entity/{entity_id}") - if response.status_code == 404: - raise NotFoundException("Location or entity not found") - response.raise_for_status() - except NotFoundException as e: - raise e - except Exception as e: - self.logger.error(f"Error removing entity {entity_id} from location {location_id}: {str(e)}") - raise ServiceException("Error removing entity from location", e) - - def remove_entity_from_current_location(self, entity_id: int) -> None: - try: - response = requests.delete(f"{self.base_url}/entity/{entity_id}") - if response.status_code == 404: - raise NotFoundException("Entity not found") - response.raise_for_status() - except NotFoundException as e: - raise e - except Exception as e: - self.logger.error(f"Error removing entity {entity_id} from current location: {str(e)}") - raise ServiceException("Error removing entity from current location", e) \ No newline at end of file diff --git a/main.py b/main.py index 839f070..3faa15c 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,10 @@ from operator import truediv import random import pygame -from environment import Environment -from environmentService import EnvironmentService +from Viron.src.main.python.preponderous.viron.models.location import Location +from Viron.src.main.python.preponderous.viron.services.environmentService import EnvironmentService +from Viron.src.main.python.preponderous.viron.services.locationService import LocationService from graphik import Graphik -from locationService import ServiceConfig -from locationService import LocationService -from location import Location black = (0,0,0) @@ -21,11 +19,8 @@ url = "http://localhost" port = 9999 -locationServiceConfig = ServiceConfig(viron_host=url, viron_port=port) -locationService = LocationService(locationServiceConfig) - -environmentServiceBaseUrl = f"{url}:{port}" -environmentService = EnvironmentService(environmentServiceBaseUrl) +locationService = LocationService(url, port) +environmentService = EnvironmentService(url, port) def log(message): print(message) From c0c3966a5543bee6e1c4d31c8571d259980f8c05 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:28:41 -0600 Subject: [PATCH 10/24] Add Docker Compose scripts for starting and stopping containers --- down.bat | 6 ++++++ up.bat | 5 +++++ 2 files changed, 11 insertions(+) create mode 100644 down.bat create mode 100644 up.bat diff --git a/down.bat b/down.bat new file mode 100644 index 0000000..ba19c87 --- /dev/null +++ b/down.bat @@ -0,0 +1,6 @@ +# This script is used to stop the Docker containers defined in the Docker Compose file. + +docker compose -f .\viron\compose.yml down --remove-orphans --volumes +REM The --remove-orphans flag removes containers for services not defined in the Compose file. +REM The --volumes flag removes the volumes associated with the containers, ensuring a clean shutdown. +REM This ensures that all resources are cleaned up when the containers are stopped. diff --git a/up.bat b/up.bat new file mode 100644 index 0000000..3c3ddd2 --- /dev/null +++ b/up.bat @@ -0,0 +1,5 @@ +# This script is used to start the Docker containers defined in the Docker Compose file. + +docker compose -f .\viron\compose.yml up -d --build +REM The -d flag runs the containers in detached mode, allowing them to run in the background. +REM The --build flag forces a rebuild of the images before starting the containers. From b6f1a9f12f85778a6b5bd14945b2031bb9cf41a7 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:28:58 -0600 Subject: [PATCH 11/24] feat: load existing environment from JSON if available, otherwise create a new one and save its ID --- .gitignore | 3 ++- main.py | 19 +++++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 7e99e36..3b6400d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -*.pyc \ No newline at end of file +*.pyc +environment.json \ No newline at end of file diff --git a/main.py b/main.py index 3faa15c..a491b65 100644 --- a/main.py +++ b/main.py @@ -5,6 +5,8 @@ from Viron.src.main.python.preponderous.viron.services.environmentService import EnvironmentService from Viron.src.main.python.preponderous.viron.services.locationService import LocationService from graphik import Graphik +import os +import json black = (0,0,0) @@ -39,8 +41,21 @@ def main(): graphik = Graphik(gameDisplay) pygame.display.set_caption("Visualizing Environment With Random Colors") - log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) - environment = environmentService.create_environment("Test", numGrids, gridSize) + env_file = "environment.json" + + if os.path.exists(env_file): + log("Environment file exists, loading...") + with open(env_file, "r") as f: + data = json.load(f) + env_id = data.get("environment_id") + environment = environmentService.get_environment_by_id(env_id) + log(f"Loaded existing environment with id {env_id}") + else: + log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) + environment = environmentService.create_environment("Test", numGrids, gridSize) + with open(env_file, "w") as f: + json.dump({"environment_id": environment.getEnvironmentId()}, f) + log(f"Created new environment with id {environment.getEnvironmentId()}") locationWidth = displayWidth/gridSize locationHeight = displayHeight/gridSize From 08c4ec52176becd4e4ddda7f4660a576c3bcb0bf Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:29:09 -0600 Subject: [PATCH 12/24] chore: update subproject commit reference --- Viron | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Viron b/Viron index 25214aa..d9809d5 160000 --- a/Viron +++ b/Viron @@ -1 +1 @@ -Subproject commit 25214aa37a0d34383c296d6ae35f6401a13969d0 +Subproject commit d9809d5632aa341f4f340f741158465022c2ff87 From fba3d9ab70325792aecafdda1c0027f814ddd229 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:34:11 -0600 Subject: [PATCH 13/24] feat: enhance environment loading logic to check grid size and number of grids before creating a new environment --- main.py | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/main.py b/main.py index a491b65..8899cdb 100644 --- a/main.py +++ b/main.py @@ -7,16 +7,27 @@ from graphik import Graphik import os import json +import sys black = (0,0,0) white = (255,255,255) -displayWidth = 600 -displayHeight = 600 +displayWidth = 800 +displayHeight = 800 + +def log(message): + print(message) numGrids = 1 -gridSize = 50 +if len(sys.argv) > 1: + try: + gridSize = int(sys.argv[1]) + except ValueError: + log("Invalid grid size argument, using default of 50.") + gridSize = 50 +else: + gridSize = 50 url = "http://localhost" port = 9999 @@ -24,9 +35,6 @@ locationService = LocationService(url, port) environmentService = EnvironmentService(url, port) -def log(message): - print(message) - def drawEnvironment(locations, graphik, locationWidth, locationHeight): for location in locations: location = Location(location_id=location['locationId'], x=location['x'], y=location['y']) @@ -48,13 +56,30 @@ def main(): with open(env_file, "r") as f: data = json.load(f) env_id = data.get("environment_id") - environment = environmentService.get_environment_by_id(env_id) - log(f"Loaded existing environment with id {env_id}") + saved_grid_size = data.get("grid_size") + saved_num_grids = data.get("num_grids") + if saved_grid_size == gridSize and saved_num_grids == numGrids: + environment = environmentService.get_environment_by_id(env_id) + log(f"Loaded existing environment with id {env_id} and size {saved_grid_size}x{saved_grid_size} with {saved_num_grids} grid(s).") + else: + log("Environment size does not match, creating new environment.") + environment = environmentService.create_environment("Test", numGrids, gridSize) + with open(env_file, "w") as fw: + json.dump({ + "environment_id": environment.getEnvironmentId(), + "grid_size": gridSize, + "num_grids": numGrids + }, fw) + log(f"Created new environment with id {environment.getEnvironmentId()}") else: log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) environment = environmentService.create_environment("Test", numGrids, gridSize) with open(env_file, "w") as f: - json.dump({"environment_id": environment.getEnvironmentId()}, f) + json.dump({ + "environment_id": environment.getEnvironmentId(), + "grid_size": gridSize, + "num_grids": numGrids + }, f) log(f"Created new environment with id {environment.getEnvironmentId()}") locationWidth = displayWidth/gridSize From c7e75e1ce94b88014fbaf214daf6b26cf85b91ec Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:36:52 -0600 Subject: [PATCH 14/24] fix: update environment file name and enhance loading logic to manage multiple environments --- .gitignore | 2 +- main.py | 43 +++++++++++++++++++------------------------ 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 3b6400d..332062e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ *.pyc -environment.json \ No newline at end of file +environments.json \ No newline at end of file diff --git a/main.py b/main.py index 8899cdb..bdfdea7 100644 --- a/main.py +++ b/main.py @@ -49,37 +49,32 @@ def main(): graphik = Graphik(gameDisplay) pygame.display.set_caption("Visualizing Environment With Random Colors") - env_file = "environment.json" + env_file = "environments.json" + environments = {} + # Load existing environments if file exists if os.path.exists(env_file): - log("Environment file exists, loading...") + log("Environments file exists, loading...") with open(env_file, "r") as f: - data = json.load(f) - env_id = data.get("environment_id") - saved_grid_size = data.get("grid_size") - saved_num_grids = data.get("num_grids") - if saved_grid_size == gridSize and saved_num_grids == numGrids: - environment = environmentService.get_environment_by_id(env_id) - log(f"Loaded existing environment with id {env_id} and size {saved_grid_size}x{saved_grid_size} with {saved_num_grids} grid(s).") - else: - log("Environment size does not match, creating new environment.") - environment = environmentService.create_environment("Test", numGrids, gridSize) - with open(env_file, "w") as fw: - json.dump({ - "environment_id": environment.getEnvironmentId(), - "grid_size": gridSize, - "num_grids": numGrids - }, fw) - log(f"Created new environment with id {environment.getEnvironmentId()}") + environments = json.load(f) + + # Create a unique key for the environment based on grid size and numGrids + env_key = f"{numGrids}x{gridSize}" + + if env_key in environments: + env_id = environments[env_key]["environment_id"] + environment = environmentService.get_environment_by_id(env_id) + log(f"Loaded existing environment with id {env_id} and size {gridSize}x{gridSize} with {numGrids} grid(s).") else: log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) environment = environmentService.create_environment("Test", numGrids, gridSize) + environments[env_key] = { + "environment_id": environment.getEnvironmentId(), + "grid_size": gridSize, + "num_grids": numGrids + } with open(env_file, "w") as f: - json.dump({ - "environment_id": environment.getEnvironmentId(), - "grid_size": gridSize, - "num_grids": numGrids - }, f) + json.dump(environments, f, indent=2) log(f"Created new environment with id {environment.getEnvironmentId()}") locationWidth = displayWidth/gridSize From 43a2ce1432e12097335065be697d09da86676abc Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:51:20 -0600 Subject: [PATCH 15/24] feat: add script to create environments with incrementing sizes and update main.py to support exit after creation --- .gitignore | 3 ++- create_environments.bat | 33 +++++++++++++++++++++++++++++++++ main.py | 9 ++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 create_environments.bat diff --git a/.gitignore b/.gitignore index 332062e..0f6c6d1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.pyc -environments.json \ No newline at end of file +environments.json + diff --git a/create_environments.bat b/create_environments.bat new file mode 100644 index 0000000..cb82658 --- /dev/null +++ b/create_environments.bat @@ -0,0 +1,33 @@ +# Script to run `python main.py` a number of times with incrementing sizes + +echo off + +setlocal enabledelayedexpansion +set "script=main.py" +REM Check if a max size argument was provided, otherwise use default +if "%~1"=="" ( + echo No max size provided, using default value. + set "max_size=100" +) else ( + echo Max size provided: %~1 + set "max_size=%~1" +) +set "size_of_next_env=1" +set "increment=1" +set "output_file=output.txt" +set "python_executable=python" +set "log_file=log.txt" +set "error_log_file=error_log.txt" + +:loop +if !size_of_next_env! leq !max_size! ( + @echo Starting environment with size !size_of_next_env! + %python_executable% %script% !size_of_next_env! --exit-after-create > %output_file% 2> %error_log_file% + if errorlevel 1 ( + echo Error occurred while running with size !size_of_next_env!. + ) else ( + echo Environment created successfully with size !size_of_next_env!. + ) + set /a size_of_next_env+=%increment% + goto loop +) \ No newline at end of file diff --git a/main.py b/main.py index bdfdea7..85dc837 100644 --- a/main.py +++ b/main.py @@ -34,7 +34,9 @@ def log(message): locationService = LocationService(url, port) environmentService = EnvironmentService(url, port) - +exit_after_create = False +if len(sys.argv) > 2 and sys.argv[2] == "--exit-after-create": + exit_after_create = True def drawEnvironment(locations, graphik, locationWidth, locationHeight): for location in locations: location = Location(location_id=location['locationId'], x=location['x'], y=location['y']) @@ -76,6 +78,11 @@ def main(): with open(env_file, "w") as f: json.dump(environments, f, indent=2) log(f"Created new environment with id {environment.getEnvironmentId()}") + + if exit_after_create: + log("Exiting after environment creation.") + pygame.quit() + return locationWidth = displayWidth/gridSize locationHeight = displayHeight/gridSize From cc2cd714899e17567351ec94478082c9cc52b7af Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:53:19 -0600 Subject: [PATCH 16/24] fix: ensure environments.json is deleted before starting environment creation --- create_environments.bat | 3 +++ 1 file changed, 3 insertions(+) diff --git a/create_environments.bat b/create_environments.bat index cb82658..0af49fb 100644 --- a/create_environments.bat +++ b/create_environments.bat @@ -12,6 +12,9 @@ if "%~1"=="" ( echo Max size provided: %~1 set "max_size=%~1" ) +REM Delete environments.json before starting +if exist environments.json del environments.json + set "size_of_next_env=1" set "increment=1" set "output_file=output.txt" From 4a1fce3732c0d70a52d2b604f7af65e79d9bd1b8 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:53:48 -0600 Subject: [PATCH 17/24] fix: update .gitignore to include all JSON and TXT files --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 0f6c6d1..e62d64d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ *.pyc -environments.json - +*.json +*.txt \ No newline at end of file From 219b3495c0e32e089ab0e1402a504091d18de7bb Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sat, 24 May 2025 23:57:31 -0600 Subject: [PATCH 18/24] feat: measure and log environment creation time in main.py --- main.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 85dc837..38602a4 100644 --- a/main.py +++ b/main.py @@ -8,6 +8,7 @@ import os import json import sys +import time black = (0,0,0) @@ -69,7 +70,9 @@ def main(): log(f"Loaded existing environment with id {env_id} and size {gridSize}x{gridSize} with {numGrids} grid(s).") else: log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) + start_time = time.time() environment = environmentService.create_environment("Test", numGrids, gridSize) + end_time = time.time() environments[env_key] = { "environment_id": environment.getEnvironmentId(), "grid_size": gridSize, @@ -77,7 +80,7 @@ def main(): } with open(env_file, "w") as f: json.dump(environments, f, indent=2) - log(f"Created new environment with id {environment.getEnvironmentId()}") + log(f"Created new environment with id {environment.getEnvironmentId()} in {end_time - start_time:.2f} seconds.") if exit_after_create: log("Exiting after environment creation.") From 7f1ba41acb58f879e76b2370565a549d538703e8 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:02:17 -0600 Subject: [PATCH 19/24] fix: redirect output and error logs to append instead of overwrite in create_environments.bat --- create_environments.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/create_environments.bat b/create_environments.bat index 0af49fb..30a5468 100644 --- a/create_environments.bat +++ b/create_environments.bat @@ -25,7 +25,7 @@ set "error_log_file=error_log.txt" :loop if !size_of_next_env! leq !max_size! ( @echo Starting environment with size !size_of_next_env! - %python_executable% %script% !size_of_next_env! --exit-after-create > %output_file% 2> %error_log_file% + %python_executable% %script% !size_of_next_env! --exit-after-create >> %output_file% 2>> %error_log_file% if errorlevel 1 ( echo Error occurred while running with size !size_of_next_env!. ) else ( From fad9cbfce1c5aac2ddf1214e49aac667754a57f7 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:02:24 -0600 Subject: [PATCH 20/24] feat: add creation time tracking for environments in main.py --- main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.py b/main.py index 38602a4..3f4084f 100644 --- a/main.py +++ b/main.py @@ -76,7 +76,8 @@ def main(): environments[env_key] = { "environment_id": environment.getEnvironmentId(), "grid_size": gridSize, - "num_grids": numGrids + "num_grids": numGrids, + "creation_time_seconds": end_time - start_time } with open(env_file, "w") as f: json.dump(environments, f, indent=2) From 27dfceaf5d6a89f15cf1738404635987b83c9431 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:05:48 -0600 Subject: [PATCH 21/24] fix: add deletion message for environments.json in create_environments.bat --- create_environments.bat | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/create_environments.bat b/create_environments.bat index 30a5468..2e95795 100644 --- a/create_environments.bat +++ b/create_environments.bat @@ -13,7 +13,13 @@ if "%~1"=="" ( set "max_size=%~1" ) REM Delete environments.json before starting -if exist environments.json del environments.json +echo Deleting environments.json if it exists... +if exist environments.json ( + echo environments.json found, deleting... + del environments.json +) else ( + echo environments.json not found, nothing to delete. +) set "size_of_next_env=1" set "increment=1" From 450ea45588cde4ce5f0188cdd3c35d0bfb05c4e8 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:08:43 -0600 Subject: [PATCH 22/24] feat: draw environment after creation and update display in main.py --- main.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/main.py b/main.py index 3f4084f..4793cb5 100644 --- a/main.py +++ b/main.py @@ -85,6 +85,10 @@ def main(): if exit_after_create: log("Exiting after environment creation.") + locations = locationService.get_locations_in_environment(environment.getEnvironmentId()) + drawEnvironment(locations, graphik, displayWidth/gridSize, displayHeight/gridSize) + pygame.display.update() + time.sleep(2) pygame.quit() return From f979b565693535041d26db7f4e0765365a408244 Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:26:20 -0600 Subject: [PATCH 23/24] feat: enhance environment loading with error handling and user feedback --- main.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/main.py b/main.py index 4793cb5..a66833a 100644 --- a/main.py +++ b/main.py @@ -65,10 +65,21 @@ def main(): env_key = f"{numGrids}x{gridSize}" if env_key in environments: + graphik.drawText("Loading existing environment, please wait...", displayWidth/2, displayHeight/2, 20, "white") env_id = environments[env_key]["environment_id"] - environment = environmentService.get_environment_by_id(env_id) - log(f"Loaded existing environment with id {env_id} and size {gridSize}x{gridSize} with {numGrids} grid(s).") + try: + environment = environmentService.get_environment_by_id(env_id) + log(f"Loaded existing environment with id {env_id} and size {gridSize}x{gridSize} with {numGrids} grid(s).") + except Exception as e: + log(f"Error loading existing environment: {e}") + graphik.drawText("Error loading environment, please check logs.", displayWidth/2, displayHeight/2 + 30, 20, "red") + pygame.display.update() + time.sleep(2) + pygame.quit() + return else: + graphik.drawText("Creating environment, please wait...", 100, 100, 20,"white") + pygame.display.update() log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) start_time = time.time() environment = environmentService.create_environment("Test", numGrids, gridSize) From f7ca682a10b72d5ff3db59b8467eae7f456d98ac Mon Sep 17 00:00:00 2001 From: dmccoystephenson Date: Sun, 25 May 2025 00:28:58 -0600 Subject: [PATCH 24/24] fix: adjust text position for environment creation message in main.py --- main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.py b/main.py index a66833a..5814952 100644 --- a/main.py +++ b/main.py @@ -78,7 +78,7 @@ def main(): pygame.quit() return else: - graphik.drawText("Creating environment, please wait...", 100, 100, 20,"white") + graphik.drawText("Creating environment, please wait...", 400, 400, 20,"white") pygame.display.update() log("Creating environment with " + str(numGrids) + " grid(s) of size " + str(gridSize) + "x" + str(gridSize)) start_time = time.time()