[Patchew-devel] [PATCH 3/9] add topic model
Paolo Bonzini
pbonzini at redhat.com
Thu Jan 16 15:09:03 UTC 2020
This will be used to allow grouping together even series whose subject
has changed. It will also replace the is_series_head field.
To migrate the database, create a new topic for every stripped_subject.
Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
---
api/migrations/0053_auto_20200116_0955.py | 27 +++++++++++++
api/migrations/0054_populate_topic.py | 29 ++++++++++++++
api/models.py | 46 ++++++++++++++++++++---
tests/test_message.py | 30 +++++++++++++++
4 files changed, 126 insertions(+), 6 deletions(-)
create mode 100644 api/migrations/0053_auto_20200116_0955.py
create mode 100644 api/migrations/0054_populate_topic.py
diff --git a/api/migrations/0053_auto_20200116_0955.py b/api/migrations/0053_auto_20200116_0955.py
new file mode 100644
index 0000000..3fae555
--- /dev/null
+++ b/api/migrations/0053_auto_20200116_0955.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.20 on 2020-01-16 09:55
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0052_auto_20190418_1357'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Topic',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ],
+ ),
+ migrations.AddField(
+ model_name='message',
+ name='topic',
+ field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='api.Topic'),
+ ),
+ ]
diff --git a/api/migrations/0054_populate_topic.py b/api/migrations/0054_populate_topic.py
new file mode 100644
index 0000000..359f00e
--- /dev/null
+++ b/api/migrations/0054_populate_topic.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations
+
+
+def topic_fill(apps, schema_editor):
+ Message = apps.get_model("api", "Message")
+ Topic = apps.get_model("api", "Topic")
+ for record in (
+ Message.objects.filter(is_series_head=True)
+ .values("stripped_subject")
+ .distinct()
+ ):
+ topic = Topic()
+ topic.save()
+ topic_subject = record["stripped_subject"]
+ Message.objects.filter(
+ is_series_head=True, stripped_subject=topic_subject
+ ).update(topic=topic)
+
+
+class Migration(migrations.Migration):
+ dependencies = [("api", "0053_auto_20200116_0955")]
+
+ operations = [
+ migrations.RunPython(topic_fill, reverse_code=migrations.RunPython.noop)
+ ]
diff --git a/api/models.py b/api/models.py
index 81bc167..6f4ea4b 100644
--- a/api/models.py
+++ b/api/models.py
@@ -457,7 +457,11 @@ class MessageManager(models.Manager):
msg.stripped_subject = m.get_subject(strip_tags=True)
msg.version = m.get_version()
msg.prefixes = m.get_prefixes()
- msg.is_series_head = m.is_series_head()
+ msg.is_series_head = False
+ if m.is_series_head():
+ msg.is_series_head = True
+ msg.topic = Topic.objects.for_stripped_subject(msg.stripped_subject)
+
msg.is_patch = m.is_patch()
msg.patch_num = m.get_num()[0]
msg.project = project
@@ -477,18 +481,25 @@ class MessageManager(models.Manager):
projects = [Project.object.get(name=project_name)]
else:
projects = find_message_projects(m)
+ stripped_subject = m.get_subject(strip_tags=True)
+ is_series_head = m.is_series_head()
for p in projects:
msg = Message(
message_id=msgid,
in_reply_to=m.get_in_reply_to() or "",
date=m.get_date(),
subject=m.get_subject(),
- stripped_subject=m.get_subject(strip_tags=True),
+ stripped_subject=stripped_subject,
version=m.get_version(),
sender=m.get_from(),
recipients=m.get_to() + m.get_cc(),
prefixes=m.get_prefixes(),
- is_series_head=m.is_series_head(),
+ is_series_head=is_series_head,
+ topic=(
+ Topic.objects.for_stripped_subject(stripped_subject)
+ if is_series_head
+ else None
+ ),
is_patch=m.is_patch(),
patch_num=m.get_num()[0],
)
@@ -520,6 +531,26 @@ class QueuedSeries(models.Model):
index_together = [("user", "message")]
+class TopicManager(models.Manager):
+ def for_stripped_subject(self, stripped_subject):
+ q = (
+ Message.objects.filter(stripped_subject=stripped_subject)
+ .order_by("date")
+ .reverse()[:1]
+ .values("topic")
+ )
+ if q:
+ topic = self.get(pk=q[0]["topic"])
+ else:
+ topic = Topic()
+ topic.save()
+ return topic
+
+
+class Topic(models.Model):
+ objects = TopicManager()
+
+
class Message(models.Model):
""" Patch email message """
@@ -555,6 +586,11 @@ class Message(models.Model):
is_tested = models.BooleanField(default=False)
is_reviewed = models.BooleanField(default=False)
+ # is series head if not Null
+ topic = models.ForeignKey(
+ "Topic", on_delete=models.CASCADE, null=True, db_index=True
+ )
+
# patch index number if is_patch
patch_num = models.PositiveSmallIntegerField(null=True, blank=True)
@@ -854,9 +890,7 @@ class Message(models.Model):
def get_alternative_revisions(self):
assert self.is_series_head
- return Message.objects.series_heads().filter(
- project=self.project, stripped_subject=self.stripped_subject
- )
+ return Message.objects.filter(project=self.project, topic=self.topic)
def set_complete(self):
if self.is_complete:
diff --git a/tests/test_message.py b/tests/test_message.py
index bc0a98d..3999948 100755
--- a/tests/test_message.py
+++ b/tests/test_message.py
@@ -20,6 +20,7 @@ from api.models import Message
class MessageTest(PatchewTestCase):
def setUp(self):
self.create_superuser()
+ self.p = self.add_project("QEMU", "qemu-devel at nongnu.org")
def test_0_second(self):
message = Message()
@@ -54,6 +55,35 @@ class MessageTest(PatchewTestCase):
asctime = message.get_asctime()
self.assertEqual(asctime, "Sat Oct 22 9:06:04 2016")
+ def test_topic_on_series_head(self):
+ self.cli_login()
+ self.cli_import("0004-multiple-patch-reviewed.mbox.gz")
+ m1 = Message.objects.get(
+ message_id="1469192015-16487-1-git-send-email-berrange at redhat.com"
+ )
+ assert m1.is_series_head
+ assert m1.topic is not None
+ m2 = Message.objects.get(
+ message_id="1469192015-16487-2-git-send-email-berrange at redhat.com"
+ )
+ assert not m2.is_series_head
+ assert m2.topic is None
+
+ def test_topic_assignment(self):
+ self.cli_login()
+ self.cli_import("0004-multiple-patch-reviewed.mbox.gz")
+ self.cli_import("0009-obsolete-by.mbox.gz")
+
+ m1 = Message.objects.get(message_id="20160628014747.20971-1-famz at redhat.com")
+ m2 = Message.objects.get(message_id="20160628014747.20971-2-famz at redhat.com")
+ m3 = Message.objects.get(message_id="20160628014747.20971-3-famz at redhat.com")
+ self.assertEqual(m1.topic, m2.topic)
+ self.assertEqual(m1.topic, m3.topic)
+ n = Message.objects.get(
+ message_id="1469192015-16487-1-git-send-email-berrange at redhat.com"
+ )
+ self.assertNotEqual(m1.topic, n.topic)
+
if __name__ == "__main__":
main()
--
2.21.0
More information about the Patchew-devel
mailing list