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 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 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 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 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() 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 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 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 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 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 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 EpicSerializer(EpicListSerializer): 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 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") external_reference = Field() tribe_gig = Field() watchers = MethodField() is_blocked = Field() blocked_note = Field() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") 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() generated_user_stories = 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 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 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 VoterSerializer(serializers.LightSerializer): id = Field() username = Field() full_name = MethodField() def get_full_name(self, obj): return obj.get_full_name()
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 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 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 EpicSerializer(CustomAttributesValuesWebhookSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() created_date = Field() modified_date = Field() subject = Field() watchers = MethodField() description = Field() tags = Field() permalink = serializers.SerializerMethodField("get_permalink") 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 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() 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 HistoryEntrySerializer(serializers.LightSerializer): id = Field() user = MethodField() created_at = Field() type = Field() key = Field() diff = Field() snapshot = Field() values = Field() values_diff = I18NJSONField() comment = I18NJSONField() comment_html = Field() delete_comment_date = Field() delete_comment_user = Field() edit_comment_date = Field() is_hidden = Field() is_snapshot = Field() def get_user(self, entry): user = {"pk": None, "username": None, "name": None, "photo": None, "is_active": False} user.update(entry.user) user["photo"] = get_user_photo_url(entry.owner) user["gravatar_id"] = get_user_gravatar_id(entry.owner) if entry.owner: user["is_active"] = entry.owner.is_active if entry.owner.is_active or entry.owner.is_system: user["name"] = entry.owner.get_full_name() user["username"] = entry.owner.username return user
class CustomAttributesValuesWebhookSerializerMixin(serializers.LightSerializer ): custom_attributes_values = MethodField() 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).values('id', 'name') return _use_name_instead_id_as_key_in_custom_attributes_values( custom_attributes, values) except ObjectDoesNotExist: return None
class AttachmentExportSerializerMixin(serializers.LightSerializer): attachments = MethodField() def get_attachments(self, obj): content_type = ContentType.objects.get_for_model(obj.__class__) attachments_qs = attachments_models.Attachment.objects.filter( object_id=obj.pk, content_type=content_type) return AttachmentExportSerializer(attachments_qs, many=True).data
class UserStoryNestedSerializer(ProjectExtraInfoSerializerMixin, StatusExtraInfoSerializerMixin, AssignedToExtraInfoSerializerMixin, DueDateSerializerMixin, serializers.LightSerializer): id = Field() ref = Field() milestone = Field(attr="milestone_id") project = Field(attr="project_id") is_closed = Field() created_date = Field() modified_date = Field() finish_date = Field() subject = Field() client_requirement = Field() team_requirement = Field() external_reference = Field() version = Field() is_blocked = Field() blocked_note = Field() backlog_order = Field() sprint_order = Field() kanban_order = Field() epics = MethodField() points = MethodField() total_points = MethodField() def get_epics(self, obj): assert hasattr( obj, "epics_attr"), "instance must have a epics_attr attribute" return obj.epics_attr def get_points(self, obj): assert hasattr(obj, "role_points_attr" ), "instance must have a role_points_attr attribute" if obj.role_points_attr is None: return {} return obj.role_points_attr 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
class UserAdminSerializer(UserSerializer): total_private_projects = MethodField() total_public_projects = MethodField() email = Field() uuid = Field() date_joined = Field() read_new_terms = Field() accepted_terms = 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 IssueStatusSerializer(serializers.LightSerializer): id = Field(attr="pk") name = MethodField() slug = MethodField() color = MethodField() is_closed = MethodField() def get_name(self, obj): return obj.name def get_slug(self, obj): return obj.slug def get_color(self, obj): return obj.color def get_is_closed(self, obj): return obj.is_closed
class TaggedInProjectResourceSerializer(serializers.LightSerializer): tags = MethodField() def get_tags(self, obj): if not obj.tags: return [] project_tag_colors = dict(obj.project.tags_colors) return [[tag, project_tag_colors.get(tag, None)] for tag in obj.tags]
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)