diff --git a/.bootstraprc b/.bootstraprc index ab4a0cccb6882f155316d46dff87435d40a1502a..cd4c5b095e1f3274f4a76081fc0879c080796e86 100644 --- a/.bootstraprc +++ b/.bootstraprc @@ -9,6 +9,8 @@ ], "extractStyles": true, "styles": { + # First tables, due to self dependencies + "tables": true, "alert": true, "button-group": true, "buttons": true, diff --git a/commentaries/factories.py b/commentaries/factories.py index 31f1354fa2c7c811daccdbfa7bd9a27cdf55850f..60f1625f2f365bd240db1d1aa7e5d7beb2a9fa73 100644 --- a/commentaries/factories.py +++ b/commentaries/factories.py @@ -2,11 +2,12 @@ import factory from scipost.constants import DISCIPLINE_PHYSICS, SCIPOST_SUBJECT_AREAS from scipost.factories import ContributorFactory -from journals.models import SCIPOST_JOURNALS_DOMAINS +from journals.constants import SCIPOST_JOURNALS_DOMAINS from common.helpers import random_arxiv_identifier_with_version_number from .models import Commentary, COMMENTARY_TYPES + class CommentaryFactory(factory.django.DjangoModelFactory): class Meta: model = Commentary diff --git a/commentaries/managers.py b/commentaries/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..545a1740ffa0c8efca402352431551ad28c6fd18 --- /dev/null +++ b/commentaries/managers.py @@ -0,0 +1,9 @@ +from django.db import models + + +class CommentaryManager(models.Manager): + def vetted(self, **kwargs): + return self.filter(vetted=True, **kwargs) + + def awaiting_vetting(self, **kwargs): + return self.filter(vetted=False, **kwargs) diff --git a/commentaries/models.py b/commentaries/models.py index 37b54c8caa499ee143360e8d086d5840dd510f39..ac6dab51bf5723cbad95556ed95bfa5c13ec9641 100644 --- a/commentaries/models.py +++ b/commentaries/models.py @@ -1,13 +1,16 @@ from django.db import models from django.contrib.postgres.fields import JSONField +from django.core.urlresolvers import reverse from django.template import Template, Context -from django.template.loader import get_template -from journals.models import SCIPOST_JOURNALS_DOMAINS -from scipost.behaviors import ArxivCallable -from scipost.models import TimeStampedModel, Contributor +from journals.constants import SCIPOST_JOURNALS_DOMAINS +from scipost.behaviors import ArxivCallable, TimeStampedModel +from scipost.models import Contributor from scipost.constants import SCIPOST_DISCIPLINES, DISCIPLINE_PHYSICS, SCIPOST_SUBJECT_AREAS +from .managers import CommentaryManager + + COMMENTARY_PUBLISHED = 'published' COMMENTARY_PREPRINT = 'preprint' COMMENTARY_TYPES = ( @@ -16,14 +19,6 @@ COMMENTARY_TYPES = ( ) -class CommentaryManager(models.Manager): - def vetted(self, **kwargs): - return self.filter(vetted=True, **kwargs) - - def awaiting_vetting(self, **kwargs): - return self.filter(vetted=False, **kwargs) - - class Commentary(ArxivCallable, TimeStampedModel): """ A Commentary contains all the contents of a SciPost Commentary page for a given publication. @@ -88,80 +83,14 @@ class Commentary(ArxivCallable, TimeStampedModel): def same_version_exists(self, identifier): return self.objects.filter(arxiv_identifier=identifier).exists() - def header_as_table(self): - # for display in Commentary page itself - header = ('<table>' - '<tr><td>Title: </td><td> </td><td>{{ pub_title }}</td></tr>' - '<tr><td>Author(s): </td><td> </td><td>{{ author_list }}</td></tr>' - '<tr><td>As Contributors: </td><td> </td>') - if self.authors.all(): - header += '<td>' - for auth in self.authors.all(): - header += ('<a href="/contributor/' + str(auth.id) + '">' + auth.user.first_name - + ' ' + auth.user.last_name + '</a>, ') - header += '</td>' - else: - header += '<td>(none claimed)</td>' - header += '</tr>' - if self.type == 'published': - header += ('<tr><td>Journal ref.: </td><td> </td><td>{{ journal }} {{ volume }}, ' - '{{ pages }}</td></tr>' - '<tr><td>DOI: </td><td> </td><td><a href="{{ pub_DOI_link }}" ' - 'target="_blank">{{ pub_DOI_link }}</a></td></tr>') - elif self.type == 'preprint': - header += ('<tr><td>arxiv Link: </td><td> </td><td><a href="{{ arxiv_link }}">' - '{{ arxiv_link }}</a></td></tr>') - if self.pub_date: - header += '<tr><td>Date: </td><td> </td><td>{{ pub_date }}</td></tr>' - header += '</table>' - template = Template(header) - context = Context({ - 'pub_title': self.pub_title, 'author_list': self.author_list, - }) - if self.type == 'published': - context['journal'] = self.journal - context['volume'] = self.volume - context['pages'] = self.pages - context['pub_DOI_link'] = self.pub_DOI_link - context['pub_date'] = self.pub_date - elif self.type == 'preprint': - context['arxiv_link'] = self.arxiv_link - return template.render(context) - def title_label(self): context = Context({ - 'scipost_url': self.scipost_url(), + 'scipost_url': reverse('commentaries:commentary', args=(self.arxiv_or_DOI_string,)), '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): - # TO BE REMOVED!!!! - template = get_template('commentaries/commentary_header_li.html') - return template.render({'object': self}) - - def simple_header_as_li(self): - # for display in Lists - context = Context({'scipost_url': self.scipost_url(), 'pub_title': self.pub_title, - 'author_list': self.author_list}) - header = ('<li>' - '<p><a href="{{ scipost_url }}" ' - 'class="pubtitleli">{{ pub_title }}</a></p>' - '<p>by {{ author_list }}') - if self.type == 'published': - header += ', {{ journal }} {{ volume }}, {{ pages }}' - context['journal'] = self.journal - context['volume'] = self.volume - context['pages'] = self.pages - elif self.type == 'preprint': - header += ', <a href="{{ arxiv_link }}">{{ arxiv_link }}</a>' - context['arxiv_link'] = self.arxiv_link - header += '</p>' - header += '</li>' - template = Template(header) - return template.render(context) - def parse_links_into_urls(self, commit=False): """ Takes the arXiv nr or DOI and turns it into the urls """ if self.pub_DOI: @@ -173,11 +102,3 @@ class Commentary(ArxivCallable, TimeStampedModel): if commit: self.save() - - def scipost_url(self): - """ Returns the url of the SciPost Commentary Page """ - return '/commentary/' + self.arxiv_or_DOI_string - - def scipost_url_full(self): - """ Returns the url of the SciPost Commentary Page """ - return 'https://scipost.org/commentary/' + self.arxiv_or_DOI_string diff --git a/commentaries/templates/commentaries/_commentary_card_content.html b/commentaries/templates/commentaries/_commentary_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..a00cd4ca86eda5aeae8d6dd1be4e027158de80b0 --- /dev/null +++ b/commentaries/templates/commentaries/_commentary_card_content.html @@ -0,0 +1,11 @@ +<div class="card-block"> + <h3 class="card-title"> + <a href="{% url 'commentaries:commentary' commentary.arxiv_or_DOI_string %}">{{ commentary.pub_title }}</a> + </h3> + <p class="card-text"> + by {{ commentary.author_list }}{% if commentary.type == 'published' %}, {{ commentary.journal }} {{ commentary.volume }}, {{ commentary.pages }}{% elif commentary.type == 'preprint' %} - <a href="{{ commentary.arxiv_link }}">{{ commentary.arxiv_link }}</a>{% endif %} + </p> + <p class="card-text text-muted"> + {% if commentary.pub_date %}(published {{ commentary.pub_date }}) - {% endif %}latest activity: {{ commentary.latest_activity }} + </p> +</div> diff --git a/commentaries/templates/commentaries/_commentary_summary.html b/commentaries/templates/commentaries/_commentary_summary.html new file mode 100644 index 0000000000000000000000000000000000000000..681641bf617197f425237dc949a917d76168e69f --- /dev/null +++ b/commentaries/templates/commentaries/_commentary_summary.html @@ -0,0 +1,45 @@ +<table class="commentary summary"> + <tr> + <td>Title:</td> + <td>{{commentary.pub_title}}</td> + </tr> + <tr> + <td>Author(s):</td> + <td>{{commentary.author_list}}</td> + </tr> + <tr> + <td>As Contributors:</td> + <td> + {% for author in commentary.authors.all %} + <a href="{% url 'scipost:contributor_info' author.id %}">{{author.user.first_name}} {{author.user.last_name}}</a> + {% empty %} + (none claimed) + {% endfor %} + </td> + </tr> + {% if commentary.type == 'published' %} + <tr> + <td>Journal ref.:</td> + <td>{{commentary.journal}} {{commentary.volume}}, {{commentary.pages}}</td> + </tr> + <tr> + <td>DOI:</td> + <td> + <a href="{{commentary.pub_DOI_link}}" target="_blank">{{commentary.pub_DOI_link}}</a> + </td> + </tr> + {% elif commentary.type == 'preprint' %} + <tr> + <td>arxiv Link:</td> + <td> + <a href="{{commentary.arxiv_link}}" target="_blank">{{commentary.arxiv_link}}</a> + </td> + </tr> + {% endif %} + {% if commentary.pub_date %} + <tr> + <td>Date:</td> + <td>{{commentary.pub_date}}</td> + </tr> + {% endif %} +</table> diff --git a/commentaries/templates/commentaries/commentary_detail.html b/commentaries/templates/commentaries/commentary_detail.html index b9c5fcd2f9a3691477692d54a4441d17f4b8c913..5b47e90f8844ea97816973ff8de2271abd9a271c 100644 --- a/commentaries/templates/commentaries/commentary_detail.html +++ b/commentaries/templates/commentaries/commentary_detail.html @@ -8,9 +8,6 @@ <script> $(document).ready(function(){ - $("#commentsbutton").click(function(){ - $("#commentslist").toggle(); - }); var comment_text_input = $("#id_comment_text"); @@ -32,20 +29,16 @@ {% block content %} - <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>SciPost Commentary Page (non-SciPost publications)</h1> - </div> + <h1 class="highlight">SciPost Commentary Page (non-SciPost publications)</h1> </div> </div> -<hr> <div class="row"> <div class="col-12"> <h2>Original publication: </h2> - {{ commentary.header_as_table }} + {% include 'commentaries/_commentary_summary.html' with commentary=commentary %} </div> </div> diff --git a/commentaries/templates/commentaries/commentary_header_li.html b/commentaries/templates/commentaries/commentary_header_li.html deleted file mode 100644 index 56fd1ee2e850419b883521ed1b89f6d5b34c70f9..0000000000000000000000000000000000000000 --- a/commentaries/templates/commentaries/commentary_header_li.html +++ /dev/null @@ -1,13 +0,0 @@ -<li> - <p> - <a href="{{ object.scipost_url }}" class="pubtitleli">{{ object.pub_title }}</a> - </p> - <p> - by {{ object.author_list }} - {% if object.type == 'published' %}, {{ object.journal }} {{ object.volume }}, {{ object.pages }} - {% elif object.type == 'preprint' %}, <a href="{{ object.arxiv_link }}">{{ object.arxiv_link }}</a>{% endif %} - </p> - <p> - {% if object.pub_date %}(published {{ object.pub_date }}) - {% endif %}latest activity: {{ object.latest_activity }} - </p> -</li> diff --git a/commentaries/templates/commentaries/commentary_list.html b/commentaries/templates/commentaries/commentary_list.html index 4a420102c155cd83ed008a0b4c8362792c7093bf..a8c92a52df708b0f81a43c36bd0b77d6817d63ef 100644 --- a/commentaries/templates/commentaries/commentary_list.html +++ b/commentaries/templates/commentaries/commentary_list.html @@ -6,54 +6,64 @@ {% block pagetitle %}: Commentaries{% endblock pagetitle %} {% block headsup %} -<script type="text/javascript" async src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script> + <script type="text/javascript" async src="//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script> {% endblock headsup %} {% block content %} <div class="row"> <div class="col-md-4"> - <div class="panel page-header-panel"> - <h1>SciPost Commentaries</h1> - <h3><a href="{% url 'commentaries:howto' %}">SciPost Commentaries how-to</a></h3> - <h3><a href="{% url 'commentaries:request_commentary' %}">Request a new Commentary Page</a></h3> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h1 class="card-title">SciPost Commentaries</h1> + <h3><a href="{% url 'commentaries:howto' %}">SciPost Commentaries how-to</a></h3> + <h3><a href="{% url 'commentaries:request_commentary' %}">Request a new Commentary Page</a></h3> + </div> </div> </div> <div class="col-md-4"> - <div class="panel page-header-panel"> - <h2>Search SciPost Commentaries:</h2> - <form action="{% url 'commentaries:commentaries' %}" class="small" method="get"> - {{ form|bootstrap:'4,8,sm' }} - <input class="btn btn-sm btn-secondary" type="submit"/> - </form> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h2 class="card-title">Search SciPost Commentaries:</h2> + <form action="{% url 'commentaries:commentaries' %}" class="small" method="get"> + {{ form|bootstrap:'4,8,sm' }} + <input class="btn btn-sm btn-secondary" type="submit"/> + </form> + </div> </div> </div> <div class="col-md-4"> - <div class="panel page-header-panel"> - <h2>View SciPost Commentaries</h2> - <ul> - <li>Physics: last <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=1 %}">week</a>, <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=4 %}">month</a> or <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=52 %}">year</a> </li> - </ul> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h2 class="card-title">View SciPost Commentaries</h2> + <ul> + <li>Physics: last <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=1 %}">week</a>, <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=4 %}">month</a> or <a href="{% url 'commentaries:browse' discipline='physics' nrweeksback=52 %}">year</a> </li> + </ul> + </div> </div> </div> </div> {% if not browse and recent %} +<hr> <div class="row"> <div class="col-12"> - <hr class="hr12"> <h2>Recent Comments</h2> - <ul> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> {% for comment in comment_list %} - {{ comment.simple_header_as_li }} + <li class="list-group-item"> + {% include 'comments/_comment_card_content.html' with comment=comment %} + </li> {% endfor %} </ul> </div> </div> {% endif %} +<hr> <div class="row"> <div class="col-12"> - <hr class="hr12"> {% if recent %} <h2>Recently active Commentaries:</h2> {% elif browse %} @@ -73,9 +83,15 @@ {% endif %} </p> {% endif %} - <ul> + + </div> + <div class="col-12"> + + <ul class="list-group list-group-flush"> {% for object in object_list %} - {% include 'commentaries/commentary_header_li.html' with object=object %} + <li class="list-group-item"> + {% include 'commentaries/_commentary_card_content.html' with commentary=object %} + </li> {% endfor %} </ul> {% else %} diff --git a/commentaries/templates/commentaries/request_commentary.html b/commentaries/templates/commentaries/request_commentary.html index 99409292c3a2ad78fff5e2383fac45f1e164ad29..dec478082ee981283b6a946ff54db43c78383faa 100644 --- a/commentaries/templates/commentaries/request_commentary.html +++ b/commentaries/templates/commentaries/request_commentary.html @@ -84,7 +84,7 @@ {% if errormessage %} <h3 style="color: red;">Error: {{ errormessage }}</h3> {% if existing_commentary %} - <ul>{% include 'commentaries/commentary_header_li.html' with object=existing_commentary %}</ul> + <ul>{% include 'commentaries/_commentary_card_content.html' with object=existing_commentary %}</ul> {% endif %} <br/> {% endif %} diff --git a/commentaries/templates/commentaries/vet_commentary_requests.html b/commentaries/templates/commentaries/vet_commentary_requests.html index 1211f37e610d29a04277ab74fae16951f2150198..70edddb6e8eaca847e8337f0d5b1d003e759daae 100644 --- a/commentaries/templates/commentaries/vet_commentary_requests.html +++ b/commentaries/templates/commentaries/vet_commentary_requests.html @@ -16,7 +16,7 @@ <hr> <div class="row"> <div class="col-8"> - {{ commentary_to_vet.header_as_table }} + {% include 'commentaries/_commentary_summary.html' with commentary=commentary_to_vet %} <h3>Abstract:</h3> <p>{{ commentary_to_vet.pub_abstract }}</p> diff --git a/commentaries/views.py b/commentaries/views.py index e103063d5ff6074d4a37aa0137a51efb166697cd..6a2dbb3754926722cd3b69682aa0c2257863b758 100644 --- a/commentaries/views.py +++ b/commentaries/views.py @@ -7,6 +7,7 @@ from django.contrib.auth.decorators import permission_required from django.contrib.auth.mixins import LoginRequiredMixin from django.core.mail import EmailMessage from django.core.urlresolvers import reverse, reverse_lazy +from django.db.models import Q from django.shortcuts import redirect from django.template.loader import render_to_string from django.views.generic.edit import CreateView, FormView @@ -282,9 +283,12 @@ class CommentaryListView(ListView): context = super().get_context_data(**kwargs) # Get newest comments - context['comment_list'] = Comment.objects.vetted().select_related( - 'author__user', 'submission', 'commentary').order_by( - '-date_submitted')[:10] + context['comment_list'] = (Comment.objects.vetted() + .filter(Q(commentary__isnull=False) | + Q(submission__isnull=False) | + Q(thesislink__isnull=False)) + .select_related('author__user', 'submission', 'commentary') + .order_by('-date_submitted')[:10]) # Form into the context! context['form'] = self.form diff --git a/comments/admin.py b/comments/admin.py index 69da3613e39f4bcc268141a5f3cab8d80e60e575..ac6a36e65aab47674d8579434abd6d721b104d8f 100644 --- a/comments/admin.py +++ b/comments/admin.py @@ -1,10 +1,19 @@ from django.contrib import admin -from comments.models import Comment +from .constants import STATUS_VETTED +from .models import Comment + + +def comment_is_vetted(comment): + '''Check if comment is vetted.''' + return comment.status is STATUS_VETTED class CommentAdmin(admin.ModelAdmin): - search_fields = ['comment_text', 'author__user__last_name'] + list_display = ('comment_text', 'author', 'date_submitted', comment_is_vetted) + date_hierarchy = 'date_submitted' + list_filter = ('status',) + comment_is_vetted.boolean = True admin.site.register(Comment, CommentAdmin) diff --git a/comments/constants.py b/comments/constants.py index 9361790ed061dcd64341a532a3920e7a000b708e..3b3cdcc44efc65dbf0c861ce2fb40c067464def7 100644 --- a/comments/constants.py +++ b/comments/constants.py @@ -1,3 +1,43 @@ EXTENTIONS_IMAGES = ['.jpg', '.png'] EXTENTIONS_PDF = ['.pdf'] EXTENTIONS_FILES = EXTENTIONS_PDF + EXTENTIONS_IMAGES + +STATUS_VETTED = 1 +STATUS_PENDING = 0 +STATUS_UNCLEAR = -1 +STATUS_INCORRECT = -2 +STATUS_NOT_USEFUL = -3 +COMMENT_STATUS = ( + (STATUS_VETTED, 'vetted'), + (STATUS_PENDING, 'not yet vetted (pending)'), + (STATUS_UNCLEAR, 'rejected (unclear)'), + (STATUS_INCORRECT, 'rejected (incorrect)'), + (STATUS_NOT_USEFUL, 'rejected (not useful)'), +) + +COMMENT_CATEGORIES = ( + ('ERR', 'erratum'), + ('REM', 'remark'), + ('QUE', 'question'), + ('ANS', 'answer to question'), + ('OBJ', 'objection'), + ('REP', 'reply to objection'), + ('VAL', 'validation or rederivation'), + ('LIT', 'pointer to related literature'), + ('SUG', 'suggestion for further work'), +) + +COMMENT_ACTION_ACCEPT = 1 +COMMENT_ACTION_REFUSE = 2 +COMMENT_ACTION_CHOICES = ( + (COMMENT_ACTION_ACCEPT, 'accept'), + (COMMENT_ACTION_REFUSE, 'refuse (give reason below)'), +) + +COMMENT_REFUSAL_EMPTY = 0 +COMMENT_REFUSAL_CHOICES = ( + (COMMENT_REFUSAL_EMPTY, '-'), + (STATUS_UNCLEAR, 'unclear'), + (STATUS_INCORRECT, 'incorrect'), + (STATUS_NOT_USEFUL, 'not useful'), +) diff --git a/comments/forms.py b/comments/forms.py index f38c9d933f5b177150cb4f43263c983d41c94c8b..8aace94b0c36586c54abc63509f04588f093ff64 100644 --- a/comments/forms.py +++ b/comments/forms.py @@ -1,25 +1,12 @@ from django import forms +from .constants import COMMENT_ACTION_CHOICES, COMMENT_REFUSAL_CHOICES from .models import Comment from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Div, Field, Fieldset, HTML, Submit -COMMENT_ACTION_CHOICES = ( - (1, 'accept'), - (2, 'refuse (give reason below)'), - ) - -COMMENT_REFUSAL_CHOICES = ( - (0, '-'), - (-1, 'unclear'), - (-2, 'incorrect'), - (-3, 'not useful'), - ) -comment_refusal_dict = dict(COMMENT_REFUSAL_CHOICES) - - class CommentForm(forms.ModelForm): class Meta: model = Comment @@ -52,7 +39,8 @@ class CommentForm(forms.ModelForm): style="border: 0px; font-size: 90%"), HTML('<br>'), Div( - Submit('submit', 'Submit your Comment for vetting', css_class="submitButton"), + Submit('submit', 'Submit your Comment for vetting', + css_class="submitButton"), HTML('<p id="goodCommenter"><i>By clicking on Submit, you agree with the ' '<a href="{% url \'scipost:terms_and_conditions\' %}">' 'Terms and Conditions</a>.</i></p>'), diff --git a/comments/migrations/0011_auto_20170326_1447.py b/comments/migrations/0011_auto_20170326_1447.py new file mode 100644 index 0000000000000000000000000000000000000000..1876386c04b0a56d15ff52eaa7437a906b2b443a --- /dev/null +++ b/comments/migrations/0011_auto_20170326_1447.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.3 on 2017-03-26 12:47 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('comments', '0010_auto_20170219_1006'), + ] + + operations = [ + migrations.AlterField( + model_name='comment', + name='in_reply_to_comment', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='nested_comments', to='comments.Comment'), + ), + migrations.AlterField( + model_name='comment', + name='status', + field=models.SmallIntegerField(choices=[(1, 'vetted'), (0, 'not yet vetted (pending)'), (-1, 'rejected (unclear)'), (-2, 'rejected (incorrect)'), (-3, 'rejected (not useful)')], default=0), + ), + ] diff --git a/comments/models.py b/comments/models.py index 3851d0737a0a93519a09ae986e63be0dad6498f5..b003cc8ab6453183c4ea36257b49f979700318cd 100644 --- a/comments/models.py +++ b/comments/models.py @@ -1,44 +1,22 @@ from django.db import models from django.shortcuts import get_object_or_404 -from django.template import Template, Context -from django.utils.safestring import mark_safe - -from .behaviors import validate_file_extension, validate_max_file_size from commentaries.models import Commentary -from scipost.models import TimeStampedModel, Contributor +from scipost.behaviors import TimeStampedModel +from scipost.models import Contributor from submissions.models import Submission, Report from theses.models import ThesisLink +from .behaviors import validate_file_extension, validate_max_file_size +from .constants import COMMENT_STATUS, STATUS_PENDING from .managers import CommentManager -COMMENT_CATEGORIES = ( - ('ERR', 'erratum'), - ('REM', 'remark'), - ('QUE', 'question'), - ('ANS', 'answer to question'), - ('OBJ', 'objection'), - ('REP', 'reply to objection'), - ('VAL', 'validation or rederivation'), - ('LIT', 'pointer to related literature'), - ('SUG', 'suggestion for further work'), - ) - -COMMENT_STATUS = ( - (1, 'vetted'), - (0, 'not yet vetted (pending)'), - (-1, 'rejected (unclear)'), - (-2, 'rejected (incorrect)'), - (-3, 'rejected (not useful)'), -) -comment_status_dict = dict(COMMENT_STATUS) - class Comment(TimeStampedModel): """ A Comment is an unsollicited note, submitted by a Contributor, on a particular publication or in reply to an earlier Comment. """ - status = models.SmallIntegerField(default=0) + status = models.SmallIntegerField(default=STATUS_PENDING, choices=COMMENT_STATUS) vetted_by = models.ForeignKey( Contributor, blank=True, @@ -48,16 +26,18 @@ class Comment(TimeStampedModel): ) file_attachment = models.FileField( upload_to='uploads/comments/%Y/%m/%d/', blank=True, - validators=[validate_file_extension, - validate_max_file_size] + validators=[validate_file_extension, validate_max_file_size] ) # a Comment is either for a Commentary or Submission or a ThesisLink. commentary = models.ForeignKey(Commentary, blank=True, null=True, on_delete=models.CASCADE) submission = models.ForeignKey(Submission, blank=True, null=True, on_delete=models.CASCADE) thesislink = models.ForeignKey(ThesisLink, blank=True, null=True, on_delete=models.CASCADE) is_author_reply = models.BooleanField(default=False) - in_reply_to_comment = models.ForeignKey('self', blank=True, null=True, on_delete=models.CASCADE) - in_reply_to_report = models.ForeignKey(Report, blank=True, null=True, on_delete=models.CASCADE) + in_reply_to_comment = models.ForeignKey('self', blank=True, null=True, + related_name="nested_comments", + on_delete=models.CASCADE) + in_reply_to_report = models.ForeignKey(Report, blank=True, null=True, + on_delete=models.CASCADE) author = models.ForeignKey(Contributor, on_delete=models.CASCADE) anonymous = models.BooleanField(default=False, verbose_name='Publish anonymously') # Categories: @@ -71,7 +51,8 @@ class Comment(TimeStampedModel): is_lit = models.BooleanField(default=False, verbose_name='pointer to related literature') is_sug = models.BooleanField(default=False, verbose_name='suggestion for further work') comment_text = models.TextField() - remarks_for_editors = models.TextField(default='', blank=True, verbose_name='optional remarks for the Editors only') + remarks_for_editors = models.TextField(default='', blank=True, + verbose_name='optional remarks for the Editors only') date_submitted = models.DateTimeField('date submitted') # Opinions nr_A = models.PositiveIntegerField(default=0) @@ -84,12 +65,26 @@ class Comment(TimeStampedModel): related_name='in_disagreement', blank=True ) + objects = CommentManager() def __str__(self): return ('by ' + self.author.user.first_name + ' ' + self.author.user.last_name + ' on ' + self.date_submitted.strftime('%Y-%m-%d') + ', ' + self.comment_text[:30]) + def get_author(self): + '''Get author, if and only if comment is not anonymous!!!''' + if not self.anonymous: + return self.author + return None + + def get_author_str(self): + '''Get author string, if and only if comment is not anonymous!!!''' + author = self.get_author() + if author: + return author.user.first_name + ' ' + author.user.last_name + return 'Anonymous' + def update_opinions(self, contributor_id, opinion): contributor = get_object_or_404(Contributor, pk=contributor_id) self.in_agreement.remove(contributor) @@ -105,234 +100,3 @@ class Comment(TimeStampedModel): self.nr_N = self.in_notsure.count() self.nr_D = self.in_disagreement.count() self.save() - - def opinions_as_ul(self): - template = Template(''' - <ul class="opinionsDisplay"> - <li style="background-color: #000099">Agree {{ nr_A }}</li> - <li style="background-color: #555555">Not sure {{ nr_N }}</li> - <li style="background-color: #990000">Disagree {{ nr_D }}</li> - </ul> - ''') - context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D}) - return template.render(context) - - def opinions_as_ul_tiny(self): - template = Template(''' - <ul class="opinionsDisplay"> - <li style="background-color: #000099; font-size: 8px; padding: 2px;">Agree {{ nr_A }}</li> - <li style="background-color: #555555; font-size: 8px; padding: 2px;">Not sure {{ nr_N }}</li> - <li style="background-color: #990000; font-size: 8px; padding: 2px;">Disagree {{ nr_D }}</li> - </ul> - ''') - context = Context({'nr_A': self.nr_A, 'nr_N': self.nr_N, 'nr_D': self.nr_D}) - return template.render(context) - - def print_identifier(self): - # for display - output = '<div class="commentid">\n' - output += '<h3><a id="comment_id{{ id }}"></a>' - context = Context({'id': self.id}) - if self.is_author_reply: - output += 'Author ' - if not self.anonymous: - output += (' <a href="/contributor/{{ author_id }}">' - + '{{ first_name }} {{ last_name }}</a> on ') - context['author_id'] = self.author.id - context['first_name'] = self.author.user.first_name - context['last_name'] = self.author.user.last_name - output += '{{ date_comment_submitted }}' - context['date_comment_submitted'] = self.date_submitted.strftime("%Y-%m-%d") - if self.in_reply_to_comment: - output += (' (in reply to <a href="#comment_id{{ in_reply_to_comment_id }}">' - '{{ in_reply_to_comment_first_name }} ' - '{{ in_reply_to_comment_last_name }} on ' - '{{ in_reply_to_comment_date }}</a>)') - context['in_reply_to_comment_id'] = self.in_reply_to_comment_id - context['in_reply_to_comment_first_name'] = (self.in_reply_to_comment - .author.user.first_name) - context['in_reply_to_comment_last_name'] = (self.in_reply_to_comment - .author.user.last_name) - context['in_reply_to_comment_date'] = (self.in_reply_to_comment - .date_submitted.strftime("%Y-%m-%d")) - elif self.in_reply_to_report: - output += ' (in reply to <a href="#report_id{{ in_reply_to_report_id }}">' - context['in_reply_to_report_id'] = self.in_reply_to_report_id - if not self.in_reply_to_report.anonymous: - output += '{{ in_reply_to_report_first_name }} {{ in_reply_to_report_last_name}}' - context['in_reply_to_report_first_name'] = (self.in_reply_to_report - .author.user.first_name) - context['in_reply_to_report_last_name'] = (self.in_reply_to_report - .author.user.last_name) - else: - output += 'Report {{ in_reply_to_report_id }}' - context['in_reply_to_report_id'] = self.in_reply_to_report_id - output += ' on {{ date_report_submitted }}</a>)' - context['date_report_submitted'] = self.in_reply_to_report.date_submitted.strftime( - "%Y-%m-%d") - output += '</h3></div>' - template = Template(output) - return template.render(context) - - def print_identifier_for_vetting(self): - # for display, same as print_identifier but named even if anonymous, not linked - output = '<div class="commentid">\n' - output += '<h3>' - context = Context() - if self.is_author_reply: - output += 'Author ' - output += ' <a href="/contributor/{{ author_id }}">{{ first_name }} {{ last_name }}</a>' - context['author_id'] = self.author.id - context['first_name'] = self.author.user.first_name - context['last_name'] = self.author.user.last_name - output += ' on {{ date_submitted }}' - context['date_submitted'] = self.date_submitted.strftime("%Y-%m-%d") - if self.in_reply_to_comment: - output += (' (in reply to <a href="#comment_id{{ in_reply_to_comment_id }}">' - '{{ in_reply_to_comment_first_name }} {{ in_reply_to_comment_last_name }} ' - 'on {{ in_reply_to_comment_date }}</a>)') - context['in_reply_to_comment_id'] = self.in_reply_to_comment_id - context['in_reply_to_comment_first_name'] = (self.in_reply_to_comment - .author.user.first_name) - context['in_reply_to_comment_last_name'] = (self.in_reply_to_comment - .author.user.last_name) - context['in_reply_to_comment_date'] = (self.in_reply_to_comment - .date_submitted.strftime("%Y-%m-%d")) - elif self.in_reply_to_report: - output += ' (in reply to <a href="#report_id{{ in_reply_to_report_id }}">' - context['in_reply_to_report_id'] = self.in_reply_to_report_id - if not self.in_reply_to_report.anonymous: - output += '{{ in_reply_to_report_first_name }} {{ in_reply_to_report_last_name}}' - context['in_reply_to_report_first_name'] = (self.in_reply_to_report - .author.user.first_name) - context['in_reply_to_report_last_name'] = (self.in_reply_to_report - .author.user.last_name) - else: - output += 'Report {{ in_reply_to_report_id }}' - context['in_reply_to_report_id'] = self.in_reply_to_report_id - output += '</a> on {{ date_submitted }})' - context['date_submitted'] = self.in_reply_to_report.date_submitted.strftime("%Y-%m-%d") - output += '</h3></div>' - template = Template(output) - return template.render(context) - - def header_as_li(self): - # for search lists - header = '<li>' - # header += '<div class="flex-container"><div class="flex-whitebox0">' - header += 'Nr {{ id }}' - context = Context({'id': self.id}) - header += ', <div class="opinionsDisplay">' + self.opinions_as_ul_tiny() + '</div>' - if self.status <= 0: - header += (', status: <span style="color:red">' - + comment_status_dict[self.status] + '</span>') - text_cut = self.comment_text[:50] - if len(self.comment_text) > 50: - text_cut += '...' - context['id'] = self.id - context['text_cut'] = text_cut - context['date_submitted'] = self.date_submitted.strftime("%Y-%m-%d") - header += ': ' - if not self.anonymous: - header += (' <a href="/contributor/{{ author_id }}">' - '{{ first_name }} {{ last_name }}</a>, ') - context['author_id'] = self.author.id - context['first_name'] = self.author.user.first_name - context['last_name'] = self.author.user.last_name - if self.submission is not None: - header += ('<a href="/submission/{{ arxiv_identifier_w_vn_nr }}#comment_id{{ id }}">' - ' \"{{ text_cut }}\"</a><p>submitted on {{ date_submitted }}') - header += (' in submission on <a href="/submission/{{ arxiv_identifier_w_vn_nr }}"' - ' class="pubtitleli">{{ submission_title }}</a> by ' - '{{ submission_author_list }}</p>') - context['arxiv_identifier_w_vn_nr'] = self.submission.arxiv_identifier_w_vn_nr - context['submission_title'] = self.submission.title - context['submission_author_list'] = self.submission.author_list - if self.commentary is not None: - header += ('<a href="/commentary/{{ commentary_url }}#comment_id{{ id }}">' - ' \"{{ text_cut }}\"</a><p>submitted on {{ date_submitted }}') - header += (' in commentary on <a href="/commentary/{{ commentary_url }}"' - ' class="pubtitleli">' - '{{ commentary_pub_title }}</a> by {{ commentary_author_list }}</p>') - context['commentary_url'] = self.commentary.arxiv_or_DOI_string - context['commentary_pub_title'] = self.commentary.pub_title - context['commentary_author_list'] = self.commentary.author_list - if self.thesislink is not None: - header += ('<a href="/thesis/{{ thesislink_id }}#comment_id{{ id }}">' - ' \"{{ text_cut }}\"</a><p>submitted on {{ date_submitted }}') - header += (' in thesislink on ' - '<a href="/thesis/{{ thesislink_id }}" class="pubtitleli">' - '{{ thesislink_title }}</a> by {{ thesislink_author }}</p>') - context['thesislink_id'] = self.thesislink.id - context['thesislink_title'] = self.thesislink.title - context['thesislink_author'] = self.thesislink.author - # header += '</div></div>' - header += '</li>' - template = Template(header) - return template.render(context) - - def simple_header_as_li(self): - # for Lists - header = '<li>' - # header += '<div class="flex-container"><div class="flex-whitebox0">' - context = Context({}) - text_cut = self.comment_text[:30] - if len(self.comment_text) > 30: - text_cut += '...' - context['text_cut'] = text_cut - if not self.anonymous: - header += ' <a href="/contributor/{{ author_id }}">{{ first_name }} {{ last_name }}</a>, ' - context['author_id'] = self.author.id - context['first_name'] = self.author.user.first_name - context['last_name'] = self.author.user.last_name - if self.submission is not None: - header += ('<a href="/submission/{{ arxiv_identifier_w_vn_nr }}#comment_id{{ id }}"> ' - '\"{{ text_cut }}\"</a>' - ' in submission on <a href="/submission/{{ arxiv_identifier_w_vn_nr }}" class="pubtitleli">' - '{{ submission_title }}</a> by {{ submission_author_list }}</p>') - context['arxiv_identifier_w_vn_nr'] = self.submission.arxiv_identifier_w_vn_nr - context['submission_title'] = self.submission.title - context['submission_author_list'] = self.submission.author_list - if self.commentary is not None: - header += ('<a href="/commentary/{{ commentary_url }}#comment_id{{ id }}"> ' - '\"{{ text_cut }}\"</a>' - ' in commentary on <a href="/commentary/{{ commentary_url }}" class="pubtitleli">' - '{{ commentary_pub_title }}</a> by {{ commentary_author_list }}</p>') - context['commentary_url'] = self.commentary.arxiv_or_DOI_string - context['commentary_pub_title'] = self.commentary.pub_title - context['commentary_author_list'] = self.commentary.author_list - if self.thesislink is not None: - header += '<a href="/thesis/{{ thesislink_id }}#comment_id{{ id }}"> \"{{ text_cut }}\"</a>' - header += (' in thesislink on ' - '<a href="/thesis/{{ thesislink_id }}" class="pubtitleli">' - '{{ thesislink_title }}</a> by {{ thesislink_author }}</p>') - context['thesislink_id'] = self.thesislink.id - context['thesislink_title'] = self.thesislink.title - context['thesislink_author'] = self.thesislink.author - # header += '</div></div>' - header += '</li>' - template = Template(header) - return template.render(context) - - def categories_as_ul(self): - output = '<div class="commentcategorydisplay"><h4>Category:</h4><ul>' - if self.is_rem: - output += '<li>remark</li>' - if self.is_que: - output += '<li>question</li>' - if self.is_ans: - output += '<li>answer to question</li>' - if self.is_obj: - output += '<li>objection</li>' - if self.is_rep: - output += '<li>reply to objection</li>' - if self.is_cor: - output += '<li>correction</li>' - if self.is_val: - output += '<li>validation or rederivation</li>' - if self.is_lit: - output += '<li>pointer to related literature</li>' - if self.is_sug: - output += '<li>suggestion for further work</li>' - output += '</ul></div>' - return mark_safe(output) diff --git a/comments/templates/comments/_add_comment_form.html b/comments/templates/comments/_add_comment_form.html new file mode 100644 index 0000000000000000000000000000000000000000..aa5a8bd0abe0f8b1d1b5c64899c88de47f3f9552 --- /dev/null +++ b/comments/templates/comments/_add_comment_form.html @@ -0,0 +1,35 @@ +<script> + $(document).ready(function(){ + + var comment_text_input = $("#id_comment_text"); + + function set_comment_text(value) { + $("#preview-comment_text").text(value) + } + set_comment_text(comment_text_input.val()) + + comment_text_input.keyup(function(){ + var new_text = $(this).val() + set_comment_text(new_text) + MathJax.Hub.Queue(["Typeset",MathJax.Hub]); + }) + + }); +</script> + +<div class="row"> + <div class="col-12"> + <form enctype="multipart/form-data" action="{{url}}" method="post"> + {% csrf_token %} + {% load crispy_forms_tags %} + {% crispy form %} + </form> + </div> +</div> + +<div class="row"> + <div class="col-md-10"> + <h3>Preview of your comment:</h3> + <p id="preview-comment_text"></p> + </div> +</div> diff --git a/comments/templates/comments/_comment_card_content.html b/comments/templates/comments/_comment_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..fba6a0aee5a47323a4c8a44090b04290a72b5f62 --- /dev/null +++ b/comments/templates/comments/_comment_card_content.html @@ -0,0 +1,31 @@ +<div class="card-block card-comment"> + {% block card_block_header %}{% endblock %} + <p class="card-text"> + <span class="text-blue"> + <a href="{% if comment.get_author %}{% url 'scipost:contributor_info' comment.get_author.id %}{% else %}javascript:;{% endif %}">{{comment.get_author_str}}</a>: + </span> + + {% if comment.submission %} + <a href="{% url 'submissions:submission' comment.submission.arxiv_identifier_w_vn_nr %}#comment_id{{comment.id}}"> + "{{comment.comment_text|slice:'30'}}{% if comment.comment_text|length > 30 %}...{% endif %}" + </a> + </p><p class="card-text pl-md-3"> + in submission on <a href="{% url 'submissions:submission' comment.submission.arxiv_identifier_w_vn_nr %}" class="pubtitleli">{{comment.submission.title}}</a> + <span class="text-muted">by {{comment.submission.author_list}}</span> + {% elif comment.commentary %} + <a href="{% url 'commentaries:commentary' comment.commentary.arxiv_or_DOI_string %}#comment_id{{comment.id}}"> + "{{comment.comment_text|slice:'30'}}{% if comment.comment_text|length > 30 %}...{% endif %}" + </a> + </p><p class="card-text pl-md-3"> + in commentary on <a href="{% url 'commentaries:commentary' comment.commentary.arxiv_or_DOI_string %}" class="pubtitleli">{{comment.commentary.pub_title}}</a> + <span class="text-muted">by {{comment.commentary.author_list}}</span> + {% elif comment.thesislink %} + <a href="{% url 'theses:thesis' comment.thesislink.id %}#comment_id{{comment.id}}"> + "{{comment.comment_text|slice:'30'}}{% if comment.comment_text|length > 30 %}...{% endif %}" + </a> + </p><p class="card-text pl-md-3"> + in thesislink on <a href="{% url 'theses:thesis' comment.thesislink.id %}" class="pubtitleli">{{comment.thesislink.title}}</a> + <span class="text-muted">by {{ comment.thesislink.author }}</span> + {% endif %} + </p> +</div> diff --git a/comments/templates/comments/_comment_card_extended_content.html b/comments/templates/comments/_comment_card_extended_content.html new file mode 100644 index 0000000000000000000000000000000000000000..168b2eef9c649099eef5062d4a35d3fa13f56004 --- /dev/null +++ b/comments/templates/comments/_comment_card_extended_content.html @@ -0,0 +1,8 @@ +{% extends 'comments/_comment_card_content.html' %} + +{% block card_block_header %} + <div class="mb-2"> + <div class="d-inline-block mr-1">Nr {{comment.id}}</div> + {% include 'comments/_comment_voting_summary.html' with comment=comment class='small' %} + </div> +{% endblock %} diff --git a/comments/templates/comments/_comment_categories.html b/comments/templates/comments/_comment_categories.html new file mode 100644 index 0000000000000000000000000000000000000000..fec5707adee9e21640e36ce5c4d8208df2ee2893 --- /dev/null +++ b/comments/templates/comments/_comment_categories.html @@ -0,0 +1,30 @@ +<div class="btn-group category-group {{class}}"> + <label class="btn btn-secondary name">Category:</label> + {% if comment.is_rem %} + <label class="btn btn-secondary"><span class="inner">remark</spin></label> + {% endif %} + {% if comment.is_que %} + <label class="btn btn-secondary"><span class="inner">question</spin></label> + {% endif %} + {% if comment.is_ans %} + <label class="btn btn-secondary"><span class="inner">answer to question</spin></label> + {% endif %} + {% if comment.is_obj %} + <label class="btn btn-secondary"><span class="inner">objection</spin></label> + {% endif %} + {% if comment.is_rep %} + <label class="btn btn-secondary"><span class="inner">reply to objection</spin></label> + {% endif %} + {% if comment.is_cor %} + <label class="btn btn-secondary"><span class="inner">correction</spin></label> + {% endif %} + {% if comment.is_val %} + <label class="btn btn-secondary"><span class="inner">validation or rederivation</spin></label> + {% endif %} + {% if comment.is_lit %} + <label class="btn btn-secondary"><span class="inner">pointer to related literature</spin></label> + {% endif %} + {% if comment.is_sug %} + <label class="btn btn-secondary"><span class="inner">suggestion for further work</spin></label> + {% endif %} +</div> diff --git a/comments/templates/comments/_comment_identifier.html b/comments/templates/comments/_comment_identifier.html new file mode 100644 index 0000000000000000000000000000000000000000..3407a7c0bdd69ec7dc9a6b8b613de50112a87dd9 --- /dev/null +++ b/comments/templates/comments/_comment_identifier.html @@ -0,0 +1,30 @@ +<div class="commentid" id="comment_id{{comment.id}}"> + <h3> + {% if comment.is_author_reply %}Author{% endif %} + + {% block comment_author %} + {% if not comment.anonymous %} + <a href="{% url 'scipost:contributor_info' comment.get_author.id %}">{{comment.get_author_str}}</a> + {% else %} + Anonymous + {% endif %} + {% endblock comment_author %} + on {{comment.date_submitted|date:'Y-m-d'}} + </h3> + <h4> + {% if comment.in_reply_to_comment %} + (in reply to <a href="#comment_id{{comment.in_reply_to_comment.id}}">{{comment.in_reply_to_comment.comment.get_author_str}}</a> on {{comment.in_reply_to_comment.date_submitted|date:'Y-m-d'}}) + {% elif comment.in_reply_to_report %} + (in reply to <a href="#report_id{{comment.in_reply_to_report.id}}"> + + {% if not comment.in_reply_to_report.anonymous %} + {{comment.in_reply_to_report.get_author_str}} + {% else %} + Report {{comment.in_reply_to_report.id}} + {% endif %} + + </a> on {{comment.in_reply_to_report.date_submitted|date:'Y-m-d'}}) + {% endif %} + + </h4> +</div> diff --git a/comments/templates/comments/_comment_identifier_vetting.html b/comments/templates/comments/_comment_identifier_vetting.html new file mode 100644 index 0000000000000000000000000000000000000000..edf903c7eac54853e71e69c30c5640d01262bf42 --- /dev/null +++ b/comments/templates/comments/_comment_identifier_vetting.html @@ -0,0 +1,12 @@ +{% extends 'comments/_comment_identifier.html' %} + +{% comment %} + + Be careful using this template!!! + It overwrites the anonymity of the writer! + +{% endcomment %} + +{% block comment_author %} + <a href="{% url 'scipost:contributor_info' comment.author.id %}">{{comment.author.user.first_name}} {{comment.author.user.last_name}}</a> +{% endblock comment_author %} diff --git a/comments/templates/comments/_comment_voting_form.html b/comments/templates/comments/_comment_voting_form.html new file mode 100644 index 0000000000000000000000000000000000000000..1563284d7cfd90111e4864b04809f642d3d05b47 --- /dev/null +++ b/comments/templates/comments/_comment_voting_form.html @@ -0,0 +1,20 @@ +{% if user.is_authenticated and perms.scipost.can_express_opinion_on_comments %} + {% if user.contributor != comment.author %} + <div class="btn-group voting-group {{class}}"> + <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='A' %}" method="post"> + {% csrf_token %} + <input type="submit" class="btn agree" value="Agree {{ comment.nr_A }}"/> + </form> + <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='N' %}" method="post"> + {% csrf_token %} + <input type="submit" class="btn neutral" value="Not sure {{ comment.nr_N }}"/> + </form> + <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='D'%}" method="post"> + {% csrf_token %} + <input type="submit" class="btn disagree" value="Disagree {{ comment.nr_D }}"/> + </form> + </div> + {% else %} + {% include 'comments/_comment_voting_summary.html' with comment=comment %} + {% endif %} +{% endif %} diff --git a/comments/templates/comments/_comment_voting_summary.html b/comments/templates/comments/_comment_voting_summary.html new file mode 100644 index 0000000000000000000000000000000000000000..b57fb55e3572fd01a3b6698ba201dc737dda0077 --- /dev/null +++ b/comments/templates/comments/_comment_voting_summary.html @@ -0,0 +1,5 @@ +<div class="btn-group voting-group {{class}}"> + <label class="btn agree">Agree {{ comment.nr_A }}</label> + <label class="btn neutral">Not sure {{ comment.nr_N }}</label> + <label class="btn disagree">Disagree {{ comment.nr_D }}</label> +</div> diff --git a/comments/templates/comments/_single_comment.html b/comments/templates/comments/_single_comment.html new file mode 100644 index 0000000000000000000000000000000000000000..1eaaf85a016bf09f61c8b349bd7339cbae35e843 --- /dev/null +++ b/comments/templates/comments/_single_comment.html @@ -0,0 +1,54 @@ +{% load scipost_extras %} +{% load filename %} +{% load file_extentions %} + +<div class="row"> + <div class="col-12"> + <div class="comment" id="comment_id{{comment.id}}"> + + <div class="row"> + <div class="col-12"> + {% include 'comments/_comment_identifier.html' with comment=comment %} + + {% include 'comments/_comment_categories.html' with comment=comment class='mr-2' %} + + {% include 'comments/_comment_voting_form.html' with comment=comment perms=perms user=user %} + </div> + </div> + + + <div class="row"> + <div class="col-12"> + <p> + {{ comment.comment_text|linebreaks }} + + {% if comment.file_attachment %} + <h3>Attachment:</h3> + <p> + <a target="_blank" href="{{ comment.file_attachment.url }}"> + {% if comment.file_attachment|is_image %} + <img class="attachment attachment-comment" src="{{ comment.file_attachment.url }}"> + {% else %} + {{ comment.file_attachment|filename }}<br><small>{{ comment.file_attachment.size|filesizeformat }}</small> + {% endif %} + </a> + </p> + {% endif %} + </p> + {% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' %} + {% if comment.remarks_for_editors %} + <h3>Remarks for editors:</h3> + <p>{{ comment.remarks_for_editors|linebreaks }}</p> + {% endif %} + {% endif %} + </div> + </div> + + {% for reply in comment.nested_comments.vetted %} + {% include 'comments/_single_comment.html' with comment=reply perms=perms user=user %} + {% endfor %} + + {% block comment_footer %}{% endblock %} + </div> + </div> +</div> diff --git a/comments/templates/comments/_single_comment_with_link.html b/comments/templates/comments/_single_comment_with_link.html new file mode 100644 index 0000000000000000000000000000000000000000..06cf9a4b95f2bb72bfe3d90b5ed87eac4b8e0b73 --- /dev/null +++ b/comments/templates/comments/_single_comment_with_link.html @@ -0,0 +1,12 @@ +{% extends 'comments/_single_comment.html' %} + +{% block comment_footer %} + {% if user.is_authenticated and perms.scipost.can_submit_comments %} + <hr class="small"> + <div class="row"> + <div class="col-12"> + <h3><a href="{% url 'comments:reply_to_comment' comment_id=comment.id %}">Reply to this comment</a></h3> + </div> + </div> + {% endif %} +{% endblock %} diff --git a/comments/templates/comments/reply_to_comment.html b/comments/templates/comments/reply_to_comment.html index a31a2a92d8160f143c72c1e9dca36a81c275ccaa..3937e5d0051a557def52eb7728998e2b5f0ccbf3 100644 --- a/comments/templates/comments/reply_to_comment.html +++ b/comments/templates/comments/reply_to_comment.html @@ -4,32 +4,10 @@ {% block content %} -<script> - $(document).ready(function(){ - - var comment_text_input = $("#id_comment_text"); - - function set_comment_text(value) { - $("#preview-comment_text").text(value) - } - set_comment_text(comment_text_input.val()) - - comment_text_input.keyup(function(){ - var new_text = $(this).val() - set_comment_text(new_text) - MathJax.Hub.Queue(["Typeset",MathJax.Hub]); - }) - - }); -</script> - - {% if user.is_authenticated %} <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>SciPost Reply to Comment Page</h1> - </div> + <h1 class="highlight">SciPost Reply to Comment Page</h1> </div> </div> @@ -37,7 +15,7 @@ <div class="col-12"> {% if comment.commentary %} <h2>The Commentary concerned:</h2> - {{ comment.commentary.header_as_table }} + {% include 'commentaries/_commentary_summary.html' with commentary=comment.commentary %} <h3 class="mt-3">Abstract:</h3> <p>{{ comment.commentary.pub_abstract }}</p> @@ -45,21 +23,18 @@ {% if comment.submission %} <h2>The Submission concerned:</h2> - {{ comment.submission.header_as_table }} - <h3 class="mt-3">Abstract:</h3> - <p>{{ comment.submission.abstract }}</p> + {% include 'submissions/_submission_summary.html' with submission=comment.submission %} + {% endif %} {% if comment.thesislink %} <h2>The Thesis concerned:</h2> - {% include "theses/_header_as_table.html" with thesislink=comment.thesislink %} - - <h3 class="mt-3">Abstract:</h3> - <p>{{ comment.thesislink.abstract }}</p> + {% include "theses/_thesislink_information.html" with thesislink=comment.thesislink %} {% endif %} </div> </div> + <div class="row"> <div class="col-12"> <h2>The Comment you wish to reply to:</h2> @@ -68,11 +43,11 @@ <div class="row"> <div class="col-12"> <div class="comment"> - {{ comment.print_identifier }} - {{ comment.categories_as_ul }} - <div class="opinionsDisplay"> - {{ comment.opinions_as_ul }} - </div> + {% include 'comments/_comment_identifier.html' with comment=comment %} + + {% include 'comments/_comment_categories.html' with comment=comment class='mr-2' %} + + {% include 'comments/_comment_voting_summary.html' with comment=comment %} <p>{{ comment.comment_text|linebreaks }}</p> </div> @@ -83,33 +58,21 @@ <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Your Reply to this Comment:</h2> - {% if is_author %} - <h3>(you are identified as an author, your reply will appear as an author reply)</h3> - {% else %} - <h3>(you are not identified as an author of this publication; if you are, you can claim authorship on your Personal Page)</h3> - {% endif %} + <div class="card card-grey"> + <div class="card-block"> + <h2>Your Reply to this Comment:</h2> + {% if is_author %} + <h3>(you are identified as an author, your reply will appear as an author reply)</h3> + {% else %} + <h3>(you are not identified as an author of this publication; if you are, you can claim authorship on your Personal Page)</h3> + {% endif %} + </div> </div> </div> </div> - <div class="row"> - <div class="col-12"> - <form enctype="multipart/form-data" action="{% url 'comments:reply_to_comment' comment.id %}" method="post"> - {% csrf_token %} - {% load crispy_forms_tags %} - {% crispy form %} - </form> - </div> - </div> - - <div class="row"> - <div class="col-12"> - <h3>Preview of your comment:</h3> - <p id="preview-comment_text"></p> - </div> - </div> + {% url 'comments:reply_to_comment' comment.id as add_comment_url %} + {% include 'comments/_add_comment_form.html' with url=add_comment_url form=form %} {% endif %} diff --git a/comments/templates/comments/reply_to_report.html b/comments/templates/comments/reply_to_report.html index af123a74c633a67803b2dca89b2419e1846a709c..348d82701826f73a80777e21357ef24fbc042db9 100644 --- a/comments/templates/comments/reply_to_report.html +++ b/comments/templates/comments/reply_to_report.html @@ -2,70 +2,37 @@ {% block pagetitle %}: reply to report{% endblock pagetitle %} -{% block bodysup %} - -<script> - $(document).ready(function(){ - - var comment_text_input = $("#id_comment_text"); - - function set_comment_text(value) { - $("#preview-comment_text").text(value) - } - set_comment_text(comment_text_input.val()) - - comment_text_input.keyup(function(){ - var new_text = $(this).val() - set_comment_text(new_text) - MathJax.Hub.Queue(["Typeset",MathJax.Hub]); - }) - - }); -</script> - +{% block content %} {% if user.is_authenticated %} -<section> - <hr class="hr12"> - <h1>SciPost Reply to Report Page</h1> - - {% if not is_author %} - <h3>(you are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page)</h3> - {% else %} - - <hr class="hr12"> - <h1>The Submission concerned:</h1> - {{ report.submission.header_as_table }} - - <h3>Abstract:</h3> - <p>{{ report.submission.abstract }}</p> - <br> - - <hr class="hr6"> - <h2>The Report you wish to reply to:</h2> + <div class="row"> + <div class="col-12"> + <h1 class="highlight">SciPost Reply to Report Page</h1> + </div> + </div> - {{ report.print_identifier }} - {{ report.print_contents }} + <div class="row"> + <div class="col-12"> + {% if not is_author %} + <h2>(you are not identified as an author of this Submission; if you are, you can claim authorship on your Personal Page)</h2> + {% else %} + <h2>The Submission concerned:</h2> + {% include 'submissions/_submission_summary.html' with submission=report.submission %} - <hr class="hr6"> - <h1>Your Reply to this Report:</h1> + </div> + </div> - <form enctype="multipart/form-data" action="{% url 'comments:reply_to_report' report_id=report.id %}" method="post"> - {% csrf_token %} - {% load crispy_forms_tags %} - {% crispy form %} - </form> + {% include 'submissions/_single_public_report_without_comments.html' with report=report %} - <div class="row"> - <div class="col-10"> - <h3>Preview of your comment:</h3> - <p id="preview-comment_text"></p> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Your Reply to this Report:</h2> + {% url 'comments:reply_to_report' report_id=report.id as add_comment_url %} + {% include 'comments/_add_comment_form.html' with url=add_comment_url form=form %} + {% endif %} + </div> </div> - </div> - - {% endif %} -</section> {% endif %} -{% endblock bodysup %} +{% endblock content %} diff --git a/comments/templates/comments/vet_submitted_comments.html b/comments/templates/comments/vet_submitted_comments.html index 9300f1ff4820dee5f1385ee77386d714a13ee40d..e3a71b702cb6ab815ad2af54cf9abf1147506ad5 100644 --- a/comments/templates/comments/vet_submitted_comments.html +++ b/comments/templates/comments/vet_submitted_comments.html @@ -11,74 +11,79 @@ {% if not comments_to_vet %} <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>There are no comments for you to vet.</h1> - </div> + <h1 class="highlight">There are no comments for you to vet.</h1> </div> </div> {% else %} <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>SciPost Comments to vet:</h1> - </div> + <h1 class="highlight">SciPost Comments to vet:</h1> </div> </div> <div class="row"> - {% for comment_to_vet in comments_to_vet %} - <div class="col-12"> - {% if comment_to_vet.commentary %} - <h2>From Commentary (<a href="{% url 'commentaries:commentary' arxiv_or_DOI_string=comment_to_vet.commentary.arxiv_or_DOI_string %}">link</a>)</h2> - {{ comment_to_vet.commentary.header_as_table }} - <br /> - {% endif %} + <div class="col-12"> + {% for comment_to_vet in comments_to_vet %} + <div class="card card-vetting"> + <div class="card-header"> + + {% if comment_to_vet.commentary %} + <h2>From Commentary (<a href="{% url 'commentaries:commentary' arxiv_or_DOI_string=comment_to_vet.commentary.arxiv_or_DOI_string %}">link</a>)</h2> + {% include 'commentaries/_commentary_summary.html' with commentary=comment_to_vet.commentary %} + {% endif %} + + {% if comment_to_vet.submission %} + <h2>From Submission (<a href="{% url 'submissions:submission' arxiv_identifier_w_vn_nr=comment_to_vet.submission.arxiv_identifier_w_vn_nr %}">link</a>)</h2> + {% include 'submissions/_submission_summary_short.html' with submission=comment_to_vet.submission %} + {% endif %} + + {% if comment_to_vet.thesislink %} + <h2>From Thesis Link (<a href="{% url 'theses:thesis' comment_to_vet.thesislink.id %}">link</a>)</h2> + {% include 'theses/_thesislink_information.html' with thesislink=comment_to_vet.thesislink %} + {% endif %} + </div> + <div class="card-block"> - {% if comment_to_vet.submission %} - <h2>From Submission (<a href="{% url 'submissions:submission' arxiv_identifier_w_vn_nr=comment_to_vet.submission.arxiv_identifier_w_vn_nr %}">link</a>)</h2> - {{ comment_to_vet.submission.header_as_table }} - <br /> - {% endif %} + <h2 class="card-title">The Comment to be vetted:</h2> - <hr class="small"> - <h2>The Comment to be vetted:</h2> + <div class="row"> + <div class="col-md-6"> + {% include 'comments/_comment_identifier_vetting.html' with comment=comment_to_vet %} + <hr class="small"> - <div class="row"> - <div class="col-md-6"> - {{ comment_to_vet.print_identifier_for_vetting }} - <h3>Comment text:</h3> - <p>{{ comment_to_vet.comment_text }}</p> + <h3>Comment text:</h3> + <p>{{ comment_to_vet.comment_text }}</p> - {% if comment_to_vet.file_attachment %} - <h3>Attachment:</h3> - <p> - <a target="_blank" href="{{ comment_to_vet.file_attachment.url }}"> - {% if comment_to_vet.file_attachment|is_image %} - <img class="attachment attachment-comment" src="{{ comment_to_vet.file_attachment.url }}"> - {% else %} - {{ comment_to_vet.file_attachment|filename }}<br><small>{{ comment_to_vet.file_attachment.size|filesizeformat }}</small> + {% if comment_to_vet.file_attachment %} + <h3>Attachment:</h3> + <p> + <a target="_blank" href="{{ comment_to_vet.file_attachment.url }}"> + {% if comment_to_vet.file_attachment|is_image %} + <img class="attachment attachment-comment" src="{{ comment_to_vet.file_attachment.url }}"> + {% else %} + {{ comment_to_vet.file_attachment|filename }}<br><small>{{ comment_to_vet.file_attachment.size|filesizeformat }}</small> + {% endif %} + </a> + </p> {% endif %} - </a> - </p> - {% endif %} - {% if comment_to_vet.remarks_for_editors %} - <h3>Remarks for Editors only:</h3> - <p>{{ comment_to_vet.remarks_for_editors }}</p> - {% endif %} - </div> - <div class="col-md-6"> - <form action="{% url 'comments:vet_submitted_comment_ack' comment_id=comment_to_vet.id %}" method="post"> - {% csrf_token %} - {{ form|bootstrap }} - <input class="btn btn-primary" type="submit" value="Submit" /> - </form> + {% if comment_to_vet.remarks_for_editors %} + <h3>Remarks for Editors only:</h3> + <p>{{ comment_to_vet.remarks_for_editors }}</p> + {% endif %} + </div> + <div class="col-md-6"> + <form action="{% url 'comments:vet_submitted_comment_ack' comment_id=comment_to_vet.id %}" method="post"> + {% csrf_token %} + {{ form|bootstrap }} + <input class="btn btn-primary" type="submit" value="Submit" /> + </form> + </div> + </div> + </div> </div> - </div> - <hr> + {% endfor %} </div> - - {% endfor %} </div> {% endif %} diff --git a/comments/views.py b/comments/views.py index ce859b86553018a6788aee4a82472c71cfa388f8..af5577b3316f4f7d4508ebf52bf1a2e244d9a760 100644 --- a/comments/views.py +++ b/comments/views.py @@ -10,14 +10,15 @@ from django.http import HttpResponseRedirect, Http404 import strings from .models import Comment -from .forms import CommentForm, VetCommentForm, comment_refusal_dict +from .forms import CommentForm, VetCommentForm -from scipost.models import Contributor, title_dict +from scipost.models import Contributor from theses.models import ThesisLink from submissions.utils import SubmissionUtils from submissions.models import Submission, Report from commentaries.models import Commentary + @permission_required('scipost.can_submit_comments', raise_exception=True) def new_comment(request, **kwargs): if request.method == "POST": @@ -46,7 +47,7 @@ def new_comment(request, **kwargs): if not thesislink.open_for_commenting: raise PermissionDenied new_comment.thesislink = thesislink - redirect_link = reverse('theses:thesis', kwargs={"thesislink_id":thesislink.id}) + redirect_link = reverse('theses:thesis', kwargs={"thesislink_id": thesislink.id}) elif type_of_object == "submission": submission = Submission.objects.get(id=object_id) if not submission.open_for_commenting: @@ -62,7 +63,8 @@ def new_comment(request, **kwargs): raise PermissionDenied new_comment.commentary = commentary redirect_link = reverse( - 'commentaries:commentary', kwargs={'arxiv_or_DOI_string': commentary.arxiv_or_DOI_string} + 'commentaries:commentary', + kwargs={'arxiv_or_DOI_string': commentary.arxiv_or_DOI_string} ) new_comment.save() @@ -75,6 +77,7 @@ def new_comment(request, **kwargs): # This view is only accessible by POST request raise Http404 + @permission_required('scipost.can_vet_comments', raise_exception=True) def vet_submitted_comments(request): contributor = Contributor.objects.get(user=request.user) @@ -95,7 +98,7 @@ def vet_submitted_comment_ack(request, comment_id): comment.status = 1 comment.vetted_by = request.user.contributor comment.save() - email_text = ('Dear ' + title_dict[comment.author.title] + ' ' + email_text = ('Dear ' + comment.author.get_title_display() + ' ' + comment.author.user.last_name + ', \n\nThe Comment you have submitted, ' 'concerning publication with title ') @@ -138,7 +141,7 @@ def vet_submitted_comment_ack(request, comment_id): if comment.status == 0: comment.status == -1 comment.save() - email_text = ('Dear ' + title_dict[comment.author.title] + ' ' + email_text = ('Dear ' + comment.author.get_title_display() + ' ' + comment.author.user.last_name + ', \n\nThe Comment you have submitted, ' 'concerning publication with title ') @@ -151,7 +154,7 @@ def vet_submitted_comment_ack(request, comment_id): elif comment.thesislink is not None: email_text += comment.thesislink.title + ' by ' + comment.thesislink.author email_text += (', has been rejected for the following reason: ' - + comment_refusal_dict[comment.status] + '.' + + + comment.get_status_display() + '.' + '\n\nWe copy it below for your convenience.' + '\n\nThank you for your contribution, \n\nThe SciPost Team.') if form.cleaned_data['email_response_field']: diff --git a/journals/constants.py b/journals/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..60fe1b1ab93fcd43f23d82d2ca76f90225fb1ce9 --- /dev/null +++ b/journals/constants.py @@ -0,0 +1,44 @@ +SCIPOST_JOURNAL_PHYSICS_SELECT = 'SciPost Physics Select' +SCIPOST_JOURNAL_PHYSICS = 'SciPost Physics' +SCIPOST_JOURNAL_LECTURE_NOTES = 'SciPost Physics Lecture Notes' +SCIPOST_JOURNALS = ( + (SCIPOST_JOURNAL_PHYSICS_SELECT, 'SciPost Physics Select'), + (SCIPOST_JOURNAL_PHYSICS, 'SciPost Physics'), + (SCIPOST_JOURNAL_LECTURE_NOTES, 'SciPost Physics Lecture Notes'), +) + +# Same as SCIPOST_JOURNALS, but SciPost Select deactivated +SCIPOST_JOURNALS_SUBMIT = ( + (SCIPOST_JOURNAL_PHYSICS, 'SciPost Physics'), + (SCIPOST_JOURNAL_LECTURE_NOTES, 'SciPost Physics Lecture Notes'), +) + +SCIPOST_JOURNALS_DOMAINS = ( + ('E', 'Experimental'), + ('T', 'Theoretical'), + ('C', 'Computational'), + ('ET', 'Exp. & Theor.'), + ('EC', 'Exp. & Comp.'), + ('TC', 'Theor. & Comp.'), + ('ETC', 'Exp., Theor. & Comp.'), +) + +SCIPOST_JOURNALS_SPECIALIZATIONS = ( + ('A', 'Atomic, Molecular and Optical Physics'), + ('B', 'Biophysics'), + ('C', 'Condensed Matter Physics'), + ('F', 'Fluid Dynamics'), + ('G', 'Gravitation, Cosmology and Astroparticle Physics'), + ('H', 'High-Energy Physics'), + ('M', 'Mathematical Physics'), + ('N', 'Nuclear Physics'), + ('Q', 'Quantum Statistical Mechanics'), + ('S', 'Statistical and Soft Matter Physics'), +) + +STATUS_DRAFT = 'draft' +STATUS_PUBLISHED = 'published' +ISSUE_STATUSES = ( + (STATUS_DRAFT, 'Draft'), + (STATUS_PUBLISHED, 'Published'), +) diff --git a/journals/exceptions.py b/journals/exceptions.py new file mode 100644 index 0000000000000000000000000000000000000000..16248c28c53995ed8286a46b91accb78138023e1 --- /dev/null +++ b/journals/exceptions.py @@ -0,0 +1,22 @@ +class JournalNameError(Exception): + def __init__(self, name): + self.name = name + + def __str__(self): + return self.name + + +class PaperNumberError(Exception): + def __init__(self, nr): + self.nr = nr + + def __str__(self): + return self.nr + + +class PaperNumberingError(Exception): + def __init__(self, nr): + self.nr = nr + + def __str__(self): + return self.nr diff --git a/journals/helpers.py b/journals/helpers.py new file mode 100644 index 0000000000000000000000000000000000000000..fb08cf89eaf8e0ec12dc5bee07ff9d54f8efa618 --- /dev/null +++ b/journals/helpers.py @@ -0,0 +1,34 @@ +from .exceptions import JournalNameError, PaperNumberError + + +def journal_name_abbrev_citation(journal_name): + if journal_name == 'SciPost Physics': + return 'SciPost Phys.' + elif journal_name == 'SciPost Physics Select': + return 'SciPost Phys. Sel.' + elif journal_name == 'SciPost Physics Lecture Notes': + return 'SciPost Phys. Lect. Notes' + else: + raise JournalNameError(journal_name) + + +def journal_name_abbrev_doi(journal_name): + if journal_name == 'SciPost Physics': + return 'SciPostPhys' + elif journal_name == 'SciPost Physics Select': + return 'SciPostPhysSel' + elif journal_name == 'SciPost Physics Lecture Notes': + return 'SciPostPhysLectNotes' + else: + raise JournalNameError(journal_name) + + +def paper_nr_string(nr): + if nr < 10: + return '00' + str(nr) + elif nr < 100: + return '0' + str(nr) + elif nr < 1000: + return str(nr) + else: + raise PaperNumberError(nr) diff --git a/journals/managers.py b/journals/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..1c31bb440e771011abaacf05e83f2022eb11460b --- /dev/null +++ b/journals/managers.py @@ -0,0 +1,48 @@ +from django.db import models +from django.http import Http404 +from django.utils import timezone + +from .constants import STATUS_PUBLISHED, STATUS_DRAFT + + +class IssueManager(models.Manager): + def get_published(self, *args, **kwargs): + try: + return self.published(*args, **kwargs)[0] + except IndexError: + raise Http404 + + def published(self, journal=None, **kwargs): + issues = self.filter(status=STATUS_PUBLISHED, **kwargs) + if journal: + issues.filter(in_volume__in_journal__name=journal) + return issues + + def in_draft(self, journal=None, **kwargs): + issues = self.filter(status=STATUS_DRAFT, **kwargs) + if journal: + issues.filter(in_volume__in_journal__name=journal) + return issues + + def get_current_issue(self, *args, **kwargs): + return self.published(start_date__lte=timezone.now(), + until_date__gte=timezone.now(), + **kwargs).order_by('-until_date').first() + + def get_last_filled_issue(self, *args, **kwargs): + return self.published(publication__isnull=False, + **kwargs).order_by('-until_date').first() + + +class PublicationManager(models.Manager): + def get_published(self, *args, **kwargs): + try: + return self.published(*args, **kwargs)[0] + except IndexError: + raise Http404 + + def published(self, **kwargs): + return self.filter(in_issue__status=STATUS_PUBLISHED, **kwargs) + + def in_draft(self, **kwargs): + return self.filter(in_issue__status=STATUS_DRAFT, **kwargs) diff --git a/journals/migrations/0001_initial.py b/journals/migrations/0001_initial.py index 6718cec95b70dbfe1cdcec686434655475253045..2cd9caec1d1cd94f5e65fb406ca6ddeb17481a52 100644 --- a/journals/migrations/0001_initial.py +++ b/journals/migrations/0001_initial.py @@ -46,7 +46,7 @@ class Migration(migrations.Migration): ('discipline', models.CharField(choices=[('physics', 'Physics'), ('astrophysics', 'Astrophysics'), ('mathematics', 'Mathematics'), ('computerscience', 'Computer Science')], default='physics', max_length=20)), ('domain', models.CharField(choices=[('E', 'Experimental'), ('T', 'Theoretical'), ('C', 'Computational'), ('ET', 'Exp. & Theor.'), ('EC', 'Exp. & Comp.'), ('TC', 'Theor. & Comp.'), ('ETC', 'Exp., Theor. & Comp.')], max_length=3)), ('subject_area', models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], default='Phys:QP', max_length=10, verbose_name='Primary subject area')), - ('secondary_areas', scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), + ('secondary_areas', scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), ('title', models.CharField(max_length=300)), ('author_list', models.CharField(max_length=1000, verbose_name='author list')), ('abstract', models.TextField()), diff --git a/journals/models.py b/journals/models.py index d858d6bcc51394a7f299831ae2f5011494c52e87..e411c98354c069e0f1567201514d6175fbe401e5 100644 --- a/journals/models.py +++ b/journals/models.py @@ -1,11 +1,16 @@ from django.contrib.postgres.fields import JSONField from django.db import models -from django.http import Http404 from django.template import Template, Context from django.utils import timezone +from .constants import SCIPOST_JOURNALS, SCIPOST_JOURNALS_DOMAINS,\ + STATUS_DRAFT, STATUS_PUBLISHED, ISSUE_STATUSES +from .helpers import paper_nr_string, journal_name_abbrev_citation +from .managers import IssueManager, PublicationManager + from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS -from scipost.models import ChoiceArrayField, Contributor +from scipost.fields import ChoiceArrayField +from scipost.models import Contributor class UnregisteredAuthor(models.Model): @@ -16,103 +21,6 @@ class UnregisteredAuthor(models.Model): return self.last_name + ', ' + self.first_name -SCIPOST_JOURNALS = ( - ('SciPost Physics Select', 'SciPost Physics Select'), - ('SciPost Physics', 'SciPost Physics'), - ('SciPost Physics Lecture Notes', 'SciPost Physics Lecture Notes'), - ) -journals_dict = dict(SCIPOST_JOURNALS) - - -class JournalNameError(Exception): - def __init__(self, name): - self.name = name - - def __str__(self): - return self.name - - -def journal_name_abbrev_citation(journal_name): - if journal_name == 'SciPost Physics': - return 'SciPost Phys.' - elif journal_name == 'SciPost Physics Select': - return 'SciPost Phys. Sel.' - elif journal_name == 'SciPost Physics Lecture Notes': - return 'SciPost Phys. Lect. Notes' - else: - raise JournalNameError(journal_name) - - -def journal_name_abbrev_doi(journal_name): - if journal_name == 'SciPost Physics': - return 'SciPostPhys' - elif journal_name == 'SciPost Physics Select': - return 'SciPostPhysSel' - elif journal_name == 'SciPost Physics Lecture Notes': - return 'SciPostPhysLectNotes' - else: - raise JournalNameError(journal_name) - - -class PaperNumberError(Exception): - def __init__(self, nr): - self.nr = nr - - def __str__(self): - return self.nr - - -def paper_nr_string(nr): - if nr < 10: - return '00' + str(nr) - elif nr < 100: - return '0' + str(nr) - elif nr < 1000: - return str(nr) - else: - raise PaperNumberError(nr) - - -class PaperNumberingError(Exception): - def __init__(self, nr): - self.nr = nr - - def __str__(self): - return self.nr - - -SCIPOST_JOURNALS_SUBMIT = ( # Same as SCIPOST_JOURNALS, but SP Select deactivated - ('SciPost Physics', 'SciPost Physics'), - ('SciPost Physics Lecture Notes', 'SciPost Physics Lecture Notes'), - ) -journals_submit_dict = dict(SCIPOST_JOURNALS_SUBMIT) - -SCIPOST_JOURNALS_DOMAINS = ( - ('E', 'Experimental'), - ('T', 'Theoretical'), - ('C', 'Computational'), - ('ET', 'Exp. & Theor.'), - ('EC', 'Exp. & Comp.'), - ('TC', 'Theor. & Comp.'), - ('ETC', 'Exp., Theor. & Comp.'), -) -journals_domains_dict = dict(SCIPOST_JOURNALS_DOMAINS) - -SCIPOST_JOURNALS_SPECIALIZATIONS = ( - ('A', 'Atomic, Molecular and Optical Physics'), - ('B', 'Biophysics'), - ('C', 'Condensed Matter Physics'), - ('F', 'Fluid Dynamics'), - ('G', 'Gravitation, Cosmology and Astroparticle Physics'), - ('H', 'High-Energy Physics'), - ('M', 'Mathematical Physics'), - ('N', 'Nuclear Physics'), - ('Q', 'Quantum Statistical Mechanics'), - ('S', 'Statistical and Soft Matter Physics'), - ) -journals_spec_dict = dict(SCIPOST_JOURNALS_SPECIALIZATIONS) - - class Journal(models.Model): name = models.CharField(max_length=100, choices=SCIPOST_JOURNALS, unique=True) @@ -137,43 +45,6 @@ class Volume(models.Model): return str(self.in_journal) + ' Vol. ' + str(self.number) -STATUS_DRAFT = 'draft' -STATUS_PUBLISHED = 'published' -ISSUE_STATUSES = ( - (STATUS_DRAFT, 'Draft'), - (STATUS_PUBLISHED, 'Published'), -) - - -class IssueManager(models.Manager): - def get_published(self, *args, **kwargs): - try: - return self.published(*args, **kwargs)[0] - except IndexError: - raise Http404 - - def published(self, journal=None, **kwargs): - issues = self.filter(status=STATUS_PUBLISHED, **kwargs) - if journal: - issues.filter(in_volume__in_journal__name=journal) - return issues - - def in_draft(self, journal=None, **kwargs): - issues = self.filter(status=STATUS_DRAFT, **kwargs) - if journal: - issues.filter(in_volume__in_journal__name=journal) - return issues - - def get_current_issue(self, *args, **kwargs): - return self.published(start_date__lte=timezone.now(), - until_date__gte=timezone.now(), - **kwargs).order_by('-until_date').first() - - def get_last_filled_issue(self, *args, **kwargs): - return self.published(publication__isnull=False, - **kwargs).order_by('-until_date').first() - - class Issue(models.Model): in_volume = models.ForeignKey(Volume, on_delete=models.CASCADE) number = models.PositiveSmallIntegerField() @@ -198,7 +69,7 @@ class Issue(models.Model): def period_as_string(self): if self.start_date.month == self.until_date.month: - return ' (' + self.until_date.strftime('%B') + ' ' + self.until_date.strftime('%Y') + ')' + return ' (%s %s)' % (self.until_date.strftime('%B'), self.until_date.strftime('%Y')) else: return (' (' + self.start_date.strftime('%B') + '-' + self.until_date.strftime('%B') + ' ' + self.until_date.strftime('%Y') + ')') @@ -215,20 +86,6 @@ class Issue(models.Model): return template.render(context) -class PublicationManager(models.Manager): - def get_published(self, *args, **kwargs): - try: - return self.published(*args, **kwargs)[0] - except IndexError: - raise Http404 - - def published(self, **kwargs): - return self.filter(in_issue__status=STATUS_PUBLISHED, **kwargs) - - def in_draft(self, **kwargs): - return self.filter(in_issue__status=STATUS_DRAFT, **kwargs) - - class Publication(models.Model): accepted_submission = models.OneToOneField('submissions.Submission', on_delete=models.CASCADE) in_issue = models.ForeignKey(Issue, on_delete=models.CASCADE) @@ -296,7 +153,7 @@ class Publication(models.Model): def citation_for_web_linked(self): citation = ('<a href="{% url \'scipost:publication_detail\' doi_string=doi_string %}">' '{{ abbrev }} <strong>{{ volume_nr }}</strong>' - ', {{ paper_nr }} ({{ year }})') + ', {{ paper_nr }} ({{ year }})</a>') template = Template(citation) context = Context( {'doi_string': self.doi_string, @@ -307,72 +164,6 @@ class Publication(models.Model): 'year': self.publication_date.strftime('%Y'), }) return template.render(context) - def header_as_li(self): - header = ('<div class="publicationHeader">' - '<h3 class="publicationTitle"><a href="{% url \'scipost:publication_detail\' doi_string=doi_string %}">{{ title }}</a></h3>' - '<p class="publicationAuthors">{{ author_list }}</p>' - '<p class="publicationReference">{{ citation }} ' - '| published {{ pub_date }}</p>' - '<p class="publicationAbstract">{{ abstract }}</p>' - '<ul class="publicationClickables">' - '<li><button class="btn btn-secondary toggleAbstractButton">Toggle abstract</button></li>' - '<li class="publicationPDF"><a href="{% url \'scipost:publication_pdf\' doi_string=doi_string %}" target="_blank">pdf</a></li>' - '</ul>' - '</div>') - template = Template(header) - context = Context({ - 'doi_string': self.doi_string, - 'title': self.title, - 'author_list': self.author_list, - 'citation': self.citation, - 'pub_date': self.publication_date.strftime('%d %B %Y'), - 'abstract': self.abstract, - }) - return template.render(context) - - def details(self): - """ - This method is called from the publication_detail template. - It provides all the details for a publication. - """ - pub_details = ( - '<div class="row"><div class="col-12">' - '<h3 class="publicationTitle">' - '<a href="{% url \'scipost:publication_detail\' doi_string=doi_string %}">{{ title }}</a>' - '</h3>' - '<p class="publicationAuthors">{{ author_list }}</p>' - '<p class="publicationReference">{{ citation }} ' - '| published {{ pub_date}}</p>' - '<ul class="publicationClickables">' - '<li>doi: {{ doi_string }}</li>' - '<li class="publicationPDF">' - '<a href="{% url \'scipost:publication_pdf\' doi_string=doi_string %}" target="_blank">pdf</a>' - '</li>' - '<li><a href="#openModal">BiBTeX</a></li>' - '<li><a href="{% url \'submissions:submission\' arxiv_identifier_w_vn_nr=' - 'arxiv_identifier_w_vn_nr %}">Submissions/Reports</a></li>' - '</ul></div></div>' - '<div class="row"><div class="col-12"><hr>' - '<h3>Abstract:</h3>' - '<p class="publicationAbstract">{{ abstract }}</p>' - '<div id="openModal" class="modalDialog"><div>' - '<a href="#close" title="Close" class="close">X</a>' - '<h2>BiBTeX</h2><p>{{ BiBTeX|linebreaks }}</p></div></div>' - '</div></div>' - ) - template = Template(pub_details) - context = Context({ - 'title': self.title, - 'author_list': self.author_list, - 'citation': self.citation_for_web, - 'pub_date': self.publication_date.strftime('%d %B %Y'), - 'abstract': self.abstract, - 'doi_string': self.doi_string, - 'BiBTeX': self.BiBTeX_entry, - 'arxiv_identifier_w_vn_nr': self.accepted_submission.arxiv_identifier_w_vn_nr - }) - return template.render(context) - def citations_as_ul(self): output = '<ul>' context = Context({}) diff --git a/journals/templates/journals/_publication_card_content.html b/journals/templates/journals/_publication_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..68cb6396513fd7f0804c2a5e8f14f03a5c3b765b --- /dev/null +++ b/journals/templates/journals/_publication_card_content.html @@ -0,0 +1,12 @@ +<div class="card-header"> + <h3><a href="{% url 'scipost:publication_detail' publication.doi_string %}">{{ publication.title }}</a></h3> +</div> +<div class="card-block publication-{{publication.id}}"> + <p>{{ publication.author_list }}</p> + <p>{{ publication.citation }} | published {{ publication.publication_date|date:'j F Y' }}</p> + <p class="abstract" style="display:none;">{{ publication.abstract }}</p> + <div class="actions"> + <button class="btn btn-secondary mr-3" data-toggle="toggle" data-target=".card-block.publication-{{publication.id}} .abstract">Toggle abstract</button> + <a href="{% url 'scipost:publication_pdf' publication.doi_string %}" target="_blank">pdf</a> + </div> +</div> diff --git a/journals/templates/journals/_publication_details.html b/journals/templates/journals/_publication_details.html new file mode 100644 index 0000000000000000000000000000000000000000..ef9a813844b23d42e3c7352477c23236ffac652c --- /dev/null +++ b/journals/templates/journals/_publication_details.html @@ -0,0 +1,32 @@ +<div class="row"> + <div class="col-12"> + <h3 class="highlight py-3"> + <a href="{% url 'scipost:publication_detail' publication.doi_string %}">{{publication.title}}</a> + </h3> + + <p class="font-weight-bold">{{ publication.author_list }}</p> + <p>{{ publication.citation }} | published {{ publication.publication_date|date:'j F Y' }}</p> + + <ul class="publicationClickables"> + <li>doi: {{publication.doi_string}}</li> + <li class="publicationPDF"> + <a href="{% url 'scipost:publication_pdf' publication.doi_string %}" target="_blank">pdf</a> + </li> + <li><a href="#openModal">BiBTeX</a></li> + <li><a href="{% url 'submissions:submission' publication.accepted_submission.arxiv_identifier_w_vn_nr %}">Submissions/Reports</a></li> + </ul> + </div> +</div> +<div class="row"> + <div class="col-12"> + <h3>Abstract</h3> + <p class="abstract">{{ publication.abstract }}</p> + </div> +</div> +<div id="openModal" class="modalDialog"> + <div> + <a href="#close" title="Close" class="close">X</a> + <h2>BiBTeX</h2> + <p>{{publication.BiBTeX_entry|linebreaks}}</p> + </div> +</div> diff --git a/journals/templates/journals/add_author.html b/journals/templates/journals/add_author.html index 241de8b1a11ef7a0b1aa86685a8abb8c261400cf..fabb202ea90b856b73e0cbc2154f00e138f615c6 100644 --- a/journals/templates/journals/add_author.html +++ b/journals/templates/journals/add_author.html @@ -2,90 +2,102 @@ {% block pagetitle %}: add author to publication{% endblock pagetitle %} -{% block headsup %} - {% load scipost_extras %} - -{% endblock headsup %} - -{% block bodysup %} - - -<section> - <div class="flex-greybox"> - <h1>Add author to publication</h1> - </div> - {{ publication.details }} -</section> - - -<section> - <div class="flex-greybox"> - <h1>Add an (unregistered) author</h1> - </div> - - <h3>Current list of authors as contributors:</h3> - <p> - {% for author in publication.authors.all %} - <a href="/contributor/{{ author.id }}">{{ author.user.first_name }} {{ author.user.last_name }}</a> - {% endfor %} - </p> - <h3>Current list of additional authors (unregistered):</h3> - <p> - {% for author in publication.authors_unregistered.all %} - {{ author }} - {% endfor %} - </p> - - <h3>Search for missing author:</h3> - <form action="{% url 'journals:add_author' publication_id=publication.id %}" method="post"> - {% csrf_token %} - {{ form.as_p }} - <input type="submit" value="Search"> - </form> - - {% if contributors_found %} - <h3>Identified as contributor:</h3> - <table> - {% for contributor in contributors_found %} - <tr> - <td>{{ contributor.user.first_name }} {{ contributor.user.last_name }}</td> - <td> </td> - <td><a href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a></td> - </tr> - {% endfor %} - </table> - {% elif form.has_changed %} - <p>No Contributor with this name could be identified.</p> - {% endif %} - <br/> - - {% if unregistered_authors_found %} - <h3>Identified as existing unregistered author:</h3> - <table> - {% for unreg_auth in unregistered_authors_found %} - <tr> - <td>{{ unreg_auth }}</td> - <td> </td> - <td><a href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a></td> - </tr> - {% endfor %} - </table> - {% elif form.has_changed %} - <p>No UnregisteredAuthor with this name could be found in the database.</p> - {% endif %} - <br/> - - <h3>You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3> - <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post"> - {% csrf_token %} - {{ new_unreg_author_form.as_p }} - <input type="submit" value="Add"> - </form> - - <h3><a href="{% url 'scipost:publication_detail' doi_string=publication.doi_string %}">Return to the publication's page</a></h3> - -</section> - - -{% endblock bodysup %} +{% load bootstrap %} + +{% block content %} + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Add author to publication</h1> + </div> +</div> + +<div class="row"> + <div class="col-12"> + {% include 'journals/_publication_details.html' with publication=publication %} + </div> +</div> + + +<div class="row"> + <div class="col-12"> + <h2 class="highlight">Add an (unregistered) author</h2> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h3>Current list of authors as contributors:</h3> + <ul class="list-group list-group-noborder"> + {% for author in publication.authors.all %} + <li class="list-group-item py-1 pl-2"> + <a href="{% url 'scipost:contributor_info' author.id %}">{{ author.user.first_name }} {{ author.user.last_name }}</a> + </li> + {% empty %} + No unregistered authors known. + {% endfor %} + </ul> + <h3>Current list of additional authors (unregistered):</h3> + <ul class="list-group list-group-noborder"> + {% for author in publication.authors_unregistered.all %} + <li class="list-group-item py-1 pl-2">{{ author }}</li> + {% empty %} + No unregistered authors known. + {% endfor %} + </ul> + <hr class="small"> + + <div class="row"> + <div class="col-md-8"> + <h3>Search for missing author:</h3> + <form action="{% url 'journals:add_author' publication.id %}" method="post"> + {% csrf_token %} + {{form|bootstrap}} + <input class="btn btn-secondary" type="submit" value="Search"> + </form> + + {% if form.has_changed %} + <h3 class="mt-4">Identified as contributor:</h3> + <ul class="list-group"> + {% for contributor in contributors_found %} + <li class="list-group-item p-2"> + <div class="d-block w-100 font-weight-bold">{{ contributor.user.first_name }} {{ contributor.user.last_name }}</div> + <a class="d-block" href="{% url 'journals:add_author' publication_id=publication.id contributor_id=contributor.id %}">Add this Contributor as author of this Publication</a> + </li> + {% empty %} + <span class="text-danger">No Contributor with this name could be identified.</span> + {% endfor %} + </ul> + + <h3 class="mt-2">Identified as existing unregistered author:</h3> + <ul class="list-group"> + {% for unreg_auth in unregistered_authors_found %} + <li class="list-group-item"> + <div class="d-block w-100 font-weight-bold">{{ unreg_auth }} + <a class="d-block" href="{% url 'journals:add_unregistered_author' publication_id=publication.id unregistered_author_id=unreg_auth.id %}">Add this unregistered author as author of this Publication</a> + </li> + {% empty %} + <span class="text-danger">No UnregisteredAuthor with this name could be found in the database.</span> + {% endfor %} + </ul> + + <h3 class="mt-3">You can otherwise create an UnregisteredAuthor object instance and link it to this publication:</h3> + <form action="{% url 'journals:add_new_unreg_author' publication_id=publication.id %}" method="post"> + {% csrf_token %} + {{ new_unreg_author_form|bootstrap }} + <input class="btn btn-secondary" type="submit" value="Add"> + </form> + + {% endif %} + </div> + </div> + + <h3> + <a href="{% url 'scipost:publication_detail' doi_string=publication.doi_string %}">Return to the publication's page</a> + </h3> + </div> +</div> + + +{% endblock content %} diff --git a/journals/templates/journals/journals.html b/journals/templates/journals/journals.html index 5a7bc0530bcc7d734365634439e922c004b1c238..a9cb62092e54e9152d071197e24834fb5eda5d68 100644 --- a/journals/templates/journals/journals.html +++ b/journals/templates/journals/journals.html @@ -6,9 +6,7 @@ <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>SciPost Physics Journals</h1> - </div> + <h1 class="highlight">SciPost Physics Journals</h1> </div> </div> <div class="row"> @@ -18,11 +16,10 @@ </div> <div class="row"> - <div class="col-12 col-md-6"> - {# <hr>#} - <div class="SciPostPhysicsBanner"> - <h1><a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a></h1> - </div> + <div class="col-md-6"> + <h1 class="banner"> + <a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a> + </h1> <div class="py-2"> <p>SciPost Physics publishes outstanding-quality research articles in all domains and subject areas of Physics.</p> <p>The journal accepts three types of content: Letters, Articles and Reviews.</p> @@ -32,13 +29,10 @@ </div> </div> - <div class="col-12 col-md-6"> + <div class="col-md-6"> <div class="row"> <div class="col-12"> - {# <hr>#} - <div class="SciPostPhysicsBanner"> - <h1>SciPost Physics Select</h1> - </div> + <h1 class="banner">SciPost Physics Select</h1> <div class="py-2"> <p>SciPost Physics Select publishes articles of superlative quality in the field of Physics.</p> <p>Authors cannot submit directly to this Journal; SPS papers are editorially selected from the most outstanding Submissions to SciPost Physics.</p> @@ -49,10 +43,7 @@ <div class="row"> <div class="col-12"> - {# <hr>#} - <div class="SciPostPhysicsBanner"> - <h1>SciPost Physics Lecture Notes</h1> - </div> + <h1 class="banner">SciPost Physics Lecture Notes</h1> <div class="py-2"> <p>Research-level didactic material in all domains and subject areas of Physics.</p> <p style="color: red;">Open for submission!</p> @@ -62,40 +53,9 @@ </div> </div> -{% comment %} <div class="row"> - <div class="col-12"> - <hr> - <div class="SciPostPhysicsBanner"> - <h3><a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a></h3> - </div> - <div class="py-2"> - <p>SciPost Physics publishes outstanding-quality research articles in all domains and subject areas of Physics.</p> - <p>The journal accepts three types of content: Letters, Articles and Reviews.</p> - <p>Letters report broad-interest, significant breakthroughs in Physics, of interest and importance to researchers in multiple subject areas.</p> - <p>Articles provide in-depth, detailed reports of groundbreaking research within one or more subject areas.</p> - <p>Reviews are short pieces taking a snapshot of a research area, written by recognized leaders in the field, providing a critical assessment of current frontline research and providing pointers towards future opportunities.</p> - </div> - </div> -</div>{% endblock %} - -{% comment %} <div class="row"> - <div class="col-12"> - <hr> - <div class="SciPostPhysicsBanner"> - <h3>SciPost Physics Select</h3> - </div> - <div class="py-2"> - <p>SciPost Physics Select publishes articles of superlative quality in the field of Physics.</p> - <p>Authors cannot submit directly to this Journal; SPS papers are editorially selected from the most outstanding Submissions to SciPost Physics.</p> - <p style="color: red;"><em>Coming soon!</p> - </div> - </div> -</div>{% endcomment %} - - +<hr> <div class="row"> <div class="col-12"> - <hr> <p>The collection of SciPost Physics Journals covers research in the domains of Experimental, Theoretical and Computational physics, including the following specialties:</p> <ul> <li>A: Atomic, Molecular and Optical Physics</li> @@ -111,9 +71,10 @@ </ul> </div> </div> + +<hr> <div class="row"> <div class="col-12"> - <hr> <h3><a href="{% url 'journals:journals_terms_and_conditions' %}">SciPost Journals Terms and Conditions</a></h3> <h3><a href="{% url 'submissions:author_guidelines' %}">Author guidelines</a></h3> <h3><a href="{% url 'submissions:sub_and_ref_procedure' %}">Submission and Refereeing procedure</a></h3> diff --git a/journals/templates/journals/publication_detail.html b/journals/templates/journals/publication_detail.html index 12c8c509f7d5d5edc0d11a5232571a47874c8b6a..8b9d46ecd843d98224c350dad63c5efdb6d6cf4c 100644 --- a/journals/templates/journals/publication_detail.html +++ b/journals/templates/journals/publication_detail.html @@ -40,11 +40,7 @@ {% include 'journals/scipost_physics_menu.html' %} -<div class="row"> - <div class="col-12"> - {{ publication.details }} - </div> -</div> +{% include 'journals/_publication_details.html' with publication=publication %} {% if publication.citedby|length >= 1 %} <hr> diff --git a/journals/templates/journals/scipost_physics.html b/journals/templates/journals/scipost_physics.html index 4ed754b5d0b5f509f600d7211f8fbe235e262323..6aa469bf679dd86baad9e131540a4e0758f8219c 100644 --- a/journals/templates/journals/scipost_physics.html +++ b/journals/templates/journals/scipost_physics.html @@ -2,21 +2,6 @@ {% block pagetitle %}: SciPost Physics{% endblock pagetitle %} -{% block headsup %} - -<script> - $(document).ready(function(){ - - $(".publicationAbstract").hide(); - - $(".toggleAbstractButton").click(function(){ - $(this).parent("li").parent("ul").siblings("p.publicationAbstract").toggle(); - }); - }); -</script> - -{% endblock headsup %} - {% block content %} {% include 'journals/scipost_physics_menu.html' %} @@ -32,11 +17,13 @@ <div class="publicationHeaderList"> <div class="row"> - {% for paper in current_issue.publication_set.all|dictsort:"paper_nr" %} - <div class="col-12"> - {{ paper.header_as_li }} - </div> - {% endfor %} + <div class="col-12"> + {% for paper in current_issue.publication_set.all|dictsort:"paper_nr" %} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=paper %} + </div> + {% endfor %} + </div> </div> </div> <hr> @@ -53,11 +40,13 @@ <div class="publicationHeaderList"> <div class="row"> - {% for paper in latest_issue.publication_set.all|dictsort:"paper_nr" %} - <div class="col-12"> - {{ paper.header_as_li }} - </div> - {% endfor %} + <div class="col-12"> + {% for paper in latest_issue.publication_set.all|dictsort:"paper_nr" %} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=paper %} + </div> + {% endfor %} + </div> </div> </div> {% endif %} diff --git a/journals/templates/journals/scipost_physics_accepted.html b/journals/templates/journals/scipost_physics_accepted.html index d4ff241e74faaac3b9675fa1c41d3e67e6228c91..fc820ce148524ecff2f1aaacf42b3286bde04e8c 100644 --- a/journals/templates/journals/scipost_physics_accepted.html +++ b/journals/templates/journals/scipost_physics_accepted.html @@ -17,9 +17,11 @@ <div class="row"> <div class="col-12"> {% if accepted_SP_submissions %} - <ul> + <ul class="list-group list-group-flush"> {% for submission in accepted_SP_submissions %} - {{ submission.header_as_li }} + <li class="list-group-item"> + {% include 'submissions/_submission_card_content.html' with submission=submission %} + </li> {% endfor %} </ul> {% else %} diff --git a/journals/templates/journals/scipost_physics_issue_detail.html b/journals/templates/journals/scipost_physics_issue_detail.html index c153f276d52fedb4a7b0e5f8a9cadda20d4875ef..7906d350b003b1ca7173bf7783b1d5970feb96a1 100644 --- a/journals/templates/journals/scipost_physics_issue_detail.html +++ b/journals/templates/journals/scipost_physics_issue_detail.html @@ -4,17 +4,6 @@ {% block headsup %} -<script> - $(document).ready(function(){ - - $(".publicationAbstract").hide(); - - $(".toggleAbstractButton").click(function(){ - $(this).parent("li").parent("ul").siblings("p.publicationAbstract").toggle(); - }); - }); -</script> - {% endblock headsup %} {% block content %} @@ -31,13 +20,13 @@ <div class="publicationHeaderList"> <div class="row"> - {% for paper in papers %} - <div class="col-12"> - <div class="panel"> - {{ paper.header_as_li }} + <div class="col-12"> + {% for paper in papers %} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=paper %} </div> - </div> - {% endfor %} + {% endfor %} + </div> </div> </div> diff --git a/journals/templates/journals/scipost_physics_menu.html b/journals/templates/journals/scipost_physics_menu.html index 3f6a16a2cc605b5ff52873b6bc9a04f997330f1c..093a6e941c80ac01a7389b9fad30a7a700ad6c98 100644 --- a/journals/templates/journals/scipost_physics_menu.html +++ b/journals/templates/journals/scipost_physics_menu.html @@ -1,9 +1,7 @@ <ul class="SciPostPhysicsTabMenu"> <li> - <div class="SciPostPhysicsTab"> - <h3><a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a></h3> - </div> + <h3 class="banner py-2"><a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a></h3> </li> <li><a href="{% url 'journals:scipost_physics_issues' %}">Issues</li> <li><a href="{% url 'journals:scipost_physics_recent' %}">Recent</li> diff --git a/journals/templates/journals/scipost_physics_recent.html b/journals/templates/journals/scipost_physics_recent.html index a0340ae76be42a86c6add47b0e629b080eb40bae..8ec348d99b4e36c8f160f5f1e82b11502eb92af7 100644 --- a/journals/templates/journals/scipost_physics_recent.html +++ b/journals/templates/journals/scipost_physics_recent.html @@ -2,19 +2,6 @@ {% block pagetitle %}: SciPost Physics: recent{% endblock pagetitle %} -{% block headsup %} -<script> - $(document).ready(function(){ - - $(".publicationAbstract").hide(); - - $(".toggleAbstractButton").click(function(){ - $(this).parent("li").parent("ul").siblings("p.publicationAbstract").toggle(); - }); - }); -</script> -{% endblock headsup %} - {% block content %} {% include 'journals/scipost_physics_menu.html' %} @@ -30,11 +17,13 @@ {% if recent_papers %} <div class="publicationHeaderList"> <div class="row"> - {% for paper in recent_papers %} - <div class="col-12"> - {{ paper.header_as_li }} - </div> - {% endfor %} + <div class="col-12"> + {% for paper in recent_papers %} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=paper %} + </div> + {% endfor %} + </div> </div> </div> {% endif %} diff --git a/journals/templates/journals/validate_publication.html b/journals/templates/journals/validate_publication.html index a9245987880f9d174621755158794e5091096201..e2fd2cd90b373a7ca0e1a2ec5c48a5e52d452c4d 100644 --- a/journals/templates/journals/validate_publication.html +++ b/journals/templates/journals/validate_publication.html @@ -1,26 +1,29 @@ {% extends 'scipost/base.html' %} -{% block pagetitle %}: Validate publication{% endblock pagetitle %} - -{% block bodysup %} - - -<section> - <div class="flex-greybox"> - <h1>Validate publication page</h1> - </div> - - {% if errormessage %} - <h2 style="color: red;">{{ errormessage }}</h2> - {% endif %} - - <form action="{% url 'journals:validate_publication' %}" method="post" enctype="multipart/form-data"> - {% csrf_token %} - {{ validate_publication_form.as_p }} - <input type="submit" value="Submit"> - </form> - -</section> +{% load bootstrap %} +{% block pagetitle %}: Validate publication{% endblock pagetitle %} -{% endblock bodysup %} +{% block content %} + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Validate publication page</h1> + </div> +</div> + +<div class="row"> + <div class="col-lg-10 offset-lg-1"> + {% if errormessage %} + <h2 style="color: red;">{{ errormessage }}</h2> + {% endif %} + + <form action="{% url 'journals:validate_publication' %}" method="post" enctype="multipart/form-data"> + {% csrf_token %} + {{ validate_publication_form|bootstrap }} + <input class="btn btn-secondary" type="submit" value="Submit"> + </form> + </div> +</div> + +{% endblock content %} diff --git a/journals/templatetags/journals_extras.py b/journals/templatetags/journals_extras.py index c5625821237805fb08970b9be997c43384996c73..382ac91e2b0e6a2528fbd9c54349ca4a9e0ac332 100644 --- a/journals/templatetags/journals_extras.py +++ b/journals/templatetags/journals_extras.py @@ -1,6 +1,6 @@ from django import template -from journals.models import paper_nr_string +from journals.helpers import paper_nr_string register = template.Library() diff --git a/journals/utils.py b/journals/utils.py index 71d5cae1cd91cb6373334c5fd1d76b607bdb32bf..ccb5852064de8ae78db09de828d791749e7b5b0b 100644 --- a/journals/utils.py +++ b/journals/utils.py @@ -1,7 +1,5 @@ from django.core.mail import EmailMessage -from scipost.models import title_dict - class JournalUtils(object): @@ -14,7 +12,7 @@ class JournalUtils(object): def send_authors_paper_published_email(cls): """ Requires loading 'publication' attribute. """ email_text = ('Dear ' - + title_dict[cls.publication.accepted_submission.submitted_by.title] + + cls.publication.accepted_submission.submitted_by.get_title_display() + ' ' + cls.publication.accepted_submission.submitted_by.user.last_name + ', \n\nWe are happy to inform you that your Submission to SciPost,\n\n' + diff --git a/journals/views.py b/journals/views.py index 77c1df2b0b48ffc596807004214966204c6c898a..5a4bf03f75a2007a68dbaf387d081de9907db0d4 100644 --- a/journals/views.py +++ b/journals/views.py @@ -8,14 +8,13 @@ import xml.etree.ElementTree as ET from django.conf import settings from django.utils import timezone from django.shortcuts import get_object_or_404, render, redirect -from django.core.files import File from django.core.urlresolvers import reverse from django.db import transaction from django.http import HttpResponse -from .models import Issue, Publication, PaperNumberingError,\ - journal_name_abbrev_doi, paper_nr_string, journal_name_abbrev_citation,\ - UnregisteredAuthor +from .exceptions import PaperNumberingError +from .helpers import journal_name_abbrev_citation, journal_name_abbrev_doi, paper_nr_string +from .models import Issue, Publication, UnregisteredAuthor from .forms import FundingInfoForm, InitiatePublicationForm, ValidatePublicationForm,\ UnregisteredAuthorForm, CreateMetadataXMLForm, CitationListBibitemsForm from .utils import JournalUtils diff --git a/news/models.py b/news/models.py index 8f73d1be7c615125ae53c98b0f74a6f9b4d78748..a8992a3e7c5464b359a81208f4240c589e901320 100644 --- a/news/models.py +++ b/news/models.py @@ -1,5 +1,4 @@ from django.db import models -from django.template import Template, Context class NewsItem(models.Model): @@ -14,39 +13,3 @@ class NewsItem(models.Model): def __str__(self): return self.date.strftime('%Y-%m-%d') + ', ' + self.headline - - def descriptor_full(self): - """ For News page. """ - descriptor = ('<div class="flex-greybox640">' - '<h3 class="NewsHeadline">{{ headline }}</h3>' - '<p>{{ date }}</p>' - '<p>{{ blurb }}</p>' - ) - context = Context({'headline': self.headline, - 'date': self.date.strftime('%Y-%m-%d'), - 'blurb': self.blurb, }) - if self.followup_link: - descriptor += '<p><a href="{{ followup_link }}">{{ followup_link_text }}</a></p>' - context['followup_link'] = self.followup_link - context['followup_link_text'] = self.followup_link_text - descriptor += '</div>' - template = Template(descriptor) - return template.render(context) - - def descriptor_small(self): - """ For index page. """ - descriptor = ('<h3 class="NewsHeadline">{{ headline }}</h3>' - '<div class="p-2">' - '<p>{{ date }}</p>' - '<p>{{ blurb }}</p>' - ) - context = Context({'headline': self.headline, - 'date': self.date.strftime('%Y-%m-%d'), - 'blurb': self.blurb, }) - if self.followup_link: - descriptor += '<a href="{{ followup_link }}">{{ followup_link_text }}</a>' - context['followup_link'] = self.followup_link - context['followup_link_text'] = self.followup_link_text - descriptor += '</div>' - template = Template(descriptor) - return template.render(context) diff --git a/news/templates/news/news_card_content.html b/news/templates/news/news_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..fe8b19596f38c3b2bc802dc86fc2c77bf7f7a234 --- /dev/null +++ b/news/templates/news/news_card_content.html @@ -0,0 +1,11 @@ +<div class="card-header p-2 border-0"> + <h3 class="card-title mb-0">{{news.headline}}</h3> +</div> +<div class="card-block px-2"> + <h4 class="text-muted font-weight-bold">{{news.date|date:'Y-n-j'}}</h4> + <p>{{news.blurb|linebreaks}}</p> + + {% if news.followup_link %} + <a href="{{news.followup_link}}">{{news.followup_link_text}}</a> + {% endif %} +</div> diff --git a/scipost/behaviors.py b/scipost/behaviors.py index 32e689beb8574010e3f9e8621492dd00e717ada8..1140c889dd21a75820f85e10182286069b4a13f3 100644 --- a/scipost/behaviors.py +++ b/scipost/behaviors.py @@ -1,3 +1,9 @@ +from django.db import models +from django.utils import timezone + +from .db.fields import AutoDateTimeField + + class ArxivCallable(object): '''Models that contain a Arxiv identification should contain these methods to be compatible with the ArxivCaller(). @@ -6,3 +12,16 @@ class ArxivCallable(object): def same_version_exists(self, identifier): '''Check if the given identifier already is present in the database.''' raise NotImplementedError + + +class TimeStampedModel(models.Model): + """ + All objects should inherit from this abstract model. + This will ensure the creation of created and modified + timestamps in the objects. + """ + created = models.DateTimeField(default=timezone.now) + latest_activity = AutoDateTimeField(default=timezone.now) + + class Meta: + abstract = True diff --git a/scipost/constants.py b/scipost/constants.py index 5175737aab2fe2a7d5c3378996ac8b1f49aa3b57..2956972ceba3d9945703e54d685f3a3789a88c73 100644 --- a/scipost/constants.py +++ b/scipost/constants.py @@ -1,3 +1,6 @@ +import datetime + + DISCIPLINE_PHYSICS = 'physics' DISCIPLINE_ASTROPHYSICS = 'astrophysics' DISCIPLINE_MATH = 'mathematics' @@ -7,8 +10,7 @@ SCIPOST_DISCIPLINES = ( (DISCIPLINE_ASTROPHYSICS, 'Astrophysics'), (DISCIPLINE_MATH, 'Mathematics'), (DISCIPLINE_COMPUTERSCIENCE, 'Computer Science'), - ) -disciplines_dict = dict(SCIPOST_DISCIPLINES) +) SCIPOST_SUBJECT_AREAS = ( ('Physics', ( @@ -122,3 +124,101 @@ subject_areas_raw_dict = dict(SCIPOST_SUBJECT_AREAS) subject_areas_dict = {} for k in subject_areas_raw_dict.keys(): subject_areas_dict.update(dict(subject_areas_raw_dict[k])) + + +CONTRIBUTOR_STATUS = ( + # status determine the type of Contributor: + # 0: newly registered (unverified; not allowed to submit, comment or vote) + # 1: contributor has been vetted through + # + # Negative status denotes rejected requests or: + # -1: not a professional scientist (>= PhD student in known university) + # -2: other account already exists for this person + # -3: barred from SciPost (abusive behaviour) + # -4: disabled account (deceased) + (0, 'newly registered'), + (1, 'normal user'), + (-1, 'not a professional scientist'), + (-2, 'other account already exists'), + (-3, 'barred from SciPost'), + (-4, 'account disabled'), + ) + +TITLE_CHOICES = ( + ('PR', 'Prof.'), + ('DR', 'Dr'), + ('MR', 'Mr'), + ('MRS', 'Mrs'), +) + +INVITATION_EDITORIAL_FELLOW = 'F' +INVITATION_CONTRIBUTOR = 'C' +INVITATION_REFEREEING = 'R' +INVITATION_CITED_SUBMISSION = 'ci' +INVITATION_CITED_PUBLICATION = 'cp' +INVITATION_TYPE = ( + (INVITATION_EDITORIAL_FELLOW, 'Editorial Fellow'), + (INVITATION_CONTRIBUTOR, 'Contributor'), + (INVITATION_REFEREEING, 'Refereeing'), + (INVITATION_CITED_SUBMISSION, 'cited in submission'), + (INVITATION_CITED_PUBLICATION, 'cited in publication'), +) + +INVITATION_FORMAL = 'F' +INVITATION_PERSONAL = 'P' +INVITATION_STYLE = ( + (INVITATION_FORMAL, 'formal'), + (INVITATION_PERSONAL, 'personal'), +) + +AUTHORSHIP_CLAIM_ACCEPTED = 1 +AUTHORSHIP_CLAIM_PENDING = 0 +AUTHORSHIP_CLAIM_REJECTED = -1 +AUTHORSHIP_CLAIM_STATUS = ( + (AUTHORSHIP_CLAIM_ACCEPTED, 'accepted'), + (AUTHORSHIP_CLAIM_PENDING, 'not yet vetted (pending)'), + (AUTHORSHIP_CLAIM_REJECTED, 'rejected'), +) + +SCIPOST_FROM_ADDRESSES = ( + ('Admin', 'SciPost Admin <admin@scipost.org>'), + ('J.-S. Caux', 'J.-S. Caux <jscaux@scipost.org>'), + ('J. van Wezel', 'J. van Wezel <vanwezel@scipost.org>'), +) +SciPost_from_addresses_dict = dict(SCIPOST_FROM_ADDRESSES) + +# +# Supporting partner models +# +PARTNER_TYPES = ( + ('Int. Fund. Agency', 'International Funding Agency'), + ('Nat. Fund. Agency', 'National Funding Agency'), + ('Nat. Library', 'National Library'), + ('Univ. Library', 'University Library'), + ('Res. Library', 'Research Library'), + ('Consortium', 'Consortium'), + ('Foundation', 'Foundation'), + ('Individual', 'Individual'), +) + +PARTNER_STATUS = ( + ('Prospective', 'Prospective'), + ('Active', 'Active'), + ('Inactive', 'Inactive'), +) + + +SPB_MEMBERSHIP_AGREEMENT_STATUS = ( + ('Submitted', 'Request submitted by Partner'), + ('Pending', 'Sent to Partner, response pending'), + ('Signed', 'Signed by Partner'), + ('Honoured', 'Honoured: payment of Partner received'), +) + +SPB_MEMBERSHIP_DURATION = ( + (datetime.timedelta(days=365), '1 year'), + (datetime.timedelta(days=730), '2 years'), + (datetime.timedelta(days=1095), '3 years'), + (datetime.timedelta(days=1460), '4 years'), + (datetime.timedelta(days=1825), '5 years'), +) diff --git a/scipost/factories.py b/scipost/factories.py index 62eb21c81e74b9fa81c6d0c7892f06ef578bbc8c..7381d6173165155478253327f9aacac1665129c7 100644 --- a/scipost/factories.py +++ b/scipost/factories.py @@ -6,7 +6,8 @@ from django.contrib.auth.models import Group from django_countries.data import COUNTRIES -from .models import Contributor, EditorialCollege, EditorialCollegeFellowship, TITLE_CHOICES +from .models import Contributor, EditorialCollege, EditorialCollegeFellowship +from .constants import TITLE_CHOICES class ContributorFactory(factory.django.DjangoModelFactory): diff --git a/scipost/feeds.py b/scipost/feeds.py index 29ea0a31d6fced705e0c8fd6ac77381e7ed818f8..6edb9e1b7d4b1aaf221382ba83cff76a5064d27b 100644 --- a/scipost/feeds.py +++ b/scipost/feeds.py @@ -5,11 +5,12 @@ from django.utils.feedgenerator import Atom1Feed from django.core.urlresolvers import reverse from django.db.models import Q -from scipost.models import subject_areas_dict from comments.models import Comment from journals.models import Publication from news.models import NewsItem -from submissions.models import Submission, SUBMISSION_STATUS_PUBLICLY_INVISIBLE +from scipost.models import subject_areas_dict +from submissions.constants import SUBMISSION_STATUS_PUBLICLY_INVISIBLE +from submissions.models import Submission class LatestCommentsFeedRSS(Feed): diff --git a/scipost/fields.py b/scipost/fields.py new file mode 100644 index 0000000000000000000000000000000000000000..0e42e07039b5b136dc6444913f833df822d6c635 --- /dev/null +++ b/scipost/fields.py @@ -0,0 +1,19 @@ +from django import forms +from django.contrib.postgres.fields import ArrayField + + +class ChoiceArrayField(ArrayField): + """ + A field that allows us to store an array of choices. + Uses Django 1.9's postgres ArrayField + and a MultipleChoiceField for its formfield. + """ + + def formfield(self, **kwargs): + defaults = { + 'form_class': forms.MultipleChoiceField, + 'widget': forms.CheckboxSelectMultiple, + 'choices': self.base_field.choices, + } + defaults.update(kwargs) + return super(ArrayField, self).formfield(**defaults) diff --git a/scipost/forms.py b/scipost/forms.py index 3a85ac22032944518aae6cb8a7230eee68005bb9..6fa06cc261eec4e8f2e7999757031b7950c0394f 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -10,15 +10,13 @@ from captcha.fields import ReCaptchaField from crispy_forms.helper import FormHelper from crispy_forms.layout import Layout, Div, Field, HTML, Submit -from .constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS -from .models import TITLE_CHOICES, SCIPOST_FROM_ADDRESSES,\ - Contributor, DraftInvitation, RegistrationInvitation,\ +from .constants import SCIPOST_DISCIPLINES, TITLE_CHOICES, SCIPOST_FROM_ADDRESSES +from .models import Contributor, DraftInvitation, RegistrationInvitation,\ SupportingPartner, SPBMembershipAgreement,\ UnavailabilityPeriod, PrecookedEmail -from virtualmeetings.models import Feedback, Nomination, Motion from journals.models import Publication -from submissions.models import SUBMISSION_STATUS_PUBLICLY_UNLISTED +from submissions.constants import SUBMISSION_STATUS_PUBLICLY_UNLISTED from submissions.models import Submission @@ -315,60 +313,3 @@ class SPBMembershipForm(forms.ModelForm): css_class="col-4"), css_class="row"), ) - -# -# ################# -# # VGMs, Motions # -# ################# -# -# class FeedbackForm(forms.ModelForm): -# class Meta: -# model = Feedback -# fields = ['feedback'] -# -# -# class NominationForm(forms.ModelForm): -# class Meta: -# model = Nomination -# fields = ['first_name', 'last_name', -# 'discipline', 'expertises', 'webpage'] -# -# def __init__(self, *args, **kwargs): -# super(NominationForm, self).__init__(*args, **kwargs) -# self.fields['expertises'].widget = forms.SelectMultiple(choices=SCIPOST_SUBJECT_AREAS) -# -# -# class MotionForm(forms.ModelForm): -# class Meta: -# model = Motion -# fields = ['category', 'background', 'motion'] -# -# def __init__(self, *args, **kwargs): -# super(MotionForm, self).__init__(*args, **kwargs) -# self.fields['background'].label = '' -# self.fields['background'].widget.attrs.update( -# {'rows': 8, 'cols': 100, -# 'placeholder': 'Provide useful background information on your Motion.'}) -# self.fields['motion'].label = '' -# self.fields['motion'].widget.attrs.update( -# {'rows': 8, 'cols': 100, -# 'placeholder': 'Phrase your Motion as clearly and succinctly as possible.'}) -# self.helper = FormHelper() -# self.helper.layout = Layout( -# Field('category'), -# Div( -# Div(HTML('<p>Background:</p>'), -# css_class="col-2"), -# Div( -# Field('background'), -# css_class="col-10"), -# css_class="row"), -# Div( -# Div(HTML('<p>Motion:</p>'), -# css_class="col-2"), -# Div( -# Field('motion'), -# css_class="col-10"), -# css_class="row"), -# Submit('submit', 'Submit'), -# ) diff --git a/scipost/managers.py b/scipost/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..1572535c3b5175afef919a21d38e43a628ff7941 --- /dev/null +++ b/scipost/managers.py @@ -0,0 +1,15 @@ +import datetime + +from django.db import models +from django.db.models import Q + + +class FellowManager(models.Manager): + def active(self, *args, **kwargs): + today = datetime.date.today() + return self.filter( + Q(start_date__lte=today, until_date__isnull=True) | + Q(start_date__isnull=True, until_date__gte=today) | + Q(start_date__lte=today, until_date__gte=today) | + Q(start_date__isnull=True, until_date__isnull=True), + **kwargs).order_by('contributor__user__last_name') diff --git a/scipost/migrations/0013_auto_20160810_1608.py b/scipost/migrations/0013_auto_20160810_1608.py index e5d8565449276b8f486f92812c7dd00c96632757..67205d09c51b5a143c9542eaa5c168a80fb3bc0e 100644 --- a/scipost/migrations/0013_auto_20160810_1608.py +++ b/scipost/migrations/0013_auto_20160810_1608.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals from django.db import migrations, models import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -16,7 +17,7 @@ class Migration(migrations.Migration): migrations.AddField( model_name='contributor', name='expertises', - field=scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:A', 'Atomic, Molecular and Optical Physics'), ('Phys:B', 'Biophysics'), ('Phys:C', 'Condensed Matter Physics'), ('Phys:F', 'Fluid Dynamics'), ('Phys:G', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:H', 'High-Energy Physics'), ('Phys:M', 'Mathematical Physics'), ('Phys:N', 'Nuclear Physics'), ('Phys:Q', 'Quantum Statistical Mechanics'), ('Phys:S', 'Statistical and Soft Matter Physics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:PDE', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:ODE', 'Classical Analysis and ODEs'), ('Math:COMB', 'Combinatorics'), ('Math:CA', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GenT', 'General Topology'), ('Math:GeoT', 'Geometric Topology'), ('Math:Group', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:L', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:Proba', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SpecT', 'Spectral Theory'), ('Math:StatT', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), + field=scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:A', 'Atomic, Molecular and Optical Physics'), ('Phys:B', 'Biophysics'), ('Phys:C', 'Condensed Matter Physics'), ('Phys:F', 'Fluid Dynamics'), ('Phys:G', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:H', 'High-Energy Physics'), ('Phys:M', 'Mathematical Physics'), ('Phys:N', 'Nuclear Physics'), ('Phys:Q', 'Quantum Statistical Mechanics'), ('Phys:S', 'Statistical and Soft Matter Physics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:PDE', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:ODE', 'Classical Analysis and ODEs'), ('Math:COMB', 'Combinatorics'), ('Math:CA', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GenT', 'General Topology'), ('Math:GeoT', 'Geometric Topology'), ('Math:Group', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:L', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:Proba', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SpecT', 'Spectral Theory'), ('Math:StatT', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), ), migrations.AlterField( model_name='contributor', diff --git a/scipost/migrations/0014_auto_20160811_1057.py b/scipost/migrations/0014_auto_20160811_1057.py index 6adcb30188ed47f5c05c1048fa833c49c737df38..dd9fc91596bcb1dc89326e7a67a4f1a314058667 100644 --- a/scipost/migrations/0014_auto_20160811_1057.py +++ b/scipost/migrations/0014_auto_20160811_1057.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals from django.db import migrations, models import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -21,6 +22,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='contributor', name='expertises', - field=scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:A', 'Atomic, Molecular and Optical Physics'), ('Phys:B', 'Biophysics'), ('Phys:C', 'Condensed Matter Physics'), ('Phys:F', 'Fluid Dynamics'), ('Phys:G', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:H', 'High-Energy Physics'), ('Phys:M', 'Mathematical Physics'), ('Phys:N', 'Nuclear Physics'), ('Phys:Q', 'Quantum Statistical Mechanics'), ('Phys:S', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:PDE', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:ODE', 'Classical Analysis and ODEs'), ('Math:COMB', 'Combinatorics'), ('Math:CA', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GenT', 'General Topology'), ('Math:GeoT', 'Geometric Topology'), ('Math:Group', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:L', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:Proba', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SpecT', 'Spectral Theory'), ('Math:StatT', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), + field=scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:A', 'Atomic, Molecular and Optical Physics'), ('Phys:B', 'Biophysics'), ('Phys:C', 'Condensed Matter Physics'), ('Phys:F', 'Fluid Dynamics'), ('Phys:G', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:H', 'High-Energy Physics'), ('Phys:M', 'Mathematical Physics'), ('Phys:N', 'Nuclear Physics'), ('Phys:Q', 'Quantum Statistical Mechanics'), ('Phys:S', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:PDE', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:ODE', 'Classical Analysis and ODEs'), ('Math:COMB', 'Combinatorics'), ('Math:CA', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GenT', 'General Topology'), ('Math:GeoT', 'Geometric Topology'), ('Math:Group', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:L', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:Proba', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SpecT', 'Spectral Theory'), ('Math:StatT', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), ), ] diff --git a/scipost/migrations/0015_auto_20160811_1305.py b/scipost/migrations/0015_auto_20160811_1305.py index 297749de0c3674266ccf5b2c387e8f0642a4eb7f..8253a887e60eb4c6349de4dac58e649e44c14633 100644 --- a/scipost/migrations/0015_auto_20160811_1305.py +++ b/scipost/migrations/0015_auto_20160811_1305.py @@ -4,6 +4,7 @@ from __future__ import unicode_literals from django.db import migrations, models import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -21,6 +22,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='contributor', name='expertises', - field=scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), + field=scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), ), ] diff --git a/scipost/migrations/0032_auto_20170121_1032.py b/scipost/migrations/0032_auto_20170121_1032.py index 0ed75e0e513916b1b25223e3aea4a3d11e62339a..0e56271c226691e3a00debaaf504f5645c2c5d26 100644 --- a/scipost/migrations/0032_auto_20170121_1032.py +++ b/scipost/migrations/0032_auto_20170121_1032.py @@ -6,6 +6,7 @@ from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -23,7 +24,7 @@ class Migration(migrations.Migration): ('first_name', models.CharField(default='', max_length=30)), ('last_name', models.CharField(default='', max_length=30)), ('discipline', models.CharField(choices=[('physics', 'Physics'), ('astrophysics', 'Astrophysics'), ('mathematics', 'Mathematics'), ('computerscience', 'Computer Science')], default='physics', max_length=20, verbose_name='Main discipline')), - ('expertises', scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), + ('expertises', scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), ('nr_A', models.PositiveIntegerField(default=0)), ('nr_N', models.PositiveIntegerField(default=0)), ('nr_D', models.PositiveIntegerField(default=0)), diff --git a/scipost/models.py b/scipost/models.py index 2bb4c15cfb9b6ca2c262301852f55f68dbdad5c1..6cd70a7297cffa8436b78cc7a105806e86b6fb10 100644 --- a/scipost/models.py +++ b/scipost/models.py @@ -1,81 +1,32 @@ import datetime -from django import forms from django.contrib.auth.models import User from django.contrib.postgres.fields import ArrayField from django.db import models -from django.db.models import Q from django.template import Template, Context from django.utils import timezone -from django.utils.encoding import force_text from django.utils.safestring import mark_safe from django_countries.fields import CountryField +from .behaviors import TimeStampedModel from .constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\ - disciplines_dict, subject_areas_dict -from .db.fields import AutoDateTimeField - - -class ChoiceArrayField(ArrayField): - """ - A field that allows us to store an array of choices. - Uses Django 1.9's postgres ArrayField - and a MultipleChoiceField for its formfield. - """ - - def formfield(self, **kwargs): - defaults = { - 'form_class': forms.MultipleChoiceField, - 'widget': forms.CheckboxSelectMultiple, - 'choices': self.base_field.choices, - } - defaults.update(kwargs) - return super(ArrayField, self).formfield(**defaults) - - -CONTRIBUTOR_STATUS = ( - # status determine the type of Contributor: - # 0: newly registered (unverified; not allowed to submit, comment or vote) - # 1: contributor has been vetted through - # - # Negative status denotes rejected requests or: - # -1: not a professional scientist (>= PhD student in known university) - # -2: other account already exists for this person - # -3: barred from SciPost (abusive behaviour) - # -4: disabled account (deceased) - (0, 'newly registered'), - (1, 'normal user'), - (-1, 'not a professional scientist'), - (-2, 'other account already exists'), - (-3, 'barred from SciPost'), - (-4, 'account disabled'), - ) - -TITLE_CHOICES = ( - ('PR', 'Prof.'), - ('DR', 'Dr'), - ('MR', 'Mr'), - ('MRS', 'Mrs'), - ) -title_dict = dict(TITLE_CHOICES) - - -class TimeStampedModel(models.Model): - """ - All objects should inherit from this abstract model. - This will ensure the creation of created and modified - timestamps in the objects. - """ - created = models.DateTimeField(default=timezone.now) - latest_activity = AutoDateTimeField(default=timezone.now) - - class Meta: - abstract = True + subject_areas_dict, CONTRIBUTOR_STATUS, TITLE_CHOICES,\ + INVITATION_STYLE, INVITATION_TYPE,\ + INVITATION_CONTRIBUTOR, INVITATION_FORMAL,\ + AUTHORSHIP_CLAIM_PENDING, AUTHORSHIP_CLAIM_STATUS,\ + PARTNER_TYPES, PARTNER_STATUS,\ + SPB_MEMBERSHIP_AGREEMENT_STATUS, SPB_MEMBERSHIP_DURATION +from .fields import ChoiceArrayField +from .managers import FellowManager def get_sentinel_user(): - '''Fallback user for models relying on Contributor that is being deleted.''' + ''' + Temporary fix: eventually the 'to-be-removed-Contributor' should be + status: "deactivated" and anonymized. + Fallback user for models relying on Contributor that is being deleted. + ''' user, new = User.objects.get_or_create(username='deleted') return Contributor.objects.get_or_create(status=-4, user=user)[0] @@ -117,7 +68,8 @@ class Contributor(models.Model): return '%s, %s' % (self.user.last_name, self.user.first_name) def get_title(self): - return title_dict[self.title] + # Please use get_title_display(). To be removed in future + return self.get_title_display() def is_currently_available(self): unav_periods = UnavailabilityPeriod.objects.filter(contributor=self) @@ -145,7 +97,7 @@ class Contributor(models.Model): </table> ''') context = Context({ - 'title': title_dict[self.title], + 'title': self.get_title_display(), 'first_name': self.user.first_name, 'last_name': self.user.last_name, 'email': self.user.email, @@ -174,7 +126,7 @@ class Contributor(models.Model): </table> ''') context = Context({ - 'title': title_dict[self.title], + 'title': self.get_title_display(), 'first_name': self.user.first_name, 'last_name': self.user.last_name, 'email': self.user.email, @@ -187,7 +139,8 @@ class Contributor(models.Model): return template.render(context) def discipline_as_string(self): - return disciplines_dict[self.discipline] + # Redundant, to be removed in future + return self.get_discipline_display() def expertises_as_ul(self): output = '<ul>' @@ -288,20 +241,6 @@ class Remark(models.Model): # Invitations # ############### -INVITATION_TYPE = ( - ('F', 'Editorial Fellow'), - ('C', 'Contributor'), - ('R', 'Refereeing'), - ('ci', 'cited in submission'), - ('cp', 'cited in publication'), - ) - -INVITATION_STYLE = ( - ('F', 'formal'), - ('P', 'personal'), - ) - - class DraftInvitation(models.Model): """ Draft of an invitation, filled in by an officer. @@ -310,7 +249,8 @@ class DraftInvitation(models.Model): first_name = models.CharField(max_length=30, default='') last_name = models.CharField(max_length=30, default='') email = models.EmailField() - invitation_type = models.CharField(max_length=2, choices=INVITATION_TYPE, default='C') + invitation_type = models.CharField(max_length=2, choices=INVITATION_TYPE, + default=INVITATION_CONTRIBUTOR) cited_in_submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE, blank=True, null=True) @@ -335,14 +275,16 @@ class RegistrationInvitation(models.Model): first_name = models.CharField(max_length=30, default='') last_name = models.CharField(max_length=30, default='') email = models.EmailField() - invitation_type = models.CharField(max_length=2, choices=INVITATION_TYPE, default='C') + invitation_type = models.CharField(max_length=2, choices=INVITATION_TYPE, + default=INVITATION_CONTRIBUTOR) cited_in_submission = models.ForeignKey('submissions.Submission', on_delete=models.CASCADE, blank=True, null=True) cited_in_publication = models.ForeignKey('journals.Publication', on_delete=models.CASCADE, blank=True, null=True) - message_style = models.CharField(max_length=1, choices=INVITATION_STYLE, default='F') + message_style = models.CharField(max_length=1, choices=INVITATION_STYLE, + default=INVITATION_FORMAL) personal_message = models.TextField(blank=True, null=True) invitation_key = models.CharField(max_length=40, default='') key_expires = models.DateTimeField(default=timezone.now) @@ -381,13 +323,6 @@ class CitationNotification(models.Model): return text -AUTHORSHIP_CLAIM_STATUS = ( - (1, 'accepted'), - (0, 'not yet vetted (pending)'), - (-1, 'rejected'), -) - - class AuthorshipClaim(models.Model): claimant = models.ForeignKey(Contributor, on_delete=models.CASCADE, @@ -404,15 +339,8 @@ class AuthorshipClaim(models.Model): vetted_by = models.ForeignKey(Contributor, on_delete=models.CASCADE, blank=True, null=True) - status = models.SmallIntegerField(choices=AUTHORSHIP_CLAIM_STATUS, default=0) - - -SCIPOST_FROM_ADDRESSES = ( - ('Admin', 'SciPost Admin <admin@scipost.org>'), - ('J.-S. Caux', 'J.-S. Caux <jscaux@scipost.org>'), - ('J. van Wezel', 'J. van Wezel <vanwezel@scipost.org>'), -) -SciPost_from_addresses_dict = dict(SCIPOST_FROM_ADDRESSES) + status = models.SmallIntegerField(choices=AUTHORSHIP_CLAIM_STATUS, + default=AUTHORSHIP_CLAIM_PENDING) class PrecookedEmail(models.Model): @@ -447,26 +375,6 @@ class AffiliationObject(models.Model): # Supporting Partners Board # ############################# -PARTNER_TYPES = ( - ('Int. Fund. Agency', 'International Funding Agency'), - ('Nat. Fund. Agency', 'National Funding Agency'), - ('Nat. Library', 'National Library'), - ('Univ. Library', 'University Library'), - ('Res. Library', 'Research Library'), - ('Consortium', 'Consortium'), - ('Foundation', 'Foundation'), - ('Individual', 'Individual'), -) -partner_types_dict = dict(PARTNER_TYPES) - -PARTNER_STATUS = ( - ('Prospective', 'Prospective'), - ('Active', 'Active'), - ('Inactive', 'Inactive'), -) -partner_status_dict = dict(PARTNER_STATUS) - - class SupportingPartner(models.Model): """ Supporting Partners. @@ -480,25 +388,7 @@ class SupportingPartner(models.Model): contact_person = models.ForeignKey(Contributor, on_delete=models.CASCADE) def __str__(self): - return self.institution_acronym + ' (' + partner_status_dict[self.status] + ')' - - -SPB_MEMBERSHIP_AGREEMENT_STATUS = ( - ('Submitted', 'Request submitted by Partner'), - ('Pending', 'Sent to Partner, response pending'), - ('Signed', 'Signed by Partner'), - ('Honoured', 'Honoured: payment of Partner received'), -) -SPB_membership_agreement_status_dict = dict(SPB_MEMBERSHIP_AGREEMENT_STATUS) - -SPB_MEMBERSHIP_DURATION = ( - (datetime.timedelta(days=365), '1 year'), - (datetime.timedelta(days=730), '2 years'), - (datetime.timedelta(days=1095), '3 years'), - (datetime.timedelta(days=1460), '4 years'), - (datetime.timedelta(days=1825), '5 years'), -) -spb_membership_duration_dict = dict(SPB_MEMBERSHIP_DURATION) + return self.institution_acronym + ' (' + self.get_status_display() + ')' class SPBMembershipAgreement(models.Model): @@ -515,7 +405,7 @@ class SPBMembershipAgreement(models.Model): def __str__(self): return (str(self.partner) + - ' [' + spb_membership_duration_dict[self.duration] + + ' [' + self.get_duration_display() + ' from ' + self.start_date.strftime('%Y-%m-%d') + ']') @@ -523,17 +413,6 @@ class SPBMembershipAgreement(models.Model): # Static info models # ###################### -class FellowManager(models.Manager): - def active(self, *args, **kwargs): - today = datetime.date.today() - return self.filter( - Q(start_date__lte=today, until_date__isnull=True) | - Q(start_date__isnull=True, until_date__gte=today) | - Q(start_date__lte=today, until_date__gte=today) | - Q(start_date__isnull=True, until_date__isnull=True), - **kwargs).order_by('contributor__user__last_name') - - class EditorialCollege(models.Model): '''A SciPost Editorial College for a specific discipline.''' discipline = models.CharField(max_length=255, unique=True) diff --git a/scipost/static/scipost/assets/config/preconfig.scss b/scipost/static/scipost/assets/config/preconfig.scss index 0ca0434f571a37fc3d31d816d25957730b6091f2..e924f4f07db1eaf8e875412d873bf70b3136edb1 100644 --- a/scipost/static/scipost/assets/config/preconfig.scss +++ b/scipost/static/scipost/assets/config/preconfig.scss @@ -24,9 +24,11 @@ $card-border-color: rgba(238, 238, 238, 0.5); // Colors // +$scipost-light: #C3D7EE; $scipost-lightblue: #6884C2; $scipost-darkblue: #002b49; $scipost-orange: #FFA300; +$green: #6ebb6e; $blue: $scipost-lightblue !default; $body-color: $scipost-darkblue !default; @@ -63,6 +65,10 @@ $font-size-h4: 0.8rem; $font-size-h5: 0.8rem; $font-size-h6: 0.8rem; +// Tables +// +$table-cell-padding: 0.25rem 0.5rem; + // Navbar // diff --git a/scipost/static/scipost/assets/css/_buttons.scss b/scipost/static/scipost/assets/css/_buttons.scss index 90781a20da4ef3d3fb0a51dc4953bef2e104771a..3646c5181e9edd3179e727450cadb28d9ebdb5d3 100644 --- a/scipost/static/scipost/assets/css/_buttons.scss +++ b/scipost/static/scipost/assets/css/_buttons.scss @@ -6,3 +6,56 @@ cursor: pointer; font-family: inherit; } + +.category-group, +.voting-group { + border-radius: 0.05rem; + + .btn { + color: #fff; + box-shadow: 0 1px 1px 0 #ccc; + border-color: #ccc; + margin: 0; + font-size: 0.7rem; + border-radius: 0.05rem; + cursor: default; + + &.agree { + background-color: $scipost-darkblue; + } + &.neutral { + background-color: $scipost-lightblue; + } + &.disagree { + background-color: $red; + } + } + + &.small .btn { + font-size: 0.55rem; + } + + form .btn { + cursor: pointer; + + &.agree:hover { + background-color: #004f86; + } + &.neutral:hover { + background-color: #045f9e; + } + &.disagree:hover { + background-color: #c9302c; + } + } +} + +.category-group .btn { + color: #333; + background-color: #fafafa; + + &.name { + background-color: #ddd; + color: #002b49; + } +} diff --git a/scipost/static/scipost/assets/css/_cards.scss b/scipost/static/scipost/assets/css/_cards.scss index 2fe5f997e617af4967c022c0c15eb03bb448fd0a..78bce205b80996f4d7607e1bbfa19301cccc45e7 100644 --- a/scipost/static/scipost/assets/css/_cards.scss +++ b/scipost/static/scipost/assets/css/_cards.scss @@ -4,6 +4,16 @@ &.card-grey { background-color: #F4F4F4; } + + &.card-publication { + .card-header { + background-color: #eee; + } + + .card-block { + background-color: #f8f8f8; + } + } } .list-group-item > .card-block { @@ -14,3 +24,14 @@ .card-text { margin-bottom: 0.25rem; } + +.card-subtitle { + line-height: 1.5; +} + +.card.card-news { + .card-header { + background-color: $scipost-darkblue; + color: $scipost-light; + } +} diff --git a/scipost/static/scipost/assets/css/_general.scss b/scipost/static/scipost/assets/css/_general.scss new file mode 100644 index 0000000000000000000000000000000000000000..b3f467cd09b7050a18ec50b7aba415a88554dd6d --- /dev/null +++ b/scipost/static/scipost/assets/css/_general.scss @@ -0,0 +1,16 @@ +.banner { + background-color: #002b49; + line-height: 1.5; + padding: 10px 20px; + text-align: center; + border-radius: 1.4px; + + &, + a { + color: #FFA300; + } +} + +.bg-transparent { + background-color: transparent; +} diff --git a/scipost/static/scipost/assets/css/_list_group.scss b/scipost/static/scipost/assets/css/_list_group.scss new file mode 100644 index 0000000000000000000000000000000000000000..773da713e8db185741b7b2c6288588e6f557b5a8 --- /dev/null +++ b/scipost/static/scipost/assets/css/_list_group.scss @@ -0,0 +1,4 @@ + .list-group-noborder, + .list-group-noborder .list-group-item { + border: 0; + } diff --git a/scipost/static/scipost/assets/css/_submissions.scss b/scipost/static/scipost/assets/css/_submissions.scss index a2c299931cd9ce9a2306612835ffb2cc03deee72..0b8166e69f7fbc3991d9dcf59e17a1c753f89d2d 100644 --- a/scipost/static/scipost/assets/css/_submissions.scss +++ b/scipost/static/scipost/assets/css/_submissions.scss @@ -27,4 +27,8 @@ table.submission_header { background-color: $brand-danger; color: $white; border-radius: $card-border-radius; + + &.no-actions { + background-color: $brand-success; + } } diff --git a/scipost/static/scipost/assets/css/_tables.scss b/scipost/static/scipost/assets/css/_tables.scss new file mode 100644 index 0000000000000000000000000000000000000000..f5804cd57081915cd0ddd6da358bd5177562f70d --- /dev/null +++ b/scipost/static/scipost/assets/css/_tables.scss @@ -0,0 +1,12 @@ +.table { + th, + td { + padding: $table-cell-padding; + vertical-align: middle; + } +} + + +.table-invitations { + background-color: #ddd; +} diff --git a/scipost/static/scipost/assets/css/_type.scss b/scipost/static/scipost/assets/css/_type.scss index f352738152fabc94e77a394155b560e9946840c1..6c6ce87ccb03805e7664ababd65ec22117d6e01b 100644 --- a/scipost/static/scipost/assets/css/_type.scss +++ b/scipost/static/scipost/assets/css/_type.scss @@ -22,17 +22,29 @@ h1, h2, h3, h4, h5, h6 { .highlight { background-color: #f4f4f4; margin: 10px 0; + border-radius: 1.4px; &.tight { display: inline-block; padding: 3px 5px; } } +.highlight-inline { + padding: 0.15rem 0.3rem; + background-color: #f4f4f4; + border-radius: 0.15rem; + color: #6884C2; +} + h1.highlight, h2.highlight { padding: 15px; } +h3.highlight { + padding: 10px; +} + hr, hr.hr12 { height: 3px; diff --git a/scipost/static/scipost/assets/css/style.scss b/scipost/static/scipost/assets/css/style.scss index 50ebdb189857fbc100f2cd5e0b7f5098941bafa0..b40f5ca89e040ec6aaa5d37cde766c8709ee29e8 100644 --- a/scipost/static/scipost/assets/css/style.scss +++ b/scipost/static/scipost/assets/css/style.scss @@ -23,10 +23,12 @@ @import "form"; @import "grid"; @import "labels"; +@import "list_group"; @import "messages"; // @import "modal"; @import "navbar"; @import "page_header"; +@import "tables"; @import "tooltip"; @import "type"; @@ -34,6 +36,8 @@ * SciPost Specific * */ +@import "general"; + @import "about"; @import "comments"; @import "journals"; diff --git a/scipost/static/scipost/assets/js/scripts.js b/scipost/static/scipost/assets/js/scripts.js index 001f02c0ead487734d86757d0d303035c10f7343..ff2b6d6312ad34227951b20ec566e1ba7841ace8 100644 --- a/scipost/static/scipost/assets/js/scripts.js +++ b/scipost/static/scipost/assets/js/scripts.js @@ -5,4 +5,9 @@ function hide_all_alerts() { $(function(){ // Remove all alerts in screen automatically after 10sec. setTimeout(function() {hide_all_alerts()}, 10000); + + // Start general toggle + $('[data-toggle="toggle"]').on('click', function() { + $($(this).attr('data-target')).toggle(); + }); }); diff --git a/scipost/templates/scipost/Fellow_activity_overview.html b/scipost/templates/scipost/Fellow_activity_overview.html index 273de7c154e07d186decdbe4750d63948edb282e..3e2bacaa8d6f19781f406e14d306a351e64d8a80 100644 --- a/scipost/templates/scipost/Fellow_activity_overview.html +++ b/scipost/templates/scipost/Fellow_activity_overview.html @@ -2,78 +2,79 @@ {% block pagetitle %}: Overview{% endblock pagetitle %} -{% block headsup %} - -{% endblock headsup %} - -{% block bodysup %} - {% load scipost_extras %} {% load submissions_extras %} -<section> - <div class="flex-container"> - <div class="flex-greybox"> - <h1>Overview of Fellows's activities</h1> +{% block content %} + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Overview of Fellows's activities</h1> + <h3>Click on a Fellow's name to view full assignment details.</h3> </div> - </div> - <p>Click on a Fellow's name to view full assignment details.</p> - <table class="assignments_listing"> - <thead> - <th>Name</th> - <th>Expertises</th> - <th>Ongoing</th> - <th>Assignments<br/>last yr / tot</th> - <th>Accepted<br/>last yr / tot</th> - <th>Refused<br/>last yr / tot</th> - <th>Ignored<br/>last yr / tot</th> - <th>Fulfilled<br/>last yr / tot</th> - </thead> - <tbody> - {% for Fellow in Fellows %} - <tr> - <td><a href="{% url 'scipost:Fellow_activity_overview' Fellow_id=Fellow.id %}">{{ Fellow.user.last_name }}, {{ Fellow.user.first_name }}</a></td> - {{ Fellow.assignments_summary_as_td }} - </tr> - {% endfor %} - </tbody> - </table> +</div> -</section> +<div class="row"> + <div class="col-12"> + <table class="assignments_listing w-100"> + <thead> + <th>Name</th> + <th>Expertises</th> + <th>Ongoing</th> + <th>Assignments<br/>last yr / tot</th> + <th>Accepted<br/>last yr / tot</th> + <th>Refused<br/>last yr / tot</th> + <th>Ignored<br/>last yr / tot</th> + <th>Fulfilled<br/>last yr / tot</th> + </thead> + <tbody> + {% for fellow in fellows %} + <tr> + <td><a href="{% url 'scipost:Fellow_activity_overview' Fellow_id=fellow.id %}">{{ fellow.user.last_name }}, {{ fellow.user.first_name }}</a></td> + {{ fellow.assignments_summary_as_td }} + </tr> + {% endfor %} + </tbody> + </table> + </div> +</div> -{% if Fellow %} -<section> - <div class="flex-container"> - <div class="flex-greybox"> - <h1>Overview of Fellows's activities</h1> +{% if fellow %} + <div class="row"> + <div class="col-12"> + <h3 class="highlight">Assignments for {{ fellow.user.first_name }} {{ fellow.user.last_name }}</h3> + </div> </div> - </div> - <h3>Assignments for {{ Fellow.user.first_name }} {{ Fellow.user.last_name }}</h3> - <h4>Ongoing:</h4> - <ul> - {% for assignment in assignments_of_Fellow %} - {% if assignment.accepted and not assignment.completed %} - {% if request.user|is_not_author_of_submission:assignment.submission.arxiv_identifier_w_vn_nr %} - {{ assignment.header_as_li }} - {% endif %} - {% endif %} - {% endfor %} - </ul> + <div class="row"> + <div class="col-12"> + <h3>Ongoing:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for assignment in assignments_ongoing %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_contributor_content.html' with submission=assignment.submission %} + </li> + {% endfor %} + </ul> + </div> - <h4>Completed:</h4> - <ul> - {% for assignment in assignments_of_Fellow %} - {% if assignment.completed %} - {% if request.user|is_not_author_of_submission:assignment.submission.arxiv_identifier_w_vn_nr %} - {{ assignment.header_as_li }} - {% endif %} - {% endif %} - {% endfor %} - </ul> + <div class="col-12"> + <h3>Completed:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for assignment in assignments_completed %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_contributor_content.html' with submission=assignment.submission %} + </li> + {% endfor %} + </ul> + </div> + </div> -</section> {% endif %} -{% endblock bodysup %} +{% endblock content %} diff --git a/scipost/templates/scipost/_contributor_short.html b/scipost/templates/scipost/_contributor_short.html index 412c56712c22cb699f7b4093889d015ec46bf7e8..2055f37d736ae795d1ccc69cef2b3468b018a4eb 100644 --- a/scipost/templates/scipost/_contributor_short.html +++ b/scipost/templates/scipost/_contributor_short.html @@ -2,7 +2,7 @@ {% load static %} -<h3 class="mb-0 py-0 d-block"> +<h3 class="mb-0 pb-0 d-block"> {% if contributor.personalwebpage %} <a target="_blank" href="{{ contributor.personalwebpage }}"> {% endif %} diff --git a/scipost/templates/scipost/about.html b/scipost/templates/scipost/about.html index 0728f95d21542d31d73333adfaeca93c40f77f22..3dc00b19359f5f4017fc58d8a5f6e1d21f3bdf5f 100644 --- a/scipost/templates/scipost/about.html +++ b/scipost/templates/scipost/about.html @@ -159,7 +159,7 @@ {% if codes %} <div class="row"> <div class="col-12"> - <a href="javascript:;" class="d-block mb-1" data-toggle="toggle-show" data-target="#specializations-{{college|lower}}">Show all specialization codes</a> + <a href="#editorial_college_{{ college|lower }}" class="d-block mb-1" data-toggle="toggle-show" data-target="#specializations-{{college|lower}}">Show Fellows by specialization</a> <div id="specializations-{{college|lower}}" class="all-specializations" style="border: 1px solid; display: none;"> {% for code in codes %} <div class="specialization" data-specialization="{{code.0|lower}}">{{code.0}} - {{code.1}}</div> diff --git a/scipost/templates/scipost/claim_authorships.html b/scipost/templates/scipost/claim_authorships.html index 2554bd2ed89b73fde73120e1ff6720ae69f5d8e0..2630c6844582f8b7e476ad2063d3884044977a44 100644 --- a/scipost/templates/scipost/claim_authorships.html +++ b/scipost/templates/scipost/claim_authorships.html @@ -6,81 +6,104 @@ {% endblock headsup %} -{% block bodysup %} +{% block content %} -<section> - <div class="flex-greybox"> - <h1>Contributor Authorship Claims</h1> - </div> - - {% if submission_authorships_to_claim %} - <hr class="hr12"> - <div class="flex-greybox"> - <h1>SciPost Submissions</h1> +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Contributor Authorship Claims</h1> </div> - <h3>Potential authorships to claim (auto-detected)</h3> - <ul> - {% for sub in submission_authorships_to_claim %} - {{ sub.header_as_li }} - <form action="{% url 'scipost:claim_sub_authorship' submission_id=sub.id claim=1%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am an author" /> - </form> - <form action="{% url 'scipost:claim_sub_authorship' submission_id=sub.id claim=0%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am not an author" /> - </form> - {% endfor %} - </ul> - {% endif %} +</div> - {% if commentary_authorships_to_claim %} - <hr class="hr12"> - <div class="flex-greybox"> - <h1>SciPost Commentaries</h1> +{% if submission_authorships_to_claim %} + <div class="row"> + <div class="col-12"> + <h2 class="highlight">SciPost Submissions</h2> + <h3>Potential authorships to claim (auto-detected)</h3> + </div> </div> - <h3>Potential authorships to claim (auto-detected)</h3> - <ul> - {% for com in commentary_authorships_to_claim %} - {{ com.header_as_li }} - <form action="{% url 'scipost:claim_com_authorship' commentary_id=com.id claim=1%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am an author" /> - </form> - <form action="{% url 'scipost:claim_com_authorship' commentary_id=com.id claim=0%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am not an author" /> - </form> - {% endfor %} - </ul> - {% endif %} + <div class="row"> + <div class="col-12"> + {% for sub in submission_authorships_to_claim %} + <div class="card"> + {% include 'submissions/_submission_card_content.html' with submission=sub %} + <div class="card-footer"> + <form class="d-inline-block" action="{% url 'scipost:claim_sub_authorship' submission_id=sub.id claim=1 %}" method="post"> + {% csrf_token %} + <input class="btn btn-secondary" type="submit" value="I am an author" /> + </form> + <form class="d-inline-block ml-1" action="{% url 'scipost:claim_sub_authorship' submission_id=sub.id claim=0 %}" method="post"> + {% csrf_token %} + <input class="btn btn-danger" type="submit" value="I am not an author" /> + </form> + </div> + </div> + {% endfor %} + </div> + </div> +{% endif %} - {% if thesis_authorships_to_claim %} - <hr class="hr12"> - <div class="flex-greybox"> - <h1>SciPost Thesis Links</h1> +{% if commentary_authorships_to_claim %} + <div class="row"> + <div class="col-12"> + <h2 class="highlight">SciPost Commentaries</h2> + <h3>Potential authorships to claim (auto-detected)</h3> + </div> + </div> + <div class="row"> + <div class="col-12"> + {% for com in commentary_authorships_to_claim %} + <div class="card"> + {% include 'commentaries/_commentary_card_content.html' with commentary=com %} + <div class="card-footer"> + <form class="d-inline-block" action="{% url 'scipost:claim_com_authorship' commentary_id=com.id claim=1 %}" method="post"> + {% csrf_token %} + <input class="btn btn-secondary" type="submit" value="I am an author" /> + </form> + <form class="d-inline-block ml-1" action="{% url 'scipost:claim_com_authorship' commentary_id=com.id claim=0 %}" method="post"> + {% csrf_token %} + <input class="btn btn-danger" type="submit" value="I am not an author" /> + </form> + </div> + </div> + {% endfor %} + </div> </div> - <h3>Potential authorships to claim (auto-detected)</h3> - <ul> - {% for thesis in thesis_authorships_to_claim %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesis %} - <form action="{% url 'scipost:claim_thesis_authorship' thesis_id=thesis.id claim=1%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am an author" /> - </form> - <form action="{% url 'scipost:claim_thesis_authorship' thesis_id=thesis.id claim=0%}" method="post"> - {% csrf_token %} - <input type="submit" value="I am not an author" /> - </form> - {% endfor %} - </ul> {% endif %} - {% if not submission_authorships_to_claim and not commentary_authorships_to_claim and not thesis_authorships_to_claim %} - <hr class="hr12"> - <h1>You have no authorships to claim</h1> - {% endif %} +{% if thesis_authorships_to_claim %} + <div class="row"> + <div class="col-12"> + <h2 class="highlight">SciPost Thesis Links</h2> + <h3>Potential authorships to claim (auto-detected)</h3> + </div> + </div> + <div class="row"> + <div class="col-12"> + {% for thesis in thesis_authorships_to_claim %} + <div class="card"> + {% include 'theses/_thesislink_card_content.html' with thesislink=thesis %} + <div class="card-footer"> + <form class="d-inline-block" action="{% url 'scipost:claim_thesis_authorship' thesis_id=thesis.id claim=1%}" method="post"> + {% csrf_token %} + <input class="btn btn-secondary" type="submit" value="I am an author" /> + </form> + <form class="d-inline-block ml-1" action="{% url 'scipost:claim_thesis_authorship' thesis_id=thesis.id claim=0%}" method="post"> + {% csrf_token %} + <input class="btn btn-danger" type="submit" value="I am not an author" /> + </form> + </div> + </div> + {% endfor %} + </div> + </div> +{% endif %} -</section> +{% if not submission_authorships_to_claim and not commentary_authorships_to_claim and not thesis_authorships_to_claim %} +<div class="row"> + <div class="col-12"> + <h2>You have no authorships to claim</h2> + </div> +</div> +{% endif %} -{% endblock bodysup %} +{% endblock content %} diff --git a/scipost/templates/scipost/comments_block.html b/scipost/templates/scipost/comments_block.html index babd085c7a2678c783f26dc4fac4079243c1bde3..9b9507f085931320986c9eb93c5ac93131b2260a 100644 --- a/scipost/templates/scipost/comments_block.html +++ b/scipost/templates/scipost/comments_block.html @@ -1,151 +1,19 @@ -{% load scipost_extras %} - -{% load filename %} -{% load file_extentions %} - {% if comments %} <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Comments on this publication</h2> - <button class="btn btn-secondary" id="commentsbutton">Toggle comments view</button> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Comments on this publication</h2> + <button class="btn btn-secondary" data-toggle="toggle" data-target="#commentslist">Toggle comments view</button> + </div> </div> </div> </div> -<div class="row" id="commentslist"> +<div id="commentslist"> {% for comment in comments %} - <div class="col-12"> - <div class="comment"> - - <div class="row"> - <div class="col-12"> - {{ comment.print_identifier }} - {{ comment.categories_as_ul }} - - <div class="opinionsDisplay"> - {% if user.is_authenticated and perms.scipost.can_express_opinion_on_comments %} - {% if user.contributor != comment.author %} - <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='A' %}" method="post"> - {% csrf_token %} - <input type="submit" class="agree" value="Agree {{ comment.nr_A }} "/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='N' %}" method="post"> - {% csrf_token %} - <input type="submit" class="notsure" value="Not sure {{ comment.nr_N }}"/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=comment.id opinion='D'%}" method="post"> - {% csrf_token %} - <input type="submit" class="disagree" value="Disagree {{ comment.nr_D }}"/> - </form> - {% else %} - {{ comment.opinions_as_ul }} - {% endif %} - {% endif %} - </div> - </div> - </div> - - - <div class="row"> - <div class="col-12"> - <p> - {{ comment.comment_text|linebreaks }} - - {% if comment.file_attachment %} - <h3>Attachment:</h3> - <p> - <a target="_blank" href="{{ comment.file_attachment.url }}"> - {% if comment.file_attachment|is_image %} - <img class="attachment attachment-comment" src="{{ comment.file_attachment.url }}"> - {% else %} - {{ comment.file_attachment|filename }}<br><small>{{ comment.file_attachment.size|filesizeformat }}</small> - {% endif %} - </a> - </p> - {% endif %} - </p> - {% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' %} - {% if comment.remarks_for_editors %} - <h3>Remarks for editors:</h3> - <p>{{ comment.remarks_for_editors|linebreaks }}</p> - {% endif %} - {% endif %} - </div> - </div> - - {% for reply in author_replies %} - {% if reply.in_reply_to_comment %} - {% if reply.in_reply_to_comment.id == comment.id %} - <div class="row"> - <div class="col-12"> - {{ reply.print_identifier }} - {{ reply.categories_as_ul }} - <div class="opinionsDisplay"> - {% if user.is_authenticated and perms.scipost.can_express_opinion_on_comments %} - {% if user.contributor != reply.author %} - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='A' %}" method="post"> - {% csrf_token %} - <input type="submit" class="agree" value="Agree {{ reply.nr_A }} "/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='N' %}" method="post"> - {% csrf_token %} - <input type="submit" class="notsure" value="Not sure {{ reply.nr_N }}"/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='D'%}" method="post"> - {% csrf_token %} - <input type="submit" class="disagree" value="Disagree {{ reply.nr_D }}"/> - </form> - {% else %} - {{ reply.opinions_as_ul }} - {% endif %} - {% endif %} - </div> - </div> - </div> - - <div class="row"> - <div class="col-12"> - <p> - {{ reply.comment_text|linebreaks }} - {% 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 %} - </p> - - {% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' %} - {% if reply.remarks_for_editors %} - <h3>Remarks for editors:</h3> - <p>{{ reply.remarks_for_editors|linebreaks }}</p> - {% endif %} - {% endif %} - </div> - </div> - - {% endif %} - {% endif %} - {% endfor %} - - {% if user.is_authenticated and perms.scipost.can_submit_comments %} - <hr class="small"> - <div class="row"> - <div class="col-12"> - <h3><a href="{% url 'comments:reply_to_comment' comment_id=comment.id %}">Reply to this comment</a></h3> - </div> - </div> - {% endif %} - </div> - </div> + {% include 'comments/_single_comment_with_link.html' with comment=comment perms=perms user=request.user %} {% endfor %} </div> {% endif %} diff --git a/scipost/templates/scipost/contributor_info.html b/scipost/templates/scipost/contributor_info.html index be6f2d0bbbafb4e05494ee4c822a85d8c8c12dc9..7160c77f293a90c85add66d4306a4206bbbaeba6 100644 --- a/scipost/templates/scipost/contributor_info.html +++ b/scipost/templates/scipost/contributor_info.html @@ -2,146 +2,132 @@ {% block pagetitle %}: personal page{% endblock pagetitle %} -{% block headsup %} +{% block content %} -<script> - $(document).ready(function(){ - $("#mypublicationsbutton").click(function(){ - $("#mypublicationslist").toggle(); - }); - $("#mysubmissionsbutton").click(function(){ - $("#mysubmissionslist").toggle(); - }); - $("#mycommentariesbutton").click(function(){ - $("#mycommentarieslist").toggle(); - }); - $("#mythesesbutton").click(function(){ - $("#mytheseslist").toggle(); - }); - $("#mycommentsbutton").click(function(){ - $("#mycommentslist").toggle(); - }); - $("#myauthorrepliesbutton").click(function(){ - $("#myauthorreplieslist").toggle(); - }); - }); -</script> +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Contributor info</h1> + </div> +</div> -{% endblock headsup %} - -{% block bodysup %} - -<section> - <div class="flex-greybox"> - <h1>Contributor info</h1> - </div> - {{ contributor.public_info_as_table }} -</section> +{{ contributor.public_info_as_table }} {% if contributor_publications %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Publications</h1> - <button id="mypublicationsbutton">View/hide publications</button> - </div> - <div id="mypublicationslist"> - <h3>Publications for which this Contributor is identified as an author:</h3> - <ul> - {% for pub in contributor_publications %} - {{ pub.header_as_li }} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Publications <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#mypublicationslist">View/hide publications</span></h2> + </div> + <div class="col-12" id="mypublicationslist"> + <h3 class="mb-2">Publications for which this Contributor is identified as an author:</h3> + {% for pub in contributor_publications %} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=pub %} + </div> + {% endfor %} + </div> + </div> + {% endif %} {% if contributor_submissions %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Submissions</h1> - <button id="mysubmissionsbutton">View/hide submissions</button> - </div> - <div id="mysubmissionslist"> - <h3>Submissions for which this Contributor is identified as an author:</h3> - <ul> - {% for sub in contributor_submissions %} - {{ sub.header_as_li }} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Submissions <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#mysubmissionslist">View/hide submissions</span></h2> + </div> + <div class="col-12" id="mysubmissionslist"> + <h3>Submissions for which this Contributor is identified as an author:</h3> + <div> + <ul class="list-group list-group-flush"> + {% for sub in contributor_submissions %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_content.html' with submission=sub %} + </li> + {% endfor %} + </ul> + </div> + </div> + </div> {% endif %} {% if contributor_commentaries %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Commentaries</h1> - <button id="mycommentariesbutton">View/hide commentaries</button> - </div> - <div id="mycommentarieslist"> - <h3>Commentaries for which this Contributor is identified as an author:</h3> - <ul> - {% for com in contributor_commentaries %} - {{ com.header_as_li }} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Commentaries <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#mycommentarieslist">View/hide commentaries</span></h2> + + </div> + <div class="col-12" id="mycommentarieslist"> + <h3>Commentaries for which this Contributor is identified as an author:</h3> + <div> + <ul class="list-group list-group-flush"> + {% for com in contributor_commentaries %} + <li class="list-group-item"> + {% include 'commentaries/_commentary_card_content.html' with commentary=com %} + </li> + {% endfor %} + </ul> + </div> + </div> + </div> {% endif %} {% if contributor_theses %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Theses</h1> - <button id="mythesesbutton">View/hide theses</button> - </div> - <div id="mytheseslist"> - <h3>Theses for which this Contributor is identified as an author:</h3> - <ul> - {% for thesis in contributor_theses %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesis %} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Theses <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#mytheseslist">View/hide theses</span></h2> + </div> + <div class="col-12" id="mytheseslist"> + <h3>Theses for which this Contributor is identified as an author:</h3> + <div> + <ul class="list-group list-group-flush"> + {% for thesis in contributor_theses %} + <li class="list-group-item"> + {% include 'theses/_thesislink_card_content.html' with thesislink=thesis %} + </li> + {% endfor %} + </ul> + </div> + </div> + </div> {% endif %} {% if contributor_comments %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Comments</h1> - <button id="mycommentsbutton">View/hide comments</button> - </div> - <div id="mycommentslist"> - <ul> - {% for comment in contributor_comments %} - {{ comment.header_as_li }} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Comments <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#mycommentslist">View/hide comments</span></h2> + </div> + <div class="col-12" id="mycommentslist"> + <ul class="list-group list-group-flush"> + {% for comment in contributor_comments %} + <li class="list-group-item"> + {% include 'comments/_comment_card_content.html' with comment=comment %} + </li> + {% endfor %} + </ul> + </div> + </div> {% endif %} {% if contributor_authorreplies %} -<section> - <hr class="hr12"> - <div class="flex-greybox"> - <h1>Author Replies</h1> - <button id="myauthorrepliesbutton">View/hide author replies</button> - </div> - <div id="myauthorreplieslist"> - <ul> - {% for reply in contributor_authorreplies %} - {{ reply.header_as_li }} - {% endfor %} - </ul> - </div> -</section> + <hr> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Author Replies <span class="btn btn-secondary ml-2" data-toggle="toggle" data-target="#myauthorreplieslist">View/hide author replies</span></h2> + </div> + <div class="col-12" id="myauthorreplieslist"> + <ul class="list-group list-group-flush"> + {% for reply in contributor_authorreplies %} + <li class="list-group-item"> + {% include 'comments/_comment_card_extended_content.html' with comment=reply %} + </li> + {% endfor %} + </ul> + </div> + </div> {% endif %} -{% endblock bodysup %} +{% endblock content %} diff --git a/scipost/templates/scipost/index.html b/scipost/templates/scipost/index.html index 2b03326f8a296976e7827f58156adc9d4c42cc8a..16a00c30829ecda0931490f739d3b3bf72e03bcc 100644 --- a/scipost/templates/scipost/index.html +++ b/scipost/templates/scipost/index.html @@ -13,15 +13,11 @@ <h1 class="card-title mb-0"><a href="{% url 'news:news' %}">News</a><a style="float: right;" href="{% url 'scipost:feeds' %}"><img src="{% static 'scipost/images/feed-icon-14x14.png' %}" alt="Feed logo" width="14"></a></h1> <h4 class="card-subtitle mb-0 pb-0 text-muted">Latest news and announcements.</h4> </div> - <ul class="list-group list-group-flush"> {% for item in latest_newsitems %} - <li class="list-group-item"> - <div class="card-block"> - {{ item.descriptor_small }} - </div> - </li> + <div class="card card-news bg-transparent m-2"> + {% include 'news/news_card_content.html' with news=item %} + </div> {% endfor %} - </ul> </div> </div> {% endif %} @@ -69,19 +65,17 @@ <div class="col-md-6 {% if user.is_authenticated %}col-lg-4{% else %}col-lg-3{% endif %}"> <div class="card card-grey"> <div class="card-block"> - <h1 class="card-title mb-0"><a href="{% url 'journals:journals' %}">Journals</a></h1> - <h4 class="card-subtitle mb-2 text-muted">SciPost publishes a portfolio of high-quality two-way open access scientific journals.</h4> - <div class="SciPostPhysicsBanner"> - <h2 class="py-0"> - <a class="pb-0" href="{% url 'journals:scipost_physics' %}">SciPost Physics</a> - </h2> - </div> + <h1 class="card-title"><a href="{% url 'journals:journals' %}">Latest Publications</a></h1> + <h2 class="banner"> + <a href="{% url 'journals:scipost_physics' %}">SciPost Physics</a> + </h2> {% if issue and publications %} - <h4 class="card-text text-center">A selection from the {% if issue.is_current %}current{% else %}last{% endif %} issue:</h4> + <h4 class="card-text text-center mt-2">A selection from the {% if issue.is_current %}current{% else %}last{% endif %} issue:</h4> {% if issue %} - <div class="text-muted text-center">Vol. {{ issue.in_volume.number }} issue {{ issue.number }} {{issue.period_as_string}}</div> + <div class="text-muted text-center mt-2">Vol. {{ issue.in_volume.number }} issue {{ issue.number }} {{issue.period_as_string}}</div> {% endif %} - + </div> + <div class="card-block"> <ul class="list-group list-group-flush"> {% for publication in publications %} <li class="list-group-item"> @@ -103,6 +97,7 @@ <div class="card card-grey"> <div class="card-block"> <h1 class="card-title"><a href="{% url 'journals:journals' %}">Journals</a></h1> + <h4 class="card-subtitle m text-muted">SciPost publishes a portfolio of high-quality two-way open access scientific journals.</h4> <p>All SciPost Journals implement the stringent <a href="/FAQ#pwr">peer-witnessed refereeing</a> principle.</p> <p>All Journals are fully managed by professional scientists.</p> <h3><a href="{% url 'scipost:about' %}#editorial_college_physics">Editorial College (Physics)</a></h3> diff --git a/scipost/templates/scipost/news.html b/scipost/templates/scipost/news.html index f1ff82c7973d63ea39d5871a87f2db21f5527961..71982a644a9dd23d04c4c0090f67b18d4eb5a525 100644 --- a/scipost/templates/scipost/news.html +++ b/scipost/templates/scipost/news.html @@ -4,25 +4,22 @@ {% load staticfiles %} -{% block bodysup %} +{% block content %} - -<section> - <div class="flex-container"> - <div class="flex-greybox"> - <h1>SciPost News</h1> +<div class="row"> + <div class="col-12"> + <h1 class="highlight">SciPost News</h1> </div> - </div> - - <div class="flex-container"> - <ul class="NewsItemsList"> - {% for item in newsitems %} - <li>{{ item.descriptor_full|linebreaks }}</li> - {% endfor %} - </ul> - </div> - -</section> - +</div> + +<div class="row"> + <div class="col-12"> + {% for item in newsitems %} + <div class="card card-grey card-news"> + {% include 'news/news_card_content.html' with news=item %} + </div> + {% endfor %} + </div> +</div> -{% endblock bodysup %} +{% endblock content %} diff --git a/scipost/templates/scipost/personal_page.html b/scipost/templates/scipost/personal_page.html index 8969b01a8ce301c6bddb8bac6625ce3f8a127410..a71ba32e9ed293f2bedc3ace6d73206b24e36024 100644 --- a/scipost/templates/scipost/personal_page.html +++ b/scipost/templates/scipost/personal_page.html @@ -82,9 +82,7 @@ <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>Welcome to your SciPost Personal Page, {{ appellation }}</h1> - </div> + <h1 class="highlight">Welcome to your SciPost Personal Page, {{ appellation }}</h1> </div> </div> @@ -110,8 +108,10 @@ <div class="TabSection" id="Account"> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Your Account</h2> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title mb-0">Your Account</h2> + </div> </div> </div> </div> @@ -173,8 +173,10 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Your Availability</h2> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title mb-0">Your Availability</h2> + </div> </div> </div> </div> @@ -213,286 +215,319 @@ {% if 'SciPost Administrators' in user_groups or 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups or 'Vetting Editors' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %} -<div class="TabSection" id="EdActions"> - - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Pending Editorial Actions</h2> + <div class="TabSection" id="EdActions"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title mb-0">Pending Editorial Actions</h2> + </div> + </div> </div> </div> - </div> - <div class="row"> - {% if 'SciPost Administrators' in user_groups or 'Advisory Board' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %} - <div class="col-md-4"> - <h3>Registration actions</h3> - <ul> - {% if perms.scipost.can_vet_registration_requests %} - <li><a href="{% url 'scipost:vet_registration_requests' %}">Vet Registration requests</a> ({{ nr_reg_to_vet }})</li> - <li>Awaiting validation ({{ nr_reg_awaiting_validation }}) (no action necessary)</li> - {% endif %} - {% if perms.scipost.can_draft_registration_invitations %} - <li><a href="{% url 'scipost:draft_registration_invitation' %}">Draft a Registration Invitation</a></li> - {% endif %} + <div class="row"> + {% if 'SciPost Administrators' in user_groups or 'Advisory Board' in user_groups or 'Ambassadors' in user_groups or 'Junior Ambassadors' in user_groups %} + <div class="col-md-4"> + <h3>Registration actions</h3> + <ul> + {% if perms.scipost.can_vet_registration_requests %} + <li><a href="{% url 'scipost:vet_registration_requests' %}">Vet Registration requests</a> ({{ nr_reg_to_vet }})</li> + <li>Awaiting validation ({{ nr_reg_awaiting_validation }}) (no action necessary)</li> + {% endif %} + {% if perms.scipost.can_draft_registration_invitations %} + <li><a href="{% url 'scipost:draft_registration_invitation' %}">Draft a Registration Invitation</a></li> + {% endif %} + {% if perms.scipost.can_manage_registration_invitations %} + <li><a href="{% url 'scipost:registration_invitations' %}">Manage Registration Invitations</a></li> + {% endif %} + </ul> + {% if perms.scipost.can_manage_registration_invitations %} - <li><a href="{% url 'scipost:registration_invitations' %}">Manage Registration Invitations</a></li> + <h3>Notifications</h3> + <ul> + <li><a href="{% url 'scipost:citation_notifications' %}">Manage citation notifications</a></li> + </ul> {% endif %} - </ul> - {% if perms.scipost.can_manage_registration_invitations %} - <h3>Notifications</h3> - <ul> - <li><a href="{% url 'scipost:citation_notifications' %}">Manage citation notifications</a></li> - </ul> + <h3>Email communications</h3> + <ul> + {% if perms.scipost.can_email_group_members %} + <li><a href="{% url 'scipost:email_group_members' %}">Email Group Members</a></li> + {% endif %} + {% if perms.scipost.can_email_particulars %} + <li><a href="{% url 'scipost:send_precooked_email' %}">Send a precooked email</a></li> + <li><a href="{% url 'scipost:email_particular' %}">Email a particular individual/address</a></li> + {% endif %} + </ul> + </div> {% endif %} - <h3>Email communications</h3> - <ul> - {% if perms.scipost.can_email_group_members %} - <li><a href="{% url 'scipost:email_group_members' %}">Email Group Members</a></li> - {% endif %} - {% if perms.scipost.can_email_particulars %} - <li><a href="{% url 'scipost:send_precooked_email' %}">Send a precooked email</a></li> - <li><a href="{% url 'scipost:email_particular' %}">Email a particular individual/address</a></li> - {% endif %} - </ul> - </div> - {% endif %} + <div class="col-md-4"> + <h3>Vetting actions</h3> + <ul> + {% if perms.scipost.can_vet_commentary_requests %} + <li><a href="{% url 'commentaries:vet_commentary_requests' %}">Vet Commentary Page requests</a> ({{ nr_commentary_page_requests_to_vet }})</li> + {% endif %} + {% if perms.scipost.can_vet_comments %} + <li><a href="{% url 'comments:vet_submitted_comments' %}">Vet submitted Comments</a> ({{ nr_comments_to_vet }})</li> + {% endif %} + {% if perms.scipost.can_vet_thesislink_requests %} + <li><a href="{% url 'theses:unvetted_thesislinks' %}">Vet Thesis Link Requests</a> ({{ nr_thesislink_requests_to_vet }})</li> + {% endif %} + {% if perms.scipost.can_vet_authorship_claims %} + <li><a href="{% url 'scipost:vet_authorship_claims' %}">Vet Authorship Claims</a> ({{ nr_authorship_claims_to_vet }})</li> + {% endif %} + {% if perms.scipost.can_vet_submitted_reports %} + <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ nr_reports_to_vet }})</li> + {% endif %} + </ul> - <div class="col-md-4"> - <h3>Vetting actions</h3> - <ul> - {% if perms.scipost.can_vet_commentary_requests %} - <li><a href="{% url 'commentaries:vet_commentary_requests' %}">Vet Commentary Page requests</a> ({{ nr_commentary_page_requests_to_vet }})</li> - {% endif %} - {% if perms.scipost.can_vet_comments %} - <li><a href="{% url 'comments:vet_submitted_comments' %}">Vet submitted Comments</a> ({{ nr_comments_to_vet }})</li> + {% if perms.scipost.can_attend_VGMs %} + <h3>Virtual General Meetings</h3> + <ul> + <li><a href="{% url 'virtualmeetings:VGMs' %}">List of VGMs</a></li> + </ul> {% endif %} - {% if perms.scipost.can_vet_thesislink_requests %} - <li><a href="{% url 'theses:unvetted_thesislinks' %}">Vet Thesis Link Requests</a> ({{ nr_thesislink_requests_to_vet }})</li> + </div> + + {% if 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups %} + <div class="col-md-4"> + <h3>Info</h3> + <ul> + <li><a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a></li> + </ul> + + <h3>Submissions assignments</h3> + <ul> + {% if perms.scipost.can_view_pool %} + <li><a href="{% url 'submissions:assignments' %}">Your assignments</a></li> + <li><a href="{% url 'scipost:Fellow_activity_overview' %}">View assignments overview</a></li> {% endif %} - {% if perms.scipost.can_vet_authorship_claims %} - <li><a href="{% url 'scipost:vet_authorship_claims' %}">Vet Authorship Claims</a> ({{ nr_authorship_claims_to_vet }})</li> + {% if perms.scipost.can_assign_submissions %} + <li>Assign Submissions via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_submissions_to_assign }})</li> {% endif %} - {% if perms.scipost.can_vet_submitted_reports %} - <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ nr_reports_to_vet }})</li> + {% if perms.scipost.can_take_charge_of_submissions %} + <li>Accept or decline assignments via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_assignments_to_consider }})</li> {% endif %} - </ul> + </ul> - {% if perms.scipost.can_attend_VGMs %} - <h3>Virtual General Meetings</h3> - <ul> - <li><a href="{% url 'virtualmeetings:VGMs' %}">List of VGMs</a></li> - </ul> + <h3>Voting</h3> + <ul> + <li>Prepare Editorial Recommendations for voting via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_recommendations_to_prepare_for_voting }})</li> + </ul> + </div> {% endif %} </div> - {% if 'Editorial Administrators' in user_groups or 'Editorial College' in user_groups %} - <div class="col-md-4"> - <h3>Info</h3> - <ul> - <li><a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a></li> - </ul> - - <h3>Submissions assignments</h3> - <ul> - {% if perms.scipost.can_view_pool %} - <li><a href="{% url 'submissions:assignments' %}">Your assignments</a></li> - <li><a href="{% url 'scipost:Fellow_activity_overview' %}">View assignments overview</a></li> - {% endif %} - {% if perms.scipost.can_assign_submissions %} - <li>Assign Submissions via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_submissions_to_assign }})</li> - {% endif %} - {% if perms.scipost.can_take_charge_of_submissions %} - <li>Accept or decline assignments via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_assignments_to_consider }})</li> - {% endif %} - </ul> - - <h3>Voting</h3> - <ul> - <li>Prepare Editorial Recommendations for voting via the <a href="{% url 'submissions:pool' %}">Submissions Pool</a> ({{ nr_recommendations_to_prepare_for_voting }})</li> - </ul> + {% if active_assignments %} + <div class="row"> + <div class="col-12"> + <h3 class="highlight">Submissions for which you are Editor-in-charge</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for assignment in active_assignments %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_eic_content.html' with submission=assignment.submission %} + </li> + {% endfor %} + </ul> + </div> </div> {% endif %} </div> - - {% if active_assignments %} - <div class="row"> - <div class="col-12"> - <h3>Submissions for which you are Editor-in-charge</h3> - <ul> - {% for assignment in active_assignments %} - {{ assignment.header_as_li_for_eic }} - {% endfor %} - </ul> - </div> - </div> {% endif %} -</div> -{% endif %} -{% if perms.scipost.can_referee %} -<div class="TabSection" id="Refereeing"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Refereeing Tasks</h2> - <ul class="mb-0"> - <li><a href="{% url 'submissions:accept_or_decline_ref_invitations' %}">Accept/decline refereeing invitations</a> ({{ nr_ref_inv_to_consider }})</li> - </ul> + {% if perms.scipost.can_referee %} + <div class="TabSection" id="Refereeing"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Refereeing Tasks</h2> + <ul class="mb-0"> + <li><a href="{% url 'submissions:accept_or_decline_ref_invitations' %}">Accept/decline refereeing invitations</a> ({{ nr_ref_inv_to_consider }})</li> + </ul> + </div> + </div> </div> </div> - </div> - {% if pending_ref_tasks %} - <div class="row"> - <div class="col-12"> - <h3>Pending Refereeing Tasks:</h3> - <ul> - {% for task in pending_ref_tasks %} - <li>{{ task.submission }}, due {{ task.submission.reporting_deadline }}. - <a href="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=task.submission.arxiv_identifier_w_vn_nr %}">Submit your Report</a> - <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=task.submission.arxiv_identifier_w_vn_nr comtype='RtoE' referee_id=contributor.user.contributor.id %}">Write to the Editor-in-charge</a>. - </li> - {% endfor %} - </ul> + {% if pending_ref_tasks %} + <div class="row"> + <div class="col-12"> + <h3>Pending Refereeing Tasks:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for task in pending_ref_tasks %} + <li class="list-group-item"> + {% include 'submissions/_refereeing_invitation_card_content.html' with invitation=task %} + </li> + {% endfor %} + </ul> + </div> </div> + {% endif %} </div> {% endif %} -</div> -{% endif %} -<div class="TabSection" id="Submissions"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Submissions</h2> - <ul class="mb-0"> - {% if nr_submission_authorships_to_claim > 0 %} - <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_submission_authorships_to_claim}})</a></li> - {% endif %} - <li><a href="{% url 'submissions:submit_manuscript' %}">Submit an arXiv preprint to a SciPost Journal</a></li> - </ul> + <div class="TabSection" id="Submissions"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Submissions</h2> + <ul class="mb-0"> + {% if nr_submission_authorships_to_claim > 0 %} + <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_submission_authorships_to_claim}})</a></li> + {% endif %} + <li><a href="{% url 'submissions:submit_manuscript' %}">Submit an arXiv preprint to a SciPost Journal</a></li> + </ul> + </div> + </div> </div> </div> - </div> - {% if own_submissions %} - <div class="row" id="mysubmissionslist"> - <div class="col-12"> - <h3>Submissions for which you are identified as an author:</h3> - <ul class="mt-3"> - {% for sub in own_submissions %} - {{ sub.header_as_li_for_authors }} - {% if contributor.user.contributor == sub.submitted_by %} - <p><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>.</p> - {% endif %} - {% endfor %} - </ul> + {% if own_submissions %} + <div class="row" id="mysubmissionslist"> + <div class="col-12"> + <h3>Submissions for which you are identified as an author:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for sub in own_submissions %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_author_content.html' with submission=sub current_user=request.user %} + </li> + {% endfor %} + </ul> + </div> </div> + {% endif %} </div> - {% endif %} -</div> -<div class="TabSection" id="Commentaries"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Commentaries</h2> - <ul class="mb-0"> - {% if nr_commentary_authorships_to_claim > 0 %} - <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_commentary_authorships_to_claim}})</a></li> - {% endif %} - <li><a href="{% url 'commentaries:request_commentary' %}">Request opening a SciPost Commentary Page</a></li> - </ul> + <div class="TabSection" id="Commentaries"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Commentaries</h2> + <ul class="mb-0"> + {% if nr_commentary_authorships_to_claim > 0 %} + <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_commentary_authorships_to_claim}})</a></li> + {% endif %} + <li><a href="{% url 'commentaries:request_commentary' %}">Request opening a SciPost Commentary Page</a></li> + </ul> + </div> + </div> </div> </div> - </div> - {% if own_commentaries %} - <div class="row" id="mycommentarieslist"> - <div class="col-12"> - <h3>Commentaries for which you are identified as an author:</h3> - <ul> - {% for com in own_commentaries %} - {{ com.header_as_li }} - {% endfor %} - </ul> + {% if own_commentaries %} + <div class="row" id="mycommentarieslist"> + <div class="col-12"> + <h3>Commentaries for which you are identified as an author:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for com in own_commentaries %} + <li class="list-group-item"> + {% include 'commentaries/_commentary_card_content.html' with commentary=com %} + </li> + {% endfor %} + </ul> + </div> </div> + {% endif %} </div> - {% endif %} -</div> -<div class="TabSection" id="Theses"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Theses</h2> - <ul class="mb-0"> - {% if nr_thesis_authorships_to_claim > 0 %} - <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_thesis_authorships_to_claim}})</a></li> - {% endif %} - <li><a href="{% url 'theses:request_thesislink' %}">Request a SciPost ThesisLink</a></li> - </ul> + <div class="TabSection" id="Theses"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Theses</h2> + <ul class="mb-0"> + {% if nr_thesis_authorships_to_claim > 0 %} + <li><a href="{% url 'scipost:claim_authorships' %}">Potential authorships to claim (auto-detected: {{ nr_thesis_authorships_to_claim}})</a></li> + {% endif %} + <li><a href="{% url 'theses:request_thesislink' %}">Request a SciPost ThesisLink</a></li> + </ul> + </div> + </div> </div> </div> + {% if own_thesislinks %} + <div class="row" id="mytheseslist"> + <div class="col-12"> + <h3>Theses for which you are identified as an author:</h3> + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for thesis in own_thesislinks %} + <li class="list-group-item"> + {% include 'theses/_thesislink_card_content.html' with thesislink=thesis %} + </li> + {% endfor %} + </ul> + </div> + </div> + {% endif %} </div> - {% if own_thesislinks %} - <div class="row" id="mytheseslist"> - <div class="col-12"> - <h3>Theses for which you are identified as an author:</h3> - <ul> - {% for thesis in own_thesislinks %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesis %} - {% endfor %} - </ul> - </div> - </div> - {% endif %} -</div> -<div class="TabSection" id="Comments"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Your Comments</h2> + <div class="TabSection" id="Comments"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title mb-0">Your Comments</h2> + </div> + </div> </div> </div> - </div> - <div class="row" id="mycommentslist"> - <div class="col-12"> - <ul> - {% for own_comment in own_comments %} - {{ own_comment.header_as_li }} - {% empty %} - <li>You have not commented yet.</li> - {% endfor %} - </ul> + + <div class="row" id="mycommentslist"> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for own_comment in own_comments %} + <li class="list-group-item"> + {% include 'comments/_comment_card_extended_content.html' with comment=own_comment %} + </li> + {% empty %} + <li class="list-group-item">You have not commented yet.</li> + {% endfor %} + </ul> + </div> </div> </div> -</div> -{% if own_authorreplies %} -<div class="TabSection" id="AuthorReplies"> - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Your Author Replies</h2> + <div class="TabSection" id="AuthorReplies"> + <div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title mb-0">Your Author Replies</h2> + </div> + </div> </div> </div> - </div> - <div class="row" id="myauthorreplieslist"> - <div class="col-12"> - <ul> - {% for own_reply in own_authorreplies %} - {{ own_reply.header_as_li }} - {% endfor %} - </ul> + + <div class="row" id="myauthorreplieslist"> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for own_reply in own_authorreplies %} + <li class="list-group-item"> + {% include 'comments/_comment_card_extended_content.html' with comment=own_reply %} + </li> + {% empty %} + <li class="list-group-item">You have not Author Replies yet.</li> + {% endfor %} + </ul> + </div> </div> </div> -</div> -{% endif %} {% endif %} diff --git a/scipost/templates/scipost/search.html b/scipost/templates/scipost/search.html index 911e4686ed965a1f8a4ebb054ac3e25b8a0adcaa..dd9d6d630935dfd9ee83abfe95198de6019530f2 100644 --- a/scipost/templates/scipost/search.html +++ b/scipost/templates/scipost/search.html @@ -17,16 +17,16 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Publications</h2> - </div> + <h2 class="highlight">Publications ({{publication_search_list|length}})</h2> </div> </div> <div class="row"> <div class="col-12"> {% for publication in publication_search_list %} - {{ publication.header_as_li }} + <div class="card card-publication"> + {% include 'journals/_publication_card_content.html' with publication=publication %} + </div> {% endfor %} </div> </div> @@ -46,7 +46,6 @@ {% endif %} </span> </div> - </div> </div> {% endif %} @@ -56,16 +55,16 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Commentaries</h2> - </div> + <h2 class="highlight">Commentaries ({{commentary_search_list|length}})</h2> </div> </div> <div class="row"> <div class="col-12"> - <ul> + <ul class="list-group list-group-flush"> {% for commentary in commentary_search_list %} - {{ commentary.header_as_li }} + <li class="list-group-item"> + {% include 'commentaries/_commentary_card_content.html' with commentary=commentary %} + </li> {% endfor %} </ul> </div> @@ -86,7 +85,6 @@ {% endif %} </span> </div> - </div> </div> {% endif %} @@ -96,16 +94,16 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Submissions</h2> - </div> + <h2 class="highlight">Submissions ({{submission_search_list|length}})</h2> </div> </div> <div class="row"> <div class="col-12"> - <ul> + <ul class="list-group list-group-flush"> {% for submission in submission_search_list %} - {{ submission.header_as_li }} + <li class="list-group-item"> + {% include 'submissions/_submission_card_content.html' with submission=submission %} + </li> {% endfor %} </ul> </div> @@ -134,39 +132,40 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Theses</h2> - </div> + <h2 class="highlight">Theses ({{thesislink_search_list|length}})</h2> </div> </div> <div class="row"> <div class="col-12"> - <ul> + <ul class="list-group list-group-flush"> {% for thesislink in thesislink_search_list %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} + <li class="list-group-item"> + {% include 'theses/_thesislink_card_content.html' with thesislink=thesislink %} + </li> {% endfor %} - </ul> - {% endif %} + </ul> + </div> +</div> +{% endif %} - {% if comment_search_list %} - <div class="row"> - <div class="col-12"> - <div class="panel"> - <h2>Comments</h2> - </div> - </div> - </div> - <div class="row"> - <div class="col-12"> - <ul> - {% for comment in comment_search_list %} - {{ comment.header_as_li }} - {% endfor %} - </ul> - </div> - </div> - {% endif %} +{% if comment_search_list %} +<hr> +<div class="row"> + <div class="col-12"> + <h2 class="highlight">Comments ({{comment_search_list|length}})</h2> + </div> +</div> +<div class="row"> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for comment in comment_search_list %} + <li class="list-group-item"> + {% include 'comments/_comment_card_extended_content.html' with comment=comment %} + </li> + {% endfor %} + </ul> </div> </div> +{% endif %} {% endblock content %} diff --git a/scipost/templates/scipost/vet_authorship_claims.html b/scipost/templates/scipost/vet_authorship_claims.html index ba894d8b264de40d938f78bc9eb1677f8646f19d..71ca952c25d72dbb55d9036785181cddfcb79929 100644 --- a/scipost/templates/scipost/vet_authorship_claims.html +++ b/scipost/templates/scipost/vet_authorship_claims.html @@ -6,42 +6,56 @@ {% endblock headsup %} -{% block bodysup %} +{% block content %} -<section> - <div class="flex-greybox"> - <h1>Vet Authorship Claims</h1> +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Vet Authorship Claims</h1> </div> - {% if not claims_to_vet %} - <h3>There are no authorship claims to vet</h3> - {% else %} +</div> - <hr class="hr12"> - <ul> +{% if not claims_to_vet %} + <div class="row"> + <div class="col-12"> + <h3>There are no authorship claims to vet</h3> + </div> + </div> +{% else %} + + <ul class="list-group list-group-flush"> {% for claim in claims_to_vet %} - {% if claim.submission %} - <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Submission:</h4> - {{ claim.submission.header_as_li }} - {% elif claim.commentary %} - <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Submission:</h4> - {{ claim.commentary.header_as_li }} - {% elif claim.thesislink %} - <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Thesis:</h4> - {% include 'theses/_thesislink_header_as_li.html' with thesislink=claim.thesislink %} - {% endif %} - - <form action="{% url 'scipost:vet_authorship_claim' claim_id=claim.id claim=1%}" method="post"> - {% csrf_token %} - <input type="submit" value="Accept" /> - </form> - <form action="{% url 'scipost:vet_authorship_claim' claim_id=claim.id claim=0%}" method="post"> - {% csrf_token %} - <input type="submit" value="Deny" /> - </form> + <li class="list-group-item"> + <div class="card w-100"> + {% if claim.submission %} + <div class="card-header"> + <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Submission:</h4> + </div> + {% include 'submissions/_submission_card_content.html' with submission=claim.submission %} + {% elif claim.commentary %} + <div class="card-header"> + <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Commentary:</h4> + </div> + {% include 'commentaries/_commentary_card_content.html' with commentary=claim.commentary %} + {% elif claim.thesislink %} + <div class="card-header"> + <h4>Contributor {{ claim.claimant.user.first_name }} {{ claim.claimant.user.last_name }} claims to be an author of Thesis:</h4> + </div> + {% include 'theses/_thesislink_card_content.html' with thesislink=claim.thesislink %} + {% endif %} + <div class="card-footer"> + <form class="d-inline-block" action="{% url 'scipost:vet_authorship_claim' claim_id=claim.id claim=1%}" method="post"> + {% csrf_token %} + <input class="btn btn-secondary" type="submit" value="Accept" /> + </form> + <form class="d-inline-block ml-1" action="{% url 'scipost:vet_authorship_claim' claim_id=claim.id claim=0%}" method="post"> + {% csrf_token %} + <input class="btn btn-danger" type="submit" value="Deny" /> + </form> + </div> + </div> + </li> {% endfor %} </ul> {% endif %} -</section> - -{% endblock bodysup %} +{% endblock content %} diff --git a/scipost/templatetags/bootstrap.py b/scipost/templatetags/bootstrap.py index 5f7816e6a69bf51bd32a83e28ffc55d21330e22b..c06ec80d8eba9401d0696df6e668fa82bceda2f7 100644 --- a/scipost/templatetags/bootstrap.py +++ b/scipost/templatetags/bootstrap.py @@ -35,8 +35,18 @@ def bootstrap(element, args='2,10'): @register.filter -def bootstrap_inline(element): - markup_classes = {'label': 'sr-only', 'value': '', 'single_value': ''} +def bootstrap_inline(element, args='2,10'): + args = [arg.strip() for arg in args.split(',')] + markup_classes = { + 'label': 'sr-only col-md-%s' % args[0], + 'value': 'col-md-%s' % args[1], + 'single_value': '' + } + try: + markup_classes['label'] += ' col-form-label-%s' % args[2] + markup_classes['form_control'] = 'form-control-%s' % args[2] + except IndexError: + markup_classes['form_control'] = '' return render(element, markup_classes) diff --git a/scipost/utils.py b/scipost/utils.py index bac564998baf16da8d187141d2d65d5c12214b30..20e45420ea434d53d2921f003f7c24cbcc084405 100644 --- a/scipost/utils.py +++ b/scipost/utils.py @@ -8,7 +8,7 @@ from django.core.mail import EmailMultiAlternatives from django.template import Context, Template from django.utils import timezone -from .models import Contributor, DraftInvitation, RegistrationInvitation, title_dict +from .models import Contributor, DraftInvitation, RegistrationInvitation SCIPOST_SUMMARY_FOOTER = ( @@ -154,7 +154,7 @@ class Utils(object): cls.contributor.key_expires = datetime.datetime.strftime( datetime.datetime.now() + datetime.timedelta(days=2), "%Y-%m-%d %H:%M:%S") cls.contributor.save() - email_text = ('Dear ' + title_dict[cls.contributor.title] + ' ' + + email_text = ('Dear ' + cls.contributor.get_title_display() + ' ' + cls.contributor.user.last_name + ', \n\nYour request for registration to the SciPost publication portal' + ' has been received. You now need to validate your email by visiting ' + @@ -172,7 +172,7 @@ class Utils(object): '\n<p>Your registration will thereafter be vetted. Many thanks for your interest.</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.contributor.title], + 'title': cls.contributor.get_title_display(), 'last_name': cls.contributor.user.last_name, 'activation_key': cls.contributor.activation_key, }) @@ -220,7 +220,7 @@ class Utils(object): @classmethod def send_registration_invitation_email(cls, renew=False): - signature = (title_dict[cls.invitation.invited_by.title] + ' ' + signature = (cls.invitation.invited_by.get_title_display() + ' ' + cls.invitation.invited_by.user.first_name + ' ' + cls.invitation.invited_by.user.last_name) if not renew: @@ -253,9 +253,9 @@ class Utils(object): email_text += 'Dear ' email_text_html += 'Dear ' if cls.invitation.message_style == 'F': - email_text += title_dict[cls.invitation.title] + ' ' + cls.invitation.last_name + email_text += cls.invitation.get_title_display() + ' ' + cls.invitation.last_name email_text_html += '{{ title }} {{ last_name }}' - email_context['title'] = title_dict[cls.invitation.title] + email_context['title'] = cls.invitation.get_title_display() email_context['last_name'] = cls.invitation.last_name else: email_text += cls.invitation.first_name @@ -645,10 +645,10 @@ class Utils(object): Requires loading the 'notification' attribute. """ email_context = Context({}) - email_text = ('Dear ' + title_dict[cls.notification.contributor.title] + + email_text = ('Dear ' + cls.notification.contributor.get_title_display() + ' ' + cls.notification.contributor.user.last_name) email_text_html = 'Dear {{ title }} {{ last_name }}' - email_context['title'] = title_dict[cls.notification.contributor.title] + email_context['title'] = cls.notification.contributor.get_title_display() email_context['last_name'] = cls.notification.contributor.user.last_name email_text += ',\n\n' email_text_html += ',<br/>' diff --git a/scipost/views.py b/scipost/views.py index 16fe27bf23c0e91f4685aac54438831a17cf3e39..3b8a505af8d0da4eb23d1d0378b3db6dc8c2a822 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -26,11 +26,11 @@ from django.db.models import Prefetch from guardian.decorators import permission_required -from .constants import SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict +from .constants import SCIPOST_SUBJECT_AREAS, subject_areas_raw_dict, SciPost_from_addresses_dict from .models import Contributor, CitationNotification, UnavailabilityPeriod,\ DraftInvitation, RegistrationInvitation,\ - title_dict, SciPost_from_addresses_dict,\ - AuthorshipClaim, SupportingPartner, SPBMembershipAgreement, EditorialCollege, EditorialCollegeFellowship + AuthorshipClaim, SupportingPartner, SPBMembershipAgreement,\ + EditorialCollege, EditorialCollegeFellowship from .forms import AuthenticationForm, DraftInvitationForm, UnavailabilityPeriodForm,\ RegistrationForm, RegistrationInvitationForm, AuthorshipClaimForm,\ ModifyPersonalMessageForm, SearchForm, VetRegistrationForm, reg_ref_dict,\ @@ -43,9 +43,9 @@ from commentaries.models import Commentary from comments.models import Comment from journals.models import Publication, Issue from news.models import NewsItem -from submissions.models import SUBMISSION_STATUS_PUBLICLY_UNLISTED -from submissions.models import Submission, EditorialAssignment -from submissions.models import RefereeInvitation, Report, EICRecommendation +from submissions.constants import SUBMISSION_STATUS_PUBLICLY_UNLISTED +from submissions.models import Submission, EditorialAssignment, RefereeInvitation,\ + Report, EICRecommendation from theses.models import ThesisLink @@ -327,7 +327,7 @@ def invitation(request, key): form.fields['first_name'].initial = invitation.first_name form.fields['email'].initial = invitation.email errormessage = '' - welcome_message = ('Welcome, ' + title_dict[invitation.title] + ' ' + welcome_message = ('Welcome, ' + invitation.get_title_display() + ' ' + invitation.last_name + ', and thanks in advance for ' 'registering (by completing this form)') return render(request, 'scipost/register.html', { @@ -374,7 +374,7 @@ def request_new_activation_link(request, oldkey): contributor.key_expires = datetime.datetime.strftime( datetime.datetime.now() + datetime.timedelta(days=2), "%Y-%m-%d %H:%M:%S") contributor.save() - email_text = ('Dear ' + title_dict[contributor.title] + ' ' + contributor.user.last_name + + email_text = ('Dear ' + contributor.get_title_display() + ' ' + contributor.user.last_name + ', \n\n' 'Your request for a new email activation link for registration to the SciPost ' 'publication portal has been received. You now need to visit this link within ' @@ -453,7 +453,7 @@ def vet_registration_request_ack(request, contributor_id): except RefereeInvitation.DoesNotExist: pending_ref_inv_exists = False - email_text = ('Dear ' + title_dict[contributor.title] + ' ' + email_text = ('Dear ' + contributor.get_title_display() + ' ' + contributor.user.last_name + ', \n\nYour registration to the SciPost publication portal ' 'has been accepted. ' @@ -472,7 +472,7 @@ def vet_registration_request_ack(request, contributor_id): emailmessage.send(fail_silently=False) else: ref_reason = int(form.cleaned_data['refusal_reason']) - email_text = ('Dear ' + title_dict[contributor.title] + ' ' + email_text = ('Dear ' + contributor.get_title_display() + ' ' + contributor.user.last_name + ', \n\nYour registration to the SciPost publication portal ' 'has been turned down, the reason being: ' @@ -1012,7 +1012,7 @@ def personal_page(request): .filter(author=contributor, is_author_reply=True) .order_by('-date_submitted')) - appellation = title_dict[contributor.title] + ' ' + contributor.user.last_name + appellation = contributor.get_title_display() + ' ' + contributor.user.last_name context = { 'contributor': contributor, 'user_groups': user_groups, @@ -1300,7 +1300,7 @@ def email_group_members(request): # emailmessage.send(fail_silently=False) # with mail.get_connection() as connection: # for member in form.cleaned_data['group'].user_set.all(): - # email_text = ('Dear ' + title_dict[member.contributor.title] + ' ' + + # email_text = ('Dear ' + member.contributor.get_title_display() + ' ' + # member.last_name + ', \n\n' # + form.cleaned_data['email_text']) # mail.EmailMessage(form.cleaned_data['email_subject'], @@ -1316,7 +1316,7 @@ def email_group_members(request): email_text = '' email_text_html = '' if form.cleaned_data['personalize']: - email_text = ('Dear ' + title_dict[member.contributor.title] + email_text = ('Dear ' + member.contributor.get_title_display() + ' ' + member.last_name + ', \n\n') email_text_html = 'Dear {{ title }} {{ last_name }},<br/>' email_text += form.cleaned_data['email_text'] @@ -1334,7 +1334,7 @@ def email_group_members(request): 'emails? <a href="https://scipost.org/unsubscribe/{{ key }}">' 'Unsubscribe</a>.</p>') email_context = Context({ - 'title': title_dict[member.contributor.title], + 'title': member.contributor.get_title_display(), 'last_name': member.last_name, 'email_text': form.cleaned_data['email_text'], 'key': member.contributor.activation_key, @@ -1450,15 +1450,21 @@ def EdCol_bylaws(request): @permission_required('scipost.can_view_pool', return_403=True) def Fellow_activity_overview(request, Fellow_id=None): - Fellows = Contributor.objects.filter( + fellows = Contributor.objects.filter( user__groups__name='Editorial College').order_by('user__last_name') - context = {'Fellows': Fellows, } + context = {'fellows': fellows} if Fellow_id: - Fellow = get_object_or_404(Contributor, pk=Fellow_id) - context['Fellow'] = Fellow - assignments_of_Fellow = EditorialAssignment.objects.filter( - to=Fellow).order_by('-date_created') - context['assignments_of_Fellow'] = assignments_of_Fellow + fellow = get_object_or_404(Contributor, pk=Fellow_id) + context['fellow'] = fellow + + assignments_ongoing = (EditorialAssignment.objects.get_for_user_in_pool(request.user) + .filter(accepted=True, completed=False, to=fellow) + .order_by('-date_created')) + context['assignments_ongoing'] = assignments_ongoing + + assignments_completed = (EditorialAssignment.objects.get_for_user_in_pool(request.user) + .filter(completed=True, to=fellow).order_by('-date_created')) + context['assignments_completed'] = assignments_completed return render(request, 'scipost/Fellow_activity_overview.html', context) diff --git a/submissions/constants.py b/submissions/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..477c4e18352facc9e707b89fae3d999efbcf900e --- /dev/null +++ b/submissions/constants.py @@ -0,0 +1,161 @@ + +SUBMISSION_STATUS = ( + ('unassigned', 'Unassigned, undergoing pre-screening'), + ('assignment_failed', 'Failed to assign Editor-in-charge; manuscript rejected'), + ('EICassigned', 'Editor-in-charge assigned, manuscript under review'), + ('review_closed', 'Review period closed, editorial recommendation pending'), + # If revisions required: resubmission creates a new Submission object + ('revision_requested', 'Editor-in-charge has requested revision'), + ('resubmitted', 'Has been resubmitted'), + ('resubmitted_and_rejected', 'Has been resubmitted and subsequently rejected'), + ('resubmitted_and_rejected_visible', + 'Has been resubmitted and subsequently rejected (still publicly visible)'), + # If acceptance/rejection: + ('voting_in_preparation', 'Voting in preparation (eligible Fellows being selected)'), + ('put_to_EC_voting', 'Undergoing voting at the Editorial College'), + ('EC_vote_completed', 'Editorial College voting rounded up'), + ('accepted', 'Publication decision taken: accept'), + ('rejected', 'Publication decision taken: reject'), + ('rejected_visible', 'Publication decision taken: reject (still publicly visible)'), + ('published', 'Published'), + # If withdrawn: + ('withdrawn', 'Withdrawn by the Authors'), +) + +SUBMISSION_STATUS_OUT_OF_POOL = [ + 'assignment_failed', + 'resubmitted', + 'published', + 'withdrawn', + 'rejected', + 'rejected_visible', +] + +# Submissions which should not appear in search lists +SUBMISSION_STATUS_PUBLICLY_UNLISTED = [ + 'unassigned', + 'assignment_failed', + 'resubmitted', + 'resubmitted_rejected', + 'resubmitted_rejected_visible', + 'rejected', + 'published', + 'withdrawn', +] + +# Submissions which should not be viewable (except by admins, Fellows and authors) +SUBMISSION_STATUS_PUBLICLY_INVISIBLE = [ + 'unassigned', + 'assignment_failed', + 'resubmitted_rejected', + 'rejected', + 'withdrawn', +] + +# Submissions for which voting on a related recommendation is deprecated: +SUBMISSION_STATUS_VOTING_DEPRECATED = [ + 'rejected', + 'published', + 'withdrawn', +] + +SUBMISSION_TYPE = ( + ('Letter', 'Letter (broad-interest breakthrough results)'), + ('Article', 'Article (in-depth reports on specialized research)'), + ('Review', 'Review (candid snapshot of current research in a given area)'), +) + +ED_COMM_CHOICES = ( + ('EtoA', 'Editor-in-charge to Author'), + ('EtoR', 'Editor-in-charge to Referee'), + ('EtoS', 'Editor-in-charge to SciPost Editorial Administration'), + ('AtoE', 'Author to Editor-in-charge'), + ('RtoE', 'Referee to Editor-in-Charge'), + ('StoE', 'SciPost Editorial Administration to Editor-in-charge'), +) + +ASSIGNMENT_BOOL = ((True, 'Accept'), (False, 'Decline')) +ASSIGNMENT_NULLBOOL = ((None, 'Response pending'), (True, 'Accept'), (False, 'Decline')) + +ASSIGNMENT_REFUSAL_REASONS = ( + ('BUS', 'Too busy'), + ('VAC', 'Away on vacation'), + ('COI', 'Conflict of interest: coauthor in last 5 years'), + ('CCC', 'Conflict of interest: close colleague'), + ('NIR', 'Cannot give an impartial assessment'), + ('NIE', 'Not interested enough'), + ('DNP', 'SciPost should not even consider this paper'), +) + +REFEREE_QUALIFICATION = ( + (4, 'expert in this subject'), + (3, 'very knowledgeable in this subject'), + (2, 'knowledgeable in this subject'), + (1, 'generally qualified'), + (0, 'not qualified'), +) + +QUALITY_SPEC = ( + (6, 'perfect'), + (5, 'excellent'), + (4, 'good'), + (3, 'reasonable'), + (2, 'acceptable'), + (1, 'below threshold'), + (0, 'mediocre'), +) + +# Only values between 0 and 100 are kept, anything outside those limits is discarded. +RANKING_CHOICES = ( + (101, '-'), + (100, 'top'), + (80, 'high'), + (60, 'good'), + (40, 'ok'), + (20, 'low'), + (0, 'poor') +) + +REPORT_REC = ( + (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), + (2, 'Publish as Tier II (top 50% of papers in this journal)'), + (3, 'Publish as Tier III (meets the criteria of this journal)'), + (-1, 'Ask for minor revision'), + (-2, 'Ask for major revision'), + (-3, 'Reject') +) + +# +# Reports +# +REPORT_ACTION_ACCEPT = 1 +REPORT_ACTION_REFUSE = 2 +REPORT_ACTION_CHOICES = ( + (REPORT_ACTION_ACCEPT, 'accept'), + (REPORT_ACTION_REFUSE, 'refuse'), +) + +STATUS_VETTED = 1 +STATUS_UNVETTED = 0 +STATUS_UNCLEAR = -1 +STATUS_INCORRECT = -2 +STATUS_NOT_USEFUL = -3 +STATUS_NOT_ACADEMIC = -4 + +REPORT_REFUSAL_NONE = 0 +REPORT_REFUSAL_CHOICES = ( + (STATUS_UNVETTED, '-'), + (STATUS_UNCLEAR, 'insufficiently clear'), + (STATUS_INCORRECT, 'not fully factually correct'), + (STATUS_NOT_USEFUL, 'not useful for the authors'), + (STATUS_NOT_ACADEMIC, 'not sufficiently academic in style'), +) + +REPORT_STATUSES = ( + (STATUS_VETTED, 'Vetted'), + (STATUS_UNVETTED, 'Unvetted'), + (STATUS_INCORRECT, 'Rejected (incorrect)'), + (STATUS_UNCLEAR, 'Rejected (unclear)'), + (STATUS_NOT_USEFUL, 'Rejected (not useful)'), + (STATUS_NOT_ACADEMIC, 'Rejected (not academic in style)') +) diff --git a/submissions/forms.py b/submissions/forms.py index bcac8cac71b9590b2e4c30d78aecfb018a45e53e..6bb7af39bb29008fd9eb097450b5178d4a7f4402 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -1,8 +1,9 @@ from django import forms from django.core.validators import RegexValidator -from .models import ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS,\ - Submission, RefereeInvitation, Report, EICRecommendation +from .constants import ASSIGNMENT_BOOL, ASSIGNMENT_REFUSAL_REASONS,\ + REPORT_ACTION_CHOICES, REPORT_REFUSAL_CHOICES +from .models import Submission, RefereeInvitation, Report, EICRecommendation from scipost.constants import SCIPOST_SUBJECT_AREAS from scipost.models import Contributor @@ -158,23 +159,6 @@ class VotingEligibilityForm(forms.Form): # Reports: ############ -REPORT_ACTION_CHOICES = ( - # (0, 'modify'), - (1, 'accept'), - (2, 'refuse'), -) - -REPORT_REFUSAL_CHOICES = ( - (0, '-'), - (-1, 'insufficiently clear'), - (-2, 'not fully factually correct'), - (-3, 'not useful for the authors'), - (-4, 'not sufficiently academic in style'), -) - -report_refusal_choices_dict = dict(REPORT_REFUSAL_CHOICES) - - class ReportForm(forms.ModelForm): class Meta: model = Report diff --git a/submissions/managers.py b/submissions/managers.py new file mode 100644 index 0000000000000000000000000000000000000000..f9f30092cf2592faeb76485da837c3eb8e08416e --- /dev/null +++ b/submissions/managers.py @@ -0,0 +1,28 @@ +from django.db import models +from django.db.models import Q + +from .constants import SUBMISSION_STATUS_OUT_OF_POOL + + +class SubmissionManager(models.Manager): + def get_pool(self, user): + return self.exclude(status__in=SUBMISSION_STATUS_OUT_OF_POOL)\ + .exclude(is_current=False)\ + .exclude(authors=user.contributor)\ + .exclude(Q(author_list__icontains=user.last_name), + ~Q(authors_false_claims=user.contributor))\ + .order_by('-submission_date') + + +class EditorialAssignmentManager(models.Manager): + def get_for_user_in_pool(self, user): + return self.exclude(submission__authors=user.contributor)\ + .exclude(Q(submission__author_list__icontains=user.last_name), + ~Q(submission__authors_false_claims=user.contributor)) + + +class EICRecommendationManager(models.Manager): + def get_for_user_in_pool(self, user): + return self.exclude(submission__authors=user.contributor)\ + .exclude(Q(submission__author_list__icontains=user.last_name), + ~Q(submission__authors_false_claims=user.contributor)) diff --git a/submissions/migrations/0022_auto_20160822_1934.py b/submissions/migrations/0022_auto_20160822_1934.py index 448b5cee0542821379882faed3a9db24f7b25dbe..00d0d0d90d1d500fcd4a310bce8ba5254d7b287a 100644 --- a/submissions/migrations/0022_auto_20160822_1934.py +++ b/submissions/migrations/0022_auto_20160822_1934.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals from django.db import migrations, models -import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -16,6 +16,6 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='submission', name='secondary_areas', - field=scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), + field=scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None), ), ] diff --git a/submissions/models.py b/submissions/models.py index f720ae1baa5310d8db70a8c3716bfd2768d3111f..893353e6ff72279109f4ef6cb06a793909785cf2 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -2,100 +2,26 @@ import datetime from django.utils import timezone from django.db import models, transaction -from django.db.models import Q from django.contrib.postgres.fields import JSONField -from django.template import Template, Context + +from .constants import ASSIGNMENT_REFUSAL_REASONS, SUBMISSION_STATUS, ASSIGNMENT_NULLBOOL,\ + SUBMISSION_TYPE, ED_COMM_CHOICES, REFEREE_QUALIFICATION, QUALITY_SPEC,\ + RANKING_CHOICES, REPORT_REC, REPORT_REFUSAL_CHOICES,\ + REPORT_STATUSES, STATUS_UNVETTED +from .managers import SubmissionManager, EditorialAssignmentManager, EICRecommendationManager from scipost.behaviors import ArxivCallable -from scipost.models import ChoiceArrayField, Contributor, TITLE_CHOICES, title_dict -from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS, subject_areas_dict -from journals.models import SCIPOST_JOURNALS_SUBMIT, SCIPOST_JOURNALS_DOMAINS -from journals.models import journals_submit_dict, journals_domains_dict +from scipost.constants import TITLE_CHOICES +from scipost.fields import ChoiceArrayField +from scipost.models import Contributor +from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS +from journals.constants import SCIPOST_JOURNALS_SUBMIT, SCIPOST_JOURNALS_DOMAINS from journals.models import Publication ############### # Submissions: ############### -SUBMISSION_STATUS = ( - ('unassigned', 'Unassigned, undergoing pre-screening'), - ('assignment_failed', 'Failed to assign Editor-in-charge; manuscript rejected'), - ('EICassigned', 'Editor-in-charge assigned, manuscript under review'), - ('review_closed', 'Review period closed, editorial recommendation pending'), - # If revisions required: resubmission creates a new Submission object - ('revision_requested', 'Editor-in-charge has requested revision'), - ('resubmitted', 'Has been resubmitted'), - ('resubmitted_and_rejected', 'Has been resubmitted and subsequently rejected'), - ('resubmitted_and_rejected_visible', - 'Has been resubmitted and subsequently rejected (still publicly visible)'), - # If acceptance/rejection: - ('voting_in_preparation', 'Voting in preparation (eligible Fellows being selected)'), - ('put_to_EC_voting', 'Undergoing voting at the Editorial College'), - ('EC_vote_completed', 'Editorial College voting rounded up'), - ('accepted', 'Publication decision taken: accept'), - ('rejected', 'Publication decision taken: reject'), - ('rejected_visible', 'Publication decision taken: reject (still publicly visible)'), - ('published', 'Published'), - # If withdrawn: - ('withdrawn', 'Withdrawn by the Authors'), - ) -submission_status_dict = dict(SUBMISSION_STATUS) - -SUBMISSION_STATUS_OUT_OF_POOL = [ - 'assignment_failed', - 'resubmitted', - 'published', - 'withdrawn', - 'rejected', - 'rejected_visible', -] - -# Submissions which should not appear in search lists -SUBMISSION_STATUS_PUBLICLY_UNLISTED = [ - 'unassigned', - 'assignment_failed', - 'resubmitted', - 'resubmitted_rejected', - 'resubmitted_rejected_visible', - 'rejected', - 'published', - 'withdrawn', -] - -# Submissions which should not be viewable (except by admins, Fellows and authors) -SUBMISSION_STATUS_PUBLICLY_INVISIBLE = [ - 'unassigned', - 'assignment_failed', - 'resubmitted_rejected', - 'rejected', - 'withdrawn', -] - -# Submissions for which voting on a related recommendation is deprecated: -SUBMISSION_STATUS_VOTING_DEPRECATED = [ - 'rejected', - 'published', - 'withdrawn', -] - -SUBMISSION_TYPE = ( - ('Letter', 'Letter (broad-interest breakthrough results)'), - ('Article', 'Article (in-depth reports on specialized research)'), - ('Review', 'Review (candid snapshot of current research in a given area)'), -) -submission_type_dict = dict(SUBMISSION_TYPE) - - -class SubmissionManager(models.Manager): - def get_pool(self, user): - return self.exclude(status__in=SUBMISSION_STATUS_OUT_OF_POOL)\ - .exclude(is_current=False)\ - .exclude(authors=user.contributor)\ - .exclude(Q(author_list__icontains=user.last_name), - ~Q(authors_false_claims=user.contributor))\ - .order_by('-submission_date') - - class Submission(ArxivCallable, models.Model): # Main submission fields author_comments = models.TextField(blank=True, null=True) @@ -116,7 +42,8 @@ class Submission(ArxivCallable, models.Model): secondary_areas = ChoiceArrayField( models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS), blank=True, null=True) - status = models.CharField(max_length=30, choices=SUBMISSION_STATUS, default='unassigned') # set by Editors + # Status set by Editors + status = models.CharField(max_length=30, choices=SUBMISSION_STATUS, default='unassigned') subject_area = models.CharField(max_length=10, choices=SCIPOST_SUBJECT_AREAS, verbose_name='Primary subject area', default='Phys:QP') submission_type = models.CharField(max_length=10, choices=SUBMISSION_TYPE, @@ -167,9 +94,7 @@ class Submission(ArxivCallable, models.Model): @property def reporting_deadline_has_passed(self): - if timezone.now() > self.reporting_deadline: - return True - return False + return timezone.now() > self.reporting_deadline @transaction.atomic def finish_submission(self): @@ -236,91 +161,6 @@ class Submission(ArxivCallable, models.Model): arxiv_identifier_wo_vn_nr=self.arxiv_identifier_wo_vn_nr ).exclude(pk=self.id).order_by('-arxiv_vn_nr') - def header_as_table(self): - # for Submission page - header = '<table class="submission_header">' - header += '<tr><td>Title: </td><td>{{ title }}</td></tr>' - header += '<tr><td>Author(s): </td><td>{{ author_list }}</td></tr>' - header += '<tr><td>As Contributors: </td>' - if self.authors.all(): - header += '<td>' - for auth in self.authors.all(): - header += ('<a href="/contributor/' + str(auth.id) + '">' + auth.user.first_name - + ' ' + auth.user.last_name + '</a>') - header += '</td>' - else: - header += '<td>(none claimed)</td>' - header += ('</tr>' - '<tr><td>arxiv Link: </td>' - '<td><a href="{{ arxiv_link }}" target="_blank">{{ arxiv_link }}</a></td></tr>' - '<tr><td>Date submitted: </td><td>{{ submission_date }}</td></tr>' - '<tr><td>Submitted by: </td><td>{{ submitted_by }}</td></tr>' - '<tr><td>Submitted to: </td><td>{{ to_journal }}</td></tr>' - '<tr><td>Domain(s): </td><td>{{ domain }}</td></tr>' - '<tr><td>Subject area: </td><td>{{ subject_area }}</td></tr>' - '</table>') - template = Template(header) - context = Context({ - 'title': self.title, 'author_list': self.author_list, - 'arxiv_link': self.arxiv_link, 'submission_date': self.submission_date, - 'submitted_by': self.submitted_by, - 'to_journal': journals_submit_dict[self.submitted_to_journal], - 'domain': journals_domains_dict[self.domain], - 'subject_area': subject_areas_dict[self.subject_area], - }) - return template.render(context) - - def header_as_li(self): - # for search lists - header = ('<li>' - '<p>' - '<a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p>Version {{ arxiv_vn_nr }}') - if self.is_current: - header += ' (current version)' - else: - header += ' (deprecated version {{ arxiv_vn_nr }})' - header += ('</p><p> Submitted {{ submission_date }} to {{ to_journal }}' - ' - latest activity: {{ latest_activity }}</p>' - '</li>') - context = Context({'arxiv_identifier_w_vn_nr': self.arxiv_identifier_w_vn_nr, - 'arxiv_vn_nr': self.arxiv_vn_nr, - 'title': self.title, 'author_list': self.author_list, - 'submission_date': self.submission_date, - 'to_journal': journals_submit_dict[self.submitted_to_journal], - 'latest_activity': self.latest_activity.strftime('%Y-%m-%d %H:%M')}) - template = Template(header) - return template.render(context) - - def header_as_li_for_authors(self): - # includes status specification - header = ('<li>' - '<p><a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p>Version {{ arxiv_vn_nr }}') - if self.is_current: - header += ' (current version)' - else: - header += ' (deprecated version {{ arxiv_vn_nr }})' - header += ('</p><p>Submitted {{ submission_date }} to {{ to_journal }}' - ' - latest activity: {{ latest_activity }}</p>' - '<p>Status: {{ status }}</p>' - '</li>') - context = Context({ - 'arxiv_identifier_w_vn_nr': self.arxiv_identifier_w_vn_nr, - 'arxiv_vn_nr': self.arxiv_vn_nr, - 'title': self.title, 'author_list': self.author_list, - 'submission_date': self.submission_date, - 'to_journal': journals_submit_dict[self.submitted_to_journal], - 'latest_activity': self.latest_activity.strftime('%Y-%m-%d %H:%M'), - 'status': submission_status_dict[self.status] - }) - template = Template(header) - return template.render(context) - def count_accepted_invitations(self): return self.refereeinvitation_set.filter(accepted=True).count() @@ -345,132 +185,11 @@ class Submission(ArxivCallable, models.Model): def count_awaiting_vetting(self): return self.reports.filter(status=0).count() - def refereeing_status_as_p(self): - nr_ref_invited = RefereeInvitation.objects.filter(submission=self).count() - nr_ref_accepted = RefereeInvitation.objects.filter(submission=self, accepted=True).count() - nr_ref_declined = RefereeInvitation.objects.filter(submission=self, accepted=False).count() - nr_invited_reports_in = Report.objects.filter(submission=self, - status=1, invited=True).count() - nr_contrib_reports_in = Report.objects.filter(submission=self, - status=1, invited=False).count() - nr_reports_awaiting_vetting = Report.objects.filter(submission=self, status=0).count() - nr_reports_refused = Report.objects.filter(submission=self, status__lte=-1).count() - header = ('<p>Nr referees invited: ' + str(nr_ref_invited) + - ' [' + str(nr_ref_accepted) + ' accepted/ ' + - str(nr_ref_declined) + ' declined/ ' + - str(nr_ref_invited - nr_ref_accepted - nr_ref_declined) + - ' response pending]</p>' + - '<p>Nr reports obtained: ' + - str(nr_invited_reports_in + nr_contrib_reports_in) + ' [' + - str(nr_invited_reports_in) + ' invited/ ' + str(nr_contrib_reports_in) + - ' contributed], nr refused: ' + str(nr_reports_refused) + - ', nr awaiting vetting: ' + str(nr_reports_awaiting_vetting) + '</p>') - template = Template(header) - context = Context({}) - return template.render(context) - - def header_as_li_for_Fellows(self): - # for submissions pool - header = ('<li>' - '<p><a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p>Version {{ arxiv_vn_nr }}') - if self.is_current: - header += ' (current version)' - else: - header += ' (deprecated version {{ arxiv_vn_nr }})' - header += ('</p><p> Submitted {{ submission_date }} to {{ to_journal }}' - ' - latest activity: {{ latest_activity }}</p>') - if self.status == 'unassigned': - header += ('<p style="color: red">Status: {{ status }}.' - ' You can volunteer to become Editor-in-charge by ' - '<a href="/submissions/volunteer_as_EIC/{{ arxiv_identifier_w_vn_nr }}">' - 'clicking here</a>.</p>') - else: - header += '<p>Editor-in-charge: {{ EIC }}</p><p>Status: {{ status }}</p>' - header += self.refereeing_status_as_p() - header += '</li>' - context = Context({'arxiv_identifier_w_vn_nr': self.arxiv_identifier_w_vn_nr, - 'arxiv_vn_nr': self.arxiv_vn_nr, - 'title': self.title, 'author_list': self.author_list, - 'submission_date': self.submission_date, - 'to_journal': journals_submit_dict[self.submitted_to_journal], - 'latest_activity': self.latest_activity.strftime('%Y-%m-%d %H:%M'), - 'EIC': str(self.editor_in_charge), - 'status': submission_status_dict[self.status]}) - template = Template(header) - return template.render(context) - - def simple_header_as_li(self): - # for Lists - header = ('<li>' - '<p>' - '<a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p>Version {{ arxiv_vn_nr }}') - if self.is_current: - header += ' (current version)' - else: - header += ' (deprecated version {{ arxiv_vn_nr }})' - header += ('</p>' - '</li>') - context = Context({'arxiv_identifier_w_vn_nr': self.arxiv_identifier_w_vn_nr, - 'arxiv_vn_nr': self.arxiv_vn_nr, - 'title': self.title, 'author_list': self.author_list}) - template = Template(header) - return template.render(context) - - def version_info_as_li(self): - # for listing all versions of a Submission - header = ('<li>' - '<p>' - '<a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">version {{ arxiv_vn_nr }}</a>') - if self.is_current: - header += ' (current version)' - else: - header += ' (deprecated version {{ arxiv_vn_nr }})' - header += ('</p>' - '</li>') - context = Context({'arxiv_identifier_w_vn_nr': self.arxiv_identifier_w_vn_nr, - 'arxiv_vn_nr': self.arxiv_vn_nr, }) - template = Template(header) - return template.render(context) - - def status_info_as_table(self): - header = '<table><tr><td>Current status: </td><td> </td><td>{{ status }}' - context = Context({'status': submission_status_dict[self.status], }) - try: - context['citation'] = self.publication.citation_for_web_linked() - header += ' as {{ citation }}' - except Publication.DoesNotExist: - pass - header += '</td></tr></table>' - template = Template(header) - return template.render(context) - ###################### # Editorial workflow # ###################### -ASSIGNMENT_BOOL = ((True, 'Accept'), (False, 'Decline')) -ASSIGNMENT_NULLBOOL = ((None, 'Response pending'), (True, 'Accept'), (False, 'Decline')) - -ASSIGNMENT_REFUSAL_REASONS = ( - ('BUS', 'Too busy'), - ('VAC', 'Away on vacation'), - ('COI', 'Conflict of interest: coauthor in last 5 years'), - ('CCC', 'Conflict of interest: close colleague'), - ('NIR', 'Cannot give an impartial assessment'), - ('NIE', 'Not interested enough'), - ('DNP', 'SciPost should not even consider this paper'), - ) -assignment_refusal_reasons_dict = dict(ASSIGNMENT_REFUSAL_REASONS) - - class EditorialAssignment(models.Model): submission = models.ForeignKey(Submission, on_delete=models.CASCADE) to = models.ForeignKey(Contributor, on_delete=models.CASCADE) @@ -483,78 +202,13 @@ class EditorialAssignment(models.Model): date_created = models.DateTimeField(default=timezone.now) date_answered = models.DateTimeField(blank=True, null=True) + objects = EditorialAssignmentManager() + def __str__(self): return (self.to.user.first_name + ' ' + self.to.user.last_name + ' to become EIC of ' + self.submission.title[:30] + ' by ' + self.submission.author_list[:30] + ', requested on ' + self.date_created.strftime('%Y-%m-%d')) - def info_as_li(self): - context = Context({'first_name': self.to.user.first_name, - 'last_name': self.to.user.last_name, - 'date_created': self.date_created.strftime('%Y-%m-%d %H:%M')}) - info = '<li' - if self.accepted: - info += ' style="color: green"' - elif self.deprecated: - info += ' style="color: purple"' - elif not self.accepted: - if self.refusal_reason == 'NIE' or self.refusal_reason == 'DNP': - info += ' style="color: #CC0000"' - else: - info += ' style="color: #FF7700"' - info += '>{{ first_name }} {{ last_name }}, requested {{ date_created }}' - if self.accepted: - info += ', accepted {{ date_answered }}' - context['date_answered'] = self.date_answered.strftime('%Y-%m-%d %H:%M') - if self.deprecated: - info += ', deprecated' - if self.refusal_reason: - info += ', declined {{ date_answered }}, reason: {{ reason }}' - context['date_answered'] = self.date_answered.strftime('%Y-%m-%d %H:%M') - context['reason'] = assignment_refusal_reasons_dict[self.refusal_reason] - info += '</li>' - template = Template(info) - return template.render(context) - - def header_as_li_for_eic(self): - header = ('<li>' - '<p><a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p> (submitted {{ date }} to {{ to_journal }})</p>' - '<p>Status: {{ status }}</p><p>Manage this Submission from its ' - '<a href="/submissions/editorial_page/{{ arxiv_identifier_w_vn_nr }}">' - 'Editorial Page</a>.' - '</p>' - '</li>') - template = Template(header) - context = Context({'arxiv_identifier_w_vn_nr': self.submission.arxiv_identifier_w_vn_nr, - 'title': self.submission.title, - 'author_list': self.submission.author_list, - 'date': self.submission.submission_date, - 'to_journal': journals_submit_dict[self.submission.submitted_to_journal], - 'status': submission_status_dict[self.submission.status]}) - return template.render(context) - - def header_as_li(self): - """ Same as above, but without link to Editorial Page. """ - header = ('<li>' - '<p><a href="/submission/{{ arxiv_identifier_w_vn_nr }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>by {{ author_list }}</p>' - '<p> (submitted {{ date }} to {{ to_journal }})</p>' - '<p>Status: {{ status }}</p>' - '</li>') - template = Template(header) - context = Context({ - 'arxiv_identifier_w_vn_nr': self.submission.arxiv_identifier_w_vn_nr, - 'title': self.submission.title, - 'author_list': self.submission.author_list, - 'date': self.submission.submission_date, - 'to_journal': journals_submit_dict[self.submission.submitted_to_journal], - 'status': submission_status_dict[self.submission.status]}) - return template.render(context) - class RefereeInvitation(models.Model): submission = models.ForeignKey(Submission, on_delete=models.CASCADE) @@ -583,81 +237,14 @@ class RefereeInvitation(models.Model): self.submission.title[:30] + ' by ' + self.submission.author_list[:30] + ', invited on ' + self.date_invited.strftime('%Y-%m-%d')) - def summary_as_tds(self): - context = Context({'first_name': self.first_name, 'last_name': self.last_name, - 'date_invited': self.date_invited.strftime('%Y-%m-%d %H:%M')}) - output = ('<td>{{ first_name }} {{ last_name }}</td><td>invited <br/>' - '{{ date_invited }}</td><td>') - if self.cancelled: - output += '<strong style="color: red;">cancelled</strong>' - elif self.accepted is not None: - if self.accepted: - output += '<strong style="color: green">task accepted</strong> ' - else: - output += '<strong style="color: red">task declined</strong> ' - output += '<br/>{{ date_responded }}' - context['date_responded'] = self.date_responded.strftime('%Y-%m-%d %H:%M') - else: - output += 'response pending' - if self.fulfilled: - output += '<br/><strong style="color: green">task fulfilled</strong>' - output += '</td>' - template = Template(output) - return template.render(context) - ########### # Reports: ########### -REFEREE_QUALIFICATION = ( - (4, 'expert in this subject'), - (3, 'very knowledgeable in this subject'), - (2, 'knowledgeable in this subject'), - (1, 'generally qualified'), - (0, 'not qualified'), - ) -ref_qualif_dict = dict(REFEREE_QUALIFICATION) - -QUALITY_SPEC = ( - (6, 'perfect'), - (5, 'excellent'), - (4, 'good'), - (3, 'reasonable'), - (2, 'acceptable'), - (1, 'below threshold'), - (0, 'mediocre'), - ) -quality_spec_dict = dict(QUALITY_SPEC) - - -RANKING_CHOICES = ( - (101, '-'), # Only values between 0 and 100 are kept, anything outside those limits is discarded. - (100, 'top'), (80, 'high'), (60, 'good'), (40, 'ok'), (20, 'low'), (0, 'poor') - ) -ranking_choices_dict = dict(RANKING_CHOICES) - -REPORT_REC = ( - (1, 'Publish as Tier I (top 10% of papers in this journal, qualifies as Select) NOTE: SELECT NOT YET OPEN, STARTS EARLY 2017'), - (2, 'Publish as Tier II (top 50% of papers in this journal)'), - (3, 'Publish as Tier III (meets the criteria of this journal)'), - (-1, 'Ask for minor revision'), - (-2, 'Ask for major revision'), - (-3, 'Reject') - ) -report_rec_dict = dict(REPORT_REC) - - class Report(models.Model): """ Both types of reports, invited or contributed. """ - # status: see forms.py:REPORT_REFUSAL_CHOICES - # 1: vetted - # 0: unvetted - # -1: rejected (unclear) - # -2: rejected (incorrect) - # -3: rejected (not useful) - # -4: rejected (not academic in style) - status = models.SmallIntegerField(default=0) + status = models.SmallIntegerField(choices=REPORT_STATUSES, default=STATUS_UNVETTED) submission = models.ForeignKey(Submission, related_name='reports', on_delete=models.CASCADE) vetted_by = models.ForeignKey(Contributor, related_name="report_vetted_by", blank=True, null=True, on_delete=models.CASCADE) @@ -694,84 +281,11 @@ class Report(models.Model): return (self.author.user.first_name + ' ' + self.author.user.last_name + ' on ' + self.submission.title[:50] + ' by ' + self.submission.author_list[:50]) - def print_identifier(self): - context = Context({'id': self.id, 'author_id': self.author.id, - 'first_name': self.author.user.first_name, - 'last_name': self.author.user.last_name, - 'date_submitted': self.date_submitted.strftime("%Y-%m-%d")}) - output = '<div class="reportid">' - output += '<h3><a id="report_id{{ id }}"></a>' - if self.anonymous: - output += 'Anonymous Report {{ id }}' - else: - output += '<a href="/contributor/{{ author_id }}">{{ first_name }} {{ last_name }}</a>' - output += ' on {{ date_submitted }}</h3></div>' - template = Template(output) - return template.render(context) - - 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-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>' - '<li>originality: ' + ranking_choices_dict[self.originality] + '</li>' - '<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></div></div></div>') - template = Template(output) - return template.render(context) - - def print_contents_for_editors(self): - context = Context({ - 'id': self.id, 'author_id': self.author.id, - 'author_first_name': self.author.user.first_name, - 'author_last_name': self.author.user.last_name, - 'date_submitted': self.date_submitted.strftime("%Y-%m-%d"), - 'remarks_for_editors': self.remarks_for_editors, - }) - output = '<div class="reportid">' - output += '<h3>' - if self.anonymous: - output += '(chose public anonymity) ' - output += ('<a href="/contributor/{{ author_id }}">' - '{{ author_first_name }} {{ author_last_name }}</a>' - ' on {{ date_submitted }}</h3></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 += '<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) - ########################## # EditorialCommunication # ########################## -ED_COMM_CHOICES = ( - ('EtoA', 'Editor-in-charge to Author'), - ('EtoR', 'Editor-in-charge to Referee'), - ('EtoS', 'Editor-in-charge to SciPost Editorial Administration'), - ('AtoE', 'Author to Editor-in-charge'), - ('RtoE', 'Referee to Editor-in-Charge'), - ('StoE', 'SciPost Editorial Administration to Editor-in-charge'), - ) -ed_comm_choices_dict = dict(ED_COMM_CHOICES) - - class EditorialCommunication(models.Model): """ Each individual communication between Editor-in-charge @@ -792,47 +306,11 @@ class EditorialCommunication(models.Model): + self.submission.author_list[:30]) return output - def print_contents_as_li(self): - context = Context({'timestamp': self.timestamp.strftime("%Y-%m-%d %H:%M"), - 'text': self.text}) - output = '<li><p>' - if self.comtype == 'EtoA': - output += 'From you to Authors' - elif self.comtype == 'EtoR': - output += 'From you to Referee ' - try: - output += self.referee.user.first_name + ' ' + self.referee.user.last_name - except AttributeError: - pass - elif self.comtype == 'EtoS': - output += 'From you to SciPost Ed Admin' - elif self.comtype == 'AtoE': - output += 'From Authors to you' - elif self.comtype == 'RtoE': - output += 'From Referee ' - try: - output += (self.referee.user.first_name + ' ' + - self.referee.user.last_name + ' to you') - except AttributeError: - pass - elif self.comtype == 'StoE': - output += 'From SciPost Ed Admin to you' - output += ' on {{ timestamp }}</p><p>{{ text }}</p>' - template = Template(output) - return template.render(context) - ############################ # Editorial Recommendation # ############################ -class EICRecommendationManager(models.Manager): - def get_for_user_in_pool(self, user): - return self.exclude(submission__authors=user.contributor)\ - .exclude(Q(submission__author_list__icontains=user.last_name), - ~Q(submission__authors_false_claims=user.contributor)) - - # From the Editor-in-charge of a Submission class EICRecommendation(models.Model): submission = models.ForeignKey(Submission, on_delete=models.CASCADE) @@ -855,7 +333,7 @@ class EICRecommendation(models.Model): def __str__(self): return (self.submission.title[:20] + ' by ' + self.submission.author_list[:30] + - ', ' + report_rec_dict[self.recommendation]) + ', ' + self.get_recommendation_display()) @property def nr_for(self): @@ -868,41 +346,3 @@ class EICRecommendation(models.Model): @property def nr_abstained(self): return self.voted_abstain.count() - - def print_for_authors(self): - output = ('<h3>Date: {{ date_submitted }}</h3>' - '<h3>Remarks for authors</h3>' - '<p>{{ remarks_for_authors }}</p>' - '<h3>Requested changes</h3>' - '<p>{{ requested_changes }}</p>' - '<h3>Recommendation</h3>' - '<p>{{ recommendation }}</p>') - context = Context({ - 'date_submitted': self.date_submitted.strftime('%Y-%m-%d %H:%M'), - 'remarks_for_authors': self.remarks_for_authors, - 'requested_changes': self.requested_changes, - 'recommendation': report_rec_dict[self.recommendation], }) - template = Template(output) - return template.render(context) - - def print_for_Fellows(self): - output = ('<h3>By {{ Fellow }}, formulated on {{ date_submitted }}</h3>' - '<h3>Remarks for authors</h3>' - '<p>{{ remarks_for_authors }}</p>' - '<h3>Requested changes</h3>' - '<p>{{ requested_changes }}</p>' - '<h3>Remarks for Editorial College</h3>' - '<p>{{ remarks_for_editorial_college }}</p>' - '<h3>Recommendation</h3>' - '<p>{{ recommendation }}</p>') - context = Context({ - 'Fellow': (title_dict[self.submission.editor_in_charge.title] + - ' ' + self.submission.editor_in_charge.user.first_name + - ' ' + self.submission.editor_in_charge.user.last_name), - 'date_submitted': self.date_submitted.strftime('%Y-%m-%d %H:%M'), - 'remarks_for_authors': self.remarks_for_authors, - 'requested_changes': self.requested_changes, - 'remarks_for_editorial_college': self.remarks_for_editorial_college, - 'recommendation': report_rec_dict[self.recommendation], }) - template = Template(output) - return template.render(context) diff --git a/submissions/templates/submissions/_assignment_info.html b/submissions/templates/submissions/_assignment_info.html new file mode 100644 index 0000000000000000000000000000000000000000..c8868667b22a8093c1be89ee2139def1ca615634 --- /dev/null +++ b/submissions/templates/submissions/_assignment_info.html @@ -0,0 +1,23 @@ +<li class="py-1"> + {{ assignment.to.user.first_name }} {{ assignment.to.user.last_name }} + + {% if assignment.accepted %} + <span class="label label-sm label-outline-success">accepted</span> + {% endif %} + {% if assignment.deprecated %} + <span class="label label-sm label-outline-info">deprecated</span> + {% endif %} + {% if assignment.refusal_reason %} + <span class="label label-sm label-outline-{% if assignment.refusal_reason == 'NIE' or assignment.refusal_reason == 'DNP' %}danger{% else %}warning{% endif %}">declined + | Reason: {{ assignment.get_refusal_reason_display }} + </span> + {% endif %} + + <br> + <span class="text-muted"> + requested {{ assignment.date_created }} + {% if assignment.date_answered %} + | answered {{ assignment.date_answered }} + {% endif %} + </span> +</li> diff --git a/submissions/templates/submissions/_editorial_communication_content.html b/submissions/templates/submissions/_editorial_communication_content.html new file mode 100644 index 0000000000000000000000000000000000000000..9086065ca8fc031f9a77fa1ff9f1efd03661bda4 --- /dev/null +++ b/submissions/templates/submissions/_editorial_communication_content.html @@ -0,0 +1,25 @@ +<div class="card-block pt-3{% if communication.comtype == 'EtoA' or communication.comtype == 'EtoR' or communication.comtype == 'EtoS' %} text-right{% endif %}"> + <div class="label label-sm label-secondary"> + {% if communication.comtype == 'EtoA' %} + From you to Authors + {% elif communication.comtype == 'EtoR' %} + From you to Referee + {% if communication.referee %} + {{communication.referee.user.first_name}} {{communication.referee.user.last_name}} + {% endif %} + {% elif communication.comtype == 'EtoS' %} + From you to SciPost Ed Admin + {% elif communication.comtype == 'AtoE' %} + From Authors to you + {% elif communication.comtype == 'RtoE' %} + From Referee + {% if communication.referee %} + {{communication.referee.user.first_name}} {{communication.referee.user.last_name}} + {% endif %} to you + {% elif communication.comtype == 'StoE' %} + From SciPost Ed Admin to you + {% endif %} + </div> + <div class="text pb-1 pt-1">{{communication.text|linebreaks}}</div> + <div class="text-muted">on {{communication.timestamp}}</div> +</div> diff --git a/submissions/templates/submissions/_recommendation_author_content.html b/submissions/templates/submissions/_recommendation_author_content.html new file mode 100644 index 0000000000000000000000000000000000000000..7f4646b6e17a7fcd414a547c940f63bcceec4dc8 --- /dev/null +++ b/submissions/templates/submissions/_recommendation_author_content.html @@ -0,0 +1,19 @@ +<div class="card-block"> + {% block recommendation_header %} + <h3 class="card-title">Date {{recommendation.date_submitted}}</h3> + {% endblock %} + + <h3 class="pb-0">Remarks for authors</h3> + <p class="pl-md-3">{{recommendation.remarks_for_authors}}</p> + + <h3 class="pb-0">Requested changes</h3> + <p class="pl-md-3">{{recommendation.requested_changes}}</p> + + <h3 class="pb-0">Remarks for Editorial College</h3> + <p class="pl-md-3">{{recommendation.remarks_for_editorial_college}}</p> + + {% block recommendation_before_recommendation %}{% endblock %} + + <h3 class="pb-0">Recommendation</h3> + <p class="pl-md-3 mb-0">{{recommendation.get_recommendation_display}}</p> +</div> diff --git a/submissions/templates/submissions/_recommendation_fellow_content.html b/submissions/templates/submissions/_recommendation_fellow_content.html index 3ee1572de1ee79da41f0751b8a84edf9bf8e7e61..1cb07e3a91404cba5bfef1a2d0c9b5dc61cf1813 100644 --- a/submissions/templates/submissions/_recommendation_fellow_content.html +++ b/submissions/templates/submissions/_recommendation_fellow_content.html @@ -1,15 +1,10 @@ -<div class="card-block"> - <h3 class="card-title text-blue">By {{recommendation.submission.editor_in_charge.get_title_display}} {{recommendation.submission.editor_in_charge.user.first_name}} {{recommendation.submission.editor_in_charge.user.last_name}}, formulated on {{recommendation.date_submitted}}</h3> - - <h3 class="pb-0">Remarks for authors</h3> - <p class="pl-md-3">{{recommendation.remarks_for_authors}}</p> +{% extends 'submissions/_recommendation_author_content.html' %} - <h3 class="pb-0">Requested changes</h3> - <p class="pl-md-3">{{recommendation.requested_changes}}</p> +{% block recommendation_header %} + <h3 class="card-title text-blue">By {{recommendation.submission.editor_in_charge.get_title_display}} {{recommendation.submission.editor_in_charge.user.first_name}} {{recommendation.submission.editor_in_charge.user.last_name}}, formulated on {{recommendation.date_submitted}}</h3> +{% endblock %} +{% block recommendation_before_recommendation %} <h3 class="pb-0">Remarks for Editorial College</h3> <p class="pl-md-3">{{recommendation.remarks_for_editorial_college}}</p> - - <h3 class="pb-0">Recommendation</h3> - <p class="pl-md-3 mb-0">{{recommendation.get_recommendation_display}}</p> -</div> +{% endblock %} diff --git a/submissions/templates/submissions/_refereeing_invitation_card_content.html b/submissions/templates/submissions/_refereeing_invitation_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..e90930c773afc24efa3ea9b0e676e25d2f7f617b --- /dev/null +++ b/submissions/templates/submissions/_refereeing_invitation_card_content.html @@ -0,0 +1,10 @@ +<div class="card-block"> + <h3 class="card-title">{% if invitation.submission.reporting_deadline_has_passed %}<span class="label label-sm label-danger mr-2">overdue</span> {% endif %}{{ invitation.submission }}</h3> + <h4 class="card-subtitle text-muted">due: {{ invitation.submission.reporting_deadline }}</h4> + + <div class="d-block"> + <a class="d-inline-block" href="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=invitation.submission.arxiv_identifier_w_vn_nr %}">Submit your Report</a> <span class="text-blue">|</span> + <a class="d-inline-block" href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=invitation.submission.arxiv_identifier_w_vn_nr comtype='RtoE' referee_id=request.user.contributor.id %}">Write to the Editor-in-charge</a>. + </div> + +</div> diff --git a/submissions/templates/submissions/_remark_add_form.html b/submissions/templates/submissions/_remark_add_form.html new file mode 100644 index 0000000000000000000000000000000000000000..1541145e29fca3ec142bae5ec2d6fde733a54bea --- /dev/null +++ b/submissions/templates/submissions/_remark_add_form.html @@ -0,0 +1,26 @@ +{% load bootstrap %} + +<script> +$(document).ready(function(){ + $('#ref_reason').hide(); + + $('#id_accept').on('change', function() { + if ($('#id_accept_1').is(':checked')) { + $('#ref_reason').show(); + } + else { + $('#ref_reason').hide(); + } + }); + + }); +</script> + +<button class="btn btn-secondary mb-2" data-toggle="toggle" data-target="#remarkForm{{ submission.id }}" id="remarkButton{{ submission.id }}">Add a remark on this Submission</button> +<div class="submitRemarkForm pb-2" id="remarkForm{{ submission.id }}" style="display:none;"> + <form action="{% url 'submissions:add_remark' submission.arxiv_identifier_w_vn_nr %}" method="post"> + {% csrf_token %} + {{ form|bootstrap:'0,12' }} + <input class="btn btn-secondary" type="submit" value="Submit" /> + </form> +</div> diff --git a/submissions/templates/submissions/_single_public_report.html b/submissions/templates/submissions/_single_public_report.html new file mode 100644 index 0000000000000000000000000000000000000000..a733936561c287c2c8b5ccf6f579efe52b20fd56 --- /dev/null +++ b/submissions/templates/submissions/_single_public_report.html @@ -0,0 +1,10 @@ +{% extends 'submissions/_single_public_report_without_comments.html' %} + +{% block single_report_footer %} + <hr class="small"> + <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3> + + {% for reply in report.comment_set.vetted %} + {% include 'comments/_single_comment_with_link.html' with comment=reply perms=perms user=user %} + {% endfor %} +{% endblock %} diff --git a/submissions/templates/submissions/_single_public_report_without_comments.html b/submissions/templates/submissions/_single_public_report_without_comments.html new file mode 100644 index 0000000000000000000000000000000000000000..c983cd7acf95dd88e1d6a49ca2a4ba187bf06d77 --- /dev/null +++ b/submissions/templates/submissions/_single_public_report_without_comments.html @@ -0,0 +1,53 @@ +{% load scipost_extras %} +{% load submissions_extras %} + +<div class="row"> + <div class="col-12"> + <div class="report"> + {% if user.contributor == submission.editor_in_charge or user|is_in_group:'Editorial Administrators' and not is_author or user|is_in_group:'Editorial Administrators' and not is_author_unchecked %} + + <div class="reportid"> + <h3>{% if report.anonymous %}(chose public anonymity) {% endif %}<a href="{% url 'scipost:contributor_info' report.author.id %}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a> + on {{ report.date_submitted|date:'Y-n-j' }}</h3> + </h3> + </div> + + {% if report.flagged %} + <h4 class="text-danger font-weight-bold">CAUTION: check if this referee has been flagged by the authors</h4> + {% endif %} + + <div class="row"> + <div class="col-12"> + <h3 class="highlight tight">Qualification</h3> + <div class="pl-md-4">{{ report.get_qualification_display}}</div> + </div> + </div> + + {% include 'submissions/_single_report_content.html' with report=report %} + + <div class="row"> + <div class="col-12"> + <h3>Remarks for editors</h3> + <div class="pl-md-4">{{ report.remarks_for_editors }}</div> + </div> + </div> + <div class="row"> + <div class="col-12"> + <h3>Recommendation</h3> + <div class="pl-md-4">{{report.get_recommendation_display}}</div> + </div> + </div> + {% else %} + <div class="reportid"> + <h3 id="report_id{{report.id}}">{% if report.anonymous %}Anonymous Report {{report.id}}{% else %}<a href="{% url 'scipost:contributor_info' report.author.id %}">{{ report.author.user.first_name }} {{ report.author.user.last_name }}</a>{% endif %} + on {{ report.date_submitted|date:'Y-n-j' }}</h3> + </h3> + </div> + + {% include 'submissions/_single_report_content.html' with report=report %} + {% endif %} + + {% block single_report_footer %}{% endblock %} + </div> + </div> +</div> diff --git a/submissions/templates/submissions/_single_report_content.html b/submissions/templates/submissions/_single_report_content.html new file mode 100644 index 0000000000000000000000000000000000000000..82e06f943f39743d148e56b154382759fe1b2fa8 --- /dev/null +++ b/submissions/templates/submissions/_single_report_content.html @@ -0,0 +1,27 @@ +<div class="row"> + <div class="col-12"> + <h3 class="highlight tight">Strengths</h3> + <div class="pl-md-4">{{ report.strengths|linebreaks }}</div> + </div> +</div> +<div class="row"> + <div class="col-12"> + <h3 class="highlight tight">Weaknesses</h3> + <div class="pl-md-4">{{ report.weaknesses|linebreaks }}</div> + </div> +</div> +<div class="row"> + <div class="col-12"> + <h3 class="highlight tight">Report</h3> + <div class="pl-md-4">{{ report.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>{{ report.requested_changes|linebreaks }}</p> + {% include 'submissions/_single_report_ratings.html' with report=report %} + </div> + </div> +</div> diff --git a/submissions/templates/submissions/_single_report_ratings.html b/submissions/templates/submissions/_single_report_ratings.html new file mode 100644 index 0000000000000000000000000000000000000000..0ea7b074ed8dd315f18d2ed6d6aecfcab29f529a --- /dev/null +++ b/submissions/templates/submissions/_single_report_ratings.html @@ -0,0 +1,10 @@ +<div class="reportRatings"> + <ul> + <li>validity: {{report.get_validity_display}}</li> + <li>significance: {{report.get_significance_display}}</li> + <li>originality: {{report.get_originality_display}}</li> + <li>clarity: {{report.get_clarity_display}}</li> + <li>formatting: {{report.get_formatting_display}}</li> + <li>grammar: {{report.get_grammar_display}}</li> + </ul> +</div> diff --git a/submissions/templates/submissions/_submission_assignment_request.html b/submissions/templates/submissions/_submission_assignment_request.html new file mode 100644 index 0000000000000000000000000000000000000000..fa5d6099f74988830f2e27c18cac379fc0b2b548 --- /dev/null +++ b/submissions/templates/submissions/_submission_assignment_request.html @@ -0,0 +1,26 @@ +{% load bootstrap %} + +<div class="card-block"> + {% include 'submissions/_submission_summary.html' with submission=assignment.submission %} + <br /> +</div> +<div class="card-footer"> + <h1>Accept or Decline this Assignment</h1> + <h3 class="mb-2">By accepting, you will be required to start a refereeing round on the next screen.</h3> + + <form action="{% url 'submissions:accept_or_decline_assignment_ack' assignment_id=assignment.id %}" method="post"> + {% csrf_token %} + <div class="form-group row"> + <div class="col-12"> + {{ consider_assignment_form.accept }} + </div> + </div> + <div class="row" id="ref_reason"> + <div class="col-12"> + <p>Please select a reason for declining this assignment</p> + {{ consider_assignment_form.refusal_reason|bootstrap:'0,12' }} + </div> + </div> + <input class="btn btn-secondary" type="submit" value="Submit" /> + </form> +</div> diff --git a/submissions/templates/submissions/_submission_card_author_content.html b/submissions/templates/submissions/_submission_card_author_content.html new file mode 100644 index 0000000000000000000000000000000000000000..f653408362c24a276babd4278640d06688b756dd --- /dev/null +++ b/submissions/templates/submissions/_submission_card_author_content.html @@ -0,0 +1,15 @@ +{% extends 'submissions/_submission_card_base.html' %} + +{% block card_block_footer %} + {{block.super}} + <p class="card-text">by {{submission.author_list}}</p> + <p class="card-text text-muted">Version {{submission.arxiv_vn_nr}} ({% if submission.is_current %}current version{% else %}deprecated version {{submission.arxiv_vn_nr}}{% endif %})</p> + <p class="card-text text-muted">Submitted {{submission.submission_date}} to {{submission.get_submitted_to_journal_display}} - latest activity: {{submission.latest_activity}}</p> + <p class="card-text">Status: {{submission.get_status_display}}</p> + + {% if current_user and current_user.contributor == submission.submitted_by %} + <p> + <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='AtoE' %}">Write to the Editor-in-charge</a>. + </p> + {% endif %} +{% endblock %} diff --git a/submissions/templates/submissions/_submission_card_base.html b/submissions/templates/submissions/_submission_card_base.html new file mode 100644 index 0000000000000000000000000000000000000000..355d2f2e137b96c0c708c7b9b25def988627f611 --- /dev/null +++ b/submissions/templates/submissions/_submission_card_base.html @@ -0,0 +1,7 @@ +<div class="card-block"> + <h3 class="card-title"> + <a href="{% url 'submissions:submission' submission.arxiv_identifier_w_vn_nr %}">{{submission.title}}</a> + </h3> + + {% block card_block_footer %}{% endblock %} +</div> diff --git a/submissions/templates/submissions/_submission_card_content.html b/submissions/templates/submissions/_submission_card_content.html index 324763720467f6f4fdfb49f023246eb5f6ee4679..ed9d01a7aef68db99bbdce1b013860b2d2c1c1e9 100644 --- a/submissions/templates/submissions/_submission_card_content.html +++ b/submissions/templates/submissions/_submission_card_content.html @@ -1,8 +1,8 @@ -<div class="card-block"> - <h3 class="card-title"> - <a href="{% url 'submissions:submission' submission.arxiv_identifier_w_vn_nr %}">{{submission.title}}</a> - </h3> +{% extends 'submissions/_submission_card_base.html' %} + +{% block card_block_footer %} + {{block.super}} <p class="card-text">by {{submission.author_list}}</p> <p class="card-text text-muted">Version {{submission.arxiv_vn_nr}} ({% if submission.is_current %}current version{% else %}deprecated version {{submission.arxiv_vn_nr}}{% endif %})</p> <p class="card-text text-muted">Submitted {{submission.submission_date}} to {{submission.get_submitted_to_journal_display}} - latest activity: {{submission.latest_activity}}</p> -</div> +{% endblock %} diff --git a/submissions/templates/submissions/_submission_card_contributor_content.html b/submissions/templates/submissions/_submission_card_contributor_content.html new file mode 100644 index 0000000000000000000000000000000000000000..4f5b8fbe93eb705b4d1e3f6b7fc01315f7646fc7 --- /dev/null +++ b/submissions/templates/submissions/_submission_card_contributor_content.html @@ -0,0 +1,8 @@ +{% extends 'submissions/_submission_card_base.html' %} + +{% block card_block_footer %} + {{block.super}} + <p class="card-text">by {{submission.author_list}}</p> + <p class="card-text text-muted">Submitted {{submission.submission_date}} to {{submission.get_submitted_to_journal_display}}</p> + <p class="card-text text-muted">Status: {{submission.get_status_display}}</p> +{% endblock %} diff --git a/submissions/templates/submissions/_submission_card_eic_content.html b/submissions/templates/submissions/_submission_card_eic_content.html new file mode 100644 index 0000000000000000000000000000000000000000..41d94af29220d1f0b69ec2e5db8b7edf75c070c1 --- /dev/null +++ b/submissions/templates/submissions/_submission_card_eic_content.html @@ -0,0 +1,8 @@ +{% extends 'submissions/_submission_card_base.html' %} + +{% block card_block_footer %} + {{block.super}} + <p class="card-text text-muted">by {{submission.author_list}} (submitted {{submission.submission_date}} to {{submission.get_submitted_to_journal_display}})</p> + <p class="card-text text-muted">Status: {{submission.get_status_display}}</p> + <p class="card-text mt-2">Manage this Submission from its <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}">Editorial Page</a>.</p> +{% endblock %} diff --git a/submissions/templates/submissions/_submission_card_fellow_content.html b/submissions/templates/submissions/_submission_card_fellow_content.html index e75e6caf6aafae299b180123a9fb87817d074084..ac70f328dc94adadfb72beb81d9d836b3146f045 100644 --- a/submissions/templates/submissions/_submission_card_fellow_content.html +++ b/submissions/templates/submissions/_submission_card_fellow_content.html @@ -1,7 +1,8 @@ -<div class="card-block"> - <h3 class="card-title"> - <a href="{% url 'submissions:submission' submission.arxiv_identifier_w_vn_nr %}">{{submission.title}}</a> - </h3> +{% extends 'submissions/_submission_card_base.html' %} + +{% block card_block_footer %} + {{block.super}} + <p class="card-text">by {{submission.author_list}}</p> <p class="card-text text-muted">Version {{submission.arxiv_vn_nr}} ({% if submission.is_current %}current version{% else %}deprecated version {{submission.arxiv_vn_nr}}{% endif %})</p> <p class="card-text text-muted">Submitted {{submission.submission_date}} to {{submission.get_submitted_to_journal_display}} - latest activity: {{submission.latest_activity}}</p> @@ -15,5 +16,4 @@ {% endif %} {% include 'submissions/_submission_refereeing_status.html' with submission=submission %} - {# {{submission.refereeing_status_as_p}}#} -</div> +{% endblock %} diff --git a/submissions/templates/submissions/_submission_card_in_pool.html b/submissions/templates/submissions/_submission_card_in_pool.html new file mode 100644 index 0000000000000000000000000000000000000000..5012644dfd3e3efc3e712ad2271b7232c5879f0a --- /dev/null +++ b/submissions/templates/submissions/_submission_card_in_pool.html @@ -0,0 +1,66 @@ +{% load guardian_tags %} +{% load scipost_extras %} +{% load submissions_extras %} + + +{% include 'submissions/_submission_card_fellow_content.html' with submission=submission %} + +<div class="card-block"> + {% if submission.remark_set.all %} + <h4>Remarks on this submission:</h4> + <ul> + {% for rem in submission.remark_set.all %} + {{ rem.as_li }} + {% endfor %} + </ul> + {% endif %} + + {% if remark_form %} + {% include 'submissions/_remark_add_form.html' with submission=submission form=remark_form %} + {% endif %} + + {% get_obj_perms request.user for submission as "sub_perms" %} + {% if "can_take_editorial_actions" in sub_perms or request.user|is_in_group:'Editorial Administrators' %} + {% if submission|required_actions %} + <div class="required-actions"> + <h3 class="pt-0">Required actions:</h3> + <ul> + {% for todoitem in submission|required_actions %} + <li>{{ todoitem }}</li> + {% endfor %} + </ul> + </div> + {% endif %} + + <h4> + <a href="{% url 'submissions:editorial_page' submission.arxiv_identifier_w_vn_nr %}">Go to this Submission's Editorial Page</a> + </h4> + {% endif %} + + {% if perms.scipost.can_assign_submissions %} + {% if submission.editorialassignment_set.all %} + <h4>EIC Assignment requests:</h4> + <ul> + {% for assignment in submission.editorialassignment_set.all %} + {% include 'submissions/_assignment_info.html' with assignment=assignment %} + {% endfor %} + </ul> + {% endif %} + {% if submission.editor_in_charge == None %} + <h4>Actions:</h4> + <ul> + <li><a href="{% url 'submissions:assign_submission' submission.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li> + <li><a href="{% url 'submissions:assignment_failed' submission.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li> + </ul> + {% endif %} + {% endif %} + + {% if request.user|is_in_group:'Editorial Administrators' %} + <h4> + <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a> + </h4> + {% if submission.status == 'accepted' %} + <h4>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</h4> + {% endif %} + {% endif %} +</div> diff --git a/submissions/templates/submissions/_submission_refereeing_invitations.html b/submissions/templates/submissions/_submission_refereeing_invitations.html new file mode 100644 index 0000000000000000000000000000000000000000..cda5c83f100004d2102c5173aec72cb71e607a32 --- /dev/null +++ b/submissions/templates/submissions/_submission_refereeing_invitations.html @@ -0,0 +1,62 @@ +<table class="table table-invitations"> + <tbody> + {% for invitation in invitations %} + <tr> + <td>{{invitation.first_name}} {{invitation.last_name}}</td> + <td> + invited <br/> + {{invitation.date_invited}} + </td> + <td> + {% if invitation.fulfilled %} + <strong style="color: green">task fulfilled</strong> + {% elif invitation.cancelled %} + <strong class="text-danger">cancelled</strong> + {% elif invitation.accepted is not None %} + {% if invitation.accepted %} + <strong style="color: green">task accepted</strong> + {% else %} + <strong class="text-danger">task declined</strong> + {% endif %} + <div>{{invitation.date_responded}}</div> + {% else %} + reponse pending + {% endif %} + </td> + + {% if not invitation.accepted == False and not invitation.cancelled %} + <td> + {% if invitation.referee %} + <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoR' referee_id=invitation.referee.id %}">Write a communication</a> + {% else %} + (not yet registered) + {% endif %} + </td> + <td> + {% if not invitation.fulfilled %} + <a href="{% url 'submissions:ref_invitation_reminder' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr invitation_id=invitation.id %}">Send reminder email</a> + {% else %} + <strong style="color: green">Report has been delivered</strong> + {% endif %} + </td> + <td> + {% if invitation.nr_reminders > 0 %} + (nr reminders sent: {{ invitation.nr_reminders }}, <br/>last on {{ invitation.date_last_reminded }}) + {% endif %} + </td> + <td> + {% if not invitation.fulfilled %} + <a href="{% url 'submissions:cancel_ref_invitation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr invitation_id=invitation.id %}">Cancel invitation</a> + {% endif %} + </td> + {% else %} + <td colspan="4"></td> + {% endif %} + </tr> + {% empty %} + <tr> + <td class="text-center py-3">You have not invited any referees yet.</td> + </tr> + {% endfor %} + </tbody> +</table> diff --git a/submissions/templates/submissions/_submission_status_block.html b/submissions/templates/submissions/_submission_status_block.html new file mode 100644 index 0000000000000000000000000000000000000000..3229f263d36177a58aebc907fd93c6121aa21b21 --- /dev/null +++ b/submissions/templates/submissions/_submission_status_block.html @@ -0,0 +1,7 @@ +<h3 class="d-inline-block">Current status:</h3> +<div class="d-inline"> + <span class="label label-secondary">{{submission.get_status_display}}</span> + {% if submission.publication %} + as {{submission.publication.citation_for_web_linked}} + {% endif %} +</div> diff --git a/submissions/templates/submissions/_submission_summary.html b/submissions/templates/submissions/_submission_summary.html new file mode 100644 index 0000000000000000000000000000000000000000..334f2d67912757293c26183e4412ee0e8f6d1601 --- /dev/null +++ b/submissions/templates/submissions/_submission_summary.html @@ -0,0 +1,6 @@ +{% extends 'submissions/_submission_summary_short.html' %} + +{% block submission_summary_footer %} + <h3 class="mt-3">Abstract</h3> + <p>{{submission.abstract}}</p> +{% endblock %} diff --git a/submissions/templates/submissions/_submission_summary_short.html b/submissions/templates/submissions/_submission_summary_short.html new file mode 100644 index 0000000000000000000000000000000000000000..ca045cbf8b37536f29828c769d0d9fec1d764a9e --- /dev/null +++ b/submissions/templates/submissions/_submission_summary_short.html @@ -0,0 +1,49 @@ +<table class="submission summary"> + <tr> + <td>Title:</td> + <td>{{submission.title}}</td> + </tr> + <tr> + <td>Author(s):</td> + <td>{{submission.author_list}}</td> + </tr> + <tr> + <td>As Contributors:</td> + <td> + {% for author in submission.authors.all %} + <a href="{% url 'scipost:contributor_info' author.id %}">{{author.user.first_name}} {{author.user.last_name}}</a> + {% empty %} + (none claimed) + {% endfor %} + </td> + </tr> + + <tr> + <td>arxiv Link:</td> + <td> + <a href="{{submission.arxiv_link}}" target="_blank">{{submission.arxiv_link}}</a> + </td> + </tr> + <tr> + <td>Date submitted:</td> + <td>{{submission.submission_date}}</td> + </tr> + <tr> + <td>Submitted by:</td> + <td>{{submission.submitted_by}}</td> + </tr> + <tr> + <td>Submitted to:</td> + <td>{{submission.get_submitted_to_journal_display}}</td> + </tr> + <tr> + <td>Domain(s):</td> + <td>{{submission.get_domain_display}}</td> + </tr> + <tr> + <td>Subject area:</td> + <td>{{submission.get_subject_area_display}}</td> + </tr> +</table> + +{% block submission_summary_footer %}{% endblock %} diff --git a/submissions/templates/submissions/_submission_version.html b/submissions/templates/submissions/_submission_version.html new file mode 100644 index 0000000000000000000000000000000000000000..9bb1c6e240fc2b77895a9bed0bc9ce28cfdabff1 --- /dev/null +++ b/submissions/templates/submissions/_submission_version.html @@ -0,0 +1,10 @@ +<div class="py-1"> + <a href="{% url 'submissions:submission' submission.arxiv_identifier_w_vn_nr %}" class="pubtitleli">version {{submission.arxiv_vn_nr}}</a> + <span class="version-suffix"> + {% if submission.is_current %} + (current version) + {% else %} + (deprecated version {{submission.arxiv_vn_nr}}) + {% endif %} + </span> +</div> diff --git a/submissions/templates/submissions/accept_or_decline_ref_invitations.html b/submissions/templates/submissions/accept_or_decline_ref_invitations.html index 518a0144693bf276a95899ce0a6651f150e24858..12465e7f61e2510bd50d5b474c0dad6df54fe8c5 100644 --- a/submissions/templates/submissions/accept_or_decline_ref_invitations.html +++ b/submissions/templates/submissions/accept_or_decline_ref_invitations.html @@ -33,10 +33,8 @@ $(document).ready(function(){ </div> <br> <hr> - {{ invitation_to_consider.submission.header_as_table }} - <br /> - <h4>Abstract:</h4> - <p>{{ invitation_to_consider.submission.abstract }}</p> + {% include 'submissions/_submission_summary.html' with submission=invitation_to_consider.submission %} + <br/> <hr> <div class="flex-greybox"> diff --git a/submissions/templates/submissions/assign_submission.html b/submissions/templates/submissions/assign_submission.html index 6365bf7feb95c769e7d3f8fd23f9e55a462faf47..15599863694c23cd653f9bc7a8b8e576f10ce594 100644 --- a/submissions/templates/submissions/assign_submission.html +++ b/submissions/templates/submissions/assign_submission.html @@ -10,10 +10,9 @@ <br> <hr> - {{ submission_to_assign.header_as_table }} - <br /> - <h4>Abstract:</h4> - <p>{{ submission_to_assign.abstract }}</p> + + {% include 'submissions/_submission_summary.html' with submission=submission_to_assign %} + <br/> <hr/> @@ -29,7 +28,7 @@ <br/> <hr> - {{ submission_to_assign.status_info_as_table }} + {% include 'submissions/_submission_status_block.html' with submission=submission %} <hr> {% if submission_to_assign.editorialassignment_set.all %} @@ -37,7 +36,7 @@ <h3>If more than 5 Fellows have declined an assignment for a red-marked reason, the Submission should be rejected.</h3> <ul> {% for assignment in sub.editorialassignment_set.all %} - {{ assignment.info_as_li }} + {% include 'submissions/_assignment_info.html' with assignment=assignment %} {% endfor %} </ul> {% endif %} diff --git a/submissions/templates/submissions/assignments.html b/submissions/templates/submissions/assignments.html index 9fa1e95e0cdad78833979b564e726cbe4311fa2b..ed4ba37f61f4da762b7137600fcbae98dbc24c82 100644 --- a/submissions/templates/submissions/assignments.html +++ b/submissions/templates/submissions/assignments.html @@ -1,8 +1,12 @@ {% extends 'scipost/base.html' %} +{% load guardian_tags %} +{% load scipost_extras %} +{% load submissions_extras %} + {% block pagetitle %}: Assignments{% endblock pagetitle %} -{% block bodysup %} +{% block content %} <script> $(document).ready(function(){ @@ -16,92 +20,74 @@ $(document).ready(function(){ else { $('#ref_reason').hide(); } - }); - - $(".submitRemarkForm").hide(); - - $(".submitRemarkButton").click( function() { - $(this).next("div").toggle(); - }); }); +}); </script> -{% load guardian_tags %} -{% load scipost_extras %} -{% load submissions_extras %} - - {% if assignments_to_consider %} -<section> - - {% for assignment_to_consider in assignments_to_consider %} - - <div class="flex-greybox"> - <h1>Assignment request: can you act as Editor-in-charge? (see below to accept/decline):</h1> - </div> - <br> - <hr> - - {{ assignment_to_consider.submission.header_as_table }} - <br /> - <h4>Abstract:</h4> - <p>{{ assignment_to_consider.submission.abstract }}</p> - <br/> - - <hr> - <div class="flex-greybox"> - <h1>Accept or Decline this Assignment</h1> - </div> - <h3>By accepting, you will be required to start a refereeing round on the next screen.</h3> - <form action="{% url 'submissions:accept_or_decline_assignment_ack' assignment_id=assignment_to_consider.id %}" method="post"> - {% csrf_token %} - {{ consider_assignment_form.accept }} - <div id="ref_reason"> - <p>Please select a reason for declining this assignment:</p> - {{ consider_assignment_form.refusal_reason }} + <div class="row"> + <div class="col-12"> + <div class="highlight d-block p-3"> + <h1 class="p-0">Assignment request</h1> + <h3 class="p-0 mt-1 d-block text-muted">Can you act as Editor-in-charge? (see below to accept/decline)</h3> + </div> + </div> </div> - <input type="submit" value="Submit" /> - </form> - - <hr class="hr6"/> - {% endfor %} - -</section> -<hr class="hr12"/> + {% for assignment_to_consider in assignments_to_consider %} + <div class="row"> + <div class="col-12"> + <div class="card"> + {% include 'submissions/_submission_assignment_request.html' with assignment=assignment_to_consider %} + </div> + </div> + </div> + {% endfor %} +<hr> {% endif %} {% if current_assignments %} -<section> - <div class="flex-container"> - <div class="flex-greybox"> - <h1>Your current assignments:</h1> + <div class="row"> + <div class="col-12"> + <h1 class="highlight">Your current assignments:</h1> + </div> </div> - </div> - <ul> - {% for assignment in current_assignments %} - {{ assignment.submission.header_as_li_for_Fellows }} - <div class="flex-container"> - <div class-"flex-whitebox" style="background-color: #ffaaaa;"> - <h3>Required actions:</h3> - <ul> - {% for todoitem in assignment.submission|required_actions %} - <li>{{ todoitem }}</li> - {% endfor %} - </ul> - </div> + <div class="row"> + <div class="col-12"> + <ul class="list-group list-group-flush"> + {% for assignment in current_assignments %} + <li class="list-group-item"> + {% include 'submissions/_submission_card_fellow_content.html' with submission=assignment.submission %} + <div class="card-block"> + {% with actions=assignment.submission|required_actions %} + <div class="required-actions{% if not actions %} no-actions{% endif %}"> + <h3>{% if actions %}Required actions{% else %}No required actions{% endif %}</h3> + {% if actions %} + <ul> + {% for todoitem in assignment.submission|required_actions %} + <li>{{ todoitem }}</li> + {% endfor %} + </ul> + {% endif %} + </div> + {% endwith %} + <h4 class="d-block mt-2"> + <a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=assignment.submission.arxiv_identifier_w_vn_nr %}">Go to this Submission's Editorial Page</a> + </h4> + </div> + </li> + {% endfor %} + </ul> + </div> </div> - <h4><a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=assignment.submission.arxiv_identifier_w_vn_nr %}"> - Go to this Submission's Editorial Page</a></h4> - {% endfor %} - </ul> -</section> {% else %} -<section> - <p>You currently have no assignments to take care of.</p> -</section> + <div class="row"> + <div class="col-12"> + <p>You currently have no assignments to take care of.</p> + </div> + </div> {% endif %} -{% endblock bodysup %} +{% endblock content %} diff --git a/submissions/templates/submissions/editorial_page.html b/submissions/templates/submissions/editorial_page.html index 989af1cedd256f936cf5fc3059bba6ad5655488e..e05ae5187a5e3654bfc031a68f6cd24ab1e767ea 100644 --- a/submissions/templates/submissions/editorial_page.html +++ b/submissions/templates/submissions/editorial_page.html @@ -2,199 +2,215 @@ {% block pagetitle %}: editorial page for submission{% endblock pagetitle %} -{% block headsup %} - {% load scipost_extras %} {% load submissions_extras %} +{% load bootstrap %} + +{% block content %} + +<div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h1>Editorial Page for Submission</h1> + {% if not submission.is_current %} + <h3 class="text-danger">This is not the editorial page for the current version.</h3> + <p>Please go to the current version's page.</p> + {% endif %} + + <h3>(go to the <a href="{% url 'submissions:submission' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Submissions Page</a> to view Reports and Comments)</h3> + </div> + </div> + </div> +</div> + + +{% if other_versions %} + <div class="row"> + <div class="col-12"> + <h3>Other versions of this Submission exist:</h3> + <div class="pl-4"> + {% for vn in other_versions %} + {% include 'submissions/_submission_version.html' with submission=vn %} + {% endfor %} + </div> + </div> + </div> +{% endif %} + + +<div class="row"> + <div class="col-12"> + <h2>Submission:</h2> + {% include 'submissions/_submission_summary_short.html' with submission=submission %} + </div> +</div> + +<div class="row"> + <div class="col-12"> + {% if submission.author_comments %} + <h3>Author comments upon resubmission</h3> + <p>{{ submission.author_comments|linebreaks }}</p> + {% endif %} + + {% if submission.list_of_changes %} + <h3>List of changes</h3> + <p>{{ submission.list_of_changes|linebreaks }}</p> + {% endif %} + + {% if submission.remarks_for_editors %} + <h3>Comments for the Editor-in-charge</h3> + <p>{{ submission.remarks_for_editors|linebreaks }}</p> + {% endif %} + + {% if submission.referees_suggested %} + <h3>Referees suggested by authors upon submission:</h3> + <p>{{ submission.referees_suggested }}</p> + {% endif %} + + {% if submission.referees_flagged %} + <h3>Referees flagged upon submission (treat reports with caution):</h3> + <p>{{ submission.referees_flagged }}</p> + {% endif %} -{% endblock headsup %} - -{% block bodysup %} - - -<section> - <div class="flex-greybox"> - <h1>Editorial Page for Submission</h1> - {% if not submission.is_current %} - <h3 style="color: red;">This is not the editorial page for the current version.</h3> - <p>Please go to the current version's page.</p> - {% endif %} - <h3>(go to the <a href="{% url 'submissions:submission' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}"> - Submissions Page</a> to view Reports and Comments)</h3> - </div> - - {% if other_versions %} - <h3>Other versions of this Submission exist:</h3> - <ul> - {% for vn in other_versions %} - {{ vn.version_info_as_li }} - {% endfor %} - </ul> - {% endif %} - - <hr class="hr12"> - <div class="row"> - <div class="col-4"> - <h2>Submission:</h2> </div> - </div> - {{ submission.header_as_table }} - - {% if submission.author_comments %} - <h3>Author comments upon resubmission</h3> - <p>{{ submission.author_comments|linebreaks }}</p> - {% endif %} - - {% if submission.list_of_changes %} - <h3>List of changes</h3> - <p>{{ submission.list_of_changes|linebreaks }}</p> - {% endif %} - - {% if submission.remarks_for_editors %} - <h3>Comments for the Editor-in-charge</h3> - <p>{{ submission.remarks_for_editors|linebreaks }}</p> - {% endif %} - - {% if submission.referees_suggested %} - <h3>Referees suggested by authors upon submission:</h3> - <p>{{ submission.referees_suggested }}</p> - {% endif %} - - {% if submission.referees_flagged %} - <h3>Referees flagged upon submission (treat reports with caution):</h3> - <p>{{ submission.referees_flagged }}</p> - {% endif %} -</section> +</div> {% if recommendation %} -<section> - <div class="flex-greybox"> - <h1>Editorial Recommendation</h1> - </div> - {{ recommendation.print_for_authors }} -</section> + <div class="row"> + <div class="col-12"> + <h2 class="highlight">Editorial Recommendation</h2> + {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %} + </div> + </div> {% endif %} -<section> - <div class="flex-greybox"> - <h1>Editorial Workflow</h1> - <a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a> - </div> - <h3>Status:</h3> - {{ submission.status_info_as_table }} - {% if submission|required_actions %} - <div class="flex-container"> - <div class-"flex-whitebox" style="background-color: #ffaaaa;"> - <h3>Required actions:</h3> - <ul> - {% for todoitem in submission|required_actions %} - <li>{{ todoitem }}</li> - {% endfor %} - </ul> +<div class="row"> + <div class="col-12"> + <div class="card card-grey"> + <div class="card-block"> + <h1 class="card-title">Editorial Workflow</h1> + <a href="{% url 'submissions:editorial_workflow' %}">How-to guide: summary of the editorial workflow</a> + </div> + </div> </div> - </div> - {% endif %} - <hr/> - - <h3>Refereeing status summary:</h3> - {{ submission.refereeing_status_as_p }} - - <h4>Detail of refereeing invitations:</h4> - {% if ref_invitations %} - <table class="ref_listing"> - {% for invitation in ref_invitations %} - <tr> - {{ invitation.summary_as_tds }} - {% if not invitation.accepted == False and not invitation.cancelled %} - <td> - {% if invitation.referee %} - <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoR' referee_id=invitation.referee.id %}">Write a communication</a> - {% else %} - (not yet registered) - {% endif %} - </td> - <td> - {% if not invitation.fulfilled %} - <a href="{% url 'submissions:ref_invitation_reminder' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr invitation_id=invitation.id %}">Send reminder email</a> - {% else %} - <strong style="color: green">Report has been delivered</strong> - {% endif %} - </td> - <td> - {% if invitation.nr_reminders > 0 %} - (nr reminders sent: {{ invitation.nr_reminders }}, <br/>last on {{ invitation.date_last_reminded }}) - {% endif %} - </td> - <td> - {% if not invitation.fulfilled %} - <a href="{% url 'submissions:cancel_ref_invitation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr invitation_id=invitation.id %}">Cancel invitation</a> - {% endif %} - </td> - {% else %} - <td></td><td></td><td></td><td></td> - {% endif %} - </tr> - {% endfor %} - </table> - {% else %} - <p>You have not invited any referees yet.</p> - {% endif %} - - <hr class="hr6"/> - <h3>Actions:</h3> - {% if not submission.is_current %} - <h3 style="color: red;">BEWARE: This is not the editorial page for the current version.</h3> - <p>The tools here are thus available only for exceptional circumstances (e.g. vetting a late report on a deprecated version).</p> - <p>Please go to the current version's page using the link at the top.</p> - <br/> - {% endif %} - <ul> - <li><a href="{% url 'submissions:select_referee' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}"> - Select an additional referee</a> (bear in mind flagged referees if any)</li> - <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline|date:'Y-m-d' }}) by - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=2 %}">2 days</a>, - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=7 %}">1 week</a> or - <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=14 %}">2 weeks</a> - {% if submission.reporting_deadline_has_passed %} - <b style="color: red">THE REPORTING DEADLINE HAS PASSED</b> - {% endif %} - </li> - <li> - Set refereeing deadline: - <form action="{% url 'submissions:set_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post"> - {% csrf_token %}{{ set_deadline_form }} - <input type="submit" value="Set deadline"/> - </form> - </li> - <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ nr_reports_to_vet }})</li> - {% if not submission.reporting_deadline_has_passed %} - <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> (deactivates submission of new Reports and Comments)</li> - {% endif %} - <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li> - <li>Communicate with a Referee: see the table above. - </li> - <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li> - <li><a href="{% url 'submissions:eic_recommendation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Formulate an Editorial Recommendation</a> - <p>If you recommend revisions, this will be communicated directly to the Authors, who will be asked to resubmit. - <br/>If you recommend acceptance or rejection, this will be put to the Editorial College for ratification.</p> - </li> - </ul> -</section> - -<section> - <div class="flex-greybox"> - <h1>Communications</h1> - </div> - {% if communications %} - <ul> - {% for comm in communications %} - {{ comm.print_contents_as_li }} - {% endfor %} - </ul> - {% else %} - <p>There have been no communications for this Submission.</p> - {% endif %} -</section> - - -{% endblock bodysup %} +</div> + +<div class="row"> + <div class="col-md-12"> + {% include 'submissions/_submission_status_block.html' with submission=submission %} + </div> +</div> + +<div class="row"> + <div class="col-md-10 col-lg-8"> + <div class="card {% if submission|required_actions %}card-danger text-white{% else %}card-outline-success text-success{% endif %}"> + <div class="card-block"> + <h3 class="card-title pt-0">Required actions:</h3> + <ul class="mb-0"> + {% for todoitem in submission|required_actions %} + <li>{{ todoitem }}</li> + {% empty %} + <li>No actions required</li> + {% endfor %} + </ul> + </div> + </div> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h3>Refereeing status summary:</h3> + {% include 'submissions/_submission_refereeing_status.html' with submission=submission %} + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h3 class="mb-2">Detail of refereeing invitations:</h3> + {% include 'submissions/_submission_refereeing_invitations.html' with submission=submission invitations=ref_invitations %} + </div> +</div> + +<hr> + +{% if not submission.is_current %} +<div class="row"> + <div class="col-12"> + <div class="card card-outline-warning"> + <div class="card-block"> + <h3 class="mb-3 font-weight-bold">BEWARE: This is not the editorial page for the current version!</h3> + <p class="mb-0"> + The tools here are thus available only for exceptional circumstances (e.g. vetting a late report on a deprecated version). + <br>Please go to the current version's page using the link at the top. + </p> + </div> + </div> + </div> +</div> +{% endif %} + +<div class="row"> + <div class="col-12"> + <h3>Actions:</h3> + <ul> + <li> + <a href="{% url 'submissions:select_referee' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Select an additional referee</a> (bear in mind flagged referees if any) + </li> + <li>Extend the refereeing deadline (currently {{ submission.reporting_deadline|date:'Y-m-d' }}) by + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=2 %}">2 days</a>, + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=7 %}">1 week</a> or + <a href="{% url 'submissions:extend_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr days=14 %}">2 weeks</a> + {% if submission.reporting_deadline_has_passed %} + <span class="ml-1 label label-sm label-outline-danger">THE REPORTING DEADLINE HAS PASSED</span> + {% endif %} + </li> + <li> + Set refereeing deadline: + <form class="form-inline" action="{% url 'submissions:set_refereeing_deadline' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}" method="post"> + {% csrf_token %}{{ set_deadline_form|bootstrap_inline:'0,12' }} + <div class="ml-2 form-group row"> + <div class="col-12"> + <input class="btn btn-secondary" type="submit" value="Set deadline"/> + </div> + </div> + </form> + </li> + <li><a href="{% url 'submissions:vet_submitted_reports' %}">Vet submitted Reports</a> ({{ nr_reports_to_vet }})</li> + {% if not submission.reporting_deadline_has_passed %} + <li><a href="{% url 'submissions:close_refereeing_round' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Close the refereeing round</a> (deactivates submission of new Reports and Comments)</li> + {% endif %} + <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoA' %}">Draft and send a communication with the submitting Author</a></li> + <li>Communicate with a Referee: see the table above.</li> + <li><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr comtype='EtoS' %}">Draft and send a communication with SciPost Editorial Administration</a></li> + <li> + <a href="{% url 'submissions:eic_recommendation' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Formulate an Editorial Recommendation</a> + <p>If you recommend revisions, this will be communicated directly to the Authors, who will be asked to resubmit. + <br/>If you recommend acceptance or rejection, this will be put to the Editorial College for ratification.</p> + </li> + </ul> + </div> +</div> + +<div class="row"> + <div class="col-12"> + <h1 class="highlight">Communications</h1> + </div> +</div> + +<div class="row"> + <div class="col-lg-6 offset-lg-3 col-md-8 offset-md-2"> + <ul class="list-group list-group-flush"> + {% for comm in communications %} + <li class="list-group-item"> + {% include 'submissions/_editorial_communication_content.html' with communication=comm %} + </li> + {% empty %} + <li class="list-group-item">There have been no communications for this Submission.</li> + {% endfor %} + </ul> + </div> +</div> + +{% endblock content %} diff --git a/submissions/templates/submissions/eic_recommendation.html b/submissions/templates/submissions/eic_recommendation.html index 135a636cc4ebbf643a53fad4fa01767bec0bb9d8..c692faa02da942295b07e82cbca56b835c89fdda 100644 --- a/submissions/templates/submissions/eic_recommendation.html +++ b/submissions/templates/submissions/eic_recommendation.html @@ -51,7 +51,7 @@ <h2>Submission:</h2> </div> </div> - {{ submission.header_as_table }} + {% include 'submissions/_submission_summary.html' with submission=submission %} <h3>Abstract:</h3> <p>{{ submission.abstract }}</p> diff --git a/submissions/templates/submissions/pool.html b/submissions/templates/submissions/pool.html index b0a5e39d7226ed24706fb783a3480814a559bc27..5cc698d47945e9c2a56e925a49279b00f0b4b18b 100644 --- a/submissions/templates/submissions/pool.html +++ b/submissions/templates/submissions/pool.html @@ -9,28 +9,6 @@ {% block content %} -<script> -$(document).ready(function(){ - - $('#ref_reason').hide(); - - $('#id_accept').on('change', function() { - if ($('#id_accept_1').is(':checked')) { - $('#ref_reason').show(); - } - else { - $('#ref_reason').hide(); - } - }); - - $(".submitRemarkForm").hide(); - - $(".submitRemarkButton").click( function() { - $(this).next("div").toggle(); - }); - }); -</script> - {% if request.user|is_in_group:'Editorial Administrators' and recommendations_undergoing_voting %} <div class="row"> <div class="col-12"> @@ -63,7 +41,6 @@ $(document).ready(function(){ <h3>Editorial recommendation</h3> </div> <div class="card-block"> - {# {{ rec.print_for_Fellows }}#} <div class="card card-outline-secondary"> {% include 'submissions/_recommendation_fellow_content.html' with recommendation=rec %} </div> @@ -145,33 +122,7 @@ $(document).ready(function(){ <div class="row"> <div class="col-12"> <div class="card"> - <div class="card-block"> - {{ assignment_to_consider.submission.header_as_table }} - <br /> - - <h4>Abstract:</h4> - <p>{{ assignment_to_consider.submission.abstract }}</p> - </div> - <div class="card-footer"> - <h1>Accept or Decline this Assignment</h1> - <h3 class="mb-2">By accepting, you will be required to start a refereeing round on the next screen.</h3> - - <form action="{% url 'submissions:accept_or_decline_assignment_ack' assignment_id=assignment_to_consider.id %}" method="post"> - {% csrf_token %} - <div class="form-group row"> - <div class="col-12"> - {{ consider_assignment_form.accept }} - </div> - </div> - <div class="row" id="ref_reason"> - <div class="col-12"> - <p>Please select a reason for declining this assignment</p> - {{ consider_assignment_form.refusal_reason|bootstrap:'0,12' }} - </div> - </div> - <input class="btn btn-secondary" type="submit" value="Submit" /> - </form> - </div> + {% include 'submissions/_submission_assignment_request.html' with assignment=assignment_to_consider %} </div> </div> </div> @@ -202,7 +153,7 @@ $(document).ready(function(){ <h3>Editorial recommendation</h3> </div> <div class="card-block"> - {{ rec.print_for_Fellows }} + {% include 'submissions/_recommendation_fellow_content.html' with recommendation=rec %} </div> <div class="card-footer"> <h3>Actions:</h3> @@ -239,7 +190,7 @@ $(document).ready(function(){ <h3>Editorial recommendation</h3> </div> <div class="card-block"> - {{ rec.print_for_Fellows }} + {% include 'submissions/_recommendation_fellow_content.html' with recommendation=rec %} </div> <div class="card-footer"> <h3>Your position on this recommendation</h3> @@ -281,71 +232,7 @@ $(document).ready(function(){ <!-- Submissions list --> {% for sub in submissions_in_pool %} <div class="card card-outline-secondary mt-1"> - {% include 'submissions/_submission_card_fellow_content.html' with submission=sub %} - - <div class="card-block"> - {% if sub.remark_set.all %} - <h4>Remarks on this submission:</h4> - <ul> - {% for rem in sub.remark_set.all %} - {{ rem.as_li }} - {% endfor %} - </ul> - {% endif %} - <button class="btn btn-secondary mb-2 submitRemarkButton" id="remarkButton{{ submission.id }}">Add a remark on this Submission</button> - <div class="submitRemarkForm pb-2" id="remarkForm{{ submission.id }}"> - <form action="{% url 'submissions:add_remark' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}" method="post"> - {% csrf_token %} - {{ remark_form|bootstrap:'0,12' }} - <input class="btn btn-secondary" type="submit" value="Submit" /> - </form> - </div> - - {% get_obj_perms request.user for sub as "sub_perms" %} - {% if "can_take_editorial_actions" in sub_perms or request.user|is_in_group:'Editorial Administrators' %} - {% if sub|required_actions %} - <div class="required-actions"> - <h3 class="pt-0">Required actions:</h3> - <ul> - {% for todoitem in sub|required_actions %} - <li>{{ todoitem }}</li> - {% endfor %} - </ul> - </div> - {% endif %} - - <h4> - <a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}">Go to this Submission's Editorial Page</a> - </h4> - {% endif %} - - {% if perms.scipost.can_assign_submissions %} - {% if sub.editorialassignment_set.all %} - <h4>EIC Assignment requests:</h4> - <ul> - {% for assignment in sub.editorialassignment_set.all %} - {{ assignment.info_as_li }} - {% endfor %} - </ul> - {% endif %} - {% if sub.editor_in_charge == None %} - <h4>Actions:</h4> - <ul> - <li><a href="{% url 'submissions:assign_submission' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li> - <li><a href="{% url 'submissions:assignment_failed' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li> - </ul> - {% endif %} - {% endif %} - - {% if request.user|is_in_group:'Editorial Administrators' %} - <h4> - <a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a> - </h4> - {% if sub.status == 'accepted' %} - <h4>After proofs have been accepted, you can <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</h4> - {% endif %} - {% endif %} - </div> + {% include 'submissions/_submission_card_in_pool.html' with submission=sub remark_form=remark_form %} </div> {% endfor %} </div> diff --git a/submissions/templates/submissions/prepare_for_voting.html b/submissions/templates/submissions/prepare_for_voting.html index dcd1a2e686a8350d33e18ac302784473f1aad7ca..bb9b8af8999559b01a46ce8fd115e0fd08feb7a5 100644 --- a/submissions/templates/submissions/prepare_for_voting.html +++ b/submissions/templates/submissions/prepare_for_voting.html @@ -34,7 +34,9 @@ <div class="flex-greybox"> <h3>Editorial recommendation:</h3> <ul> - <li>{{ recommendation.print_for_Fellows }}</li> + <li> + {% include 'submissions/_recommendation_fellow_content.html' with recommendation=recommendation %} + </li> </ul> </div> diff --git a/submissions/templates/submissions/submission_detail.html b/submissions/templates/submissions/submission_detail.html index 3e793e6ced6e4fdf739845e90fc5ef1584e0fb95..935acfd7a48ebae50cb4928556263aea5b10f398 100644 --- a/submissions/templates/submissions/submission_detail.html +++ b/submissions/templates/submissions/submission_detail.html @@ -14,12 +14,6 @@ $("#invitedreportsbutton").click(function(){ $("#invitedreportslist").toggle(); }); - $("#contributedreportsbutton").click(function(){ - $("#contributedreportslist").toggle(); - }); - $("#commentsbutton").click(function(){ - $("#commentslist").toggle(); - }); var comment_text_input = $("#id_comment_text"); @@ -44,14 +38,16 @@ <div class="row"> <div class="col-12"> - <div class="panel"> - <h1>SciPost Submission Page</h1> - {% if not submission.is_current %} - <h3 style="color: red;">This is not the current version.</h3> - {% endif %} - {% if user.contributor == submission.editor_in_charge %} - <h3>(You are the Editor-in-charge, go to the <a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Editorial Page</a> to take editorial actions)</h3> - {% endif %} + <div class="card card-grey"> + <div class="card-block"> + <h1>SciPost Submission Page</h1> + {% if not submission.is_current %} + <h3 style="color: red;">This is not the current version.</h3> + {% endif %} + {% if user.contributor == submission.editor_in_charge %} + <h3>(You are the Editor-in-charge, go to the <a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Editorial Page</a> to take editorial actions)</h3> + {% endif %} + </div> </div> </div> </div> @@ -59,26 +55,21 @@ {% if other_versions %} <div class="row"> <div class="col-12"> - <h3>Other versions of this Submission (with Reports) exist:</h3> - <ul> - {% for vn in other_versions %} - {{ vn.version_info_as_li }} - {% endfor %} - </ul> + <h3>Other versions of this Submission (with Reports) exist:</h3> + <div class="pl-4"> + {% for vn in other_versions %} + {% include 'submissions/_submission_version.html' with submission=vn %} + {% endfor %} + </div> </div> </div> {% endif %} <div class="row"> <div class="col-12"> - <hr> - {{ submission.header_as_table }} + {% include 'submissions/_submission_summary.html' with submission=submission %} - <h3 class="mt-3">Abstract:</h3> - <p>{{ submission.abstract }}</p> - - <h3>Status:</h3> - {{ submission.status_info_as_table }} + {% include 'submissions/_submission_status_block.html' with submission=submission %} {% if submission.author_comments %} <h3>Author comments upon resubmission</h3> @@ -93,16 +84,17 @@ </div> {% if is_author or user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' %} -{% if recommendation %} -{% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' or recommendation|is_viewable_by_authors %} -<div class="row"> - <div class="col-12"> - <h2>Editorial Recommendation</h2> - {{ recommendation.print_for_authors }} - </div> -</div> -{% endif %} -{% endif %} + {% if recommendation %} + {% if user|is_in_group:'Editorial College' or user|is_in_group:'Editorial Administrators' or recommendation|is_viewable_by_authors %} + <hr> + <div class="row"> + <div class="col-12"> + <h2>Editorial Recommendation</h2> + {% include 'submissions/_recommendation_author_content.html' with recommendation=recommendation %} + </div> + </div> + {% endif %} + {% endif %} {% endif %} @@ -119,12 +111,17 @@ <ul> {% if submission.open_for_reporting %} {% if perms.scipost.can_referee and not is_author and not is_author_unchecked %} - <li><h3><a href="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Contribute a Report</a></h3> - <div class="reportingDeadline">Deadline for reporting: {{ submission.reporting_deadline|date:"Y-m-d" }}</div></li> + <li> + <h3><a href="{% url 'submissions:submit_report' arxiv_identifier_w_vn_nr=submission.arxiv_identifier_w_vn_nr %}">Contribute a Report</a></h3> + <div class="text-danger">Deadline for reporting: {{ submission.reporting_deadline|date:"Y-m-d" }}</div> + </li> {% elif is_author_unchecked %} - <li><h3>Contribute a Report [deactivated]: the system flagged you as a potential author of this Submission. - Please go to your <a href="{% url 'scipost:personal_page' %}">personal page</a> - under the Submissions tab to clarify this.</h3></li> + <li> + <h3 class="text-blue">Contribute a Report [deactivated]</h3> + <div>The system flagged you as a potential author of this Submission. + Please go to your <a href="{% url 'scipost:personal_page' %}">personal page</a> + under the Submissions tab to clarify this.</div> + </li> {% endif %} {% else %} <li>Reporting for this Submission is closed.</li> @@ -145,81 +142,18 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Invited Reports on this Submission</h2> - <button class="btn btn-secondary" id="invitedreportsbutton">Toggle invited reports view</button> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Invited Reports on this Submission</h2> + <button class="btn btn-secondary" data-toggle="toggle" data-target="#invitedreportslist">Toggle invited reports view</button> + </div> </div> </div> </div> -<div class="row" id="invitedreportslist"> +<div id="invitedreportslist"> {% for report in invited_reports %} - <div class="col-12"> - <div class="report"> - {% if user.contributor == submission.editor_in_charge or user|is_in_group:'Editorial Administrators' and not is_author or user|is_in_group:'Editorial Administrators' and not is_author_unchecked %} - {% if report.flagged %} - <h4 style="color: red">CAUTION: check if this referee has been flagged by the authors</h4> - {% endif %} - {{ report.print_contents_for_editors }} - {% else %} - {{ report.print_identifier }} - {{ report.print_contents }} - {% endif %} - - <hr class="small"> - <h3 class="mb-3"><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3> - - {% for reply in author_replies %} - {% if reply.in_reply_to_report %} - {% if reply.in_reply_to_report.id == report.id %} - <div class="report nested_report"> - <div class="row"> - <div class="col-12"> - {{ reply.print_identifier }} - {{ reply.categories_as_ul }} - <div class="opinionsDisplay"> - {% if user.is_authenticated and perms.scipost.can_express_opinion_on_comments %} - {% if user.contributor != reply.author %} - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='A' %}" method="post"> - {% csrf_token %} - <input type="submit" class="agree" value="Agree {{ reply.nr_A }} "/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='N' %}" method="post"> - {% csrf_token %} - <input type="submit" class="notsure" value="Not sure {{ reply.nr_N }}"/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='D'%}" method="post"> - {% csrf_token %} - <input type="submit" class="disagree" value="Disagree {{ reply.nr_D }}"/> - </form> - {% else %} - {{ reply.opinions_as_ul }} - {% endif %} - {% endif %} - </div> - </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> - {% endif %} - {% endif %} - {% endfor %} - </div> - </div> + {% include 'submissions/_single_public_report.html' with report=report user=request.user perms=perms %} {% endfor %} </div> @@ -229,76 +163,18 @@ <hr> <div class="row"> <div class="col-12"> - <div class="panel"> - <h2>Contributed Reports on this Submission</h2> - <button class="btn btn-secondary" id="contributedreportsbutton">Toggle contributed reports view</button> + <div class="card card-grey"> + <div class="card-block"> + <h2 class="card-title">Contributed Reports on this Submission</h2> + <button class="btn btn-secondary" data-toggle="toggle" data-target="#contributedreportslist">Toggle contributed reports view</button> + </div> </div> </div> </div> -<div class="row" id="contributedreportslist"> +<div id="contributedreportslist"> {% for report in contributed_reports %} - <div class="col-12"> - <div class="report"> - {% if user.contributor == submission.editor_in_charge or user|is_in_group:'Editorial Administrators' and not is_author or user|is_in_group:'Editorial Administrators' and not is_author_unchecked %} - {% if report.flagged %} - <h4 style="color: red">CAUTION: check if this referee has been flagged by the authors</h4> - {% endif %} - {{ report.print_contents_for_editors }} - {% else %} - {{ report.print_identifier }} - {{ report.print_contents }} - {% endif %} - - <hr class="small"> - <h3><a href="{% url 'comments:reply_to_report' report_id=report.id %}">Reply to this Report</a> (authors only)</h3> - - {% for reply in author_replies %} - {% if reply.in_reply_to_report %} - {% if reply.in_reply_to_report.id == report.id %} - <div class="row"> - <div class="col-1"></div> - <hr style="border-style: dotted;" /> - - <div class="flex-container"> - <div class="flex-commentbox"> - {{ reply.print_identifier }} - {{ reply.categories_as_ul }} - <div class="opinionsDisplay"> - {% if user.is_authenticated and perms.scipost.can_express_opinion_on_comments %} - {% if user.contributor != reply.author %} - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='A' %}" method="post"> - {% csrf_token %} - <input type="submit" class="agree" value="Agree {{ reply.nr_A }} "/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='N' %}" method="post"> - {% csrf_token %} - <input type="submit" class="notsure" value="Not sure {{ reply.nr_N }}"/> - </form> - <form action="{% url 'comments:express_opinion' comment_id=reply.id opinion='D'%}" method="post"> - {% csrf_token %} - <input type="submit" class="disagree" value="Disagree {{ reply.nr_D }}"/> - </form> - {% else %} - {{ reply.opinions_as_ul }} - {% endif %} - {% endif %} - </div> - </div> - </div> - </div> - <div class="row"> - <div class="col-1"></div> - <div class="col-10"> - <p>{{ reply.comment_text|linebreaks }}</p> - </div> - </div> - - {% endif %} - {% endif %} - {% endfor %} - </div> - </div> + {% include 'submissions/_single_public_report.html' with report=report user=request.user perms=perms %} {% endfor %} </div> diff --git a/submissions/templates/submissions/submissions.html b/submissions/templates/submissions/submissions.html index 4abd6ffd43c7d5e22b2ce747a91ecfd61cc48bd5..08e868ff3505519edb3c14721c56bb7f83dcd464 100644 --- a/submissions/templates/submissions/submissions.html +++ b/submissions/templates/submissions/submissions.html @@ -40,9 +40,9 @@ </div> </div> +<hr> <div class="row"> <div class="col-12"> - <hr class="hr12"> {% if recent %} <h2>Recent Submissions:</h2> {% elif browse %} @@ -52,16 +52,20 @@ {% endif %} {% if object_list %} {% if is_paginated %} - <p> - {% if page_obj.has_previous %} - <a href="?{% url_replace page=page_obj.previous_page_number %}">Previous</a> - {% endif %} - Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}. - {% if page_obj.has_next %} - <a href="?{% url_replace page=page_obj.next_page_number %}">Next</a> - {% endif %} - </p> + <p> + {% if page_obj.has_previous %} + <a href="?{% url_replace page=page_obj.previous_page_number %}">Previous</a> + {% endif %} + Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}. + {% if page_obj.has_next %} + <a href="?{% url_replace page=page_obj.next_page_number %}">Next</a> + {% endif %} + </p> {% endif %} + + </div> + <div class="col-12"> + <ul class="list-group list-group-flush"> {% for submission in object_list %} <li class="list-group-item"> diff --git a/submissions/templates/submissions/submissions_by_status.html b/submissions/templates/submissions/submissions_by_status.html index 82a4babfa350f766ac8af7373d850a4815e0b7b7..260620dec68e83973eb23b1916aa969299c4545c 100644 --- a/submissions/templates/submissions/submissions_by_status.html +++ b/submissions/templates/submissions/submissions_by_status.html @@ -1,98 +1,28 @@ {% extends 'scipost/base.html' %} -{% block pagetitle %}: Submissions by status{% endblock pagetitle %} - -{% block bodysup %} - -<script> -$(document).ready(function(){ - - $('#ref_reason').hide(); - - $('#id_accept').on('change', function() { - if ($('#id_accept_1').is(':checked')) { - $('#ref_reason').show(); - } - else { - $('#ref_reason').hide(); - } - }); - - $(".submitRemarkForm").hide(); - - $(".submitRemarkButton").click( function() { - $(this).next("div").toggle(); - }); - }); - -</script> - {% load guardian_tags %} {% load scipost_extras %} {% load submissions_extras %} +{% block pagetitle %}: Submissions by status{% endblock pagetitle %} + +{% block content %} -<section> - <div class="flex-container"> - <div class="flex-greybox"> - <h1>SciPost Submissions with status {{ status }}</h1> +<div class="row"> + <div class="col-12"> + <h1 class="highlight">SciPost Submissions with status {{ submissions_of_status.first.get_status_display }}</h1> </div> - </div> - - <ul> - {% for sub in submissions_of_status %} - {% if request.user|is_not_author_of_submission:sub.arxiv_identifier_w_vn_nr %} - <br/> - {{ sub.header_as_li_for_Fellows }} - {% if sub.remark_set.all %} - <h4>Remarks on this submission:</h4> - <ul> - {% for rem in sub.remark_set.all %} - {{ rem.as_li }} - {% endfor %} - </ul> - {% endif %} - <button class="submitRemarkButton" id="remarkButton{{ submission.id }}">Add a remark on this Submission</button> - <div class="submitRemarkForm" id="remarkForm{{ submission.id }}"> - <form action="{% url 'submissions:add_remark' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}" method="post"> - {% csrf_token %} - {{ remark_form.as_p }} - <input type="submit" value="Submit" /> - </form> +</div> + +<div class="row"> + <div class="col-12"> + <!-- Submissions list --> + {% for sub in submissions_of_status %} + <div class="card card-outline-secondary mt-1"> + {% include 'submissions/_submission_card_in_pool.html' with submission=sub remark_form=remark_form %} + </div> + {% endfor %} </div> - {% get_obj_perms request.user for sub as "sub_perms" %} - {% if "can_take_editorial_actions" in sub_perms or request.user|is_in_group:'Editorial Administrators' %} - <h4><a href="{% url 'submissions:editorial_page' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}"> - Go to this Submission's Editorial Page</a></h4> - {% endif %} - {% if perms.scipost.can_assign_submissions %} - {% if sub.editorialassignment_set.all %} - <h4>EIC Assignment requests:</h4> - <ul> - {% for assignment in sub.editorialassignment_set.all %} - {{ assignment.info_as_li }} - {% endfor %} - </ul> - {% endif %} - {% if sub.editor_in_charge == None %} - <h4>Actions:</h4> - <ul> - <li><a href="{% url 'submissions:assign_submission' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}">Send a new assignment request</a></li> - <li><a href="{% url 'submissions:assignment_failed' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr %}">Close pre-screening: failure to find EIC</a></li> - </ul> - {% endif %} - {% endif %} - {% if request.user|is_in_group:'Editorial Administrators' %} - <h4><a href="{% url 'submissions:communication' arxiv_identifier_w_vn_nr=sub.arxiv_identifier_w_vn_nr comtype='StoE' %}">Send a communication to the Editor-in-charge</a></h4> - {% if sub.status == 'accepted' %} - <h4>After proofs have been accepted, you can - <a href="{% url 'journals:initiate_publication' %}">initiate the publication process</a> (leads to the validation page)</h4> - {% endif %} - {% endif %} - {% endif %} - {% endfor %} - </ul> - -</section> +</div> -{% endblock bodysup %} +{% endblock content %} diff --git a/submissions/templates/submissions/submit_report.html b/submissions/templates/submissions/submit_report.html index fad83a5aa691770c3437a6f8df26caa3da55b786..d47385506a57446fc570f74ab22a4b0eca855a8d 100644 --- a/submissions/templates/submissions/submit_report.html +++ b/submissions/templates/submissions/submit_report.html @@ -65,10 +65,8 @@ <div class="flex-greybox"> <h2>Submission summary and link</h2> </div> - {{ submission.header_as_table }} - <br /> - <h3>Abstract:</h3> - <p>{{ submission.abstract }}</p> + {% include 'submissions/_submission_summary.html' with submission=submission %} + </section> diff --git a/submissions/templates/submissions/vet_submitted_reports.html b/submissions/templates/submissions/vet_submitted_reports.html index d88bdeae77764c5e05b341a0f7ddc2865cdaa999..d545a3b09ebd6488f70b8ce3632a806e9b6c2c98 100644 --- a/submissions/templates/submissions/vet_submitted_reports.html +++ b/submissions/templates/submissions/vet_submitted_reports.html @@ -2,6 +2,8 @@ {% block pagetitle %}: vet reports{% endblock pagetitle %} +{% load bootstrap %} + {% block headsup %} <script> @@ -9,7 +11,7 @@ $(document).ready(function(){ $('#refusal').hide(); - $('#id_action_option').on('change', function() { + $('[name="action_option"]').on('change', function() { if ($('#id_action_option_1').is(':checked')) { $('#refusal').show(); } @@ -22,46 +24,40 @@ $(document).ready(function(){ {% endblock headsup %} -{% block bodysup %} - -<section> - {% if not report_to_vet %} - <h1>There are no Reports for you to vet.</h1> - - {% else %} - - <h1>SciPost Report to vet:</h1> - - <br> - <hr> - <h3>Submission associated to Report:</h3> - {{ report_to_vet.submission.header_as_table }} - <br /> - <h4>Abstract:</h4> - <p>{{ report_to_vet.submission.abstract }}</p> - <hr style="border-style: dotted;" /> - <div class="flex-greybox"> - <h3>Report to vet:</h3> - </div> - {{ report_to_vet.print_contents_for_editors|linebreaks }} - - <hr class="hr6"/> - <div class="flex-greaybox"> - <h2>Please vet this Report:</h2> - </div> - <form action="{% url 'submissions:vet_submitted_report_ack' report_id=report_to_vet.id %}" method="post"> - {% csrf_token %} - {{ form.action_option }} - <div id="refusal"> - <ul> - <li>Refusal reason: {{ form.refusal_reason }}</li> - <li>{{ form.email_response_field }}</li> - </ul> +{% block content %} + +<div class="row"> + <div class="col-12"> + {% if not report_to_vet %} + <h1>There are no Reports for you to vet.</h1> + {% else %} + <h1 class="highlight">SciPost Report to vet:</h1> + + <h2 class="mb-2">Submission associated to Report:</h2> + <div class="row"> + <div class="col-12"> + {% include 'submissions/_submission_summary_short.html' with submission=report_to_vet.submission %} + </div> + </div> + + <h2 class="mb-2">Report to vet:</h2> + + {% include 'submissions/_single_public_report_without_comments.html' with report=report_to_vet %} + + <hr class="small"> + <h2>Please vet this Report:</h2> + <form action="{% url 'submissions:vet_submitted_report_ack' report_id=report_to_vet.id %}" method="post"> + {% csrf_token %} + {{ form.action_option|bootstrap }} + <div class="col-md-6" id="refusal"> + {{ form.refusal_reason|bootstrap }} + {{ form.email_response_field|bootstrap }} + </div> + <input class="btn btn-secondary" type="submit" value="Submit" /> + </form> + + {% endif %} </div> - <input type="submit" value="Submit" /> - </form> - - {% endif %} -</section> +</div> -{% endblock bodysup %} +{% endblock content %} diff --git a/submissions/templatetags/submissions_extras.py b/submissions/templatetags/submissions_extras.py index b2b785c0357b7be546be77fe2a3eb0d1761022da..2da991f6d3ce3c33c022055bee26bbbbc5d7c597 100644 --- a/submissions/templatetags/submissions_extras.py +++ b/submissions/templatetags/submissions_extras.py @@ -2,14 +2,13 @@ import datetime from django import template from django.utils import timezone -from django.utils.timesince import timesince -from urllib.parse import urlencode -from submissions.models import SUBMISSION_STATUS_OUT_OF_POOL +from submissions.constants import SUBMISSION_STATUS_OUT_OF_POOL from submissions.models import Submission register = template.Library() + @register.filter(name='is_not_author_of_submission') def is_not_author_of_submission(user, arxiv_identifier_w_vn_nr): submission = Submission.objects.get(arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) @@ -17,7 +16,7 @@ def is_not_author_of_submission(user, arxiv_identifier_w_vn_nr): and (user.last_name not in submission.author_list or - user.contributor in submission.authors_false_claims.all() ) ) + user.contributor in submission.authors_false_claims.all())) @register.filter(name='is_viewable_by_authors') @@ -26,6 +25,7 @@ def is_viewable_by_authors(recommendation): 'accepted', 'rejected', 'published', 'withdrawn'] + @register.filter(name='required_actions') def required_actions(submission): """ diff --git a/submissions/utils.py b/submissions/utils.py index 18fcb7e14d6c46f5df576fe95e17cbb281ea959c..5687a3f35f856a97fd4429324ce60d02b70c879e 100644 --- a/submissions/utils.py +++ b/submissions/utils.py @@ -3,13 +3,9 @@ import datetime from django.core.mail import EmailMessage, EmailMultiAlternatives from django.template import Context, Template -from journals.models import journals_submit_dict -from scipost.models import title_dict from scipost.utils import EMAIL_FOOTER from submissions.models import EditorialAssignment -from submissions.models import assignment_refusal_reasons_dict, ed_comm_choices_dict -from submissions.forms import report_refusal_choices_dict class SubmissionUtils(object): @@ -46,7 +42,7 @@ class SubmissionUtils(object): @classmethod def send_authors_submission_ack_email(cls): """ Requires loading 'submission' attribute. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nWe have received your Submission to SciPost,\n\n' + cls.submission.title + ' by ' + cls.submission.author_list + '.' + @@ -68,7 +64,7 @@ class SubmissionUtils(object): '<p>With many thanks,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.submission.submitted_by.title], + 'title': cls.submission.submitted_by.get_title_display(), 'last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -88,7 +84,7 @@ class SubmissionUtils(object): @classmethod def send_authors_resubmission_ack_email(cls): """ Requires loading 'submission' attribute. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nWe have received your Resubmission to SciPost,\n\n' + cls.submission.title + ' by ' + cls.submission.author_list + '.' + @@ -107,7 +103,7 @@ class SubmissionUtils(object): '<p>With many thanks,</p>' '<p>The SciPost Team</p>') email_context = Context({ - 'title': title_dict[cls.submission.submitted_by.title], + 'title': cls.submission.submitted_by.get_title_display(), 'last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -127,7 +123,7 @@ class SubmissionUtils(object): @classmethod def send_assignment_request_email(cls): """ Requires loading 'assignment' attribute. """ - email_text = ('Dear ' + title_dict[cls.assignment.to.title] + ' ' + + email_text = ('Dear ' + cls.assignment.to.get_title_display() + ' ' + cls.assignment.to.user.last_name + ', \n\nWe have received a Submission to SciPost ' + 'for which we would like you to consider becoming Editor-in-charge:\n\n' + @@ -160,7 +156,7 @@ class SubmissionUtils(object): '\n<p>Many thanks in advance for your collaboration,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.assignment.to.title], + 'title': cls.assignment.to.get_title_display(), 'last_name': cls.assignment.to.user.last_name, 'sub_title': cls.assignment.submission.title, 'author_list': cls.assignment.submission.author_list, @@ -180,7 +176,7 @@ class SubmissionUtils(object): @classmethod def send_EIC_appointment_email(cls): """ Requires loading 'assignment' attribute. """ - email_text = ('Dear ' + title_dict[cls.assignment.to.title] + ' ' + email_text = ('Dear ' + cls.assignment.to.get_title_display() + ' ' + cls.assignment.to.user.last_name + ', \n\nThank you for accepting to become Editor-in-charge ' 'of the SciPost Submission\n\n' @@ -216,7 +212,7 @@ class SubmissionUtils(object): '<p>Many thanks in advance for your collaboration,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.assignment.to.title], + 'title': cls.assignment.to.get_title_display(), 'last_name': cls.assignment.to.user.last_name, 'sub_title': cls.assignment.submission.title, 'author_list': cls.assignment.submission.author_list, @@ -237,7 +233,7 @@ class SubmissionUtils(object): @classmethod def send_EIC_reappointment_email(cls): """ Requires loading 'submission' attribute. """ - email_text = ('Dear ' + title_dict[cls.submission.editor_in_charge.title] + ' ' + email_text = ('Dear ' + cls.submission.editor_in_charge.get_title_display() + ' ' + cls.submission.editor_in_charge.user.last_name + ', \n\nThe authors of the SciPost Submission\n\n' + cls.submission.title + ' by ' @@ -278,7 +274,7 @@ class SubmissionUtils(object): '<p>Many thanks in advance for your collaboration,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.submission.editor_in_charge.title], + 'title': cls.submission.editor_in_charge.get_title_display(), 'last_name': cls.submission.editor_in_charge.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -299,7 +295,7 @@ class SubmissionUtils(object): @classmethod def send_author_prescreening_passed_email(cls): """ Requires loading 'assignment' attribute. """ - email_text = ('Dear ' + title_dict[cls.assignment.submission.submitted_by.title] + ' ' + email_text = ('Dear ' + cls.assignment.submission.submitted_by.get_title_display() + ' ' + cls.assignment.submission.submitted_by.user.last_name + ', \n\nWe are pleased to inform you that your recent Submission to SciPost,\n\n' + cls.assignment.submission.title + ' by ' + cls.assignment.submission.author_list @@ -354,7 +350,7 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.assignment.submission.submitted_by.title], + 'title': cls.assignment.submission.submitted_by.get_title_display(), 'last_name': cls.assignment.submission.submitted_by.user.last_name, 'sub_title': cls.assignment.submission.title, 'author_list': cls.assignment.submission.author_list, @@ -377,7 +373,7 @@ class SubmissionUtils(object): @classmethod def assignment_failed_email_authors(cls): """ Requires loading 'submission' attribute. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nYou recent Submission to SciPost,\n\n' + cls.submission.title + ' by ' + cls.submission.author_list @@ -406,7 +402,7 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.submission.submitted_by.title], + 'title': cls.submission.submitted_by.get_title_display(), 'last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -433,11 +429,11 @@ class SubmissionUtils(object): instead, which calls the send_registration_email method in scipost/utils. Requires loading 'invitation' attribute. """ - email_text = ('Dear ' + title_dict[cls.invitation.referee.title] + ' ' + + email_text = ('Dear ' + cls.invitation.referee.get_title_display() + ' ' + cls.invitation.referee.user.last_name + ', \n\nWe have received a Submission to SciPost ' 'which, in view of your expertise and on behalf of the Editor-in-charge ' - + title_dict[cls.invitation.submission.editor_in_charge.title] + ' ' + + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + cls.invitation.submission.editor_in_charge.user.last_name + ', we would like to invite you to referee:\n\n' + cls.invitation.submission.title + ' by ' + cls.invitation.submission.author_list @@ -486,9 +482,9 @@ class SubmissionUtils(object): 'and thank you in advance for your consideration.</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'title': title_dict[cls.invitation.referee.title], + 'title': cls.invitation.referee.get_title_display(), 'last_name': cls.invitation.referee.user.last_name, - 'EIC_title': title_dict[cls.invitation.submission.editor_in_charge.title], + 'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(), 'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name, 'sub_title': cls.invitation.submission.title, 'author_list': cls.invitation.submission.author_list, @@ -515,10 +511,10 @@ class SubmissionUtils(object): This method is used to remind a referee who is not registered as a Contributor. It is called from the ref_invitation_reminder method in submissions/views.py. """ - email_text = ('Dear ' + title_dict[cls.invitation.title] + ' ' + email_text = ('Dear ' + cls.invitation.get_title_display() + ' ' + cls.invitation.last_name + ',\n\n' 'On behalf of the Editor-in-charge ' - + title_dict[cls.invitation.submission.editor_in_charge.title] + ' ' + + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + cls.invitation.submission.editor_in_charge.user.last_name + ', we would like to cordially remind you of our recent request to referee\n\n' + cls.invitation.submission.title + ' by ' @@ -584,9 +580,9 @@ class SubmissionUtils(object): '<p>Many thanks in advance,</p>' '<p>The SciPost Team</p>') email_context = Context({ - 'title': title_dict[cls.invitation.title], + 'title': cls.invitation.get_title_display(), 'last_name': cls.invitation.last_name, - 'EIC_title': title_dict[cls.invitation.submission.editor_in_charge.title], + 'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(), 'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name, 'sub_title': cls.invitation.submission.title, 'author_list': cls.invitation.submission.author_list, @@ -614,10 +610,10 @@ class SubmissionUtils(object): This method is used to inform a referee that his/her services are no longer required. It is called from the cancel_ref_invitation method in submissions/views.py. """ - email_text = ('Dear ' + title_dict[cls.invitation.title] + ' ' + email_text = ('Dear ' + cls.invitation.get_title_display() + ' ' + cls.invitation.last_name + ',\n\n' 'On behalf of the Editor-in-charge ' - + title_dict[cls.invitation.submission.editor_in_charge.title] + ' ' + + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + cls.invitation.submission.editor_in_charge.user.last_name + ', we would like to inform you that your report on\n\n' + cls.invitation.submission.title + ' by ' @@ -655,9 +651,9 @@ class SubmissionUtils(object): 'after which your registration will be activated, giving you full access to ' 'the portal\'s facilities (in particular allowing you to provide referee reports).</p>') email_context = Context({ - 'title': title_dict[cls.invitation.title], + 'title': cls.invitation.get_title_display(), 'last_name': cls.invitation.last_name, - 'EIC_title': title_dict[cls.invitation.submission.editor_in_charge.title], + 'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(), 'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name, 'sub_title': cls.invitation.submission.title, 'author_list': cls.invitation.submission.author_list, @@ -679,9 +675,9 @@ class SubmissionUtils(object): @classmethod def email_referee_response_to_EIC(cls): """ Requires loading 'invitation' attribute. """ - email_text = ('Dear ' + title_dict[cls.invitation.submission.editor_in_charge.title] + ' ' + + email_text = ('Dear ' + cls.invitation.submission.editor_in_charge.get_title_display() + ' ' + cls.invitation.submission.editor_in_charge.user.last_name + ',' - '\n\nReferee ' + title_dict[cls.invitation.referee.title] + ' ' + + '\n\nReferee ' + cls.invitation.referee.get_title_display() + ' ' + cls.invitation.referee.user.last_name + ' has ') email_text_html = ( '<p>Dear {{ EIC_title }} {{ EIC_last_name }},</p>' @@ -693,7 +689,7 @@ class SubmissionUtils(object): email_subject = 'SciPost: referee accepts to review' elif not cls.invitation.accepted: email_text += ('declined (due to reason: ' - + assignment_refusal_reasons_dict[cls.invitation.refusal_reason] + ') ') + + cls.invitation.get_refusal_reason_display() + ') ') email_text_html += 'declined (due to reason: {{ reason }}) ' email_text += ('to referee Submission\n\n' @@ -715,16 +711,16 @@ class SubmissionUtils(object): email_text_html += ('<p>Many thanks for your collaboration,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'EIC_title': title_dict[cls.invitation.submission.editor_in_charge.title], + 'EIC_title': cls.invitation.submission.editor_in_charge.get_title_display(), 'EIC_last_name': cls.invitation.submission.editor_in_charge.user.last_name, - 'ref_title': title_dict[cls.invitation.referee.title], + 'ref_title': cls.invitation.referee.get_title_display(), 'ref_last_name': cls.invitation.referee.user.last_name, 'sub_title': cls.invitation.submission.title, 'author_list': cls.invitation.submission.author_list, 'arxiv_identifier_w_vn_nr': cls.invitation.submission.arxiv_identifier_w_vn_nr, }) if cls.invitation.refusal_reason: - email_context['reason'] = assignment_refusal_reasons_dict[cls.invitation.refusal_reason] + email_context['reason'] = cls.invitation.get_refusal_reason_display email_text_html += '<br/>' + EMAIL_FOOTER html_template = Template(email_text_html) html_version = html_template.render(email_context) @@ -740,9 +736,9 @@ class SubmissionUtils(object): @classmethod def email_EIC_report_delivered(cls): """ Requires loading 'report' attribute. """ - email_text = ('Dear ' + title_dict[cls.report.submission.editor_in_charge.title] + ' ' + email_text = ('Dear ' + cls.report.submission.editor_in_charge.get_title_display() + ' ' + cls.report.submission.editor_in_charge.user.last_name + ',' - '\n\nReferee ' + title_dict[cls.report.author.title] + ' ' + '\n\nReferee ' + cls.report.author.get_title_display() + ' ' + cls.report.author.user.last_name + ' has delivered a Report for Submission\n\n' + cls.report.submission.title + ' by ' @@ -762,9 +758,9 @@ class SubmissionUtils(object): '<p>Many thanks for your collaboration,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'EIC_title': title_dict[cls.report.submission.editor_in_charge.title], + 'EIC_title': cls.report.submission.editor_in_charge.get_title_display(), 'EIC_last_name': cls.report.submission.editor_in_charge.user.last_name, - 'ref_title': title_dict[cls.report.author.title], + 'ref_title': cls.report.author.get_title_display(), 'ref_last_name': cls.report.author.user.last_name, 'sub_title': cls.report.submission.title, 'author_list': cls.report.submission.author_list, @@ -784,7 +780,7 @@ class SubmissionUtils(object): @classmethod def acknowledge_report_email(cls): """ Requires loading 'report' attribute. """ - email_text = ('Dear ' + title_dict[cls.report.author.title] + ' ' + + email_text = ('Dear ' + cls.report.author.get_title_display() + ' ' + cls.report.author.user.last_name + ',' '\n\nMany thanks for your Report on Submission\n\n' + cls.report.submission.title + ' by ' @@ -804,7 +800,7 @@ class SubmissionUtils(object): else: email_text += ('\n\nYour Report has been reviewed by the Editor-in-charge of the Submission, ' 'who decided not to admit it for online posting, citing the reason: ' - + report_refusal_choices_dict[int(cls.report.status)] + '.' + + cls.report.get_status_display() + '.' ' We copy the text entries of your report below for your convenience, ' 'if ever you wish to reformulate it and resubmit it.') email_text_html += ( @@ -837,7 +833,7 @@ class SubmissionUtils(object): '\n<strong>Requested changes</strong>: <br/><p>{{ requested_changes|linebreaks }}</p>' '\n<strong>Remarks for Editors</strong>: <br/><p>{{ remarks_for_editors|linebreaks }}</p>') email_context = Context({ - 'ref_title': title_dict[cls.report.author.title], + 'ref_title': cls.report.author.get_title_display(), 'ref_last_name': cls.report.author.user.last_name, 'sub_title': cls.report.submission.title, 'author_list': cls.report.submission.author_list, @@ -849,7 +845,7 @@ class SubmissionUtils(object): 'remarks_for_editors': cls.report.remarks_for_editors, }) if cls.report.status < 0: - email_context['refusal_reason'] = report_refusal_choices_dict[int(cls.report.status)] + email_context['refusal_reason'] = cls.report.get_status_display() email_text_html += '<br/>' + EMAIL_FOOTER html_template = Template(email_text_html) html_version = html_template.render(email_context) @@ -866,7 +862,7 @@ class SubmissionUtils(object): @classmethod def send_author_report_received_email(cls): """ Requires loading 'report' attribute. """ - email_text = ('Dear ' + title_dict[cls.report.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.report.submission.submitted_by.get_title_display() + ' ' + cls.report.submission.submitted_by.user.last_name + ', \n\nA Report has been posted on your recent Submission to SciPost,\n\n' + cls.report.submission.title + ' by ' + cls.report.submission.author_list + '.' @@ -897,7 +893,7 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'auth_title': title_dict[cls.report.submission.submitted_by.title], + 'auth_title': cls.report.submission.submitted_by.get_title_display(), 'auth_last_name': cls.report.submission.submitted_by.user.last_name, 'sub_title': cls.report.submission.title, 'author_list': cls.report.submission.author_list, @@ -918,7 +914,7 @@ class SubmissionUtils(object): @classmethod def send_author_comment_received_email(cls): """ Requires loading 'submission' attribute. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nA Comment has been posted on your recent Submission to SciPost,\n\n' + cls.submission.title + ' by ' + cls.submission.author_list + '.' @@ -939,7 +935,7 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'auth_title': title_dict[cls.submission.submitted_by.title], + 'auth_title': cls.submission.submitted_by.get_title_display(), 'auth_last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -971,7 +967,7 @@ class SubmissionUtils(object): if cls.communication.comtype in ['AtoE', 'RtoE', 'StoE']: recipient_email.append(cls.communication.submission.editor_in_charge.user.email) recipient_greeting = ('Dear ' + - title_dict[cls.communication.submission.editor_in_charge.title] + ' ' + + cls.communication.submission.editor_in_charge.get_title_display() + ' ' + cls.communication.submission.editor_in_charge.user.last_name) further_action_page = ('https://scipost.org/submission/editorial_page/' + cls.communication.submission.arxiv_identifier_w_vn_nr) @@ -981,14 +977,14 @@ class SubmissionUtils(object): elif cls.communication.comtype in ['EtoA']: recipient_email.append(cls.communication.submission.submitted_by.user.email) recipient_greeting = ('Dear ' + - title_dict[cls.communication.submission.submitted_by.title] + ' ' + + cls.communication.submission.submitted_by.get_title_display() + ' ' + cls.communication.submission.submitted_by.user.last_name) bcc_emails.append(cls.communication.submission.editor_in_charge) bcc_emails.append('submissions@scipost.org') elif cls.communication.comtype in ['EtoR']: recipient_email.append(cls.communication.referee.user.email) recipient_greeting = ('Dear ' + - title_dict[cls.communication.referee.title] + ' ' + + cls.communication.referee.get_title_display() + ' ' + cls.communication.referee.user.last_name) bcc_emails.append(cls.communication.submission.editor_in_charge) bcc_emails.append('submissions@scipost.org') @@ -1000,7 +996,7 @@ class SubmissionUtils(object): email_text = (recipient_greeting + ', \n\nPlease find here a communication (' + - ed_comm_choices_dict[cls.communication.comtype] + ') ' + cls.communication.get_comtype_display() + ') ' 'concerning Submission\n\n' + cls.communication.submission.title + ' by ' + cls.communication.submission.author_list + '.' @@ -1012,7 +1008,7 @@ class SubmissionUtils(object): '\n\nSincerely,' + '\n\nThe SciPost Team.') emailmessage = EmailMessage( - 'SciPost: communication (' + ed_comm_choices_dict[cls.communication.comtype] + ')', + 'SciPost: communication (' + cls.communication.get_comtype_display() + ')', email_text, 'SciPost Editorial Admin <submissions@scipost.org>', recipient_email, @@ -1023,7 +1019,7 @@ class SubmissionUtils(object): @classmethod def send_author_revision_requested_email(cls): """ Requires loading 'submission' and 'recommendation' attributes. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nThe Editor-in-charge of your recent Submission to SciPost,\n\n' + cls.submission.title + ' by ' + cls.submission.author_list + ',' @@ -1070,7 +1066,7 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'auth_title': title_dict[cls.submission.submitted_by.title], + 'auth_title': cls.submission.submitted_by.get_title_display(), 'auth_last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, @@ -1092,7 +1088,7 @@ class SubmissionUtils(object): @classmethod def send_author_College_decision_email(cls): """ Requires loading 'submission' and 'recommendation' attributes. """ - email_text = ('Dear ' + title_dict[cls.submission.submitted_by.title] + ' ' + + email_text = ('Dear ' + cls.submission.submitted_by.get_title_display() + ' ' + cls.submission.submitted_by.user.last_name + ', \n\nThe Editorial College of SciPost has taken a decision ' 'regarding your recent Submission,\n\n' + @@ -1107,7 +1103,7 @@ class SubmissionUtils(object): or cls.recommendation.recommendation == 3): email_text += ('We are pleased to inform you that your Submission ' 'has been accepted for publication in ' - + journals_submit_dict[cls.submission.submitted_to_journal]) + + cls.submission.get_submitted_to_journal_display()) email_text_html += ( '<p>We are pleased to inform you that your Submission ' 'has been accepted for publication in <strong>{{ journal }}</strong>') @@ -1159,12 +1155,12 @@ class SubmissionUtils(object): '<p>Sincerely,</p>' '<p>The SciPost Team.</p>') email_context = Context({ - 'auth_title': title_dict[cls.submission.submitted_by.title], + 'auth_title': cls.submission.submitted_by.get_title_display(), 'auth_last_name': cls.submission.submitted_by.user.last_name, 'sub_title': cls.submission.title, 'author_list': cls.submission.author_list, 'arxiv_identifier_w_vn_nr': cls.submission.arxiv_identifier_w_vn_nr, - 'journal': journals_submit_dict[cls.submission.submitted_to_journal], + 'journal': cls.submission.get_submitted_to_journal_display(), }) email_text_html += '<br/>' + EMAIL_FOOTER html_template = Template(email_text_html) diff --git a/submissions/views.py b/submissions/views.py index 93e008ea3a86bbeff4ce7cc9d51a55cefbfc2c99..c0fc5b703691ef0174d41d696a6dd48258efe2fa 100644 --- a/submissions/views.py +++ b/submissions/views.py @@ -10,17 +10,15 @@ from django.http import HttpResponseRedirect 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 LoginRequiredMixin, PermissionRequiredMixin +from guardian.mixins import PermissionRequiredMixin from guardian.shortcuts import assign_perm +from .constants import SUBMISSION_STATUS_PUBLICLY_UNLISTED, SUBMISSION_STATUS_VOTING_DEPRECATED,\ + SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS, ED_COMM_CHOICES from .models import Submission, EICRecommendation, EditorialAssignment,\ - RefereeInvitation, Report, EditorialCommunication,\ - SUBMISSION_STATUS_PUBLICLY_UNLISTED, SUBMISSION_STATUS_VOTING_DEPRECATED,\ - SUBMISSION_STATUS_PUBLICLY_INVISIBLE, SUBMISSION_STATUS_OUT_OF_POOL,\ - SUBMISSION_STATUS, submission_status_dict, ed_comm_choices_dict + RefereeInvitation, Report, EditorialCommunication from .forms import SubmissionIdentifierForm, SubmissionForm, SubmissionSearchForm,\ RecommendationVoteForm, ConsiderAssignmentForm, AssignSubmissionForm,\ SetRefereeingDeadlineForm, RefereeSelectForm, RefereeRecruitmentForm,\ @@ -29,9 +27,8 @@ from .forms import SubmissionIdentifierForm, SubmissionForm, SubmissionSearchFor from .utils import SubmissionUtils from comments.models import Comment -from journals.models import journals_submit_dict from scipost.forms import ModifyPersonalMessageForm, RemarkForm -from scipost.models import Contributor, title_dict, Remark, RegistrationInvitation +from scipost.models import Contributor, Remark, RegistrationInvitation from scipost.services import ArxivCaller from scipost.utils import Utils @@ -381,13 +378,15 @@ def pool(request): @login_required @permission_required('scipost.can_view_pool', raise_exception=True) def submissions_by_status(request, status): - if status not in submission_status_dict.keys(): + if status not in dict(SUBMISSION_STATUS).keys(): errormessage = 'Unknown status.' return render(request, 'scipost/error.html', {'errormessage': errormessage}) - submissions_of_status = Submission.objects.filter( - status=status).order_by('-submission_date') - context = {'status': submission_status_dict[status], - 'submissions_of_status': submissions_of_status, } + submissions_of_status = (Submission.objects.get_pool(request.user) + .filter(status=status).order_by('-submission_date')) + context = { + 'submissions_of_status': submissions_of_status, + 'remark_form': RemarkForm() + } return render(request, 'submissions/submissions_by_status.html', context) @@ -468,7 +467,7 @@ def accept_or_decline_assignment_ack(request, assignment_id): context = {'errormessage': errormessage} return render(request, 'submissions/accept_or_decline_assignment_ack.html', context) if assignment.submission.editor_in_charge: - errormessage = (title_dict[assignment.submission.editor_in_charge.title] + ' ' + + errormessage = (assignment.submission.editor_in_charge.get_title_display() + ' ' + assignment.submission.editor_in_charge.user.last_name + ' has already agreed to be Editor-in-charge of this Submission.') context = {'errormessage': errormessage} @@ -523,7 +522,7 @@ def volunteer_as_EIC(request, arxiv_identifier_w_vn_nr): context = {'errormessage': errormessage} return render(request, 'submissions/accept_or_decline_assignment_ack.html', context) if submission.editor_in_charge: - errormessage = (title_dict[submission.editor_in_charge.title] + ' ' + + errormessage = (submission.editor_in_charge.get_title_display() + ' ' + submission.editor_in_charge.user.last_name + ' has already agreed to be Editor-in-charge of this Submission.') context = {'errormessage': errormessage} @@ -708,10 +707,10 @@ def recruit_referee(request, arxiv_identifier_w_vn_nr): ref_invitation.save() # Create and send a registration invitation ref_inv_message_head = ('On behalf of the Editor-in-charge ' + - title_dict[submission.editor_in_charge.title] + ' ' + + submission.editor_in_charge.get_title_display() + ' ' + submission.editor_in_charge.user.last_name + ', we would like to invite you to referee a Submission to ' + - journals_submit_dict[submission.submitted_to_journal] + + submission.get_submitted_to_journal_display + ', namely\n\n' + submission.title + '\nby ' + submission.author_list + '\n (see https://scipost.org/submission/' @@ -915,7 +914,7 @@ def communication(request, arxiv_identifier_w_vn_nr, comtype, referee_id=None): """ submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) errormessage = None - if comtype not in ed_comm_choices_dict.keys(): + if comtype not in dict(ED_COMM_CHOICES).keys(): errormessage = 'Unknown type of cummunication.' # TODO: Verify that this is requested by an authorized contributor (eic, ref, author) elif (comtype in ['EtoA', 'EtoR', 'EtoS'] and @@ -969,7 +968,7 @@ def eic_recommendation(request, arxiv_identifier_w_vn_nr): submission = get_object_or_404(Submission, arxiv_identifier_w_vn_nr=arxiv_identifier_w_vn_nr) if submission.status not in ['EICassigned', 'review_closed']: errormessage = ('This submission\'s current status is: ' + - submission_status_dict[submission.status] + '. ' + submission.get_status_display + '. ' 'An Editorial Recommendation is not required.') return render(request, 'scipost/error.html', {'errormessage': errormessage}) if request.method == 'POST': diff --git a/theses/constants.py b/theses/constants.py new file mode 100644 index 0000000000000000000000000000000000000000..36157994481348e9a350223babaab919c9788979 --- /dev/null +++ b/theses/constants.py @@ -0,0 +1,8 @@ +MASTER_THESIS = 'MA' +PHD_THESIS = 'PhD' +HABILITATION_THESIS = 'Hab' +THESIS_TYPES = ( + (MASTER_THESIS, 'Master\'s'), + (PHD_THESIS, 'Ph.D.'), + (HABILITATION_THESIS, 'Habilitation'), +) diff --git a/theses/forms.py b/theses/forms.py index 3f5dfcc0e5784131d4e8a0d9f7039bad5b07064a..f211402036e27e1ad7c12f19ecaff8972f9bd512 100644 --- a/theses/forms.py +++ b/theses/forms.py @@ -3,13 +3,11 @@ from django.core.mail import EmailMessage from django.template.loader import render_to_string from django.urls import reverse -from scipost.models import Contributor, title_dict +from scipost.models import Contributor from .models import ThesisLink from .helpers import past_years -from scipost.models import Contributor, title_dict - class RequestThesisLinkForm(forms.ModelForm): class Meta: @@ -64,7 +62,7 @@ class VetThesisLinkForm(RequestThesisLinkForm): def vet_request(self, thesislink, user): mail_params = { - 'vocative_title': title_dict[thesislink.requested_by.title], + 'vocative_title': thesislink.requested_by.get_title_display(), 'thesislink': thesislink, 'full_url': self.request.build_absolute_uri( reverse('theses:thesis', kwargs={'thesislink_id': thesislink.id})) diff --git a/theses/managers.py b/theses/managers.py index 79e971b796332fa2fd46270961a988389b00d0f2..68dc44574b8722927314cc063cbd22ef26c02a58 100644 --- a/theses/managers.py +++ b/theses/managers.py @@ -1,7 +1,4 @@ -import datetime - from django.db import models -from django.utils import timezone class ThesisLinkManager(models.Manager): diff --git a/theses/models.py b/theses/models.py index 0b5d333757c72aeb3d893454b2a520faad373f69..48a957c3c840b730ad48215e7518c3c1d68e3a6b 100644 --- a/theses/models.py +++ b/theses/models.py @@ -1,26 +1,15 @@ from django.utils import timezone from django.db import models -from django.template import Template, Context -from journals.models import SCIPOST_JOURNALS_DOMAINS, journals_domains_dict -from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\ - subject_areas_dict, disciplines_dict +from journals.constants import SCIPOST_JOURNALS_DOMAINS +from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS from scipost.models import Contributor +from .constants import THESIS_TYPES from .managers import ThesisLinkManager class ThesisLink(models.Model): - MASTER_THESIS = 'MA' - PHD_THESIS = 'PhD' - HABILITATION_THESIS = 'Hab' - THESIS_TYPES = ( - (MASTER_THESIS, 'Master\'s'), - (PHD_THESIS, 'Ph.D.'), - (HABILITATION_THESIS, 'Habilitation'), - ) - THESIS_TYPES_DICT = dict(THESIS_TYPES) - """ An URL pointing to a thesis """ requested_by = models.ForeignKey( Contributor, blank=True, null=True, @@ -70,16 +59,3 @@ class ThesisLink(models.Model): def __str__(self): return self.title - - def simple_header_as_li(self): - # for Lists - context = Context({ - 'id': self.id, 'title': self.title, 'author': self.author}) - header = ( - '<li><div class="flex-container">' - '<div class="flex-whitebox0"><p><a href="/thesis/{{ id }}" ' - 'class="pubtitleli">{{ title }}</a></p>' - '<p>' + self.THESIS_TYPES_DICT[self.type] + - ' thesis by {{ author }} </div></div></li>') - template = Template(header) - return template.render(context) diff --git a/theses/templates/theses/_thesislink_card_content.html b/theses/templates/theses/_thesislink_card_content.html new file mode 100644 index 0000000000000000000000000000000000000000..89fbde9224a364d55fb1851c9e474345a82a8d2c --- /dev/null +++ b/theses/templates/theses/_thesislink_card_content.html @@ -0,0 +1,15 @@ +{% load theses_extras %} + +<div class="card-block"> + <h3 class="card-title"> + <a href="{% url 'theses:thesis' thesislink_id=thesislink.id %}">{{ thesislink.title }}</a> + </h3> + <p class="card-text"> + {{ thesislink.get_type_display }} thesis by {{ thesislink.author }} + (supervisor(s): {{ thesislink.supervisor }}) in + {{ thesislink.get_discipline_display }}, {{ thesislink.get_domain_display }} {{ thesislink.get_subject_area_display }}. + </p> + <p class="card-text text-muted"> + Defense date: {{ thesislink.defense_date }}. Latest activity: {{ thesislink.latest_activity|date:"DATE_FORMAT" }}. + </p> +</div> diff --git a/theses/templates/theses/_thesislink_header_as_li.html b/theses/templates/theses/_thesislink_header_as_li.html deleted file mode 100644 index bb6f8503518925af1ddf5fa8048fdcbc05da9590..0000000000000000000000000000000000000000 --- a/theses/templates/theses/_thesislink_header_as_li.html +++ /dev/null @@ -1,12 +0,0 @@ -{% load theses_extras %} - -<li> - <p> - <a href="{% url 'theses:thesis' thesislink_id=thesislink.id %}" class="pubtitleli">{{ thesislink.title }}</a> - </p> - <p>{{ thesislink|type }} thesis by {{ thesislink.author }} - (supervisor(s): {{ thesislink.supervisor }}) in - {{ thesislink|discipline }}, {{ thesislink|domain }} {{ thesislink|subject_area }}. - </p> - <p>Defense date: {{ thesislink.defense_date }}. Latest activity: {{ thesislink.latest_activity|date:"DATE_FORMAT" }}.</p> -</li> diff --git a/theses/templates/theses/theses.html b/theses/templates/theses/theses.html deleted file mode 100644 index 6abaedb7eb8c1764cbcdee25d1b3f0e222cfde93..0000000000000000000000000000000000000000 --- a/theses/templates/theses/theses.html +++ /dev/null @@ -1,87 +0,0 @@ -{% extends 'scipost/base.html' %} - -{% load bootstrap %} - -{% block pagetitle %}: Theses{% endblock pagetitle %} - -{% block headsup %} -<script type="text/javascript" async src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script> -{% endblock headsup %} - -{% block content %} - -<div class="row"> - <div class="col-md-4"> - <div class="panel page-header-panel"> - <h1>SciPost Theses</h1> - <h3><a href="{% url 'theses:request_thesislink' %}">Request a new Thesis Link</a></h3> - </div> - </div> - <div class="col-md-4"> - <div class="panel page-header-panel"> - <h2>Search SciPost Theses:</h2> - <form class="small" action="{% url 'theses:theses' %}" method="get"> - <table> - {{ form|bootstrap:'4,8,sm' }} - </table> - <input class="btn btn-sm btn-secondary" type="submit" name="Submit" /> - </form> - </div> - </div> - <div class="col-md-4"> - <div class="panel page-header-panel"> - <h2>View SciPost Theses</h2> - <ul> - <li>Physics: last <a href="{% url 'theses:browse' discipline='physics' nrweeksback=1 %}">week</a>, <a href="{% url 'theses:browse' discipline='physics' nrweeksback=4 %}">month</a> or <a href="{% url 'theses:browse' discipline='physics' nrweeksback=52 %}">year</a> </li> - </ul> - </div> - </div> - </div> - - {% if search_results or form.has_changed %} - <div class="row"> - <div class="col-12"> - <hr class="hr12"> - <h3>Search results:</h3> - {% if search_results %} - <ul> - {% for thesislink in search_results %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} - {% endfor %} - </ul> - {% elif form.has_changed %} - <h3>No match found for your search query.</h3> - {% endif %} - </div> -</div> -{% endif %} - -{% if recent_theses %} -<div class="row"> - <div class="col-12"> - <hr class="hr12"> - <h2>Recently active Thesis Links:</h2> - <ul> - {% for thesislink in recent_theses %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} - {% endfor %} - </ul> - </div> -</div> -{% endif %} - -{% if thesislink_browse_list %} -<div class="row"> - <div class="col-12"> - <hr class="hr12"> - <h2>Thesis Links in {{ discipline }} in the last {{ nrweeksback }} week{% if nrweeksback == '1' %}{% else %}s{% endif %}:</h2> - <ul> - {% for thesislink in thesislink_browse_list %} - {% include 'theses/_thesislink_header_as_li.html' with thesislink=thesislink %} - {% endfor %} - </ul> - </div> -</div> -{% endif %} - -{% endblock content %} diff --git a/theses/templates/theses/thesis_detail.html b/theses/templates/theses/thesis_detail.html index edde03144f188effb6c6fad2c30bf6783b4ac6b9..12a49b417caea35912379368119483f12134d5b5 100644 --- a/theses/templates/theses/thesis_detail.html +++ b/theses/templates/theses/thesis_detail.html @@ -8,9 +8,6 @@ <script> $(document).ready(function(){ - $("#commentsbutton").click(function(){ - $("#commentslist").toggle(); - }); var comment_text_input = $("#id_comment_text"); @@ -33,11 +30,9 @@ {% block content %} <div class="row"> - <div class="col-12"> - <div class="panel"> - <h1>SciPost Thesis Link</h1> + <div class="col-12"> + <h1 class="highlight">SciPost Thesis Link</h1> </div> - </div> </div> <hr /> diff --git a/theses/templates/theses/thesislink_list.html b/theses/templates/theses/thesislink_list.html new file mode 100644 index 0000000000000000000000000000000000000000..c735fd247c1ef7fe05aa75e5887e59007d2f5b54 --- /dev/null +++ b/theses/templates/theses/thesislink_list.html @@ -0,0 +1,86 @@ +{% extends 'scipost/base.html' %} + +{% load bootstrap %} +{% load request_filters %} + +{% block pagetitle %}: Theses{% endblock pagetitle %} + +{% block headsup %} +<script type="text/javascript" async src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script> +{% endblock headsup %} + +{% block content %} + +<div class="row"> + <div class="col-md-4"> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h1 class="card-title">SciPost Theses</h1> + <h3><a href="{% url 'theses:request_thesislink' %}">Request a new Thesis Link</a></h3> + </div> + </div> + </div> + <div class="col-md-4"> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h2 class="card-title">Search SciPost Theses:</h2> + <form class="small" action="{% url 'theses:theses' %}" method="get"> + {{ form|bootstrap:'4,8,sm' }} + <input class="btn btn-sm btn-secondary" type="submit" name="Submit" /> + </form> + </div> + </div> + </div> + <div class="col-md-4"> + <div class="card card-grey"> + <div class="card-block min-height-190"> + <h2 class="card-title">View SciPost Theses</h2> + <ul> + <li>Physics: last <a href="{% url 'theses:browse' discipline='physics' nrweeksback=1 %}">week</a>, <a href="{% url 'theses:browse' discipline='physics' nrweeksback=4 %}">month</a> or <a href="{% url 'theses:browse' discipline='physics' nrweeksback=52 %}">year</a> </li> + </ul> + </div> + </div> + </div> +</div> + +<hr> +<div class="row"> + <div class="col-12"> + {% if recent %} + <h2>Recently active Thesis Links:</h2> + {% elif browse %} + <h2>Thesis Links in {{ discipline }} in the last {{ nrweeksback }} week{{ nrweeksback|pluralize }}:</h2> + {% else %} + <h2>Search results:</h3> + {% endif %} + + {% if object_list %} + {% if is_paginated %} + <p> + {% if page_obj.has_previous %} + <a href="?{% url_replace page=page_obj.previous_page_number %}">Previous</a> + {% endif %} + Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}. + {% if page_obj.has_next %} + <a href="?{% url_replace page=page_obj.next_page_number %}">Next</a> + {% endif %} + </p> + {% endif %} + + </div> + <div class="col-12"> + + <ul class="list-group list-group-flush"> + {% for thesislink in object_list %} + <li class="list-group-item"> + {% include 'theses/_thesislink_card_content.html' with thesislink=thesislink %} + </li> + {% endfor %} + </ul> + {% else %} + <h3>No match found for your search query.</h3> + {% endif %} + </div> +</div> + +{% endblock content %} diff --git a/theses/templatetags/theses_extras.py b/theses/templatetags/theses_extras.py index f3b441f41f64e3bb5a7ad23f852eb3e627fe9dec..e60c4ecf59d309bd7596b3574c08f021dc1de282 100644 --- a/theses/templatetags/theses_extras.py +++ b/theses/templatetags/theses_extras.py @@ -1,26 +1,27 @@ from django import template -from scipost.constants import SCIPOST_DISCIPLINES, subject_areas_dict, disciplines_dict -from journals.models import journals_domains_dict - register = template.Library() @register.filter def type(thesislink): - return thesislink.THESIS_TYPES_DICT[thesislink.type] + # deprecated method, to be removed in future + return thesislink.get_type_display() @register.filter def discipline(thesislink): - return disciplines_dict[thesislink.discipline] + # deprecated method, to be removed in future + return thesislink.get_discipline_display() @register.filter def domain(thesislink): - return journals_domains_dict[thesislink.domain] + # deprecated method, to be removed in future + return thesislink.get_domain_display() @register.filter def subject_area(thesislink): - return subject_areas_dict[thesislink.subject_area] + # deprecated method, to be removed in future + return thesislink.get_subject_area_display() diff --git a/theses/urls.py b/theses/urls.py index a0734fdb52195d0ffaa5864a8ed649fe7129630d..5f8baf0e35cb4f7e7564746256b3cb99b58589a8 100644 --- a/theses/urls.py +++ b/theses/urls.py @@ -5,8 +5,8 @@ from . import views urlpatterns = [ # Thesis Links - url(r'^$', views.theses, name='theses'), - url(r'^browse/(?P<discipline>[a-z]+)/(?P<nrweeksback>[0-9]+)/$', views.browse, name='browse'), + url(r'^$', views.ThesisListView.as_view(), name='theses'), + url(r'^browse/(?P<discipline>[a-z]+)/(?P<nrweeksback>[0-9]+)/$', views.ThesisListView.as_view(), name='browse'), url(r'^(?P<thesislink_id>[0-9]+)/$', views.thesis_detail, name='thesis'), url(r'^request_thesislink$', views.RequestThesisLink.as_view(), name='request_thesislink'), url(r'^unvetted_thesislinks$', views.UnvettedThesisLinks.as_view(), name='unvetted_thesislinks'), diff --git a/theses/views.py b/theses/views.py index 87d39a7f6d182336dc43c3e32c1de106acd1bdc7..b91abefdb2170c88a4de62c374fa7095e6093317 100644 --- a/theses/views.py +++ b/theses/views.py @@ -13,13 +13,9 @@ from django.utils.decorators import method_decorator from .models import ThesisLink from .forms import RequestThesisLinkForm, ThesisLinkSearchForm, VetThesisLinkForm -from comments.models import Comment from comments.forms import CommentForm -from scipost.forms import TITLE_CHOICES -from scipost.models import Contributor -import strings -title_dict = dict(TITLE_CHOICES) # Convert titles for use in emails +import strings ################ @@ -86,47 +82,44 @@ class VetThesisLink(UpdateView): return kwargs -def theses(request): - form = ThesisLinkSearchForm(request.GET) - if form.is_valid() and form.has_changed(): - search_results = ThesisLink.objects.search_results(form) - recent_theses = [] - else: - recent_theses = ThesisLink.objects.latest(5) - search_results = [] +class ThesisListView(ListView): + model = ThesisLink + form = ThesisLinkSearchForm + thesis_search_list = [] + paginate_by = 10 + + def get_queryset(self): + # Context is not saved to View object by default + self.pre_context = self.kwargs + + # Browse is discipline is given + if 'discipline' in self.kwargs: + self.pre_context['browse'] = True + + # Queryset for browsing + if self.kwargs.get('browse', False): + return self.model.objects.vetted().filter( + discipline=self.kwargs['discipline'], + latest_activity__gte=timezone.now() + datetime.timedelta( + weeks=-int(self.kwargs['nrweeksback'])), + ) + + # Queryset for searchform is processed by managers + form = self.form(self.request.GET) + if form.is_valid() and form.has_changed(): + return self.model.objects.search_results(form) + self.pre_context['recent'] = True + return self.model.objects.vetted() - context = { - 'form': form, 'search_results': search_results, - 'recent_theses': recent_theses - } - return render(request, 'theses/theses.html', context) + def get_context_data(self, **kwargs): + # Update the context data from `get_queryset` + context = super().get_context_data(**kwargs) + context.update(self.pre_context) + # Search form added to context + context['form'] = self.form(initial=self.request.GET) -def browse(request, discipline, nrweeksback): - 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 = [] - context = {'form': form, 'thesislink_search_list': thesislink_search_list} - return HttpResponseRedirect(request, 'theses/theses.html', context) - else: - form = ThesisLinkSearchForm() - thesislink_browse_list = (ThesisLink.objects.filter( - vetted=True, discipline=discipline, - latest_activity__gte=timezone.now() + datetime.timedelta(weeks=-int(nrweeksback)))) - context = {'form': form, 'discipline': discipline, - 'nrweeksback': nrweeksback, - 'thesislink_browse_list': thesislink_browse_list} - return render(request, 'theses/theses.html', context) + return context def thesis_detail(request, thesislink_id): diff --git a/virtualmeetings/migrations/0001_initial.py b/virtualmeetings/migrations/0001_initial.py index 567764e57de6f7ee69c5fa158016d95f64917c0a..492b8e80ef3a4adc0541c026e15e68618489c93c 100644 --- a/virtualmeetings/migrations/0001_initial.py +++ b/virtualmeetings/migrations/0001_initial.py @@ -6,6 +6,7 @@ from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import scipost.models +import scipost.fields class Migration(migrations.Migration): @@ -54,7 +55,7 @@ class Migration(migrations.Migration): ('first_name', models.CharField(default='', max_length=30)), ('last_name', models.CharField(default='', max_length=30)), ('discipline', models.CharField(choices=[('physics', 'Physics'), ('astrophysics', 'Astrophysics'), ('mathematics', 'Mathematics'), ('computerscience', 'Computer Science')], default='physics', max_length=20, verbose_name='Main discipline')), - ('expertises', scipost.models.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), + ('expertises', scipost.fields.ChoiceArrayField(base_field=models.CharField(choices=[('Physics', (('Phys:AE', 'Atomic, Molecular and Optical Physics - Experiment'), ('Phys:AT', 'Atomic, Molecular and Optical Physics - Theory'), ('Phys:BI', 'Biophysics'), ('Phys:CE', 'Condensed Matter Physics - Experiment'), ('Phys:CT', 'Condensed Matter Physics - Theory'), ('Phys:FD', 'Fluid Dynamics'), ('Phys:GR', 'Gravitation, Cosmology and Astroparticle Physics'), ('Phys:HE', 'High-Energy Physics - Experiment'), ('Phys:HT', 'High-Energy Physics- Theory'), ('Phys:HP', 'High-Energy Physics - Phenomenology'), ('Phys:MP', 'Mathematical Physics'), ('Phys:NE', 'Nuclear Physics - Experiment'), ('Phys:NT', 'Nuclear Physics - Theory'), ('Phys:QP', 'Quantum Physics'), ('Phys:SM', 'Statistical and Soft Matter Physics'))), ('Astrophysics', (('Astro:GA', 'Astrophysics of Galaxies'), ('Astro:CO', 'Cosmology and Nongalactic Astrophysics'), ('Astro:EP', 'Earth and Planetary Astrophysics'), ('Astro:HE', 'High Energy Astrophysical Phenomena'), ('Astro:IM', 'Instrumentation and Methods for Astrophysics'), ('Astro:SR', 'Solar and Stellar Astrophysics'))), ('Mathematics', (('Math:AG', 'Algebraic Geometry'), ('Math:AT', 'Algebraic Topology'), ('Math:AP', 'Analysis of PDEs'), ('Math:CT', 'Category Theory'), ('Math:CA', 'Classical Analysis and ODEs'), ('Math:CO', 'Combinatorics'), ('Math:AC', 'Commutative Algebra'), ('Math:CV', 'Complex Variables'), ('Math:DG', 'Differential Geometry'), ('Math:DS', 'Dynamical Systems'), ('Math:FA', 'Functional Analysis'), ('Math:GM', 'General Mathematics'), ('Math:GN', 'General Topology'), ('Math:GT', 'Geometric Topology'), ('Math:GR', 'Group Theory'), ('Math:HO', 'History and Overview'), ('Math:IT', 'Information Theory'), ('Math:KT', 'K-Theory and Homology'), ('Math:LO', 'Logic'), ('Math:MP', 'Mathematical Physics'), ('Math:MG', 'Metric Geometry'), ('Math:NT', 'Number Theory'), ('Math:NA', 'Numerical Analysis'), ('Math:OA', 'Operator Algebras'), ('Math:OC', 'Optimization and Control'), ('Math:PR', 'Probability'), ('Math:QA', 'Quantum Algebra'), ('Math:RT', 'Representation Theory'), ('Math:RA', 'Rings and Algebras'), ('Math:SP', 'Spectral Theory'), ('Math:ST', 'Statistics Theory'), ('Math:SG', 'Symplectic Geometry'))), ('Computer Science', (('Comp:AI', 'Artificial Intelligence'), ('Comp:CC', 'Computational Complexity'), ('Comp:CE', 'Computational Engineering, Finance, and Science'), ('Comp:CG', 'Computational Geometry'), ('Comp:GT', 'Computer Science and Game Theory'), ('Comp:CV', 'Computer Vision and Pattern Recognition'), ('Comp:CY', 'Computers and Society'), ('Comp:CR', 'Cryptography and Security'), ('Comp:DS', 'Data Structures and Algorithms'), ('Comp:DB', 'Databases'), ('Comp:DL', 'Digital Libraries'), ('Comp:DM', 'Discrete Mathematics'), ('Comp:DC', 'Distributed, Parallel, and Cluster Computing'), ('Comp:ET', 'Emerging Technologies'), ('Comp:FL', 'Formal Languages and Automata Theory'), ('Comp:GL', 'General Literature'), ('Comp:GR', 'Graphics'), ('Comp:AR', 'Hardware Architecture'), ('Comp:HC', 'Human-Computer Interaction'), ('Comp:IR', 'Information Retrieval'), ('Comp:IT', 'Information Theory'), ('Comp:LG', 'Learning'), ('Comp:LO', 'Logic in Computer Science'), ('Comp:MS', 'Mathematical Software'), ('Comp:MA', 'Multiagent Systems'), ('Comp:MM', 'Multimedia'), ('Comp:NI', 'Networking and Internet Architecture'), ('Comp:NE', 'Neural and Evolutionary Computing'), ('Comp:NA', 'Numerical Analysis'), ('Comp:OS', 'Operating Systems'), ('Comp:OH', 'Other Computer Science'), ('Comp:PF', 'Performance'), ('Comp:PL', 'Programming Languages'), ('Comp:RO', 'Robotics'), ('Comp:SI', 'Social and Information Networks'), ('Comp:SE', 'Software Engineering'), ('Comp:SD', 'Sound'), ('Comp:SC', 'Symbolic Computation'), ('Comp:SY', 'Systems and Control')))], max_length=10), blank=True, null=True, size=None)), ('webpage', models.URLField(default='')), ('nr_A', models.PositiveIntegerField(default=0)), ('nr_N', models.PositiveIntegerField(default=0)), diff --git a/virtualmeetings/models.py b/virtualmeetings/models.py index 55aaacefe039c513e6f0a63644e44d2d4f59c46c..f78744fc9114cd35791da721d09d57adcbad9778 100644 --- a/virtualmeetings/models.py +++ b/virtualmeetings/models.py @@ -6,8 +6,9 @@ from django.utils import timezone from .constants import MOTION_CATEGORIES from scipost.constants import SCIPOST_DISCIPLINES, SCIPOST_SUBJECT_AREAS,\ - subject_areas_dict, disciplines_dict -from scipost.models import Contributor, ChoiceArrayField + subject_areas_dict +from scipost.fields import ChoiceArrayField +from scipost.models import Contributor class VGM(models.Model): @@ -112,7 +113,7 @@ class Nomination(models.Model): 'proposer': '%s %s' % (self.by.user.first_name, self.by.user.last_name), 'name': self.first_name + ' ' + self.last_name, - 'discipline': disciplines_dict[self.discipline], + 'discipline': self.get_discipline_display(), 'webpage': self.webpage, }) template = Template(html)