diff options
Diffstat (limited to 'pydis_site')
24 files changed, 181 insertions, 99 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, diff --git a/pydis_site/static/images/events/summer_code_jam_2020.png b/pydis_site/static/images/events/summer_code_jam_2020.png Binary files differnew file mode 100644 index 00000000..63c311b0 --- /dev/null +++ b/pydis_site/static/images/events/summer_code_jam_2020.png diff --git a/pydis_site/templates/base/navbar.html b/pydis_site/templates/base/navbar.html index 376dab5a..f07662ae 100644 --- a/pydis_site/templates/base/navbar.html +++ b/pydis_site/templates/base/navbar.html @@ -84,8 +84,14 @@ Privacy </a> <hr class="navbar-divider"> - <a class="navbar-item" href="{% url 'wiki:get' path="code-jams/" %}"> - Code Jams + <div class="navbar-item"> + <strong>Events</strong> + </div> + <a class="navbar-item" href="{% url 'wiki:get' path="code-jams/code-jam-7/" %}"> + Upcoming: Code Jam 7 + </a> + <a class="navbar-item" href="{% url 'wiki:get' path="events/" %}"> + All events </a> <hr class="navbar-divider"> diff --git a/pydis_site/templates/home/index.html b/pydis_site/templates/home/index.html index d153b293..3e96cc91 100644 --- a/pydis_site/templates/home/index.html +++ b/pydis_site/templates/home/index.html @@ -38,14 +38,10 @@ </div> {# Right column container #} - <div class="column is-half-desktop video-container"> - <iframe - width="560" - height="315" - src="https://www.youtube.com/embed/I97L_Y3rhvc?start=381" - frameborder="0" - allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen> - </iframe> + <div class="column is-half-desktop"> + <a href="https://pythondiscord.com/pages/code-jams/code-jam-7/"> + <img src="{% static "images/events/summer_code_jam_2020.png" %}"> + </a> </div> </div> diff --git a/pydis_site/tests/test_utils_account.py b/pydis_site/tests/test_utils_account.py index d2946368..e8db7b64 100644 --- a/pydis_site/tests/test_utils_account.py +++ b/pydis_site/tests/test_utils_account.py @@ -61,16 +61,18 @@ class AccountUtilsTests(TestCase): position=0 ) - self.discord_user_role.roles.add(everyone_role) - self.discord_user_two_roles.roles.add(everyone_role) + self.discord_user_role.roles.append(everyone_role.id) + self.discord_user_two_roles.roles.append(everyone_role.id) - self.discord_user_two_roles.roles.add(Role.objects.create( + developers_role = Role.objects.create( id=1, name="Developers", colour=0, permissions=0, position=1 - )) + ) + + self.discord_user_two_roles.roles.append(developers_role.id) def test_account_adapter(self): """Test that our Allauth account adapter functions correctly.""" diff --git a/pydis_site/utils/account.py b/pydis_site/utils/account.py index 2d699c88..b4e41198 100644 --- a/pydis_site/utils/account.py +++ b/pydis_site/utils/account.py @@ -54,7 +54,7 @@ class SocialAccountAdapter(DefaultSocialAccountAdapter): raise ImmediateHttpResponse(redirect(reverse("home"))) - if user.roles.count() <= 1: + if len(user.roles) <= 1: add_message(request, ERROR, ERROR_JOIN_DISCORD) raise ImmediateHttpResponse(redirect(reverse("home"))) |