From 595e02f3dab8ad1e01a86955e726b6360a1d9e2b Mon Sep 17 00:00:00 2001 From: Jorran de Wit <jorrandewit@outlook.com> Date: Sat, 10 Mar 2018 17:38:56 +0100 Subject: [PATCH] Ready --- funders/forms.py | 4 +- journals/behaviors.py | 10 +- journals/constants.py | 3 +- journals/forms.py | 271 ++++++++++++------ journals/managers.py | 33 ++- journals/models.py | 19 ++ journals/templates/journals/_base.html | 2 +- journals/templates/journals/add_author.html | 2 - .../templates/journals/journal_accepted.html | 2 +- .../journals/journal_issue_detail.html | 4 +- .../templates/journals/journal_issues.html | 2 +- .../journals/journal_landing_page.html | 18 +- .../templates/journals/journal_recent.html | 2 +- journals/templates/journals/journals.html | 8 +- .../templates/journals/manage_metadata.html | 46 ++- .../journals/publication_detail.html | 2 +- .../templates/journals/publication_form.html | 2 +- .../templates/xml/publication_crossref.html | 48 ++-- journals/urls/general.py | 50 ++-- journals/urls/journal.py | 6 +- journals/views.py | 208 ++++++++------ .../scipost/assets/css/_list_group.scss | 4 + scipost/urls.py | 10 +- .../submissions/submission_list.html | 2 +- submissions/views.py | 25 +- 25 files changed, 505 insertions(+), 278 deletions(-) diff --git a/funders/forms.py b/funders/forms.py index a5c7d8d29..a88322618 100644 --- a/funders/forms.py +++ b/funders/forms.py @@ -28,9 +28,9 @@ class GrantForm(HttpRefererFormMixin, forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['recipient'] = forms.ModelChoiceField( - queryset=Contributor.objects.all().order_by('user__last_name'), + queryset=Contributor.objects.select_related('user').order_by('user__last_name'), required=False) class GrantSelectForm(forms.Form): - grant = forms.ModelChoiceField(queryset=Grant.objects.all()) + grant = forms.ModelChoiceField(queryset=Grant.objects.all().select_related('funder')) diff --git a/journals/behaviors.py b/journals/behaviors.py index eca874354..8079e19c7 100644 --- a/journals/behaviors.py +++ b/journals/behaviors.py @@ -1,5 +1,8 @@ from django.core.validators import RegexValidator +from .constants import PUBLICATION_DOI_VALIDATION_REGEX + + doi_journal_validator = RegexValidator(r'^[a-zA-Z]+$', 'Only valid DOI expressions are allowed ([a-zA-Z]+).') doi_volume_validator = RegexValidator(r'^[a-zA-Z]+.[0-9]+$', @@ -7,6 +10,7 @@ doi_volume_validator = RegexValidator(r'^[a-zA-Z]+.[0-9]+$', doi_issue_validator = RegexValidator(r'^[a-zA-Z]+.[0-9]+.[0-9]+$', ('Only valid DOI expressions are allowed ' '([a-zA-Z]+.[0-9]+.[0-9]+).')) -doi_publication_validator = RegexValidator(r'^[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,}$', - ('Only valid DOI expressions are allowed ' - '([a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,}).')) +doi_publication_validator = RegexValidator( + r'^{regex}$'.format(regex=PUBLICATION_DOI_VALIDATION_REGEX), + ('Only valid DOI expressions are allowed ' + '(`[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,}` or `[a-zA-Z]+.[0-9]+`)')) diff --git a/journals/constants.py b/journals/constants.py index ac2bd20b3..60a544014 100644 --- a/journals/constants.py +++ b/journals/constants.py @@ -26,6 +26,7 @@ REGEX_CHOICES = '|'.join([ SCIPOST_JOURNAL_PHYSICS ]) +PUBLICATION_DOI_REGEX = PUBLICATION_DOI_VALIDATION_REGEX = '[a-zA-Z]+.[0-9]+(.[0-9]+.[0-9]{3,})?' SCIPOST_JOURNALS_DOMAINS = ( ('E', 'Experimental'), @@ -85,6 +86,6 @@ ISSUES_ONLY = 'IO' INDIVIDUAL_PUBLCATIONS = 'IP' JOURNAL_STRUCTURE = ( (ISSUES_AND_VOLUMES, 'Issues and Volumes'), - (ISSUES_ONLY, 'Issues only'), + # (ISSUES_ONLY, 'Issues only'), # This option complies with Crossref's rules, but is not implemented (yet). (INDIVIDUAL_PUBLCATIONS, 'Individual Publications'), ) diff --git a/journals/forms.py b/journals/forms.py index bba8de058..4464d567a 100644 --- a/journals/forms.py +++ b/journals/forms.py @@ -19,6 +19,7 @@ from .utils import JournalUtils from funders.models import Grant, Funder +from journals.models import Journal from mails.utils import DirectMailUtil from production.constants import PROOFS_PUBLISHED from production.models import ProductionEvent @@ -127,17 +128,20 @@ class CreateMetadataXMLForm(forms.ModelForm): class CreateMetadataDOAJForm(forms.ModelForm): class Meta: model = Publication - fields = () + fields = ['metadata_DOAJ'] def __init__(self, *args, **kwargs): self.request = kwargs.pop('request') + kwargs['initial'] = { + 'metadata_DOAJ': self.generate(kwargs.get('instance')) + } super().__init__(*args, **kwargs) - def save(self, *args, **kwargs): - self.instance.metadata_DOAJ = self.generate(self.instance) - return super().save(*args, **kwargs) - def generate(self, publication): + if publication.in_issue: + issn = str(publication.in_issue.in_volume.in_journal.issn) + else: + issn = str(publication.in_journal.issn) md = { 'bibjson': { 'author': [{'name': publication.author_list}], @@ -149,7 +153,7 @@ class CreateMetadataDOAJForm(forms.ModelForm): 'identifier': [ { 'type': 'eissn', - 'id': str(publication.in_issue.in_volume.in_journal.issn) + 'id': issn }, { 'type': 'doi', @@ -162,28 +166,48 @@ class CreateMetadataDOAJForm(forms.ModelForm): 'type': 'fulltext', } ], - 'journal': { - 'publisher': 'SciPost', - 'volume': str(publication.in_issue.in_volume.number), - 'number': str(publication.in_issue.number), - 'identifier': [{ - 'type': 'eissn', - 'id': str(publication.in_issue.in_volume.in_journal.issn) - }], - 'license': [ - { - 'url': self.request.build_absolute_uri( - publication.in_issue.in_volume.in_journal.get_absolute_url()), - 'open_access': 'true', - 'type': publication.get_cc_license_display(), - 'title': publication.get_cc_license_display(), - } - ], - 'language': ['EN'], - 'title': publication.in_issue.in_volume.in_journal.get_name_display(), - } } } + if publication.in_issue: + md['journal'] = { + 'publisher': 'SciPost', + 'volume': str(publication.in_issue.in_volume.number), + 'number': str(publication.in_issue.number), + 'identifier': [{ + 'type': 'eissn', + 'id': issn + }], + 'license': [ + { + 'url': self.request.build_absolute_uri( + publication.in_issue.in_volume.in_journal.get_absolute_url()), + 'open_access': 'true', + 'type': publication.get_cc_license_display(), + 'title': publication.get_cc_license_display(), + } + ], + 'language': ['EN'], + 'title': publication.in_issue.in_volume.in_journal.get_name_display(), + } + else: + md['journal'] = { + 'publisher': 'SciPost', + 'identifier': [{ + 'type': 'eissn', + 'id': issn + }], + 'license': [ + { + 'url': self.request.build_absolute_uri( + publication.in_journal.get_absolute_url()), + 'open_access': 'true', + 'type': publication.get_cc_license_display(), + 'title': publication.get_cc_license_display(), + } + ], + 'language': ['EN'], + 'title': publication.in_journal.get_name_display(), + } return md @@ -306,20 +330,32 @@ class DraftPublicationForm(forms.ModelForm): # Use separate instance to be able to prefill the form without any existing Publication self.submission = None self.issue = None + self.to_journal = None if arxiv_identifier_w_vn_nr: try: self.submission = Submission.objects.accepted().get( arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) except Submission.DoesNotExist: self.submission = None - if issue_id: + + # Check if the Submission is related to a Journal with individual Publications only + if self.submission: + try: + self.to_journal = Journal.objects.has_individual_publications().get( + name=self.submission.submitted_to_journal) + except Journal.DoesNotExist: + self.to_journal = None + + # If the Journal is not for individual publications, choose a Issue for Publication + if issue_id and not self.to_journal: try: self.issue = self.get_possible_issues().get(id=issue_id) except Issue.DoesNotExist: self.issue = None super().__init__(data, *args, **kwargs) - if kwargs.get('instance') or self.issue: + + if kwargs.get('instance') or self.issue or self.to_journal: # When updating: fix in_issue, because many fields are directly related to the issue. del self.fields['in_issue'] self.prefill_fields() @@ -328,7 +364,10 @@ class DraftPublicationForm(forms.ModelForm): self.delete_secondary_fields() def get_possible_issues(self): - return Issue.objects.filter(until_date__gte=timezone.now()) + issues = Issue.objects.filter(until_date__gte=timezone.now()) + if self.submission: + issues = issues.for_journal(self.submission.submitted_to_journal) + return issues def delete_secondary_fields(self): """ @@ -351,6 +390,17 @@ class DraftPublicationForm(forms.ModelForm): del self.fields['acceptance_date'] del self.fields['publication_date'] + def clean(self): + data = super().clean() + if not self.instance.id: + if self.submission: + self.instance.accepted_submission = self.submission + if self.issue: + self.instance.in_issue = self.issue + if self.to_journal: + self.instance.in_journal = self.to_journal + return data + def save(self, *args, **kwargs): """ Save the Publication object always as a draft and prefill the Publication with @@ -359,10 +409,7 @@ class DraftPublicationForm(forms.ModelForm): do_prefill = False if not self.instance.id: do_prefill = True - if self.submission: - self.instance.accepted_submission = self.submission - self.instance.in_issue = self.issue - self.instance = super().save(*args, **kwargs) + super().save(*args, **kwargs) if do_prefill: self.first_time_fill() return self.instance @@ -398,51 +445,101 @@ class DraftPublicationForm(forms.ModelForm): self.fields['secondary_areas'].initial = self.submission.secondary_areas self.fields['submission_date'].initial = self.submission.submission_date self.fields['acceptance_date'].initial = self.submission.acceptance_date + self.fields['publication_date'].initial = timezone.now() # Fill data that may be derived from the issue data - issue = self.instance.in_issue if hasattr(self.instance, 'in_issue') else self.issue + issue = None + if hasattr(self.instance, 'in_issue') and self.instance.in_issue: + issue = self.instance.in_issue + elif self.issue: + issue = self.issue if issue: - # Determine next available paper number: - paper_nr = Publication.objects.filter(in_issue__in_volume=issue.in_volume).count() - paper_nr += paper_nr - if paper_nr > 999: - raise PaperNumberingError(paper_nr) - self.fields['paper_nr'].initial = str(paper_nr) - doi_label = '{journal}.{vol}.{issue}.{paper}'.format( - journal=issue.in_volume.in_journal.name, - vol=issue.in_volume.number, - issue=issue.number, - paper=str(paper_nr).rjust(3, '0')) - self.fields['doi_label'].initial = doi_label - - doi_string = '10.21468/{doi}'.format(doi=doi_label) - bibtex_entry = ( - '@Article{%s,\n' - '\ttitle={{%s},\n' - '\tauthor={%s},\n' - '\tjournal={%s},\n' - '\tvolume={%i},\n' - '\tissue={%i},\n' - '\tpages={%i},\n' - '\tyear={%s},\n' - '\tpublisher={SciPost},\n' - '\tdoi={%s},\n' - '\turl={https://scipost.org/%s},\n' - '}' - ) % ( - doi_string, - self.submission.title, - self.submission.author_list.replace(',', ' and'), - issue.in_volume.in_journal.abbreviation_citation, - issue.in_volume.number, - issue.number, - paper_nr, - issue.until_date.strftime('%Y'), - doi_string, - doi_string) - self.fields['BiBTeX_entry'].initial = bibtex_entry - if not self.instance.BiBTeX_entry: - self.instance.BiBTeX_entry = bibtex_entry + self.prefill_with_issue(issue) + + # Fill data that may be derived from the issue data + journal = None + if hasattr(self.instance, 'in_journal') and self.instance.in_journal: + journal = self.instance.in_issue + elif self.to_journal: + journal = self.to_journal + if journal: + self.prefill_with_journal(journal) + + def prefill_with_issue(self, issue): + # Determine next available paper number: + paper_nr = Publication.objects.filter(in_issue__in_volume=issue.in_volume).count() + 1 + if paper_nr > 999: + raise PaperNumberingError(paper_nr) + self.fields['paper_nr'].initial = str(paper_nr) + doi_label = '{journal}.{vol}.{issue}.{paper}'.format( + journal=issue.in_volume.in_journal.name, + vol=issue.in_volume.number, + issue=issue.number, + paper=str(paper_nr).rjust(3, '0')) + self.fields['doi_label'].initial = doi_label + + doi_string = '10.21468/{doi}'.format(doi=doi_label) + bibtex_entry = ( + '@Article{%s,\n' + '\ttitle={{%s},\n' + '\tauthor={%s},\n' + '\tjournal={%s},\n' + '\tvolume={%i},\n' + '\tissue={%i},\n' + '\tpages={%i},\n' + '\tyear={%s},\n' + '\tpublisher={SciPost},\n' + '\tdoi={%s},\n' + '\turl={https://scipost.org/%s},\n' + '}' + ) % ( + doi_string, + self.submission.title, + self.submission.author_list.replace(',', ' and'), + issue.in_volume.in_journal.abbreviation_citation, + issue.in_volume.number, + issue.number, + paper_nr, + issue.until_date.strftime('%Y'), + doi_string, + doi_string) + self.fields['BiBTeX_entry'].initial = bibtex_entry + if not self.instance.BiBTeX_entry: + self.instance.BiBTeX_entry = bibtex_entry + + def prefill_with_journal(self, journal): + # Determine next available paper number: + paper_nr = journal.publications.count() + 1 + self.fields['paper_nr'].initial = str(paper_nr) + doi_label = '{journal}.{paper}'.format( + journal=journal.name, + paper=paper_nr) + self.fields['doi_label'].initial = doi_label + + doi_string = '10.21468/{doi}'.format(doi=doi_label) + bibtex_entry = ( + '@Article{%s,\n' + '\ttitle={{%s},\n' + '\tauthor={%s},\n' + '\tjournal={%s},\n' + '\tpages={%i},\n' + '\tyear={%s},\n' + '\tpublisher={SciPost},\n' + '\tdoi={%s},\n' + '\turl={https://scipost.org/%s},\n' + '}' + ) % ( + doi_string, + self.submission.title, + self.submission.author_list.replace(',', ' and'), + journal.abbreviation_citation, + paper_nr, + timezone.now().year, + doi_string, + doi_string) + self.fields['BiBTeX_entry'].initial = bibtex_entry + if not self.instance.BiBTeX_entry: + self.instance.BiBTeX_entry = bibtex_entry class DraftPublicationApprovalForm(forms.ModelForm): @@ -483,14 +580,24 @@ class PublicationPublishForm(RequestFormMixin, forms.ModelForm): fields = [] def move_pdf(self): - # Move file to final location + """ + To keep the Publication pdfs organized we move the pdfs to their own folder + organized by journal and optional issue folder. + """ initial_path = self.instance.pdf_file.path - new_dir = (settings.MEDIA_ROOT + self.instance.in_issue.path + '/' - + self.instance.get_paper_nr()) - new_path = new_dir + '/' + self.instance.doi_label.replace('.', '_') + '.pdf' - os.makedirs(new_dir) - os.rename(initial_path, new_path) - self.instance.pdf_file.name = new_path + + new_dir = '' + if self.instance.in_issue: + new_dir += self.instance.in_issue.path + elif self.instance.in_journal: + new_dir += 'SCIPOST_JOURNALS/{name}'.format(name=self.instance.in_journal.name) + + new_dir += '/{paper_nr}'.format(paper_nr=self.instance.get_paper_nr()) + os.makedirs(settings.MEDIA_ROOT + new_dir) + + new_dir += '/{doi}.pdf'.format(doi=self.instance.doi_label.replace('.', '_')) + os.rename(initial_path, settings.MEDIA_ROOT + new_dir) + self.instance.pdf_file.name = new_dir self.instance.status = PUBLICATION_PUBLISHED self.instance.save() diff --git a/journals/managers.py b/journals/managers.py index 573836301..8bddbf37b 100644 --- a/journals/managers.py +++ b/journals/managers.py @@ -2,7 +2,7 @@ from django.db import models from django.utils import timezone from .constants import STATUS_PUBLISHED, STATUS_DRAFT, PUBLICATION_PUBLISHED, ISSUES_AND_VOLUMES,\ - ISSUES_ONLY + ISSUES_ONLY, INDIVIDUAL_PUBLCATIONS class JournalQuerySet(models.QuerySet): @@ -12,19 +12,21 @@ class JournalQuerySet(models.QuerySet): def has_issues(self): return self.filter(structure__in=(ISSUES_AND_VOLUMES, ISSUES_ONLY)) + def has_individual_publications(self): + return self.filter(structure=INDIVIDUAL_PUBLCATIONS) + class IssueQuerySet(models.QuerySet): - def published(self, journal=None): - issues = self.filter(status=STATUS_PUBLISHED) - if journal: - issues.filter(in_volume__in_journal=journal) - return issues - - def in_draft(self, journal=None): - issues = self.filter(status=STATUS_DRAFT) - if journal: - issues.filter(in_volume__in_journal=journal) - return issues + def published(self): + return self.filter(status=STATUS_PUBLISHED) + + def in_draft(self): + return self.filter(status=STATUS_DRAFT) + + def for_journal(self, journal_name): + return self.filter( + models.Q(in_volume__in_journal__name=journal_name) | + models.Q(in_journal__name=journal_name)) def get_current_issue(self): return self.published( @@ -32,7 +34,7 @@ class IssueQuerySet(models.QuerySet): class PublicationQuerySet(models.QuerySet): - def published(self, **kwargs): + def published(self): return self.filter(status=PUBLICATION_PUBLISHED).filter( models.Q(in_issue__status=STATUS_PUBLISHED) | models.Q(in_journal__active=True)) @@ -44,3 +46,8 @@ class PublicationQuerySet(models.QuerySet): def drafts(self): return self.filter(status=STATUS_DRAFT) + + def for_journal(self, journal_name): + return self.filter( + models.Q(in_issue__in_volume__in_journal__name=journal_name) | + models.Q(in_journal__name=journal_name)) diff --git a/journals/models.py b/journals/models.py index f33359a32..5b755195e 100644 --- a/journals/models.py +++ b/journals/models.py @@ -109,6 +109,20 @@ class Journal(models.Model): def abbreviation_citation(self): return journal_name_abbrev_citation(self.name) + def get_issues(self): + if self.structure == ISSUES_AND_VOLUMES: + return Issue.objects.filter(in_volume__in_journal=self) + elif self.structure == ISSUES_ONLY: + return self.issues.all() + return Issue.objects.none() + + def get_publications(self): + if self.structure == ISSUES_AND_VOLUMES: + return Publication.objects.filter(in_issue__in_volume__in_journal=self) + elif self.structure == ISSUES_ONLY: + return Publication.objects.filter(in_issue__in_journal=self) + return self.publications.all() + def nr_publications(self, tier=None): publications = Publication.objects.filter(in_issue__in_volume__in_journal=self) if tier: @@ -153,6 +167,7 @@ class Volume(models.Model): validators=[doi_volume_validator]) class Meta: + default_related_name = 'volumes' unique_together = ('number', 'in_journal') def __str__(self): @@ -227,6 +242,7 @@ class Issue(models.Model): objects = IssueQuerySet.as_manager() class Meta: + default_related_name = 'issues' ordering = ('-until_date',) unique_together = ('number', 'in_volume') @@ -495,6 +511,9 @@ class Publication(models.Model): year=self.publication_date.strftime('%Y')) return txt + def get_journal(self): + return self.in_journal or self.in_issue.in_volume.in_journal + def get_paper_nr(self): return paper_nr_string(self.paper_nr) diff --git a/journals/templates/journals/_base.html b/journals/templates/journals/_base.html index 2d17cbad6..e34dfe309 100644 --- a/journals/templates/journals/_base.html +++ b/journals/templates/journals/_base.html @@ -21,7 +21,7 @@ <div class="container mt-3"> <div class="row"> <div class="col journal"> - <h2 class="banner d-inline-block mr-2"><a href="{% url 'scipost:landing_page' journal.doi_label %}">{{journal}}</a></h2> + <h2 class="banner d-inline-block mr-2"><a href="{{ journal.get_absolute_url }}">{{journal}}</a></h2> <ul class="links"> {% if journal.active or request.user.is_staff %} {% if journal.has_issues %} diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html index 668919333..627dd1a06 100644 --- a/journals/templates/journals/add_author.html +++ b/journals/templates/journals/add_author.html @@ -7,8 +7,6 @@ <div class="container"> <nav class="breadcrumb hidden-sm-down"> <a href="{% url 'journals:journals' %}" class="breadcrumb-item">Journals</a> - <a href="{{publication.in_issue.in_volume.in_journal.get_absolute_url}}" class="breadcrumb-item">{{publication.in_issue.in_volume.in_journal}}</a> - <a href="{{publication.in_issue.get_absolute_url}}" class="breadcrumb-item">{{publication.in_issue.short_str}}</a> <a href="{{publication.get_absolute_url}}" class="breadcrumb-item">{{publication.citation}}</a> <span class="breadcrumb-item active">Add author to publication</span> diff --git a/journals/templates/journals/journal_accepted.html b/journals/templates/journals/journal_accepted.html index 2eb16483d..d5944bf76 100644 --- a/journals/templates/journals/journal_accepted.html +++ b/journals/templates/journals/journal_accepted.html @@ -19,7 +19,7 @@ <div class="row"> <div class="col-12"> <ul class="list-group list-group-flush"> - {% for submission in accepted_SP_submissions %} + {% for submission in accepted_submissions %} <li class="list-group-item"> <div class="card-body px-0"> {% include 'partials/submissions/submission_card_content.html' with submission=submission %} diff --git a/journals/templates/journals/journal_issue_detail.html b/journals/templates/journals/journal_issue_detail.html index 6b646613d..5b22c11f7 100644 --- a/journals/templates/journals/journal_issue_detail.html +++ b/journals/templates/journals/journal_issue_detail.html @@ -14,10 +14,10 @@ {% block journal_header_block %} {% if prev_issue %} - <h4 class="d-inline-block"><a href="{{prev_issue.get_absolute_url}}">< Previous issue | {{prev_issue.short_str}}</a></h4> + <h4 class="d-inline-block"><a href="{{prev_issue.get_absolute_url}}"><i class="fa fa-long-arrow-left"></i> Previous issue | {{prev_issue.short_str}}</a></h4> {% endif %} {% if next_issue %} - <h4 class="float-right d-inline-block"><a href="{{next_issue.get_absolute_url}}">{{next_issue.short_str}} | Next issue ></a></h4> + <h4 class="float-right d-inline-block"><a href="{{next_issue.get_absolute_url}}">{{next_issue.short_str}} | Next issue <i class="fa fa-long-arrow-right"></i></a></h4> {% endif %} {% endblock %} diff --git a/journals/templates/journals/journal_issues.html b/journals/templates/journals/journal_issues.html index 601a8c550..e69b81f25 100644 --- a/journals/templates/journals/journal_issues.html +++ b/journals/templates/journals/journal_issues.html @@ -18,7 +18,7 @@ <div class="row"> <div class="col-12"> <ul> - {% for issue in issues %} + {% for issue in journal.get_issues %} <li> <a href="{{issue.get_absolute_url}}">{{issue}}</a> {% if issue.proceedings %} diff --git a/journals/templates/journals/journal_landing_page.html b/journals/templates/journals/journal_landing_page.html index eac446d3c..98bae00dc 100644 --- a/journals/templates/journals/journal_landing_page.html +++ b/journals/templates/journals/journal_landing_page.html @@ -13,7 +13,7 @@ <div class="col-12"> <h2 class="highlight-empty text-blue m-0 p-0 pt-2">Current issue: Vol. {{ current_issue.in_volume.number }} issue {{ current_issue.number }} (in progress)</h2> {% if prev_issue %} - <h4 class="d-inline-block"><a href="{{prev_issue.get_absolute_url}}">< Previous issue | Vol. {{prev_issue.in_volume.number}} issue {{prev_issue.number}}</a></h4> + <h4 class="d-inline-block"><a href="{{prev_issue.get_absolute_url}}"><i class="fa fa-long-arrow-left"></i> Previous issue | Vol. {{prev_issue.in_volume.number}} issue {{prev_issue.number}}</a></h4> {% endif %} </div> </div> @@ -65,11 +65,16 @@ </div> </div> {% endif %} - {% elif publications %} + {% elif page_object %} + <div class="row"> + <div class="col-12"> + <h2 class="text-blue">{{ journal.get_name_display }} Publications</h2> + </div> + </div> <div class="row"> <div class="col-12"> <ul class="list-unstyled"> - {% for publication in publications %} + {% for publication in page_object.object_list %} <li> {% include 'partials/journals/publication_card.html' with publication=publication %} </li> @@ -81,8 +86,13 @@ </ul> </div> </div> + <div class="row"> + <div class="col-12"> + {% include 'partials/pagination.html' with page_obj=page_object %} + </div> + </div> {% else %} - <h3>First Publication coming soon!</h3> + <h3 class="none-found">First Publication coming soon!</h3> {% endif %} {% endblock %} diff --git a/journals/templates/journals/journal_recent.html b/journals/templates/journals/journal_recent.html index d12a18090..66c96e501 100644 --- a/journals/templates/journals/journal_recent.html +++ b/journals/templates/journals/journal_recent.html @@ -19,7 +19,7 @@ <div class="row"> <div class="col-12"> <ul class="list-unstyled"> - {% for paper in recent_papers %} + {% for paper in journal.get_publications.published|slice:':20' %} <li> {% include 'partials/journals/publication_card.html' with publication=paper %} </li> diff --git a/journals/templates/journals/journals.html b/journals/templates/journals/journals.html index de1e80066..a696b5cd0 100644 --- a/journals/templates/journals/journals.html +++ b/journals/templates/journals/journals.html @@ -77,9 +77,13 @@ </div> </div> <div class="col-md-6"> - <h1 class="banner">SciPost Physics Lecture Notes</h1> + <h1 class="banner"><a href="{% url 'scipost:landing_page' 'SciPostPhysLectNotes' %}">SciPost Physics Lecture Notes</a></h1> <div class="py-2"> - <p>Research-level didactic material in all domains and subject areas of Physics.</p> + <p> + <a href="{% url 'journal:about' 'SciPostPhysLectNotes' %}">Go directly to SciPost Physics Lecture Notes</a> + <br><br> + Research-level didactic material in all domains and subject areas of Physics. + </p> </div> </div> </div> diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html index d77c5d434..08ae88c80 100644 --- a/journals/templates/journals/manage_metadata.html +++ b/journals/templates/journals/manage_metadata.html @@ -19,23 +19,47 @@ event: "focusin" <span class="breadcrumb-item">Manage metadata</span> {% endblock %} +{% block body_class %}{{ block.super }} manage_metadata{% endblock %} + {% block content %} <div class="row"> <div class="col-12"> - <h1 class="highlight">Manage Publications Metadata{% if issue_doi_label %} for issue {{ issue_doi_label }}{% endif %}</h1> - {% if issue_doi_label %} - <h3>Return to the <a href="{% url 'journals:manage_metadata' %}">Main manage metadata page</a></h3> - {% endif %} - <h3>Manage metadata per issue:</h3> - <ul> - {% for issue in issues %} - <li> - <a href="{% url 'journals:manage_metadata' issue_doi_label=issue.doi_label %}">{{ issue }}</a> - </li> - {% endfor %} + <h1 class="highlight">Manage Publications Metadata{% if issue_doi_label %} for issue {{ issue_doi_label }}{% elif journal %} for {{ journal }}{% endif %}</h1> + + </div> +</div> +<div class="row"> + <div class="col-md-6"> + <h3>Available journals</h3> + <ul class="links"> + {% for journal in journals %} + {% url 'journals:manage_metadata' journal_doi_label=journal.doi_label as url %} + <li class="{% if url == request.path %}active{% endif %}"> + <a href="{{ url }}">{{ journal }}</a> + </li> + {% endfor %} </ul> </div> + <div class="col-md-6"> + <h3>Manage metadata per issue:</h3> + {% if journal.has_issues %} + <ul class="links"> + {% for volume in journal.volumes.all %} + {% for issue in volume.issues.all %} + {% url 'journals:manage_metadata' issue_doi_label=journal.doi_label as url %} + <li class="{% if url == request.path %}active{% endif %}"> + <a href="{{ url }}">{{ issue }}</a> + </li> + {% endfor %} + {% empty %} + <li><em>There are no Volumes and Issues for this Journal</em></li> + {% endfor %} + </ul> + {% else %} + <em>This Journal does not have Issues, but individual Publications.</em> + {% endif %} + </div> </div> diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html index f8d8085e3..20f08ba69 100644 --- a/journals/templates/journals/publication_detail.html +++ b/journals/templates/journals/publication_detail.html @@ -189,7 +189,7 @@ <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'test' %}">Test metadata deposit (via Crossref test server)</a></li> <li><a href="{% url 'journals:metadata_xml_deposit' publication.doi_label 'deposit' %}">Deposit the metadata to Crossref</a></li> <li><a href="{% url 'journals:harvest_citedby_links' publication.doi_label %}">Update Crossref cited-by links</a></li> - <li><a href="{% url 'journals:manage_metadata' %}">Metadata management page</a></li> + <li><a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">Metadata management page</a></li> <li><a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">This publication's metadata management page</a></li> <li><a href="{% url 'journals:update_references' doi_label=publication.doi_label %}">Update references</a></li> {% if not publication.is_published %} diff --git a/journals/templates/journals/publication_form.html b/journals/templates/journals/publication_form.html index 6217eef9d..8d46616c3 100644 --- a/journals/templates/journals/publication_form.html +++ b/journals/templates/journals/publication_form.html @@ -9,7 +9,7 @@ <h1>Draft publication</h1> -{% if request.GET.issue or form.instance.id %} +{% if request.GET.issue or form.instance.id or form.to_journal %} <form method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form|bootstrap }} diff --git a/journals/templates/xml/publication_crossref.html b/journals/templates/xml/publication_crossref.html index 2d5eba9f2..f4fb35034 100644 --- a/journals/templates/xml/publication_crossref.html +++ b/journals/templates/xml/publication_crossref.html @@ -11,24 +11,36 @@ </head> <body> <journal> - <journal_metadata> - <full_title>{{ publication.in_issue.in_volume.in_journal.get_name_display }}</full_title> - <abbrev_title>{{ publication.in_issue.in_volume.in_journal.abbreviation_citation }}</abbrev_title> - <issn media_type='electronic'>{{ publication.in_issue.in_volume.in_journal.issn }}</issn> - <doi_data> - <doi>{{ publication.in_issue.in_volume.in_journal.doi_string }}</doi> - <resource>https://scipost.org/{{ publication.in_issue.in_volume.in_journal.doi_string }}</resource> - </doi_data> - </journal_metadata> - <journal_issue> - <publication_date media_type='online'> - <year>{{ publication.publication_date|date:'Y' }}</year> - </publication_date> - <journal_volume> - <volume>{{ publication.in_issue.in_volume.number }}</volume> - </journal_volume> - <issue>{{ publication.in_issue.number }}</issue> - </journal_issue> + {% if publication.in_issue %} + <journal_metadata> + <full_title>{{ publication.in_issue.in_volume.in_journal.get_name_display }}</full_title> + <abbrev_title>{{ publication.in_issue.in_volume.in_journal.abbreviation_citation }}</abbrev_title> + <issn media_type='electronic'>{{ publication.in_issue.in_volume.in_journal.issn }}</issn> + <doi_data> + <doi>{{ publication.in_issue.in_volume.in_journal.doi_string }}</doi> + <resource>https://scipost.org/{{ publication.in_issue.in_volume.in_journal.doi_string }}</resource> + </doi_data> + </journal_metadata> + <journal_issue> + <publication_date media_type='online'> + <year>{{ publication.publication_date|date:'Y' }}</year> + </publication_date> + <journal_volume> + <volume>{{ publication.in_issue.in_volume.number }}</volume> + </journal_volume> + <issue>{{ publication.in_issue.number }}</issue> + </journal_issue> + {% else %} + <journal_metadata> + <full_title>{{ publication.in_journal.get_name_display }}</full_title> + <abbrev_title>{{ publication.in_journal.abbreviation_citation }}</abbrev_title> + <issn media_type='electronic'>{{ publication.in_journal.issn }}</issn> + <doi_data> + <doi>{{ publication.in_journal.doi_string }}</doi> + <resource>https://scipost.org/{{ publication.in_journal.doi_string }}</resource> + </doi_data> + </journal_metadata> + {% endif %} <journal_article publication_type='full_text'> <titles> <title>{{ publication.title }}</title> diff --git a/journals/urls/general.py b/journals/urls/general.py index 0293ca043..bf2d672b4 100644 --- a/journals/urls/general.py +++ b/journals/urls/general.py @@ -4,8 +4,10 @@ from django.views.generic import TemplateView, RedirectView from submissions.constants import SUBMISSIONS_COMPLETE_REGEX +from journals.constants import PUBLICATION_DOI_REGEX, REGEX_CHOICES from journals import views as journals_views + urlpatterns = [ # Journals url(r'^$', journals_views.journals, name='journals'), @@ -22,64 +24,76 @@ urlpatterns = [ url(r'^admin/publications/{regex}/$'.format(regex=SUBMISSIONS_COMPLETE_REGEX), journals_views.DraftPublicationUpdateView.as_view(), name='update_publication'), - url(r'^admin/publications/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/publish$', + url(r'^admin/publications/(?P<doi_label>{regex})/publish$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.PublicationPublishView.as_view(), name='publish_publication'), - url(r'^admin/publications/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/approval$', + url(r'^admin/publications/(?P<doi_label>{regex})/approval$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.DraftPublicationApprovalView.as_view(), name='send_publication_for_approval'), - url(r'^admin/publications/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/grants$', + url(r'^admin/publications/(?P<doi_label>{regex})/grants$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.PublicationGrantsView.as_view(), name='update_grants'), - url(r'^admin/publications/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/grants/(?P<grant_id>[0-9]+)/remove$', + url(r'^admin/publications/(?P<doi_label>{regex})/grants/(?P<grant_id>[0-9]+)/remove$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.PublicationGrantsRemovalView.as_view(), name='remove_grant'), # Editorial and Administrative Workflow - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/authors/add/(?P<contributor_id>[0-9]+)$', + url(r'^admin/(?P<doi_label>{regex})/authors/add/(?P<contributor_id>[0-9]+)$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.add_author, name='add_author'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/authors/add$', + url(r'^admin/(?P<doi_label>{regex})/authors/add$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.add_author, name='add_author'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/authors/mark_first/(?P<author_object_id>[0-9]+)$', + url(r'^admin/(?P<doi_label>{regex})/authors/mark_first/(?P<author_object_id>[0-9]+)$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.mark_first_author, name='mark_first_author'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/manage_metadata$', + url(r'^admin/(?P<doi_label>{regex})/manage_metadata$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.manage_metadata, name='manage_metadata'), url(r'^admin/(?P<issue_doi_label>[a-zA-Z]+.[0-9]+.[0-9]+)/manage_metadata$', journals_views.manage_metadata, name='manage_metadata'), + url(r'^admin/(?P<journal_doi_label>{regex})/manage_metadata$'.format(regex=REGEX_CHOICES), + journals_views.manage_metadata, + name='manage_metadata'), url(r'^admin/manage_metadata/$', journals_views.manage_metadata, name='manage_metadata'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/citation_list_metadata$', + url(r'^admin/(?P<doi_label>{regex})/citation_list_metadata$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.CitationUpdateView.as_view(), name='create_citation_list_metadata'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/update_references$', + url(r'^admin/(?P<doi_label>{regex})/update_references$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.update_references, name='update_references'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/funders/create_metadata$', + url(r'^admin/(?P<doi_label>{regex})/funders/create_metadata$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.FundingInfoView.as_view(), name='create_funding_info_metadata'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/funders/add_generic$', + url(r'^admin/(?P<doi_label>{regex})/funders/add_generic$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.add_generic_funder, name='add_generic_funder'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/grants/add$', + url(r'^admin/(?P<doi_label>{regex})/grants/add$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.add_associated_grant, name='add_associated_grant'), # Metadata handling - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/crossref/create$', + url(r'^admin/(?P<doi_label>{regex})/metadata/crossref/create$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.CreateMetadataXMLView.as_view(), name='create_metadata_xml'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/crossref/deposit/(?P<option>[a-z]+)$', + url(r'^admin/(?P<doi_label>{regex})/metadata/crossref/deposit/(?P<option>[a-z]+)$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.metadata_xml_deposit, name='metadata_xml_deposit'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/DOAJ$', + url(r'^admin/(?P<doi_label>{regex})/metadata/DOAJ$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.produce_metadata_DOAJ, name='produce_metadata_DOAJ'), - url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/DOAJ/deposit$', + url(r'^admin/(?P<doi_label>{regex})/metadata/DOAJ/deposit$'.format( + regex=PUBLICATION_DOI_REGEX), journals_views.metadata_DOAJ_deposit, name='metadata_DOAJ_deposit'), url(r'^admin/metadata/crossref/(?P<deposit_id>[0-9]+)/mark/(?P<success>[0-1])$', @@ -102,7 +116,7 @@ urlpatterns = [ url(r'^admin/citedby/$', journals_views.harvest_citedby_list, name='harvest_citedby_list'), - url(r'^admin/citedby/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/harvest$', + url(r'^admin/citedby/(?P<doi_label>{regex})/harvest$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.harvest_citedby_links, name='harvest_citedby_links'), diff --git a/journals/urls/journal.py b/journals/urls/journal.py index 5cffb7d42..e8526ee4d 100644 --- a/journals/urls/journal.py +++ b/journals/urls/journal.py @@ -4,9 +4,9 @@ from journals import views as journals_views urlpatterns = [ # Journal routes - url(r'^issues$', journals_views.issues, name='issues'), - url(r'^recent$', journals_views.recent, name='recent'), - url(r'^accepted$', journals_views.accepted, name='accepted'), + url(r'^issues$', journals_views.IssuesView.as_view(), name='issues'), + url(r'^recent$', journals_views.RecentView.as_view(), name='recent'), + url(r'^accepted$', journals_views.AcceptedView.as_view(), name='accepted'), url(r'^info_for_authors$', journals_views.info_for_authors, name='info_for_authors'), url(r'^about$', journals_views.about, name='about'), ] diff --git a/journals/views.py b/journals/views.py index e898a47de..5f2571efa 100644 --- a/journals/views.py +++ b/journals/views.py @@ -21,10 +21,10 @@ from django.utils import timezone from django.utils.decorators import method_decorator from django.views.generic.detail import DetailView from django.views.generic.edit import UpdateView -from django.shortcuts import get_object_or_404, render, redirect +from django.shortcuts import get_object_or_404, get_list_or_404, render, redirect from .constants import STATUS_DRAFT -from .helpers import paper_nr_string, issue_doi_label_from_doi_label +from .helpers import issue_doi_label_from_doi_label from .models import Journal, Issue, Publication, Deposit, DOAJDeposit,\ GenericDOIDeposit, PublicationAuthorsTable from .forms import FundingInfoForm,\ @@ -36,7 +36,7 @@ from .utils import JournalUtils from comments.models import Comment from funders.forms import FunderSelectForm, GrantSelectForm -from funders.models import Funder, Grant +from funders.models import Grant from submissions.models import Submission, Report from scipost.forms import ConfirmationForm from scipost.models import Contributor @@ -68,11 +68,11 @@ def landing_page(request, doi_label): if journal.has_issues: current_issue = Issue.objects.published().filter( in_volume__in_journal=journal, - start_date__lte=timezone.now, - until_date__gte=timezone.now).first() + start_date__lte=timezone.now(), + until_date__gte=timezone.now()).first() latest_issue = Issue.objects.published().filter( in_volume__in_journal=journal, - until_date__lte=timezone.now).first() + until_date__lte=timezone.now()).first() prev_issue = None if current_issue: prev_issue = Issue.objects.published().filter( @@ -85,65 +85,56 @@ def landing_page(request, doi_label): 'prev_issue': prev_issue, }) else: - context['publications'] = journal.publications.published() + paginator = Paginator(journal.publications.published(), 10) + context.update({ + 'page_object': paginator.page(request.GET.get('page', 1)), + }) return render(request, 'journals/journal_landing_page.html', context) -def issues(request, doi_label): - journal = get_object_or_404(Journal.objects.has_issues(), doi_label=doi_label) - - issues = Issue.objects.published().filter(in_volume__in_journal=journal) - context = { - 'issues': issues, - 'journal': journal - } - return render(request, 'journals/journal_issues.html', context) +class IssuesView(DetailView): + """ + List all Issues sorted per Journal. + """ + queryset = Journal.objects.has_issues() + slug_field = slug_url_kwarg = 'doi_label' + template_name = 'journals/journal_issues.html' -def recent(request, doi_label): +class RecentView(DetailView): """ - Display page for the most recent 20 publications in SciPost Physics. + List all recent Publications for a specific Journal. """ - journal = get_object_or_404(Journal, doi_label=doi_label) - recent_papers = Publication.objects.published().filter( - in_issue__in_volume__in_journal=journal).order_by('-publication_date', - '-paper_nr')[:20] - context = { - 'recent_papers': recent_papers, - 'journal': journal, - } - return render(request, 'journals/journal_recent.html', context) + queryset = Journal.objects.active() + slug_field = slug_url_kwarg = 'doi_label' + template_name = 'journals/journal_recent.html' -def accepted(request, doi_label): +class AcceptedView(DetailView): """ - Display page for submissions to SciPost Physics which - have been accepted but are not yet published. + List all Submissions for a specific Journal which have been accepted but are not + yet published. """ - journal = get_object_or_404(Journal, doi_label=doi_label) - accepted_SP_submissions = (Submission.objects.accepted() - .filter(submitted_to_journal=journal.name) - .order_by('-latest_activity')) - context = { - 'accepted_SP_submissions': accepted_SP_submissions, - 'journal': journal - } - return render(request, 'journals/journal_accepted.html', context) + queryset = Journal.objects.active() + slug_field = slug_url_kwarg = 'doi_label' + template_name = 'journals/journal_accepted.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['accepted_submissions'] = Submission.objects.accepted().filter( + submitted_to_journal=context['journal'].name).order_by('-latest_activity') + return context def info_for_authors(request, doi_label): journal = get_object_or_404(Journal, doi_label=doi_label) - context = { - 'journal': journal - } + context = {'journal': journal} return render(request, 'journals/%s_info_for_authors.html' % doi_label, context) def about(request, doi_label): journal = get_object_or_404(Journal, doi_label=doi_label) - context = { - 'journal': journal - } + context = {'journal': journal} return render(request, 'journals/%s_about.html' % doi_label, context) @@ -251,19 +242,40 @@ class PublicationPublishView(PermissionsMixin, RequestViewMixin, UpdateView): @permission_required('scipost.can_publish_accepted_submission', return_403=True) -def manage_metadata(request, issue_doi_label=None, doi_label=None): - issues = Issue.objects.all().order_by('-until_date') - publications = Publication.objects.all() +def manage_metadata(request, doi_label=None, issue_doi_label=None, journal_doi_label=None): + journal = None + journals = Journal.objects.all() + issue = None + if doi_label: - issue_doi_label = issue_doi_label_from_doi_label(doi_label) - if issue_doi_label: - publications = publications.filter(in_issue__doi_label=issue_doi_label) - publications = publications.order_by('-publication_date', '-paper_nr') + publications = get_list_or_404(Publication, doi_label=doi_label) + journal = publications[0].get_journal() + elif issue_doi_label: + issue = get_object_or_404(Issue, doi_label=issue_doi_label) + if issue.in_volume: + journal = issue.in_volume.in_journal + else: + journal = issue.in_journal + publications = issue.publications.all() + elif journal_doi_label: + journal = get_object_or_404(Journal, doi_label=journal_doi_label) + publications = Publication.objects.for_journal(journal.name) + else: + # Limit the amount of Publications to still an idiot size + publications = Publication.objects.all()[:50] + + # Speeds up operations by reducing the number of queries + if not isinstance(publications, list): + publications = publications.prefetch_related( + 'authors', 'funders_generic', 'deposit_set', 'doajdeposit_set') + associate_grant_form = GrantSelectForm() associate_generic_funder_form = FunderSelectForm() context = { - 'issues': issues, + 'journal': journal, + 'journals': journals, 'issue_doi_label': issue_doi_label, + 'journal_doi_label': journal_doi_label, 'publications': publications, 'associate_grant_form': associate_grant_form, 'associate_generic_funder_form': associate_generic_funder_form, @@ -446,13 +458,27 @@ def metadata_xml_deposit(request, doi_label, option='test'): return redirect(reverse('journals:create_metadata_xml', kwargs={'doi_label': publication.doi_label})) - timestamp = (publication.metadata_xml.partition( - '<timestamp>'))[2].partition('</timestamp>')[0] - doi_batch_id = (publication.metadata_xml.partition( - '<doi_batch_id>'))[2].partition('</doi_batch_id>')[0] - path = (settings.MEDIA_ROOT + publication.in_issue.path + '/' - + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') - + '_Crossref_' + timestamp + '.xml') + timestamp = publication.metadata_xml.partition( + '<timestamp>')[2].partition('</timestamp>')[0] + doi_batch_id = publication.metadata_xml.partition( + '<doi_batch_id>')[2].partition('</doi_batch_id>')[0] + + # Find Crossref xml files + path = settings.MEDIA_ROOT + if publication.in_issue: + path += '{issue_path}/{paper_nr}/{doi_label}_Crossref'.format( + issue_path=publication.in_issue.path, + paper_nr=publication.get_paper_nr(), + doi_label=publication.doi_label.replace('.', '_')) + + if publication.in_journal: + path += 'SCIPOST_JOURNALS/{journal_name}/{paper_nr}/{doi_label}_Crossref'.format( + journal_name=publication.in_journal.name, + paper_nr=publication.get_paper_nr(), + doi_label=publication.doi_label.replace('.', '_')) + + path_wo_timestamp = path + '.xml' + path += '_{timestamp}.xml'.format(timestamp=timestamp) valid = True response_headers = None @@ -463,7 +489,7 @@ def metadata_xml_deposit(request, doi_label, option='test'): else: # New deposit, go for it. if option == 'deposit' and not settings.DEBUG: - # CAUTION: Real deposit only on production (non-debug-mode) + # CAUTION: Real deposit only on production! url = 'http://doi.crossref.org/servlet/deposit' else: url = 'http://test.crossref.org/servlet/deposit' @@ -493,24 +519,14 @@ def metadata_xml_deposit(request, doi_label, option='test'): deposit.response_text = r.text # Save the filename with timestamp - path_with_timestamp = '{issue}/{paper}/{doi}_Crossref_{timestamp}.xml'.format( - issue=publication.in_issue.path, - paper=publication.get_paper_nr(), - doi=publication.doi_label.replace('.', '_'), - timestamp=timestamp) - f = open(settings.MEDIA_ROOT + path_with_timestamp, 'w', encoding='utf-8') + f = open(settings.MEDIA_ROOT + path, 'w', encoding='utf-8') f.write(publication.metadata_xml) f.close() - # Copy file - path_without_timestamp = '{issue}/{paper}/{doi}_Crossref.xml'.format( - issue=publication.in_issue.path, - paper=publication.get_paper_nr(), - doi=publication.doi_label.replace('.', '_')) - shutil.copyfile(settings.MEDIA_ROOT + path_with_timestamp, - settings.MEDIA_ROOT + path_without_timestamp) - - deposit.metadata_xml_file = path_with_timestamp + # Update Crossref timestamp-free file to latest deposit + shutil.copyfile(settings.MEDIA_ROOT + path, + settings.MEDIA_ROOT + path_wo_timestamp) + deposit.metadata_xml_file = path deposit.save() publication.latest_crossref_deposit = timezone.now() publication.save() @@ -567,11 +583,24 @@ def metadata_DOAJ_deposit(request, doi_label): 'DOAJ metadata before depositing.' % publication.doi_label) return redirect(reverse('journals:manage_metadata')) - timestamp = (publication.metadata_xml.partition( - '<timestamp>'))[2].partition('</timestamp>')[0] - path = (settings.MEDIA_ROOT + publication.in_issue.path + '/' - + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') - + '_DOAJ_' + timestamp + '.json') + timestamp = publication.metadata_xml.partition('<timestamp>')[2].partition('</timestamp>')[0] + + # Find DOAJ xml files + path = settings.MEDIA_ROOT + if publication.in_issue: + path += '{issue_path}/{paper_nr}/{doi_label}_DOAJ'.format( + issue_path=publication.in_issue.path, + paper_nr=publication.get_paper_nr(), + doi_label=publication.doi_label.replace('.', '_')) + elif publication.in_journal: + path += 'SCIPOST_JOURNALS/{journal_name}/{paper_nr}/{doi_label}_DOAJ'.format( + journal_name=publication.in_journal.name, + paper_nr=publication.get_paper_nr(), + doi_label=publication.doi_label.replace('.', '_')) + + path_wo_timestamp = path + '.json' + path += '_{timestamp}.json'.format(timestamp=timestamp) + if os.path.isfile(path): errormessage = 'The metadata file for this metadata timestamp already exists' return render(request, 'scipost/error.html', context={'errormessage': errormessage}) @@ -593,25 +622,16 @@ def metadata_DOAJ_deposit(request, doi_label): deposit.response_text = r.text # Save a copy to the filename with and without timestamp - path_with_timestamp = '{issue}/{paper}/{doi}_DOAJ_{timestamp}.json'.format( - issue=publication.in_issue.path, - paper=publication.get_paper_nr(), - doi=publication.doi_label.replace('.', '_'), - timestamp=timestamp) - f = open(settings.MEDIA_ROOT + path_with_timestamp, 'w') + f = open(settings.MEDIA_ROOT + path, 'w') f.write(json.dumps(publication.metadata_DOAJ)) f.close() # Copy file - path_without_timestamp = '{issue}/{paper}/{doi}_DOAJ.json'.format( - issue=publication.in_issue.path, - paper=publication.get_paper_nr(), - doi=publication.doi_label.replace('.', '_')) - shutil.copyfile(settings.MEDIA_ROOT + path_with_timestamp, - settings.MEDIA_ROOT + path_without_timestamp) + shutil.copyfile(settings.MEDIA_ROOT + path, + settings.MEDIA_ROOT + path_wo_timestamp) # Save the database entry - deposit.metadata_DOAJ_file = path_with_timestamp + deposit.metadata_DOAJ_file = path deposit.save() messages.success(request, '<h3>%s</h3>Successfull deposit of metadata DOAJ.' diff --git a/scipost/static/scipost/assets/css/_list_group.scss b/scipost/static/scipost/assets/css/_list_group.scss index b598898a0..c2313938b 100644 --- a/scipost/static/scipost/assets/css/_list_group.scss +++ b/scipost/static/scipost/assets/css/_list_group.scss @@ -45,3 +45,7 @@ ul.references { margin: 0 0 0.2rem 2rem; } } + +ul.links > li.active a { + font-weight: 700; +} diff --git a/scipost/urls.py b/scipost/urls.py index 9da0a19f2..862b31635 100644 --- a/scipost/urls.py +++ b/scipost/urls.py @@ -7,7 +7,7 @@ from .feeds import LatestNewsFeedRSS, LatestNewsFeedAtom, LatestCommentsFeedRSS, LatestPublicationsFeedRSS, LatestPublicationsFeedAtom from journals import views as journals_views -from journals.constants import REGEX_CHOICES +from journals.constants import REGEX_CHOICES, PUBLICATION_DOI_REGEX from submissions import views as submission_views JOURNAL_REGEX = '(?P<doi_label>%s)' % REGEX_CHOICES @@ -185,16 +185,16 @@ urlpatterns = [ name='author_reply_detail'), # Publication detail (+pdf) - url(r'^10.21468/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^10.21468/(?P<doi_label>{regex})$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.publication_detail, name='publication_detail'), - url(r'^(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^(?P<doi_label>{regex})$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.publication_detail, name='publication_detail'), - url(r'^10.21468/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/pdf$', + url(r'^10.21468/(?P<doi_label>{regex})/pdf$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.publication_detail_pdf, name='publication_pdf'), - url(r'^(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/pdf$', + url(r'^(?P<doi_label>{regex})/pdf$'.format(regex=PUBLICATION_DOI_REGEX), journals_views.publication_detail_pdf, name='publication_pdf'), diff --git a/submissions/templates/submissions/submission_list.html b/submissions/templates/submissions/submission_list.html index 05e114e3f..ca2cefaf7 100644 --- a/submissions/templates/submissions/submission_list.html +++ b/submissions/templates/submissions/submission_list.html @@ -44,7 +44,7 @@ <div class="row"> <div class="col-12"> {% if recent %} - <h2>Recent Submissions:</h2> + <h2>Recent Submissions{% if to_journal %} to {{ to_journal }}{% endif %}:</h2> {% elif browse %} <h2>Submissions in {{ discipline }} in the last {{ nrweeksback }} week{% if nrweeksback == '1' %}{% else %}s{% endif %}:</h2> {% else %} diff --git a/submissions/views.py b/submissions/views.py index 382fa6213..3df758bca 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -1,5 +1,6 @@ import datetime import feedparser +import strings from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required @@ -36,19 +37,17 @@ from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSe from .utils import SubmissionUtils from colleges.permissions import fellowship_required, fellowship_or_admin_required -from mails.views import MailEditingSubView -from scipost.forms import ModifyPersonalMessageForm, RemarkForm -from scipost.mixins import PaginationMixin -from scipost.models import Contributor, Remark - from comments.forms import CommentForm from invitations.constants import INVITATION_REFEREEING from invitations.models import RegistrationInvitation +from journals.models import Journal from mails.utils import DirectMailUtil +from mails.views import MailEditingSubView from production.forms import ProofsDecisionForm from production.models import ProductionStream - -import strings +from scipost.forms import ModifyPersonalMessageForm, RemarkForm +from scipost.mixins import PaginationMixin +from scipost.models import Contributor, Remark ############### @@ -136,10 +135,10 @@ class SubmissionListView(PaginationMixin, ListView): def get_queryset(self): queryset = Submission.objects.public_newest() self.form = self.form(self.request.GET) - if 'to_journal' in self.kwargs: + if 'to_journal' in self.request.GET: queryset = queryset.filter( latest_activity__gte=timezone.now() + datetime.timedelta(days=-60), - submitted_to_journal=self.kwargs['to_journal'] + submitted_to_journal=self.request.GET['to_journal'] ) elif 'discipline' in self.kwargs and 'nrweeksback' in self.kwargs: discipline = self.kwargs['discipline'] @@ -161,8 +160,12 @@ class SubmissionListView(PaginationMixin, ListView): context['form'] = self.form # To customize display in the template - if 'to_journal' in self.kwargs: - context['to_journal'] = self.kwargs['to_journal'] + if 'to_journal' in self.request.GET: + try: + context['to_journal'] = Journal.objects.filter( + name=self.request.GET['to_journal']).first().get_name_display() + except (Journal.DoesNotExist, AttributeError): + context['to_journal'] = self.request.GET['to_journal'] if 'discipline' in self.kwargs: context['discipline'] = self.kwargs['discipline'] context['nrweeksback'] = self.kwargs['nrweeksback'] -- GitLab