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. --- ...inations_from_infraction_to_nomination_model.py | 64 ++++++++++++++++++++++ pydis_site/apps/api/models/bot/nomination.py | 5 ++ pydis_site/apps/api/tests/test_models.py | 36 ++++++++++-- 3 files changed, 100 insertions(+), 5 deletions(-) create mode 100644 pydis_site/apps/api/migrations/0044_migrate_nominations_from_infraction_to_nomination_model.py (limited to 'pydis_site') diff --git a/pydis_site/apps/api/migrations/0044_migrate_nominations_from_infraction_to_nomination_model.py b/pydis_site/apps/api/migrations/0044_migrate_nominations_from_infraction_to_nomination_model.py new file mode 100644 index 00000000..a56450c0 --- /dev/null +++ b/pydis_site/apps/api/migrations/0044_migrate_nominations_from_infraction_to_nomination_model.py @@ -0,0 +1,64 @@ +# Generated by Django 2.2.5 on 2019-09-30 12:15 +import logging + +from django.db import migrations +from django.db.models import Q + +log = logging.getLogger('nomination_migration') + + +def migrate_nominations_to_new_model(apps, schema_editor): + """ + Migrations nominations from the infraction model to the nomination model. + + This migration works by replaying the nomination history in chronological order, adding and + ending nominations as we've recorded them. + """ + Infraction = apps.get_model('api', 'Infraction') + Nomination = apps.get_model('api', 'Nomination') + + all_nominations = ( + Q(reason__startswith="Helper nomination:") | Q(reason__startswith="Unwatched (talent-pool):") + ) + + for infraction in Infraction.objects.filter(all_nominations).order_by('inserted_at'): + if infraction.reason.startswith("Helper nomination:"): + if Nomination.objects.filter(user=infraction.user, active=True).exists(): + log.error( + f"User `{infraction.user.id}` already has an active nomination, aborting." + ) + continue + nomination = Nomination( + user=infraction.user, + inserted_at=infraction.inserted_at, + reason=infraction.reason[19:], # Strip "Helper nomination: " prefix + actor=infraction.actor, + active=True, + ) + nomination.save() + infraction.delete() + elif infraction.reason.startswith("Unwatched (talent-pool):"): + if not Nomination.objects.filter(user=infraction.user, active=True).exists(): + log.error( + f"User `{infraction.user.id}` has no active nomination, can't end it!" + ) + continue + nomination = Nomination.objects.get(user=infraction.user, active=True) + nomination.end_reason = infraction.reason[25:] # Strip "Unwatched (talent-pool):" + nomination.ended_at = infraction.inserted_at + nomination.active = False + nomination.save() + infraction.delete() + else: + log.error(f"I don't understand this infraction: {infraction}") + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0043_infraction_hidden_warnings_to_notes'), + ] + + operations = [ + migrations.RunPython(migrate_nominations_to_new_model), + ] diff --git a/pydis_site/apps/api/models/bot/nomination.py b/pydis_site/apps/api/models/bot/nomination.py index 8a8f4d36..cd9951aa 100644 --- a/pydis_site/apps/api/models/bot/nomination.py +++ b/pydis_site/apps/api/models/bot/nomination.py @@ -39,3 +39,8 @@ class Nomination(ModelReprMixin, models.Model): help_text="When the nomination was ended.", null=True ) + + def __str__(self): + """Representation that makes the target and state of the nomination immediately evident.""" + status = "active" if self.active else "ended" + return f"Nomination of {self.user} ({status})" 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 7136018c73028142193c00c19ddf69ea3d602d5a Mon Sep 17 00:00:00 2001 From: ByteCommander Date: Tue, 8 Oct 2019 15:37:21 +0200 Subject: Add favicons; workaround for gitattributes --- .gitattributes | 10 +++++++++- .../static/favicons/android-chrome-192x192.png | Bin 0 -> 1629 bytes .../static/favicons/android-chrome-512x512.png | Bin 0 -> 3948 bytes pydis_site/static/favicons/apple-touch-icon.png | Bin 0 -> 1553 bytes pydis_site/static/favicons/browserconfig.xml | 9 +++++++++ pydis_site/static/favicons/favicon-16x16.png | Bin 0 -> 402 bytes pydis_site/static/favicons/favicon-32x32.png | Bin 0 -> 543 bytes pydis_site/static/favicons/favicon.ico | Bin 0 -> 7406 bytes pydis_site/static/favicons/mstile-150x150.png | Bin 0 -> 1600 bytes pydis_site/static/favicons/safari-pinned-tab.svg | 1 + pydis_site/static/favicons/site.webmanifest | 19 +++++++++++++++++++ pydis_site/templates/base/base.html | 13 +++++++++++++ 12 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 pydis_site/static/favicons/android-chrome-192x192.png create mode 100644 pydis_site/static/favicons/android-chrome-512x512.png create mode 100644 pydis_site/static/favicons/apple-touch-icon.png create mode 100644 pydis_site/static/favicons/browserconfig.xml create mode 100644 pydis_site/static/favicons/favicon-16x16.png create mode 100644 pydis_site/static/favicons/favicon-32x32.png create mode 100644 pydis_site/static/favicons/favicon.ico create mode 100644 pydis_site/static/favicons/mstile-150x150.png create mode 100644 pydis_site/static/favicons/safari-pinned-tab.svg create mode 100644 pydis_site/static/favicons/site.webmanifest (limited to 'pydis_site') diff --git a/.gitattributes b/.gitattributes index a90a0a96..e9e08359 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,11 @@ # Declare files that will always have LF line endings on checkout # This prevents git on Windows from automatically inserting CRLF line endings -* text=auto eol=lf \ No newline at end of file +* text=auto eol=lf + +# Specifically declare known binary files to avoid problems with Git versions +# before 2.10, where the 'eol' setting has higher priority than 'text=auto', +# causing binary files to get normalized and corrupted otherwise. +# See e.g. https://stackoverflow.com/a/38588882/4464570 +*.png binary +*.whl binary + diff --git a/pydis_site/static/favicons/android-chrome-192x192.png b/pydis_site/static/favicons/android-chrome-192x192.png new file mode 100644 index 00000000..fbcc75ca Binary files /dev/null and b/pydis_site/static/favicons/android-chrome-192x192.png differ diff --git a/pydis_site/static/favicons/android-chrome-512x512.png b/pydis_site/static/favicons/android-chrome-512x512.png new file mode 100644 index 00000000..1381841a Binary files /dev/null and b/pydis_site/static/favicons/android-chrome-512x512.png differ diff --git a/pydis_site/static/favicons/apple-touch-icon.png b/pydis_site/static/favicons/apple-touch-icon.png new file mode 100644 index 00000000..a0ac158f Binary files /dev/null and b/pydis_site/static/favicons/apple-touch-icon.png differ diff --git a/pydis_site/static/favicons/browserconfig.xml b/pydis_site/static/favicons/browserconfig.xml new file mode 100644 index 00000000..c0081b1d --- /dev/null +++ b/pydis_site/static/favicons/browserconfig.xml @@ -0,0 +1,9 @@ + + + + + + #da532c + + + diff --git a/pydis_site/static/favicons/favicon-16x16.png b/pydis_site/static/favicons/favicon-16x16.png new file mode 100644 index 00000000..1a69b5b0 Binary files /dev/null and b/pydis_site/static/favicons/favicon-16x16.png differ diff --git a/pydis_site/static/favicons/favicon-32x32.png b/pydis_site/static/favicons/favicon-32x32.png new file mode 100644 index 00000000..a1cf0f9f Binary files /dev/null and b/pydis_site/static/favicons/favicon-32x32.png differ diff --git a/pydis_site/static/favicons/favicon.ico b/pydis_site/static/favicons/favicon.ico new file mode 100644 index 00000000..bf9a36ff Binary files /dev/null and b/pydis_site/static/favicons/favicon.ico differ diff --git a/pydis_site/static/favicons/mstile-150x150.png b/pydis_site/static/favicons/mstile-150x150.png new file mode 100644 index 00000000..1e9bf200 Binary files /dev/null and b/pydis_site/static/favicons/mstile-150x150.png differ diff --git a/pydis_site/static/favicons/safari-pinned-tab.svg b/pydis_site/static/favicons/safari-pinned-tab.svg new file mode 100644 index 00000000..79cc94fa --- /dev/null +++ b/pydis_site/static/favicons/safari-pinned-tab.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pydis_site/static/favicons/site.webmanifest b/pydis_site/static/favicons/site.webmanifest new file mode 100644 index 00000000..66b4e5a5 --- /dev/null +++ b/pydis_site/static/favicons/site.webmanifest @@ -0,0 +1,19 @@ +{ + "name": "Python Discord", + "short_name": "Python Discord", + "icons": [ + { + "src": "/static/favicons/android-chrome-192x192.png?v=8jMYXa7g8e", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/static/favicons/android-chrome-512x512.png?v=8jMYXa7g8e", + "sizes": "512x512", + "type": "image/png" + } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/pydis_site/templates/base/base.html b/pydis_site/templates/base/base.html index a419521c..6a0da0ae 100644 --- a/pydis_site/templates/base/base.html +++ b/pydis_site/templates/base/base.html @@ -11,6 +11,19 @@ + {# Generated with https://realfavicongenerator.net/ #} + + + + + + + + + + + + Python Discord | {% block title %}Website{% endblock %} {% bulma %} -- 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') 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 87105f2c31e5384428e9f44a146b60d2f95fb67b Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 19:49:07 +0200 Subject: Pluralize properly. --- .../migrations/0044_add_plural_name_for_log_entry.py | 17 +++++++++++++++++ pydis_site/apps/api/models/log_entry.py | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py (limited to 'pydis_site') diff --git a/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py b/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py new file mode 100644 index 00000000..6f388179 --- /dev/null +++ b/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.3 on 2019-10-11 17:48 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0043_infraction_hidden_warnings_to_notes'), + ] + + operations = [ + migrations.AlterModelOptions( + name='logentry', + options={'verbose_name_plural': 'Log entries'}, + ), + ] diff --git a/pydis_site/apps/api/models/log_entry.py b/pydis_site/apps/api/models/log_entry.py index 55a022d7..cb7275f9 100644 --- a/pydis_site/apps/api/models/log_entry.py +++ b/pydis_site/apps/api/models/log_entry.py @@ -61,3 +61,8 @@ class LogEntry(ModelReprMixin, models.Model): level = self.level[:4].upper() return f'{timestamp} | {self.application} | {level} | {message}' + + class Meta: + """Customizes the default generated plural name to valid English.""" + + verbose_name_plural = 'Log entries' -- 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') 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 From 8309c94fb2b79ee87b1c2c66533eeb7924e9062f Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 19:57:21 +0200 Subject: Group fieldsets. --- pydis_site/apps/api/admin.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 8a9b6051..2a44eb7a 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -19,6 +19,11 @@ class LogEntryAdmin(admin.ModelAdmin): """Allows viewing logs in the Django Admin without allowing edits.""" list_display = ('timestamp', 'application', 'level', 'message') + fieldsets = ( + ('Overview', {'fields': ('timestamp', 'application', 'logger_name')}), + ('Metadata', {'fields': ('level', 'module', 'line')}), + ('Contents', {'fields': ('message',)}) + ) readonly_fields = ( 'application', 'logger_name', -- cgit v1.2.3 From 195d66b310c34e2b0f548a5c0cb1d8d1d69f1f76 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 20:07:41 +0200 Subject: Remove old import. --- pydis_site/apps/api/models/log_entry.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/models/log_entry.py b/pydis_site/apps/api/models/log_entry.py index 9717c700..488af48e 100644 --- a/pydis_site/apps/api/models/log_entry.py +++ b/pydis_site/apps/api/models/log_entry.py @@ -1,5 +1,3 @@ -import textwrap - from django.db import models from django.utils import timezone -- cgit v1.2.3 From f1584220c5ecdcddb11650fe2764dd47075369fd Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 20:49:51 +0200 Subject: Allow filtering through metadata, and searching by message. --- pydis_site/apps/api/admin.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 2a44eb7a..d82ce186 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -24,6 +24,8 @@ class LogEntryAdmin(admin.ModelAdmin): ('Metadata', {'fields': ('level', 'module', 'line')}), ('Contents', {'fields': ('message',)}) ) + list_filter = ('application', 'level', 'timestamp') + search_fields = ('message',) readonly_fields = ( 'application', 'logger_name', -- cgit v1.2.3 From b3aa11bfff29ec1083fbe6217f5f6a499a282bd3 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 21:41:22 +0200 Subject: Deny `LogEntry` deletion. --- pydis_site/apps/api/admin.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index d82ce186..ed483897 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.""" + actions = None list_display = ('timestamp', 'application', 'level', 'message') fieldsets = ( ('Overview', {'fields': ('timestamp', 'application', 'logger_name')}), @@ -36,6 +37,10 @@ class LogEntryAdmin(admin.ModelAdmin): 'message' ) + def has_delete_permission(self, request, obj=None) -> bool: + """Deny LogEntry deletion.""" + return False + admin.site.register(BotSetting) admin.site.register(DeletedMessage) -- cgit v1.2.3 From 879d807cf06f52dd54b859ac4610f88e922111a3 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 21:46:29 +0200 Subject: Improve formatting for `has_delete_permission`, typespec. --- pydis_site/apps/api/admin.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index ed483897..2600b410 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -1,4 +1,7 @@ +from typing import Optional + from django.contrib import admin +from django.http import HttpRequest from .models import ( BotSetting, @@ -37,7 +40,11 @@ class LogEntryAdmin(admin.ModelAdmin): 'message' ) - def has_delete_permission(self, request, obj=None) -> bool: + def has_delete_permission( + self, + request: HttpRequest, + obj: Optional[LogEntry] = None + ) -> bool: """Deny LogEntry deletion.""" return False -- cgit v1.2.3 From 673cc3bd89056d288451085488ae6f1f67cc1e21 Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 21:47:58 +0200 Subject: Resolve migration merge conflicts. --- .../migrations/0044_add_plural_name_for_log_entry.py | 17 ----------------- .../migrations/0045_add_plural_name_for_log_entry.py | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 17 deletions(-) delete mode 100644 pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py create mode 100644 pydis_site/apps/api/migrations/0045_add_plural_name_for_log_entry.py (limited to 'pydis_site') diff --git a/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py b/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py deleted file mode 100644 index 6f388179..00000000 --- a/pydis_site/apps/api/migrations/0044_add_plural_name_for_log_entry.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.3 on 2019-10-11 17:48 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0043_infraction_hidden_warnings_to_notes'), - ] - - operations = [ - migrations.AlterModelOptions( - name='logentry', - options={'verbose_name_plural': 'Log entries'}, - ), - ] diff --git a/pydis_site/apps/api/migrations/0045_add_plural_name_for_log_entry.py b/pydis_site/apps/api/migrations/0045_add_plural_name_for_log_entry.py new file mode 100644 index 00000000..6b9933d8 --- /dev/null +++ b/pydis_site/apps/api/migrations/0045_add_plural_name_for_log_entry.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.3 on 2019-10-11 17:48 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0044_migrate_nominations_from_infraction_to_nomination_model'), + ] + + operations = [ + migrations.AlterModelOptions( + name='logentry', + options={'verbose_name_plural': 'Log entries'}, + ), + ] -- cgit v1.2.3 From 749f1576f3912846d99ccc59e2ba4acb847a737a Mon Sep 17 00:00:00 2001 From: Johannes Christ Date: Fri, 11 Oct 2019 21:57:05 +0200 Subject: Deny manual `LogEntry` creation. --- pydis_site/apps/api/admin.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'pydis_site') diff --git a/pydis_site/apps/api/admin.py b/pydis_site/apps/api/admin.py index 2600b410..059f52eb 100644 --- a/pydis_site/apps/api/admin.py +++ b/pydis_site/apps/api/admin.py @@ -40,6 +40,10 @@ class LogEntryAdmin(admin.ModelAdmin): 'message' ) + def has_add_permission(self, request: HttpRequest) -> bool: + """Deny manual LogEntry creation.""" + return False + def has_delete_permission( self, request: HttpRequest, -- cgit v1.2.3