Source code for commentaries.views

import datetime
import feedparser
import re
import requests

from django.db.models import Q
from django.utils import timezone
from django.shortcuts import get_object_or_404, render
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.models import User
from django.core.mail import EmailMessage
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_protect
from django.db.models import Avg

from .models import Commentary
from .forms import RequestCommentaryForm, DOIToQueryForm, IdentifierToQueryForm
from .forms import VetCommentaryForm, CommentarySearchForm, commentary_refusal_dict

from comments.models import Comment
from comments.forms import CommentForm
from scipost.models import Contributor
from scipost.models import title_dict
from scipost.forms import AuthenticationForm


################
# Commentaries
################


@login_required
@permission_required('scipost.can_request_commentary_pages', raise_exception=True)
def request_commentary(request):
    if request.method == 'POST':
        form = RequestCommentaryForm(request.POST)
        if form.is_valid():
#            if form.cleaned_data['arxiv_identifier'] is None and form.cleaned_data['pub_DOI'] is None:
            errormessage = ''
            existing_commentary = None
            if form.cleaned_data['arxiv_identifier'] =='' and form.cleaned_data['pub_DOI'] == '':
                errormessage = ('You must provide either a DOI (for a published paper) '
                                'or an arXiv identifier (for a preprint).')
            elif (form.cleaned_data['arxiv_identifier'] !='' and
                  (Commentary.objects
                   .filter(arxiv_identifier=form.cleaned_data['arxiv_identifier']).exists())):
                errormessage = 'There already exists a Commentary Page on this preprint, see'
                existing_commentary = get_object_or_404(
                    Commentary,
                    arxiv_identifier=form.cleaned_data['arxiv_identifier'])
            elif (form.cleaned_data['pub_DOI'] !='' and
                  Commentary.objects.filter(pub_DOI=form.cleaned_data['pub_DOI']).exists()):
                errormessage = 'There already exists a Commentary Page on this publication, see'
                existing_commentary = get_object_or_404(Commentary, pub_DOI=form.cleaned_data['pub_DOI'])
            if errormessage != '':
                doiform = DOIToQueryForm()
                identifierform = IdentifierToQueryForm()
                context = {'form': form, 'doiform': doiform, 'identifierform': identifierform,
                           'errormessage': errormessage,
                           'existing_commentary': existing_commentary}
                return render(request, 'commentaries/request_commentary.html', context)
            # otherwise we can create the Commentary
            contributor = Contributor.objects.get(user=request.user)
            commentary = Commentary (
                requested_by = contributor,
                type = form.cleaned_data['type'],
                discipline = form.cleaned_data['discipline'],
                domain = form.cleaned_data['domain'],
#                specialization = form.cleaned_data['specialization'],
                subject_area = form.cleaned_data['subject_area'],
                pub_title = form.cleaned_data['pub_title'],
                arxiv_identifier = form.cleaned_data['arxiv_identifier'],
                pub_DOI = form.cleaned_data['pub_DOI'],
                metadata = form.cleaned_data['metadata'],
                author_list = form.cleaned_data['author_list'],
                journal = form.cleaned_data['journal'],
                volume = form.cleaned_data['volume'],
                pages = form.cleaned_data['pages'],
                pub_date = form.cleaned_data['pub_date'],
                pub_abstract = form.cleaned_data['pub_abstract'],
                latest_activity = timezone.now(),
                )
            commentary.parse_links_into_urls()
            commentary.save()
#            return HttpResponseRedirect('request_commentary_ack')
            context = {'ack_header': 'Thank you for your request for a Commentary Page',
                       'ack_message': 'Your request will soon be handled by an Editor. ',
                       'followup_message': 'Return to your ',
                       'followup_link': reverse('scipost:personal_page'),
                       'followup_link_label': 'personal page'}
            return render(request, 'scipost/acknowledgement.html', context)
    else:
        form = RequestCommentaryForm()
    doiform = DOIToQueryForm()
    identifierform = IdentifierToQueryForm()
    context = {'form': form, 'doiform': doiform, 'identifierform': identifierform}
    return render(request, 'commentaries/request_commentary.html', context)

