Skip to content

Commit

Permalink
Project patch fixed and dtos refactored
Browse files Browse the repository at this point in the history
  • Loading branch information
prabinoid committed Oct 22, 2024
1 parent 093e0ed commit c5896d1
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 205 deletions.
5 changes: 3 additions & 2 deletions backend/api/projects/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,9 @@ async def patch(
project_dto.project_id = project_id

try:
await ProjectAdminService.update_project(project_dto, user.id, db)
return JSONResponse(content={"Status": "Updated"}, status_code=200)
async with db.transaction():
await ProjectAdminService.update_project(project_dto, user.id, db)
return JSONResponse(content={"Status": "Updated"}, status_code=200)
except InvalidGeoJson as e:
return JSONResponse(content={"Invalid GeoJson": str(e)}, status_code=400)
except ProjectAdminServiceError as e:
Expand Down
7 changes: 4 additions & 3 deletions backend/models/dtos/campaign_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ class CampaignDTO(BaseModel):
logo: Optional[str] = None
url: Optional[str] = None
description: Optional[str] = None
organisations: List[OrganisationDTO] = Field(
default=None, serialization_alias="organisations"
)
organisations: List[OrganisationDTO] = Field(default=None, alias="organisations")

class Config:
populate_by_name = True


class CampaignProjectDTO(BaseModel):
Expand Down
9 changes: 6 additions & 3 deletions backend/models/dtos/interests_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,18 @@ class InterestDTO(BaseModel):
id: Optional[int] = None
name: Optional[str] = Field(default=None, min_length=1)
user_selected: Optional[bool] = Field(
serialization_alias="userSelected", default=None, none_if_default=True
alias="userSelected", default=None, none_if_default=True
)
count_projects: Optional[int] = Field(
serialize=False, serialization_alias="countProjects", default=None
serialize=False, alias="countProjects", default=None
)
count_users: Optional[int] = Field(
serialize=False, serialization_alias="countUsers", default=None
serialize=False, alias="countUsers", default=None
)

class Config:
populate_by_name = True


class ListInterestDTO(BaseModel):
id: Optional[int] = None
Expand Down
22 changes: 10 additions & 12 deletions backend/models/dtos/message_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,16 @@
class MessageDTO(BaseModel):
"""DTO used to define a message that will be sent to a user"""

message_id: int = Field(None, serialization_alias="message_id")
subject: str = Field(None, serialization_alias="subject")
message: str = Field(None, serialization_alias="message")
from_username: Optional[str] = Field("", serialization_alias="fromUsername")
display_picture_url: Optional[str] = Field(
"", serialization_alias="displayPictureUrl"
)
project_id: Optional[int] = Field(None, serialization_alias="projectId")
project_title: Optional[str] = Field(None, serialization_alias="projectTitle")
task_id: Optional[int] = Field(None, serialization_alias="taskId")
message_type: Optional[str] = Field(None, serialization_alias="message_type")
sent_date: datetime = Field(None, serialization_alias="sentDate")
message_id: int = Field(None, alias="message_id")
subject: str = Field(None, alias="subject")
message: str = Field(None, alias="message")
from_username: Optional[str] = Field("", alias="fromUsername")
display_picture_url: Optional[str] = Field("", alias="displayPictureUrl")
project_id: Optional[int] = Field(None, alias="projectId")
project_title: Optional[str] = Field(None, alias="projectTitle")
task_id: Optional[int] = Field(None, alias="taskId")
message_type: Optional[str] = Field(None, alias="message_type")
sent_date: datetime = Field(None, alias="sentDate")
read: bool = False

class Config:
Expand Down
37 changes: 24 additions & 13 deletions backend/models/dtos/organisation_dto.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,42 @@ def is_known_organisation_type(value):

class OrganisationManagerDTO(BaseModel):
username: Optional[str] = None
picture_url: Optional[str] = Field(None, serialization_alias="pictureUrl")
picture_url: Optional[str] = Field(None, alias="pictureUrl")

class Config:
populate_by_name = True


class OrganisationTeamsDTO(BaseModel):
team_id: Optional[int] = Field(None, serialization_alias="teamId")
team_id: Optional[int] = Field(None, alias="teamId")
name: Optional[str] = None
description: Optional[str] = None
join_method: Optional[str] = Field(None, serialization_alias="joinMethod")
join_method: Optional[str] = Field(None, alias="joinMethod")
visibility: Optional[str] = None
members: List[Dict[str, Optional[str]]] = Field(default=[])

class Config:
populate_by_name = True


class OrganisationDTO(BaseModel):
organisation_id: Optional[int] = Field(None, serialization_alias="organisationId")
organisation_id: Optional[int] = Field(None, alias="organisationId")
managers: Optional[List[OrganisationManagerDTO]] = None
name: Optional[str] = None
slug: Optional[str] = None
logo: Optional[str] = None
description: Optional[str] = None
url: Optional[str] = None
is_manager: Optional[bool] = Field(None, serialization_alias="isManager")
is_manager: Optional[bool] = Field(None, alias="isManager")
projects: Optional[List[str]] = Field(default=[], alias="projects")
teams: List[OrganisationTeamsDTO] = None
campaigns: Optional[List[List[str]]] = None
stats: Optional[OrganizationStatsDTO] = None
type: Optional[str] = Field(None)
subscription_tier: Optional[int] = Field(
None, serialization_alias="subscriptionTier"
)
subscription_tier: Optional[int] = Field(None, alias="subscriptionTier")

class Config:
populate_by_name = True

@field_validator("type", mode="before")
def validate_type(cls, value):
Expand All @@ -67,17 +74,18 @@ def __init__(self):
class NewOrganisationDTO(BaseModel):
"""Describes a JSON model to create a new organisation"""

organisation_id: Optional[int] = Field(None, serialization_alias="organisationId")
organisation_id: Optional[int] = Field(None, alias="organisationId")
managers: List[str]
name: str
slug: Optional[str] = None
logo: Optional[str] = None
description: Optional[str] = None
url: Optional[str] = None
type: str
subscription_tier: Optional[int] = Field(
None, serialization_alias="subscriptionTier"
)
subscription_tier: Optional[int] = Field(None, alias="subscriptionTier")

class Config:
populate_by_name = True

@field_validator("type", mode="before")
@classmethod
Expand All @@ -94,7 +102,7 @@ def validate_type(cls, value: Optional[str]) -> Optional[str]:


class UpdateOrganisationDTO(OrganisationDTO):
organisation_id: Optional[int] = Field(None, serialization_alias="organisationId")
organisation_id: Optional[int] = Field(None, alias="organisationId")
managers: List[str] = Field(default=[])
name: Optional[str] = None
slug: Optional[str] = None
Expand All @@ -103,6 +111,9 @@ class UpdateOrganisationDTO(OrganisationDTO):
url: Optional[str] = None
type: Optional[str] = None

class Config:
populate_by_name = True

@field_validator("type", mode="before")
@classmethod
def validate_type(cls, value: Optional[str]) -> Optional[str]:
Expand Down
152 changes: 64 additions & 88 deletions backend/models/dtos/project_dto.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
# from schematics import Model
# from schematics.exceptions import ValidationError
from backend.models.dtos.task_annotation_dto import TaskAnnotationDTO
from datetime import date, datetime
from typing import Dict, List, Optional, Union

from fastapi import HTTPException
from pydantic import BaseModel, Field

from backend.models.dtos.campaign_dto import CampaignDTO
from backend.models.dtos.interests_dto import InterestDTO
from backend.models.dtos.stats_dto import Pagination
from backend.models.dtos.task_annotation_dto import TaskAnnotationDTO
from backend.models.dtos.team_dto import ProjectTeamDTO
from backend.models.dtos.interests_dto import InterestDTO
from backend.models.postgis.statuses import (
ProjectStatus,
ProjectPriority,
MappingTypes,
TaskCreationMode,
Editors,
MappingPermission,
ValidationPermission,
MappingTypes,
ProjectDifficulty,
ProjectPriority,
ProjectStatus,
TaskCreationMode,
ValidationPermission,
)
from backend.models.dtos.campaign_dto import CampaignDTO
from pydantic import BaseModel, Field
from typing import Dict, List, Optional, Union
from datetime import datetime
from datetime import date
from fastapi import HTTPException


def is_known_project_status(value: str) -> str:
Expand Down Expand Up @@ -178,6 +179,9 @@ class DraftProjectDTO(BaseModel):
has_arbitrary_tasks: bool = Field(False, alias="arbitraryTasks")
user_id: int = Field(None)

class Config:
populate_by_name = True


class ProjectInfoDTO(BaseModel):
"""Contains the localized project info"""
Expand Down Expand Up @@ -241,7 +245,7 @@ class ProjectDTO(BaseModel):
country_tag: Optional[List[str]] = Field(None, alias="countryTag")
license_id: Optional[int] = Field(None, alias="licenseId")
allowed_usernames: Optional[List[str]] = Field(default=[], alias="allowedUsernames")
priority_areas: Optional[Dict] = Field(None, alias="priorityAreas")
priority_areas: Optional[List[Dict]] = Field(None, alias="priorityAreas")
created: Optional[datetime] = None
last_updated: Optional[datetime] = Field(None, alias="lastUpdated")
author: Optional[str] = None
Expand Down Expand Up @@ -407,9 +411,10 @@ class ProjectSearchBBoxDTO(BaseModel):
bbox: List[float] = Field(..., min_items=4, max_items=4)
input_srid: int = Field(..., choices=[4326])
preferred_locale: Optional[str] = Field(default="en")
project_author: Optional[int] = Field(
default=None, serialization_alias="projectAuthor"
)
project_author: Optional[int] = Field(default=None, alias="projectAuthor")

class Config:
populate_by_name = True


class ListSearchResultDTO(BaseModel):
Expand All @@ -431,6 +436,9 @@ class ListSearchResultDTO(BaseModel):
total_contributors: Optional[int] = Field(alias="totalContributors", default=None)
country: Optional[str] = Field(default="", serialize=False)

class Config:
populate_by_name = True


# class ProjectSearchResultsDTO(BaseModel):
# map_results: Optional[List] = []
Expand Down Expand Up @@ -468,6 +476,9 @@ class ProjectComment(BaseModel):
user_name: str = Field(alias="userName")
task_id: int = Field(alias="taskId")

class Config:
populate_by_name = True


class ProjectCommentsDTO(BaseModel):
"""Contains all comments on a project"""
Expand Down Expand Up @@ -496,85 +507,50 @@ class ProjectContribsDTO(BaseModel):


class ProjectSummary(BaseModel):
project_id: int = Field(..., serialization_alias="projectId")
default_locale: Optional[str] = Field(None, serialization_alias="defaultLocale")
project_id: int = Field(..., alias="projectId")
default_locale: Optional[str] = Field(None, alias="defaultLocale")
author: Optional[str] = None
created: Optional[datetime] = None
due_date: Optional[datetime] = Field(None, serialization_alias="dueDate")
last_updated: Optional[datetime] = Field(None, serialization_alias="lastUpdated")
priority: Optional[str] = Field(None, serialization_alias="projectPriority")
due_date: Optional[datetime] = Field(None, alias="dueDate")
last_updated: Optional[datetime] = Field(None, alias="lastUpdated")
priority: Optional[str] = Field(None, alias="projectPriority")
campaigns: List[CampaignDTO] = Field(default_factory=list)
organisation: Optional[int] = None
organisation_name: Optional[str] = Field(
None, serialization_alias="organisationName"
)
organisation_slug: Optional[str] = Field(
None, serialization_alias="organisationSlug"
)
organisation_logo: Optional[str] = Field(
None, serialization_alias="organisationLogo"
)
country_tag: List[str] = Field(
default_factory=list, serialization_alias="countryTag"
)
osmcha_filter_id: Optional[str] = Field(None, serialization_alias="osmchaFilterId")
mapping_types: List[str] = Field(
default_factory=list, serialization_alias="mappingTypes"
)
changeset_comment: Optional[str] = Field(
None, serialization_alias="changesetComment"
)
percent_mapped: Optional[int] = Field(None, serialization_alias="percentMapped")
percent_validated: Optional[int] = Field(
None, serialization_alias="percentValidated"
)
percent_bad_imagery: Optional[int] = Field(
None, serialization_alias="percentBadImagery"
)
aoi_centroid: Optional[Union[dict, None]] = Field(
None, serialization_alias="aoiCentroid"
)
difficulty: Optional[str] = Field(None, serialization_alias="difficulty")
mapping_permission: Optional[int] = Field(
None, serialization_alias="mappingPermission"
)
validation_permission: Optional[int] = Field(
None, serialization_alias="validationPermission"
)
allowed_usernames: List[str] = Field(
default_factory=list, serialization_alias="allowedUsernames"
)
organisation_name: Optional[str] = Field(None, alias="organisationName")
organisation_slug: Optional[str] = Field(None, alias="organisationSlug")
organisation_logo: Optional[str] = Field(None, alias="organisationLogo")
country_tag: List[str] = Field(default_factory=list, alias="countryTag")
osmcha_filter_id: Optional[str] = Field(None, alias="osmchaFilterId")
mapping_types: List[str] = Field(default_factory=list, alias="mappingTypes")
changeset_comment: Optional[str] = Field(None, alias="changesetComment")
percent_mapped: Optional[int] = Field(None, alias="percentMapped")
percent_validated: Optional[int] = Field(None, alias="percentValidated")
percent_bad_imagery: Optional[int] = Field(None, alias="percentBadImagery")
aoi_centroid: Optional[Union[dict, None]] = Field(None, alias="aoiCentroid")
difficulty: Optional[str] = Field(None, alias="difficulty")
mapping_permission: Optional[int] = Field(None, alias="mappingPermission")
validation_permission: Optional[int] = Field(None, alias="validationPermission")
allowed_usernames: List[str] = Field(default_factory=list, alias="allowedUsernames")
random_task_selection_enforced: bool = Field(
default=False, serialization_alias="enforceRandomTaskSelection"
)
private: Optional[bool] = Field(None, serialization_alias="private")
allowed_users: List[str] = Field(
default_factory=list, serialization_alias="allowedUsernames"
)
project_teams: List[ProjectTeamDTO] = Field(
default_factory=list, serialization_alias="teams"
)
project_info: Optional[ProjectInfoDTO] = Field(
None, serialization_alias="projectInfo"
)
short_description: Optional[str] = Field(
None, serialization_alias="shortDescription"
default=False, alias="enforceRandomTaskSelection"
)
private: Optional[bool] = Field(None, alias="private")
allowed_users: List[str] = Field(default_factory=list, alias="allowedUsernames")
project_teams: List[ProjectTeamDTO] = Field(default_factory=list, alias="teams")
project_info: Optional[ProjectInfoDTO] = Field(None, alias="projectInfo")
short_description: Optional[str] = Field(None, alias="shortDescription")
status: Optional[str] = None
imagery: Optional[str] = None
license_id: Optional[int] = Field(None, serialization_alias="licenseId")
id_presets: List[str] = Field(default_factory=list, serialization_alias="idPresets")
extra_id_params: Optional[str] = Field(None, serialization_alias="extraIdParams")
rapid_power_user: bool = Field(default=False, serialization_alias="rapidPowerUser")
mapping_editors: List[str] = Field(
..., min_items=1, serialization_alias="mappingEditors"
)
validation_editors: List[str] = Field(
..., min_items=1, serialization_alias="validationEditors"
)
custom_editor: Optional[CustomEditorDTO] = Field(
None, serialization_alias="customEditor"
)
license_id: Optional[int] = Field(None, alias="licenseId")
id_presets: List[str] = Field(default_factory=list, alias="idPresets")
extra_id_params: Optional[str] = Field(None, alias="extraIdParams")
rapid_power_user: bool = Field(default=False, alias="rapidPowerUser")
mapping_editors: List[str] = Field(..., min_items=1, alias="mappingEditors")
validation_editors: List[str] = Field(..., min_items=1, alias="validationEditors")
custom_editor: Optional[CustomEditorDTO] = Field(None, alias="customEditor")

class Config:
populate_by_name = True

# TODO: Make Validators work.

Expand Down
Loading

0 comments on commit c5896d1

Please sign in to comment.