backend/models/dtos/user_dto.py (175 lines of code) (raw):

from schematics import Model from schematics.exceptions import ValidationError from schematics.types import ( StringType, IntType, EmailType, LongType, BooleanType, ) from schematics.types.compound import ListType, ModelType, BaseType from backend.models.dtos.stats_dto import Pagination from backend.models.dtos.mapping_dto import TaskDTO from backend.models.dtos.interests_dto import InterestDTO from backend.models.postgis.statuses import MappingLevel, UserRole def is_known_mapping_level(value): """ Validates that supplied mapping level is known value """ if value.upper() == "ALL": return True try: value = value.split(",") for level in value: MappingLevel[level.upper()] except KeyError: raise ValidationError( f"Unknown mappingLevel: {value} Valid values are {MappingLevel.BEGINNER.name}, " f"{MappingLevel.INTERMEDIATE.name}, {MappingLevel.ADVANCED.name}, ALL" ) def is_known_role(value): """ Validates that supplied user role is known value """ try: value = value.split(",") for role in value: UserRole[role.upper()] except KeyError: raise ValidationError( f"Unknown mappingRole: {value} Valid values are {UserRole.ADMIN.name}, " f"{UserRole.READ_ONLY.name}, {UserRole.MAPPER.name}" ) class UserDTO(Model): """ DTO for User """ id = LongType() username = StringType() role = StringType() mapping_level = StringType( serialized_name="mappingLevel", validators=[is_known_mapping_level] ) projects_mapped = IntType(serialized_name="projectsMapped") email_address = EmailType(serialized_name="emailAddress") is_email_verified = EmailType( serialized_name="isEmailVerified", serialize_when_none=False ) is_expert = BooleanType(serialized_name="isExpert", serialize_when_none=False) twitter_id = StringType(serialized_name="twitterId") facebook_id = StringType(serialized_name="facebookId") linkedin_id = StringType(serialized_name="linkedinId") slack_id = StringType(serialized_name="slackId") irc_id = StringType(serialized_name="ircId") skype_id = StringType(serialized_name="skypeId") city = StringType(serialized_name="city") country = StringType(serialized_name="country") name = StringType(serialized_name="name") picture_url = StringType(serialized_name="pictureUrl") default_editor = StringType(serialized_name="defaultEditor") mentions_notifications = BooleanType(serialized_name="mentionsNotifications") comments_notifications = BooleanType(serialized_name="commentsNotifications") projects_notifications = BooleanType(serialized_name="projectsNotifications") tasks_notifications = BooleanType(serialized_name="tasksNotifications") teams_notifications = BooleanType(serialized_name="teamsNotifications") # these are read only gender = StringType( serialized_name="gender", choices=("MALE", "FEMALE", "SELF_DESCRIBE", "PREFER_NOT"), ) self_description_gender = StringType( serialized_name="selfDescriptionGender", default=None ) def validate_self_description(self, data, value): if ( data["gender"] == "SELF_DESCRIBE" and data["self_description_gender"] is None ): raise ValueError("selfDescription field is not defined") return value class UserCountryContributed(Model): """ DTO for country a user has contributed """ name = StringType(required=True) mapped = IntType(required=True) validated = IntType(required=True) total = IntType(required=True) class UserCountriesContributed(Model): """ DTO for countries a user has contributed """ def __init__(self): super().__init__() self.countries_contributed = [] countries_contributed = ListType( ModelType(UserCountryContributed), serialized_name="countries" ) total = IntType() class UserContributionDTO(Model): date = StringType() count = IntType() class UserStatsDTO(Model): """ DTO containing statistics about the user """ total_time_spent = IntType(serialized_name="totalTimeSpent") time_spent_mapping = IntType(serialized_name="timeSpentMapping") time_spent_validating = IntType(serialized_name="timeSpentValidating") projects_mapped = IntType(serialized_name="projectsMapped") countries_contributed = ModelType( UserCountriesContributed, serialized_name="countriesContributed" ) contributions_by_day = ListType( ModelType(UserContributionDTO), serialized_name="contributionsByDay" ) tasks_mapped = IntType(serialized_name="tasksMapped") tasks_validated = IntType(serialized_name="tasksValidated") tasks_invalidated = IntType(serialized_name="tasksInvalidated") tasks_invalidated_by_others = IntType(serialized_name="tasksInvalidatedByOthers") tasks_validated_by_others = IntType(serialized_name="tasksValidatedByOthers") contributions_interest = ListType( ModelType(InterestDTO), serialized_name="ContributionsByInterest" ) class UserOSMDTO(Model): """ DTO containing OSM details for the user """ account_created = StringType(required=True, serialized_name="accountCreated") changeset_count = IntType(required=True, serialized_name="changesetCount") class MappedProject(Model): """ Describes a single project a user has mapped """ project_id = IntType(serialized_name="projectId") name = StringType() tasks_mapped = IntType(serialized_name="tasksMapped") tasks_validated = IntType(serialized_name="tasksValidated") status = StringType() centroid = BaseType() class UserMappedProjectsDTO(Model): """ DTO for projects a user has mapped """ def __init__(self): super().__init__() self.mapped_projects = [] mapped_projects = ListType( ModelType(MappedProject), serialized_name="mappedProjects" ) class UserSearchQuery(Model): """ Describes a user search query, that a user may submit to filter the list of users """ username = StringType() role = StringType(validators=[is_known_role]) mapping_level = StringType( serialized_name="mappingLevel", validators=[is_known_mapping_level] ) page = IntType() def __hash__(self): """ Make object hashable so we can cache user searches""" return hash((self.username, self.role, self.mapping_level, self.page)) class ListedUser(Model): """ Describes a user within the User List """ id = LongType() username = StringType() role = StringType() mapping_level = StringType(serialized_name="mappingLevel") picture_url = StringType(serialized_name="pictureUrl") class UserRegisterEmailDTO(Model): """ DTO containing data for user registration with email model """ id = IntType(serialize_when_none=False) email = StringType(required=True) success = BooleanType(default=False) details = StringType() class ProjectParticipantUser(Model): """ Describes a user who has participated in a project """ username = StringType() project_id = LongType(serialized_name="projectId") is_participant = BooleanType(serialized_name="isParticipant") class UserSearchDTO(Model): """ Paginated list of TM users """ def __init__(self): super().__init__() self.users = [] pagination = ModelType(Pagination) users = ListType(ModelType(ListedUser)) class UserFilterDTO(Model): """ DTO to hold all Tasking Manager users """ def __init__(self): super().__init__() self.usernames = [] self.users = [] pagination = ModelType(Pagination) usernames = ListType(StringType) users = ListType(ModelType(ProjectParticipantUser)) class UserTaskDTOs(Model): """ Describes an array of Task DTOs""" def __init__(self): """ DTO constructor initialise all arrays to empty""" super().__init__() self.user_tasks = [] user_tasks = ListType(ModelType(TaskDTO), serialized_name="tasks") pagination = ModelType(Pagination)