diff --git a/submissions/forms.py b/submissions/forms.py index 210a0adcb339cca19e8a4aa0c37eeab21a3c6d89..e299e58cd601c661b44c9bcd3adb8148729ed554 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.core.validators import RegexValidator #from django.contrib.auth.models import User, Group from .models import * @@ -20,10 +21,22 @@ class SubmissionSearchForm(forms.Form): ############################### class SubmissionIdentifierForm(forms.Form): - identifier = forms.CharField(widget=forms.TextInput( - {'label': 'arXiv identifier', - 'placeholder': 'new style (with version nr) ####.####(#)v#(#)', - 'cols': 20})) + identifier = forms.CharField( + widget=forms.TextInput( + {'label': 'arXiv identifier', + 'placeholder': 'new style (with version nr) ####.####(#)v#(#)', + 'cols': 20} + ), + validators=[ + RegexValidator( + regex="^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$", + message='The identifier you entered is improperly formatted ' + '(did you forget the version number?)', + code='invalid_identifier' + ), + ]) + + class SubmissionForm(forms.ModelForm): class Meta: diff --git a/submissions/services.py b/submissions/services.py index feb7c1683c447ef8fd1135cdd654b62186033eb3..bd16fb2ae70960507034ca3e46f8b6780a85fe87 100644 --- a/submissions/services.py +++ b/submissions/services.py @@ -1 +1,86 @@ # Module for making external api calls as needed in the submissions cycle +import feedparser + +from .models import * + + +class ArxivCaller(): + def lookup_article(identifier): + # Pre-checks + if same_version_exists(identifier) + return False, "This preprint version has already been submitted to SciPost." + + # Split the given identifier in an article identifier and version number + identifier_without_vn_nr = identifier.rpartition('v')[0] + arxiv_vn_nr = int(identifier.rpartition('v')[2]) + + resubmission = False + if previous_submission_undergoing_refereeing(identifier): + errormessage = '<p>There exists a preprint with this arXiv identifier ' + 'but an earlier version number, which is still undergoing ' + 'peer refereeing.</p>' + '<p>A resubmission can only be performed after request ' + 'from the Editor-in-charge. Please wait until the ' + 'closing of the previous refereeing round and ' + 'formulation of the Editorial Recommendation ' + 'before proceeding with a resubmission.</p>' + return False, errormessage + + # Arxiv query + queryurl = ('http://export.arxiv.org/api/query?id_list=%s' + % identifier) + arxiv_response = feedparser.parse(queryurl) + + # Check if response has at least one entry + if not 'entries' in arxiv_response + errormessage = 'Bad response from Arxiv.' + return False, errormessage + + # Check if preprint exists + if not preprint_exists(arxiv_response) + errormessage = 'A preprint associated to this identifier does not exist.' + return False, errormessage + + # Check via journal ref if already published + arxiv_journal_ref = published_journal_ref + if arxiv_journal_ref + errormessage = 'This paper has been published as ' + arxiv_journal_ref + + '. You cannot submit it to SciPost anymore.' + return False, resubmission + + # Check via DOI if already published + arxiv_doi = published_journal_ref + if arxiv_doi + errormessage = 'This paper has been published under DOI ' + arxiv_doi + + '. You cannot submit it to SciPost anymore.' + return False, errormessage + + return arxiv_response, "" + + + def same_version_exists(identifier): + return Submission.objects.filter(arxiv_identifier_w_vn_nr=identifier).exists() + + def previous_submission_undergoing_refereeing(identifier): + previous_submissions = Submission.objects.filter( + arxiv_identifier_wo_vn_nr=identifier).order_by('-arxiv_vn_nr') + + if previous_submissions: + return not previous_submissions[0].status == 'revision_requested' + else: + return False + + def preprint_exists(arxiv_response): + return 'title' in arxiv_response['entries'][0] + + def published_journal_ref(arxiv_response): + if 'arxiv_journal_ref' in arxiv_response['entries'][0] + return arxiv_response['entries'][0]['arxiv_journal_ref'] + else: + return False + + def published_DOI(arxiv_response): + if 'arxiv_doi' in arxiv_response['entries'][0] + return arxiv_response['entries'][0]['arxiv_doi'] + else: + return False diff --git a/submissions/tests/test_views.py b/submissions/tests/test_views.py index 0dab58dc06ee0971289b52b80d8f5ae8f8453a9b..f35d237bde6def6e0755612febe441d1d10d6d63 100644 --- a/submissions/tests/test_views.py +++ b/submissions/tests/test_views.py @@ -8,7 +8,7 @@ from submissions.views import * class PrefillUsingIdentifierTest(TestCase): fixtures = ['permissions', 'groups', 'contributors'] - def test_retrieving_arxiv_paper(self): + def test_retrieving_existing_arxiv_paper(self): client = Client() client.login(username="Test", password="testpw") @@ -16,3 +16,12 @@ class PrefillUsingIdentifierTest(TestCase): {'identifier': '1512.00030v1'}) self.assertEqual(response.status_code, 200) + + def test_still_200_ok_if_identifier_is_wrong(self): + client = Client() + client.login(username="Test", password="testpw") + + response = client.post('/submissions/prefill_using_identifier', + {'identifier': '1512.00030'}) + + self.assertEqual(response.status_code, 200) diff --git a/submissions/views.py b/submissions/views.py index 3aefb20320d5fc729d049ed99c5aa0a50b80d82c..f7a4ac054a33887fecb3f5c76662125ea437275f 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -44,26 +44,15 @@ def prefill_using_identifier(request): if request.method == "POST": identifierform = SubmissionIdentifierForm(request.POST) if identifierform.is_valid(): - # we allow 1 or 2 digits for version - identifierpattern = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$") - errormessage = '' - if not identifierpattern.match(identifierform.cleaned_data['identifier']): - errormessage = ('The identifier you entered is improperly formatted ' - '(did you forget the version number?)') - elif (Submission.objects - .filter(arxiv_identifier_w_vn_nr=identifierform.cleaned_data['identifier']) - .exists()): - errormessage = 'This preprint version has already been submitted to SciPost.' - if errormessage != '': + # Perform Arxiv query and check if results are OK for submission + metadata, errormessage = lookup_article(identifierform.cleaned_data['identifier']) + + if not metadata: form = SubmissionForm() return render(request, 'submissions/submit_manuscript.html', {'identifierform': identifierform, 'form': form, 'errormessage': errormessage}) - # Otherwise we query arXiv for the information: - identifier_without_vn_nr = identifierform.cleaned_data['identifier'].rpartition('v')[0] - arxiv_vn_nr = int(identifierform.cleaned_data['identifier'].rpartition('v')[2]) - is_resubmission = False resubmessage = '' previous_submissions = Submission.objects.filter( @@ -151,7 +140,9 @@ def prefill_using_identifier(request): 'errormessage': errormessage,} return render(request, 'submissions/submit_manuscript.html', context) else: - pass + form = SubmissionForm() + return render(request, 'submissions/submit_manuscript.html', + {'identifierform': identifierform, 'form': form}) return redirect(reverse('submissions:submit_manuscript'))