diff options
author | 2019-10-11 21:41:56 +0200 | |
---|---|---|
committer | 2019-10-11 21:41:56 +0200 | |
commit | a185a25066372e0d0bf608f71aef110dfe88d9a9 (patch) | |
tree | 942478a63cd83f17517e177780de53170d020624 /pydis_site/apps | |
parent | Deny `LogEntry` deletion. (diff) | |
parent | Merge pull request #269 from python-discord/migrate-nominations-to-nomination... (diff) |
Merge branch 'master' into simple-admin-log-entry-view
Diffstat (limited to 'pydis_site/apps')
3 files changed, 89 insertions, 0 deletions
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 6a3ef085..bce76942 100644 --- a/pydis_site/apps/api/tests/test_models.py +++ b/pydis_site/apps/api/tests/test_models.py @@ -10,6 +10,7 @@ from ..models import ( Message, MessageDeletionContext, ModelReprMixin, + Nomination, OffTopicChannelName, Reminder, Role, @@ -34,6 +35,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, @@ -109,3 +123,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) + ) |