From 9b38f42272994350a6bb58da796dcca86ee628d9 Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Mon, 30 Sep 2019 15:17:03 +0200 Subject: Migrate nominations to new Nomination model Before the migration to Django, we stored meta data on a nomination, such as the `reason` and `end_reason`, in the infraction table using "note" infractions, using a special prefix for the `reason`. We have since decided to move nominations out of the infraction context by creating a special `Nomination` model. However, given the complexity of the data migration, we did not yet migrate the old nomination data to this new model. This commit migrates that data by performing a data migration. The data migration works as follows: - Query all nomination data in chronological order; - Replay all nominations and add them to the `Nomination` model; - Delete the now obsolete `Infraction` entry. In addition, this commit also adds a useful string representation for `Nomination` objects. --- pydis_site/apps/api/tests/test_models.py | 36 +++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/tests/test_models.py b/pydis_site/apps/api/tests/test_models.py index 2120b056..aaf12045 100644 --- a/pydis_site/apps/api/tests/test_models.py +++ b/pydis_site/apps/api/tests/test_models.py @@ -3,11 +3,18 @@ from datetime import datetime as dt, timezone from django.test import SimpleTestCase from ..models import ( - DeletedMessage, DocumentationLink, - Infraction, Message, - MessageDeletionContext, ModelReprMixin, - OffTopicChannelName, Reminder, - Role, Tag, User + DeletedMessage, + DocumentationLink, + Infraction, + Message, + MessageDeletionContext, + ModelReprMixin, + Nomination, + OffTopicChannelName, + Reminder, + Role, + Tag, + User ) @@ -27,6 +34,19 @@ class ReprMixinTests(SimpleTestCase): class StringDunderMethodTests(SimpleTestCase): def setUp(self): + self.nomination = Nomination( + id=123, + actor=User( + id=9876, name='Mr. Hemlock', + discriminator=6666, avatar_hash=None + ), + user=User( + id=9876, name="Hemlock's Cat", + discriminator=7777, avatar_hash=None + ), + reason="He purrrrs like the best!", + ) + self.objects = ( DeletedMessage( id=45, @@ -102,3 +122,9 @@ class StringDunderMethodTests(SimpleTestCase): def test_returns_string(self): for instance in self.objects: self.assertIsInstance(str(instance), str) + + def test_nomination_str_representation(self): + self.assertEqual( + "Nomination of Hemlock's Cat#7777 (active)", + str(self.nomination) + ) -- cgit v1.2.3 From 6bd2ea4a1d50ea1cecbd4b3a996523425efbd65b Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 19:45:34 +0200 Subject: Allow viewing log entries in the Django Admin. --- pydis_site/apps/api/admin.py | 31 +++++++++++++++++++++---- pydis_site/apps/api/models/log_entry.py | 13 +++++++++++ pydis_site/apps/api/tests/test_models.py | 40 +++++++++++++++++++++++++++----- 3 files changed, 73 insertions(+), 11 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index c3784317..2c41d624 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -1,18 +1,39 @@ from django.contrib import admin from .models import ( - BotSetting, DeletedMessage, - DocumentationLink, Infraction, - MessageDeletionContext, Nomination, - OffTopicChannelName, Role, - Tag, User + BotSetting, + DeletedMessage, + DocumentationLink, + Infraction, + LogEntry, + MessageDeletionContext, + Nomination, + OffTopicChannelName, + Role, + Tag, + User ) +class LogEntryAdmin(admin.ModelAdmin): + """Allows viewing logs in the Django Admin without allowing edits.""" + + readonly_fields = ( + 'application', + 'logger_name', + 'timestamp', + 'level', + 'module', + 'line', + 'message' + ) + + admin.site.register(BotSetting) admin.site.register(DeletedMessage) admin.site.register(DocumentationLink) admin.site.register(Infraction) +admin.site.register(LogEntry, LogEntryAdmin) admin.site.register(MessageDeletionContext) admin.site.register(Nomination) admin.site.register(OffTopicChannelName) diff --git a/pydis_site/apps/api/models/log_entry.py b/pydis_site/apps/api/models/log_entry.py index acd7953a..55a022d7 100644 --- a/pydis_site/apps/api/models/log_entry.py +++ b/pydis_site/apps/api/models/log_entry.py @@ -1,9 +1,15 @@ +import textwrap + from django.db import models from django.utils import timezone from pydis_site.apps.api.models.utils import ModelReprMixin +# Used to shorten the timestamp length in the Django Admin. +TIMESTAMP_WITH_SECONDS_LENGTH = len('YYYY-MM-DD HH:MM:SS') + + class LogEntry(ModelReprMixin, models.Model): """A log entry generated by one of the PyDis applications.""" @@ -48,3 +54,10 @@ class LogEntry(ModelReprMixin, models.Model): message = models.TextField( help_text="The textual content of the log line." ) + + def __str__(self) -> str: + timestamp = str(self.timestamp)[:TIMESTAMP_WITH_SECONDS_LENGTH] + message = textwrap.shorten(self.message, width=140) + level = self.level[:4].upper() + + return f'{timestamp} | {self.application} | {level} | {message}' diff --git a/pydis_site/apps/api/tests/test_models.py b/pydis_site/apps/api/tests/test_models.py index 2120b056..6011ba21 100644 --- a/pydis_site/apps/api/tests/test_models.py +++ b/pydis_site/apps/api/tests/test_models.py @@ -1,13 +1,21 @@ -from datetime import datetime as dt, timezone +from datetime import datetime as dt from django.test import SimpleTestCase +from django.utils import timezone from ..models import ( - DeletedMessage, DocumentationLink, - Infraction, Message, - MessageDeletionContext, ModelReprMixin, - OffTopicChannelName, Reminder, - Role, Tag, User + DeletedMessage, + DocumentationLink, + Infraction, + LogEntry, + Message, + MessageDeletionContext, + ModelReprMixin, + OffTopicChannelName, + Reminder, + Role, + Tag, + User ) @@ -25,6 +33,26 @@ class ReprMixinTests(SimpleTestCase): self.assertEqual(repr(self.klass), expected) +class LogEntryStringDunderTests(SimpleTestCase): + def setUp(self): + self.entry = LogEntry( + application='bot', + logger_name='bot.rules.antispam', + timestamp=timezone.now(), + level='debug', + module='bot.rules.antispam', + line=44, + message="One day computers might become useful." + ) + + def test_str_shows_content(self): + tokens = str(self.entry).split(' | ') + _timestamp, app, level, message = tokens + self.assertEqual(app, 'bot') + self.assertEqual(level, 'DEBU'), + self.assertEqual(message, "One day computers might become useful.") + + class StringDunderMethodTests(SimpleTestCase): def setUp(self): self.objects = ( -- cgit v1.2.3 From 6fa19e09823680c93acd795c52f6f511a1ae9663 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 19:53:21 +0200 Subject: Use multi-column output from Django. --- pydis_site/apps/api/admin.py | 1 + pydis_site/apps/api/models/log_entry.py | 11 ----------- pydis_site/apps/api/tests/test_models.py | 21 --------------------- 3 files changed, 1 insertion(+), 32 deletions(-) (limited to 'pydis_site/apps/api/tests') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 2c41d624..8a9b6051 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -18,6 +18,7 @@ from .models import ( class LogEntryAdmin(admin.ModelAdmin): """Allows viewing logs in the Django Admin without allowing edits.""" + list_display = ('timestamp', 'application', 'level', 'message') readonly_fields = ( 'application', 'logger_name', diff --git a/pydis_site/apps/api/models/log_entry.py b/pydis_site/apps/api/models/log_entry.py index cb7275f9..9717c700 100644 --- a/pydis_site/apps/api/models/log_entry.py +++ b/pydis_site/apps/api/models/log_entry.py @@ -6,10 +6,6 @@ from django.utils import timezone from pydis_site.apps.api.models.utils import ModelReprMixin -# Used to shorten the timestamp length in the Django Admin. -TIMESTAMP_WITH_SECONDS_LENGTH = len('YYYY-MM-DD HH:MM:SS') - - class LogEntry(ModelReprMixin, models.Model): """A log entry generated by one of the PyDis applications.""" @@ -55,13 +51,6 @@ class LogEntry(ModelReprMixin, models.Model): help_text="The textual content of the log line." ) - def __str__(self) -> str: - timestamp = str(self.timestamp)[:TIMESTAMP_WITH_SECONDS_LENGTH] - message = textwrap.shorten(self.message, width=140) - level = self.level[:4].upper() - - return f'{timestamp} | {self.application} | {level} | {message}' - class Meta: """Customizes the default generated plural name to valid English.""" diff --git a/pydis_site/apps/api/tests/test_models.py b/pydis_site/apps/api/tests/test_models.py index 6011ba21..6a3ef085 100644 --- a/pydis_site/apps/api/tests/test_models.py +++ b/pydis_site/apps/api/tests/test_models.py @@ -7,7 +7,6 @@ from ..models import ( DeletedMessage, DocumentationLink, Infraction, - LogEntry, Message, MessageDeletionContext, ModelReprMixin, @@ -33,26 +32,6 @@ class ReprMixinTests(SimpleTestCase): self.assertEqual(repr(self.klass), expected) -class LogEntryStringDunderTests(SimpleTestCase): - def setUp(self): - self.entry = LogEntry( - application='bot', - logger_name='bot.rules.antispam', - timestamp=timezone.now(), - level='debug', - module='bot.rules.antispam', - line=44, - message="One day computers might become useful." - ) - - def test_str_shows_content(self): - tokens = str(self.entry).split(' | ') - _timestamp, app, level, message = tokens - self.assertEqual(app, 'bot') - self.assertEqual(level, 'DEBU'), - self.assertEqual(message, "One day computers might become useful.") - - class StringDunderMethodTests(SimpleTestCase): def setUp(self): self.objects = ( -- cgit v1.2.3