class MilestoneSerializer(WatchedResourceSerializer, ProjectExtraInfoSerializerMixin, serializers.LightSerializer): id = Field() name = Field() slug = Field() owner = Field(attr="owner_id") project = Field(attr="project_id") estimated_start = Field() estimated_finish = Field() created_date = Field() modified_date = Field() closed = Field() disponibility = Field() order = Field() watchers = Field() user_stories = MethodField() total_points = MethodField() closed_points = MethodField() def get_user_stories(self, obj): qs = obj.user_stories.all() qs = qs.prefetch_related("assigned_users") return UserStoryListSerializer(qs, many=True).data def get_total_points(self, obj): assert hasattr(obj, "total_points_attr"), "instance must have a total_points_attr attribute" return obj.total_points_attr def get_closed_points(self, obj): assert hasattr(obj, "closed_points_attr"), "instance must have a closed_points_attr attribute" return obj.closed_points_attr
class TaskListSerializer( VoteResourceSerializerMixin, WatchedResourceSerializer, OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin, StatusExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin, TaggedInProjectResourceSerializer, serializers.LightSerializer): id = Field() user_story = Field(attr="user_story_id") ref = Field() project = Field(attr="project_id") milestone = Field(attr="milestone_id") milestone_slug = MethodField() created_date = Field() modified_date = Field() finished_date = Field() subject = Field() us_order = Field() taskboard_order = Field() is_iocaine = Field() external_reference = Field() version = Field() watchers = Field() is_blocked = Field() blocked_note = Field() is_closed = MethodField() def get_milestone_slug(self, obj): return obj.milestone.slug if obj.milestone else None def get_is_closed(self, obj): return obj.status is not None and obj.status.is_closed
class UserSerializer(serializers.LightSerializer): id = Field() username = Field() full_name = Field() full_name_display = MethodField() color = Field() bio = Field() lang = Field() theme = Field() timezone = Field() is_active = Field() photo = MethodField() big_photo = MethodField() gravatar_id = MethodField() roles = MethodField() def get_full_name_display(self, obj): return obj.get_full_name() if obj else "" def get_photo(self, user): return get_user_photo_url(user) def get_big_photo(self, user): return get_user_big_photo_url(user) def get_gravatar_id(self, user): return get_user_gravatar_id(user) def get_roles(self, user): if hasattr(user, "roles_attr"): return user.roles_attr return user.memberships.order_by("role__name").values_list("role__name", flat=True).distinct()
class WikiPageSerializer( WatchedResourceSerializer, ProjectExtraInfoSerializerMixin, serializers.LightSerializer, ): id = Field() project = Field(attr="project_id") slug = Field() content = Field() owner = Field(attr="owner_id") last_modifier = Field(attr="last_modifier_id") created_date = Field() modified_date = Field() html = MethodField() editions = MethodField() version = Field() def get_html(self, obj): return mdrender(obj.project, obj.content) def get_editions(self, obj): return (history_service.get_history_queryset_by_model_instance( obj).count() + 1) # +1 for creation
class UserBasicInfoSerializer(serializers.LightSerializer): username = Field() full_name_display = MethodField() photo = MethodField() big_photo = MethodField() gravatar_id = MethodField() is_active = Field() id = Field() def get_full_name_display(self, obj): return obj.get_full_name() def get_photo(self, obj): return get_user_photo_url(obj) def get_big_photo(self, obj): return get_user_big_photo_url(obj) def get_gravatar_id(self, obj): return get_user_gravatar_id(obj) def to_value(self, instance): if instance is None: return None return super().to_value(instance)
class MembershipSerializer(serializers.LightSerializer): id = Field() user = Field(attr="user_id") project = Field(attr="project_id") role = Field(attr="role_id") is_admin = Field() created_at = Field() invited_by = Field(attr="invited_by_id") invitation_extra_text = Field() user_order = Field() role_name = MethodField() full_name = MethodField() is_user_active = MethodField() color = MethodField() photo = MethodField() gravatar_id = MethodField() project_name = MethodField() project_slug = MethodField() invited_by = UserBasicInfoSerializer() is_owner = MethodField() gamification_points = MethodField() def get_gamification_points(self, obj): if getattr(obj, 'user_id') is not None: current_user = User.objects.get(pk=getattr(obj, 'user_id')) project_id = str(getattr(obj.project, 'id')) if getattr(current_user, 'projects_activity'): points = getattr(current_user, 'projects_activity')[project_id]['points'] return points return None else: return None def get_role_name(self, obj): return obj.role.name if obj.role else None def get_full_name(self, obj): return obj.user.get_full_name() if obj.user else None def get_is_user_active(self, obj): return obj.user.is_active if obj.user else False def get_color(self, obj): return obj.user.color if obj.user else None def get_photo(self, obj): return get_user_photo_url(obj.user) def get_gravatar_id(self, obj): return get_user_gravatar_id(obj.user) def get_project_name(self, obj): return obj.project.name if obj and obj.project else "" def get_project_slug(self, obj): return obj.project.slug if obj and obj.project else "" def get_is_owner(self, obj): return (obj and obj.user_id and obj.project_id and obj.project.owner_id and obj.user_id == obj.project.owner_id)
class AttachmentSerializer(serializers.LightSerializer): id = Field() project = Field(attr="project_id") owner = Field(attr="owner_id") name = Field() attached_file = FileField() size = Field() url = Field() description = Field() is_deprecated = Field() from_comment = Field() created_date = Field() modified_date = Field() object_id = Field() order = Field() sha1 = Field() url = MethodField("get_url") thumbnail_card_url = MethodField("get_thumbnail_card_url") preview_url = MethodField("get_preview_url") def get_url(self, obj): return obj.attached_file.url def get_thumbnail_card_url(self, obj): return services.get_card_image_thumbnail_url(obj) def get_preview_url(self, obj): if obj.name.endswith(".psd"): return services.get_attachment_image_preview_url(obj) return self.get_url(obj)
class UserSerializer(serializers.LightSerializer): id = Field(attr="pk") permalink = MethodField() username = MethodField() full_name = MethodField() photo = MethodField() gravatar_id = MethodField() def get_permalink(self, obj): return resolve_front_url("user", obj.username) def get_username(self, obj): return obj.get_username() def get_full_name(self, obj): return obj.get_full_name() def get_photo(self, obj): return get_user_photo_url(obj) def get_gravatar_id(self, obj): return get_user_gravatar_id(obj) def to_value(self, instance): if instance is None: return None return super().to_value(instance)
class EpicListSerializer( VoteResourceSerializerMixin, WatchedResourceSerializer, OwnerExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin, StatusExtraInfoSerializerMixin, ProjectExtraInfoSerializerMixin, BasicAttachmentsInfoSerializerMixin, TaggedInProjectResourceSerializer, serializers.LightSerializer): id = Field() ref = Field() project = Field(attr="project_id") created_date = Field() modified_date = Field() subject = Field() color = Field() epics_order = Field() client_requirement = Field() team_requirement = Field() version = Field() watchers = Field() is_blocked = Field() blocked_note = Field() is_closed = MethodField() user_stories_counts = MethodField() def get_is_closed(self, obj): return obj.status is not None and obj.status.is_closed def get_user_stories_counts(self, obj): assert hasattr(obj, "user_stories_counts" ), "instance must have a user_stories_counts attribute" return obj.user_stories_counts
class MilestoneSerializer(ProjectExtraInfoSerializerMixin, serializers.LightSerializer): id = Field() name = Field() slug = Field() owner = Field(attr="owner_id") project = Field(attr="project_id") estimated_start = Field() estimated_finish = Field() created_date = Field() modified_date = Field() closed = Field() disponibility = Field() order = Field() user_stories = MethodField() total_points = MethodField() closed_points = MethodField() def get_user_stories(self, obj): return UserStoryNestedSerializer(obj.user_stories.all(), many=True).data def get_total_points(self, obj): assert hasattr(obj, "total_points_attr" ), "instance must have a total_points_attr attribute" return obj.total_points_attr def get_closed_points(self, obj): assert hasattr(obj, "closed_points_attr" ), "instance must have a closed_points_attr attribute" return obj.closed_points_attr
class EpicSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() subject = Field() watchers = MethodField() description = Field() tags = Field() permalink = MethodField() project = ProjectSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = EpicStatusSerializer() epics_order = Field() color = Field() client_requirement = Field() team_requirement = Field() client_requirement = Field() team_requirement = Field() def get_permalink(self, obj): return resolve_front_url("epic", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.epiccustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class DashboardSerializer(serializers.LightSerializer): issues_identified = MethodField() issue_closed = MethodField() accidents_report = MethodField() user_count = MethodField() def get_user_count(self, obj): user_count = 0 if obj.is_superuser: user_count = User.objects.all().count() else: projects = Project.objects.filter(members__in=[obj.id]) for project in projects: user_count = user_count + project.members.count() return user_count def get_issues_identified(self, obj): issues_identified_count = 0 if obj.is_superuser: issues_identified_count = Issue.objects.filter( type__name='Issue').count() else: projects = Project.objects.filter(members=obj.id) for project in projects: issues_identified_count = issues_identified_count + Issue.objects.filter( project_id=project.id, status__name='Open', type__name='Issue').count() return issues_identified_count def get_issue_closed(self, obj): issues_closed_count = 0 if obj.is_superuser: issues_closed_count = Issue.objects.filter( status__name='Closed', type__name='Issue').count() else: projects = Project.objects.filter(members=obj.id) for project in projects: issues_closed_count = issues_closed_count + Issue.objects.filter( project_id=project.id, status__name='Closed', type__name='Issue').count() return issues_closed_count def get_accidents_report(self, obj): accident_report_count = 0 if obj.is_superuser: accident_report_count = Issue.objects.filter( type__name='Accident').count() else: projects = Project.objects.filter(members=obj.id) for project in projects: accident_report_count = accident_report_count + Issue.objects.filter( project_id=project.id, type__name='Accident').count() return accident_report_count
class SeveritySerializer(serializers.LightSerializer): id = Field(attr="pk") name = MethodField() color = MethodField() def get_name(self, obj): return obj.name def get_color(self, obj): return obj.color
class EpicRelatedUserStorySerializer(serializers.LightSerializer): id = Field() user_story = MethodField() epic = MethodField() order = Field() def get_user_story(self, obj): return UserStorySerializer(obj.user_story).data def get_epic(self, obj): return EpicSerializer(obj.epic).data
class VoteResourceSerializerMixin(serializers.LightSerializer): is_voter = MethodField() total_voters = MethodField() def get_is_voter(self, obj): # The "is_voted" attribute is attached in the get_queryset of the viewset. return getattr(obj, "is_voter", False) or False def get_total_voters(self, obj): # The "total_voters" attribute is attached in the get_queryset of the viewset. return getattr(obj, "total_voters", 0) or 0
class RolePointsSerializer(serializers.LightSerializer): role = MethodField() name = MethodField() value = MethodField() def get_role(self, obj): return obj.role.name def get_name(self, obj): return obj.points.name def get_value(self, obj): return obj.points.value
class UserAdminSerializer(UserSerializer): total_private_projects = MethodField() total_public_projects = MethodField() email = Field() max_private_projects = Field() max_public_projects = Field() max_memberships_private_projects = Field() max_memberships_public_projects = Field() def get_total_private_projects(self, user): return user.owned_projects.filter(is_private=True).count() def get_total_public_projects(self, user): return user.owned_projects.filter(is_private=False).count()
class ProjectSerializer(serializers.LightSerializer): id = Field(attr="pk") permalink = MethodField() name = MethodField() logo_big_url = MethodField() def get_permalink(self, obj): return resolve_front_url("project", obj.slug) def get_name(self, obj): return obj.name def get_logo_big_url(self, obj): return get_logo_big_thumbnail_url(obj)
class UserStorySerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() project = ProjectSerializer() is_closed = Field() created_date = Field() modified_date = Field() finish_date = Field() due_date = Field() due_date_reason = Field() subject = Field() client_requirement = Field() team_requirement = Field() generated_from_issue = Field(attr="generated_from_issue_id") generated_from_task = Field(attr="generated_from_task_id") from_task_ref = Field() external_reference = Field() tribe_gig = Field() watchers = MethodField() is_blocked = Field() blocked_note = Field() description = Field() tags = Field() permalink = MethodField() owner = UserSerializer() assigned_to = UserSerializer() assigned_users = MethodField() points = MethodField() status = UserStoryStatusSerializer() milestone = MilestoneSerializer() def get_permalink(self, obj): return resolve_front_url("userstory", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.userstorycustomattributes.all() def get_assigned_users(self, obj): """Get the assigned of an object. :return: User queryset object representing the assigned users """ return [user.id for user in obj.assigned_users.all()] def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True)) def get_points(self, obj): return RolePointsSerializer(obj.role_points.all(), many=True).data
class TaskSerializer(TaskListSerializer): comment = MethodField() blocked_note_html = MethodField() description = Field() description_html = MethodField() def get_comment(self, obj): return "" def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description)
class WatchedResourceSerializer(serializers.LightSerializer): is_watcher = MethodField() total_watchers = MethodField() def get_is_watcher(self, obj): # The "is_watcher" attribute is attached in the get_queryset of the viewset. if "request" in self.context: user = self.context["request"].user return user.is_authenticated and getattr(obj, "is_watcher", False) return False def get_total_watchers(self, obj): # The "total_watchers" attribute is attached in the get_queryset of the viewset. return getattr(obj, "total_watchers", 0) or 0
class UserStorySerializer(UserStoryListSerializer): comment = MethodField() blocked_note_html = MethodField() description = Field() description_html = MethodField() def get_comment(self, obj): # NOTE: This method and field is necessary to historical comments work return "" def get_blocked_note_html(self, obj): return mdrender(obj.project, obj.blocked_note) def get_description_html(self, obj): return mdrender(obj.project, obj.description)
class ObjectSerializer(serializers.LightSerializer): id = Field() ref = MethodField() subject = MethodField() content_type = MethodField() def get_ref(self, obj): return obj.ref if hasattr(obj, 'ref') else None def get_subject(self, obj): return obj.subject if hasattr(obj, 'subject') else None def get_content_type(self, obj): content_type = ContentType.objects.get_for_model(obj) return content_type.model if content_type else None
class MembershipSerializer(serializers.LightSerializer): id = Field() user = Field(attr="user_id") project = Field(attr="project_id") role = Field(attr="role_id") is_admin = Field() created_at = Field() invited_by = Field(attr="invited_by_id") invitation_extra_text = Field() user_order = Field() role_name = MethodField() full_name = MethodField() is_user_active = MethodField() color = MethodField() photo = MethodField() gravatar_id = MethodField() project_name = MethodField() project_slug = MethodField() invited_by = UserBasicInfoSerializer() is_owner = MethodField() def get_role_name(self, obj): return obj.role.name if obj.role else None def get_full_name(self, obj): return obj.user.get_full_name() if obj.user else None def get_is_user_active(self, obj): return obj.user.is_active if obj.user else False def get_color(self, obj): return obj.user.color if obj.user else None def get_photo(self, obj): return get_user_photo_url(obj.user) def get_gravatar_id(self, obj): return get_user_gravatar_id(obj.user) def get_project_name(self, obj): return obj.project.name if obj and obj.project else "" def get_project_slug(self, obj): return obj.project.slug if obj and obj.project else "" def get_is_owner(self, obj): return ( obj and obj.user_id and obj.project_id and obj.project.owner_id and obj.user_id == obj.project.owner_id )
class BasicAttachmentsInfoSerializerMixin(serializers.LightSerializer): """ Assumptions: - The queryset has an attribute called "include_attachments" indicating if the attachments array should contain information about the related elements, otherwise it will be empty - The method attach_basic_attachments has been used to include the necessary json data about the attachments in the "attachments_attr" column """ attachments = MethodField() def get_attachments(self, obj): include_attachments = getattr(obj, "include_attachments", False) if include_attachments: assert hasattr(obj, "attachments_attr" ), "instance must have a attachments_attr attribute" if not include_attachments or obj.attachments_attr is None: return [] for at in obj.attachments_attr: at["thumbnail_card_url"] = get_thumbnail_url( at["attached_file"], settings.THN_ATTACHMENT_CARD) return obj.attachments_attr
class TaskSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() finished_date = Field() due_date = Field() due_date_reason = Field() subject = Field() us_order = Field() taskboard_order = Field() is_iocaine = Field() external_reference = Field() watchers = MethodField() is_blocked = Field() blocked_note = Field() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") project = ProjectSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = TaskStatusSerializer() user_story = UserStorySerializer() milestone = MilestoneSerializer() def get_permalink(self, obj): return resolve_front_url("task", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.taskcustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class IssueSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() finished_date = Field() due_date = Field() due_date_reason = Field() subject = Field() external_reference = Field() watchers = MethodField() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") project = ProjectSerializer() milestone = MilestoneSerializer() owner = UserSerializer() assigned_to = UserSerializer() status = IssueStatusSerializer() type = IssueTypeSerializer() priority = PrioritySerializer() severity = SeveritySerializer() time_spent_note = Field() affects_customer = Field() def get_permalink(self, obj): return resolve_front_url("issue", obj.project.slug, obj.ref) def custom_attributes_queryset(self, project): return project.issuecustomattributes.all() def get_watchers(self, obj): return list(obj.get_watchers().values_list("id", flat=True))
class VoterSerializer(serializers.LightSerializer): id = Field() username = Field() full_name = MethodField() def get_full_name(self, obj): return obj.get_full_name()
class CustomAttributesValuesExportSerializerMixin(serializers.LightSerializer): custom_attributes_values = MethodField("get_custom_attributes_values") def custom_attributes_queryset(self, project): raise NotImplementedError() def get_custom_attributes_values(self, obj): def _use_name_instead_id_as_key_in_custom_attributes_values( custom_attributes, values): ret = {} for attr in custom_attributes: value = values.get(str(attr["id"]), None) if value is not None: ret[attr["name"]] = value return ret try: values = obj.custom_attributes_values.attributes_values custom_attributes = self.custom_attributes_queryset(obj.project) return _use_name_instead_id_as_key_in_custom_attributes_values( custom_attributes, values) except ObjectDoesNotExist: return None
class ProjectExtraInfoSerializerMixin(serializers.LightSerializer): project = Field(attr="project_id") project_extra_info = MethodField() def to_value(self, instance): self._serialized_project = {} return super().to_value(instance) def get_project_extra_info(self, obj): if obj.project_id is None: return None serialized_project = self._serialized_project.get(obj.project_id, None) if serialized_project is None: serialized_project = { "name": obj.project.name, "slug": obj.project.slug, "logo_small_url": services.get_logo_small_thumbnail_url(obj.project), "id": obj.project_id } self._serialized_project[obj.project_id] = serialized_project return serialized_project