diff --git a/.gitignore b/.gitignore index 5485507a52adc3c6ccb46f76e14087e42860cb86..4d43f387e85330c273f8f85b730634253f3f74e7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,7 @@ __pycache__ .python-version - +/uploads* /media* SCIPOST_JOURNALS diff --git a/README.md b/README.md index 99340c790242facd727f41e6c44105b89844cd8a..fc63276cd5eea6b4756d47419c148c7f7f4a47ad 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ In this project, host-specific settings are defined in the `scipost-host-setting "CERTFILE": "none", "DEBUG": true, "ADMINS": "", + "MANAGERS": "", "ALLOWED_HOSTS": ["localhost", "127.0.0.1"], "SESSION_COOKIE_SECURE": false, "CSRF_COOKIE_SECURE": false, diff --git a/SciPost_v1/settings.py b/SciPost_v1/settings.py index 39653937b45dd4be739df580cf5ae639aedc2727..ea7e4611ac1264e4d01d8ff4a23d113b77ea3151 100644 --- a/SciPost_v1/settings.py +++ b/SciPost_v1/settings.py @@ -35,6 +35,7 @@ DEBUG = host_settings["DEBUG"] # Emails for server error reporting ADMINS = host_settings["ADMINS"] +MANAGERS = host_settings["MANAGERS"] ALLOWED_HOSTS = host_settings["ALLOWED_HOSTS"] diff --git a/SciPost_v1/urls.py b/SciPost_v1/urls.py index e1c8742b3efdde36aeb2adb9bf7a037939ef5cea..8bb1cbd455cf3f734dcc129e7f8c02ba31d6cf1f 100644 --- a/SciPost_v1/urls.py +++ b/SciPost_v1/urls.py @@ -15,7 +15,6 @@ Including another URLconf """ from django.conf import settings from django.conf.urls import include, url -from django.conf.urls.static import static from django.contrib import admin urlpatterns = [ @@ -33,7 +32,5 @@ urlpatterns = [ url(r'^theses/', include('theses.urls', namespace="theses")), url(r'^thesis/', include('theses.urls', namespace="theses")), url(r'^captcha/', include('captcha.urls')), -] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +] - -# urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) diff --git a/commentaries/forms.py b/commentaries/forms.py index 2660f4e5b4dbe04bd75f21d022daeb9d9478b683..6f781e535afca05c1f68b160d01c49b51180fcbe 100644 --- a/commentaries/forms.py +++ b/commentaries/forms.py @@ -37,7 +37,8 @@ class IdentifierToQueryForm(forms.Form): commentary = None if commentary: - msg = 'There already exists a Commentary Page on this preprint, see %s' % commentary.header_as_li() + msg = 'There already exists a Commentary Page on this preprint, see %s' % ( + commentary.title_label()) self.add_error('identifier', msg) return cleaned_data diff --git a/commentaries/models.py b/commentaries/models.py index 58f56c67a4ba63295037569b629b5e197b0e0c49..e42eb41640b13a46ca98fa5e6a012af8c91e215e 100644 --- a/commentaries/models.py +++ b/commentaries/models.py @@ -127,6 +127,15 @@ class Commentary(ArxivCallable, TimeStampedModel): context['arxiv_link'] = self.arxiv_link return template.render(context) + def title_label(self): + context = Context({ + 'scipost_url': self.scipost_url(), + 'pub_title': self.pub_title + }) + template = Template('<a href="{{scipost_url}}" class="pubtitleli">{{pub_title}}</a>') + return template.render(context) + + def header_as_li(self): # for display in search lists context = Context({'scipost_url': self.scipost_url(), 'pub_title': self.pub_title, diff --git a/commentaries/urls.py b/commentaries/urls.py index 3edb7d4a26b84c2684b5d62813b569738b65cc05..2f203ac38365a3ebef2892e851f2562b6bcd64f5 100644 --- a/commentaries/urls.py +++ b/commentaries/urls.py @@ -16,9 +16,9 @@ urlpatterns = [ url(r'^(?P<arxiv_or_DOI_string>arXiv:[0-9]{4,}.[0-9]{5,}(v[0-9]+)?)/$', views.commentary_detail, name='commentary'), # old style identifiers: url(r'^(?P<arxiv_or_DOI_string>arXiv:[a-z-]+/[0-9]{7,}(v[0-9]+)?)/$', views.commentary_detail, name='commentary'), + url(r'^request_commentary$', views.RequestCommentary.as_view(), name='request_commentary'), url(r'^prefill_using_DOI$', views.prefill_using_DOI, name='prefill_using_DOI'), - # 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'^vet_commentary_requests$', views.vet_commentary_requests, name='vet_commentary_requests'), url(r'^vet_commentary_request_ack/(?P<commentary_id>[0-9]+)$', views.vet_commentary_request_ack, name='vet_commentary_request_ack'), diff --git a/commentaries/views.py b/commentaries/views.py index ea2608cfce560aec49d68a6a93e7d6a411b8acf3..339bab4f935cf0a3bcaefbf36a682982be70c215 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -152,93 +152,6 @@ def prefill_using_DOI(request): return redirect(reverse('commentaries:request_commentary')) -# @permission_required('scipost.can_request_commentary_pages', raise_exception=True) -# 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 (IndexError, KeyError): -# 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 (IndexError, KeyError): -# 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 (IndexError, KeyError, ValueError): -# # 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) -# else: -# pass -# return redirect(reverse('commentaries:request_commentary')) - @method_decorator(permission_required( 'scipost.can_request_commentary_pages', raise_exception=True), name='dispatch') class PrefillUsingIdentifierView(RequestCommentaryMixin, FormView): @@ -284,39 +197,8 @@ class PrefillUsingIdentifierView(RequestCommentaryMixin, FormView): return render(self.request, 'commentaries/request_commentary.html', self.get_context_data(**context)) else: - # Arxiv response is not valid - errormessages = { - 'preprint_does_not_exist': - 'A preprint associated to this identifier does not exist.', - 'paper_published_journal_ref': - ('This paper has been published as ' + caller.arxiv_journal_ref + - '. Please comment on the published version.'), - 'paper_published_doi': - ('This paper has been published under DOI ' + caller.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 ' + - caller.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 ' - '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.'), - 'preprint_already_submitted': - 'This preprint version has already been submitted to SciPost.', - 'previous_submissions_rejected': - ('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.') - } - messages.error(self.request, errormessages[caller.errorcode]) + msg = caller.get_error_message() + messages.error(self.request, msg) return render(self.request, 'commentaries/request_commentary.html', self.get_context_data(**{})) diff --git a/comments/models.py b/comments/models.py index 38a1a0f25f3e4e62ef803807e5940faae1991ddb..e449d2a7382c0b0054082c1772ac5f46cf689b64 100644 --- a/comments/models.py +++ b/comments/models.py @@ -40,7 +40,7 @@ class Comment(TimeStampedModel): vetted_by = models.ForeignKey(Contributor, blank=True, null=True, on_delete=models.CASCADE, related_name='comment_vetted_by') - file_attachment = models.FileField(upload_to='comments/%Y/%m/%d/', blank=True, + file_attachment = models.FileField(upload_to='uploads/comments/%Y/%m/%d/', blank=True, validators=[validate_file_extension, validate_max_file_size]) # a Comment is either for a Commentary or Submission or a ThesisLink. diff --git a/journals/templates/journals/scipost_physics.html b/journals/templates/journals/scipost_physics.html index b34bfcf0d31c7dc1fc493218021b458d36565d4f..4ed754b5d0b5f509f600d7211f8fbe235e262323 100644 --- a/journals/templates/journals/scipost_physics.html +++ b/journals/templates/journals/scipost_physics.html @@ -33,10 +33,8 @@ <div class="publicationHeaderList"> <div class="row"> {% for paper in current_issue.publication_set.all|dictsort:"paper_nr" %} - <div class="col-md-6"> - <div class="panel"> - {{ paper.header_as_li }} - </div> + <div class="col-12"> + {{ paper.header_as_li }} </div> {% endfor %} </div> @@ -56,10 +54,8 @@ <div class="publicationHeaderList"> <div class="row"> {% for paper in latest_issue.publication_set.all|dictsort:"paper_nr" %} - <div class="col-md-6"> - <div class="panel"> - {{ paper.header_as_li }} - </div> + <div class="col-12"> + {{ paper.header_as_li }} </div> {% endfor %} </div> diff --git a/journals/templates/journals/scipost_physics_issue_detail.html b/journals/templates/journals/scipost_physics_issue_detail.html index e3356078538a1229818019eaae5a8144e09fb3fb..c153f276d52fedb4a7b0e5f8a9cadda20d4875ef 100644 --- a/journals/templates/journals/scipost_physics_issue_detail.html +++ b/journals/templates/journals/scipost_physics_issue_detail.html @@ -32,7 +32,7 @@ <div class="publicationHeaderList"> <div class="row"> {% for paper in papers %} - <div class="col-md-6"> + <div class="col-12"> <div class="panel"> {{ paper.header_as_li }} </div> diff --git a/journals/templates/journals/scipost_physics_recent.html b/journals/templates/journals/scipost_physics_recent.html index b50d25ccdf1816bfd8a5a3f0e1f69a623404350d..a0340ae76be42a86c6add47b0e629b080eb40bae 100644 --- a/journals/templates/journals/scipost_physics_recent.html +++ b/journals/templates/journals/scipost_physics_recent.html @@ -31,10 +31,8 @@ <div class="publicationHeaderList"> <div class="row"> {% for paper in recent_papers %} - <div class="col-md-6"> - <div class="panel"> - {{ paper.header_as_li }} - </div> + <div class="col-12"> + {{ paper.header_as_li }} </div> {% endfor %} </div> diff --git a/scipost/services.py b/scipost/services.py index cd9c511a8c126e5692fd2692266ae2925088485c..957bb7603e66f5980f8d1568fcd29508427b5b8c 100644 --- a/scipost/services.py +++ b/scipost/services.py @@ -3,8 +3,11 @@ import feedparser import requests import re +from django.template import Template, Context from .behaviors import ArxivCallable +from strings import arxiv_caller_errormessages + class BaseCaller(object): '''Base mixin for caller (Arxiv, DOI). @@ -22,6 +25,8 @@ class BaseCaller(object): _is_processed = False caller_regex = None errorcode = None + errorvariables = {} + errormessages = {} identifier_without_vn_nr = '' identifier_with_vn_nr = '' metadata = {} @@ -63,6 +68,7 @@ class BaseCaller(object): self.identifier_with_vn_nr = self.identifier self.version_nr = int(self.identifier.rpartition('v')[2]) else: + self.errorvariables['identifier_with_vn_nr'] = self.identifier raise ValueError('bad_identifier') def _check_valid_caller(self): @@ -141,6 +147,16 @@ class BaseCaller(object): self._is_processed = True + def get_error_message(self, errormessages={}): + '''Return the errormessages for a specific error code, with the possibility to + overrule the default errormessage dictionary for the specific Caller. + ''' + try: + t = Template(errormessages[self.errorcode]) + except KeyError: + t = Template(self.errormessages[self.errorcode]) + return t.render(Context(self.errorvariables)) + class DOICaller(BaseCaller): """Perform a DOI lookup for a given identifier.""" @@ -153,6 +169,12 @@ class ArxivCaller(BaseCaller): # # State of the caller resubmission = False previous_submissions = [] + errormessages = arxiv_caller_errormessages + errorvariables = { + 'arxiv_journal_ref': '', + 'arxiv_doi': '', + 'identifier_with_vn_nr': '' + } arxiv_journal_ref = '' arxiv_doi = '' metadata = {} @@ -195,11 +217,13 @@ class ArxivCaller(BaseCaller): # Check via journal ref if already published self.arxiv_journal_ref = self.published_journal_ref() + self.errorvariables['arxiv_journal_ref'] = self.arxiv_journal_ref if self.arxiv_journal_ref: raise ValueError('paper_published_journal_ref') # Check via DOI if already published self.arxiv_doi = self.published_doi() + self.errorvariables['arxiv_doi'] = self.arxiv_doi if self.arxiv_doi: raise ValueError('paper_published_doi') diff --git a/scipost/static/scipost/assets/config/preconfig.scss b/scipost/static/scipost/assets/config/preconfig.scss index 24c52d2a8a68a32684a3f35a2bd6eb786b61dc0d..e19eda442bfb4966be75761eb61a333ea5bf16fd 100644 --- a/scipost/static/scipost/assets/config/preconfig.scss +++ b/scipost/static/scipost/assets/config/preconfig.scss @@ -24,6 +24,14 @@ $scipost-orange: #FFA300; $blue: $scipost-lightblue !default; $body-color: $scipost-darkblue !default; +// Forms +// +$btn-padding-x: .5rem; +$btn-padding-y: .25rem; +$btn-transition: none; +$input-padding-x: .5rem; +$input-padding-y: .25rem; + // Fonts // $font-family-sans-serif: 'Merriweather Sans', "Helvetica Neue", Arial, sans-serif !default; diff --git a/scipost/static/scipost/assets/css/_form.scss b/scipost/static/scipost/assets/css/_form.scss index dfadd721860244cbc75166ebd9476917a882a45f..49e94deed1017ee621bd8baea9d4dbdf6327db6c 100644 --- a/scipost/static/scipost/assets/css/_form.scss +++ b/scipost/static/scipost/assets/css/_form.scss @@ -7,7 +7,7 @@ } .has-error .form-control { - border-color: #d9534f; + border-color: #d9534f; } .form-control + .help-block { @@ -16,7 +16,8 @@ font-weight: 600; } -form.small .form-group { +.form-group, +.row.form-group { margin-bottom: 0.5rem; } diff --git a/scipost/static/scipost/assets/css/_journals.scss b/scipost/static/scipost/assets/css/_journals.scss index 0ccadb843c4c75722e805b8e5aae33889eff6dcb..75632e01e3847f59c38b7b70bc9b794e512580d8 100644 --- a/scipost/static/scipost/assets/css/_journals.scss +++ b/scipost/static/scipost/assets/css/_journals.scss @@ -31,7 +31,12 @@ } .publicationHeader { - .panel & .publicationTitle { + padding: 0.75rem; + height: 100%; + background-color: #f8f8f8; + border-bottom: 10px solid #fff; + + & .publicationTitle { margin: -0.75rem -0.75rem 0.5rem -0.75rem; } } diff --git a/scipost/static/scipost/assets/css/_navbar.scss b/scipost/static/scipost/assets/css/_navbar.scss index ffca11a414ee21c0b840ebec09ac970d7b12639f..351f6e47a112b1075567d87486d2bf886c9f9e7b 100644 --- a/scipost/static/scipost/assets/css/_navbar.scss +++ b/scipost/static/scipost/assets/css/_navbar.scss @@ -10,15 +10,21 @@ padding-left: 1rem; border: 1px solid transparent; border-radius: 0.1rem; - -webkit-transition: all 0.2s ease-in-out; - -o-transition: all 0.2s ease-in-out; - transition: all 0.2s ease-in-out; + word-wrap: break-word; + white-space: nowrap; + -webkit-transition: all 0.1s ease-in-out; + -o-transition: all 0.1s ease-in-out; + transition: all 0.1s ease-in-out; @include hover-focus { background-color: $white; } } + .navbar-collapse.show .nav-item { + margin-bottom: .25rem; + } + .active > .nav-link { border-color: $scipost-darkblue; } @@ -31,6 +37,7 @@ margin-right: 0.5rem; } } + .navbar-brand { height: 38px; margin: 0; diff --git a/scipost/static/scipost/assets/css/_type.scss b/scipost/static/scipost/assets/css/_type.scss index 81966676baeb5871c41826484afd0c78be4e87eb..b26184a133ac489c3526fe2feaa860951a00d1cc 100644 --- a/scipost/static/scipost/assets/css/_type.scss +++ b/scipost/static/scipost/assets/css/_type.scss @@ -18,12 +18,21 @@ h1, h2, h3, h4, h5, h6 { text-shadow: none; font-weight: 500; } +h3.highlight { + background-color: #f4f4f4; + + &.tight { + display: inline-block; + padding: 3px 5px; + margin-bottom: 3px; + } +} hr, hr.hr12 { height: 3px; border: 0; - box-shadow: 0 1px 2px 0 #ccc; - background: rgba(104, 133, 195, 0.5); + box-shadow: none !important; + background: rgba(0, 43, 73, 0.73); margin-bottom: 1rem; &.small { diff --git a/scipost/static/scipost/assets/js/scripts.js b/scipost/static/scipost/assets/js/scripts.js index b3c0ab7cefa52a90d62b01eff3a8e20de8cd0f82..001f02c0ead487734d86757d0d303035c10f7343 100644 --- a/scipost/static/scipost/assets/js/scripts.js +++ b/scipost/static/scipost/assets/js/scripts.js @@ -2,7 +2,6 @@ function hide_all_alerts() { $(".alert").fadeOut(300); } - $(function(){ // Remove all alerts in screen automatically after 10sec. setTimeout(function() {hide_all_alerts()}, 10000); diff --git a/scipost/templates/scipost/base.html b/scipost/templates/scipost/base.html index 4a3105f7a1ef8dc2fa23b523e0415cbd2438dd72..baa04274b5b7b487f2e81c493db95e203016819d 100644 --- a/scipost/templates/scipost/base.html +++ b/scipost/templates/scipost/base.html @@ -18,6 +18,8 @@ <title>SciPost{% block pagetitle %}{% endblock pagetitle %}</title> <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script> + <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css"> + <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> {% block headsup %} {% endblock headsup %} diff --git a/scipost/templates/scipost/navbar.html b/scipost/templates/scipost/navbar.html index a8742b17d79f3a1c11c3adc064b4850c9ce695d1..04cce9fedff90383eb8df8bf20fd99d4fdc1d979 100644 --- a/scipost/templates/scipost/navbar.html +++ b/scipost/templates/scipost/navbar.html @@ -1,4 +1,4 @@ -<nav class="navbar navbar-light navbar-toggleable-md"> +<nav class="navbar navbar-light navbar-toggleable-sm"> <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#header-navbar"> <span class="navbar-toggler-icon"></span> </button> diff --git a/strings/__init__.py b/strings/__init__.py index bed3b4266a7950a0cd9f065df61db429a7a847bc..f51088e3aeecb9d059e14d341717c77936519e6c 100644 --- a/strings/__init__.py +++ b/strings/__init__.py @@ -7,3 +7,43 @@ acknowledge_request_commentary = ( "Your request will soon be handled by an Editor. <br>" "Thank you for your request for a Commentary Page." ) + +# Arxiv response is not valid +arxiv_caller_errormessages = { + 'preprint_does_not_exist': + 'A preprint associated to this identifier does not exist.', + 'paper_published_journal_ref': + ('This paper has been published as {{ arxiv_journal_ref }}' + '. Please comment on the published version.'), + '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.'), + 'previous_submission_undergoing_refereeing': + ('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.'), + 'preprint_already_submitted': + 'This preprint version has already been submitted to SciPost.', + 'previous_submissions_rejected': + ('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.') +} + +arxiv_caller_errormessages_submissions = { + 'paper_published_journal_ref': ('This paper has been published as {{ arxiv_journal_ref }}' + '. You cannot submit it to SciPost anymore.'), + 'paper_published_doi': ('This paper has been published under DOI {{ arxiv_doi }}' + '. You cannot submit it to SciPost anymore.') +} diff --git a/submissions/models.py b/submissions/models.py index f6b8faa61aa33bd4cfa089c2bfe5c27b74518d70..8ca56af4a8d1d553d10b49041712a5eee45a5a53 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -688,15 +688,15 @@ class Report(models.Model): def print_contents(self): context = Context({'strengths': self.strengths, 'weaknesses': self.weaknesses, 'report': self.report, 'requested_changes': self.requested_changes}) - output = ('<div class="row"><div class="col-6">' - 'Strengths:</div><div class="col-6">{{ strengths }}</div></div>' - '<div class="row"><div class="col-6">' - 'Weaknesses:</div><div class="col-6">{{ weaknesses }}</div></div>' - '<div class="row"><div class="col-6">' - 'Report:</div><div class="col-6">{{ report }}</div></div>' - '<div class="row"><div class="col-6">' - 'Requested changes:</div>' - '<div class="col-6">{{ requested_changes }}</div></div>' + output = ('<div class="row"><div class="col-12"><h3 class="highlight tight">' + 'Strengths</h3><div class="pl-md-4">{{ strengths|linebreaks }}</div></div></div>' + '<div class="row"><div class="col-12"><h3 class="highlight tight">' + 'Weaknesses</h3><div class="pl-md-4">{{ weaknesses|linebreaks }}</div></div></div>' + '<div class="row"><div class="col-12"><h3 class="highlight tight">' + 'Report</h3><div class="pl-md-4">{{ report|linebreaks }}</div></div></div>' + '<div class="row"><div class="col-12"><h3 class="highlight tight">' + 'Requested changes</h3><div class="pl-md-4">' + '<p>{{ requested_changes|linebreaks }}</p>' '<div class="reportRatings"><ul>' '<li>validity: ' + ranking_choices_dict[self.validity] + '</li>' '<li>significance: ' + ranking_choices_dict[self.significance] + '</li>' @@ -704,7 +704,7 @@ class Report(models.Model): '<li>clarity: ' + ranking_choices_dict[self.clarity] + '</li>' '<li>formatting: ' + quality_spec_dict[self.formatting] + '</li>' '<li>grammar: ' + quality_spec_dict[self.grammar] + '</li>' - '</ul></div>') + '</ul></div></div></div></div>') template = Template(output) return template.render(context) @@ -723,12 +723,12 @@ class Report(models.Model): output += ('<a href="/contributor/{{ author_id }}">' '{{ author_first_name }} {{ author_last_name }}</a>' ' on {{ date_submitted }}</h3></div>' - '<div class="row"><div class="col-6">Qualification:</div>' - '<div class="col-6">' - + ref_qualif_dict[self.qualification] + '</div></div>') + '<div class="row"><div class="col-12"><h3 class="highlight tight">Qualification</h3>' + '<div class="pl-md-4">' + + ref_qualif_dict[self.qualification] + '</div></div></div>') output += self.print_contents() - output += '<h3>Remarks for editors</h3><p>{{ remarks_for_editors }}</p>' - output += '<h3>Recommendation</h3><p>%s</p>' % report_rec_dict[self.recommendation] + output += '<div class="row"><div class="col-12"><h3>Remarks for editors</h3><div class="pl-md-4">{{ remarks_for_editors }}</div></div></div>' + output += '<div class="row"><div class="col-12"><h3>Recommendation</h3><div class="pl-md-4">%s</div></div></div>' % report_rec_dict[self.recommendation] template = Template(output) return template.render(context) diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 9a55f03955cb0cc037025847f93ac4a9fb780420..68750602f0e9eddaf708bac9af84bef5b2d2d317 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -6,6 +6,8 @@ {% load scipost_extras %} {% load submissions_extras %} +{% load filename %} +{% load file_extentions %} <script> $(document).ready(function(){ @@ -198,6 +200,18 @@ </div> <div class="col-12"> <p>{{ reply.comment_text|linebreaks }}</p> + {% if reply.file_attachment %} + <h3>Attachment:</h3> + <p> + <a target="_blank" href="{{ reply.file_attachment.url }}"> + {% if reply.file_attachment|is_image %} + <img class="attachment attachment-comment" src="{{ reply.file_attachment.url }}"> + {% else %} + {{ reply.file_attachment|filename }}<br><small>{{ reply.file_attachment.size|filesizeformat }}</small> + {% endif %} + </a> + </p> + {% endif %} </div> </div> </div> diff --git a/submissions/views.py b/submissions/views.py index 69c8ee909f278cd75c38ddc08b7e44f4b6673ebb..f69b23d8c9e75518494648553fe98f18d87bdf63 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -35,6 +35,7 @@ from scipost.models import Contributor, title_dict, Remark, RegistrationInvitati from scipost.services import ArxivCaller from scipost.utils import Utils +from strings import arxiv_caller_errormessages_submissions from comments.forms import CommentForm @@ -100,39 +101,8 @@ class PrefillUsingIdentifierView(PermissionRequiredMixin, FormView): return render(request, 'submissions/new_submission.html', context) else: - # Arxiv response is not valid - errormessages = { - 'preprint_does_not_exist': - 'A preprint associated to this identifier does not exist.', - 'paper_published_journal_ref': - ('This paper has been published as ' + caller.arxiv_journal_ref + - '. You cannot submit it to SciPost anymore.'), - 'paper_published_doi': - ('This paper has been published under DOI ' + caller.arxiv_doi + - '. You cannot submit it to SciPost anymore.'), - 'arxiv_timeout': 'Arxiv did not respond in time. Please try again later', - 'arxiv_bad_request': - ('There was an error with requesting identifier ' + - caller.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 ' - '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.'), - 'preprint_already_submitted': 'This preprint version has already been submitted to SciPost.', - 'previous_submissions_rejected': - ('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.') - } - - identifierform.add_error(None, errormessages[caller.errorcode]) + 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: diff --git a/theses/forms.py b/theses/forms.py index 3f5dfcc0e5784131d4e8a0d9f7039bad5b07064a..6f8a0e2c1757dec0992cec6e55417a3aad15a17c 100644 --- a/theses/forms.py +++ b/theses/forms.py @@ -108,3 +108,5 @@ class ThesisLinkSearchForm(forms.Form): title_keyword = forms.CharField(max_length=100, label="Title", required=False) abstract_keyword = forms.CharField(max_length=1000, required=False, label="Abstract") supervisor = forms.CharField(max_length=100, required=False, label="Supervisor") + from_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False) + to_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False) diff --git a/theses/managers.py b/theses/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..ecd55472d300655f05c42f7c0fda4b4415b4a79b --- /dev/null +++ b/theses/managers.py @@ -0,0 +1,24 @@ +import datetime + +from django.db import models +from django.utils import timezone + + +class ThesisLinkManager(models.Manager): + def search_results(self, form): + from_date = form.cleaned_data['from_date'] if form.cleaned_data['from_date'] else datetime.date(1600, 1, 1) + to_date = form.cleaned_data['to_date'] if form.cleaned_data['to_date'] else timezone.now() + + return self.vetted().filter( + title__icontains=form.cleaned_data['title_keyword'], + author__icontains=form.cleaned_data['author'], + abstract__icontains=form.cleaned_data['abstract_keyword'], + supervisor__icontains=form.cleaned_data['supervisor'], + defense_date__range=(from_date, to_date) + ).order_by('-defense_date') + + def latest(self, n): + return self.vetted().order_by('latest_activity')[:n] + + def vetted(self): + return self.filter(vetted=True) diff --git a/theses/models.py b/theses/models.py index 69fb37790d0cdeb54c948fd782199fe392b84c0f..0b5d333757c72aeb3d893454b2a520faad373f69 100644 --- a/theses/models.py +++ b/theses/models.py @@ -7,6 +7,8 @@ from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\ subject_areas_dict, disciplines_dict from scipost.models import Contributor +from .managers import ThesisLinkManager + class ThesisLink(models.Model): MASTER_THESIS = 'MA' @@ -64,6 +66,8 @@ class ThesisLink(models.Model): abstract = models.TextField(verbose_name='abstract, outline or summary') latest_activity = models.DateTimeField(default=timezone.now) + objects = ThesisLinkManager() + def __str__(self): return self.title diff --git a/theses/templates/theses/theses.html b/theses/templates/theses/theses.html index e50560f5fd18386a278748e345f8b6afedd97868..6abaedb7eb8c1764cbcdee25d1b3f0e222cfde93 100644 --- a/theses/templates/theses/theses.html +++ b/theses/templates/theses/theses.html @@ -20,8 +20,7 @@ <div class="col-md-4"> <div class="panel page-header-panel"> <h2>Search SciPost Theses:</h2> - <form class="small" action="{% url 'theses:theses' %}" method="post"> - {% csrf_token %} + <form class="small" action="{% url 'theses:theses' %}" method="get"> <table> {{ form|bootstrap:'4,8,sm' }} </table> @@ -39,14 +38,14 @@ </div> </div> - {% if thesislink_search_list or form.has_changed %} + {% if search_results or form.has_changed %} <div class="row"> <div class="col-12"> <hr class="hr12"> <h3>Search results:</h3> - {% if thesislink_search_list %} + {% if search_results %} <ul> - {% for thesislink in thesislink_search_list %} + {% for thesislink in search_results %} {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} {% endfor %} </ul> @@ -57,13 +56,13 @@ </div> {% endif %} -{% if thesislink_recent_list %} +{% if recent_theses %} <div class="row"> <div class="col-12"> <hr class="hr12"> <h2>Recently active Thesis Links:</h2> <ul> - {% for thesislink in thesislink_recent_list %} + {% for thesislink in recent_theses %} {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} {% endfor %} </ul> diff --git a/theses/views.py b/theses/views.py index a398d8622d3d8d7a7f4a7282652e52890eeec64a..b000a467910850a4be93dde39ab4db7acc7036d6 100644 --- a/theses/views.py +++ b/theses/views.py @@ -87,29 +87,17 @@ class VetThesisLink(UpdateView): def theses(request): - if request.method == 'POST': - form = ThesisLinkSearchForm(request.POST) - if form.is_valid() and form.has_changed(): - thesislink_search_list = ThesisLink.objects.filter( - title__icontains=form.cleaned_data['title_keyword'], - author__icontains=form.cleaned_data['author'], - abstract__icontains=form.cleaned_data['abstract_keyword'], - supervisor__icontains=form.cleaned_data['supervisor'], - vetted=True, - ) - thesislink_search_list.order_by('-pub_date') - else: - thesislink_search_list = [] - + form = ThesisLinkSearchForm(request.GET) + if form.is_valid() and form.has_changed(): + search_results = ThesisLink.objects.search_results(form) + recent_theses = [] else: - form = ThesisLinkSearchForm() - thesislink_search_list = [] + recent_theses = ThesisLink.objects.latest(5) + search_results = [] - thesislink_recent_list = ( - ThesisLink.objects.filter(vetted=True, latest_activity__gte=timezone.now() + datetime.timedelta(days=-7))) context = { - 'form': form, 'thesislink_search_list': thesislink_search_list, - 'thesislink_recent_list': thesislink_recent_list + 'form': form, 'search_results': search_results, + 'recent_theses': recent_theses } return render(request, 'theses/theses.html', context)