diff options
Diffstat (limited to '')
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")))  |