aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
Diffstat (limited to 'pydis_site/apps')
-rw-r--r--pydis_site/apps/api/migrations/0051_create_news_setting.py25
-rw-r--r--pydis_site/apps/api/migrations/0052_remove_user_avatar_hash.py17
-rw-r--r--pydis_site/apps/api/migrations/0053_user_roles_to_array.py24
-rw-r--r--pydis_site/apps/api/migrations/0054_user_invalidate_unknown_role.py21
-rw-r--r--pydis_site/apps/api/models/bot/bot_setting.py1
-rw-r--r--pydis_site/apps/api/models/bot/user.py35
-rw-r--r--pydis_site/apps/api/serializers.py4
-rw-r--r--pydis_site/apps/api/tests/test_deleted_messages.py2
-rw-r--r--pydis_site/apps/api/tests/test_infractions.py7
-rw-r--r--pydis_site/apps/api/tests/test_models.py53
-rw-r--r--pydis_site/apps/api/tests/test_nominations.py2
-rw-r--r--pydis_site/apps/api/tests/test_reminders.py4
-rw-r--r--pydis_site/apps/api/tests/test_users.py10
-rw-r--r--pydis_site/apps/api/viewsets/bot/user.py7
-rw-r--r--pydis_site/apps/home/signals.py10
-rw-r--r--pydis_site/apps/home/tests/mock_github_api_response.json2
-rw-r--r--pydis_site/apps/home/tests/test_signal_listener.py15
-rw-r--r--pydis_site/apps/home/views/home.py4
-rw-r--r--pydis_site/apps/staff/tests/test_logs_view.py3
19 files changed, 162 insertions, 84 deletions
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_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_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_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/models/bot/bot_setting.py b/pydis_site/apps/api/models/bot/bot_setting.py
index b1c3e47c..8d48eac7 100644
--- a/pydis_site/apps/api/models/bot/bot_setting.py
+++ b/pydis_site/apps/api/models/bot/bot_setting.py
@@ -9,6 +9,7 @@ def validate_bot_setting_name(name: str) -> None:
"""Raises a ValidationError if the given name is not a known setting."""
known_settings = (
'defcon',
+ 'news',
)
if name not in known_settings:
diff --git a/pydis_site/apps/api/models/bot/user.py b/pydis_site/apps/api/models/bot/user.py
index 5140d2bf..bff4d642 100644
--- a/pydis_site/apps/api/models/bot/user.py
+++ b/pydis_site/apps/api/models/bot/user.py
@@ -1,3 +1,5 @@
+from django.contrib.postgres.fields import ArrayField
+from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
@@ -5,6 +7,14 @@ from pydis_site.apps.api.models.bot.role import Role
from pydis_site.apps.api.models.utils import ModelReprMixin
+def _validate_existing_role(value: int) -> None:
+ """Validate that a role exists when given in to the user model."""
+ role = Role.objects.filter(id=value)
+
+ if not role:
+ raise ValidationError(f"Role with ID {value} does not exist")
+
+
class User(ModelReprMixin, models.Model):
"""A Discord user."""
@@ -31,17 +41,18 @@ class User(ModelReprMixin, models.Model):
),
help_text="The discriminator of this user, taken from Discord."
)
- avatar_hash = models.CharField(
- max_length=100,
- help_text=(
- "The user's avatar hash, taken from Discord. "
- "Null if the user does not have any custom avatar."
+ roles = ArrayField(
+ models.BigIntegerField(
+ validators=(
+ MinValueValidator(
+ limit_value=0,
+ message="Role IDs cannot be negative."
+ ),
+ _validate_existing_role
+ )
),
- null=True
- )
- roles = models.ManyToManyField(
- Role,
- help_text="Any roles this user has on our server."
+ default=list,
+ help_text="IDs of roles the user has on the server"
)
in_guild = models.BooleanField(
default=True,
@@ -59,7 +70,7 @@ class User(ModelReprMixin, models.Model):
This will fall back to the Developers role if the user does not have any roles.
"""
- roles = self.roles.all()
+ roles = Role.objects.filter(id__in=self.roles)
if not roles:
return Role.objects.get(name="Developers")
- return max(self.roles.all())
+ return max(roles)
diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py
index e11c4af2..f2d5144c 100644
--- a/pydis_site/apps/api/serializers.py
+++ b/pydis_site/apps/api/serializers.py
@@ -229,13 +229,11 @@ class TagSerializer(ModelSerializer):
class UserSerializer(BulkSerializerMixin, ModelSerializer):
"""A class providing (de-)serialization of `User` instances."""
- roles = PrimaryKeyRelatedField(many=True, queryset=Role.objects.all(), required=False)
-
class Meta:
"""Metadata defined for the Django REST Framework."""
model = User
- fields = ('id', 'avatar_hash', 'name', 'discriminator', 'roles', 'in_guild')
+ fields = ('id', 'name', 'discriminator', 'roles', 'in_guild')
depth = 1
diff --git a/pydis_site/apps/api/tests/test_deleted_messages.py b/pydis_site/apps/api/tests/test_deleted_messages.py
index fb93cae6..f079a8dd 100644
--- a/pydis_site/apps/api/tests/test_deleted_messages.py
+++ b/pydis_site/apps/api/tests/test_deleted_messages.py
@@ -13,7 +13,6 @@ class DeletedMessagesWithoutActorTests(APISubdomainTestCase):
id=55,
name='Robbie Rotten',
discriminator=55,
- avatar_hash=None
)
cls.data = {
@@ -54,7 +53,6 @@ class DeletedMessagesWithActorTests(APISubdomainTestCase):
id=12904,
name='Joe Armstrong',
discriminator=1245,
- avatar_hash=None
)
cls.data = {
diff --git a/pydis_site/apps/api/tests/test_infractions.py b/pydis_site/apps/api/tests/test_infractions.py
index bc258b77..93ef8171 100644
--- a/pydis_site/apps/api/tests/test_infractions.py
+++ b/pydis_site/apps/api/tests/test_infractions.py
@@ -47,7 +47,6 @@ class InfractionTests(APISubdomainTestCase):
id=5,
name='james',
discriminator=1,
- avatar_hash=None
)
cls.ban_hidden = Infraction.objects.create(
user_id=cls.user.id,
@@ -169,13 +168,11 @@ class CreationTests(APISubdomainTestCase):
id=5,
name='james',
discriminator=1,
- avatar_hash=None
)
cls.second_user = User.objects.create(
id=6,
name='carl',
discriminator=2,
- avatar_hash=None
)
def test_accepts_valid_data(self):
@@ -522,7 +519,6 @@ class ExpandedTests(APISubdomainTestCase):
id=5,
name='james',
discriminator=1,
- avatar_hash=None
)
cls.kick = Infraction.objects.create(
user_id=cls.user.id,
@@ -540,7 +536,7 @@ class ExpandedTests(APISubdomainTestCase):
def check_expanded_fields(self, infraction):
for key in ('user', 'actor'):
obj = infraction[key]
- for field in ('id', 'name', 'discriminator', 'avatar_hash', 'roles', 'in_guild'):
+ for field in ('id', 'name', 'discriminator', 'roles', 'in_guild'):
self.assertTrue(field in obj, msg=f'field "{field}" missing from {key}')
def test_list_expanded(self):
@@ -599,7 +595,6 @@ class SerializerTests(APISubdomainTestCase):
id=5,
name='james',
discriminator=1,
- avatar_hash=None
)
def create_infraction(self, _type: str, active: bool):
diff --git a/pydis_site/apps/api/tests/test_models.py b/pydis_site/apps/api/tests/test_models.py
index a97d3251..b4754484 100644
--- a/pydis_site/apps/api/tests/test_models.py
+++ b/pydis_site/apps/api/tests/test_models.py
@@ -39,12 +39,14 @@ class StringDunderMethodTests(SimpleTestCase):
self.nomination = Nomination(
id=123,
actor=User(
- id=9876, name='Mr. Hemlock',
- discriminator=6666, avatar_hash=None
+ id=9876,
+ name='Mr. Hemlock',
+ discriminator=6666,
),
user=User(
- id=9876, name="Hemlock's Cat",
- discriminator=7777, avatar_hash=None
+ id=9876,
+ name="Hemlock's Cat",
+ discriminator=7777,
),
reason="He purrrrs like the best!",
)
@@ -53,15 +55,17 @@ class StringDunderMethodTests(SimpleTestCase):
DeletedMessage(
id=45,
author=User(
- id=444, name='bill',
- discriminator=5, avatar_hash=None
+ id=444,
+ name='bill',
+ discriminator=5,
),
channel_id=666,
content="wooey",
deletion_context=MessageDeletionContext(
actor=User(
- id=5555, name='shawn',
- discriminator=555, avatar_hash=None
+ id=5555,
+ name='shawn',
+ discriminator=555,
),
creation=dt.utcnow()
),
@@ -84,8 +88,9 @@ class StringDunderMethodTests(SimpleTestCase):
Message(
id=45,
author=User(
- id=444, name='bill',
- discriminator=5, avatar_hash=None
+ id=444,
+ name='bill',
+ discriminator=5,
),
channel_id=666,
content="wooey",
@@ -93,8 +98,9 @@ class StringDunderMethodTests(SimpleTestCase):
),
MessageDeletionContext(
actor=User(
- id=5555, name='shawn',
- discriminator=555, avatar_hash=None
+ id=5555,
+ name='shawn',
+ discriminator=555,
),
creation=dt.utcnow()
),
@@ -103,22 +109,29 @@ class StringDunderMethodTests(SimpleTestCase):
embed={'content': "the builder"}
),
User(
- id=5, name='bob',
- discriminator=1, avatar_hash=None
+ id=5,
+ name='bob',
+ discriminator=1,
),
Infraction(
- user_id=5, actor_id=5,
- type='kick', reason='He terk my jerb!'
+ user_id=5,
+ actor_id=5,
+ type='kick',
+ reason='He terk my jerb!'
),
Infraction(
- user_id=5, actor_id=5, hidden=True,
- type='kick', reason='He terk my jerb!',
+ user_id=5,
+ actor_id=5,
+ hidden=True,
+ type='kick',
+ reason='He terk my jerb!',
expires_at=dt(5018, 11, 20, 15, 52, tzinfo=timezone.utc)
),
Reminder(
author=User(
- id=452, name='billy',
- discriminator=5, avatar_hash=None
+ id=452,
+ name='billy',
+ discriminator=5,
),
channel_id=555,
jump_url=(
diff --git a/pydis_site/apps/api/tests/test_nominations.py b/pydis_site/apps/api/tests/test_nominations.py
index 76cb4112..92c62c87 100644
--- a/pydis_site/apps/api/tests/test_nominations.py
+++ b/pydis_site/apps/api/tests/test_nominations.py
@@ -13,7 +13,6 @@ class CreationTests(APISubdomainTestCase):
id=1234,
name='joe dart',
discriminator=1111,
- avatar_hash=None
)
def test_accepts_valid_data(self):
@@ -190,7 +189,6 @@ class NominationTests(APISubdomainTestCase):
id=1234,
name='joe dart',
discriminator=1111,
- avatar_hash=None
)
cls.active_nomination = Nomination.objects.create(
diff --git a/pydis_site/apps/api/tests/test_reminders.py b/pydis_site/apps/api/tests/test_reminders.py
index 3441e0cc..c7fa07c9 100644
--- a/pydis_site/apps/api/tests/test_reminders.py
+++ b/pydis_site/apps/api/tests/test_reminders.py
@@ -53,7 +53,6 @@ class ReminderCreationTests(APISubdomainTestCase):
id=1234,
name='Mermaid Man',
discriminator=1234,
- avatar_hash=None,
)
def test_accepts_valid_data(self):
@@ -86,7 +85,6 @@ class ReminderDeletionTests(APISubdomainTestCase):
id=6789,
name='Barnacle Boy',
discriminator=6789,
- avatar_hash=None,
)
cls.reminder = Reminder.objects.create(
@@ -118,7 +116,6 @@ class ReminderListTests(APISubdomainTestCase):
id=6789,
name='Patrick Star',
discriminator=6789,
- avatar_hash=None,
)
cls.reminder_one = Reminder.objects.create(
@@ -172,7 +169,6 @@ class ReminderUpdateTests(APISubdomainTestCase):
id=666,
name='Man Ray',
discriminator=666,
- avatar_hash=None,
)
cls.reminder = Reminder.objects.create(
diff --git a/pydis_site/apps/api/tests/test_users.py b/pydis_site/apps/api/tests/test_users.py
index 86799f19..4c0f6e27 100644
--- a/pydis_site/apps/api/tests/test_users.py
+++ b/pydis_site/apps/api/tests/test_users.py
@@ -49,7 +49,6 @@ class CreationTests(APISubdomainTestCase):
url = reverse('bot:user-list', host='api')
data = {
'id': 42,
- 'avatar_hash': "validavatarhashiswear",
'name': "Test",
'discriminator': 42,
'roles': [
@@ -63,7 +62,6 @@ class CreationTests(APISubdomainTestCase):
self.assertEqual(response.json(), data)
user = User.objects.get(id=42)
- self.assertEqual(user.avatar_hash, data['avatar_hash'])
self.assertEqual(user.name, data['name'])
self.assertEqual(user.discriminator, data['discriminator'])
self.assertEqual(user.in_guild, data['in_guild'])
@@ -73,7 +71,6 @@ class CreationTests(APISubdomainTestCase):
data = [
{
'id': 5,
- 'avatar_hash': "hahayes",
'name': "test man",
'discriminator': 42,
'roles': [
@@ -83,7 +80,6 @@ class CreationTests(APISubdomainTestCase):
},
{
'id': 8,
- 'avatar_hash': "maybenot",
'name': "another test man",
'discriminator': 555,
'roles': [],
@@ -99,7 +95,6 @@ class CreationTests(APISubdomainTestCase):
url = reverse('bot:user-list', host='api')
data = {
'id': 5,
- 'avatar_hash': "hahayes",
'name': "test man",
'discriminator': 42,
'roles': [
@@ -114,7 +109,6 @@ class CreationTests(APISubdomainTestCase):
url = reverse('bot:user-list', host='api')
data = {
'id': True,
- 'avatar_hash': 1902831,
'discriminator': "totally!"
}
@@ -148,16 +142,14 @@ class UserModelTests(APISubdomainTestCase):
)
cls.user_with_roles = User.objects.create(
id=1,
- avatar_hash="coolavatarhash",
name="Test User with two roles",
discriminator=1111,
in_guild=True,
)
- cls.user_with_roles.roles.add(cls.role_bottom, cls.role_top)
+ cls.user_with_roles.roles.extend([cls.role_bottom.id, cls.role_top.id])
cls.user_without_roles = User.objects.create(
id=2,
- avatar_hash="coolavatarhash",
name="Test User without roles",
discriminator=2222,
in_guild=True,
diff --git a/pydis_site/apps/api/viewsets/bot/user.py b/pydis_site/apps/api/viewsets/bot/user.py
index a407787e..9571b3d7 100644
--- a/pydis_site/apps/api/viewsets/bot/user.py
+++ b/pydis_site/apps/api/viewsets/bot/user.py
@@ -17,7 +17,6 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
>>> [
... {
... 'id': 409107086526644234,
- ... 'avatar': "3ba3c1acce584c20b1e96fc04bbe80eb",
... 'name': "Python",
... 'discriminator': 4329,
... 'roles': [
@@ -39,7 +38,6 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
#### Response format
>>> {
... 'id': 409107086526644234,
- ... 'avatar': "3ba3c1acce584c20b1e96fc04bbe80eb",
... 'name': "Python",
... 'discriminator': 4329,
... 'roles': [
@@ -62,7 +60,6 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
#### Request body
>>> {
... 'id': int,
- ... 'avatar': str,
... 'name': str,
... 'discriminator': int,
... 'roles': List[int],
@@ -83,7 +80,6 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
#### Request body
>>> {
... 'id': int,
- ... 'avatar': str,
... 'name': str,
... 'discriminator': int,
... 'roles': List[int],
@@ -102,7 +98,6 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
#### Request body
>>> {
... 'id': int,
- ... 'avatar': str,
... 'name': str,
... 'discriminator': int,
... 'roles': List[int],
@@ -123,4 +118,4 @@ class UserViewSet(BulkCreateModelMixin, ModelViewSet):
"""
serializer_class = UserSerializer
- queryset = User.objects.prefetch_related('roles')
+ queryset = User.objects
diff --git a/pydis_site/apps/home/signals.py b/pydis_site/apps/home/signals.py
index 4cb4564b..8af48c15 100644
--- a/pydis_site/apps/home/signals.py
+++ b/pydis_site/apps/home/signals.py
@@ -150,7 +150,7 @@ class AllauthSignalListener:
social_account = SocialAccount.objects.get(user=user, provider=DiscordProvider.id)
discord_user = DiscordUser.objects.get(id=int(social_account.uid))
- mappings = RoleMapping.objects.filter(role__in=discord_user.roles.all()).all()
+ mappings = RoleMapping.objects.filter(role__id__in=discord_user.roles).all()
is_staff = any(m.is_staff for m in mappings)
if user.is_staff != is_staff:
@@ -185,7 +185,7 @@ class AllauthSignalListener:
self.mapping_model_deleted(RoleMapping, instance=old_instance)
accounts = SocialAccount.objects.filter(
- uid__in=(u.id for u in instance.role.user_set.all())
+ uid__in=(u.id for u in DiscordUser.objects.filter(roles__contains=[instance.role.id]))
)
for account in accounts:
@@ -198,7 +198,7 @@ class AllauthSignalListener:
discord_user = DiscordUser.objects.get(id=int(account.uid))
mappings = RoleMapping.objects.filter(
- role__in=discord_user.roles.all()
+ role__id__in=discord_user.roles
).exclude(id=instance.id).all()
is_staff = any(m.is_staff for m in mappings)
@@ -289,9 +289,9 @@ class AllauthSignalListener:
new_groups = []
is_staff = False
- for role in user.roles.all():
+ for role in user.roles:
try:
- mapping = mappings.get(role=role)
+ mapping = mappings.get(role__id=role)
except RoleMapping.DoesNotExist:
continue # No mapping exists
diff --git a/pydis_site/apps/home/tests/mock_github_api_response.json b/pydis_site/apps/home/tests/mock_github_api_response.json
index 37dc672e..35604a85 100644
--- a/pydis_site/apps/home/tests/mock_github_api_response.json
+++ b/pydis_site/apps/home/tests/mock_github_api_response.json
@@ -28,7 +28,7 @@
"forks_count": 31
},
{
- "full_name": "python-discord/django-crispy-bulma",
+ "full_name": "python-discord/flake8-annotations",
"description": "test",
"stargazers_count": 97,
"language": "Python",
diff --git a/pydis_site/apps/home/tests/test_signal_listener.py b/pydis_site/apps/home/tests/test_signal_listener.py
index 66a67252..d99d81a5 100644
--- a/pydis_site/apps/home/tests/test_signal_listener.py
+++ b/pydis_site/apps/home/tests/test_signal_listener.py
@@ -81,24 +81,21 @@ class SignalListenerTests(TestCase):
id=0,
name="user",
discriminator=0,
- avatar_hash=None
)
cls.discord_unmapped = DiscordUser.objects.create(
id=2,
name="unmapped",
discriminator=0,
- avatar_hash=None
)
- cls.discord_unmapped.roles.add(cls.unmapped_role)
+ cls.discord_unmapped.roles.append(cls.unmapped_role.id)
cls.discord_unmapped.save()
cls.discord_not_in_guild = DiscordUser.objects.create(
id=3,
name="not-in-guild",
discriminator=0,
- avatar_hash=None,
in_guild=False
)
@@ -106,20 +103,18 @@ class SignalListenerTests(TestCase):
id=1,
name="admin",
discriminator=0,
- avatar_hash=None
)
- cls.discord_admin.roles.set([cls.admin_role])
+ cls.discord_admin.roles = [cls.admin_role.id]
cls.discord_admin.save()
cls.discord_moderator = DiscordUser.objects.create(
id=4,
name="admin",
discriminator=0,
- avatar_hash=None
)
- cls.discord_moderator.roles.set([cls.moderator_role])
+ cls.discord_moderator.roles = [cls.moderator_role.id]
cls.discord_moderator.save()
cls.django_user_discordless = DjangoUser.objects.create(username="no-discord")
@@ -338,7 +333,7 @@ class SignalListenerTests(TestCase):
handler._apply_groups(self.discord_admin, self.social_admin)
self.assertEqual(self.django_user_discordless.groups.all().count(), 0)
- self.discord_admin.roles.add(self.admin_role)
+ self.discord_admin.roles.append(self.admin_role.id)
self.discord_admin.save()
def test_apply_groups_moderator(self):
@@ -365,7 +360,7 @@ class SignalListenerTests(TestCase):
handler._apply_groups(self.discord_moderator, self.social_moderator)
self.assertEqual(self.django_user_discordless.groups.all().count(), 0)
- self.discord_moderator.roles.add(self.moderator_role)
+ self.discord_moderator.roles.append(self.moderator_role.id)
self.discord_moderator.save()
def test_apply_groups_other(self):
diff --git a/pydis_site/apps/home/views/home.py b/pydis_site/apps/home/views/home.py
index 4cf22594..20e38ab0 100644
--- a/pydis_site/apps/home/views/home.py
+++ b/pydis_site/apps/home/views/home.py
@@ -23,8 +23,8 @@ class HomeView(View):
"python-discord/bot",
"python-discord/snekbox",
"python-discord/seasonalbot",
+ "python-discord/flake8-annotations",
"python-discord/django-simple-bulma",
- "python-discord/django-crispy-bulma",
]
def _get_api_data(self) -> Dict[str, Dict[str, str]]:
@@ -61,7 +61,7 @@ class HomeView(View):
# Try to get new data from the API. If it fails, return the cached data.
try:
api_repositories = self._get_api_data()
- except TypeError:
+ except (TypeError, ConnectionError):
return RepositoryMetadata.objects.all()
database_repositories = []
diff --git a/pydis_site/apps/staff/tests/test_logs_view.py b/pydis_site/apps/staff/tests/test_logs_view.py
index 1415c558..17910bb6 100644
--- a/pydis_site/apps/staff/tests/test_logs_view.py
+++ b/pydis_site/apps/staff/tests/test_logs_view.py
@@ -21,10 +21,9 @@ class TestLogsView(TestCase):
id=12345678901,
name='Alan Turing',
discriminator=1912,
- avatar_hash=None
)
- cls.author.roles.add(cls.developers_role)
+ cls.author.roles.append(cls.developers_role.id)
cls.deletion_context = MessageDeletionContext.objects.create(
actor=cls.actor,