From a37e56ed5e82dc8b362044cd81ec2a4bb3a6e440 Mon Sep 17 00:00:00 2001
From: Geert Kapteijns <ghkapteijns@gmail.com>
Date: Sat, 6 May 2017 16:20:42 +0200
Subject: [PATCH] Rewrite prefill_using_DOI view

I'm not happy with this yet. The template requires all forms to be
instantiated at all times, while relying on javascript to hide them.
There should just be an if-statement checking if the form object exists.
That way, the error handling, which is now on the form level, will render
properly and everything is much shorter.
---
 commentaries/views.py    | 196 ++++++++++++++++++++++-----------------
 scipost/test_services.py |   2 +
 2 files changed, 115 insertions(+), 83 deletions(-)

diff --git a/commentaries/views.py b/commentaries/views.py
index 6a2dbb375..ccd06ba20 100644
--- a/commentaries/views.py
+++ b/commentaries/views.py
@@ -13,6 +13,7 @@ from django.template.loader import render_to_string
 from django.views.generic.edit import CreateView, FormView
 from django.views.generic.list import ListView
 from django.utils.decorators import method_decorator
+from django.http import Http404
 
 from .models import Commentary
 from .forms import RequestCommentaryForm, DOIToQueryForm, IdentifierToQueryForm
@@ -21,7 +22,7 @@ from .forms import VetCommentaryForm, CommentarySearchForm
 from comments.models import Comment
 from comments.forms import CommentForm
 from scipost.models import Contributor
-from scipost.services import ArxivCaller
+from scipost.services import ArxivCaller, DOICaller
 
 import strings
 
@@ -65,90 +66,119 @@ class RequestCommentary(LoginRequiredMixin, RequestCommentaryMixin, CreateView):
 
 @permission_required('scipost.can_request_commentary_pages', raise_exception=True)
 def prefill_using_DOI(request):
-    """ Probes CrossRef API with the DOI, to pre-fill the form. """
     if request.method == "POST":
-        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]+")
-            errormessage = ''
-            existing_commentary = None
-            if not doipattern.match(doiform.cleaned_data['doi']):
-                errormessage = 'The DOI you entered is improperly formatted.'
-            elif Commentary.objects.filter(pub_DOI=doiform.cleaned_data['doi']).exists():
-                errormessage = 'There already exists a Commentary Page on this publication, see'
-                existing_commentary = get_object_or_404(Commentary,
-                                                        pub_DOI=doiform.cleaned_data['doi'])
-            if errormessage:
-                form = RequestCommentaryForm()
-                identifierform = IdentifierToQueryForm()
-                context = {
-                    'request_commentary_form': form,
-                    'doiform': doiform,
-                    'identifierform': identifierform,
-                    'errormessage': errormessage,
-                    'existing_commentary': existing_commentary}
-                return render(request, 'commentaries/request_commentary.html', context)
-
-            # Otherwise we query Crossref for the information:
-            try:
-                queryurl = 'http://api.crossref.org/works/%s' % doiform.cleaned_data['doi']
-                doiquery = requests.get(queryurl)
-                doiqueryJSON = doiquery.json()
-                metadata = doiqueryJSON
-                pub_title = doiqueryJSON['message']['title'][0]
-                authorlist = (doiqueryJSON['message']['author'][0]['given'] + ' ' +
-                              doiqueryJSON['message']['author'][0]['family'])
-                for author in doiqueryJSON['message']['author'][1:]:
-                    authorlist += ', ' + author['given'] + ' ' + author['family']
-                journal = doiqueryJSON['message']['container-title'][0]
-
-                try:
-                    volume = doiqueryJSON['message']['volume']
-                except KeyError:
-                    volume = ''
-
-                pages = ''
-                try:
-                    pages = doiqueryJSON['message']['article-number']  # for Phys Rev
-                except KeyError:
-                    pass
-                try:
-                    pages = doiqueryJSON['message']['page']
-                except KeyError:
-                    pass
-
-                pub_date = ''
-                try:
-                    pub_date = (str(doiqueryJSON['message']['issued']['date-parts'][0][0]) + '-' +
-                                str(doiqueryJSON['message']['issued']['date-parts'][0][1]))
-                    try:
-                        pub_date += '-' + str(
-                            doiqueryJSON['message']['issued']['date-parts'][0][2])
-                    except (IndexError, KeyError):
-                        pass
-                except (IndexError, KeyError):
-                    pass
-                pub_DOI = doiform.cleaned_data['doi']
-                form = RequestCommentaryForm(
-                    initial={'type': 'published', 'metadata': metadata,
-                             'pub_title': pub_title, 'author_list': authorlist,
-                             'journal': journal, 'volume': volume,
-                             'pages': pages, 'pub_date': pub_date,
-                             'pub_DOI': pub_DOI})
-                identifierform = IdentifierToQueryForm()
-                context = {
-                    'request_commentary_form': form,
-                    'doiform': doiform,
-                    'identifierform': identifierform
-                }
-                context['title'] = pub_title
-                return render(request, 'commentaries/request_commentary.html', context)
-            except (IndexError, KeyError, ValueError):
-                pass
+        doi_form = DOIToQueryForm(request.POST)
+        identifier_form = IdentifierToQueryForm()
+        # The form checks if doi is valid and commentary doesn't already exist.
+        if doi_form.is_valid():
+            doi = doi_form.cleaned_data['doi']
+            crossref_data = DOICaller(doi).data
+            additional_form_data = {'type': 'published', 'pub_DOI': doi}
+            total_form_data = {**crossref_data, **additional_form_data}
+            commentary_form = RequestCommentaryForm(initial=total_form_data)
+            context = {
+                'request_commentary_form': commentary_form,
+                'doiform': doi_form,
+                'identifierform': identifier_form,
+            }
+            return render(request, 'commentaries/request_commentary.html', context)
         else:
