From 7f2a6fdc668227819972e2163a7bbad7bdffe6fe Mon Sep 17 00:00:00 2001 From: "J.-S. Caux" <J.S.Caux@uva.nl> Date: Fri, 13 May 2016 14:55:52 +0200 Subject: [PATCH] Autofill submission form from arXiv metadata --- commentaries/views.py | 6 +- scipost/models.py | 16 +++++ scipost/templates/scipost/about.html | 3 +- submissions/forms.py | 12 +++- submissions/models.py | 4 ++ .../templates/submissions/editorial_page.html | 6 +- .../submissions/submission_detail.html | 6 ++ .../submissions/submit_manuscript.html | 18 ++++- submissions/urls.py | 1 + submissions/views.py | 68 ++++++++++++++++++- 10 files changed, 131 insertions(+), 9 deletions(-) diff --git a/commentaries/views.py b/commentaries/views.py index 0cc7bfe44..6c7df474b 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -95,7 +95,7 @@ def prefill_using_DOI(request): doiform = DOIToQueryForm(request.POST) if doiform.is_valid(): # Check if given doi is of expected form: - doipattern = re.compile("10.[0-9]{4,9}/[-._;()/:a-zA-Z0-9]+") + doipattern = re.compile("^10.[0-9]{4,9}/[-._;()/:a-zA-Z0-9]+") errormessage = '' existing_commentary = None if not doipattern.match(doiform.cleaned_data['doi']): @@ -169,8 +169,8 @@ def prefill_using_identifier(request): identifierform = IdentifierToQueryForm(request.POST) if identifierform.is_valid(): # Check if given identifier is of expected form: - identifierpattern_new = re.compile("[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}") # we allow 1 or 2 digits for version - identifierpattern_old = re.compile("[-.a-z]+/[0-9]{7,}v[0-9]{1,2}") + identifierpattern_new = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$") # we allow 1 or 2 digits for version + identifierpattern_old = re.compile("^[-.a-z]+/[0-9]{7,}v[0-9]{1,2}$") errormessage = '' existing_commentary = None if not (identifierpattern_new.match(identifierform.cleaned_data['identifier']) or diff --git a/scipost/models.py b/scipost/models.py index 323cab122..1cb8231b9 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -413,6 +413,22 @@ class Graph(models.Model): return template.render(context) +# ARC_LENGTHS = [ +# (4, '4'), (8, '8'), (16, '16'), (32, '32'), (64, '64'), (128, '128') +# ] + +# class Arc(models.Model): +# """ +# Arc of a graph, linking two nodes. +# The length is user-adjustable. +# """ +# graph = models.ForeignKey(Graph, default=None) +# added_by = models.ForeignKey(Contributor, default=None) +# created = models.DateTimeField(default=timezone.now) +# node_from = models.ForeignKey(Node) +# node_to = models.ForeignKey(Node) +# length = models.PositiveSmallIntegerField(choices=ARC_LENGTHS) + class Node(models.Model): """ Node of a graph (directed). diff --git a/scipost/templates/scipost/about.html b/scipost/templates/scipost/about.html index 88d4ffe5f..8f3a4317d 100644 --- a/scipost/templates/scipost/about.html +++ b/scipost/templates/scipost/about.html @@ -130,12 +130,13 @@ <ul> <li>Prof. <a href="http://people.sissa.it/~mussardo/">G. Mussardo</a><br/>(SISSA)</li> <li>Prof. <a href="http://www.ru.nl/ssi/members/theo_rasing/">T. Rasing</a><br/>(Radboud Univ. Nijmegen)</li> + <li>Prof. <a href="http://www.professoren.tum.de/en/spohn-herbert/">H. Spohn</a><br/>(TU Munich)</li> </ul> </div> <div class="flex-whitebox"> <ul> - <li>Prof. <a href="http://www.professoren.tum.de/en/spohn-herbert/">H. Spohn</a><br/>(TU Munich)</li> <li>Prof. <a href="http://www.uva.nl/over-de-uva/organisatie/medewerkers/content/v/e/e.p.verlinde/e.p.verlinde.html">E. P. Verlinde</a><br/>(U. van Amsterdam)</li> + <li>Prof. <a href="https://staff.fnwi.uva.nl/j.t.m.walraven/walraven/JookWalraven.htm">J.T.M. Walraven</a><br/>(U. van Amsterdam)</li> </ul> </div> </div> diff --git a/submissions/forms.py b/submissions/forms.py index 14136ed30..b5271c51c 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -7,15 +7,25 @@ from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Div, Field, Fieldset, HTML, Submit +class SubmissionIdentifierForm(forms.Form): + identifier = forms.CharField(widget=forms.TextInput({'label': 'arXiv identifier', + 'placeholder': 'new style (with version nr) ####.####(#)v#(#)', + 'cols': 20})) + class SubmissionForm(forms.ModelForm): class Meta: model = Submission - fields = ['discipline', 'submitted_to_journal', 'domain', 'specialization', 'title', 'author_list', 'abstract', 'arxiv_link'] + fields = ['discipline', 'submitted_to_journal', 'domain', 'specialization', + 'title', 'author_list', 'abstract', 'arxiv_link', 'metadata', 'referees_flagged'] def __init__(self, *args, **kwargs): super(SubmissionForm, self).__init__(*args, **kwargs) self.fields['arxiv_link'].widget.attrs.update({'placeholder': 'ex.: arxiv.org/abs/1234.56789v1'}) + self.fields['metadata'].widget = forms.HiddenInput() self.fields['abstract'].widget.attrs.update({'cols': 100}) + self.fields['referees_flagged'].widget.attrs.update({ + 'placeholder': 'Optional: names of referees whose reports should be treated with caution (+ short reason)', + 'rows': 3}) class SubmissionSearchForm(forms.Form): diff --git a/submissions/models.py b/submissions/models.py index 886811749..595dfad87 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -2,6 +2,7 @@ from django.utils import timezone from django.utils.safestring import mark_safe from django.db import models from django.contrib.auth.models import User +from django.contrib.postgres.fields import JSONField from django.template import Template, Context from .models import * @@ -49,6 +50,7 @@ class Submission(models.Model): domain = models.CharField(max_length=3, choices=SCIPOST_JOURNALS_DOMAINS) specialization = models.CharField(max_length=1, choices=SCIPOST_JOURNALS_SPECIALIZATIONS) status = models.CharField(max_length=30, choices=SUBMISSION_STATUS) # set by Editors + referees_flagged = models.TextField(blank=True, null=True) open_for_reporting = models.BooleanField(default=True) reporting_deadline = models.DateTimeField(default=timezone.now) open_for_commenting = models.BooleanField(default=True) @@ -60,6 +62,7 @@ class Submission(models.Model): authors_false_claims = models.ManyToManyField (Contributor, blank=True, related_name='authors_sub_false_claims') abstract = models.TextField() arxiv_link = models.URLField(verbose_name='arXiv link (including version nr)') + metadata = JSONField(default={}, blank=True, null=True) submission_date = models.DateField(verbose_name='submission date') latest_activity = models.DateTimeField(default=timezone.now) @@ -272,6 +275,7 @@ class Report(models.Model): # date_invited = models.DateTimeField('date invited', blank=True, null=True) # invited_by = models.ForeignKey(Contributor, blank=True, null=True, related_name='invited_by') invited = models.BooleanField(default=False) # filled from RefereeInvitation objects at moment of report submission + flagged = models.BooleanField(default=False) # if author of report has been flagged by submission authors (surname check only) date_submitted = models.DateTimeField('date submitted') author = models.ForeignKey(Contributor) qualification = models.PositiveSmallIntegerField(choices=REFEREE_QUALIFICATION, verbose_name="Qualification to referee this: I am ") diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html index 84e5b2709..d0481bcb4 100644 --- a/submissions/templates/submissions/editorial_page.html +++ b/submissions/templates/submissions/editorial_page.html @@ -27,6 +27,10 @@ <h3>Abstract:</h3> <p>{{ submission.abstract }}</p> + {% if submission.referees_flagged %} + <h3>Referees flagged upon submission (treat reports with caution):</h3> + <p>{{ submission.referees_flagged }}</p> + {% endif %} </section> @@ -40,7 +44,7 @@ <hr class="hr6"/> <h3>Actions:</h3> <ul> - <li><a href="{% url 'submissions:select_referee' submission_id=submission.id %}">Select an additional referee</a></li> + <li><a href="{% url 'submissions:select_referee' submission_id=submission.id %}">Select an additional referee</a> (bear in mind flagged referees if any)</li> <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline }}) by <a href="{% url 'submissions:extend_refereeing_deadline' submission_id=submission.id days=2 %}">2 days</a>, <a href="{% url 'submissions:extend_refereeing_deadline' submission_id=submission.id days=7 %}">1 week</a> or diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 995051028..5578d6e90 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -76,6 +76,9 @@ {% for report in invited_reports %} <hr class="hr6"/> {% if user|is_in_group:'Editorial College' %} + {% if report.flagged %} + <h4 style="color: red">CAUTION: check if this referee has been flagged by the authors</h4> + {% endif %} {{ report.print_contents_for_editors }} {% else %} {{ report.print_identifier }} @@ -148,6 +151,9 @@ {% for report in contributed_reports %} <hr class="hr6"/> {% if user|is_in_group:'Editorial College' %} + {% if report.flagged %} + <h4 style="color: red">CAUTION: check if this referee has been flagged by the authors</h4> + {% endif %} {{ report.print_contents_for_editors }} {% else %} {{ report.print_identifier }} diff --git a/submissions/templates/submissions/submit_manuscript.html b/submissions/templates/submissions/submit_manuscript.html index b14efcefb..8b17b4463 100644 --- a/submissions/templates/submissions/submit_manuscript.html +++ b/submissions/templates/submissions/submit_manuscript.html @@ -4,15 +4,29 @@ {% block bodysup %} - <section> <h1>Submit a manuscript to SciPost</h1> <p id="journalsannounce">OPEN FOR SUBMISSION STARTING JUNE 2016</p> - {% if false %} <!-- Temporary deactivate submissions --> + {% if False %} <!-- Temporary deactivate submissions --> {% if perms.scipost.can_submit_manuscript %} + + <div class="flex-greybox"> + <h3><em>You can prefill part of the form using the arXiv identifier:</em></h3> + <p><em>(give the identifier without prefix, as per the placeholder)</em></p> + {% if errormessage %} + <h3 style="color: red;">Error: {{ errormessage }}</h3> + {% endif %} + <form action="{% url 'submissions:prefill_using_identifier' %}" method="post"> + {% csrf_token %} + {{ identifierform }} + <input type="submit" value="Query arXiv"/> + </form> + </div> + <br/> + <form action="{% url 'submissions:submit_manuscript' %}" method="post"> {% csrf_token %} <table> diff --git a/submissions/urls.py b/submissions/urls.py index 3acda1a9b..d9a59d3c6 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -11,6 +11,7 @@ urlpatterns = [ url(r'^author_guidelines$', TemplateView.as_view(template_name='submissions/author_guidelines.html'), name='author_guidelines'), #url(r'^submission/(?P<submission_id>[0-9]+)/$', views.submission_detail, name='submission'), url(r'^(?P<submission_id>[0-9]+)/$', views.submission_detail, name='submission'), + url(r'^prefill_using_identifier$', views.prefill_using_identifier, name='prefill_using_identifier'), url(r'^submit_manuscript$', views.submit_manuscript, name='submit_manuscript'), url(r'^submit_manuscript_ack$', TemplateView.as_view(template_name='submissions/submit_manuscript_ack.html'), name='submit_manuscript_ack'), url(r'^assign_submissions$', views.assign_submissions, name='assign_submissions'), diff --git a/submissions/views.py b/submissions/views.py index dc167b82b..51eee2873 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -1,4 +1,8 @@ import datetime +import feedparser +import re +import requests + from django.utils import timezone from django.shortcuts import get_object_or_404, render, redirect from django.contrib.auth import authenticate, login, logout @@ -26,6 +30,61 @@ from comments.forms import CommentForm # SUBMISSIONS: ############### +@permission_required('scipost.can_submit_manuscript', raise_exception=True) +def prefill_using_identifier(request): + if request.method == "POST": + identifierform = SubmissionIdentifierForm(request.POST) + if identifierform.is_valid(): + identifierpattern = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$") # we allow 1 or 2 digits for version + errormessage = '' + if not identifierpattern.match(identifierform.cleaned_data['identifier']): + errormessage = 'The identifier you entered is improperly formatted (did you forget the version number?).' + form = SubmissionForm() + return render(request, 'submissions/submit_manuscript.html', + {'identifierform': identifierform, 'form': form, + 'errormessage': errormessage}) + # Otherwise we query arXiv for the information: + try: + queryurl = 'http://export.arxiv.org/api/query?id_list=%s' % identifierform.cleaned_data['identifier'] + arxivquery = feedparser.parse(queryurl) + # If paper has been published, should comment on published version + try: + arxiv_journal_ref = arxivquery['entries'][0]['arxiv_journal_ref'] + errormessage = 'This paper has been published as ' + arxiv_journal_ref + '. You cannot submit it to SciPost anymore.' + except: + pass + try: + arxiv_doi = arxivquery['entries'][0]['arxiv_doi'] + errormessage = 'This paper has been published under DOI ' + arxiv_DOI + '. You cannot submit it to SciPost anymore.' + except: + pass + if errormessage != '': + form = SubmissionForm() + context = {'identifierform': identifierform, 'form': form, + 'errormessage': errormessage} + return render(request, 'submissions/submit_manuscript.html', context) + # otherwise prefill the form: + metadata = arxivquery + title = arxivquery['entries'][0]['title'] + authorlist = arxivquery['entries'][0]['authors'][0]['name'] + for author in arxivquery['entries'][0]['authors'][1:]: + authorlist += ', ' + author['name'] + arxiv_link = arxivquery['entries'][0]['id'] + abstract = arxivquery['entries'][0]['summary'] + form = SubmissionForm( + initial={'metadata': metadata, + 'title': title, 'author_list': authorlist, + 'arxiv_identifier': identifierform.cleaned_data['identifier'], + 'arxiv_link': arxiv_link, 'abstract': abstract}) + context = {'identifierform': identifierform, 'form': form} + return render(request, 'submissions/submit_manuscript.html', context) + except: + pass + else: + pass + return redirect(reverse('submissions:submit_manuscript')) + + @permission_required('scipost.can_submit_manuscript', raise_exception=True) def submit_manuscript(request): if request.method == 'POST': @@ -44,12 +103,15 @@ def submit_manuscript(request): abstract = form.cleaned_data['abstract'], arxiv_link = form.cleaned_data['arxiv_link'], submission_date = timezone.now(), + referees_flagged = form.cleaned_data['referees_flagged'], ) submission.save() return HttpResponseRedirect(reverse('submissions:submit_manuscript_ack')) else: + identifierform = SubmissionIdentifierForm() form = SubmissionForm() - return render(request, 'submissions/submit_manuscript.html', {'form': form}) + return render(request, 'submissions/submit_manuscript.html', + {'identifierform': identifierform, 'form': form}) def submissions(request): @@ -416,10 +478,14 @@ def submit_report(request, submission_id): invitation = RefereeInvitation.objects.get(submission=submission, referee=request.user.contributor) invitation.fulfilled = True invitation.save() + flagged = False + if author.user.last_name in submission.referees_flagged: + flagged = True newreport = Report ( submission = submission, author = author, invited = invited, + flagged = flagged, qualification = form.cleaned_data['qualification'], strengths = form.cleaned_data['strengths'], weaknesses = form.cleaned_data['weaknesses'], -- GitLab