From 384ba4a380e17641743625f21429169aadbd2e3d Mon Sep 17 00:00:00 2001 From: Magnus Hagander Date: Mon, 14 Jul 2014 19:13:12 +0200 Subject: [PATCH] Properly normalize table of mailinglist threads --- pgcommitfest/commitfest/ajax.py | 27 ++++++++++++++++++++++----- pgcommitfest/commitfest/models.py | 9 ++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/pgcommitfest/commitfest/ajax.py b/pgcommitfest/commitfest/ajax.py index 643af70..d0e5620 100644 --- a/pgcommitfest/commitfest/ajax.py +++ b/pgcommitfest/commitfest/ajax.py @@ -85,17 +85,32 @@ def attachThread(request): raise Exception("Something happened that cannot happen") def doAttachThread(cf, patch, msgid, user): + # Note! Must be called in an open transaction! r = sorted(_archivesAPI('/message-id.json/%s' % msgid), key=lambda x: x['date']) # We have the full thread metadata - using the first and last entry, # construct a new mailthread in our own model. # First, though, check if it's already there. - if MailThread.objects.filter(messageid=r[0]['msgid'], patch=patch).exists(): - # It already existed. Pretend everything is fine. + threads = MailThread.objects.filter(messageid=r[0]['msgid']) + if len(threads): + thread = threads[0] + if thread.patches.filter(id=patch.id).exists(): + # We have everything, so claim we're done. + return True + + # We did not exist, so we'd better add ourselves. + # While at it, we update the thread entry with the latest data from the + # archives. + thread.patches.add(patch) + thread.latestmessage=r[-1]['date'] + thread.latestauthor=r[-1]['from'] + thread.latestsubject=r[-1]['subj'] + thread.altestmsgid=r[-1]['msgid'] + thread.save() return True + # No existing thread existed, so create it # Now create a new mailthread entry m = MailThread(messageid=r[0]['msgid'], - patch=patch, subject=r[0]['subj'], firstmessage=r[0]['date'], firstauthor=r[0]['from'], @@ -105,6 +120,8 @@ def doAttachThread(cf, patch, msgid, user): latestmsgid=r[-1]['msgid'], ) m.save() + m.patches.add(patch) + m.save() parse_and_add_attachments(r, m) PatchHistory(patch=patch, by=user, what='Attached mail thread %s' % r[0]['msgid']).save() patch.update_lastmail() @@ -117,9 +134,9 @@ def doAttachThread(cf, patch, msgid, user): def detachThread(request): cf = get_object_or_404(CommitFest, pk=int(request.POST['cf'])) patch = get_object_or_404(Patch, pk=int(request.POST['p']), commitfests=cf) - thread = get_object_or_404(MailThread, patch=patch, messageid=request.POST['msg']) + thread = get_object_or_404(MailThread, messageid=request.POST['msg']) - thread.delete() + patch.mailthread_set.remove(thread) PatchHistory(patch=patch, by=request.user, what='Detached mail thread %s' % request.POST['msg']).save() patch.update_lastmail() patch.set_modified() diff --git a/pgcommitfest/commitfest/models.py b/pgcommitfest/commitfest/models.py index 284c3d5..21fe733 100644 --- a/pgcommitfest/commitfest/models.py +++ b/pgcommitfest/commitfest/models.py @@ -74,7 +74,7 @@ class Patch(models.Model, DiffableModel): # If there is a git repo about this patch gitlink = models.URLField(blank=True, null=True, default='') - # Mailthreads are OneToMany in the other direction + # Mailthreads are ManyToMany in the other direction #mailthreads_set = ... authors = models.ManyToManyField(User, related_name='patch_author', blank=True) @@ -185,15 +185,15 @@ class PatchHistory(models.Model): class MailThread(models.Model): # This class tracks mail threads from the main postgresql.org # mailinglist archives. For each thread, we store *one* messageid. - # Using this messageid we can always query the arvhives for more + # Using this messageid we can always query the archives for more # detailed information, which is done dynamically as the page # is loaded. # For threads in an active or future commitfest, we also poll # the archives to fetch "updated entries" at (ir)regular intervals # so we can keep track of when there was last a change on the # thread in question. - messageid = models.CharField(max_length=1000, null=False, blank=False) - patch = models.ForeignKey(Patch, blank=False, null=False) + messageid = models.CharField(max_length=1000, null=False, blank=False, unique=True) + patches = models.ManyToManyField(Patch, blank=False, null=False) subject = models.CharField(max_length=500, null=False, blank=False) firstmessage = models.DateTimeField(null=False, blank=False) firstauthor = models.CharField(max_length=500, null=False, blank=False) @@ -207,7 +207,6 @@ class MailThread(models.Model): class Meta: ordering = ('firstmessage', ) - unique_together = (('messageid', 'patch',), ) class MailThreadAttachment(models.Model): mailthread = models.ForeignKey(MailThread, null=False, blank=False) -- 2.39.5