From 6d74bccb7d38beddd06abe76ff6dfe542ca87a1d Mon Sep 17 00:00:00 2001 From: George Katsikas <giorgakis.katsikas@gmail.com> Date: Thu, 21 Sep 2023 17:41:24 +0200 Subject: [PATCH] refactor templates to return all projects used update git repo creation to handle collection papers --- scipost_django/production/admin.py | 5 +- .../management/commands/advance_git_repos.py | 62 +++++++++++++------ scipost_django/production/models.py | 50 ++++++++++++--- .../production/tests/test_models.py | 8 +-- 4 files changed, 91 insertions(+), 34 deletions(-) diff --git a/scipost_django/production/admin.py b/scipost_django/production/admin.py index 191991474..0df3196c3 100644 --- a/scipost_django/production/admin.py +++ b/scipost_django/production/admin.py @@ -109,12 +109,15 @@ class ProofsRepositoryAdmin(GuardedModelAdmin): list_filter = ["status"] list_display = ["name", "status", "gitlab_link"] - readonly_fields = ["stream", "template_path", "gitlab_link"] + readonly_fields = ["stream", "template_paths", "gitlab_link"] def gitlab_link(self, obj): return format_html( '<a href="{1}" target="_blank">{0}</a>', obj.git_path, obj.git_url ) + def template_paths(self, obj): + return format_html("<br>".join(obj.template_paths)) + admin.site.register(ProofsRepository, ProofsRepositoryAdmin) diff --git a/scipost_django/production/management/commands/advance_git_repos.py b/scipost_django/production/management/commands/advance_git_repos.py index ae1ec0bae..42da5e382 100644 --- a/scipost_django/production/management/commands/advance_git_repos.py +++ b/scipost_django/production/management/commands/advance_git_repos.py @@ -161,9 +161,17 @@ class Command(BaseCommand): """ Return a list of gitlab actions required to fully clone a project. """ - filenames = list( - map(lambda x: x["path"], project.repository_tree(get_all=True)) - ) + try: + filenames = list( + map(lambda x: x["path"], project.repository_tree(get_all=True)) + ) + except: + self.stdout.write( + self.style.WARNING( + f"Could not get the files of {project.path_with_namespace}, it may be empty" + ) + ) + return [] actions = [] for filename in filenames: @@ -192,24 +200,23 @@ class Command(BaseCommand): """ project = self.GL.projects.get(repo.git_path) - journal_template_project = self.GL.projects.get(repo.template_path) - base_template_project = self.GL.projects.get( - "{ROOT}/Templates/Base".format(ROOT=settings.GITLAB_ROOT) - ) + # Get the cloning actions for each template project + actions = [ + self._get_project_cloning_actions(self.GL.projects.get(template_path)) + for template_path in repo.template_paths + ] + actions = list(chain(*actions)) # Flatten the list of lists - all_actions = [] - # Add "Base" and Journal specific templates to the repo - all_actions.append(self._get_project_cloning_actions(base_template_project)) - all_actions.append(self._get_project_cloning_actions(journal_template_project)) + # Keep the last action if there are multiple actions for the same file + # (i.e. the same file_path key in the dictionary) + non_duplicate_actions = [] + file_paths_to_clone = [] - # Add the "Selected" template if the submission has been accepted in Selections - if "Selections" in repo.stream.submission.editorial_decision.for_journal.name: - selected_template_project = self.GL.projects.get( - "{ROOT}/Templates/Selected".format(ROOT=settings.GITLAB_ROOT) - ) - all_actions.append( - self._get_project_cloning_actions(selected_template_project) - ) + for action in reversed(actions): + file_path = action.get("file_path", None) + if (file_path is not None) and (file_path not in file_paths_to_clone): + file_paths_to_clone.append(file_path) + non_duplicate_actions.append(action) # Add some delays to avoid: # - Commiting the files before the branch has finished being created @@ -220,7 +227,7 @@ class Command(BaseCommand): { "branch": "main", "commit_message": "copy pure templates", - "actions": list(chain(*all_actions)), + "actions": non_duplicate_actions, } ) sleep(3) @@ -396,6 +403,21 @@ class Command(BaseCommand): selections_logo_img = r"[width=34.55mm]{logo_select.pdf}" replacements_dict[default_logo_img] = (lambda _: selections_logo_img, None) + # Add collection specific information if the submission is part of a collection + if repo.stream.submission.collections.exists(): + collection = repo.stream.submission.collections.first() + series = collection.series + + collection_replacements_dict = { + "<|COLLECTION_NAME|>": (lambda _: collection.name, None), + "<|COLLECTION_URL|>": (lambda _: collection.get_absolute_url(), None), + "<|EVENT_DETAILS|>": (lambda _: collection.event_details, None), + "<|SERIES_NAME|>": (lambda _: series.name, None), + "<|SERIES_URL|>": (lambda _: series.get_absolute_url(), None), + } + + replacements_dict.update(collection_replacements_dict) + # Define a helper function to try to format and replace a placeholder # which catches any errors and prints them to the console non-intrusively def try_format_replace( diff --git a/scipost_django/production/models.py b/scipost_django/production/models.py index 2b6fbd925..44fe27351 100644 --- a/scipost_django/production/models.py +++ b/scipost_django/production/models.py @@ -2,6 +2,7 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)" __license__ = "AGPL v3" +from typing import List from django.db import models from django.contrib.contenttypes.fields import GenericRelation from django.urls import reverse @@ -410,22 +411,53 @@ class ProofsRepository(models.Model): git_path=self.git_path, ) - @property - def template_path(self) -> str: + @cached_property + def template_paths(self) -> List[str]: """ - Return the path to the template repository. + Return the list of paths to the various templates used for the proofs. """ + paths = ["{ROOT}/Templates/Base".format(ROOT=settings.GITLAB_ROOT)] + + # Determine whether to add the proceedings template or of some other journal if self.stream.submission.proceedings is not None: - return "{ROOT}/Templates/{journal_subdivision}".format( - ROOT=settings.GITLAB_ROOT, - journal_subdivision=self.journal_subdivision, + paths.append( + "{ROOT}/Templates/{journal_subdivision}".format( + ROOT=settings.GITLAB_ROOT, + journal_subdivision=self.journal_subdivision, + ) ) + # Add extra paths for any collections associated with the submission + # First add the base template for the series and then the collection + elif collections := self.stream.submission.collections.all(): + for collection in collections: + paths.append( + "{ROOT}/Templates/Series/{series}/Base".format( + ROOT=settings.GITLAB_ROOT, + series=collection.series.slug, + collection=collection.slug, + ) + ) + paths.append( + "{ROOT}/Templates/Series/{series}/{collection}".format( + ROOT=settings.GITLAB_ROOT, + series=collection.series.slug, + collection=collection.slug, + ) + ) else: - return "{ROOT}/Templates/{journal}".format( - ROOT=settings.GITLAB_ROOT, - journal=self.journal_abbrev, + paths.append( + "{ROOT}/Templates/{journal}".format( + ROOT=settings.GITLAB_ROOT, + journal=self.journal_abbrev, + ) ) + # Add the selected template if the submission is a Selections paper + if "Selections" in self.stream.submission.editorial_decision.for_journal.name: + paths.append("{ROOT}/Templates/Selected".format(ROOT=settings.GITLAB_ROOT)) + + return paths + def __str__(self) -> str: return f"Proofs repo for {self.stream}" diff --git a/scipost_django/production/tests/test_models.py b/scipost_django/production/tests/test_models.py index e82a62c0c..dcaee0bdb 100644 --- a/scipost_django/production/tests/test_models.py +++ b/scipost_django/production/tests/test_models.py @@ -207,8 +207,8 @@ class TestProofRepository(TestCase): "ProjectRoot/Proofs/SciPostPhys/2021/01/scipost_202101_00001v1_User", ) - self.assertEqual( - proofs_repo.template_path, + self.assertIn( + proofs_repo.template_paths, "ProjectRoot/Templates/SciPostPhys", ) @@ -254,7 +254,7 @@ class TestProofRepository(TestCase): "ProjectRoot/Proofs/SciPostPhysProc/2021/ProcName21/scipost_202101_00001v1_User", ) - self.assertEqual( - proofs_repo.template_path, + self.assertIn( + proofs_repo.template_paths, "ProjectRoot/Templates/SciPostPhysProc/2021/ProcName21", ) -- GitLab