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 1ced4fc37f2969765feac4f090d42148ad4377e9 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Tue, 1 Oct 2019 22:55:19 +0200 Subject: Update the landing page text. The new text was written by Tizzysaurus in his website cleanup project, and lifted from his google doc. --- pydis_site/templates/home/index.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'pydis_site') diff --git a/pydis_site/templates/home/index.html b/pydis_site/templates/home/index.html index 205e92ff..bccea71a 100644 --- a/pydis_site/templates/home/index.html +++ b/pydis_site/templates/home/index.html @@ -19,21 +19,21 @@

We're a large community focused around the Python programming language. - We believe anyone can learn programming, and are very dedicated to helping - novice developers take their first steps into the world of code. We also + We believe anyone can learn to code, and are very dedicated to helping + novice developers take their first steps into the world of programming. We also attract a lot of expert developers who are seeking friendships, collaborators, - or looking to hone their craft by teaching and getting involved in the community. + or to hone their craft by teaching and getting involved with the community.

- We organise regular community events like code jams, open source hackathons, - seasonal events and community challenges. Through our sponsorships and with - help from donations, we are even able to award prizes to the winners of our events. + We organise regular community events such as code jams, open-source hackathons, + seasonal events and community challenges. Through our sponsorships, and with + the help from donations, many of our events even have prizes to win!

You can find help with most Python-related problems in one of our help channels. - Our staff of nearly 50 dedicated expert Helpers are available around the clock + Our staff of over 50 dedicated expert Helpers, are available around the clock in every timezone. Whether you're looking to learn the language or working on a complex project, we've got someone who can help you if you get stuck.

-- cgit v1.2.3 From 0c43428ef86666dfb9d4baf119b0a30ba8dbe5cf Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 5 Oct 2019 09:20:23 +0200 Subject: Address code review from Scragly and Mark. Makes various minor changes to commas and formulations. --- pydis_site/templates/home/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'pydis_site') diff --git a/pydis_site/templates/home/index.html b/pydis_site/templates/home/index.html index bccea71a..bf217fe8 100644 --- a/pydis_site/templates/home/index.html +++ b/pydis_site/templates/home/index.html @@ -22,18 +22,18 @@ We believe anyone can learn to code, and are very dedicated to helping novice developers take their first steps into the world of programming. We also attract a lot of expert developers who are seeking friendships, collaborators, - or to hone their craft by teaching and getting involved with the community. + and who wish to hone their craft by teaching and getting involved in the community.

We organise regular community events such as code jams, open-source hackathons, - seasonal events and community challenges. Through our sponsorships, and with - the help from donations, many of our events even have prizes to win! + seasonal events, and community challenges. Through our sponsorships and donations, + many of our events even have prizes to win!

You can find help with most Python-related problems in one of our help channels. - Our staff of over 50 dedicated expert Helpers, are available around the clock + Our staff of over 50 dedicated expert Helpers are available around the clock in every timezone. Whether you're looking to learn the language or working on a complex project, we've got someone who can help you if you get stuck.

-- cgit v1.2.3 From c44b5a740a69de5b479100f4c023bb80db8605a6 Mon Sep 17 00:00:00 2001 From: Leon Sandøy Date: Sat, 5 Oct 2019 17:47:05 +0200 Subject: Make the homepage paragraphier. --- pydis_site/templates/home/index.html | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'pydis_site') diff --git a/pydis_site/templates/home/index.html b/pydis_site/templates/home/index.html index bf217fe8..45fb56e9 100644 --- a/pydis_site/templates/home/index.html +++ b/pydis_site/templates/home/index.html @@ -23,15 +23,13 @@ novice developers take their first steps into the world of programming. We also attract a lot of expert developers who are seeking friendships, collaborators, and who wish to hone their craft by teaching and getting involved in the community. - -

- +

+

We organise regular community events such as code jams, open-source hackathons, seasonal events, and community challenges. Through our sponsorships and donations, many of our events even have prizes to win! - -

- +

+

You can find help with most Python-related problems in one of our help channels. Our staff of over 50 dedicated expert Helpers are available around the clock in every timezone. Whether you're looking to learn the language or working on a -- 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