diff --git a/readthedocs/api/v2/utils.py b/readthedocs/api/v2/utils.py index c5a0bc8bfee..c16b351bb33 100644 --- a/readthedocs/api/v2/utils.py +++ b/readthedocs/api/v2/utils.py @@ -15,6 +15,7 @@ from readthedocs.builds.constants import STABLE from readthedocs.builds.constants import STABLE_VERBOSE_NAME from readthedocs.builds.constants import TAG +from readthedocs.builds.datatypes import VersionData from readthedocs.builds.models import RegexAutomationRule from readthedocs.builds.models import Version @@ -168,10 +169,13 @@ def _set_or_create_version(project, slug, version_id, verbose_name, type_): def _get_deleted_versions_qs(project, tags_data, branches_data): + # Convert to VersionData if not already + tags_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in tags_data] + branches_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in branches_data] # We use verbose_name for tags # because several tags can point to the same identifier. - versions_tags = [version["verbose_name"] for version in tags_data] - versions_branches = [version["identifier"] for version in branches_data] + versions_tags = [version.verbose_name for version in tags_data] + versions_branches = [version.identifier for version in branches_data] to_delete_qs = ( project.versions(manager=INTERNAL) @@ -196,6 +200,9 @@ def delete_versions_from_db(project, tags_data, branches_data): :returns: The slug of the deleted versions from the database. """ + # Convert to VersionData if not already + tags_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in tags_data] + branches_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in branches_data] to_delete_qs = _get_deleted_versions_qs( project=project, tags_data=tags_data, @@ -212,6 +219,9 @@ def delete_versions_from_db(project, tags_data, branches_data): def get_deleted_active_versions(project, tags_data, branches_data): """Return the slug of active versions that were deleted from the repository.""" + # Convert to VersionData if not already + tags_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in tags_data] + branches_data = [VersionData(**v) if not isinstance(v, VersionData) else v for v in branches_data] to_delete_qs = _get_deleted_versions_qs( project=project, tags_data=tags_data, diff --git a/readthedocs/builds/datatypes.py b/readthedocs/builds/datatypes.py new file mode 100644 index 00000000000..eebc72f59a1 --- /dev/null +++ b/readthedocs/builds/datatypes.py @@ -0,0 +1,6 @@ +from dataclasses import dataclass + +@dataclass +class VersionData: + identifier: str + verbose_name: str \ No newline at end of file diff --git a/readthedocs/builds/tasks.py b/readthedocs/builds/tasks.py index f23c8f2aa58..f62d6ea89b0 100644 --- a/readthedocs/builds/tasks.py +++ b/readthedocs/builds/tasks.py @@ -1,5 +1,6 @@ import json from io import BytesIO +import dataclasses import requests import structlog @@ -25,6 +26,7 @@ from readthedocs.builds.constants import LOCK_EXPIRE from readthedocs.builds.constants import MAX_BUILD_COMMAND_SIZE from readthedocs.builds.constants import TAG +from readthedocs.builds.datatypes import VersionData from readthedocs.builds.models import Build from readthedocs.builds.models import Version from readthedocs.builds.reporting import get_build_overview @@ -294,6 +296,8 @@ def sync_versions_task(project_pk, tags_data, branches_data, **kwargs): ]. :returns: `True` or `False` if the task succeeded. """ + tags_data = [VersionData(**d) for d in tags_data] + branches_data = [VersionData(**d) for d in branches_data] project = Project.objects.get(pk=project_pk) # If the currently highest non-prerelease version is active, then make @@ -309,27 +313,27 @@ def sync_versions_task(project_pk, tags_data, branches_data, **kwargs): added_versions = set() result = sync_versions_to_db( project=project, - versions=tags_data, + versions=[dataclasses.asdict(v) for v in tags_data], type=TAG, ) added_versions.update(result) result = sync_versions_to_db( project=project, - versions=branches_data, + versions=[dataclasses.asdict(v) for v in branches_data], type=BRANCH, ) added_versions.update(result) delete_versions_from_db( project=project, - tags_data=tags_data, - branches_data=branches_data, + tags_data=[dataclasses.asdict(v) for v in tags_data], + branches_data=[dataclasses.asdict(v) for v in branches_data], ) deleted_active_versions = get_deleted_active_versions( project=project, - tags_data=tags_data, - branches_data=branches_data, + tags_data=[dataclasses.asdict(v) for v in tags_data], + branches_data=[dataclasses.asdict(v) for v in branches_data], ) except Exception: log.exception("Sync Versions Error") diff --git a/readthedocs/projects/tasks/mixins.py b/readthedocs/projects/tasks/mixins.py index d7df81dcc09..0391c04a2fc 100644 --- a/readthedocs/projects/tasks/mixins.py +++ b/readthedocs/projects/tasks/mixins.py @@ -6,6 +6,8 @@ from readthedocs.builds.constants import LATEST_VERBOSE_NAME from readthedocs.builds.constants import STABLE_VERBOSE_NAME from readthedocs.builds.models import APIVersion +from readthedocs.builds.datatypes import VersionData +import dataclasses from ..exceptions import RepositoryError from ..models import Feature @@ -50,18 +52,12 @@ def sync_versions(self, vcs_repository): ) tags_data = [ - { - "identifier": v.identifier, - "verbose_name": v.verbose_name, - } + VersionData(identifier=v.identifier, verbose_name=v.verbose_name) for v in tags ] branches_data = [ - { - "identifier": v.identifier, - "verbose_name": v.verbose_name, - } + VersionData(identifier=v.identifier, verbose_name=v.verbose_name) for v in branches ] @@ -74,8 +70,8 @@ def sync_versions(self, vcs_repository): build_tasks.sync_versions_task.delay( project_pk=self.data.project.pk, - tags_data=tags_data, - branches_data=branches_data, + tags_data=[dataclasses.asdict(v) for v in tags_data], + branches_data=[dataclasses.asdict(v) for v in branches_data], ) def validate_duplicate_reserved_versions(self, tags_data, branches_data): @@ -88,7 +84,7 @@ def validate_duplicate_reserved_versions(self, tags_data, branches_data): :param data: Dict containing the versions from tags and branches """ - version_names = [version["verbose_name"] for version in tags_data + branches_data] + version_names = [version.verbose_name for version in tags_data + branches_data] counter = Counter(version_names) for reserved_name in [STABLE_VERBOSE_NAME, LATEST_VERBOSE_NAME]: if counter[reserved_name] > 1: