Skip to content

Commit

Permalink
feat: endpoint for submission page count by date (#1051)
Browse files Browse the repository at this point in the history
* created api that returns the submission count by date

* refactored response

* fix: used absolute import

* update submission cache in the background when fetching submission page apis

* feat: added planned submission in the submission page

* returne empty list for no submission

---------

Co-authored-by: sujanadh <[email protected]>
Co-authored-by: Niraj Adhikari <[email protected]>
  • Loading branch information
3 people authored Dec 27, 2023
1 parent 3c30041 commit fcd9855
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 1 deletion.
60 changes: 60 additions & 0 deletions src/backend/app/submission/submission_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
from datetime import datetime
from io import BytesIO
from pathlib import Path
from collections import Counter
from datetime import datetime, timedelta

import sozipfile.sozipfile as zipfile
from asgiref.sync import async_to_sync
Expand Down Expand Up @@ -817,3 +819,61 @@ async def get_submission_count_of_a_project(db: Session, project_id: int):
files.extend(json_data_value)

return len(files)


async def get_submissions_by_date(db: Session, project_id: int, days: int, planned_task: int):
"""
Get submissions by date.
Fetches the submissions for a given project within a specified number of days.
Args:
db (Session): The database session.
project_id (int): The ID of the project.
days (int): The number of days to consider for fetching submissions.
Returns:
dict: A dictionary containing the submission counts for each date.
Examples:
# Fetch submissions for project with ID 1 within the last 7 days
submissions = await get_submissions_by_date(db, 1, 7)
"""

project = await project_crud.get_project(db, project_id)
s3_project_path = f"/{project.organisation_id}/{project_id}"
s3_submission_path = f"/{s3_project_path}/submission.zip"

try:
file = get_obj_from_bucket(settings.S3_BUCKET_NAME, s3_submission_path)
except ValueError as e:
return []

with zipfile.ZipFile(file, "r") as zip_ref:
with zip_ref.open("submissions.json") as file_in_zip:
content = file_in_zip.read()

content = json.loads(content)
end_dates = [datetime.fromisoformat(entry["end"].split('+')[0]) for entry in content if entry.get("end")]

dates = [date.strftime('%m/%d') for date in end_dates if datetime.now() - date <= timedelta(days=days)]

submission_counts = Counter(sorted(dates))

response = [
{"date": key, "count": value}
for key, value in submission_counts.items()
]
if planned_task:
count_dict = {}
cummulative_count = 0
for date, count in submission_counts.items():
cummulative_count += count
count_dict[date] = cummulative_count
response = [
{"date": key, "count": count_dict[key], "planned": planned_task}
for key, value in submission_counts.items()
]

return response

30 changes: 29 additions & 1 deletion src/backend/app/submission/submission_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from app.db import database
from app.projects import project_crud, project_schemas

from . import submission_crud
from app.submission import submission_crud

router = APIRouter(
prefix="/submission",
Expand Down Expand Up @@ -305,3 +305,31 @@ async def get_osm_xml(
# Create a plain XML response
response = Response(content=processed_xml_string, media_type="application/xml")
return response


@router.get("/submission_page/{project_id}")
async def get_submission_page(
project_id: int,
days: int,
background_tasks: BackgroundTasks,
planned_task: Optional[int] = None,
db: Session = Depends(database.get_db),
):
"""
This api returns the submission page of a project.
It takes one parameter: project_id.
project_id: The ID of the project. This endpoint returns the submission page of this project.
"""

data = await submission_crud.get_submissions_by_date(db, project_id, days, planned_task)

# Update submission cache in the background
background_task_id = await project_crud.insert_background_task_into_database(
db, "sync_submission", project_id
)

background_tasks.add_task(
submission_crud.update_submission_in_s3, db, project_id, background_task_id
)

return data

0 comments on commit fcd9855

Please sign in to comment.