@permission_required('scipost.can_request_commentary_pages', raise_exception=True)
[docs]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 = {'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: volume = '' pages = '' try: pages = doiqueryJSON['message']['article-number'] # for Phys Rev except: pass try: pages = doiqueryJSON['message']['page'] except: 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: pass except: 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 = {'form': form, 'doiform': doiform, 'identifierform': identifierform,} context['title'] = pub_title return render(request, 'commentaries/request_commentary.html', context) except: pass else: pass return redirect(reverse('commentaries:request_commentary'))
@permission_required('scipost.can_request_commentary_pages', raise_exception=True)
[docs]def prefill_using_identifier(request): """ Probes arXiv with the identifier, to pre-fill the form. """ if request.method == "POST": identifierform = IdentifierToQueryForm(request.POST) if identifierform.is_valid(): # Check if given identifier is of expected form: # we allow 1 or 2 digits for version identifierpattern_new = re.compile("^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$") 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 identifierpattern_old.match(identifierform.cleaned_data['identifier'])): errormessage = ('The identifier you entered is improperly formatted ' '(did you forget the version number?).') elif (Commentary.objects .filter(arxiv_identifier=identifierform.cleaned_data['identifier']).exists()): errormessage = 'There already exists a Commentary Page on this preprint, see' existing_commentary = get_object_or_404( Commentary, arxiv_identifier=identifierform.cleaned_data['identifier']) if errormessage != '': form = RequestCommentaryForm() doiform = DOIToQueryForm() context = {'form': form, 'doiform': doiform, 'identifierform': identifierform, 'errormessage': errormessage, 'existing_commentary': existing_commentary} return render(request, 'commentaries/request_commentary.html', context) # 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 + '. Please comment on the published version.') except: pass try: arxiv_doi = arxivquery['entries'][0]['arxiv_doi'] errormessage = ('This paper has been published under DOI ' + arxiv_DOI + '. Please comment on the published version.') except: pass if errormessage != '': form = RequestCommentaryForm() doiform = DOIToQueryForm() context = {'form': form, 'doiform': doiform, 'identifierform': identifierform, 'errormessage': errormessage, 'existing_commentary': existing_commentary} return render(request, 'commentaries/request_commentary.html', context) # otherwise prefill the form: metadata = arxivquery pub_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 = RequestCommentaryForm( initial={'type': 'preprint', 'metadata': metadata, 'pub_title': pub_title, 'author_list': authorlist, 'arxiv_identifier': identifierform.cleaned_data['identifier'], 'arxiv_link': arxiv_link, 'pub_abstract': abstract}) doiform = DOIToQueryForm() context = {'form': form, 'doiform': doiform, 'identifierform': identifierform} context['title'] = pub_title return render(request, 'commentaries/request_commentary.html', context) except: # something went wrong with processing the arXiv data errormessage = 'An error occurred while processing the arXiv data. Are you sure this identifier exists?' form = RequestCommentaryForm() doiform = DOIToQueryForm() context = {'form': form, 'doiform': doiform, 'identifierform': identifierform, 'errormessage': errormessage, 'existing_commentary': existing_commentary} return render(request, 'commentaries/request_commentary.html', context) # pass else: pass return redirect(reverse('commentaries:request_commentary'))
@permission_required('scipost.can_vet_commentary_requests', raise_exception=True) def vet_commentary_requests(request): contributor = Contributor.objects.get(user=request.user) commentary_to_vet = Commentary.objects.filter(vetted=False).first() # only handle one at a time form = VetCommentaryForm() context = {'contributor': contributor, 'commentary_to_vet': commentary_to_vet, 'form': form } return render(request, 'commentaries/vet_commentary_requests.html', context) @permission_required('scipost.can_vet_commentary_requests', raise_exception=True) def vet_commentary_request_ack(request, commentary_id): if request.method == 'POST': form = VetCommentaryForm(request.POST) commentary = Commentary.objects.get(pk=commentary_id) if form.is_valid(): if form.cleaned_data['action_option'] == '1': # accept the commentary as is commentary.vetted = True commentary.vetted_by = Contributor.objects.get(user=request.user) commentary.latest_activity = timezone.now() commentary.save() email_text = ('Dear ' + title_dict[commentary.requested_by.title] + ' ' + commentary.requested_by.user.last_name + ', \n\nThe Commentary Page you have requested, ' 'concerning publication with title ' + commentary.pub_title + ' by ' + commentary.author_list + ', has been activated at https://scipost.org/commentary/' + str(commentary.arxiv_or_DOI_string) + '. You are now welcome to submit your comments.' '\n\nThank you for your contribution, \nThe SciPost Team.') emailmessage = EmailMessage('SciPost Commentary Page activated', email_text, 'SciPost commentaries <commentaries@scipost.org>', [commentary.requested_by.user.email], ['commentaries@scipost.org'], reply_to=['commentaries@scipost.org']) emailmessage.send(fail_silently=False) elif form.cleaned_data['action_option'] == '0': # re-edit the form starting from the data provided form2 = RequestCommentaryForm(initial={'pub_title': commentary.pub_title, 'arxiv_link': commentary.arxiv_link, 'pub_DOI_link': commentary.pub_DOI_link, 'author_list': commentary.author_list, 'pub_date': commentary.pub_date, 'pub_abstract': commentary.pub_abstract}) commentary.delete() email_text = ('Dear ' + title_dict[commentary.requested_by.title] + ' ' + commentary.requested_by.user.last_name + ', \n\nThe Commentary Page you have requested, ' 'concerning publication with title ' + commentary.pub_title + ' by ' + commentary.author_list + ', has been activated (with slight modifications to your submitted details).' ' You are now welcome to submit your comments.' '\n\nThank you for your contribution, \nThe SciPost Team.') emailmessage = EmailMessage('SciPost Commentary Page activated', email_text, 'SciPost commentaries <commentaries@scipost.org>', [commentary.requested_by.user.email], ['commentaries@scipost.org'], reply_to=['commentaries@scipost.org']) emailmessage.send(fail_silently=False) context = {'form': form2 } return render(request, 'commentaries/request_commentary.html', context) elif form.cleaned_data['action_option'] == '2': # the commentary request is simply rejected email_text = ('Dear ' + title_dict[commentary.requested_by.title] + ' ' + commentary.requested_by.user.last_name + ', \n\nThe Commentary Page you have requested, ' 'concerning publication with title ' + commentary.pub_title + ' by ' + commentary.author_list + ', has not been activated for the following reason: ' + commentary_refusal_dict[int(form.cleaned_data['refusal_reason'])] + '.\n\nThank you for your interest, \nThe SciPost Team.') if form.cleaned_data['email_response_field']: email_text += '\n\nFurther explanations: ' + form.cleaned_data['email_response_field'] emailmessage = EmailMessage('SciPost Commentary Page activated', email_text, 'SciPost commentaries <commentaries@scipost.org>', [commentary.requested_by.user.email], ['commentaries@scipost.org'], reply_to=['comentaries@scipost.org']) emailmessage.send(fail_silently=False) commentary.delete() #context = {'commentary_id': commentary_id } #return render(request, 'commentaries/vet_commentary_request_ack.html', context) context = {'ack_header': 'SciPost Commentary request vetted.', 'followup_message': 'Return to the ', 'followup_link': reverse('commentaries:vet_commentary_requests'), 'followup_link_label': 'Commentary requests page'} return render(request, 'scipost/acknowledgement.html', context) def commentaries(request): if request.method == 'POST': form = CommentarySearchForm(request.POST) if form.is_valid() and form.has_changed(): commentary_search_list = Commentary.objects.filter( pub_title__icontains=form.cleaned_data['pub_title_keyword'], author_list__icontains=form.cleaned_data['pub_author'], pub_abstract__icontains=form.cleaned_data['pub_abstract_keyword'], vetted=True, ) commentary_search_list.order_by('-pub_date') else: commentary_search_list = [] else: form = CommentarySearchForm() commentary_search_list = [] comment_recent_list = (Comment.objects.filter(status='1') .order_by('-date_submitted')[:10]) commentary_recent_list = (Commentary.objects.filter(vetted=True) .order_by('-latest_activity')[:10]) context = {'form': form, 'commentary_search_list': commentary_search_list, 'comment_recent_list': comment_recent_list, 'commentary_recent_list': commentary_recent_list } return render(request, 'commentaries/commentaries.html', context) def browse(request, discipline, nrweeksback): if request.method == 'POST': form = CommentarySearchForm(request.POST) if form.is_valid() and form.has_changed(): commentary_search_list = Commentary.objects.filter( pub_title__icontains=form.cleaned_data['pub_title_keyword'], author_list__icontains=form.cleaned_data['pub_author'], pub_abstract__icontains=form.cleaned_data['pub_abstract_keyword'], vetted=True, ) commentary_search_list.order_by('-pub_date') else: commentary_search_list = [] context = {'form': form, 'commentary_search_list': commentary_search_list } return HttpResponseRedirect(request, 'commentaries/commentaries.html', context) else: form = CommentarySearchForm() commentary_browse_list = Commentary.objects.filter( vetted=True, discipline=discipline, latest_activity__gte=timezone.now() + datetime.timedelta(weeks=-int(nrweeksback)) ) context = {'form': form, 'discipline': discipline, 'nrweeksback': nrweeksback, 'commentary_browse_list': commentary_browse_list } return render(request, 'commentaries/commentaries.html', context) def commentary_detail(request, arxiv_or_DOI_string): commentary = get_object_or_404(Commentary, arxiv_or_DOI_string=arxiv_or_DOI_string) # other_versions = Commentary.objects.filter( # arxiv_identifier_wo_vn_nr=submission.arxiv_identifier_wo_vn_nr # ).exclude(pk=submission.id) comments = commentary.comment_set.all() if request.method == 'POST': form = CommentForm(request.POST) if form.is_valid(): author = Contributor.objects.get(user=request.user) newcomment = Comment ( commentary = commentary, author = author, is_rem = form.cleaned_data['is_rem'], is_que = form.cleaned_data['is_que'], is_ans = form.cleaned_data['is_ans'], is_obj = form.cleaned_data['is_obj'], is_rep = form.cleaned_data['is_rep'], is_val = form.cleaned_data['is_val'], is_lit = form.cleaned_data['is_lit'], is_sug = form.cleaned_data['is_sug'], comment_text = form.cleaned_data['comment_text'], remarks_for_editors = form.cleaned_data['remarks_for_editors'], date_submitted = timezone.now(), ) newcomment.save() author.nr_comments = Comment.objects.filter(author=author).count() author.save() #request.session['commentary_id'] = commentary.id #return HttpResponseRedirect(reverse('comments:comment_submission_ack')) context = {'ack_header': 'Thank you for contributing a Comment.', 'ack_message': 'It will soon be vetted by an Editor.', 'followup_message': 'Back to the ', 'followup_link': reverse( 'commentaries:commentary', kwargs={'arxiv_or_DOI_string': newcomment.commentary.arxiv_or_DOI_string} ), 'followup_link_label': ' Commentary page you came from' } return render(request, 'scipost/acknowledgement.html', context) else: form = CommentForm() try: author_replies = Comment.objects.filter(commentary=commentary, is_author_reply=True, status__gte=1) except Comment.DoesNotExist: author_replies = () context = {'commentary': commentary, 'comments': comments.filter(status__gte=1).order_by('-date_submitted'), 'author_replies': author_replies, 'form': form} return render(request, 'commentaries/commentary_detail.html', context)