aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
authorGravatar Johannes Christ <[email protected]>2019-10-11 21:41:56 +0200
committerGravatar Johannes Christ <[email protected]>2019-10-11 21:41:56 +0200
commita185a25066372e0d0bf608f71aef110dfe88d9a9 (patch)
tree942478a63cd83f17517e177780de53170d020624 /pydis_site/apps
parentDeny `LogEntry` deletion. (diff)
parentMerge 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')
-rw-r--r--pydis_site/apps/api/migrations/0044_migrate_nominations_from_infraction_to_nomination_model.py64
-rw-r--r--pydis_site/apps/api/models/bot/nomination.py5
-rw-r--r--pydis_site/apps/api/tests/test_models.py20
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)
+ )