[Patchew-devel] [PATCH 05/16] Generalize Review model to Queue

Fam Zheng famz at redhat.com
Wed Nov 21 02:08:35 UTC 2018


The concept of a queue is a per-user model for maintainers. A maintainer
can have one ore more queues. The current Review model already has
accept and reject stautus, so we generalize that to support a more
flexible queue feature.

Previously, "mark as accepted" adds a (user, message, accept=True)
record in the Review model. Now it adds a (user, message, name='accept')
record in the Queue model.

Similary, for 'mark as rejected', a (user, message, name='reject')
record is added in the Queue model.

This makes the two queue names specially purposed on the web interface
and search terms, which we'll extend to also support normal queues.

Signed-off-by: Fam Zheng <famz at redhat.com>
---
 api/migrations/0040_review_to_queue.py    | 19 +++++++++++
 api/migrations/0041_auto_20181120_0636.py | 40 +++++++++++++++++++++++
 api/models.py                             | 12 +++++--
 api/search.py                             | 10 +++---
 mods/maintainer.py                        | 23 +++++++------
 5 files changed, 86 insertions(+), 18 deletions(-)
 create mode 100644 api/migrations/0040_review_to_queue.py
 create mode 100644 api/migrations/0041_auto_20181120_0636.py

diff --git a/api/migrations/0040_review_to_queue.py b/api/migrations/0040_review_to_queue.py
new file mode 100644
index 0000000..7ef9fc9
--- /dev/null
+++ b/api/migrations/0040_review_to_queue.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.16 on 2018-11-20 06:33
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('api', '0039_fix_project_attr_help_texts'),
+    ]
+
+    operations = [
+        migrations.RenameModel('Review', 'Queue'),
+    ]
diff --git a/api/migrations/0041_auto_20181120_0636.py b/api/migrations/0041_auto_20181120_0636.py
new file mode 100644
index 0000000..0b91cf0
--- /dev/null
+++ b/api/migrations/0041_auto_20181120_0636.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.16 on 2018-11-20 06:36
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('api', '0040_review_to_queue'),
+    ]
+
+    operations = [
+        migrations.RenameField(
+            model_name='message',
+            old_name='reviews',
+            new_name='queues',
+        ),
+        migrations.AddField(
+            model_name='queue',
+            name='name',
+            field=models.CharField(default='accept', help_text='Name of the queue', max_length=1024),
+            preserve_default=False,
+        ),
+        migrations.RemoveField(
+            model_name='queue',
+            name='accept',
+        ),
+        migrations.AlterUniqueTogether(
+            name='queue',
+            unique_together=set([('user', 'message', 'name')]),
+        ),
+        migrations.AlterIndexTogether(
+            name='queue',
+            index_together=set([('user', 'message')]),
+        ),
+    ]
diff --git a/api/models.py b/api/models.py
index ea3b654..3b57c73 100644
--- a/api/models.py
+++ b/api/models.py
@@ -436,11 +436,17 @@ def HeaderFieldModel(**args):
     return models.CharField(max_length=4096, **args)
 
 
-class Review(models.Model):
+class Queue(models.Model):
     user = models.ForeignKey(User)
     message = models.ForeignKey('Message')
-    accept = models.BooleanField()
+    # Special purposed queues:
+    # accept: When user marked series as "accepted"
+    # reject: When user marked series as "rejected"
+    name = models.CharField(max_length=1024, help_text="Name of the queue")
 
+    class Meta:
+        unique_together = ('user', 'message', 'name')
+        index_together = [('user', 'message')]
 
 class Message(models.Model):
     """ Patch email message """
@@ -479,7 +485,7 @@ class Message(models.Model):
     # number of patches we've got if is_series_head
     num_patches = models.IntegerField(null=False, default=-1, blank=True)
 
-    reviews = models.ManyToManyField(User, blank=True, through=Review)
+    queues = models.ManyToManyField(User, blank=True, through=Queue)
 
     objects = MessageManager()
 
diff --git a/api/search.py b/api/search.py
index 9b41641..6942ef0 100644
--- a/api/search.py
+++ b/api/search.py
@@ -8,7 +8,7 @@
 # This work is licensed under the MIT License.  Please see the LICENSE file or
 # http://opensource.org/licenses/MIT.
 
