diff options
Diffstat (limited to 'pydis_site/apps/api')
| -rw-r--r-- | pydis_site/apps/api/migrations/0074_reminder_failures.py | 18 | ||||
| -rw-r--r-- | pydis_site/apps/api/migrations/0075_add_redirects_filter.py | 18 | ||||
| -rw-r--r-- | pydis_site/apps/api/migrations/0075_infraction_dm_sent.py | 18 | ||||
| -rw-r--r-- | pydis_site/apps/api/migrations/0076_merge_20211125_1941.py | 14 | ||||
| -rw-r--r-- | pydis_site/apps/api/models/bot/filter_list.py | 1 | ||||
| -rw-r--r-- | pydis_site/apps/api/models/bot/infraction.py | 4 | ||||
| -rw-r--r-- | pydis_site/apps/api/models/bot/metricity.py | 14 | ||||
| -rw-r--r-- | pydis_site/apps/api/models/bot/reminder.py | 4 | ||||
| -rw-r--r-- | pydis_site/apps/api/serializers.py | 21 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_off_topic_channel_names.py | 2 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_offensive_message.py | 2 | ||||
| -rw-r--r-- | pydis_site/apps/api/tests/test_users.py | 23 | ||||
| -rw-r--r-- | pydis_site/apps/api/viewsets/bot/filter_list.py | 3 | ||||
| -rw-r--r-- | pydis_site/apps/api/viewsets/bot/infraction.py | 9 | ||||
| -rw-r--r-- | pydis_site/apps/api/viewsets/bot/reminder.py | 13 | ||||
| -rw-r--r-- | pydis_site/apps/api/viewsets/bot/user.py | 8 | 
16 files changed, 149 insertions, 23 deletions
| diff --git a/pydis_site/apps/api/migrations/0074_reminder_failures.py b/pydis_site/apps/api/migrations/0074_reminder_failures.py new file mode 100644 index 00000000..2860046e --- /dev/null +++ b/pydis_site/apps/api/migrations/0074_reminder_failures.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.14 on 2021-10-27 17:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0073_otn_allow_GT_and_LT'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='reminder', +            name='failures', +            field=models.IntegerField(default=0, help_text='Number of times we attempted to send the reminder and failed.'), +        ), +    ] diff --git a/pydis_site/apps/api/migrations/0075_add_redirects_filter.py b/pydis_site/apps/api/migrations/0075_add_redirects_filter.py new file mode 100644 index 00000000..23dc176f --- /dev/null +++ b/pydis_site/apps/api/migrations/0075_add_redirects_filter.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.14 on 2021-11-17 10:24 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0074_reminder_failures'), +    ] + +    operations = [ +        migrations.AlterField( +            model_name='filterlist', +            name='type', +            field=models.CharField(choices=[('GUILD_INVITE', 'Guild Invite'), ('FILE_FORMAT', 'File Format'), ('DOMAIN_NAME', 'Domain Name'), ('FILTER_TOKEN', 'Filter Token'), ('REDIRECT', 'Redirect')], help_text='The type of allowlist this is on.', max_length=50), +        ), +    ] diff --git a/pydis_site/apps/api/migrations/0075_infraction_dm_sent.py b/pydis_site/apps/api/migrations/0075_infraction_dm_sent.py new file mode 100644 index 00000000..c0ac709d --- /dev/null +++ b/pydis_site/apps/api/migrations/0075_infraction_dm_sent.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.14 on 2021-11-10 22:06 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0074_reminder_failures'), +    ] + +    operations = [ +        migrations.AddField( +            model_name='infraction', +            name='dm_sent', +            field=models.BooleanField(help_text='Whether a DM was sent to the user when infraction was applied.', null=True), +        ), +    ] diff --git a/pydis_site/apps/api/migrations/0076_merge_20211125_1941.py b/pydis_site/apps/api/migrations/0076_merge_20211125_1941.py new file mode 100644 index 00000000..097d0a0c --- /dev/null +++ b/pydis_site/apps/api/migrations/0076_merge_20211125_1941.py @@ -0,0 +1,14 @@ +# Generated by Django 3.0.14 on 2021-11-25 19:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + +    dependencies = [ +        ('api', '0075_infraction_dm_sent'), +        ('api', '0075_add_redirects_filter'), +    ] + +    operations = [ +    ] diff --git a/pydis_site/apps/api/models/bot/filter_list.py b/pydis_site/apps/api/models/bot/filter_list.py index d279e137..d30f7213 100644 --- a/pydis_site/apps/api/models/bot/filter_list.py +++ b/pydis_site/apps/api/models/bot/filter_list.py @@ -12,6 +12,7 @@ class FilterList(ModelTimestampMixin, ModelReprMixin, models.Model):          'FILE_FORMAT '          'DOMAIN_NAME '          'FILTER_TOKEN ' +        'REDIRECT '      )      type = models.CharField(          max_length=50, diff --git a/pydis_site/apps/api/models/bot/infraction.py b/pydis_site/apps/api/models/bot/infraction.py index 60c1e8dd..913631d4 100644 --- a/pydis_site/apps/api/models/bot/infraction.py +++ b/pydis_site/apps/api/models/bot/infraction.py @@ -57,6 +57,10 @@ class Infraction(ModelReprMixin, models.Model):          default=False,          help_text="Whether the infraction is a shadow infraction."      ) +    dm_sent = models.BooleanField( +        null=True, +        help_text="Whether a DM was sent to the user when infraction was applied." +    )      def __str__(self):          """Returns some info on the current infraction, for display purposes.""" diff --git a/pydis_site/apps/api/models/bot/metricity.py b/pydis_site/apps/api/models/bot/metricity.py index 33fb7ad7..901f191a 100644 --- a/pydis_site/apps/api/models/bot/metricity.py +++ b/pydis_site/apps/api/models/bot/metricity.py @@ -4,10 +4,10 @@ from django.db import connections  BLOCK_INTERVAL = 10 * 60  # 10 minute blocks -EXCLUDE_CHANNELS = [ +EXCLUDE_CHANNELS = (      "267659945086812160",  # Bot commands      "607247579608121354"  # SeasonalBot commands -] +)  class NotFoundError(Exception): @@ -46,12 +46,12 @@ class Metricity:          self.cursor.execute(              """              SELECT -              COUNT(*) +                COUNT(*)              FROM messages              WHERE -              author_id = '%s' -              AND NOT is_deleted -              AND NOT %s::varchar[] @> ARRAY[channel_id] +                author_id = '%s' +                AND NOT is_deleted +                AND channel_id NOT IN %s              """,              [user_id, EXCLUDE_CHANNELS]          ) @@ -79,7 +79,7 @@ class Metricity:                  WHERE                      author_id='%s'                      AND NOT is_deleted -                    AND NOT %s::varchar[] @> ARRAY[channel_id] +                    AND channel_id NOT IN %s                  GROUP BY interval              ) block_query;              """, diff --git a/pydis_site/apps/api/models/bot/reminder.py b/pydis_site/apps/api/models/bot/reminder.py index 7d968a0e..173900ee 100644 --- a/pydis_site/apps/api/models/bot/reminder.py +++ b/pydis_site/apps/api/models/bot/reminder.py @@ -59,6 +59,10 @@ class Reminder(ModelReprMixin, models.Model):          blank=True,          help_text="IDs of roles or users to ping with the reminder."      ) +    failures = models.IntegerField( +        default=0, +        help_text="Number of times we attempted to send the reminder and failed." +    )      def __str__(self):          """Returns some info on the current reminder, for display purposes.""" diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py index f47bedca..de2fccff 100644 --- a/pydis_site/apps/api/serializers.py +++ b/pydis_site/apps/api/serializers.py @@ -145,7 +145,16 @@ class InfractionSerializer(ModelSerializer):          model = Infraction          fields = ( -            'id', 'inserted_at', 'expires_at', 'active', 'user', 'actor', 'type', 'reason', 'hidden' +            'id', +            'inserted_at', +            'expires_at', +            'active', +            'user', +            'actor', +            'type', +            'reason', +            'hidden', +            'dm_sent'          )          validators = [              UniqueTogetherValidator( @@ -231,7 +240,15 @@ class ReminderSerializer(ModelSerializer):          model = Reminder          fields = ( -            'active', 'author', 'jump_url', 'channel_id', 'content', 'expiration', 'id', 'mentions' +            'active', +            'author', +            'jump_url', +            'channel_id', +            'content', +            'expiration', +            'id', +            'mentions', +            'failures'          ) 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 63993978..1825f6e6 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 @@ -154,7 +154,7 @@ class DeletionTests(AuthenticatedAPITestCase):          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.""" +        """Return 404 response when trying to delete unknown name."""          url = reverse('api:bot:offtopicchannelname-detail', args=('unknown-name',))          response = self.client.delete(url) diff --git a/pydis_site/apps/api/tests/test_offensive_message.py b/pydis_site/apps/api/tests/test_offensive_message.py index 9b79b38c..3cf95b75 100644 --- a/pydis_site/apps/api/tests/test_offensive_message.py +++ b/pydis_site/apps/api/tests/test_offensive_message.py @@ -58,7 +58,7 @@ class CreationTests(AuthenticatedAPITestCase):          )          for field, invalid_value in cases: -            with self.subTest(fied=field, invalid_value=invalid_value): +            with self.subTest(field=field, invalid_value=invalid_value):                  test_data = data.copy()                  test_data.update({field: invalid_value}) diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py index 295bcf64..81bfd43b 100644 --- a/pydis_site/apps/api/tests/test_users.py +++ b/pydis_site/apps/api/tests/test_users.py @@ -408,7 +408,7 @@ class UserMetricityTests(AuthenticatedAPITestCase):              in_guild=True,          ) -    def test_get_metricity_data(self): +    def test_get_metricity_data_under_1k(self):          # Given          joined_at = "foo"          total_messages = 1 @@ -421,13 +421,32 @@ class UserMetricityTests(AuthenticatedAPITestCase):          # Then          self.assertEqual(response.status_code, 200) -        self.assertEqual(response.json(), { +        self.assertCountEqual(response.json(), {              "joined_at": joined_at,              "total_messages": total_messages,              "voice_banned": False,              "activity_blocks": total_blocks          }) +    def test_get_metricity_data_over_1k(self): +        # Given +        joined_at = "foo" +        total_messages = 1001 +        total_blocks = 1001 +        self.mock_metricity_user(joined_at, total_messages, total_blocks, []) + +        # When +        url = reverse('api:bot:user-metricity-data', args=[0]) +        response = self.client.get(url) + +        # Then +        self.assertEqual(response.status_code, 200) +        self.assertCountEqual(response.json(), { +            "joined_at": joined_at, +            "total_messages": total_messages, +            "voice_banned": False, +        }) +      def test_no_metricity_user(self):          # Given          self.mock_no_metricity_user() diff --git a/pydis_site/apps/api/viewsets/bot/filter_list.py b/pydis_site/apps/api/viewsets/bot/filter_list.py index 2cb21ab9..4b05acee 100644 --- a/pydis_site/apps/api/viewsets/bot/filter_list.py +++ b/pydis_site/apps/api/viewsets/bot/filter_list.py @@ -59,7 +59,8 @@ class FilterListViewSet(ModelViewSet):      ...     ["GUILD_INVITE","Guild Invite"],      ...     ["FILE_FORMAT","File Format"],      ...     ["DOMAIN_NAME","Domain Name"], -    ...     ["FILTER_TOKEN","Filter Token"] +    ...     ["FILTER_TOKEN","Filter Token"], +    ...     ["REDIRECT", "Redirect"]      ... ]      #### Status codes diff --git a/pydis_site/apps/api/viewsets/bot/infraction.py b/pydis_site/apps/api/viewsets/bot/infraction.py index f8b0cb9d..8a48ed1f 100644 --- a/pydis_site/apps/api/viewsets/bot/infraction.py +++ b/pydis_site/apps/api/viewsets/bot/infraction.py @@ -70,7 +70,8 @@ class InfractionViewSet(      ...         'actor': 125435062127820800,      ...         'type': 'ban',      ...         'reason': 'He terk my jerb!', -    ...         'hidden': True +    ...         'hidden': True, +    ...         'dm_sent': True      ...     }      ... ] @@ -100,7 +101,8 @@ class InfractionViewSet(      ...     'hidden': True,      ...     'type': 'ban',      ...     'reason': 'He terk my jerb!', -    ...     'user': 172395097705414656 +    ...     'user': 172395097705414656, +    ...     'dm_sent': False      ... }      #### Response format @@ -118,7 +120,8 @@ class InfractionViewSet(      >>> {      ...     'active': True,      ...     'expires_at': '4143-02-15T21:04:31+00:00', -    ...     'reason': 'durka derr' +    ...     'reason': 'durka derr', +    ...     'dm_sent': True      ... }      #### Response format diff --git a/pydis_site/apps/api/viewsets/bot/reminder.py b/pydis_site/apps/api/viewsets/bot/reminder.py index 111660d9..78d7cb3b 100644 --- a/pydis_site/apps/api/viewsets/bot/reminder.py +++ b/pydis_site/apps/api/viewsets/bot/reminder.py @@ -42,7 +42,8 @@ class ReminderViewSet(      ...         'expiration': '5018-11-20T15:52:00Z',      ...         'id': 11,      ...         'channel_id': 634547009956872193, -    ...         'jump_url': "https://discord.com/channels/<guild_id>/<channel_id>/<message_id>" +    ...         'jump_url': "https://discord.com/channels/<guild_id>/<channel_id>/<message_id>", +    ...         'failures': 3      ...     },      ...     ...      ... ] @@ -67,7 +68,8 @@ class ReminderViewSet(      ...     'expiration': '5018-11-20T15:52:00Z',      ...     'id': 11,      ...     'channel_id': 634547009956872193, -    ...     'jump_url': "https://discord.com/channels/<guild_id>/<channel_id>/<message_id>" +    ...     'jump_url': "https://discord.com/channels/<guild_id>/<channel_id>/<message_id>", +    ...     'failures': 3      ... }      #### Status codes @@ -80,7 +82,7 @@ class ReminderViewSet(      #### Request body      >>> {      ...     'author': int, -    ...     'mentions': List[int], +    ...     'mentions': list[int],      ...     'content': str,      ...     'expiration': str,  # ISO-formatted datetime      ...     'channel_id': int, @@ -98,9 +100,10 @@ class ReminderViewSet(      #### Request body      >>> { -    ...     'mentions': List[int], +    ...     'mentions': list[int],      ...     'content': str, -    ...     'expiration': str  # ISO-formatted datetime +    ...     'expiration': str,  # ISO-formatted datetime +    ...     'failures': int      ... }      #### Status codes diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py index 22d13dc4..ed661323 100644 --- a/pydis_site/apps/api/viewsets/bot/user.py +++ b/pydis_site/apps/api/viewsets/bot/user.py @@ -271,9 +271,15 @@ class UserViewSet(ModelViewSet):          with Metricity() as metricity:              try:                  data = metricity.user(user.id) +                  data["total_messages"] = metricity.total_messages(user.id) +                if data["total_messages"] < 1000: +                    # Only calculate and return activity_blocks if the user has a small amount +                    # of messages, as calculating activity_blocks is expensive. +                    # 1000 message chosen as an arbitrarily large number. +                    data["activity_blocks"] = metricity.total_message_blocks(user.id) +                  data["voice_banned"] = voice_banned -                data["activity_blocks"] = metricity.total_message_blocks(user.id)                  return Response(data, status=status.HTTP_200_OK)              except NotFoundError:                  return Response(dict(detail="User not found in metricity"), | 