-            pass
-    return redirect(reverse('commentaries:request_commentary'))
+            context = {
+                'request_commentary_form': RequestCommentaryForm(),
+                'doiform': doi_form,
+                'identifierform': identifier_form
+            }
+            return render(request, 'commentaries/request_commentary.html', context)
+    else:
+        raise Http404('Only accessible by POST-request.')
+
+
+
+# def prefill_using_DOI(request):
+#     """ Probes CrossRef API with the DOI, to pre-fill the form. """
+#     if request.method == "POST":
+#         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]+")
+#             errormessage = ''
+#             existing_commentary = None
+#             if not doipattern.match(doiform.cleaned_data['doi']):
+#                 errormessage = 'The DOI you entered is improperly formatted.'
+#             elif Commentary.objects.filter(pub_DOI=doiform.cleaned_data['doi']).exists():
+#                 errormessage = 'There already exists a Commentary Page on this publication, see'
+#                 existing_commentary = get_object_or_404(Commentary,
+#                                                         pub_DOI=doiform.cleaned_data['doi'])
+#             if errormessage:
+#                 form = RequestCommentaryForm()
+#                 identifierform = IdentifierToQueryForm()
+#                 context = {
+#                     'request_commentary_form': form,
+#                     'doiform': doiform,
+#                     'identifierform': identifierform,
+#                     'errormessage': errormessage,
+#                     'existing_commentary': existing_commentary}
+#                 return render(request, 'commentaries/request_commentary.html', context)
+#
+#             # Otherwise we query Crossref for the information:
+#             try:
+#                 queryurl = 'http://api.crossref.org/works/%s' % doiform.cleaned_data['doi']
+#                 doiquery = requests.get(queryurl)
+#                 doiqueryJSON = doiquery.json()
+#                 metadata = doiqueryJSON
+#                 pub_title = doiqueryJSON['message']['title'][0]
+#                 authorlist = (doiqueryJSON['message']['author'][0]['given'] + ' ' +
+#                               doiqueryJSON['message']['author'][0]['family'])
+#                 for author in doiqueryJSON['message']['author'][1:]:
+#                     authorlist += ', ' + author['given'] + ' ' + author['family']
+#                 journal = doiqueryJSON['message']['container-title'][0]
+#
+#                 try:
+#                     volume = doiqueryJSON['message']['volume']
+#                 except KeyError:
+#                     volume = ''
+#
+#                 pages = ''
+#                 try:
+#                     pages = doiqueryJSON['message']['article-number']  # for Phys Rev
+#                 except KeyError:
+#                     pass
+#                 try:
+#                     pages = doiqueryJSON['message']['page']
+#                 except KeyError:
+#                     pass
+#
+#                 pub_date = ''
+#                 try:
+#                     pub_date = (str(doiqueryJSON['message']['issued']['date-parts'][0][0]) + '-' +
+#                                 str(doiqueryJSON['message']['issued']['date-parts'][0][1]))
+#                     try:
+#                         pub_date += '-' + str(
+#                             doiqueryJSON['message']['issued']['date-parts'][0][2])
+#                     except (IndexError, KeyError):
+#                         pass
+#                 except (IndexError, KeyError):
+#                     pass
+#                 pub_DOI = doiform.cleaned_data['doi']
+#                 form = RequestCommentaryForm(
+#                     initial={'type': 'published', 'metadata': metadata,
+#                              'pub_title': pub_title, 'author_list': authorlist,
+#                              'journal': journal, 'volume': volume,
+#                              'pages': pages, 'pub_date': pub_date,
+#                              'pub_DOI': pub_DOI})
+#                 identifierform = IdentifierToQueryForm()
+#                 context = {
+#                     'request_commentary_form': form,
+#                     'doiform': doiform,
+#                     'identifierform': identifierform
+#                 }
+#                 context['title'] = pub_title
+#                 return render(request, 'commentaries/request_commentary.html', context)
+#             except (IndexError, KeyError, ValueError):
+#                 pass
+#         else:
+#             pass
+#     return redirect(reverse('commentaries:request_commentary'))
 
 
 @method_decorator(permission_required(
diff --git a/scipost/test_services.py b/scipost/test_services.py
index ca8de44fb..120a160da 100644
--- a/scipost/test_services.py
+++ b/scipost/test_services.py
@@ -65,6 +65,8 @@ class DOICallerTest(TestCase):
         correct_data = {
             'pub_date': '2017-04-04',
             'journal': 'SciPost Physics',
+            # Inexplicably, an extra space is added between 'inpenetrable' and 'bosons', but this is a
+            # Crossref error.
             'pub_title': 'One-particle density matrix of trapped one-dimensional impenetrable  bosons from conformal invariance',
             'pages': '',
             'volume': '2',
-- 
GitLab