-from .models import Message, MessageProperty, MessageResult, Result, Review
+from .models import Message, MessageProperty, MessageResult, Result, Queue
 from functools import reduce
 from django.db.models import Q
 
@@ -247,7 +247,7 @@ Search text keyword in the email message. Example:
             q = Q(user=user, **kwargs)
         else:
             q = Q(user__username=username, **kwargs)
-        return self._make_filter_subquery(Review, q)
+        return self._make_filter_subquery(Queue, q)
 
     def _make_filter(self, term, user):
         if term.startswith("age:"):
@@ -292,13 +292,13 @@ Search text keyword in the email message. Example:
             return self._make_filter_result(term[8:], status=Result.RUNNING)
         elif term.startswith("ack:") or term.startswith("accept:") or term.startswith("accepted:"):
             username = term[term.find(":") + 1:]
-            return self._make_filter_review(username, user, accept=True)
+            return self._make_filter_review(username, user, name="accept")
         elif term.startswith("nack:") or term.startswith("reject:") or term.startswith("rejected:"):
             username = term[term.find(":") + 1:]
-            return self._make_filter_review(username, user, accept=False)
+            return self._make_filter_review(username, user, name="reject")
         elif term.startswith("review:") or term.startswith("reviewed:"):
             username = term[term.find(":") + 1:]
-            return self._make_filter_review(username, user)
+            return self._make_filter_review(username, user, name="accept")
         elif term.startswith("project:"):
             cond = term[term.find(":") + 1:]
             self._projects.add(cond)
diff --git a/mods/maintainer.py b/mods/maintainer.py
index a3874de..7f4f5fe 100644
--- a/mods/maintainer.py
+++ b/mods/maintainer.py
@@ -12,7 +12,7 @@ from django.conf.urls import url
 from django.http import Http404, HttpResponseRedirect
 from django.urls import reverse
 from mod import PatchewModule
-from api.models import Message, Review
+from api.models import Message, Queue
 
 class MaintainerModule(PatchewModule):
     """ Project maintainer related tasks """
@@ -25,8 +25,12 @@ class MaintainerModule(PatchewModule):
         msg = Message.objects.find_series(message_id)
         if not msg:
             raise Http404("Series not found")
-        Review.objects.update_or_create(user=request.user, message=msg,
-                                        defaults = { 'accept': accept })
+        if accept:
+            to_create, to_delete = 'accept', 'reject'
+        else:
+            to_create, to_delete = 'reject', 'accept'
+        Queue.objects.filter(user=request.user, message=msg, name=to_delete).delete()
+        Queue.objects.get_or_create(user=request.user, message=msg, name=to_create)
         return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
 
     def _delete_review(self, request, message_id):
@@ -35,7 +39,8 @@ class MaintainerModule(PatchewModule):
         msg = Message.objects.find_series(message_id)
         if not msg:
             raise Http404("Series not found")
-        r = Review.objects.filter(user=request.user, message=msg)
+        r = Queue.objects.filter(user=request.user, message=msg,
+                                 name__in=['accept', 'reject'])
         r.delete()
         return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
 
@@ -96,11 +101,9 @@ class MaintainerModule(PatchewModule):
                                           "icon": "check",
                                           "title": "Mark series as merged"})
 
-        try:
-            r = Review.objects.get(user=request.user, message=message)
-        except Review.DoesNotExist:
-            r = None
-        if r and r.accept:
+        r = Queue.objects.filter(user=request.user, message=message,
+                                 name__in=['accept', 'reject']).first()
+        if r and r.name == 'accept':
             message.extra_status.append({
                 "icon": "fa-check",
                 "html": 'The series is marked for merging'
@@ -112,7 +115,7 @@ class MaintainerModule(PatchewModule):
                                           "icon": "check",
                                           "title": "Mark series as accepted"})
 
-        if r and not r.accept:
+        if r and r.name == 'reject':
             message.extra_status.append({
                 "icon": "fa-times",
                 "html": 'The series is marked as rejected'
-- 
2.17.2




More information about the Patchew-devel mailing list