From d98401eca3e844dfbed0b016a6bf2a898745b627 Mon Sep 17 00:00:00 2001 From: Rob Savoye Date: Mon, 4 Mar 2024 13:51:11 -0700 Subject: [PATCH] fix: All API classes refactored to use the new PGSupport class --- tm_admin/campaigns/api.py | 83 ++++++++++++++++++------- tm_admin/messages/api.py | 77 +++++++++++++++++------ tm_admin/organizations/api.py | 111 +++++++++++++++++++--------------- tm_admin/tasks/api.py | 39 ++++-------- tm_admin/teams/api.py | 46 +++++++------- tm_admin/users/api.py | 62 ++++++------------- 6 files changed, 236 insertions(+), 182 deletions(-) diff --git a/tm_admin/campaigns/api.py b/tm_admin/campaigns/api.py index 672f97b9..204fe2c3 100644 --- a/tm_admin/campaigns/api.py +++ b/tm_admin/campaigns/api.py @@ -31,23 +31,21 @@ from cpuinfo import get_cpu_info from shapely.geometry import shape from shapely import centroid -from tm_admin.types_tm import Mappingtypes, Projectstatus, Taskcreationmode, Editors, Permissions, Projectpriority, Projectdifficulty, Teamroles -from tm_admin.projects.projects_class import ProjectsTable -from tm_admin.tasks.tasks_class import TasksTable -from tm_admin.messages.messages import MessagesDB -from tm_admin.projects.projects import ProjectsDB +from tm_admin.types_tm import Mappingtypes +from tm_admin.campaigns.campaigns_class import CampaignsTable from tm_admin.users.users import UsersDB from tm_admin.teams.teams import TeamsDB from shapely import wkb, get_coordinates from tm_admin.dbsupport import DBSupport from tm_admin.generator import Generator -from osm_rawdata.pgasync import PostgresClient +# from osm_rawdata.pgasync import PostgresClient import re # from progress import Bar, PixelBar from tqdm import tqdm import tqdm.asyncio from codetiming import Timer import asyncio +from tm_admin.pgsupport import PGSupport # The number of threads is based on the CPU cores info = get_cpu_info() @@ -56,7 +54,7 @@ # Instantiate logger log = logging.getLogger(__name__) -class CampaignsAPI(PostgresClient): +class CampaignsAPI(PGSupport): def __init__(self): """ Create a class to handle the backend API calls, so the code can be shared @@ -65,28 +63,64 @@ def __init__(self): Returns: (CampaignsAPI): An instance of this class """ - self.allowed_roles = [ - Teamroles.TEAM_MAPPER, - Teamroles.TEAM_VALIDATOR, - Teamroles.TEAM_MANAGER, - ] - self.messagesdb = MessagesDB() - self.usersdb = UsersDB() - self.teamsdb = TeamsDB() - - async def connectDBs(self, + # self.allowed_roles = [ + # Teamroles.TEAM_MAPPER, + # Teamroles.TEAM_VALIDATOR, + # Teamroles.TEAM_MANAGER, + # ] + # self.messagesdb = MessagesDB() + # self.usersdb = UsersDB() + # self.teamsdb = TeamsDB() + super().__init__("campaigns") + + async def initialize(self, uri: str, ): """ - Connect to all tables for API endpoints that require accessing multiple tables. + Connect to all tables for API endpoints that require + accessing multiple tables. Args: inuri (str): The URI for the TM Admin output database """ await self.connect(uri) - await self.messagesdb.connect(uri) - await self.usersdb.connect(uri) - await self.teamsdb.connect(uri) + await self.getTypes("campaigns") + #await self.usersdb.connect(uri) + #await self.teamsdb.connect(uri) + + async def getByID(self, + org_id: int, + ): + """ + Get all the information for an campaign using it's ID + + Args: + project_id (int): The campaign to get the data for + + Returns: + (dict): the campaign information + """ + # log.debug(f"--- getByID() ---") + sql = f"SELECT * FROM campaigns WHERE id={org_id}" + results = await self.execute(sql) + return results + + async def getByName(self, + name: str, + ): + """ + Get all the information for a campaign using the name + + Args: + name (str): The campaign to get the data for + + Returns: + (dict): the campaign information + """ + # log.debug(f"--- getByName() ---") + sql = f"SELECT * FROM campaigns WHERE name='{name}'" + results = await self.execute(sql) + return results async def create(self, campaign: CampaignsTable, @@ -100,7 +134,12 @@ async def create(self, Returns: (bool): Whether the campaign got created """ - log.warning(f"create(): unimplemented!") + # log.warning(f"create(): unimplemented!") + result = await self.insertRecords([campaign]) + + # The ID of the record that just got inserted is returned + if result: + return True return False diff --git a/tm_admin/messages/api.py b/tm_admin/messages/api.py index dd78b5c0..8d4dcc97 100755 --- a/tm_admin/messages/api.py +++ b/tm_admin/messages/api.py @@ -33,21 +33,22 @@ from shapely import centroid from tm_admin.types_tm import Mappingtypes from tm_admin.messages.messages_class import MessagesTable -from tm_admin.tasks.tasks_class import TasksTable +# from tm_admin.tasks.tasks_class import TasksTable from tm_admin.messages.messages import MessagesDB -from tm_admin.projects.projects import ProjectsDB +# from tm_admin.projects.projects import ProjectsDB from tm_admin.users.users import UsersDB -from tm_admin.teams.teams import TeamsDB +# from tm_admin.teams.teams import TeamsDB from shapely import wkb, get_coordinates from tm_admin.dbsupport import DBSupport from tm_admin.generator import Generator -from osm_rawdata.pgasync import PostgresClient +# from osm_rawdata.pgasync import PostgresClient import re # from progress import Bar, PixelBar from tqdm import tqdm import tqdm.asyncio from codetiming import Timer import asyncio +from tm_admin.pgsupport import PGSupport # The number of threads is based on the CPU cores info = get_cpu_info() @@ -56,7 +57,7 @@ # Instantiate logger log = logging.getLogger(__name__) -class MessagesAPI(PostgresClient): +class MessagesAPI(PGSupport): def __init__(self): """ Create a class to handle the backend API calls, so the code can be shared @@ -65,28 +66,60 @@ def __init__(self): Returns: (MessagesAPI): An instance of this class """ - self.allowed_roles = [ - Teamroles.TEAM_MAPPER, - Teamroles.TEAM_VALIDATOR, - Teamroles.TEAM_MANAGER, - ] - self.messagesdb = MessagesDB() - self.usersdb = UsersDB() - self.teamsdb = TeamsDB() - - async def connectDBs(self, + # self.messagesdb = MessagesDB() + # self.usersdb = UsersDB() + # self.teamsdb = TeamsDB() + + super().__init__("campaigns") + + async def initialize(self, uri: str, ): """ - Connect to all tables for API endpoints that require accessing multiple tables. + Connect to all tables for API endpoints that require + accessing multiple tables. Args: inuri (str): The URI for the TM Admin output database """ await self.connect(uri) - await self.messagesdb.connect(uri) - await self.usersdb.connect(uri) - await self.teamsdb.connect(uri) + await self.getTypes("campaigns") + #await self.usersdb.connect(uri) + #await self.teamsdb.connect(uri) + + async def getByID(self, + org_id: int, + ): + """ + Get all the information for an message using it's ID + + Args: + project_id (int): The message to get the data for + + Returns: + (dict): the message information + """ + # log.debug(f"--- getByID() ---") + sql = f"SELECT * FROM messages WHERE id={org_id}" + results = await self.execute(sql) + return results + + async def getByName(self, + name: str, + ): + """ + Get all the information for a message using the name + + Args: + name (str): The message to get the data for + + Returns: + (dict): the message information + """ + # log.debug(f"--- getByName() ---") + sql = f"SELECT * FROM messages WHERE name='{name}'" + results = await self.execute(sql) + return results async def create(self, message: MessagesTable, @@ -102,6 +135,12 @@ async def create(self, """ log.warning(f"create(): unimplemented!") + result = await self.insertRecords([message]) + + # The ID of the record that just got inserted is returned + if result: + return True + return False async def update(self, diff --git a/tm_admin/organizations/api.py b/tm_admin/organizations/api.py index 7ae49c7f..37ba51c4 100644 --- a/tm_admin/organizations/api.py +++ b/tm_admin/organizations/api.py @@ -34,11 +34,13 @@ from tm_admin.organizations.organizations import OrganizationsDB from tm_admin.organizations.organizations_class import OrganizationsTable from tm_admin.dbsupport import DBSupport -from osm_rawdata.pgasync import PostgresClient +from tm_admin.types_tm import Organizationtype +# from osm_rawdata.pgasync import PostgresClient from tqdm import tqdm import tqdm.asyncio from codetiming import Timer import asyncio +from tm_admin.pgsupport import PGSupport # The number of threads is based on the CPU cores info = get_cpu_info() @@ -47,7 +49,7 @@ # Instantiate logger log = logging.getLogger(__name__) -class OrganizationsAPI(PostgresClient): +class OrganizationsAPI(PGSupport): def __init__(self): """ Create a class to handle the backend API calls, so the code can be shared @@ -57,6 +59,57 @@ def __init__(self): (OrganizationsAPI): An instance of this class """ self.orgdb = OrganizationsDB() + super().__init__("organizations") + + async def initialize(self, + uri: str, + ): + """ + Connect to all tables for API endpoints that require + accessing multiple tables. + + Args: + inuri (str): The URI for the TM Admin output database + """ + await self.connect(uri) + await self.getTypes("organizations") + #await self.messagesdb.connect(uri) + #await self.usersdb.connect(uri) + #await self.teamsdb.connect(uri) + + async def getByID(self, + org_id: int, + ): + """ + Get all the information for an organization using it's ID + + Args: + project_id (int): The organization to get the data for + + Returns: + (dict): the organization information + """ + # log.debug(f"--- getByID() ---") + sql = f"SELECT * FROM organizations WHERE id={org_id}" + results = await self.execute(sql) + return results + + async def getByName(self, + name: str, + ): + """ + Get all the information for a organization using the name + + Args: + name (str): The organization to get the data for + + Returns: + (dict): the organization information + """ + # log.debug(f"--- getByName() ---") + sql = f"SELECT * FROM organization WHERE name='{name}'" + results = await self.execute(sql) + return results async def create(self, org: OrganizationsTable, @@ -70,7 +123,12 @@ async def create(self, Returns: (bool): Whether the organization got created """ - log.warning(f"create(): unimplemented!") + # log.warning(f"create(): unimplemented!") + result = await self.insertRecords([org]) + + # The ID of the record that just got inserted is returned + if result: + return True return False @@ -104,53 +162,6 @@ async def delete(self, """ log.warning(f"delete(): unimplemented!") - async def getByID(self, - org_id: int, - ): - """ - Get all the information for a organization using it's ID - - Args: - org_id (int): The organization to get the data for - - Returns: - (dict): the project information - """ - log.debug(f"--- getByID({org_id}) ---") - sql = f"SELECT * FROM organizations WHERE id={org_id}" - results = await self.execute(sql) - return results - - async def getByName(self, - name: str, - ): - """ - Get all the information for a project using the name - - Args: - name (str): The organizations to get the data for - - Returns: - (dict): the project information - """ - log.debug(f"--- getByName() ---") - sql = f"SELECT * FROM organizations WHERE name='{name}'" - results = await self.execute(sql) - return results - - async def getTeams(self, - org_id: int, - ): - """ - - Args: - - - Returns: - - """ - log.warning(f"getTeams(): unimplemented!") - async def getStats(self, org_id: int, ): diff --git a/tm_admin/tasks/api.py b/tm_admin/tasks/api.py index cf687191..96198b91 100755 --- a/tm_admin/tasks/api.py +++ b/tm_admin/tasks/api.py @@ -41,13 +41,13 @@ from shapely import wkb, get_coordinates from tm_admin.dbsupport import DBSupport from tm_admin.generator import Generator -from osm_rawdata.pgasync import PostgresClient import re # from progress import Bar, PixelBar from tqdm import tqdm import tqdm.asyncio from codetiming import Timer import asyncio +from tm_admin.pgsupport import PGSupport # The number of threads is based on the CPU cores info = get_cpu_info() @@ -56,7 +56,7 @@ # Instantiate logger log = logging.getLogger(__name__) -class TasksAPI(PostgresClient): +class TasksAPI(PGSupport): def __init__(self): """ Create a class to handle the backend API calls, so the code can be shared @@ -65,29 +65,8 @@ def __init__(self): Returns: (TasksAPI): An instance of this class """ - self.allowed_roles = [ - Teamroles.TEAM_MAPPER, - Teamroles.TEAM_VALIDATOR, - Teamroles.TEAM_MANAGER, - ] - self.messagesdb = MessagesDB() - self.projectsdb = ProjectsDB() - self.usersdb = UsersDB() - - async def connectDBs(self, - inuri: str, - ): - """ - Connect to all tables for API endpoints that require accessing multiple tables. + super().__init__("tasks") - Args: - inuri (str): The URI for the TM Admin output database - """ - await self.messagesdb.connect(inuri) - await self.projectsdb.connect(inuri) - await self.usersdb.connect(inuri) - await self.connect(inuri) - async def getStatus(self, task_id: int, project_id: int, @@ -135,8 +114,9 @@ async def getByUser(self, Get all the information for a project using it's ID Args: + user_id (int): The user ID to lock task_id (int): The task to lock - project_id (int): The team to get the data for + project_id (int): The project this task is part of Returns: (dict): the task information @@ -153,12 +133,17 @@ async def create(self, Create a task and add it to the database. Args: - task (TeamsTable): The taskl data + task (TasksTable): The task data Returns: (bool): Whether the task got created """ - log.warning(f"create(): unimplemented!") + # log.warning(f"create(): unimplemented!") + result = await self.insertRecords([task]) + + # The ID of the record that just got inserted is returned + if result: + return True return False diff --git a/tm_admin/teams/api.py b/tm_admin/teams/api.py index 31420c3a..32f1a287 100755 --- a/tm_admin/teams/api.py +++ b/tm_admin/teams/api.py @@ -32,7 +32,7 @@ from shapely.geometry import shape from shapely import centroid from tm_admin.types_tm import Mappingtypes, Projectstatus, Taskcreationmode, Editors, Permissions, Projectpriority, Projectdifficulty, Teamroles, Teammemberfunctions -from osm_rawdata.pgasync import PostgresClient +# from osm_rawdata.pgasync import PostgresClient from tm_admin.teams.teams_class import TeamsTable from tm_admin.teams.team_members_class import Team_membersTable from tm_admin.messages.messages import MessagesDB @@ -42,6 +42,7 @@ import re from codetiming import Timer import asyncio +from tm_admin.pgsupport import PGSupport # The number of threads is based on the CPU cores info = get_cpu_info() @@ -50,38 +51,34 @@ # Instantiate logger log = logging.getLogger(__name__) -class TeamsAPI(object): +class TeamsAPI(PGSupport): def __init__(self): """ Create a class to handle the backend API calls, so the code can be shared between test cases and the actual code. Returns: - (TasksAPI): An instance of this class + (TeamsAPI): An instance of this class """ self.allowed_roles = [ Teamroles.TEAM_MAPPER, Teamroles.TEAM_VALIDATOR, Teamroles.TEAM_MANAGER, ] - self.messagesdb = MessagesDB() - self.projectsdb = ProjectsDB() - self.usersdb = UsersDB() - self.teamsdb = TeamsDB() + super().__init__("teams") - async def connect(self, + async def initialize(self, uri: str, ): """ - Connect to all tables for API endpoints that require accessing multiple tables. + Connect to all tables for API endpoints that require + accessing multiple tables. Args: inuri (str): The URI for the TM Admin output database """ - await self.messagesdb.connect(uri) - await self.projectsdb.connect(uri) - await self.usersdb.connect(uri) - await self.teamsdb.connect(uri) + await self.connect(uri) + await self.getTypes("teams") async def getByID(self, team_id: int, @@ -97,7 +94,7 @@ async def getByID(self, """ log.debug(f"--- getByID() ---") sql = f"SELECT * FROM teams WHERE id={team_id}" - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def getByName(self, @@ -114,7 +111,7 @@ async def getByName(self, """ log.debug(f"--- getByName() ---") sql = f"SELECT * FROM teams WHERE name='{name}'" - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def create(self, @@ -129,7 +126,14 @@ async def create(self, Returns: (bool): Whether the team got created """ - log.warning(f"create(): unimplemented!") + # log.warning(f"create(): unimplemented!") + result = await self.insertRecords([team]) + + # The ID of the record that just got inserted is returned + if result: + return True + + return False async def update(self, team: Team_membersTable, @@ -272,7 +276,7 @@ async def isActive(self, """ sql = "SELECT jsonb_path_query(team_members, '$.members[*] ? (@.active==\"true\" && @.user_id==%d)') AS members FROM teams WHERE id=%d;" % (user_id, team_id) print(sql) - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) if len(results) > 0: value = eval(results[0]['members']) @@ -299,7 +303,7 @@ async def checkFunction(self, """ log.warning(f"isManager(): unimplemented!") sql = "SELECT jsonb_path_query(team_members, '$.members[*] ? (@.function==\"%s\" && @.user_id==%d)') AS members FROM teams WHERE id=%d;" % (function.name, user_id, team_id) - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def joinRequest(self, @@ -400,7 +404,7 @@ async def checkMembership(self, projectsdb.getTeamRole(project_id, team_id) # self.allowed_roles sql = f" " - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def getActiveMembers(self, @@ -422,7 +426,7 @@ async def getActiveMembers(self, else: sql = "SELECT jsonb_path_query(team_members, '$.members[*] ? (@.active==\"true\")') AS members FROM teams WHERE id=%d;" % team_id - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def getMembers(self, @@ -447,7 +451,7 @@ async def getMembers(self, # Get just members or managers sql = "SELECT jsonb_path_query(team_members, '$.members[*] ? (@.function[*] == \"%s\")')->'user_id' AS members FROM teams WHERE id=%d;" % (function.name, team_id) - results = await self.teamsdb.pg.execute(sql) + results = await self.execute(sql) return results async def main(): diff --git a/tm_admin/users/api.py b/tm_admin/users/api.py index e8263086..b443f6cc 100755 --- a/tm_admin/users/api.py +++ b/tm_admin/users/api.py @@ -41,7 +41,7 @@ from shapely import wkb, get_coordinates from tm_admin.dbsupport import DBSupport from tm_admin.generator import Generator -from osm_rawdata.pgasync import PostgresClient +from tm_admin.pgsupport import PGSupport import re # from progress import Bar, PixelBar from tqdm import tqdm @@ -56,7 +56,7 @@ # Instantiate logger log = logging.getLogger(__name__) -class UsersAPI(PostgresClient): +class UsersAPI(PGSupport): def __init__(self): self.allowed_roles = [ Teamroles.TEAM_MAPPER, @@ -65,7 +65,23 @@ def __init__(self): ] self.messagesdb = MessagesDB() self.projectsdb = ProjectsDB() - # super().__init__() + super().__init__("users") + + async def initialize(self, + uri: str, + ): + """ + Connect to all tables for API endpoints that require + accessing multiple tables. + + Args: + inuri (str): The URI for the TM Admin output database + """ + await self.connect(uri) + await self.getTypes("users") + #await self.messagesdb.connect(uri) + #await self.usersdb.connect(uri) + #await self.teamsdb.connect(uri) async def create(self, user: UsersTable, @@ -109,46 +125,6 @@ async def delete(self, """ log.warning(f"delete(): unimplemented!") - async def updateColumn(self, - user_id: int, - data: dict, - ): - """ - - Args: - - - Returns: - - """ - log.warning(f"updateColumn(): unimplemented!") - [[column, value]] = data.items() - sql = f"UPDATE users SET {column}='{value}' WHERE id='{user_id}'" - print(sql) - await self.execute(sql) - - return True - - async def appendColumn(self, - user_id: int, - data: dict, - ): - """ - - Args: - - - Returns: - - """ - log.warning(f"appendColumn(): unimplemented!") - [[column, value]] = data.items() - sql = f"UPDATE users SET {column}='{value}' WHERE id='{user_id}'" - print(sql) - await self.execute(sql) - - return True - async def getByID(self, user_id: int, ):