Properly normalize table of mailinglist threads
authorMagnus Hagander <magnus@hagander.net>
Mon, 14 Jul 2014 17:13:12 +0000 (19:13 +0200)
committerMagnus Hagander <magnus@hagander.net>
Mon, 14 Jul 2014 17:13:12 +0000 (19:13 +0200)
pgcommitfest/commitfest/ajax.py
pgcommitfest/commitfest/models.py

index 643af704dcde1a76981f911273f29e1da2ebbc61..d0e56208667138b368c45894b468c1bc761be6cc 100644 (file)
@@ -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()
index 284c3d5443842266b91356c0c34c0e7d744085bb..21fe733ebfd4818b490c9534bba59801bbc2807d 100644 (file)
@@ -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)