diff --git a/scipost/services.py b/scipost/services.py index 31760507cb1dfd82701a54de85b1b8f46e682c82..d9a03b5295223b71908cc8d7e97d0753f89ddc1a 100644 --- a/scipost/services.py +++ b/scipost/services.py @@ -101,9 +101,11 @@ class ArxivCaller: self.data = { 'pub_title': pub_title, + 'title': pub_title, # Duplicate for Commentary/Submission cross-compatibility 'author_list': author_list, 'arxiv_link': arxiv_link, 'pub_abstract': abstract, + 'abstract': abstract, # Duplicate for Commentary/Submission cross-compatibility 'pub_date': pub_date, } diff --git a/strings/__init__.py b/strings/__init__.py index 51115395b4c01978c62b95c036d3f9a5e7445cfc..614455a3452553b019e2f375efa0ad241bd8f690 100644 --- a/strings/__init__.py +++ b/strings/__init__.py @@ -43,11 +43,11 @@ arxiv_caller_errormessages = { 'paper_published_doi': ('This paper has been published under DOI {{ arxiv_doi }}' '. Please comment on the published version.'), - 'arxiv_timeout': 'Arxiv did not respond in time. Please try again later', - 'arxiv_bad_request': - ('There was an error with requesting identifier ' + - '{{ identifier_with_vn_nr }}' - ' from Arxiv. Please check the identifier and try again.'), + # 'arxiv_timeout': 'Arxiv did not respond in time. Please try again later', + # 'arxiv_bad_request': + # ('There was an error with requesting identifier ' + + # '{{ identifier_with_vn_nr }}' + # ' from Arxiv. Please check the identifier and try again.'), 'previous_submission_undergoing_refereeing': ('There exists a preprint with this arXiv identifier ' 'but an earlier version number, which is still undergoing ' diff --git a/submissions/constants.py b/submissions/constants.py index ffb506708de9a0fddee0c601d6e2ca7f97007cf4..845ecbb2ebd49f4117139978bbc36cd0d1b2fc86 100644 --- a/submissions/constants.py +++ b/submissions/constants.py @@ -6,6 +6,8 @@ STATUS_AWAITING_ED_REC = 'awaiting_ed_rec' STATUS_REVIEW_CLOSED = 'review_closed' STATUS_ACCEPTED = 'accepted' STATUS_PUBLISHED = 'published' +STATUS_REJECTED = 'rejected' +STATUS_REJECTED_VISIBLE = 'rejected_visible' STATUS_RESUBMITTED = 'resubmitted' STATUS_RESUBMITTED_REJECTED = 'resubmitted_and_rejected' STATUS_RESUBMITTED_REJECTED_VISIBLE = 'resubmitted_and_rejected_visible' @@ -27,8 +29,8 @@ SUBMISSION_STATUS = ( (STATUS_AWAITING_ED_REC, 'Awaiting Editorial Recommendation'), ('EC_vote_completed', 'Editorial College voting rounded up'), (STATUS_ACCEPTED, 'Publication decision taken: accept'), - ('rejected', 'Publication decision taken: reject'), - ('rejected_visible', 'Publication decision taken: reject (still publicly visible)'), + (STATUS_REJECTED, 'Publication decision taken: reject'), + (STATUS_REJECTED_VISIBLE, 'Publication decision taken: reject (still publicly visible)'), (STATUS_PUBLISHED, 'Published'), # If withdrawn: ('withdrawn', 'Withdrawn by the Authors'), diff --git a/submissions/forms.py b/submissions/forms.py index 70b2b792e8f3465889566fbb4e4ac600b6b59254..b0ccceb4ac825f5b9039cca8d7febeda9546f350 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -1,16 +1,21 @@ from django import forms from django.core.validators import RegexValidator +from django.db import models, transaction -from .constants import ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS,\ - REPORT_ACTION_CHOICES, REPORT_REFUSAL_CHOICES +from .constants import ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS, STATUS_RESUBMITTED,\ + REPORT_ACTION_CHOICES, REPORT_REFUSAL_CHOICES, STATUS_REVISION_REQUESTED,\ + STATUS_REJECTED, STATUS_REJECTED_VISIBLE, STATUS_RESUBMISSION_INCOMING from .models import Submission, RefereeInvitation, Report, EICRecommendation from scipost.constants import SCIPOST_SUBJECT_AREAS +from scipost.services import ArxivCaller from scipost.models import Contributor from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Div, Field, HTML, Submit +import strings + class SubmissionSearchForm(forms.Form): author = forms.CharField(max_length=100, required=False, label="Author(s)") @@ -33,46 +38,160 @@ class SubmissionSearchForm(forms.Form): # Submission and resubmission # ############################### -class SubmissionIdentifierForm(forms.Form): - 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 SubmissionChecks: + """ + Use this class as a blueprint containing checks which should be run + in multiple forms. + """ + is_resubmission = False + last_submission = None + + def _submission_already_exists(self, identifier): + if Submission.objects.filter(arxiv_identifier_w_vn_nr=identifier).exists(): + error_message = 'This preprint version has already been submitted to SciPost.' + raise forms.ValidationError(error_message, code='duplicate') + + def _call_arxiv(self, identifier): + caller = ArxivCaller(identifier) + if caller.is_valid: + self.arxiv_data = ArxivCaller(identifier).data + self.metadata = ArxivCaller(identifier).metadata + else: + error_message = 'A preprint associated to this identifier does not exist.' + raise forms.ValidationError(error_message) + + def _submission_is_already_published(self, identifier): + published_id = None + if 'arxiv_doi' in self.arxiv_data: + published_id = self.arxiv_data['arxiv_doi'] + elif 'arxiv_journal_ref' in self.arxiv_data: + published_id = self.arxiv_data['arxiv_journal_ref'] + + if published_id: + error_message = ('This paper has been published under DOI %(published_id)s' + '. Please comment on the published version.'), + raise forms.ValidationError(error_message, code='published', + params={'published_id': published_id}) + + def _submission_previous_version_is_valid_for_submission(self, identifier): + '''Check if previous submitted versions have the appropriate status.''' + identifiers = self.identifier_into_parts(identifier) + submission = (Submission.objects + .filter(arxiv_identifier_wo_vn_nr=identifiers['arxiv_identifier_wo_vn_nr']) + .order_by('-arxiv_vn_nr').last()) + + # If submissions are found; check their statuses + if submission: + self.last_submission = submission + if submission.status == STATUS_REVISION_REQUESTED: + self.is_resubmission = True + # resubmessage = ('There already exists a preprint with this arXiv identifier ' + # 'but a different version number. \nYour Submission will be ' + # 'handled as a resubmission.') + elif submission.status in [STATUS_REJECTED, STATUS_REJECTED_VISIBLE]: + error_message = ('This arXiv preprint has previously undergone refereeing ' + 'and has been rejected. Resubmission is only possible ' + 'if the manuscript has been substantially reworked into ' + 'a new arXiv submission with distinct identifier.') + raise forms.ValidationError(error_message) + else: + error_message = ('There exists a preprint with this arXiv identifier ' + 'but an earlier version number, which is still undergoing ' + 'peer refereeing.' + '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.') + raise forms.ValidationError(error_message) + + def submission_is_resubmission(self): + return self.is_resubmission + + def identifier_into_parts(self, identifier): + data = { + 'arxiv_identifier_w_vn_nr': identifier, + 'arxiv_identifier_wo_vn_nr': identifier.rpartition('v')[0], + 'arxiv_vn_nr': int(identifier.rpartition('v')[2]) + } + return data + + def do_pre_checks(self, identifier): + self._submission_already_exists(identifier) + self._call_arxiv(identifier) + self._submission_is_already_published(identifier) + self._submission_previous_version_is_valid_for_submission(identifier) + + +class SubmissionIdentifierForm(SubmissionChecks, forms.Form): + IDENTIFIER_PATTERN_NEW = r'^[0-9]{4,}.[0-9]{4,5}v[0-9]{1,2}$' + IDENTIFIER_PLACEHOLDER = 'new style (with version nr) ####.####(#)v#(#)' + + identifier = forms.RegexField(regex=IDENTIFIER_PATTERN_NEW, strip=True, + # help_text=strings.arxiv_query_help_text, + error_messages={'invalid': strings.arxiv_query_invalid}, + widget=forms.TextInput({'placeholder': IDENTIFIER_PLACEHOLDER})) + + def clean_identifier(self): + identifier = self.cleaned_data['identifier'] + self.do_pre_checks(identifier) + return identifier + + def _gather_data_from_last_submission(self): + '''Return dictionary with data coming from previous submission version.''' + if self.submission_is_resubmission(): + data = { + 'is_resubmission': True, + 'discipline': self.last_submission.discipline, + 'domain': self.last_submission.domain, + 'referees_flagged': self.last_submission.referees_flagged, + 'referees_suggested': self.last_submission.referees_suggested, + 'secondary_areas': self.last_submission.secondary_areas, + 'subject_area': self.last_submission.subject_area, + 'submitted_to_journal': self.last_submission.submitted_to_journal, + 'submission_type': self.last_submission.submission_type, + } + return data or {} + + def request_arxiv_preprint_form_prefill_data(self): + '''Return dictionary to prefill `RequestSubmissionForm`.''' + form_data = self.arxiv_data + form_data.update(self.identifier_into_parts(self.cleaned_data['identifier'])) + if self.submission_is_resubmission(): + form_data.update(self._gather_data_from_last_submission()) + return form_data + + +class RequestSubmissionForm(SubmissionChecks, forms.ModelForm): class Meta: model = Submission - fields = ['is_resubmission', - 'discipline', 'submitted_to_journal', 'submission_type', - 'domain', 'subject_area', - 'secondary_areas', - 'title', 'author_list', 'abstract', - 'arxiv_identifier_w_vn_nr', 'arxiv_identifier_wo_vn_nr', - 'arxiv_vn_nr', 'arxiv_link', 'metadata', - 'author_comments', 'list_of_changes', - 'remarks_for_editors', - 'referees_suggested', 'referees_flagged'] + fields = [ + 'is_resubmission', + 'discipline', + 'submitted_to_journal', + 'submission_type', + 'domain', + 'subject_area', + 'secondary_areas', + 'title', + 'author_list', + 'abstract', + 'arxiv_identifier_w_vn_nr', + 'arxiv_link', + 'author_comments', + 'list_of_changes', + 'remarks_for_editors', + 'referees_suggested', + 'referees_flagged' + ] def __init__(self, *args, **kwargs): - super(SubmissionForm, self).__init__(*args, **kwargs) + self.requested_by = kwargs.pop('requested_by', None) + super().__init__(*args, **kwargs) self.fields['is_resubmission'].widget = forms.HiddenInput() self.fields['arxiv_identifier_w_vn_nr'].widget = forms.HiddenInput() - self.fields['arxiv_identifier_wo_vn_nr'].widget = forms.HiddenInput() - self.fields['arxiv_vn_nr'].widget = forms.HiddenInput() self.fields['arxiv_link'].widget.attrs.update( {'placeholder': 'ex.: arxiv.org/abs/1234.56789v1'}) - self.fields['metadata'].widget = forms.HiddenInput() self.fields['secondary_areas'].widget = forms.SelectMultiple(choices=SCIPOST_SUBJECT_AREAS) self.fields['abstract'].widget.attrs.update({'cols': 100}) self.fields['author_comments'].widget.attrs.update({ @@ -88,7 +207,15 @@ class SubmissionForm(forms.ModelForm): 'placeholder': 'Optional: names of referees whose reports should be treated with caution (+ short reason)', 'rows': 3}) - def check_user_may_submit(self, current_user): + def clean(self, *args, **kwargs): + """ + Do all prechecks which are also done in the prefiller. + """ + cleaned_data = super().clean(*args, **kwargs) + self.do_pre_checks(cleaned_data['arxiv_identifier_w_vn_nr']) + return cleaned_data + + def clean_author_list(self): """ Important check! @@ -96,21 +223,69 @@ class SubmissionForm(forms.ModelForm): Also possibly may be extended to check permissions and give ultimate submission power to certain user groups. """ - return current_user.last_name.lower() in self.cleaned_data['author_list'].lower() - - def update_submission_data(self): + author_list = self.cleaned_data['author_list'] + if not self.requested_by.last_name.lower() in author_list.lower(): + error_message = ('Your name does not match that of any of the authors. ' + 'You are not authorized to submit this preprint.') + raise forms.ValidationError(error_message, code='not_an_author') + return author_list + + @transaction.atomic + def copy_and_save_data_from_resubmission(self, submission): + """ + Fill given Submission with data coming from last_submission in the SubmissionChecks + blueprint. """ - Some fields should not be accessible in the HTML form by the user and should be - inserted by for example an extra call to Arxiv into the Submission instance, right - *after* the form is submitted. - - Example fields: - - is_resubmission - - arxiv_link - - arxiv_identifier_w_vn_nr - - metadata (!) + if not self.last_submission: + raise Submission.DoesNotExist + + # Open for comment and reporting + submission.open_for_reporting = True + submission.open_for_commenting = True + + # Close last submission + self.last_submission.is_current = False + self.last_submission.open_for_reporting = False + self.last_submission.status = STATUS_RESUBMITTED + self.last_submission.save() + + # Editor-in-charge + submission.editor_in_charge = self.last_submission.editor_in_charge + submission.status = STATUS_RESUBMISSION_INCOMING + + # Author claim fields + submission.authors.add(*self.last_submission.authors.all()) + submission.authors_claims.add(*self.last_submission.authors_claims.all()) + submission.authors_false_claims.add(*self.last_submission.authors_false_claims.all()) + submission.save() + return submission + + @transaction.atomic + def save(self): + """ + Prefill instance before save. + + Because of the ManyToManyField on `authors`, commit=False for this form + is disabled. Saving the form without the database call may loose `authors` + data without notice. """ - raise NotImplementedError + submission = super().save(commit=False) + submission.submitted_by = self.requested_by.contributor + + # Save metadata directly from ArXiv call without possible user interception + submission.metadata = self.metadata + + # Update identifiers + identifiers = self.identifier_into_parts(submission.arxiv_identifier_w_vn_nr) + submission.arxiv_identifier_wo_vn_nr = identifiers['arxiv_identifier_wo_vn_nr'] + submission.arxiv_vn_nr = identifiers['arxiv_vn_nr'] + + # Save + submission.save() + if self.submission_is_resubmission(): + submission = self.copy_and_save_data_from_resubmission(submission) + submission.authors.add(self.requested_by.contributor) + return submission ###################### diff --git a/submissions/models.py b/submissions/models.py index c2364962e70eeff53d55c6d22691d6e965131bb1..9e697af3908fdf117f182ae6a0f26c337a9c900b 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -132,69 +132,6 @@ class Submission(ArxivCallable, models.Model): def reporting_deadline_has_passed(self): return timezone.now() > self.reporting_deadline - @transaction.atomic - def finish_submission(self): - if self.is_resubmission: - # If submissions is a resubmission, the submission needs to be prescreened - # by the EIC to choose which of the available submission cycle to assign - self.mark_other_versions_as_deprecated() - self.copy_authors_from_previous_version() - self.copy_EIC_from_previous_version() - self.set_resubmission_defaults() - self.status = STATUS_RESUBMISSION_INCOMING - else: - self.authors.add(self.submitted_by) - - self.save() - - @classmethod - def same_version_exists(self, identifier): - return self.objects.filter(arxiv_identifier_w_vn_nr=identifier).exists() - - @classmethod - def different_versions(self, identifier): - return self.objects.filter(arxiv_identifier_wo_vn_nr=identifier).order_by('-arxiv_vn_nr') - - def make_assignment(self): - assignment = EditorialAssignment( - submission=self, - to=self.editor_in_charge, - accepted=True, - date_created=timezone.now(), - date_answered=timezone.now(), - ) - assignment.save() - - def set_resubmission_defaults(self): - self.open_for_reporting = True - self.open_for_commenting = True - if self.other_versions()[0].submitted_to_journal == 'SciPost Physics Lecture Notes': - self.reporting_deadline = timezone.now() + datetime.timedelta(days=56) - else: - self.reporting_deadline = timezone.now() + datetime.timedelta(days=28) - - def copy_EIC_from_previous_version(self): - last_version = self.other_versions()[0] - self.editor_in_charge = last_version.editor_in_charge - self.status = 'EICassigned' - - def copy_authors_from_previous_version(self): - last_version = self.other_versions()[0] - - for author in last_version.authors.all(): - self.authors.add(author) - for author in last_version.authors_claims.all(): - self.authors_claims.add(author) - for author in last_version.authors_false_claims.all(): - self.authors_false_claims.add(author) - - def mark_other_versions_as_deprecated(self): - for sub in self.other_versions(): - sub.is_current = False - sub.open_for_reporting = False - sub.status = 'resubmitted' - sub.save() - def other_versions(self): return Submission.objects.filter( arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr diff --git a/submissions/urls.py b/submissions/urls.py index 8465d4f9c7b572bed6e6e1437a7f904c1d377132..bdd6d86f6cc0619472dad96b3bd14996cf081713 100644 --- a/submissions/urls.py +++ b/submissions/urls.py @@ -17,12 +17,9 @@ urlpatterns = [ name='submission_wo_vn_nr'), url(r'^(?P<arxiv_identifier_w_vn_nr>[0-9]{4,}.[0-9]{5,}v[0-9]{1,2})/$', views.submission_detail, name='submission'), - # url(r'^prefill_using_identifier$', - # views.prefill_using_identifier, name='prefill_using_identifier'), - url(r'^prefill_using_identifier$', - views.PrefillUsingIdentifierView.as_view(), name='prefill_using_identifier'), - # url(r'^submit_manuscript$', views.submit_manuscript, name='submit_manuscript'), - url(r'^submit_manuscript$', views.SubmissionCreateView.as_view(), name='submit_manuscript'), + url(r'^submit_manuscript$', views.RequestSubmission.as_view(), name='submit_manuscript'), + url(r'^submit_manuscript/prefill$', views.prefill_using_arxiv_identifier, + name='prefill_using_identifier'), url(r'^pool$', views.pool, name='pool'), url(r'^submissions_by_status/(?P<status>[a-zA-Z_]+)$', views.submissions_by_status, name='submissions_by_status'), diff --git a/submissions/views.py b/submissions/views.py index d6258e00d531b063229a3dc319998c3804703db6..15451982bf45bd2ff94e0653716a44c96152a7ba 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -4,22 +4,22 @@ import feedparser from django.contrib import messages from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.models import Group -from django.core.urlresolvers import reverse +from django.core.urlresolvers import reverse, reverse_lazy from django.db import transaction from django.http import Http404 from django.shortcuts import get_object_or_404, render, redirect from django.template import Template, Context from django.utils import timezone +from django.utils.decorators import method_decorator from guardian.decorators import permission_required_or_403 -from guardian.mixins import PermissionRequiredMixin from guardian.shortcuts import assign_perm from .constants import SUBMISSION_STATUS_VOTING_DEPRECATED,\ SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS, ED_COMM_CHOICES from .models import Submission, EICRecommendation, EditorialAssignment,\ RefereeInvitation, Report, EditorialCommunication -from .forms import SubmissionIdentifierForm, SubmissionForm, SubmissionSearchForm,\ +from .forms import SubmissionIdentifierForm, RequestSubmissionForm, SubmissionSearchForm,\ RecommendationVoteForm, ConsiderAssignmentForm, AssignSubmissionForm,\ SetRefereeingDeadlineForm, RefereeSelectForm, RefereeRecruitmentForm,\ ConsiderRefereeInvitationForm, EditorialCommunicationForm,\ @@ -29,206 +29,59 @@ from .utils import SubmissionUtils from scipost.forms import ModifyPersonalMessageForm, RemarkForm from scipost.models import Contributor, Remark, RegistrationInvitation -from scipost.services import ArxivCaller from scipost.utils import Utils -from strings import arxiv_caller_errormessages_submissions from comments.forms import CommentForm from production.models import ProductionStream -from django.views.generic.edit import CreateView, FormView +from django.views.generic.edit import CreateView from django.views.generic.list import ListView +import strings + ############### # SUBMISSIONS: ############### -class PrefillUsingIdentifierView(PermissionRequiredMixin, FormView): - form_class = SubmissionIdentifierForm - template_name = 'submissions/prefill_using_identifier.html' - permission_required = 'scipost.can_submit_manuscript' - raise_exception = True - - def post(self, request): - identifierform = SubmissionIdentifierForm(request.POST) - if identifierform.is_valid(): - # Use the ArxivCaller class to make the API calls - caller = ArxivCaller(identifierform.cleaned_data['identifier']) - - if caller.is_valid: - # Arxiv response is valid and can be shown - metadata = caller.metadata - - # BUG !!! - # - # - # - # OLD VARIABLES THAT WERE ACCESSIBLE ON THE OLD CALLER, BUT NOT ON THE NEW ONE: - # - # is_resubmission - # identifier_with_vn_nr - # identifier_without_vn_nr - # previous_submissions - # version_nr - - # OLD CHECKS TO BE IMPLENTED BACK IN: - # - # - # def _check_identifier(self): - # - '''Split the given identifier in an article identifier and version number.''' - # - if not self.caller_regex: - # - raise NotImplementedError('No regex is set for this caller') - # - - # - if re.match(self.caller_regex, self.identifier): - # - self.identifier_without_vn_nr = self.identifier.rpartition('v')[0] - # - self.identifier_with_vn_nr = self.identifier - # - self.version_nr = int(self.identifier.rpartition('v')[2]) - # - # - # - def _precheck_duplicate(self): - # - '''Check if identifier for object already exists.''' - # - if self.target_object.same_version_exists(self.identifier_with_vn_nr): - # - raise ValueError('preprint_already_submitted') - # - # - # - def _precheck_previous_submissions_are_valid(self): - # - '''Check if previous submitted versions have the appropriate status.''' - # - try: - # - self.previous_submissions = self.target_object.different_versions( - # - self.identifier_without_vn_nr) - # - except AttributeError: - # - # Commentaries do not have previous version numbers? - # - pass - # - - # - if self.previous_submissions: - # - for submission in [self.previous_submissions[0]]: - # - if submission.status == 'revision_requested': - # - self.resubmission = True - # - elif submission.status in ['rejected', 'rejected_visible']: - # - raise ValueError('previous_submissions_rejected') - # - else: - # - raise ValueError('previous_submission_undergoing_refereeing') - - title = metadata['entries'][0]['title'] - authorlist = metadata['entries'][0]['authors'][0]['name'] - for author in metadata['entries'][0]['authors'][1:]: - authorlist += ', ' + author['name'] - arxiv_link = metadata['entries'][0]['id'] - abstract = metadata['entries'][0]['summary'] - initialdata = {'is_resubmission': is_resubmission, - 'metadata': metadata, - 'title': title, 'author_list': authorlist, - 'arxiv_identifier_w_vn_nr': caller.identifier_with_vn_nr, - 'arxiv_identifier_wo_vn_nr': caller.identifier_without_vn_nr, - 'arxiv_vn_nr': caller.version_nr, - 'arxiv_link': arxiv_link, 'abstract': abstract} - if is_resubmission: - previous_submissions = caller.previous_submissions - resubmessage = ('There already exists a preprint with this arXiv identifier ' - 'but a different version number. \nYour Submission will be ' - 'handled as a resubmission.') - initialdata['submitted_to_journal'] = previous_submissions[0].submitted_to_journal - initialdata['submission_type'] = previous_submissions[0].submission_type - initialdata['discipline'] = previous_submissions[0].discipline - initialdata['domain'] = previous_submissions[0].domain - initialdata['subject_area'] = previous_submissions[0].subject_area - initialdata['secondary_areas'] = previous_submissions[0].secondary_areas - initialdata['referees_suggested'] = previous_submissions[0].referees_suggested - initialdata['referees_flagged'] = previous_submissions[0].referees_flagged - else: - resubmessage = '' - - form = SubmissionForm(initial=initialdata) - context = {'identifierform': identifierform, - 'form': form, - 'resubmessage': resubmessage} - return render(request, 'submissions/new_submission.html', context) - - else: - msg = caller.get_error_message(arxiv_caller_errormessages_submissions) - identifierform.add_error(None, msg) - return render(request, 'submissions/prefill_using_identifier.html', - {'form': identifierform}) - else: - return render(request, 'submissions/prefill_using_identifier.html', - {'form': identifierform}) - - -class SubmissionCreateView(PermissionRequiredMixin, CreateView): - model = Submission - form_class = SubmissionForm - +@method_decorator(permission_required('scipost.can_submit_manuscript', raise_exception=True), + name='dispatch') +class RequestSubmission(CreateView): + success_url = reverse_lazy('scipost:personal_page') + form_class = RequestSubmissionForm template_name = 'submissions/new_submission.html' - permission_required = 'scipost.can_submit_manuscript' - # Required to use Guardian's CBV PermissionRequiredMixin with a CreateView - # (see https://github.com/django-guardian/django-guardian/pull/433) - permission_object = None - raise_exception = True def get(self, request): - # Only use prefilled forms return redirect('submissions:prefill_using_identifier') - @transaction.atomic - def form_valid(self, form): - submitted_by = Contributor.objects.get(user=self.request.user) - form.instance.submitted_by = submitted_by - - # Temporary until moved to new Arxiv Caller - # Check submitting user for authorship ! - # With the new Arxiv caller, this message should already be given in the prefil form! - if not form.check_user_may_submit(self.request.user): - msg = ('Your name does not match that of any of the authors. ' - 'You are not authorized to submit this preprint.') - messages.error(self.request, msg) - return redirect('submissions:prefill_using_identifier') - - # Save all the information contained in the form - submission = form.save() - - # Perform all extra actions and set information not contained in the form - submission.finish_submission() - - if submission.is_resubmission: - # Assign permissions - assign_perm('can_take_editorial_actions', submission.editor_in_charge.user, submission) - ed_admins = Group.objects.get(name='Editorial Administrators') - assign_perm('can_take_editorial_actions', ed_admins, submission) - - # Assign editor - assignment = EditorialAssignment( - submission=submission, - to=submission.editor_in_charge, - accepted=True - ) - assignment.save() - - # Send emails - SubmissionUtils.load({'submission': submission}, self.request) - SubmissionUtils.send_authors_resubmission_ack_email() - SubmissionUtils.send_EIC_reappointment_email() - else: - # Send emails - SubmissionUtils.load({'submission': submission}) - SubmissionUtils.send_authors_submission_ack_email() + def get_form_kwargs(self): + kwargs = super().get_form_kwargs() + kwargs['requested_by'] = self.request.user + return kwargs + def form_valid(self, form): text = ('<h3>Thank you for your Submission to SciPost</h3>' 'Your Submission will soon be handled by an Editor.') messages.success(self.request, text) - return redirect(reverse('scipost:personal_page')) + return super().form_valid(form) - def mark_previous_submissions_as_deprecated(self, previous_submissions): - for sub in previous_submissions: - sub.is_current = False - sub.open_for_reporting = False - sub.status = 'resubmitted' - sub.save() - def previous_submissions(self, form): - return Submission.objects.filter( - arxiv_identifier_wo_vn_nr=form.cleaned_data['arxiv_identifier_wo_vn_nr'] - ) +@permission_required('scipost.can_submit_manuscript', raise_exception=True) +def prefill_using_arxiv_identifier(request): + query_form = SubmissionIdentifierForm(request.POST or None) + if query_form.is_valid(): + prefill_data = query_form.request_arxiv_preprint_form_prefill_data() + form = RequestSubmissionForm(initial=prefill_data) + messages.success(request, strings.acknowledge_arxiv_query, fail_silently=True) + context = { + 'form': form, + } + return render(request, 'submissions/new_submission.html', context) + + context = { + 'form': query_form, + } + return render(request, 'submissions/prefill_using_identifier.html', context) class SubmissionListView(ListView):