diff --git a/journals/factories.py b/journals/factories.py index 8d8de8ee154b5922fe4f728ca37ef39f8e3accee..802dc70c73bd9ebd6ebe630e85adfb757de6a093 100644 --- a/journals/factories.py +++ b/journals/factories.py @@ -95,8 +95,7 @@ class PublicationFactory(factory.django.DjangoModelFactory): # Authors self.author_list = self.accepted_submission.author_list - self.authors.add(*self.accepted_submission.authors.all()) - self.first_author = self.accepted_submission.authors.first() + # self.authors.add(*self.accepted_submission.authors.all()) self.authors_claims.add(*self.accepted_submission.authors_claims.all()) self.authors_false_claims.add(*self.accepted_submission.authors_false_claims.all()) diff --git a/journals/forms.py b/journals/forms.py index 44462b752ef726690395007f2765d454a0e597fa..3f662b6def96920f7e8887e64c1602792e11e1b0 100644 --- a/journals/forms.py +++ b/journals/forms.py @@ -58,16 +58,19 @@ class CitationListBibitemsForm(forms.Form): return dois -class FundingInfoForm(forms.Form): - funding_statement = forms.CharField(widget=forms.Textarea()) +class FundingInfoForm(forms.ModelForm): + funding_statement = forms.CharField(widget=forms.Textarea({ + 'rows': 10, + 'placeholder': 'Paste the funding info statement here' + })) - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - self.fields['funding_statement'].widget.attrs.update({ - 'rows': 10, - 'cols': 50, - 'placeholder': 'Paste the funding info statement here' - }) + class Meta: + model = Publication + fields = () + + def save(self, *args, **kwargs): + self.instance.metadata['funding_statement'] = self.cleaned_data['funding_statement'] + return super().save(*args, **kwargs) class CreateMetadataXMLForm(forms.ModelForm): @@ -77,10 +80,70 @@ class CreateMetadataXMLForm(forms.ModelForm): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.fields['metadata_xml'].widget.attrs.update({ - 'rows': 50, - 'cols': 50 - }) + self.fields['metadata_xml'].widget.attrs.update({'rows': 50}) + + +class CreateMetadataDOAJForm(forms.ModelForm): + class Meta: + model = Publication + fields = () + + def __init__(self, *args, **kwargs): + self.request = kwargs.pop('request') + 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): + md = { + 'bibjson': { + 'author': [{'name': publication.author_list}], + 'title': publication.title, + 'abstract': publication.abstract, + 'year': publication.publication_date.strftime('%Y'), + 'month': publication.publication_date.strftime('%m'), + 'start_page': publication.get_paper_nr(), + 'identifier': [ + { + 'type': 'eissn', + 'id': str(publication.in_issue.in_volume.in_journal.issn) + }, + { + 'type': 'doi', + 'id': publication.doi_string + } + ], + 'link': [ + { + 'url': self.request.build_absolute_uri(publication.get_absolute_url()), + '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(), + } + } + } + return md class BaseReferenceFormSet(BaseModelFormSet): diff --git a/journals/models.py b/journals/models.py index 41cd2052cc1ad1bdaba0b9852ff8219190edc51e..31c9cdc87eec453db0c84da6cf35349172b8c8ee 100644 --- a/journals/models.py +++ b/journals/models.py @@ -290,12 +290,6 @@ class Publication(models.Model): 'publication', 'unregistered_author'), related_name='publications') - first_author = models.ForeignKey('scipost.Contributor', blank=True, null=True, - on_delete=models.CASCADE, - related_name='first_author_publications') - first_author_unregistered = models.ForeignKey('journals.UnregisteredAuthor', blank=True, null=True, - on_delete=models.CASCADE, - related_name='first_author_publications') authors_claims = models.ManyToManyField('scipost.Contributor', blank=True, related_name='claimed_publications') authors_false_claims = models.ManyToManyField('scipost.Contributor', blank=True, @@ -328,12 +322,6 @@ class Publication(models.Model): latest_metadata_update = models.DateTimeField(blank=True, null=True) latest_activity = models.DateTimeField(default=timezone.now) - # Deprecated fields. About to be removed after successful database migration on production. - authors_old = models.ManyToManyField('scipost.Contributor', blank=True, - related_name='publications_old') - authors_unregistered_old = models.ManyToManyField('journals.UnregisteredAuthor', blank=True, - related_name='publications_old') - objects = PublicationQuerySet.as_manager() def __str__(self): diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html index b49a3a0408821feaf3c8ddcc5ca28cb7e9dc1e94..668919333f224cee185775fc77edd28e4510821e 100644 --- a/journals/templates/journals/add_author.html +++ b/journals/templates/journals/add_author.html @@ -60,7 +60,7 @@ {% for contributor in contributors_found %} <li> <div class="font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> - <a href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> + <a href="{% url 'journals:add_author' doi_label=publication.doi_label contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> </li> {% empty %} <li><span class="text-danger">No Contributor with this name could be identified.</span></li> @@ -68,7 +68,7 @@ </ul> <h3>You can otherwise add the author manually and link it to the publication</h3> - <form action="{% url 'journals:add_author' publication_id=publication.id %}" method="post"> + <form action="{% url 'journals:add_author' doi_label=publication.doi_label %}" method="post"> {% csrf_token %} {{ form|bootstrap }} <input class="btn btn-primary" type="submit" value="Add"> diff --git a/journals/templates/journals/create_citation_list_metadata.html b/journals/templates/journals/create_citation_list_metadata.html index 637c12a0b10145671a88bede2d81522ed7fa8da0..c6f5f6d5f79e130b4ed33a83ce96a1371c370480 100644 --- a/journals/templates/journals/create_citation_list_metadata.html +++ b/journals/templates/journals/create_citation_list_metadata.html @@ -7,9 +7,8 @@ <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> + <a href="{% url 'journals:manage_metadata' %}" class="breadcrumb-item">Administration</a> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="breadcrumb-item">{{ publication.citation }}</a> <span class="breadcrumb-item active">Create citation list metadata</span> </nav> </div> @@ -22,27 +21,24 @@ <div class="row"> <div class="col-12"> - <h1 class="highlight">Create citation list metadata page</h1> + <h1 class="highlight">Create citation list metadata page for <a href="{{ publication.get_absolute_url }}">{{ publication.doi_label }}</a></h1> </div> </div> <div class="row"> <div class="col-12"> - {% if errormessage %} - <h2 class="text-danger">{{ errormessage }}</h2> - {% endif %} - <form action="{% url 'journals:create_citation_list_metadata' publication.doi_label %}" method="post"> {% csrf_token %} {{ bibitems_form|bootstrap }} - <input type="submit" class="btn btn-secondary" value="Submit"> + <input type="submit" class="btn btn-primary" value="Submit"> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="ml-3 btn btn-link">Back to Admin for {{ publication.doi_label }}</a> </form> - <hr> + <hr class="divider"> <h3>Current citation list metadata:</h3> - <table> + <table class="table"> {% for citation in citation_list %} <tr> <td>{{ citation.key }}</td><td>{{ citation.doi }}</td> @@ -52,7 +48,7 @@ <hr> - <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></h3> + <p>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></p> </div> </div> diff --git a/journals/templates/journals/create_funding_info_metadata.html b/journals/templates/journals/create_funding_info_metadata.html index 3f5d9921bae52166335fbc2eb80f4f4d7f3180ba..2373370f7b3d9ca053ec85ace517e5e520b3e775 100644 --- a/journals/templates/journals/create_funding_info_metadata.html +++ b/journals/templates/journals/create_funding_info_metadata.html @@ -7,9 +7,8 @@ <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> + <a href="{% url 'journals:manage_metadata' %}" class="breadcrumb-item">Administration</a> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="breadcrumb-item">{{ publication.citation }}</a> <span class="breadcrumb-item active">Create funding info metadata</span> </nav> </div> @@ -22,7 +21,7 @@ <div class="row"> <div class="col-12"> - <h1 class="highlight">Create funding info metadata page</h1> + <h1 class="highlight">Create funding info metadata page for <a href="{{ publication.get_absolute_url }}">{{ publication.doi_label }}</a></h1> </div> </div> @@ -34,19 +33,20 @@ <h2 class="text-danger">{{ errormessage }}</h2> {% endif %} - <form action="{% url 'journals:create_funding_info_metadata' publication.doi_label %}" method="post"> + <form method="post"> {% csrf_token %} {{ funding_info_form|bootstrap }} - <input type="submit" class="btn btn-secondary" value="Submit"> + <input type="submit" class="btn btn-primary" value="Submit"> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="ml-3 btn btn-link">Back to Admin for {{ publication.doi_label }}</a> </form> - <hr> - <h3 class="mt-3">Current funding info metadata:</h3> - <p>{{funding_statement|linebreaks}}</p> + <hr class="divider"> + <h3>Current funding info metadata:</h3> + <p>{{ funding_statement|linebreaksbr }}</p> <hr> - <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></h3> + <p class="mb-0">Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></p> </div> </div> diff --git a/journals/templates/journals/create_metadata_xml.html b/journals/templates/journals/create_metadata_xml.html index c99b48c8a289197ee1f1ffda7f77eec19e1ca6de..a6627c2567926544804cc917b2105849d0ee91b6 100644 --- a/journals/templates/journals/create_metadata_xml.html +++ b/journals/templates/journals/create_metadata_xml.html @@ -7,9 +7,8 @@ <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> + <a href="{% url 'journals:manage_metadata' %}" class="breadcrumb-item">Administration</a> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="breadcrumb-item">{{ publication.citation }}</a> <span class="breadcrumb-item active">Create metadata XML</span> </nav> </div> @@ -35,17 +34,17 @@ <form action="{% url 'journals:create_metadata_xml' publication.doi_label %}" method="post"> {% csrf_token %} {{ create_metadata_xml_form|bootstrap }} - <input type="submit" class="btn btn-secondary" value="Accept the metadata"> + <input type="submit" class="btn btn-primary" value="Accept the metadata"> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="ml-3 btn btn-link">Back to Admin for {{ publication.doi_label }}</a> </form> - <hr class="hr6"/> + <hr class="divider"> - <h3>Current metadata xml:</h3> - <div> - <pre><code>{{ publication.metadata_xml|linebreaksbr }}</code></pre> - </div> - - <h3>Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></h3> + <h3>Current metadata xml</h3> + <br> + <pre><code>{{ publication.metadata_xml|linebreaksbr }}</code></pre> + <br> + <p class="mb-0">Once you're happy with this metadata, you can <a href="{{publication.get_absolute_url}}">return to the publication's page</a> or to the <a href="{% url 'journals:manage_metadata' %}">metadata management page</a></p> </div> </div> diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html index 0b0547b47c5be8f52046bbf7b3036ac80089d857..fc3c61d69d847dd2b23a96a8daaf7722bc7514bb 100644 --- a/journals/templates/journals/manage_metadata.html +++ b/journals/templates/journals/manage_metadata.html @@ -74,16 +74,16 @@ event: "focusin" <div class="row"> <div class="col-md-5"> <ul> - <li>Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) + <li>Mark the first author <ul class="list-unstyled pl-4"> {% for author in publication.authors.all %} <li> - {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a> + {{ author.order }}. <a href="{% url 'journals:mark_first_author' doi_label=publication.doi_label author_object_id=author.id %}">{{ author }}</a> </li> {% endfor %} </ul> </li> - <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li> + <li><a href="{% url 'journals:add_author' doi_label=publication.doi_label %}">Add a missing author</a></li> <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li> <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li> diff --git a/journals/templates/journals/metadata_doaj_create.html b/journals/templates/journals/metadata_doaj_create.html new file mode 100644 index 0000000000000000000000000000000000000000..5702c8deeba546e5181cbb1e9aa5c8ad9ccb35c5 --- /dev/null +++ b/journals/templates/journals/metadata_doaj_create.html @@ -0,0 +1,49 @@ +{% extends 'scipost/base.html' %} + +{% load bootstrap %} + +{% block pagetitle %}: Produce metadata DOAJ{% endblock pagetitle %} + +{% block breadcrumb %} + <div class="container-outside header"> + <div class="container"> + <nav class="breadcrumb hidden-sm-down"> + <a href="{% url 'journals:journals' %}" class="breadcrumb-item">Journals</a> + <a href="{% url 'journals:manage_metadata' %}" class="breadcrumb-item">Administration</a> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="breadcrumb-item">{{ publication.citation }}</a> + <span class="breadcrumb-item active">Produce metadata DOAJ</span> + </nav> + </div> + </div> +{% endblock %} + +{% block content %} + + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Produce metadata DOAJ for <a href="{{ publication.get_absolute_url }}">{{ publication.doi_label }}</a></h1> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h3>Existing DOAJ metadata</h3> + {% if publication.metadata_DOAJ %} + <pre><code>{{ publication.metadata_DOAJ }}</code></pre> + {% else %} + <p>No existing DOAJ Metadata found.</p> + {% endif %} + + <br> + <form method="post"> + {% csrf_token %} + {{ form|bootstrap }} + <input class="btn btn-primary" type="submit" value="{% if publication.metadata_DOAJ %}Reproduce{% else %}Produce{% endif %}"> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="ml-3 btn btn-link">Back to Admin for {{ publication.doi_label }}</a> + </form> + </div> +</div> + + +{% endblock %} diff --git a/journals/templates/journals/metadata_xml_deposit.html b/journals/templates/journals/metadata_xml_deposit.html index 0f40882d3e4f459ebd331fc81fcf12d3a708f4e8..960e3737b67c6a3036eb52c7d1d9b177b94967a2 100644 --- a/journals/templates/journals/metadata_xml_deposit.html +++ b/journals/templates/journals/metadata_xml_deposit.html @@ -7,9 +7,8 @@ <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> + <a href="{% url 'journals:manage_metadata' %}" class="breadcrumb-item">Administration</a> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}" class="breadcrumb-item">{{ publication.citation }}</a> <span class="breadcrumb-item active">Metadata XML deposit</span> </nav> </div> @@ -25,29 +24,35 @@ </div> </div> +{% if valid %} + <div class="row"> + <div class="col-12"> -<div class="row"> - <div class="col-12"> - - {% if errormessage %} - <h2 class="text-danger">{{ errormessage }}</h2> - {% endif %} - - <h3 class="my-1">Response headers:</h3> - <div> - <pre><code>{{ response_headers|linebreaks }}</code></pre> - </div> + <h3 class="my-1">Response headers:</h3> + <pre><code>{{ response_headers|linebreaks }}</code></pre> - <h3 class="mt-3">Response text:</h3> - <div> - <pre><code>{{ response_text|linebreaks }}</code></pre> - </div> + <h3 class="mt-3">Response text:</h3> + <pre><code>{{ response_text|linebreaks }}</code></pre> - <h3><a href="{{publication.get_absolute_url}}">return to the publication's page</a>, to the <a href="{% url 'journals:manage_metadata' %}">general metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></h3> + <br> + <p><a href="{{publication.get_absolute_url}}">return to the publication's page</a>, to the <a href="{% url 'journals:manage_metadata' %}">general metadata management page</a> or to <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">this publication's metadata management page</a></p> + </div> </div> -</div> +{% else %} + <div class="row"> + <div class="col-12"> + <p> + <span class="text-danger">The metadata file for this metadata timestamp already exists.</span><br> + You might want to <a href="{% url 'journals:create_metadata_xml' doi_label=publication.doi_label %}">produce new metadata</a> to do a new deposit instead. + <p> + + <br> + <a href="{% url 'journals:manage_metadata' doi_label=publication.doi_label %}">Back to Admin for {{ publication.doi_label }}</a> + </div> + </div> +{% endif %} {% endblock %} diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html index 358a8bbca484f3651103a84b22d9df4e010f28b9..1522969e8df4a5fd4fd4940b92cd7d863b92509a 100644 --- a/journals/templates/journals/publication_detail.html +++ b/journals/templates/journals/publication_detail.html @@ -134,16 +134,16 @@ <h3>Editorial Administration tools: </h3> <ul> <li> - Mark the first author (currently: {% if publication.first_author %}{{ publication.first_author }}{% elif publication.first_author_unregistered %}{{ publication.first_author_unregistered }} (unregistered){% endif %}) + Mark the first author <ul class="list-unstyled pl-4"> {% for author in publication.authors.all %} <li> - {{ author.order }}. <a href="{% url 'journals:mark_first_author' publication_id=publication.id author_object_id=author.id %}">{{ author }}</a> + {{ author.order }}. <a href="{% url 'journals:mark_first_author' doi_label=publication.doi_label author_object_id=author.id %}">{{ author }}</a> </li> {% endfor %} </ul> </li> - <li><a href="{% url 'journals:add_author' publication.id %}">Add a missing author</a></li> + <li><a href="{% url 'journals:add_author' doi_label=publication.doi_label %}">Add a missing author</a></li> <li><a href="{% url 'journals:create_citation_list_metadata' publication.doi_label %}">Create/update citation list metadata</a></li> <li><a href="{% url 'journals:create_funding_info_metadata' publication.doi_label %}">Create/update funding info metadata</a></li> <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">Create/update the XML metadata</a></li> diff --git a/journals/urls/general.py b/journals/urls/general.py index c57c961fd9e4985efee6e2e2b7fc310190e2547c..ca60342a93f2fb64dbd834e5fbe14fb8a7f44b56 100644 --- a/journals/urls/general.py +++ b/journals/urls/general.py @@ -17,90 +17,98 @@ urlpatterns = [ name='crossmark_policy'), # Editorial and Administrative Workflow - url(r'^initiate_publication$', + url(r'^admin/initiate_publication$', journals_views.initiate_publication, name='initiate_publication'), - url(r'^validate_publication$', + url(r'^admin/validate_publication$', journals_views.validate_publication, name='validate_publication'), - url(r'^mark_first_author/(?P<publication_id>[0-9]+)/(?P<author_object_id>[0-9]+)$', - journals_views.mark_first_author, - name='mark_first_author'), - url(r'^add_author/(?P<publication_id>[0-9]+)/(?P<contributor_id>[0-9]+)$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/authors/add/(?P<contributor_id>[0-9]+)$', journals_views.add_author, name='add_author'), - url(r'^add_author/(?P<publication_id>[0-9]+)$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/authors/add$', journals_views.add_author, name='add_author'), - url(r'^manage_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + 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]+)$', + 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$', journals_views.manage_metadata, name='manage_metadata'), - url(r'^manage_metadata/(?P<issue_doi_label>[a-zA-Z]+.[0-9]+.[0-9]+)$', + 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'^manage_metadata/$', + url(r'^admin/manage_metadata/$', journals_views.manage_metadata, name='manage_metadata'), - url(r'^create_citation_list_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/citation_list_metadata$', journals_views.create_citation_list_metadata, name='create_citation_list_metadata'), - url(r'^update_references/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/update_references$', journals_views.update_references, name='update_references'), - url(r'^create_funding_info_metadata/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/funders/create_metadata$', journals_views.create_funding_info_metadata, name='create_funding_info_metadata'), - url(r'^add_associated_grant/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', - journals_views.add_associated_grant, - name='add_associated_grant'), - url(r'^add_generic_funder/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/funders/add_generic$', journals_views.add_generic_funder, name='add_generic_funder'), - url(r'^create_metadata_xml/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/grants/add$', + 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$', journals_views.create_metadata_xml, name='create_metadata_xml'), - url(r'^metadata_xml_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/(?P<option>[a-z]+)$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/crossref/deposit/(?P<option>[a-z]+)$', journals_views.metadata_xml_deposit, name='metadata_xml_deposit'), - url(r'^mark_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', - journals_views.mark_deposit_success, - name='mark_deposit_success'), - url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/DOAJ$', journals_views.produce_metadata_DOAJ, name='produce_metadata_DOAJ'), - url(r'^metadata_DOAJ_deposit/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/metadata/DOAJ/deposit$', journals_views.metadata_DOAJ_deposit, name='metadata_DOAJ_deposit'), - url(r'^mark_doaj_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', + url(r'^admin/metadata/crossref/(?P<deposit_id>[0-9]+)/mark/(?P<success>[0-1])$', + journals_views.mark_deposit_success, + name='mark_deposit_success'), + url(r'^admin/metadata/DOAJ/(?P<deposit_id>[0-9]+)/mark/(?P<success>[0-1])$', journals_views.mark_doaj_deposit_success, name='mark_doaj_deposit_success'), - url(r'^harvest_citedby_list/$', + url(r'^admin/metadata/generic/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)/metadata$', + journals_views.generic_metadata_xml_deposit, + name='generic_metadata_xml_deposit'), + url(r'^admin/metadata/generic/(?P<deposit_id>[0-9]+)/mark/(?P<success>[0-1])$', + journals_views.mark_generic_deposit_success, + name='mark_generic_deposit_success'), + url(r'^admin/generic/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)/email_made_citable$', + journals_views.email_object_made_citable, + name='email_object_made_citable'), + + # Citedby + url(r'^admin/citedby/$', journals_views.harvest_citedby_list, name='harvest_citedby_list'), - url(r'^harvest_citedby_links/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + url(r'^admin/citedby/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})/harvest$', journals_views.harvest_citedby_links, name='harvest_citedby_links'), - url(r'^sign_existing_report/(?P<report_id>[0-9]+)$', - journals_views.sign_existing_report, - name='sign_existing_report'), - url(r'^manage_report_metadata/$', + + # Reports + url(r'^reports/$', journals_views.manage_report_metadata, name='manage_report_metadata'), - url(r'^manage_comment_metadata/$', - journals_views.manage_comment_metadata, - name='manage_comment_metadata'), - url(r'^mark_report_doi_needed/(?P<report_id>[0-9]+)/(?P<needed>[0-1])$', + url(r'^reports/(?P<report_id>[0-9]+)/sign$', + journals_views.sign_existing_report, + name='sign_existing_report'), + url(r'^reports/(?P<report_id>[0-9]+)/mark_doi_needed/(?P<needed>[0-1])$', journals_views.mark_report_doi_needed, name='mark_report_doi_needed'), - url(r'^mark_comment_doi_needed/(?P<comment_id>[0-9]+)/(?P<needed>[0-1])$', + + # Comments + url(r'^comments/$', + journals_views.manage_comment_metadata, + name='manage_comment_metadata'), + url(r'^comments/(?P<comment_id>[0-9]+)/mark_doi_needed/(?P<needed>[0-1])$', journals_views.mark_comment_doi_needed, name='mark_comment_doi_needed'), - url(r'^generic_metadata_xml_deposit/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)$', - journals_views.generic_metadata_xml_deposit, - name='generic_metadata_xml_deposit'), - url(r'^mark_generic_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', - journals_views.mark_generic_deposit_success, - name='mark_generic_deposit_success'), - url(r'^email_object_made_citable/(?P<type_of_object>[a-z]+)/(?P<object_id>[0-9]+)$', - journals_views.email_object_made_citable, - name='email_object_made_citable'), ] diff --git a/journals/utils.py b/journals/utils.py index da14da589fed0cdb9713666f5c451ad1c6263108..9ae86f9461d9c4784b9f8f2e16e89b524e7212c7 100644 --- a/journals/utils.py +++ b/journals/utils.py @@ -37,57 +37,6 @@ class JournalUtils(BaseMailUtil): reply_to=['admin@scipost.org']) emailmessage.send(fail_silently=False) - @classmethod - def generate_metadata_DOAJ(cls): - """ Requires loading 'publication' attribute. """ - md = { - 'bibjson': { - 'author': [{'name': cls.publication.author_list}], - 'title': cls.publication.title, - 'abstract': cls.publication.abstract, - 'year': cls.publication.publication_date.strftime('%Y'), - 'month': cls.publication.publication_date.strftime('%m'), - 'start_page': cls.publication.get_paper_nr(), - 'identifier': [ - { - 'type': 'eissn', - 'id': str(cls.publication.in_issue.in_volume.in_journal.issn) - }, - { - 'type': 'doi', - 'id': cls.publication.doi_string - } - ], - 'link': [ - { - 'url': cls.request.build_absolute_uri(cls.publication.get_absolute_url()), - 'type': 'fulltext', - } - ], - 'journal': { - 'publisher': 'SciPost', - 'volume': str(cls.publication.in_issue.in_volume.number), - 'number': str(cls.publication.in_issue.number), - 'identifier': [{ - 'type': 'eissn', - 'id': str(cls.publication.in_issue.in_volume.in_journal.issn) - }], - 'license': [ - { - 'url': cls.request.build_absolute_uri( - cls.publication.in_issue.in_volume.in_journal.get_absolute_url()), - 'open_access': 'true', - 'type': cls.publication.get_cc_license_display(), - 'title': cls.publication.get_cc_license_display(), - } - ], - 'language': ['EN'], - 'title': cls.publication.in_issue.in_volume.in_journal.get_name_display(), - } - } - } - return md - @classmethod def email_report_made_citable(cls): """ Requires loading 'report' attribute. """ diff --git a/journals/views.py b/journals/views.py index 2456765e8afcf0601a8725e8b6efbec92db10d3d..432e6dc162641a77220292eb28ea14f78ed1d0cd 100644 --- a/journals/views.py +++ b/journals/views.py @@ -25,7 +25,7 @@ from .models import Journal, Issue, Publication, Deposit, DOAJDeposit,\ GenericDOIDeposit, PublicationAuthorsTable from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\ UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm,\ - ReferenceFormSet + ReferenceFormSet, CreateMetadataDOAJForm from .utils import JournalUtils from comments.models import Comment @@ -248,11 +248,6 @@ def validate_publication(request): # Fill remaining data submission = publication.accepted_submission - if publication.first_author_unregistered: - PublicationAuthorsTable.objects.create( - order=1, - publication=publication, - unregistered_author=publication.first_author_unregistered) for submission_author in submission.authors.all(): PublicationAuthorsTable.objects.create( @@ -342,15 +337,6 @@ def mark_first_author(request, publication_id, author_object_id): publication = get_object_or_404(Publication, id=publication_id) author_object = get_object_or_404(publication.authors, id=author_object_id) - # Save explicit relation - if author_object.is_registered: - publication.first_author = author_object.contributor - publication.first_author_unregistered = None - else: - publication.first_author = None - publication.first_author_unregistered = author_object.unregistered_author - publication.save() - # Redo ordering author_object.order = 1 author_object.save() @@ -367,14 +353,14 @@ def mark_first_author(request, publication_id, author_object_id): @permission_required('scipost.can_publish_accepted_submission', return_403=True) @transaction.atomic -def add_author(request, publication_id, contributor_id=None, unregistered_author_id=None): +def add_author(request, doi_label, contributor_id=None, unregistered_author_id=None): """ If not all authors are registered Contributors or if they have not all claimed authorship, this method allows editorial administrators to associated them to the publication. This is important for the Crossref metadata, in which all authors must appear. """ - publication = get_object_or_404(Publication, id=publication_id) + publication = get_object_or_404(Publication, doi_label=doi_label) if contributor_id: contributor = get_object_or_404(Contributor, id=contributor_id) PublicationAuthorsTable.objects.create(contributor=contributor, publication=publication) @@ -398,7 +384,6 @@ def add_author(request, publication_id, contributor_id=None, unregistered_author kwargs={'doi_label': publication.doi_label})) elif form.is_valid(): contributors_found = Contributor.objects.filter( - # user__first_name__icontains=form.cleaned_data['first_name'], user__last_name__icontains=form.cleaned_data['last_name']) context = { 'publication': publication, @@ -417,18 +402,18 @@ def create_citation_list_metadata(request, doi_label): in the metadata field in a Publication instance. """ publication = get_object_or_404(Publication, doi_label=doi_label) - if request.method == 'POST': - bibitems_form = CitationListBibitemsForm(request.POST, request.FILES) - if bibitems_form.is_valid(): - publication.metadata['citation_list'] = bibitems_form.extract_dois() - publication.save() - bibitems_form = CitationListBibitemsForm() + bibitems_form = CitationListBibitemsForm(request.POST or None, request.FILES or None) + if bibitems_form.is_valid(): + publication.metadata['citation_list'] = bibitems_form.extract_dois() + publication.save() + messages.success(request, 'Updated citation list') + return redirect(reverse('journals:create_citation_list_metadata', + kwargs={'doi_label': publication.doi_label})) context = { 'publication': publication, 'bibitems_form': bibitems_form, + 'citation_list': publication.metadata.get('citation_list', '') } - if request.method == 'POST': - context['citation_list'] = publication.metadata['citation_list'] return render(request, 'journals/create_citation_list_metadata.html', context) @@ -468,22 +453,22 @@ def create_funding_info_metadata(request, doi_label): """ publication = get_object_or_404(Publication, doi_label=doi_label) - funding_info_form = FundingInfoForm(request.POST or None) - if funding_info_form.is_valid(): - publication.metadata['funding_statement'] = funding_info_form.cleaned_data[ - 'funding_statement'] - publication.save() - - try: - initial = {'funding_statement': publication.metadata['funding_statement']} - funding_statement = initial['funding_statement'] - except KeyError: - initial = {'funding_statement': ''} - funding_statement = '' + funding_statement = publication.metadata.get('funding_statement', '') + initial = { + 'funding_statement': funding_statement, + } + form = FundingInfoForm(request.POST or None, instance=publication, initial=initial) + if form.is_valid(): + form.save() + messages.success(request, 'Updated funding info') + return redirect(reverse('journals:create_funding_info_metadata', + kwargs={'doi_label': publication.doi_label})) - context = {'publication': publication, - 'funding_info_form': FundingInfoForm(initial=initial), - 'funding_statement': funding_statement} + context = { + 'publication': publication, + 'funding_info_form': form, + 'funding_statement': funding_statement, + } return render(request, 'journals/create_funding_info_metadata.html', context) @@ -533,13 +518,6 @@ def create_metadata_xml(request, doi_label): """ publication = get_object_or_404(Publication, doi_label=doi_label) - create_metadata_xml_form = CreateMetadataXMLForm(request.POST or None, instance=publication) - if create_metadata_xml_form.is_valid(): - create_metadata_xml_form.save() - messages.success(request, 'Metadata XML saved') - return redirect(reverse('journals:manage_metadata', - kwargs={'doi_label': doi_label})) - # create a doi_batch_id salt = "" for i in range(5): @@ -699,11 +677,20 @@ def create_metadata_xml(request, doi_label): ) initial['metadata_xml'] += '</body>\n</doi_batch>' + create_metadata_xml_form = CreateMetadataXMLForm(request.POST or None, + instance=publication, + initial=initial) + if create_metadata_xml_form.is_valid(): + create_metadata_xml_form.save() + messages.success(request, 'Metadata XML saved') + return redirect(reverse('journals:manage_metadata', + kwargs={'doi_label': doi_label})) + publication.latest_metadata_update = timezone.now() publication.save() context = { 'publication': publication, - 'create_metadata_xml_form': CreateMetadataXMLForm(initial=initial, instance=publication), + 'create_metadata_xml_form': create_metadata_xml_form, } return render(request, 'journals/create_metadata_xml.html', context) @@ -719,8 +706,11 @@ def metadata_xml_deposit(request, doi_label, option='test'): publication = get_object_or_404(Publication, doi_label=doi_label) if publication.metadata_xml is None: - errormessage = 'This publication has no metadata. Produce it first before saving it.' - return render(request, 'scipost/error.html', context={'errormessage': errormessage}) + messages.warning( + request, + 'This publication has no metadata. Produce it first before saving it.') + return redirect(reverse('journals:create_metadata_xml', + kwargs={'doi_label': publication.doi_label})) timestamp = (publication.metadata_xml.partition( '<timestamp>'))[2].partition('</timestamp>')[0] @@ -730,63 +720,71 @@ def metadata_xml_deposit(request, doi_label, option='test'): + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') + '_Crossref_' + timestamp + '.xml') + valid = True + response_headers = None + response_text = None if os.path.isfile(path): - errormessage = 'The metadata file for this metadata timestamp already exists' - return render(request, 'scipost/error.html', context={'errormessage': errormessage}) - - if option == 'deposit' and not settings.DEBUG: - # CAUTION: Real deposit only on production (non-debug-mode) - url = 'http://doi.crossref.org/servlet/deposit' + # Deposit already done before. + valid = False else: - url = 'http://test.crossref.org/servlet/deposit' - - # First perform the actual deposit to Crossref - params = { - 'operation': 'doMDUpload', - 'login_id': settings.CROSSREF_LOGIN_ID, - 'login_passwd': settings.CROSSREF_LOGIN_PASSWORD, + # New deposit, go for it. + if option == 'deposit' and not settings.DEBUG: + # CAUTION: Real deposit only on production (non-debug-mode) + url = 'http://doi.crossref.org/servlet/deposit' + else: + url = 'http://test.crossref.org/servlet/deposit' + + # First perform the actual deposit to Crossref + params = { + 'operation': 'doMDUpload', + 'login_id': settings.CROSSREF_LOGIN_ID, + 'login_passwd': settings.CROSSREF_LOGIN_PASSWORD, + } + files = { + 'fname': ('metadata.xml', publication.metadata_xml.encode('utf-8'), 'multipart/form-data') } - files = { - 'fname': ('metadata.xml', publication.metadata_xml.encode('utf-8'), 'multipart/form-data') - } - r = requests.post(url, params=params, files=files) - response_headers = r.headers - response_text = r.text - - # Then create the associated Deposit object (saving the metadata to a file) - if option == 'deposit': - deposit = Deposit(publication=publication, timestamp=timestamp, doi_batch_id=doi_batch_id, - metadata_xml=publication.metadata_xml, deposition_date=timezone.now()) - 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.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 - deposit.save() - publication.latest_crossref_deposit = timezone.now() - publication.save() + r = requests.post(url, params=params, files=files) + response_headers = r.headers + response_text = r.text + + # Then create the associated Deposit object (saving the metadata to a file) + if option == 'deposit': + deposit = Deposit(publication=publication, + timestamp=timestamp, + doi_batch_id=doi_batch_id, + metadata_xml=publication.metadata_xml, + deposition_date=timezone.now()) + 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.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 + deposit.save() + publication.latest_crossref_deposit = timezone.now() + publication.save() context = { 'option': option, 'publication': publication, 'response_headers': response_headers, 'response_text': response_text, + 'valid': valid, } return render(request, 'journals/metadata_xml_deposit.html', context) @@ -806,12 +804,17 @@ def mark_deposit_success(request, deposit_id, success): @permission_required('scipost.can_publish_accepted_submission', return_403=True) def produce_metadata_DOAJ(request, doi_label): publication = get_object_or_404(Publication, doi_label=doi_label) - JournalUtils.load({'request': request, 'publication': publication}) - publication.metadata_DOAJ = JournalUtils.generate_metadata_DOAJ() - publication.save() - messages.success(request, '<h3>%s</h3>Successfully produced metadata DOAJ.' - % publication.doi_label) - return redirect(reverse('journals:manage_metadata')) + form = CreateMetadataDOAJForm(request.POST or None, instance=publication, request=request) + if form.is_valid(): + form.save() + messages.success(request, '<h3>%s</h3>Successfully produced metadata DOAJ.' + % publication.doi_label) + return redirect(reverse('journals:manage_metadata')) + context = { + 'publication': publication, + 'form': form + } + return render(request, 'journals/metadata_doaj_create.html', context) @permission_required('scipost.can_publish_accepted_submission', return_403=True) @@ -1245,10 +1248,10 @@ def email_object_made_citable(request, **kwargs): if type_of_object == 'report': _object = get_object_or_404(Report, id=object_id) redirect_to = reverse('journals:manage_report_metadata') - publication_citation=None - publication_doi=None + publication_citation = None + publication_doi = None try: - publication=Publication.objects.get( + publication = Publication.objects.get( accepted_submission__arxiv_identifier_wo_vn_nr=_object.submission.arxiv_identifier_wo_vn_nr) publication_citation = publication.citation() publication_doi = publication.doi_string