diff --git a/backend/apps/github/models/mixins/issue.py b/backend/apps/github/models/mixins/issue.py index 048586841d..f8ca0406b7 100644 --- a/backend/apps/github/models/mixins/issue.py +++ b/backend/apps/github/models/mixins/issue.py @@ -8,7 +8,12 @@ class IssueIndexMixin: @property def is_indexable(self): - """Issues to index.""" + """Determine if the issue should be indexed. + + Returns: + bool: True if the issue meets indexing criteria, False otherwise. + + """ return ( self.id and self.state == self.State.OPEN @@ -21,120 +26,240 @@ def is_indexable(self): @property def idx_author_login(self) -> str: - """Return author login for indexing.""" + """Return author login for indexing. + + Returns: + str: The login name of the issue author. + + """ return self.author.login if self.author else "" @property def idx_author_name(self) -> str: - """Return author name for indexing.""" + """Return author name for indexing. + + Returns: + str: The name of the issue author. + + """ return self.author.name if self.author else "" @property def idx_comments_count(self) -> int: - """Return comments count at for indexing.""" + """Return comments count for indexing. + + Returns: + int: The number of comments on the issue. + + """ return self.comments_count @property def idx_created_at(self) -> float: - """Return created at for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The issue creation timestamp. + + """ return self.created_at.timestamp() @property def idx_hint(self) -> str: - """Return hint for indexing.""" + """Return hint for indexing. + + Returns: + str: The hint associated with the issue. + + """ return self.hint @property def idx_labels(self) -> list[str]: - """Return labels for indexing.""" + """Return labels for indexing. + + Returns: + list[str]: A list of label names on the issue. + + """ return [label.name for label in self.labels.all()] @property def idx_project_description(self) -> str: - """Return project description for indexing.""" + """Return project description for indexing. + + Returns: + str: The description of the associated project. + + """ return self.project.idx_description if self.project else "" @property def idx_project_level(self) -> str: - """Return project level or indexing.""" + """Return project level for indexing. + + Returns: + str: The level of the associated project. + + """ return self.project.idx_level if self.project else "" @property def idx_project_level_raw(self) -> str: - """Return project raw level for indexing.""" + """Return project raw level for indexing. + + Returns: + str: The raw level of the associated project. + + """ return self.project.idx_level_raw if self.project else "" @property def idx_project_tags(self) -> list[str]: - """Return project tags for indexing.""" + """Return project tags for indexing. + + Returns: + list[str]: A list of tags from the associated project. + + """ return self.project.idx_tags if self.project else [] @property def idx_project_topics(self) -> list[str]: - """Return project topics for indexing.""" + """Return project topics for indexing. + + Returns: + list[str]: A list of topics from the associated project. + + """ return self.project.idx_topics if self.project else [] @property def idx_project_name(self) -> str: - """Return project name for indexing.""" + """Return project name for indexing. + + Returns: + str: The name of the associated project. + + """ return self.project.idx_name if self.project else "" @property def idx_project_url(self) -> str: - """Return project URL for indexing.""" + """Return project URL for indexing. + + Returns: + str: The URL of the associated project. + + """ return self.project.idx_url if self.project else "" @property def idx_repository_contributors_count(self) -> int: - """Return repository contributors count for indexing.""" + """Return repository contributors count for indexing. + + Returns: + int: The number of contributors to the repository. + + """ return self.repository.idx_contributors_count @property def idx_repository_description(self) -> str: - """Return repository description for indexing.""" + """Return repository description for indexing. + + Returns: + str: The description of the repository. + + """ return self.repository.idx_description @property def idx_repository_forks_count(self) -> int: - """Return repository forks count for indexing.""" + """Return repository forks count for indexing. + + Returns: + int: The number of repository forks. + + """ return self.repository.idx_forks_count @property def idx_repository_languages(self) -> list[str]: - """Return repository languages for indexing.""" + """Return repository languages for indexing. + + Returns: + list[str]: A list of top languages in the repository. + + """ return self.repository.top_languages @property def idx_repository_name(self) -> str: - """Return repository name for indexing.""" + """Return repository name for indexing. + + Returns: + str: The name of the repository. + + """ return self.repository.idx_name @property def idx_repository_stars_count(self) -> int: - """Return repository stars count for indexing.""" + """Return repository stars count for indexing. + + Returns: + int: The number of stars the repository has. + + """ return self.repository.idx_stars_count @property def idx_summary(self) -> str: - """Return summary for indexing.""" + """Return summary for indexing. + + Returns: + str: The summary of the issue. + + """ return self.summary @property def idx_title(self) -> str: - """Return title for indexing.""" + """Return title for indexing. + + Returns: + str: The title of the issue. + + """ return self.title @property def idx_repository_topics(self) -> list[str]: - """Return repository stars count for indexing.""" + """Return repository topics for indexing. + + Returns: + list[str]: A list of topics from the repository. + + """ return self.repository.idx_topics @property def idx_updated_at(self) -> float: - """Return updated at for indexing.""" + """Return updated at timestamp for indexing. + + Returns: + float: The issue's last update timestamp. + + """ return self.updated_at.timestamp() @property def idx_url(self) -> str: - """Return URL for indexing.""" + """Return URL for indexing. + + Returns: + str: The URL of the issue. + + """ return self.url diff --git a/backend/apps/github/models/mixins/organization.py b/backend/apps/github/models/mixins/organization.py index 83495d4cb6..0316dfb7aa 100644 --- a/backend/apps/github/models/mixins/organization.py +++ b/backend/apps/github/models/mixins/organization.py @@ -8,12 +8,22 @@ class OrganizationIndexMixin: @property def is_indexable(self) -> bool: - """Organizations to index.""" + """Determine if the organization should be indexed. + + Returns: + bool: True if the organization meets indexing criteria, False otherwise. + + """ return bool(self.is_owasp_related_organization and self.name and self.login) @property def idx_avatar_url(self) -> str: - """Return avatar URL for indexing.""" + """Return avatar URL for indexing. + + Returns: + str: The URL of the organization's avatar. + + """ return self.avatar_url @property @@ -22,6 +32,10 @@ def idx_collaborators_count(self): This calculates the total number of unique collaborators across all repositories owned by this organization. + + Returns: + int: The number of unique collaborators. + """ from apps.github.models.repository import Repository from apps.github.models.repository_contributor import RepositoryContributor @@ -40,40 +54,80 @@ def idx_collaborators_count(self): @property def idx_created_at(self) -> float | None: - """Return created at for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float | None: The organization creation timestamp, or None. + + """ return self.created_at.timestamp() if self.created_at else None @property def idx_description(self) -> str: - """Return description for indexing.""" + """Return description for indexing. + + Returns: + str: The description of the organization. + + """ return self.description or "" @property def idx_followers_count(self) -> int: - """Return followers count for indexing.""" + """Return followers count for indexing. + + Returns: + int: The number of followers the organization has. + + """ return self.followers_count @property def idx_location(self) -> str: - """Return location for indexing.""" + """Return location for indexing. + + Returns: + str: The location of the organization. + + """ return self.location or "" @property def idx_login(self) -> str: - """Return login for indexing.""" + """Return login for indexing. + + Returns: + str: The login name of the organization. + + """ return self.login @property def idx_name(self) -> str: - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The display name of the organization. + + """ return self.name or "" @property def idx_public_repositories_count(self) -> int: - """Return public repositories count for indexing.""" + """Return public repositories count for indexing. + + Returns: + int: The number of public repositories. + + """ return self.public_repositories_count @property def idx_url(self) -> str: - """Return URL for indexing.""" + """Return URL for indexing. + + Returns: + str: The URL of the organization's GitHub page. + + """ return self.url diff --git a/backend/apps/github/models/mixins/release.py b/backend/apps/github/models/mixins/release.py index 274d4c7540..8c9c1d2da9 100644 --- a/backend/apps/github/models/mixins/release.py +++ b/backend/apps/github/models/mixins/release.py @@ -12,13 +12,22 @@ class ReleaseIndexMixin: @property def is_indexable(self) -> bool: - """Releases to index.""" + """Determine if the release should be indexed. + + Returns: + bool: True if the release meets indexing criteria, False otherwise. + + """ return not self.is_draft @property def idx_author(self) -> list[dict[str, str]]: - """Return author for indexing.""" - """Get top contributors.""" + """Return author for indexing. + + Returns: + list[dict[str, str]]: A list containing author details, or empty list. + + """ return ( [ { @@ -33,40 +42,80 @@ def idx_author(self) -> list[dict[str, str]]: @property def idx_created_at(self) -> float: - """Return created at timestamp for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The release creation timestamp. + + """ return self.created_at.timestamp() @property def idx_description(self) -> str: - """Return description for indexing.""" + """Return description for indexing. + + Returns: + str: The truncated release description. + + """ return truncate(self.description, limit=DESCRIPTION_MAX_LENGTH) @property def idx_is_pre_release(self) -> bool: - """Return is pre release count for indexing.""" + """Return pre-release status for indexing. + + Returns: + bool: True if the release is a pre-release, False otherwise. + + """ return self.is_pre_release @property def idx_name(self) -> str: - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The name of the release. + + """ return self.name @property def idx_project(self) -> str: - """Return project for indexing.""" + """Return project for indexing. + + Returns: + str: The nest key of the associated project, or empty string. + + """ return self.repository.project.nest_key if self.repository.project else "" @property def idx_published_at(self) -> float | None: - """Return published at timestamp for indexing.""" + """Return published at timestamp for indexing. + + Returns: + float | None: The release publication timestamp, or None. + + """ return self.published_at.timestamp() if self.published_at else None @property def idx_repository(self) -> str: - """Return repository for indexing.""" + """Return repository for indexing. + + Returns: + str: The repository path in lowercase. + + """ return self.repository.path.lower() @property def idx_tag_name(self) -> str: - """Return tag name for indexing.""" + """Return tag name for indexing. + + Returns: + str: The tag name of the release. + + """ return self.tag_name diff --git a/backend/apps/github/models/mixins/repository.py b/backend/apps/github/models/mixins/repository.py index 6bd7b27b6c..4d0b0f0eef 100644 --- a/backend/apps/github/models/mixins/repository.py +++ b/backend/apps/github/models/mixins/repository.py @@ -14,7 +14,12 @@ class RepositoryIndexMixin: @property def is_indexable(self) -> bool: - """Repositories to index.""" + """Determine if the repository should be indexed. + + Returns: + bool: True if the repository meets indexing criteria, False otherwise. + + """ return ( not self.is_archived and not self.is_empty @@ -24,90 +29,180 @@ def is_indexable(self) -> bool: @property def idx_commits_count(self) -> int: - """Return commits count for indexing.""" + """Return commits count for indexing. + + Returns: + int: The total number of commits in the repository. + + """ return self.commits_count @property def idx_contributors_count(self) -> int: - """Return contributors count for indexing.""" + """Return contributors count for indexing. + + Returns: + int: The number of contributors to the repository. + + """ return self.contributors_count @property def idx_created_at(self) -> float: - """Return created at for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The repository creation timestamp. + + """ return self.created_at.timestamp() @property def idx_description(self) -> str: - """Return description for indexing.""" + """Return description for indexing. + + Returns: + str: The description of the repository. + + """ return self.description @property def idx_forks_count(self) -> int: - """Return forks count for indexing.""" + """Return forks count for indexing. + + Returns: + int: The number of forks of the repository. + + """ return self.forks_count @property def idx_has_funding_yml(self) -> bool: - """Return has funding.yml for indexing.""" + """Return whether repository has funding.yml for indexing. + + Returns: + bool: True if the repository has a funding.yml file, False otherwise. + + """ return self.has_funding_yml @property def idx_key(self) -> str: - """Return key for indexing.""" + """Return key for indexing. + + Returns: + str: The repository key. + + """ return self.nest_key @property def idx_languages(self) -> list[str]: - """Return languages for indexing.""" + """Return languages for indexing. + + Returns: + list[str]: A list of programming languages used in the repository. + + """ return self.languages @property def idx_license(self) -> str: - """Return license for indexing.""" + """Return license for indexing. + + Returns: + str: The license of the repository. + + """ return self.license @property def idx_name(self) -> str: - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The name of the repository. + + """ return self.name @property def idx_open_issues_count(self) -> int: - """Return open issues count for indexing.""" + """Return open issues count for indexing. + + Returns: + int: The number of open issues in the repository. + + """ return self.open_issues_count @property def idx_project_key(self) -> str: - """Return project key for indexing.""" + """Return project key for indexing. + + Returns: + str: The key of the associated project, or empty string. + + """ return self.project.nest_key if self.project else "" @property def idx_pushed_at(self) -> float: - """Return pushed at for indexing.""" + """Return pushed at timestamp for indexing. + + Returns: + float: The last push timestamp of the repository. + + """ return self.pushed_at.timestamp() @property def idx_size(self) -> int: - """Return size for indexing.""" + """Return size for indexing. + + Returns: + int: The size of the repository in kilobytes. + + """ return self.size @property def idx_stars_count(self) -> int: - """Return stars count for indexing.""" + """Return stars count for indexing. + + Returns: + int: The number of stars the repository has received. + + """ return self.stars_count @property def idx_subscribers_count(self) -> int: - """Return subscribers count for indexing.""" - return self.stars_count + """Return subscribers count for indexing. + + Returns: + int: The number of subscribers to the repository. + + """ + return self.subscribers_count @property def idx_top_contributors(self) -> list[dict[str, Any]]: - """Return top contributors for indexing.""" + """Return top contributors for indexing. + + Returns: + list[dict[str, Any]]: A list of top contributor details. + + """ return RepositoryContributor.get_top_contributors(repository=self.key) @property def idx_topics(self): - """Return topics for indexing.""" + """Return topics for indexing. + + Returns: + list[str]: A list of topics associated with the repository. + + """ return self.topics diff --git a/backend/apps/github/models/mixins/user.py b/backend/apps/github/models/mixins/user.py index bdbb2c2f19..f760383fc2 100644 --- a/backend/apps/github/models/mixins/user.py +++ b/backend/apps/github/models/mixins/user.py @@ -12,7 +12,12 @@ class UserIndexMixin: @property def is_indexable(self): - """Users to index.""" + """Determine if the user should be indexed. + + Returns: + bool: True if the user meets indexing criteria, False otherwise. + + """ return ( not self.is_bot and not self.login.endswith(("Bot", "-bot")) @@ -21,77 +26,152 @@ def is_indexable(self): @property def idx_avatar_url(self) -> str: - """Return avatar URL for indexing.""" + """Return avatar URL for indexing. + + Returns: + str: The URL of the user's avatar. + + """ return self.avatar_url @property def idx_badge_count(self) -> int: - """Return badge count for indexing.""" + """Return badge count for indexing. + + Returns: + int: The number of active badges the user has. + + """ return self.user_badges.filter(is_active=True).count() @property def idx_bio(self) -> str: - """Return bio for indexing.""" + """Return bio for indexing. + + Returns: + str: The biography of the user. + + """ return self.bio @property def idx_company(self) -> str: - """Return company for indexing.""" + """Return company for indexing. + + Returns: + str: The name of the user's company. + + """ return self.company @property def idx_created_at(self) -> float: - """Return created at timestamp for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The user's account creation timestamp. + + """ return self.created_at.timestamp() @property def idx_email(self) -> str: - """Return email for indexing.""" + """Return email for indexing. + + Returns: + str: The user's email address. + + """ return self.email @property def idx_key(self) -> str: - """Return key for indexing.""" + """Return key for indexing. + + Returns: + str: The index key. + + """ return self.login @property def idx_followers_count(self) -> int: - """Return followers count for indexing.""" + """Return followers count for indexing. + + Returns: + int: The number of followers the user has. + + """ return self.followers_count @property def idx_following_count(self) -> int: - """Return following count for indexing.""" + """Return following count for indexing. + + Returns: + int: The number of users the user is following. + + """ return self.following_count @property def idx_location(self) -> str: - """Return location for indexing.""" + """Return location for indexing. + + Returns: + str: The location of the user. + + """ return self.location @property def idx_login(self) -> str: - """Return login for indexing.""" + """Return login for indexing. + + Returns: + str: The login name of the user. + + """ return self.login @property def idx_name(self) -> str: - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The display name of the user. + + """ return self.name @property def idx_public_repositories_count(self) -> int: - """Return public repositories count for indexing.""" + """Return public repositories count for indexing. + + Returns: + int: The number of public repositories the user owns. + + """ return self.public_repositories_count @property def idx_title(self) -> str: - """Return title for indexing.""" + """Return title for indexing. + + Returns: + str: The title of the user. + + """ return self.title @property def idx_contributions(self): - """Return contributions for indexing.""" + """Return contributions for indexing. + + Returns: + list[dict]: A list of contribution details for top repositories. + + """ from apps.github.models.repository_contributor import RepositoryContributor return [ @@ -123,12 +203,22 @@ def idx_contributions(self): @property def idx_contributions_count(self) -> int: - """Return contributions count for indexing.""" + """Return contributions count for indexing. + + Returns: + int: The total number of contributions. + + """ return self.contributions_count @property def idx_issues(self) -> list[dict]: - """Return issues for indexing.""" + """Return issues for indexing. + + Returns: + list[dict]: A list of the user's recent issues. + + """ return [ { "created_at": i.created_at.timestamp(), @@ -149,12 +239,22 @@ def idx_issues(self) -> list[dict]: @property def idx_issues_count(self) -> int: - """Return issues count for indexing.""" + """Return issues count for indexing. + + Returns: + int: The total number of issues associated with the user. + + """ return self.issues.count() @property def idx_releases(self) -> list[dict]: - """Return releases for indexing.""" + """Return releases for indexing. + + Returns: + list[dict]: A list of the user's recent releases. + + """ return [ { "is_pre_release": r.is_pre_release, @@ -175,15 +275,30 @@ def idx_releases(self) -> list[dict]: @property def idx_releases_count(self) -> int: - """Return releases count for indexing.""" + """Return releases count for indexing. + + Returns: + int: The total number of releases associated with the user. + + """ return self.releases.count() @property def idx_updated_at(self) -> float: - """Return updated at timestamp for indexing.""" + """Return updated at timestamp for indexing. + + Returns: + float: The user's last update timestamp. + + """ return self.updated_at.timestamp() @property def idx_url(self) -> str: - """Return GitHub profile URL for indexing.""" + """Return GitHub profile URL for indexing. + + Returns: + str: The URL of the user's GitHub profile. + + """ return self.url diff --git a/backend/apps/mentorship/models/mixins/program.py b/backend/apps/mentorship/models/mixins/program.py index fd843159a8..dc1f368b2d 100644 --- a/backend/apps/mentorship/models/mixins/program.py +++ b/backend/apps/mentorship/models/mixins/program.py @@ -8,40 +8,80 @@ class ProgramIndexMixin: @property def is_indexable(self) -> bool: - """Only index published programs.""" + """Determine if the program should be indexed. + + Returns: + bool: True if the program meets indexing criteria, False otherwise. + + """ return self.status == self.__class__.ProgramStatus.PUBLISHED @property def idx_name(self) -> str: - """Name for Algolia indexing.""" + """Return name for indexing. + + Returns: + str: The name of the program. + + """ return self.name @property def idx_key(self) -> str: - """Unique key for Algolia indexing.""" + """Return unique key for indexing. + + Returns: + str: The program key. + + """ return self.key @property def idx_status(self) -> str: - """Status for Algolia indexing.""" + """Return status for indexing. + + Returns: + str: The status of the program. + + """ return self.status @property def idx_description(self) -> str: - """Description for Algolia indexing.""" + """Return description for indexing. + + Returns: + str: The description of the program. + + """ return self.description or "" @property def idx_experience_levels(self) -> list[str]: - """List of experience levels for Algolia filtering.""" + """Return experience levels for filtering. + + Returns: + list[str]: A list of experience levels. + + """ return self.experience_levels or [] @property def idx_started_at(self) -> str | None: - """Formatted start datetime.""" + """Return formatted start datetime. + + Returns: + str | None: The start datetime in ISO format, or None. + + """ return self.started_at.isoformat() if self.started_at else None @property def idx_ended_at(self) -> str | None: - """Formatted end datetime for filtering/sorting.""" + """Return formatted end datetime for filtering/sorting. + + Returns: + str | None: The end datetime in ISO format, or None. + + """ return self.ended_at.isoformat() if self.ended_at else None diff --git a/backend/apps/owasp/models/mixins/chapter.py b/backend/apps/owasp/models/mixins/chapter.py index f3ae7effff..b241134482 100644 --- a/backend/apps/owasp/models/mixins/chapter.py +++ b/backend/apps/owasp/models/mixins/chapter.py @@ -11,7 +11,12 @@ class ChapterIndexMixin(RepositoryBasedEntityModelMixin): @property def is_indexable(self) -> bool: - """Chapters to index.""" + """Determine if the chapter should be indexed. + + Returns: + bool: True if the chapter meets indexing criteria, False otherwise. + + """ return ( self.latitude is not None and self.longitude is not None @@ -20,60 +25,120 @@ def is_indexable(self) -> bool: @property def idx_country(self) -> str: - """Return country for indexing.""" + """Return country for indexing. + + Returns: + str: The country where the chapter is located. + + """ return self.country @property def idx_created_at(self) -> float: - """Return created at for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The chapter creation timestamp. + + """ return (self.created_at or self.owasp_repository.created_at).timestamp() @property def idx_geo_location(self) -> tuple[float, float]: - """Return geographic location for indexing.""" + """Return geographic location for indexing. + + Returns: + tuple[float, float]: The latitude and longitude of the chapter. + + """ return self.latitude, self.longitude @property def idx_is_active(self) -> bool: - """Return active status for indexing.""" + """Return active status for indexing. + + Returns: + bool: True if the chapter is active, False otherwise. + + """ return self.is_active @property def idx_key(self) -> str: - """Return key for indexing.""" + """Return key for indexing. + + Returns: + str: The chapter key. + + """ return self.key.replace("www-chapter-", "") @property def idx_meetup_group(self) -> str: - """Return meetup group for indexing.""" + """Return meetup group for indexing. + + Returns: + str: The meetup group of the chapter. + + """ return self.meetup_group @property def idx_postal_code(self) -> str: - """Return postal code for indexing.""" + """Return postal code for indexing. + + Returns: + str: The postal code of the chapter location. + + """ return self.postal_code @property def idx_region(self) -> str: - """Return region for indexing.""" + """Return region for indexing. + + Returns: + str: The region where the chapter is located. + + """ return self.region @property def idx_related_urls(self) -> list: - """Return related URLs for indexing.""" + """Return related URLs for indexing. + + Returns: + list: A list of URLs related to the chapter. + + """ return self.related_urls @property def idx_suggested_location(self) -> str: - """Return suggested location for indexing.""" + """Return suggested location for indexing. + + Returns: + str: The suggested location for the chapter, or empty string. + + """ return self.suggested_location if self.suggested_location != "None" else "" @property def idx_top_contributors(self) -> list: - """Return top contributors for indexing.""" + """Return top contributors for indexing. + + Returns: + list: A list of top contributor details for the chapter. + + """ return RepositoryContributor.get_top_contributors(chapter=self.key) @property def idx_updated_at(self) -> float: - """Return updated at for indexing.""" + """Return updated at timestamp for indexing. + + Returns: + float: The chapter's last update timestamp. + + """ return (self.updated_at or self.owasp_repository.updated_at).timestamp() diff --git a/backend/apps/owasp/models/mixins/committee.py b/backend/apps/owasp/models/mixins/committee.py index d11d0312af..53dcdeb902 100644 --- a/backend/apps/owasp/models/mixins/committee.py +++ b/backend/apps/owasp/models/mixins/committee.py @@ -11,25 +11,50 @@ class CommitteeIndexMixin(RepositoryBasedEntityModelMixin): @property def idx_created_at(self): - """Return created at for indexing.""" + """Return created at timestamp for indexing. + + Returns: + float: The committee creation timestamp. + + """ return self.created_at.timestamp() @property def idx_key(self): - """Return key for indexing.""" + """Return key for indexing. + + Returns: + str: The committee key. + + """ return self.key.replace("www-committee-", "") @property def idx_related_urls(self): - """Return related URLs for indexing.""" + """Return related URLs for indexing. + + Returns: + list: A list of URLs related to the committee. + + """ return self.related_urls @property def idx_top_contributors(self) -> list[str]: - """Return top contributors for indexing.""" + """Return top contributors for indexing. + + Returns: + list[str]: A list of top contributor details for the committee. + + """ return RepositoryContributor.get_top_contributors(committee=self.key) @property def idx_updated_at(self): - """Return updated at for indexing.""" + """Return updated at timestamp for indexing. + + Returns: + float: The committee's last update timestamp. + + """ return self.updated_at.timestamp() diff --git a/backend/apps/owasp/models/mixins/common.py b/backend/apps/owasp/models/mixins/common.py index 2c439bb2c3..e3a6a77bd9 100644 --- a/backend/apps/owasp/models/mixins/common.py +++ b/backend/apps/owasp/models/mixins/common.py @@ -6,40 +6,80 @@ class RepositoryBasedEntityModelMixin: @property def is_indexable(self): - """Entities to index.""" + """Determine if the entity should be indexed. + + Returns: + bool: True if the entity meets indexing criteria, False otherwise. + + """ return self.has_active_repositories @property def idx_description(self): - """Return description for indexing.""" + """Return description for indexing. + + Returns: + str: The description fo the entity. + + """ return self.description @property def idx_leaders(self): - """Return leaders for indexing.""" + """Return leaders for indexing. + + Returns: + list: A list of leader names. + + """ return [leader for leader in self.leaders_raw if not leader.startswith("@")] @property def idx_name(self): - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The name of the entity. + + """ return self.name @property def idx_summary(self): - """Return summary for indexing.""" + """Return summary for indexing. + + Returns: + str: The summary of the entity. + + """ return self.summary @property def idx_tags(self): - """Return tags for indexing.""" + """Return tags for indexing. + + Returns: + list: A list of tags associated with the entity. + + """ return self.tags @property def idx_topics(self): - """Return topics for indexing.""" + """Return topics for indexing. + + Returns: + list: A list of topics associated with the entity. + + """ return self.topics @property def idx_url(self): - """Return URL for indexing.""" + """Return URL for indexing. + + Returns: + str: The URL for the entity. + + """ return self.owasp_url diff --git a/backend/apps/owasp/models/mixins/project.py b/backend/apps/owasp/models/mixins/project.py index 9af5a29f7c..802ff1a684 100644 --- a/backend/apps/owasp/models/mixins/project.py +++ b/backend/apps/owasp/models/mixins/project.py @@ -2,6 +2,8 @@ from __future__ import annotations +from typing import Any + from django.conf import settings from apps.common.utils import join_values @@ -19,73 +21,143 @@ class ProjectIndexMixin(RepositoryBasedEntityModelMixin): @property def idx_companies(self) -> str: - """Return companies for indexing.""" + """Return companies for indexing. + + Returns: + str: A space-separated string of company names. + + """ return join_values(fields=[o.company for o in self.organizations.all()]) @property def idx_contributors_count(self) -> int: - """Return contributors count for indexing.""" + """Return contributors count for indexing. + + Returns: + int: The total number of contributors to the project. + + """ return self.contributors_count @property def idx_custom_tags(self) -> str: - """Return custom tags for indexing.""" + """Return custom tags for indexing. + + Returns: + str: Custom tags associated with the project. + + """ return self.custom_tags @property def idx_forks_count(self) -> int: - """Return forks count for indexing.""" + """Return forks count for indexing. + + Returns: + int: The total number of forks across project repositories. + + """ return self.forks_count @property def idx_health_score(self) -> float | None: - """Return health score for indexing.""" + """Return health score for indexing. + + Returns: + float | None: The health score or None. + + """ # TODO(arkid15r): Enable real health score in production when ready. return DEFAULT_HEALTH_SCORE if settings.IS_PRODUCTION_ENVIRONMENT else self.health_score @property def idx_is_active(self) -> bool: - """Return active status for indexing.""" + """Return active status for indexing. + + Returns: + bool: True if the project is active, False otherwise. + + """ return self.is_active @property def idx_issues_count(self) -> int: - """Return issues count for indexing.""" + """Return issues count for indexing. + + Returns: + int: The number of open issues in the project. + + """ return self.open_issues.count() @property def idx_key(self) -> str: - """Return key for indexing.""" + """Return key for indexing. + + Returns: + str: The project key. + + """ return self.key.replace("www-project-", "") @property def idx_languages(self) -> list[str]: - """Return languages for indexing.""" + """Return languages for indexing. + + Returns: + list[str]: A list of programming languages used in the project. + + """ return self.languages @property def idx_level(self) -> str: - """Return level text value for indexing.""" + """Return level text value for indexing. + + Returns: + str: The project level as text. + + """ return self.level @property def idx_level_raw(self) -> float | None: - """Return level for indexing.""" + """Return raw level for indexing. + + Returns: + float | None: The raw numeric level of the project. + + """ return float(self.level_raw) if self.level_raw else None @property def idx_name(self) -> str: - """Return name for indexing.""" + """Return name for indexing. + + Returns: + str: The name of the project. + + """ return self.name or " ".join(self.key.replace("www-project-", "").capitalize().split("-")) @property def idx_organizations(self) -> str: - """Return organizations for indexing.""" + """Return organizations for indexing. + + Returns: + str: A space-separated string of organization names. + + """ return join_values(fields=[o.name for o in self.organizations.all()]) @property - def idx_repositories(self) -> list[dict]: - """Return repositories for indexing.""" + def idx_repositories(self) -> list[dict[str, Any]]: + """Return repositories for indexing. + + Returns: + list[dict[str, Any]]: A list of repository details for the project. + + """ return [ { "contributors_count": r.contributors_count, @@ -103,25 +175,51 @@ def idx_repositories(self) -> list[dict]: @property def idx_repositories_count(self) -> int: - """Return repositories count for indexing.""" + """Return repositories count for indexing. + + Returns: + int: The total number of repositories in the project. + + """ return self.repositories.count() @property def idx_stars_count(self) -> int: - """Return stars count for indexing.""" + """Return stars count for indexing. + + Returns: + int: The total number of stars across project repositories. + + """ return self.stars_count @property - def idx_top_contributors(self) -> list: - """Return top contributors for indexing.""" + def idx_top_contributors(self) -> list[dict[str, Any]]: + """Return top contributors for indexing. + + Returns: + list[dict[str, Any]]: A list of top contributor details for the project. + + """ return RepositoryContributor.get_top_contributors(project=self.key) @property def idx_type(self) -> str: - """Return type for indexing.""" + """Return type for indexing. + + Returns: + str: The type of the project. + + """ return self.type @property def idx_updated_at(self) -> str | float: - """Return updated at for indexing.""" + """Return updated at timestamp for indexing. + + Returns: + str | float: The project's last update timestamp as a float, + or empty string if unavailable. + + """ return self.updated_at.timestamp() if self.updated_at else ""