diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py index 4083889191653f3b3464621e2b8374370f43dd47..861544adb28ad4486484f1974dffafa2cb563a9a 100644 --- a/SciPost_v1/settings/base.py +++ b/SciPost_v1/settings/base.py @@ -240,6 +240,7 @@ JOURNALS_DIR = 'journals' CROSSREF_LOGIN_ID = '' CROSSREF_LOGIN_PASSWORD = '' +DOAJ_API_KEY = '' # Google reCaptcha with Google's global test keys # https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha-v2-what-should-i-do diff --git a/SciPost_v1/settings/production.py b/SciPost_v1/settings/production.py index b6f220c85893695023746f93a09ea40c130f7c14..ab2cfb01f139d2fd78784cccc683cbfb7267adc6 100644 --- a/SciPost_v1/settings/production.py +++ b/SciPost_v1/settings/production.py @@ -38,6 +38,7 @@ SERVER_EMAIL = get_secret("SERVER_EMAIL") # Other CROSSREF_LOGIN_ID = get_secret("CROSSREF_LOGIN_ID") CROSSREF_LOGIN_PASSWORD = get_secret("CROSSREF_LOGIN_PASSWORD") +DOAJ_API_KEY = get_secret("DOAJ_API_KEY") HAYSTACK_CONNECTIONS['default']['PATH'] = '/home/jscaux/webapps/scipost/SciPost_v1/whoosh_index' MAILCHIMP_API_USER = get_secret("MAILCHIMP_API_USER") MAILCHIMP_API_KEY = get_secret("MAILCHIMP_API_KEY") diff --git a/journals/admin.py b/journals/admin.py index 167b0f62e4f1dadb5dcecaff88dc8d128c367ad5..a128f6021b845ab370c588f7dd4f71597c0af4ed 100644 --- a/journals/admin.py +++ b/journals/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin, messages from django import forms -from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, Deposit +from journals.models import UnregisteredAuthor, Journal, Volume, Issue, Publication, \ + Deposit, CLOCKSSmetadata, DOAJDeposit from scipost.models import Contributor from submissions.models import Submission @@ -79,3 +80,8 @@ class DepositAdmin(admin.ModelAdmin): admin.site.register(Deposit, DepositAdmin) + + +admin.site.register(CLOCKSSmetadata) + +admin.site.register(DOAJDeposit) diff --git a/journals/constants.py b/journals/constants.py index 6bd5de5cf9a4285d253a22a9bbb638efde5396f0..7db8b8c2a556c43aaddb121825a6ec209746412e 100644 --- a/journals/constants.py +++ b/journals/constants.py @@ -56,3 +56,12 @@ ISSUE_STATUSES = ( (STATUS_DRAFT, 'Draft'), (STATUS_PUBLISHED, 'Published'), ) + +CCBY4 = 'CC BY 4.0' +CCBYSA4 = 'CC BY-SA 4.0' +CCBYNC4 = 'CC BY-NC 4.0' +CC_LICENSES = ( + (CCBY4, 'CC BY (4.0)'), + (CCBYSA4, 'CC BY-SA (4.0)'), + (CCBYNC4, 'CC BY-NC (4.0)'), +) diff --git a/journals/migrations/0031_clockssmetadata.py b/journals/migrations/0031_clockssmetadata.py new file mode 100644 index 0000000000000000000000000000000000000000..e9f252ab1d59866c6a86176dd8eebf6abdd03841 --- /dev/null +++ b/journals/migrations/0031_clockssmetadata.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-11 03:34 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0030_auto_20170710_1051'), + ] + + operations = [ + migrations.CreateModel( + name='CLOCKSSmetadata', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('metadata_xml_file_CLOCKSS', models.FileField(blank=True, max_length=512, null=True, upload_to='')), + ('publication', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Publication')), + ], + ), + ] diff --git a/journals/migrations/0032_auto_20170711_0952.py b/journals/migrations/0032_auto_20170711_0952.py new file mode 100644 index 0000000000000000000000000000000000000000..25f177b24634e1d976dbad6b66e3b292b83133b5 --- /dev/null +++ b/journals/migrations/0032_auto_20170711_0952.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-11 07:52 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0031_clockssmetadata'), + ] + + operations = [ + migrations.AlterModelOptions( + name='clockssmetadata', + options={'verbose_name': 'CLOCKSS metadata'}, + ), + ] diff --git a/journals/migrations/0033_auto_20170711_2041.py b/journals/migrations/0033_auto_20170711_2041.py new file mode 100644 index 0000000000000000000000000000000000000000..7c77db3e5381b1873623fa4f1e9606ae3af30e7e --- /dev/null +++ b/journals/migrations/0033_auto_20170711_2041.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-11 18:41 +from __future__ import unicode_literals + +import django.contrib.postgres.fields.jsonb +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0032_auto_20170711_0952'), + ] + + operations = [ + migrations.CreateModel( + name='DOAJDeposit', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('timestamp', models.CharField(default='', max_length=40)), + ('metadata_DOAJ', django.contrib.postgres.fields.jsonb.JSONField()), + ('deposition_date', models.DateTimeField(blank=True, null=True)), + ('response_text', models.TextField(blank=True, null=True)), + ('deposit_successful', models.NullBooleanField(default=None)), + ], + options={ + 'verbose_name': 'DOAJ deposit', + }, + ), + migrations.AddField( + model_name='publication', + name='metadata_DOAJ', + field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True), + ), + migrations.AddField( + model_name='doajdeposit', + name='publication', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='journals.Publication'), + ), + ] diff --git a/journals/migrations/0034_publication_cc_license.py b/journals/migrations/0034_publication_cc_license.py new file mode 100644 index 0000000000000000000000000000000000000000..b23b2c997bd72c6252c82999dd57c112826b2a28 --- /dev/null +++ b/journals/migrations/0034_publication_cc_license.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-07-12 06:10 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('journals', '0033_auto_20170711_2041'), + ] + + operations = [ + migrations.AddField( + model_name='publication', + name='cc_license', + field=models.CharField(choices=[('CC BY 4.0', 'CC BY (4.0)'), ('CC BY-SA 4.0', 'CC BY-SA (4.0)'), ('CC BY-NC 4.0', 'CC BY-NC (4.0)')], default='CC BY 4.0', max_length=32), + ), + ] diff --git a/journals/models.py b/journals/models.py index 3f5454a8f8edf552449f05324e644d8d6cac8718..fe5dee82967a4c6e4b8d7d14bffccc6c3245d4f8 100644 --- a/journals/models.py +++ b/journals/models.py @@ -7,7 +7,8 @@ from django.urls import reverse from .behaviors import doi_journal_validator, doi_volume_validator,\ doi_issue_validator, doi_publication_validator from .constants import SCIPOST_JOURNALS, SCIPOST_JOURNALS_DOMAINS,\ - STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES + STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES,\ + CCBY4, CC_LICENSES from .helpers import paper_nr_string, journal_name_abbrev_citation from .managers import IssueManager, PublicationManager @@ -140,9 +141,11 @@ class Publication(models.Model): related_name='authors_pub_false_claims') abstract = models.TextField() pdf_file = models.FileField(upload_to='UPLOADS/PUBLICATIONS/%Y/%m/', max_length=200) + cc_license = models.CharField(max_length=32, choices=CC_LICENSES, default=CCBY4) metadata = JSONField(default={}, blank=True, null=True) metadata_xml = models.TextField(blank=True, null=True) # for Crossref deposit latest_metadata_update = models.DateTimeField(blank=True, null=True) + metadata_DOAJ = JSONField(blank=True, null=True) BiBTeX_entry = models.TextField(blank=True, null=True) doi_label = models.CharField(max_length=200, unique=True, db_index=True, validators=[doi_publication_validator]) @@ -235,4 +238,36 @@ class Deposit(models.Model): def __str__(self): return (self.deposition_date.strftime('%Y-%m-%D') + - ' for 10.21468/' + self.publication.doi_label) + ' for ' + self.publication.doi_label) + + +class CLOCKSSmetadata(models.Model): + """ + For the CLOCKSS archive, JATS formatted XML is produced. + """ + publication = models.ForeignKey(Publication, on_delete=models.CASCADE) + metadata_xml_file_CLOCKSS = models.FileField(blank=True, null=True, max_length=512) + + class Meta: + verbose_name = 'CLOCKSS metadata' + + def __str__(self): + return ('CLOCKSS metadata for ' + self.publication.doi_label) + + +class DOAJDeposit(models.Model): + """ + For the Directory of Open Access Journals. + """ + publication = models.ForeignKey(Publication, on_delete=models.CASCADE) + timestamp = models.CharField(max_length=40, default='') + metadata_DOAJ = JSONField() + deposition_date = models.DateTimeField(blank=True, null=True) + response_text = models.TextField(blank=True, null=True) + deposit_successful = models.NullBooleanField(default=None) + + class Meta: + verbose_name = 'DOAJ deposit' + + def __str__(self): + return ('DOAJ deposit for ' + self.publication.doi_label) diff --git a/journals/templates/journals/manage_metadata.html b/journals/templates/journals/manage_metadata.html index 2d5ec8c2408bec25d1d633d422a2e865a7dc6f7a..cff6224e24894f7cc100e138777a4a6548faf709 100644 --- a/journals/templates/journals/manage_metadata.html +++ b/journals/templates/journals/manage_metadata.html @@ -35,6 +35,8 @@ event: "focusin" <th>Publication date</th> <th>Latest metadata update</th> <th>Latest successful Crossref deposit</th> + <th>CLOCKSS</th> + <th>DOAJ</th> </tr> </thead> @@ -51,9 +53,11 @@ event: "focusin" <td>No info available</td> {% endif %} <td>{{ publication|latest_successful_crossref_deposit }}</td> + <td>{% if publication.clockssmetadata_set.all.exists %}File exists{% else %}File does not exist{% endif %}</td> + <td>{{ publication|latest_successful_DOAJ_deposit }}</td> </tr> <tr id="collapse{{ publication.id }}" class="collapse" role="tabpanel" aria-labelledby="heading{{ publication.id }}" style="background-color: #fff;"> - <td colspan="4"> + <td colspan="5"> <h3 class="ml-3">Actions</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 %}) @@ -87,8 +91,11 @@ event: "focusin" <li><a href="{% url 'journals:create_metadata_xml' publication.doi_label %}">(re)create metadata</a></li> <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:produce_CLOCKSS_metadata_file' doi_label=publication.doi_label %}">Produce CLOCKSS metadata file</a></li> + <li><a href="{% url 'journals:produce_metadata_DOAJ' doi_label=publication.doi_label %}">Produce DOAJ metadata</a></li> + <li><a href="{% url 'journals:metadata_DOAJ_deposit' doi_label=publication.doi_label %}">Deposit the metadata to DOAJ</a></li> </ul> - <h3 class="ml-3">Deposits</h3> + <h3 class="ml-3">Crossref Deposits</h3> <table class="ml-5"> <thead class="thead-default"> <th>Timestamp</th> @@ -112,12 +119,42 @@ event: "focusin" </td> </tr> {% empty %} + <tr> + <td colspan="5">No Deposits found for this publication</td> + </tr> + {% endfor %} + </tbody> + </table> + + <h3 class="ml-3">DOAJ Deposits</h3> + <table class="ml-5"> + <thead class="thead-default"> + <th>Timestamp</th> + <th>deposition date</th> + <th>Successful?</th> + <th>actions</th> + </thead> + <tbody> + {% for deposit in publication.doajdeposit_set.all %} + <tr> + <td>{{ deposit.timestamp }}</td> + <td>{% if deposit.deposition_date %}{{ deposit.deposition_date }}{% else %}Not deposited{% endif %}</td> + <td>{{ deposit.deposit_successful }}</td> + <td>Mark deposit as + <ul> + <li><a href="{% url 'journals:mark_doaj_deposit_success' deposit_id=deposit.id success=1 %}">successful</a></li> + <li><a href="{% url 'journals:mark_doaj_deposit_success' deposit_id=deposit.id success=0 %}">unsuccessful</a></li> + </ul> + </td> + </tr> + {% empty %} <tr> <td colspan="4">No Deposits found for this publication</td> </tr> {% endfor %} </tbody> </table> + </td> </tr> {% empty %} diff --git a/journals/templates/journals/publication_metadata_jats.xml b/journals/templates/journals/publication_metadata_jats.xml new file mode 100644 index 0000000000000000000000000000000000000000..6f97e3fb7fc8eb3b2ef9163e82333ab1b2f95add --- /dev/null +++ b/journals/templates/journals/publication_metadata_jats.xml @@ -0,0 +1,22 @@ +<article dtd-version="1.1d3"> +<front> +<journal-meta> +<publisher> +<publisher-name>SciPost</publisher-name> +</publisher> +<issn>{{ publication.in_issue.in_volume.in_journal.issn }}</issn> +</journal-meta> +<article-meta> +<title-group> +<article-title>{{ publication.title }}</article-title> +</title-group> +<article-id pub-id-type="doi">{{ publication.doi_string }}</article-id> +<volume>{{ publication.in_issue.in_volume.number }}</volume> +<issue>{{ publication.in_issue.number }}</issue> +<pub-date publication-format="epub" date-type="pub" iso-8601-date="{{ publication.publication_date|date:'Y-m-d' }}"> +<day>{{ publication.publication_date|date:'d' }}</day> +<month>{{ publication.publication_date|date:'m' }}</month> +<year>{{ publication.publication_date|date:'Y' }}</year> +</pub-date></article-meta> +</front> +</article> diff --git a/journals/templatetags/journals_extras.py b/journals/templatetags/journals_extras.py index 36ca1920715e306fd6e8ed8cccc0caa6ca998747..d995ca07c160a96cad93d8efab44c91e72bf4dc2 100644 --- a/journals/templatetags/journals_extras.py +++ b/journals/templatetags/journals_extras.py @@ -10,10 +10,19 @@ def paper_nr_string_filter(nr): return paper_nr_string(nr) @register.filter(name='latest_successful_crossref_deposit') -def latest_crossref_deposition_date(publication): +def latest_successful_crossref_deposit(publication): latest = publication.deposit_set.filter( deposit_successful=True).order_by('-deposition_date').first() if latest: return latest.deposition_date.strftime('%Y-%m-%d') else: return "No successful deposit found" + +@register.filter(name='latest_successful_DOAJ_deposit') +def latest_successful_DOAJ_deposit(publication): + latest = publication.doajdeposit_set.filter( + deposit_successful=True).order_by('-deposition_date').first() + if latest: + return latest.deposition_date.strftime('%Y-%m-%d') + else: + return "No successful deposit found" diff --git a/journals/urls/general.py b/journals/urls/general.py index 3fd938879af8c5c5c48efd01b797d8f557d29595..eb5dbc91cb505466188ef1aae4e2a55de2472514 100644 --- a/journals/urls/general.py +++ b/journals/urls/general.py @@ -7,7 +7,8 @@ from journals import views as journals_views urlpatterns = [ # Journals url(r'^$', TemplateView.as_view(template_name='journals/journals.html'), name='journals'), - url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page', args=['SciPostPhys']))), + url(r'scipost_physics', RedirectView.as_view(url=reverse_lazy('scipost:landing_page', + args=['SciPostPhys']))), url(r'^journals_terms_and_conditions$', TemplateView.as_view(template_name='journals/journals_terms_and_conditions.html'), name='journals_terms_and_conditions'), @@ -55,6 +56,18 @@ urlpatterns = [ 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_CLOCKSS_metadata_file/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + journals_views.produce_CLOCKSS_metadata_file, + name='produce_CLOCKSS_metadata_file'), + url(r'^produce_metadata_DOAJ/(?P<doi_label>[a-zA-Z]+.[0-9]+.[0-9]+.[0-9]{3,})$', + 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,})$', + journals_views.metadata_DOAJ_deposit, + name='metadata_DOAJ_deposit'), + url(r'^mark_doaj_deposit_success/(?P<deposit_id>[0-9]+)/(?P<success>[0-1])$', + journals_views.mark_doaj_deposit_success, + name='mark_doaj_deposit_success'), url(r'^harvest_citedby_list/$', journals_views.harvest_citedby_list, name='harvest_citedby_list'), diff --git a/journals/utils.py b/journals/utils.py index b1e7630d7fc7656e2a559f33977dedad3b42f3ba..1f1f0e0bd21261c6a9e11ed714e2036c245da992 100644 --- a/journals/utils.py +++ b/journals/utils.py @@ -39,5 +39,48 @@ class JournalUtils(object): emailmessage.send(fail_silently=False) @classmethod - def generate_metadata_xml_file(cls): + 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': '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 diff --git a/journals/views.py b/journals/views.py index 4eb5a68106b50e0a52caa29f5114ba02f4ffdc2a..6509c95d3d81a5f230dfe27da309d5603ccbe05b 100644 --- a/journals/views.py +++ b/journals/views.py @@ -11,17 +11,19 @@ from django.conf import settings from django.contrib import messages from django.utils import timezone from django.shortcuts import get_object_or_404, render, redirect +from django.template import Context +from django.template.loader import get_template from django.db import transaction from django.http import HttpResponse from .exceptions import PaperNumberingError from .helpers import paper_nr_string -from .models import Journal, Issue, Publication, UnregisteredAuthor +from .models import Journal, Issue, Publication, UnregisteredAuthor, DOAJDeposit from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\ UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm from .utils import JournalUtils -from journals.models import Publication, Deposit +from journals.models import Deposit, CLOCKSSmetadata from submissions.models import Submission from scipost.models import Contributor @@ -137,7 +139,6 @@ def issue_detail(request, doi_label): return render(request, 'journals/journal_issue_detail.html', context) - ####################### # Publication process # ####################### @@ -273,7 +274,7 @@ def validate_publication(request): @permission_required('scipost.can_publish_accepted_submission', return_403=True) def manage_metadata(request): - publications = Publication.objects.order_by('-publication_date') + publications = Publication.objects.order_by('-publication_date', '-paper_nr') context = { 'publications': publications } @@ -471,11 +472,13 @@ def create_metadata_xml(request, doi_label): '<body>\n' '<journal>\n' '<journal_metadata>\n' - '<full_title>' + publication.in_issue.in_volume.in_journal.get_name_display() + '</full_title>\n' + '<full_title>' + publication.in_issue.in_volume.in_journal.get_name_display() + + '</full_title>\n' '<abbrev_title>' + publication.in_issue.in_volume.in_journal.get_abbreviation_citation() + '</abbrev_title>\n' - '<issn>' + publication.in_issue.in_volume.in_journal.issn + '</issn>\n' + '<issn media_type=\'electronic\'>' + publication.in_issue.in_volume.in_journal.issn + + '</issn>\n' '<doi_data>\n' '<doi>' + publication.in_issue.in_volume.in_journal.doi_string + '</doi>\n' '<resource>https://scipost.org/' @@ -584,6 +587,16 @@ def metadata_xml_deposit(request, doi_label, option='test'): Makes use of the python requests module. """ publication = get_object_or_404(Publication, doi_label=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') + 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': url = 'http://doi.crossref.org/servlet/deposit' elif option == 'test': @@ -608,22 +621,23 @@ def metadata_xml_deposit(request, doi_label, option='test'): response_headers = r.headers response_text = r.text - # Then, if deposit, create the associated Deposit object (saving the metadata to a file) - content = ContentFile(publication.metadata_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] - path = (settings.MEDIA_ROOT + publication.in_issue.path + '/' - + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') - + '_' + timestamp + '.xml') - deposit = Deposit(publication=publication, timestamp=timestamp, doi_batch_id=doi_batch_id, - metadata_xml=publication.metadata_xml, deposition_date=timezone.now()) - deposit.metadata_xml_file.save(path, content) - deposit.response_text = r.text - deposit.save() - publication.latest_crossref_deposit = timezone.now() - publication.save() + # Then create the associated Deposit object (saving the metadata to a file) + if option == 'deposit': + content = ContentFile(publication.metadata_xml) + deposit = Deposit(publication=publication, timestamp=timestamp, doi_batch_id=doi_batch_id, + metadata_xml=publication.metadata_xml, deposition_date=timezone.now()) + deposit.metadata_xml_file.save(path, content) + deposit.response_text = r.text + deposit.save() + publication.latest_crossref_deposit = timezone.now() + publication.save() + # Save a copy to the filename without timestamp + path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/' + + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') + + '_Crossref.xml') + f = open(path1, 'w') + f.write(publication.metadata_xml) + f.close() context = { 'option': option, @@ -645,6 +659,121 @@ def mark_deposit_success(request, deposit_id, success): return redirect(reverse('journals:manage_metadata')) +@permission_required('scipost.can_publish_accepted_submission', return_403=True) +def produce_CLOCKSS_metadata_file(request, doi_label): + publication = get_object_or_404(Publication, doi_label=doi_label) + context = Context({'publication': publication}) + xml = get_template('journals/publication_metadata_jats.xml').render(context) + content = ContentFile(xml) + 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('.', '_') + + '_CLOCKSS_' + timestamp + '.xml') + if os.path.isfile(path): + errormessage = 'The CLOCKSS metadata file for this metadata timestamp already exists' + return render(request, 'scipost/error.html', context={'errormessage': errormessage}) + clockssmeta = CLOCKSSmetadata(publication=publication) + clockssmeta.metadata_xml_file_CLOCKSS.save(path, content) + clockssmeta.save() + # Save a copy to the filename without timestamp + path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/' + + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') + + '_CLOCKSS.xml') + f = open(path1, 'w') + f.write(xml) + f.close() + return redirect(reverse('journals:manage_metadata')) + + +@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')) + + +@permission_required('scipost.can_publish_accepted_submission', return_403=True) +@transaction.atomic +def metadata_DOAJ_deposit(request, doi_label): + """ + DOAJ metadata deposit. + Makes use of the python requests module. + """ + publication = get_object_or_404(Publication, doi_label=doi_label) + if not publication.metadata_DOAJ: + messages.warning(request, '<h3>%s</h3>Failed: please first produce ' + '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') + if os.path.isfile(path): + errormessage = 'The metadata file for this metadata timestamp already exists' + return render(request, 'scipost/error.html', context={'errormessage': errormessage}) + url = 'https://doaj.org/api/v1/articles' + + params = { + 'operation': 'doMDUpload', + 'api_key': settings.DOAJ_API_KEY, + } + files = {'fname': ('metadata.json', publication.metadata_xml, 'application/json')} + try: + r = requests.post(url, params=params, files=files) + r.raise_for_status() + except requests.exceptions.HTTPError: + messages.warning(request, '<h3>%s</h3>Failed: Post went wrong. Did you set the right ' + 'DOAJ API KEY?' % publication.doi_label) + return redirect(reverse('journals:manage_metadata')) + + # Then create the associated Deposit object (saving the metadata to a file) + content = ContentFile(publication.metadata_xml) + deposit = DOAJDeposit(publication=publication, timestamp=timestamp, + metadata_DOAJ=publication.metadata_DOAJ, deposition_date=timezone.now()) + deposit.metadata_xml_file.save(path, content) + deposit.response_text = r.text + deposit.save() + publication.latest_crossref_deposit = timezone.now() + publication.save() + + # Save a copy to the filename without timestamp + path1 = (settings.MEDIA_ROOT + publication.in_issue.path + '/' + + publication.get_paper_nr() + '/' + publication.doi_label.replace('.', '_') + + '_DOAJ.json') + f = open(path1, 'w') + f.write(publication.metadata_DOAJ) + f.close() + + # response_headers = r.headers + # response_text = r.text + # context = { + # 'publication': publication, + # 'response_headers': response_headers, + # 'response_text': response_text, + # } + messages.success(request, '<h3>%s</h3>Successfull deposit of metadata DOAJ.' + % publication.doi_label) + return redirect(reverse('journals:manage_metadata')) + + +@permission_required('scipost.can_publish_accepted_submission', return_403=True) +def mark_doaj_deposit_success(request, deposit_id, success): + deposit = get_object_or_404(DOAJDeposit, pk=deposit_id) + if success == '1': + deposit.deposit_successful = True + elif success == '0': + deposit.deposit_successful = False + deposit.save() + return redirect(reverse('journals:manage_metadata')) + + @permission_required('scipost.can_publish_accepted_submission', return_403=True) def harvest_citedby_list(request): publications = Publication.objects.order_by('-publication_date')