From 92ef37666e3718abcceb3e9f24cb41193c1d6ba5 Mon Sep 17 00:00:00 2001 From: Jorran de Wit <jorrandewit@outlook.com> Date: Tue, 4 Dec 2018 20:59:15 +0100 Subject: [PATCH] Add explicit `threads` --- .../migrations/0002_notification_url_code.py | 20 +++++++++++ submissions/admin.py | 3 +- submissions/forms.py | 5 +-- submissions/managers.py | 4 ++- .../migrations/0047_auto_20181204_2011.py | 25 +++++++++++++ .../migrations/0048_submission_thread_hash.py | 21 +++++++++++ .../migrations/0049_auto_20181204_2040.py | 35 +++++++++++++++++++ submissions/models.py | 16 +++++---- 8 files changed, 119 insertions(+), 10 deletions(-) create mode 100644 notifications/migrations/0002_notification_url_code.py create mode 100644 submissions/migrations/0047_auto_20181204_2011.py create mode 100644 submissions/migrations/0048_submission_thread_hash.py create mode 100644 submissions/migrations/0049_auto_20181204_2040.py diff --git a/notifications/migrations/0002_notification_url_code.py b/notifications/migrations/0002_notification_url_code.py new file mode 100644 index 000000000..b8922d06c --- /dev/null +++ b/notifications/migrations/0002_notification_url_code.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-12-04 19:11 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('notifications', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='notification', + name='url_code', + field=models.CharField(blank=True, max_length=255), + ), + ] diff --git a/submissions/admin.py b/submissions/admin.py index 7b7a19e8e..78df5387c 100644 --- a/submissions/admin.py +++ b/submissions/admin.py @@ -65,8 +65,9 @@ class SubmissionAdmin(GuardedModelAdmin): }), ('Versioning', { 'fields': ( + 'thread_hash', 'is_current', - 'is_resubmission', + '_is_resubmission', 'is_resubmission_of', 'list_of_changes'), }), diff --git a/submissions/forms.py b/submissions/forms.py index 67f6d5b45..47668d7bd 100644 --- a/submissions/forms.py +++ b/submissions/forms.py @@ -242,11 +242,12 @@ class SubmissionService: Submission.objects.filter(id=submission.id).update( open_for_reporting=True, open_for_commenting=True, - is_resubmission=True, + is_resubmission_of=self.latest_submission, visible_pool=True, refereeing_cycle=CYCLE_UNDETERMINED, editor_in_charge=self.latest_submission.editor_in_charge, - status=STATUS_EIC_ASSIGNED) + status=STATUS_EIC_ASSIGNED, + thread_hash=self.latest_submission.thread_hash) # Add author(s) (claim) fields submission.authors.add(*self.latest_submission.authors.all()) diff --git a/submissions/managers.py b/submissions/managers.py index 64ac57918..dc7332095 100644 --- a/submissions/managers.py +++ b/submissions/managers.py @@ -17,6 +17,8 @@ now = timezone.now() class SubmissionQuerySet(models.QuerySet): def _newest_version_only(self, queryset): """ + TODO: Make more efficient... with agregation or whatever. + The current Queryset should return only the latest version of the Arxiv submissions known to SciPost. @@ -157,7 +159,7 @@ class SubmissionQuerySet(models.QuerySet): (including subsequent resubmissions, even if those came in later). """ identifiers = [] - for sub in self.filter(is_resubmission=False, + for sub in self.filter(is_resubmission_of__isnull=True, submission_date__range=(from_date, until_date)): identifiers.append(sub.preprint.identifier_wo_vn_nr) return self.filter(preprint__identifier_wo_vn_nr__in=identifiers) diff --git a/submissions/migrations/0047_auto_20181204_2011.py b/submissions/migrations/0047_auto_20181204_2011.py new file mode 100644 index 000000000..15fe0d2cb --- /dev/null +++ b/submissions/migrations/0047_auto_20181204_2011.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-12-04 19:11 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0046_auto_20181130_1013'), + ] + + operations = [ + migrations.RenameField( + model_name='submission', + old_name='is_resubmission', + new_name='_is_resubmission', + ), + migrations.AlterField( + model_name='submission', + name='submission_type', + field=models.CharField(blank=True, choices=[('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)')], max_length=10), + ), + ] diff --git a/submissions/migrations/0048_submission_thread_hash.py b/submissions/migrations/0048_submission_thread_hash.py new file mode 100644 index 000000000..ddf50c99d --- /dev/null +++ b/submissions/migrations/0048_submission_thread_hash.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-12-04 19:37 +from __future__ import unicode_literals + +from django.db import migrations, models +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0047_auto_20181204_2011'), + ] + + operations = [ + migrations.AddField( + model_name='submission', + name='thread_hash', + field=models.UUIDField(default=uuid.uuid4), + ), + ] diff --git a/submissions/migrations/0049_auto_20181204_2040.py b/submissions/migrations/0049_auto_20181204_2040.py new file mode 100644 index 000000000..bbcd903d8 --- /dev/null +++ b/submissions/migrations/0049_auto_20181204_2040.py @@ -0,0 +1,35 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.4 on 2018-12-04 19:40 +from __future__ import unicode_literals + +import uuid + +from django.db import migrations + + +def get_thread_ids(parent, submissions_list=[]): + successor = parent.successor.first() + if not successor: + return submissions_list + + submissions_list.append(successor.id) + return get_thread_ids(successor, submissions_list) + + +def populate_thread_hashes(apps, schema_editor): + Submission = apps.get_model('submissions', 'Submission') + + for original_submission in Submission.objects.filter(is_resubmission_of__isnull=True): + children_ids = get_thread_ids(original_submission, [original_submission.id]) + Submission.objects.filter(id__in=children_ids).update(thread_hash=uuid.uuid4()) + + +class Migration(migrations.Migration): + + dependencies = [ + ('submissions', '0048_submission_thread_hash'), + ] + + operations = [ + migrations.RunPython(populate_thread_hashes, reverse_code=migrations.RunPython.noop), + ] diff --git a/submissions/models.py b/submissions/models.py index 19e17e177..f7348cfb6 100644 --- a/submissions/models.py +++ b/submissions/models.py @@ -4,6 +4,7 @@ __license__ = "AGPL v3" import datetime import feedparser +import uuid from django.contrib.postgres.fields import JSONField from django.contrib.contenttypes.fields import GenericRelation @@ -77,7 +78,8 @@ class Submission(models.Model): visible_pool = models.BooleanField("Is visible in the Pool", default=False) is_resubmission_of = models.ForeignKey( 'self', blank=True, null=True, related_name='successor') - is_resubmission = models.BooleanField(default=False) + thread_hash = models.UUIDField(default=uuid.uuid4) + _is_resubmission = models.BooleanField(default=False) refereeing_cycle = models.CharField( max_length=30, choices=SUBMISSION_CYCLES, default=CYCLE_DEFAULT, blank=True) @@ -196,6 +198,10 @@ class Submission(models.Model): """Return url of the Submission detail page.""" return reverse('submissions:submission', args=(self.preprint.identifier_w_vn_nr,)) + @property + def is_resubmission(self): + return self.is_resubmission_of is not None + @property def notification_name(self): """Return string representation of this Submission as shown in Notifications.""" @@ -232,13 +238,12 @@ class Submission(models.Model): def original_submission_date(self): """Return the submission_date of the first Submission in the thread.""" return Submission.objects.filter( - preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).first().submission_date + thread_hash=self.thread_hash, is_resubmission_of__isnull=True).first().submission_date @property def thread(self): """Return all (public) Submissions in the database in this ArXiv identifier series.""" - return Submission.objects.public().filter( - preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).order_by( + return Submission.objects.public().filter(thread_hash=self.thread_hash).order_by( '-preprint__vn_nr') @cached_property @@ -253,8 +258,7 @@ class Submission(models.Model): def get_other_versions(self): """Return queryset of other Submissions with this ArXiv identifier series.""" - return Submission.objects.filter( - preprint__identifier_wo_vn_nr=self.preprint.identifier_wo_vn_nr).exclude(pk=self.id) + return Submission.objects.filter(thread_hash=self.thread_hash).exclude(pk=self.id) def count_accepted_invitations(self): """Count number of accepted RefereeInvitations for this Submission.""" -- GitLab