From dae68c46831ef14e6a0715add1025f9af1b5a73d Mon Sep 17 00:00:00 2001 From: MarkKoz Date: Sat, 29 Aug 2020 10:00:45 -0700 Subject: Revert pull request #348 Revert commit 330a27926a7f2a9bdae56a5928cd81e55ccb38ed to reverse changes made to 6c08da2f3e48db9c9dd452f2e0505c4a61e46592. Migrations were failing when those changes were deployed. --- .../api/migrations/0051_create_news_setting.py | 25 ++++ .../api/migrations/0052_create_news_setting.py | 25 ---- .../api/migrations/0052_remove_user_avatar_hash.py | 17 +++ .../migrations/0053_offtopicchannelname_used.py | 18 --- .../api/migrations/0053_user_roles_to_array.py | 24 ++++ .../api/migrations/0054_remove_user_avatar_hash.py | 17 --- .../0054_user_invalidate_unknown_role.py | 21 +++ .../api/migrations/0055_merge_20200714_2027.py | 14 ++ .../apps/api/migrations/0055_reminder_mentions.py | 20 +++ .../api/migrations/0055_user_roles_to_array.py | 24 ---- .../api/migrations/0056_allow_blank_user_roles.py | 21 +++ .../0056_user_invalidate_unknown_role.py | 21 --- .../api/migrations/0057_merge_20200716_0751.py | 14 ++ .../apps/api/migrations/0057_reminder_mentions.py | 20 --- .../api/migrations/0058_allow_blank_user_roles.py | 21 --- .../migrations/0058_create_new_filterlist_model.py | 33 +++++ .../migrations/0059_create_new_filterlist_model.py | 33 ----- .../api/migrations/0059_populate_filterlists.py | 153 +++++++++++++++++++++ .../api/migrations/0060_populate_filterlists.py | 153 --------------------- .../migrations/0060_populate_filterlists_fix.py | 85 ++++++++++++ .../migrations/0061_populate_filterlists_fix.py | 85 ------------ .../apps/api/models/bot/off_topic_channel_name.py | 5 - .../apps/api/tests/test_off_topic_channel_names.py | 27 +--- .../api/viewsets/bot/off_topic_channel_name.py | 27 +--- 24 files changed, 431 insertions(+), 472 deletions(-) create mode 100644 pydis_site/apps/api/migrations/0051_create_news_setting.py delete mode 100644 pydis_site/apps/api/migrations/0052_create_news_setting.py create mode 100644 pydis_site/apps/api/migrations/0052_remove_user_avatar_hash.py delete mode 100644 pydis_site/apps/api/migrations/0053_offtopicchannelname_used.py create mode 100644 pydis_site/apps/api/migrations/0053_user_roles_to_array.py delete mode 100644 pydis_site/apps/api/migrations/0054_remove_user_avatar_hash.py create mode 100644 pydis_site/apps/api/migrations/0054_user_invalidate_unknown_role.py create mode 100644 pydis_site/apps/api/migrations/0055_merge_20200714_2027.py create mode 100644 pydis_site/apps/api/migrations/0055_reminder_mentions.py delete mode 100644 pydis_site/apps/api/migrations/0055_user_roles_to_array.py create mode 100644 pydis_site/apps/api/migrations/0056_allow_blank_user_roles.py delete mode 100644 pydis_site/apps/api/migrations/0056_user_invalidate_unknown_role.py create mode 100644 pydis_site/apps/api/migrations/0057_merge_20200716_0751.py delete mode 100644 pydis_site/apps/api/migrations/0057_reminder_mentions.py delete mode 100644 pydis_site/apps/api/migrations/0058_allow_blank_user_roles.py create mode 100644 pydis_site/apps/api/migrations/0058_create_new_filterlist_model.py delete mode 100644 pydis_site/apps/api/migrations/0059_create_new_filterlist_model.py create mode 100644 pydis_site/apps/api/migrations/0059_populate_filterlists.py delete mode 100644 pydis_site/apps/api/migrations/0060_populate_filterlists.py create mode 100644 pydis_site/apps/api/migrations/0060_populate_filterlists_fix.py delete mode 100644 pydis_site/apps/api/migrations/0061_populate_filterlists_fix.py (limited to 'pydis_site') diff --git a/pydis_site/apps/api/migrations/0051_create_news_setting.py b/pydis_site/apps/api/migrations/0051_create_news_setting.py new file mode 100644 index 00000000..f18fdfb1 --- /dev/null +++ b/pydis_site/apps/api/migrations/0051_create_news_setting.py @@ -0,0 +1,25 @@ +from django.db import migrations + + +def up(apps, schema_editor): + BotSetting = apps.get_model('api', 'BotSetting') + setting = BotSetting( + name='news', + data={} + ).save() + + +def down(apps, schema_editor): + BotSetting = apps.get_model('api', 'BotSetting') + BotSetting.objects.get(name='news').delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0050_remove_infractions_active_default_value'), + ] + + operations = [ + migrations.RunPython(up, down) + ] diff --git a/pydis_site/apps/api/migrations/0052_create_news_setting.py b/pydis_site/apps/api/migrations/0052_create_news_setting.py deleted file mode 100644 index b101d19d..00000000 --- a/pydis_site/apps/api/migrations/0052_create_news_setting.py +++ /dev/null @@ -1,25 +0,0 @@ -from django.db import migrations - - -def up(apps, schema_editor): - BotSetting = apps.get_model('api', 'BotSetting') - setting = BotSetting( - name='news', - data={} - ).save() - - -def down(apps, schema_editor): - BotSetting = apps.get_model('api', 'BotSetting') - BotSetting.objects.get(name='news').delete() - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0051_allow_blank_message_embeds'), - ] - - operations = [ - migrations.RunPython(up, down) - ] diff --git a/pydis_site/apps/api/migrations/0052_remove_user_avatar_hash.py b/pydis_site/apps/api/migrations/0052_remove_user_avatar_hash.py new file mode 100644 index 00000000..26b3b954 --- /dev/null +++ b/pydis_site/apps/api/migrations/0052_remove_user_avatar_hash.py @@ -0,0 +1,17 @@ +# Generated by Django 2.2.11 on 2020-05-27 07:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0051_create_news_setting'), + ] + + operations = [ + migrations.RemoveField( + model_name='user', + name='avatar_hash', + ), + ] diff --git a/pydis_site/apps/api/migrations/0053_offtopicchannelname_used.py b/pydis_site/apps/api/migrations/0053_offtopicchannelname_used.py deleted file mode 100644 index b51ce1d2..00000000 --- a/pydis_site/apps/api/migrations/0053_offtopicchannelname_used.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.11 on 2020-03-30 10:24 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0052_create_news_setting'), - ] - - operations = [ - migrations.AddField( - model_name='offtopicchannelname', - name='used', - field=models.BooleanField(default=False, help_text='Whether or not this name has already been used during this rotation'), - ), - ] diff --git a/pydis_site/apps/api/migrations/0053_user_roles_to_array.py b/pydis_site/apps/api/migrations/0053_user_roles_to_array.py new file mode 100644 index 00000000..7ff3a548 --- /dev/null +++ b/pydis_site/apps/api/migrations/0053_user_roles_to_array.py @@ -0,0 +1,24 @@ +# Generated by Django 2.2.11 on 2020-06-02 13:42 + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0052_remove_user_avatar_hash'), + ] + + operations = [ + migrations.RemoveField( + model_name='user', + name='roles', + ), + migrations.AddField( + model_name='user', + name='roles', + field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.')]), default=list, help_text='IDs of roles the user has on the server', size=None), + ), + ] diff --git a/pydis_site/apps/api/migrations/0054_remove_user_avatar_hash.py b/pydis_site/apps/api/migrations/0054_remove_user_avatar_hash.py deleted file mode 100644 index be9fd948..00000000 --- a/pydis_site/apps/api/migrations/0054_remove_user_avatar_hash.py +++ /dev/null @@ -1,17 +0,0 @@ -# Generated by Django 2.2.11 on 2020-05-27 07:17 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0053_offtopicchannelname_used'), - ] - - operations = [ - migrations.RemoveField( - model_name='user', - name='avatar_hash', - ), - ] diff --git a/pydis_site/apps/api/migrations/0054_user_invalidate_unknown_role.py b/pydis_site/apps/api/migrations/0054_user_invalidate_unknown_role.py new file mode 100644 index 00000000..96230015 --- /dev/null +++ b/pydis_site/apps/api/migrations/0054_user_invalidate_unknown_role.py @@ -0,0 +1,21 @@ +# Generated by Django 2.2.11 on 2020-06-02 20:08 + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models +import pydis_site.apps.api.models.bot.user + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0053_user_roles_to_array'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='roles', + field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.'), pydis_site.apps.api.models.bot.user._validate_existing_role]), default=list, help_text='IDs of roles the user has on the server', size=None), + ), + ] diff --git a/pydis_site/apps/api/migrations/0055_merge_20200714_2027.py b/pydis_site/apps/api/migrations/0055_merge_20200714_2027.py new file mode 100644 index 00000000..f2a0e638 --- /dev/null +++ b/pydis_site/apps/api/migrations/0055_merge_20200714_2027.py @@ -0,0 +1,14 @@ +# Generated by Django 3.0.8 on 2020-07-14 20:27 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0051_allow_blank_message_embeds'), + ('api', '0054_user_invalidate_unknown_role'), + ] + + operations = [ + ] diff --git a/pydis_site/apps/api/migrations/0055_reminder_mentions.py b/pydis_site/apps/api/migrations/0055_reminder_mentions.py new file mode 100644 index 00000000..d73b450d --- /dev/null +++ b/pydis_site/apps/api/migrations/0055_reminder_mentions.py @@ -0,0 +1,20 @@ +# Generated by Django 2.2.14 on 2020-07-15 07:37 + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0054_user_invalidate_unknown_role'), + ] + + operations = [ + migrations.AddField( + model_name='reminder', + name='mentions', + field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Mention IDs cannot be negative.')]), blank=True, default=list, help_text='IDs of roles or users to ping with the reminder.', size=None), + ), + ] diff --git a/pydis_site/apps/api/migrations/0055_user_roles_to_array.py b/pydis_site/apps/api/migrations/0055_user_roles_to_array.py deleted file mode 100644 index e7b4a983..00000000 --- a/pydis_site/apps/api/migrations/0055_user_roles_to_array.py +++ /dev/null @@ -1,24 +0,0 @@ -# Generated by Django 2.2.11 on 2020-06-02 13:42 - -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0054_remove_user_avatar_hash'), - ] - - operations = [ - migrations.RemoveField( - model_name='user', - name='roles', - ), - migrations.AddField( - model_name='user', - name='roles', - field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.')]), default=list, help_text='IDs of roles the user has on the server', size=None), - ), - ] diff --git a/pydis_site/apps/api/migrations/0056_allow_blank_user_roles.py b/pydis_site/apps/api/migrations/0056_allow_blank_user_roles.py new file mode 100644 index 00000000..489941c7 --- /dev/null +++ b/pydis_site/apps/api/migrations/0056_allow_blank_user_roles.py @@ -0,0 +1,21 @@ +# Generated by Django 3.0.8 on 2020-07-14 20:35 + +import django.contrib.postgres.fields +import django.core.validators +from django.db import migrations, models +import pydis_site.apps.api.models.bot.user + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0055_merge_20200714_2027'), + ] + + operations = [ + migrations.AlterField( + model_name='user', + name='roles', + field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.'), pydis_site.apps.api.models.bot.user._validate_existing_role]), blank=True, default=list, help_text='IDs of roles the user has on the server', size=None), + ), + ] diff --git a/pydis_site/apps/api/migrations/0056_user_invalidate_unknown_role.py b/pydis_site/apps/api/migrations/0056_user_invalidate_unknown_role.py deleted file mode 100644 index ab2696aa..00000000 --- a/pydis_site/apps/api/migrations/0056_user_invalidate_unknown_role.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 2.2.11 on 2020-06-02 20:08 - -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import pydis_site.apps.api.models.bot.user - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0055_user_roles_to_array'), - ] - - operations = [ - migrations.AlterField( - model_name='user', - name='roles', - field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.'), pydis_site.apps.api.models.bot.user._validate_existing_role]), default=list, help_text='IDs of roles the user has on the server', size=None), - ), - ] diff --git a/pydis_site/apps/api/migrations/0057_merge_20200716_0751.py b/pydis_site/apps/api/migrations/0057_merge_20200716_0751.py new file mode 100644 index 00000000..47a6d2d4 --- /dev/null +++ b/pydis_site/apps/api/migrations/0057_merge_20200716_0751.py @@ -0,0 +1,14 @@ +# Generated by Django 2.2.14 on 2020-07-16 07:51 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('api', '0055_reminder_mentions'), + ('api', '0056_allow_blank_user_roles'), + ] + + operations = [ + ] diff --git a/pydis_site/apps/api/migrations/0057_reminder_mentions.py b/pydis_site/apps/api/migrations/0057_reminder_mentions.py deleted file mode 100644 index fb829a17..00000000 --- a/pydis_site/apps/api/migrations/0057_reminder_mentions.py +++ /dev/null @@ -1,20 +0,0 @@ -# Generated by Django 2.2.14 on 2020-07-15 07:37 - -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0056_user_invalidate_unknown_role'), - ] - - operations = [ - migrations.AddField( - model_name='reminder', - name='mentions', - field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Mention IDs cannot be negative.')]), blank=True, default=list, help_text='IDs of roles or users to ping with the reminder.', size=None), - ), - ] diff --git a/pydis_site/apps/api/migrations/0058_allow_blank_user_roles.py b/pydis_site/apps/api/migrations/0058_allow_blank_user_roles.py deleted file mode 100644 index 8f7fddfc..00000000 --- a/pydis_site/apps/api/migrations/0058_allow_blank_user_roles.py +++ /dev/null @@ -1,21 +0,0 @@ -# Generated by Django 3.0.8 on 2020-07-14 20:35 - -import django.contrib.postgres.fields -import django.core.validators -from django.db import migrations, models -import pydis_site.apps.api.models.bot.user - - -class Migration(migrations.Migration): - - dependencies = [ - ('api', '0057_reminder_mentions'), - ] - - operations = [ - migrations.AlterField( - model_name='user', - name='roles', - field=django.contrib.postgres.fields.ArrayField(base_field=models.BigIntegerField(validators=[django.core.validators.MinValueValidator(limit_value=0, message='Role IDs cannot be negative.'), pydis_site.apps.api.models.bot.user._validate_existing_role]), blank=True, default=list, help_text='IDs of roles the user has on the server', size=None), - ), - ] diff --git a/pydis_site/apps/api/migrations/0058_create_new_filterlist_model.py b/pydis_site/apps/api/migrations/0058_create_new_filterlist_model.py new file mode 100644 index 00000000..aecfdad7 --- /dev/null +++ b/pydis_site/apps/api/migrations/0058_create_new_filterlist_model.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.8 on 2020-07-15 11:23 + +from django.db import migrations, models +import pydis_site.apps.api.models.mixins + + +class Migration(migrations.Migration): + dependencies = [ + ('api', '0057_merge_20200716_0751'), + ] + + operations = [ + migrations.CreateModel( + name='FilterList', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ('type', models.CharField( + choices=[('GUILD_INVITE', 'Guild Invite'), ('FILE_FORMAT', 'File Format'), + ('DOMAIN_NAME', 'Domain Name'), ('FILTER_TOKEN', 'Filter Token')], + help_text='The type of allowlist this is on.', max_length=50)), + ('allowed', models.BooleanField(help_text='Whether this item is on the allowlist or the denylist.')), + ('content', models.TextField(help_text='The data to add to the allow or denylist.')), + ('comment', models.TextField(help_text="Optional comment on this entry.", null=True)), + ], + bases=(pydis_site.apps.api.models.mixins.ModelReprMixin, models.Model), + ), + migrations.AddConstraint( + model_name='filterlist', + constraint=models.UniqueConstraint(fields=('content', 'type'), name='unique_filter_list') + ) + ] diff --git a/pydis_site/apps/api/migrations/0059_create_new_filterlist_model.py b/pydis_site/apps/api/migrations/0059_create_new_filterlist_model.py deleted file mode 100644 index eac5542d..00000000 --- a/pydis_site/apps/api/migrations/0059_create_new_filterlist_model.py +++ /dev/null @@ -1,33 +0,0 @@ -# Generated by Django 3.0.8 on 2020-07-15 11:23 - -from django.db import migrations, models -import pydis_site.apps.api.models.mixins - - -class Migration(migrations.Migration): - dependencies = [ - ('api', '0058_allow_blank_user_roles'), - ] - - operations = [ - migrations.CreateModel( - name='FilterList', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('created_at', models.DateTimeField(auto_now_add=True)), - ('updated_at', models.DateTimeField(auto_now=True)), - ('type', models.CharField( - choices=[('GUILD_INVITE', 'Guild Invite'), ('FILE_FORMAT', 'File Format'), - ('DOMAIN_NAME', 'Domain Name'), ('FILTER_TOKEN', 'Filter Token')], - help_text='The type of allowlist this is on.', max_length=50)), - ('allowed', models.BooleanField(help_text='Whether this item is on the allowlist or the denylist.')), - ('content', models.TextField(help_text='The data to add to the allow or denylist.')), - ('comment', models.TextField(help_text="Optional comment on this entry.", null=True)), - ], - bases=(pydis_site.apps.api.models.mixins.ModelReprMixin, models.Model), - ), - migrations.AddConstraint( - model_name='filterlist', - constraint=models.UniqueConstraint(fields=('content', 'type'), name='unique_filter_list') - ) - ] diff --git a/pydis_site/apps/api/migrations/0059_populate_filterlists.py b/pydis_site/apps/api/migrations/0059_populate_filterlists.py new file mode 100644 index 00000000..8c550191 --- /dev/null +++ b/pydis_site/apps/api/migrations/0059_populate_filterlists.py @@ -0,0 +1,153 @@ +from django.db import migrations + +guild_invite_whitelist = [ + ("discord.gg/python", "Python Discord", True), + ("discord.gg/4JJdJKb", "RLBot", True), + ("discord.gg/djPtTRJ", "Kivy", True), + ("discord.gg/QXyegWe", "Pyglet", True), + ("discord.gg/9XsucTT", "Panda3D", True), + ("discord.gg/AP3rq2k", "PyWeek", True), + ("discord.gg/vSPsP9t", "Microsoft Python", True), + ("discord.gg/bRCvFy9", "Discord.js Official", True), + ("discord.gg/9zT7NHP", "Programming Discussions", True), + ("discord.gg/ysd6M4r", "JetBrains Community", True), + ("discord.gg/4xJeCgy", "Raspberry Pie", True), + ("discord.gg/AStb3kZ", "Ren'Py", True), + ("discord.gg/t655QNV", "Python Discord: Emojis 1", True), + ("discord.gg/vRZPkqC", "Python Discord: Emojis 2", True), + ("discord.gg/jTtgWuy", "Django", True), + ("discord.gg/W9BypZF", "STEM", True), + ("discord.gg/dpy", "discord.py", True), + ("discord.gg/programming", "Programmers Hangout", True), + ("discord.gg/qhGUjGD", "SpeakJS", True), + ("discord.gg/eTbWSZj", "Functional Programming", True), + ("discord.gg/r8yreB6", "PyGame", True), + ("discord.gg/5UBnR3P", "Python Atlanta", True), + ("discord.gg/ccyrDKv", "C#", True), +] + +domain_name_blacklist = [ + ("pornhub.com", None, False), + ("liveleak.com", None, False), + ("grabify.link", None, False), + ("bmwforum.co", None, False), + ("leancoding.co", None, False), + ("spottyfly.com", None, False), + ("stopify.co", None, False), + ("yoütu.be", None, False), + ("discörd.com", None, False), + ("minecräft.com", None, False), + ("freegiftcards.co", None, False), + ("disçordapp.com", None, False), + ("fortnight.space", None, False), + ("fortnitechat.site", None, False), + ("joinmy.site", None, False), + ("curiouscat.club", None, False), + ("catsnthings.fun", None, False), + ("yourtube.site", None, False), + ("youtubeshort.watch", None, False), + ("catsnthing.com", None, False), + ("youtubeshort.pro", None, False), + ("canadianlumberjacks.online", None, False), + ("poweredbydialup.club", None, False), + ("poweredbydialup.online", None, False), + ("poweredbysecurity.org", None, False), + ("poweredbysecurity.online", None, False), + ("ssteam.site", None, False), + ("steamwalletgift.com", None, False), + ("discord.gift", None, False), + ("lmgtfy.com", None, False), +] + +filter_token_blacklist = [ + ("\bgoo+ks*\b", None, False), + ("\bky+s+\b", None, False), + ("\bki+ke+s*\b", None, False), + ("\bbeaner+s?\b", None, False), + ("\bcoo+ns*\b", None, False), + ("\bnig+lets*\b", None, False), + ("\bslant-eyes*\b", None, False), + ("\btowe?l-?head+s*\b", None, False), + ("\bchi*n+k+s*\b", None, False), + ("\bspick*s*\b", None, False), + ("\bkill* +(?:yo)?urself+\b", None, False), + ("\bjew+s*\b", None, False), + ("\bsuicide\b", None, False), + ("\brape\b", None, False), + ("\b(re+)tar+(d+|t+)(ed)?\b", None, False), + ("\bta+r+d+\b", None, False), + ("\bcunts*\b", None, False), + ("\btrann*y\b", None, False), + ("\bshemale\b", None, False), + ("fa+g+s*", None, False), + ("卐", None, False), + ("卍", None, False), + ("࿖", None, False), + ("࿕", None, False), + ("࿘", None, False), + ("࿗", None, False), + ("cuck(?!oo+)", None, False), + ("nigg+(?:e*r+|a+h*?|u+h+)s?", None, False), + ("fag+o+t+s*", None, False), +] + +file_format_whitelist = [ + (".3gp", None, True), + (".3g2", None, True), + (".avi", None, True), + (".bmp", None, True), + (".gif", None, True), + (".h264", None, True), + (".jpg", None, True), + (".jpeg", None, True), + (".m4v", None, True), + (".mkv", None, True), + (".mov", None, True), + (".mp4", None, True), + (".mpeg", None, True), + (".mpg", None, True), + (".png", None, True), + (".tiff", None, True), + (".wmv", None, True), + (".svg", None, True), + (".psd", "Photoshop", True), + (".ai", "Illustrator", True), + (".aep", "After Effects", True), + (".xcf", "GIMP", True), + (".mp3", None, True), + (".wav", None, True), + (".ogg", None, True), + (".webm", None, True), + (".webp", None, True), +] + +populate_data = { + "FILTER_TOKEN": filter_token_blacklist, + "DOMAIN_NAME": domain_name_blacklist, + "FILE_FORMAT": file_format_whitelist, + "GUILD_INVITE": guild_invite_whitelist, +} + + +class Migration(migrations.Migration): + dependencies = [("api", "0058_create_new_filterlist_model")] + + def populate_filterlists(app, _): + FilterList = app.get_model("api", "FilterList") + + for filterlist_type, metadata in populate_data.items(): + for content, comment, allowed in metadata: + FilterList.objects.create( + type=filterlist_type, + allowed=allowed, + content=content, + comment=comment, + ) + + def clear_filterlists(app, _): + FilterList = app.get_model("api", "FilterList") + FilterList.objects.all().delete() + + operations = [ + migrations.RunPython(populate_filterlists, clear_filterlists) + ] diff --git a/pydis_site/apps/api/migrations/0060_populate_filterlists.py b/pydis_site/apps/api/migrations/0060_populate_filterlists.py deleted file mode 100644 index 35fde95a..00000000 --- a/pydis_site/apps/api/migrations/0060_populate_filterlists.py +++ /dev/null @@ -1,153 +0,0 @@ -from django.db import migrations - -guild_invite_whitelist = [ - ("discord.gg/python", "Python Discord", True), - ("discord.gg/4JJdJKb", "RLBot", True), - ("discord.gg/djPtTRJ", "Kivy", True), - ("discord.gg/QXyegWe", "Pyglet", True), - ("discord.gg/9XsucTT", "Panda3D", True), - ("discord.gg/AP3rq2k", "PyWeek", True), - ("discord.gg/vSPsP9t", "Microsoft Python", True), - ("discord.gg/bRCvFy9", "Discord.js Official", True), - ("discord.gg/9zT7NHP", "Programming Discussions", True), - ("discord.gg/ysd6M4r", "JetBrains Community", True), - ("discord.gg/4xJeCgy", "Raspberry Pie", True), - ("discord.gg/AStb3kZ", "Ren'Py", True), - ("discord.gg/t655QNV", "Python Discord: Emojis 1", True), - ("discord.gg/vRZPkqC", "Python Discord: Emojis 2", True), - ("discord.gg/jTtgWuy", "Django", True), - ("discord.gg/W9BypZF", "STEM", True), - ("discord.gg/dpy", "discord.py", True), - ("discord.gg/programming", "Programmers Hangout", True), - ("discord.gg/qhGUjGD", "SpeakJS", True), - ("discord.gg/eTbWSZj", "Functional Programming", True), - ("discord.gg/r8yreB6", "PyGame", True), - ("discord.gg/5UBnR3P", "Python Atlanta", True), - ("discord.gg/ccyrDKv", "C#", True), -] - -domain_name_blacklist = [ - ("pornhub.com", None, False), - ("liveleak.com", None, False), - ("grabify.link", None, False), - ("bmwforum.co", None, False), - ("leancoding.co", None, False), - ("spottyfly.com", None, False), - ("stopify.co", None, False), - ("yoütu.be", None, False), - ("discörd.com", None, False), - ("minecräft.com", None, False), - ("freegiftcards.co", None, False), - ("disçordapp.com", None, False), - ("fortnight.space", None, False), - ("fortnitechat.site", None, False), - ("joinmy.site", None, False), - ("curiouscat.club", None, False), - ("catsnthings.fun", None, False), - ("yourtube.site", None, False), - ("youtubeshort.watch", None, False), - ("catsnthing.com", None, False), - ("youtubeshort.pro", None, False), - ("canadianlumberjacks.online", None, False), - ("poweredbydialup.club", None, False), - ("poweredbydialup.online", None, False), - ("poweredbysecurity.org", None, False), - ("poweredbysecurity.online", None, False), - ("ssteam.site", None, False), - ("steamwalletgift.com", None, False), - ("discord.gift", None, False), - ("lmgtfy.com", None, False), -] - -filter_token_blacklist = [ - ("\bgoo+ks*\b", None, False), - ("\bky+s+\b", None, False), - ("\bki+ke+s*\b", None, False), - ("\bbeaner+s?\b", None, False), - ("\bcoo+ns*\b", None, False), - ("\bnig+lets*\b", None, False), - ("\bslant-eyes*\b", None, False), - ("\btowe?l-?head+s*\b", None, False), - ("\bchi*n+k+s*\b", None, False), - ("\bspick*s*\b", None, False), - ("\bkill* +(?:yo)?urself+\b", None, False), - ("\bjew+s*\b", None, False), - ("\bsuicide\b", None, False), - ("\brape\b", None, False), - ("\b(re+)tar+(d+|t+)(ed)?\b", None, False), - ("\bta+r+d+\b", None, False), - ("\bcunts*\b", None, False), - ("\btrann*y\b", None, False), - ("\bshemale\b", None, False), - ("fa+g+s*", None, False), - ("卐", None, False), - ("卍", None, False), - ("࿖", None, False), - ("࿕", None, False), - ("࿘", None, False), - ("࿗", None, False), - ("cuck(?!oo+)", None, False), - ("nigg+(?:e*r+|a+h*?|u+h+)s?", None, False), - ("fag+o+t+s*", None, False), -] - -file_format_whitelist = [ - (".3gp", None, True), - (".3g2", None, True), - (".avi", None, True), - (".bmp", None, True), - (".gif", None, True), - (".h264", None, True), - (".jpg", None, True), - (".jpeg", None, True), - (".m4v", None, True), - (".mkv", None, True), - (".mov", None, True), - (".mp4", None, True), - (".mpeg", None, True), - (".mpg", None, True), - (".png", None, True), - (".tiff", None, True), - (".wmv", None, True), - (".svg", None, True), - (".psd", "Photoshop", True), - (".ai", "Illustrator", True), - (".aep", "After Effects", True), - (".xcf", "GIMP", True), - (".mp3", None, True), - (".wav", None, True), - (".ogg", None, True), - (".webm", None, True), - (".webp", None, True), -] - -populate_data = { - "FILTER_TOKEN": filter_token_blacklist, - "DOMAIN_NAME": domain_name_blacklist, - "FILE_FORMAT": file_format_whitelist, - "GUILD_INVITE": guild_invite_whitelist, -} - - -class Migration(migrations.Migration): - dependencies = [("api", "0059_create_new_filterlist_model")] - - def populate_filterlists(app, _): - FilterList = app.get_model("api", "FilterList") - - for filterlist_type, metadata in populate_data.items(): - for content, comment, allowed in metadata: - FilterList.objects.create( - type=filterlist_type, - allowed=allowed, - content=content, - comment=comment, - ) - - def clear_filterlists(app, _): - FilterList = app.get_model("api", "FilterList") - FilterList.objects.all().delete() - - operations = [ - migrations.RunPython(populate_filterlists, clear_filterlists) - ] diff --git a/pydis_site/apps/api/migrations/0060_populate_filterlists_fix.py b/pydis_site/apps/api/migrations/0060_populate_filterlists_fix.py new file mode 100644 index 00000000..53846f02 --- /dev/null +++ b/pydis_site/apps/api/migrations/0060_populate_filterlists_fix.py @@ -0,0 +1,85 @@ +from django.db import migrations + +bad_guild_invite_whitelist = [ + ("discord.gg/python", "Python Discord", True), + ("discord.gg/4JJdJKb", "RLBot", True), + ("discord.gg/djPtTRJ", "Kivy", True), + ("discord.gg/QXyegWe", "Pyglet", True), + ("discord.gg/9XsucTT", "Panda3D", True), + ("discord.gg/AP3rq2k", "PyWeek", True), + ("discord.gg/vSPsP9t", "Microsoft Python", True), + ("discord.gg/bRCvFy9", "Discord.js Official", True), + ("discord.gg/9zT7NHP", "Programming Discussions", True), + ("discord.gg/ysd6M4r", "JetBrains Community", True), + ("discord.gg/4xJeCgy", "Raspberry Pie", True), + ("discord.gg/AStb3kZ", "Ren'Py", True), + ("discord.gg/t655QNV", "Python Discord: Emojis 1", True), + ("discord.gg/vRZPkqC", "Python Discord: Emojis 2", True), + ("discord.gg/jTtgWuy", "Django", True), + ("discord.gg/W9BypZF", "STEM", True), + ("discord.gg/dpy", "discord.py", True), + ("discord.gg/programming", "Programmers Hangout", True), + ("discord.gg/qhGUjGD", "SpeakJS", True), + ("discord.gg/eTbWSZj", "Functional Programming", True), + ("discord.gg/r8yreB6", "PyGame", True), + ("discord.gg/5UBnR3P", "Python Atlanta", True), + ("discord.gg/ccyrDKv", "C#", True), +] + +guild_invite_whitelist = [ + ("267624335836053506", "Python Discord", True), + ("348658686962696195", "RLBot", True), + ("423249981340778496", "Kivy", True), + ("438622377094414346", "Pyglet", True), + ("524691714909274162", "Panda3D", True), + ("666560367173828639", "PyWeek", True), + ("702724176489873509", "Microsoft Python", True), + ("222078108977594368", "Discord.js Official", True), + ("238666723824238602", "Programming Discussions", True), + ("433980600391696384", "JetBrains Community", True), + ("204621105720328193", "Raspberry Pie", True), + ("286633898581164032", "Ren'Py", True), + ("440186186024222721", "Python Discord: Emojis 1", True), + ("578587418123304970", "Python Discord: Emojis 2", True), + ("159039020565790721", "Django", True), + ("273944235143593984", "STEM", True), + ("336642139381301249", "discord.py", True), + ("244230771232079873", "Programmers Hangout", True), + ("239433591950540801", "SpeakJS", True), + ("280033776820813825", "Functional Programming", True), + ("349505959032389632", "PyGame", True), + ("488751051629920277", "Python Atlanta", True), + ("143867839282020352", "C#", True), +] + + +class Migration(migrations.Migration): + dependencies = [("api", "0059_populate_filterlists")] + + def fix_filterlist(app, _): + FilterList = app.get_model("api", "FilterList") + FilterList.objects.filter(type="GUILD_INVITE").delete() # Clear out the stuff added in 0059. + + for content, comment, allowed in guild_invite_whitelist: + FilterList.objects.create( + type="GUILD_INVITE", + allowed=allowed, + content=content, + comment=comment, + ) + + def restore_bad_filterlist(app, _): + FilterList = app.get_model("api", "FilterList") + FilterList.objects.filter(type="GUILD_INVITE").delete() + + for content, comment, allowed in bad_guild_invite_whitelist: + FilterList.objects.create( + type="GUILD_INVITE", + allowed=allowed, + content=content, + comment=comment, + ) + + operations = [ + migrations.RunPython(fix_filterlist, restore_bad_filterlist) + ] diff --git a/pydis_site/apps/api/migrations/0061_populate_filterlists_fix.py b/pydis_site/apps/api/migrations/0061_populate_filterlists_fix.py deleted file mode 100644 index eaaafb38..00000000 --- a/pydis_site/apps/api/migrations/0061_populate_filterlists_fix.py +++ /dev/null @@ -1,85 +0,0 @@ -from django.db import migrations - -bad_guild_invite_whitelist = [ - ("discord.gg/python", "Python Discord", True), - ("discord.gg/4JJdJKb", "RLBot", True), - ("discord.gg/djPtTRJ", "Kivy", True), - ("discord.gg/QXyegWe", "Pyglet", True), - ("discord.gg/9XsucTT", "Panda3D", True), - ("discord.gg/AP3rq2k", "PyWeek", True), - ("discord.gg/vSPsP9t", "Microsoft Python", True), - ("discord.gg/bRCvFy9", "Discord.js Official", True), - ("discord.gg/9zT7NHP", "Programming Discussions", True), - ("discord.gg/ysd6M4r", "JetBrains Community", True), - ("discord.gg/4xJeCgy", "Raspberry Pie", True), - ("discord.gg/AStb3kZ", "Ren'Py", True), - ("discord.gg/t655QNV", "Python Discord: Emojis 1", True), - ("discord.gg/vRZPkqC", "Python Discord: Emojis 2", True), - ("discord.gg/jTtgWuy", "Django", True), - ("discord.gg/W9BypZF", "STEM", True), - ("discord.gg/dpy", "discord.py", True), - ("discord.gg/programming", "Programmers Hangout", True), - ("discord.gg/qhGUjGD", "SpeakJS", True), - ("discord.gg/eTbWSZj", "Functional Programming", True), - ("discord.gg/r8yreB6", "PyGame", True), - ("discord.gg/5UBnR3P", "Python Atlanta", True), - ("discord.gg/ccyrDKv", "C#", True), -] - -guild_invite_whitelist = [ - ("267624335836053506", "Python Discord", True), - ("348658686962696195", "RLBot", True), - ("423249981340778496", "Kivy", True), - ("438622377094414346", "Pyglet", True), - ("524691714909274162", "Panda3D", True), - ("666560367173828639", "PyWeek", True), - ("702724176489873509", "Microsoft Python", True), - ("222078108977594368", "Discord.js Official", True), - ("238666723824238602", "Programming Discussions", True), - ("433980600391696384", "JetBrains Community", True), - ("204621105720328193", "Raspberry Pie", True), - ("286633898581164032", "Ren'Py", True), - ("440186186024222721", "Python Discord: Emojis 1", True), - ("578587418123304970", "Python Discord: Emojis 2", True), - ("159039020565790721", "Django", True), - ("273944235143593984", "STEM", True), - ("336642139381301249", "discord.py", True), - ("244230771232079873", "Programmers Hangout", True), - ("239433591950540801", "SpeakJS", True), - ("280033776820813825", "Functional Programming", True), - ("349505959032389632", "PyGame", True), - ("488751051629920277", "Python Atlanta", True), - ("143867839282020352", "C#", True), -] - - -class Migration(migrations.Migration): - dependencies = [("api", "0060_populate_filterlists")] - - def fix_filterlist(app, _): - FilterList = app.get_model("api", "FilterList") - FilterList.objects.filter(type="GUILD_INVITE").delete() # Clear out the stuff added in 0059. - - for content, comment, allowed in guild_invite_whitelist: - FilterList.objects.create( - type="GUILD_INVITE", - allowed=allowed, - content=content, - comment=comment, - ) - - def restore_bad_filterlist(app, _): - FilterList = app.get_model("api", "FilterList") - FilterList.objects.filter(type="GUILD_INVITE").delete() - - for content, comment, allowed in bad_guild_invite_whitelist: - FilterList.objects.create( - type="GUILD_INVITE", - allowed=allowed, - content=content, - comment=comment, - ) - - operations = [ - migrations.RunPython(fix_filterlist, restore_bad_filterlist) - ] diff --git a/pydis_site/apps/api/models/bot/off_topic_channel_name.py b/pydis_site/apps/api/models/bot/off_topic_channel_name.py index 403c7465..20e77b9f 100644 --- a/pydis_site/apps/api/models/bot/off_topic_channel_name.py +++ b/pydis_site/apps/api/models/bot/off_topic_channel_name.py @@ -16,11 +16,6 @@ class OffTopicChannelName(ModelReprMixin, models.Model): help_text="The actual channel name that will be used on our Discord server." ) - used = models.BooleanField( - default=False, - help_text="Whether or not this name has already been used during this rotation", - ) - def __str__(self): """Returns the current off-topic name, for display purposes.""" return self.name diff --git a/pydis_site/apps/api/tests/test_off_topic_channel_names.py b/pydis_site/apps/api/tests/test_off_topic_channel_names.py index 3ab8b22d..bd42cd81 100644 --- a/pydis_site/apps/api/tests/test_off_topic_channel_names.py +++ b/pydis_site/apps/api/tests/test_off_topic_channel_names.py @@ -10,14 +10,12 @@ class UnauthenticatedTests(APISubdomainTestCase): self.client.force_authenticate(user=None) def test_cannot_read_off_topic_channel_name_list(self): - """Return a 401 response when not authenticated.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(url) self.assertEqual(response.status_code, 401) def test_cannot_read_off_topic_channel_name_list_with_random_item_param(self): - """Return a 401 response when `random_items` provided and not authenticated.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=no') @@ -26,7 +24,6 @@ class UnauthenticatedTests(APISubdomainTestCase): class EmptyDatabaseTests(APISubdomainTestCase): def test_returns_empty_object(self): - """Return empty list when no names in database.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(url) @@ -34,7 +31,6 @@ class EmptyDatabaseTests(APISubdomainTestCase): self.assertEqual(response.json(), []) def test_returns_empty_list_with_get_all_param(self): - """Return empty list when no names and `random_items` param provided.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=5') @@ -42,7 +38,6 @@ class EmptyDatabaseTests(APISubdomainTestCase): self.assertEqual(response.json(), []) def test_returns_400_for_bad_random_items_param(self): - """Return error message when passing not integer as `random_items`.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=totally-a-valid-integer') @@ -52,7 +47,6 @@ class EmptyDatabaseTests(APISubdomainTestCase): }) def test_returns_400_for_negative_random_items_param(self): - """Return error message when passing negative int as `random_items`.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=-5') @@ -65,11 +59,10 @@ class EmptyDatabaseTests(APISubdomainTestCase): class ListTests(APISubdomainTestCase): @classmethod def setUpTestData(cls): - cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand', used=False) - cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk', used=True) + cls.test_name = OffTopicChannelName.objects.create(name='lemons-lemonade-stand') + cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk') def test_returns_name_in_list(self): - """Return all off-topic channel names.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(url) @@ -83,21 +76,11 @@ class ListTests(APISubdomainTestCase): ) def test_returns_single_item_with_random_items_param_set_to_1(self): - """Return not-used name instead used.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.get(f'{url}?random_items=1') self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json()), 1) - self.assertEqual(response.json(), [self.test_name.name]) - - def test_running_out_of_names_with_random_parameter(self): - """Reset names `used` parameter to `False` when running out of names.""" - url = reverse('bot:offtopicchannelname-list', host='api') - response = self.client.get(f'{url}?random_items=2') - - self.assertEqual(response.status_code, 200) - self.assertEqual(response.json(), [self.test_name.name, self.test_name_2.name]) class CreationTests(APISubdomainTestCase): @@ -110,7 +93,6 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 201) def test_returns_201_for_unicode_chars(self): - """Accept all valid characters.""" url = reverse('bot:offtopicchannelname-list', host='api') names = ( '𝖠𝖡𝖢𝖣𝖤𝖥𝖦𝖧𝖨𝖩𝖪𝖫𝖬𝖭𝖮𝖯𝖰𝖱𝖲𝖳𝖴𝖵𝖶𝖷𝖸𝖹', @@ -122,7 +104,6 @@ class CreationTests(APISubdomainTestCase): self.assertEqual(response.status_code, 201) def test_returns_400_for_missing_name_param(self): - """Return error message when name not provided.""" url = reverse('bot:offtopicchannelname-list', host='api') response = self.client.post(url) self.assertEqual(response.status_code, 400) @@ -131,7 +112,6 @@ class CreationTests(APISubdomainTestCase): }) def test_returns_400_for_bad_name_param(self): - """Return error message when invalid characters provided.""" url = reverse('bot:offtopicchannelname-list', host='api') invalid_names = ( 'space between words', @@ -154,21 +134,18 @@ class DeletionTests(APISubdomainTestCase): cls.test_name_2 = OffTopicChannelName.objects.create(name='bbq-with-bisk') def test_deleting_unknown_name_returns_404(self): - """Return 404 reponse when trying to delete unknown name.""" url = reverse('bot:offtopicchannelname-detail', args=('unknown-name',), host='api') response = self.client.delete(url) self.assertEqual(response.status_code, 404) def test_deleting_known_name_returns_204(self): - """Return 204 response when deleting was successful.""" url = reverse('bot:offtopicchannelname-detail', args=(self.test_name.name,), host='api') response = self.client.delete(url) self.assertEqual(response.status_code, 204) def test_name_gets_deleted(self): - """Name gets actually deleted.""" url = reverse('bot:offtopicchannelname-detail', args=(self.test_name_2.name,), host='api') response = self.client.delete(url) diff --git a/pydis_site/apps/api/viewsets/bot/off_topic_channel_name.py b/pydis_site/apps/api/viewsets/bot/off_topic_channel_name.py index 826ad25e..d6da2399 100644 --- a/pydis_site/apps/api/viewsets/bot/off_topic_channel_name.py +++ b/pydis_site/apps/api/viewsets/bot/off_topic_channel_name.py @@ -1,4 +1,3 @@ -from django.db.models import Case, Value, When from django.db.models.query import QuerySet from django.http.request import HttpRequest from django.shortcuts import get_object_or_404 @@ -21,9 +20,7 @@ class OffTopicChannelNameViewSet(DestroyModelMixin, ViewSet): Return all known off-topic channel names from the database. If the `random_items` query parameter is given, for example using... $ curl api.pythondiscord.local:8000/bot/off-topic-channel-names?random_items=5 - ... then the API will return `5` random items from the database - that is not used in current rotation. - When running out of names, API will mark all names to not used and start new rotation. + ... then the API will return `5` random items from the database. #### Response format Return a list of off-topic-channel names: @@ -109,27 +106,7 @@ class OffTopicChannelNameViewSet(DestroyModelMixin, ViewSet): 'random_items': ["Must be a positive integer."] }) - queryset = self.get_queryset().order_by('used', '?')[:random_count] - - # When any name is used in our listing then this means we reached end of round - # and we need to reset all other names `used` to False - if any(offtopic_name.used for offtopic_name in queryset): - # These names that we just got have to be excluded from updating used to False - self.get_queryset().update( - used=Case( - When( - name__in=(offtopic_name.name for offtopic_name in queryset), - then=Value(True) - ), - default=Value(False) - ) - ) - else: - # Otherwise mark selected names `used` to True - self.get_queryset().filter( - name__in=(offtopic_name.name for offtopic_name in queryset) - ).update(used=True) - + queryset = self.get_queryset().order_by('?')[:random_count] serialized = self.serializer_class(queryset, many=True) return Response(serialized.data) -- cgit v1.2.3