diff --git a/backend/api/campaigns/resources.py b/backend/api/campaigns/resources.py index 5efa21b394..498bcc5d07 100644 --- a/backend/api/campaigns/resources.py +++ b/backend/api/campaigns/resources.py @@ -1,5 +1,6 @@ from databases import Database from fastapi import APIRouter, Depends, Request +from fastapi.responses import JSONResponse from backend.db import get_db from backend.models.dtos.campaign_dto import ( @@ -138,13 +139,20 @@ async def update_campaign( raise ValueError("User not a Org Manager") except ValueError as e: error_msg = f"CampaignsRestAPI PATCH: {str(e)}" - return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403 + return JSONResponse( + content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403 + ) try: campaign = await CampaignService.update_campaign(campaign_dto, campaign_id, db) - return {"Success": "Campaign {} updated".format(campaign.id)}, 200 + return JSONResponse( + content={"Success": "Campaign {} updated".format(campaign.id)}, + status_code=200, + ) except ValueError: error_msg = "Campaign PATCH - name already exists" - return {"Error": error_msg, "SubCode": "NameExists"} + return JSONResponse( + content={"Error": error_msg, "SubCode": "NameExists"}, status_code=400 + ) @router.delete("/{campaign_id}/") @@ -200,11 +208,13 @@ async def delete_campaign( raise ValueError("User not a Org Manager") except ValueError as e: error_msg = f"CampaignsRestAPI DELETE: {str(e)}" - return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403 + return JSONResponse( + content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403 + ) campaign = await CampaignService.get_campaign(campaign_id, db) await CampaignService.delete_campaign(campaign.id, db) - return {"Success": "Campaign deleted"}, 200 + return JSONResponse(content={"Success": "Campaign deleted"}, status_code=200) @router.get("/", response_model=CampaignListDTO) @@ -298,10 +308,15 @@ async def create_campaign( raise ValueError("User not a Org Manager") except ValueError as e: error_msg = f"CampaignsAllAPI POST: {str(e)}" - return {"Error": error_msg, "SubCode": "UserNotPermitted"}, 403 + return JSONResponse( + content={"Error": error_msg, "SubCode": "UserNotPermitted"}, status_code=403 + ) try: campaign_id = await CampaignService.create_campaign(campaign_dto, db) - return {"campaignId": campaign_id}, 201 + return JSONResponse(content={"campaignId": campaign_id}, status_code=201) except ValueError as e: - return {"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]}, 409 + return JSONResponse( + content={"Error": str(e).split("-")[1], "SubCode": str(e).split("-")[0]}, + status_code=409, + ) diff --git a/backend/models/postgis/project.py b/backend/models/postgis/project.py index d38a5b5715..14ff1a1713 100644 --- a/backend/models/postgis/project.py +++ b/backend/models/postgis/project.py @@ -685,7 +685,6 @@ async def update(self, project_dto: ProjectDTO, db: Database): new_info = await ProjectInfo.create_from_dto( dto, self.id, db ) # Can't find info so must be new locale - self.project_info.append(new_info) else: await ProjectInfo.update_from_dto(ProjectInfo(**project_info), dto, db) diff --git a/backend/models/postgis/project_info.py b/backend/models/postgis/project_info.py index 42ef511337..e7a04bc95b 100644 --- a/backend/models/postgis/project_info.py +++ b/backend/models/postgis/project_info.py @@ -87,7 +87,10 @@ async def update_from_dto(self, dto: ProjectInfoDTO, db: Database): columns.pop("locale", None) query = ( update(ProjectInfo.__table__) - .where(ProjectInfo.project_id == self.project_id) + .where( + ProjectInfo.project_id == self.project_id, + ProjectInfo.locale == self.locale, + ) .values(**columns) ) result = await db.execute(query) diff --git a/backend/services/messaging/message_service.py b/backend/services/messaging/message_service.py index b199f2a090..9a513430dc 100644 --- a/backend/services/messaging/message_service.py +++ b/backend/services/messaging/message_service.py @@ -235,7 +235,6 @@ async def _push_messages(messages: list, db: Database): if (i + 1) % 10 == 0: time.sleep(0.5) - # TODO Explore better approach. if messages_objs: insert_values = [ { @@ -461,14 +460,13 @@ async def send_request_to_join_team( message.message_type = MessageType.REQUEST_TEAM_NOTIFICATION.value message.from_user_id = from_user message.to_user_id = to_user - message.date = timestamp() - message.read = False user_link = MessageService.get_user_link(from_username) team_link = MessageService.get_team_link(team_name, team_id, True) message.subject = f"{user_link} requested to join {team_link}" message.message = f"{user_link} has requested to join the {team_link} team.\ Access the team management page to accept or reject that request." - await Message.save(message, db) + user = await UserService.get_user_by_id(to_user, db) + await MessageService._push_messages([dict(message=message, user=user)], db) @staticmethod async def accept_reject_request_to_join_team( @@ -492,7 +490,8 @@ async def accept_reject_request_to_join_team( message.message = ( f"{user_link} has {response}ed your request to join the {team_link} team." ) - await Message.save(message, db) + user = await UserService.get_user_by_id(to_user, db) + await MessageService._push_messages([dict(message=message, user=user)], db) @staticmethod async def accept_reject_invitation_request_for_team( @@ -522,7 +521,8 @@ async def accept_reject_invitation_request_for_team( sending_member, MessageService.get_team_link(team_name, team_id, True), ) - await Message.save(message, db) + user = await UserService.get_user_by_id(to_user, db) + await MessageService._push_messages([dict(message=message, user=user)], db) @staticmethod async def send_team_join_notification( @@ -545,8 +545,8 @@ async def send_team_join_notification( Access the {team_link}'s page to view more info about this team." message.date = timestamp() message.read = False - - await Message.save(message, db) + user = await UserService.get_user_by_id(to_user, db) + await MessageService._push_messages([dict(message=message, user=user)], db) @staticmethod async def send_message_after_chat( diff --git a/backend/services/stats_service.py b/backend/services/stats_service.py index a85e7091a7..feb3cc7b44 100644 --- a/backend/services/stats_service.py +++ b/backend/services/stats_service.py @@ -748,7 +748,7 @@ async def get_task_stats( if org_id: filters.append("AND organisation_id = :org_id") - values["org_id"] = org_id + values["org_id"] = int(org_id) if org_name: filters.append(""" diff --git a/backend/services/team_service.py b/backend/services/team_service.py index 7ee5985480..2e5205020e 100644 --- a/backend/services/team_service.py +++ b/backend/services/team_service.py @@ -3,6 +3,7 @@ from loguru import logger from markdown import markdown +from backend.db import db_connection from backend.exceptions import NotFound from backend.models.dtos.message_dto import MessageDTO from backend.models.dtos.stats_dto import Pagination @@ -28,7 +29,6 @@ from backend.services.messaging.message_service import MessageService from backend.services.organisation_service import OrganisationService from backend.services.users.user_service import UserService -from backend.db import db_connection class TeamServiceError(Exception): @@ -812,7 +812,6 @@ async def send_message_to_all_team_members( team_member.user_id, conn ) messages.append(dict(message=message, user=user)) - # Push messages await MessageService._push_messages(messages, conn) logger.info("Messages sent successfully.") except Exception as e: diff --git a/scripts/locust/locustfile.py b/scripts/locust/locustfile.py index 7b95be3f3f..151a887c59 100644 --- a/scripts/locust/locustfile.py +++ b/scripts/locust/locustfile.py @@ -1,6 +1,15 @@ import os from locust import HttpUser, TaskSet, task, between +# Define tokens for Flask and FastAPI +FASTAPI_TOKEN = "TVRBeU5UQTBOVFkuWjJVOWNnLmtBNUZUcDZaMkpYVGJ2QnhFN29mb3lqZXZlSQ==" +FLASK_TOKEN = "TVRBeU5UQTBOVFkuWjJVeDV3LmtDTHhCbFdQR2ROZTEzYzJORWRVblp4akFCMA==" + +LOCUST_HOST = os.getenv("LOCUST_HOST", "https://tm.naxa.com.np") + + +AUTH_TOKEN = FASTAPI_TOKEN if "tm-fastapi.naxa.com.np" in LOCUST_HOST else FLASK_TOKEN + class ProjectAndComments(TaskSet): @task def get_project(self): @@ -12,8 +21,18 @@ def get_comments(self): class ProjectList(TaskSet): @task - def get_project(self): - self.client.get("/api/v2/projects/") + def project_list(self): + self.client.get("/api/v2/projects/?action=any&omitMapResults=true", headers={"Authorization": f"Token {AUTH_TOKEN}"}) + +class TaskStatistics(TaskSet): + @task + def get_contributions(self): + self.client.get("/api/v2/tasks/statistics/?startDate=2024-01-01", headers={"Authorization": f"Token {AUTH_TOKEN}"}) + +class TaskPage(TaskSet): + @task + def get_tasks(self): + self.client.get("/api/v2/projects/114/tasks/", headers={"Authorization": f"Token {AUTH_TOKEN}"}) class GetSimilarProjects(TaskSet): @task @@ -43,6 +62,9 @@ def get_action_any(self): # Mapping task names to classes task_mapping = { "project_and_comments": ProjectAndComments, + "project_list": ProjectList, + "task_statistics": TaskStatistics, + "task_page": TaskPage, "similar_projects": GetSimilarProjects, "contributions": GetContributions, "contributions_by_day": GetContributionsByDay, @@ -57,9 +79,8 @@ class ApiBenchmarkUser(HttpUser): # Dynamically select tasks based on environment variable or CLI parameter def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - task_name = os.getenv("TASK_SET", "get_contributions").lower() - print(task_name, "The task name....") - self.tasks = [task_mapping.get(task_name, GetContributions)] + task_name = os.getenv("TASK_SET", "project_list").lower() + self.tasks = [task_mapping.get(task_name, TaskPage)] '''