aboutsummaryrefslogtreecommitdiffstats
path: root/pydis_site/apps
diff options
context:
space:
mode:
authorGravatar mbaruh <[email protected]>2023-03-21 16:22:36 +0200
committerGravatar mbaruh <[email protected]>2023-03-21 16:31:57 +0200
commita1a8e49f097739bbd2c989e1568fe4fe18946bbf (patch)
tree0660e01117b1a179e7115484ec44ca53f38437f2 /pydis_site/apps
parentFix filter serializers for false-y values (diff)
parentMerge pull request #908 from python-discord/fix-ci (diff)
Merge branch 'main' into new-filter-schema
Diffstat (limited to 'pydis_site/apps')
-rw-r--r--pydis_site/apps/api/migrations/0086_infraction_jump_url.py18
-rw-r--r--pydis_site/apps/api/migrations/0087_alter_mute_to_timeout.py25
-rw-r--r--pydis_site/apps/api/migrations/0088_new_filter_schema.py (renamed from pydis_site/apps/api/migrations/0086_new_filter_schema.py)6
-rw-r--r--pydis_site/apps/api/migrations/0089_unique_constraint_filters.py (renamed from pydis_site/apps/api/migrations/0087_unique_constraint_filters.py)2
-rw-r--r--pydis_site/apps/api/migrations/0090_unique_filter_list.py (renamed from pydis_site/apps/api/migrations/0088_unique_filter_list.py)2
-rw-r--r--pydis_site/apps/api/migrations/0091_antispam_filter_list.py (renamed from pydis_site/apps/api/migrations/0089_antispam_filter_list.py)4
-rw-r--r--pydis_site/apps/api/models/bot/infraction.py11
-rw-r--r--pydis_site/apps/api/serializers.py3
-rw-r--r--pydis_site/apps/api/tests/test_filters.py6
-rw-r--r--pydis_site/apps/api/tests/test_infractions.py24
-rw-r--r--pydis_site/apps/api/viewsets/bot/infraction.py8
-rw-r--r--pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md4
-rw-r--r--pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md19
-rw-r--r--pydis_site/apps/content/resources/guides/python-guides/keeping-tokens-safe.md2
-rw-r--r--pydis_site/apps/content/resources/guides/python-guides/why-not-json-as-database.md2
-rw-r--r--pydis_site/apps/resources/resources/vcokltfre_discord_bot_tutorial.yaml2
16 files changed, 96 insertions, 42 deletions
diff --git a/pydis_site/apps/api/migrations/0086_infraction_jump_url.py b/pydis_site/apps/api/migrations/0086_infraction_jump_url.py
new file mode 100644
index 00000000..7ae65751
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0086_infraction_jump_url.py
@@ -0,0 +1,18 @@
+# Generated by Django 4.1.7 on 2023-03-10 17:25
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0085_add_thread_id_to_nominations'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='infraction',
+ name='jump_url',
+ field=models.URLField(default=None, help_text='The jump url to message invoking the infraction.', max_length=88, null=True),
+ ),
+ ]
diff --git a/pydis_site/apps/api/migrations/0087_alter_mute_to_timeout.py b/pydis_site/apps/api/migrations/0087_alter_mute_to_timeout.py
new file mode 100644
index 00000000..8a826ba5
--- /dev/null
+++ b/pydis_site/apps/api/migrations/0087_alter_mute_to_timeout.py
@@ -0,0 +1,25 @@
+from django.apps.registry import Apps
+from django.db import migrations, models
+
+import pydis_site.apps.api.models
+
+
+def rename_type(apps: Apps, _) -> None:
+ infractions: pydis_site.apps.api.models.Infraction = apps.get_model("api", "Infraction")
+ infractions.objects.filter(type="mute").update(type="timeout")
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('api', '0086_infraction_jump_url'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='infraction',
+ name='type',
+ field=models.CharField(choices=[('note', 'Note'), ('warning', 'Warning'), ('watch', 'Watch'), ('timeout', 'Timeout'), ('kick', 'Kick'), ('ban', 'Ban'), ('superstar', 'Superstar'), ('voice_ban', 'Voice Ban'), ('voice_mute', 'Voice Mute')], help_text='The type of the infraction.', max_length=10),
+ ),
+ migrations.RunPython(rename_type, migrations.RunPython.noop)
+ ]
diff --git a/pydis_site/apps/api/migrations/0086_new_filter_schema.py b/pydis_site/apps/api/migrations/0088_new_filter_schema.py
index 5da3a3b1..46756781 100644
--- a/pydis_site/apps/api/migrations/0086_new_filter_schema.py
+++ b/pydis_site/apps/api/migrations/0088_new_filter_schema.py
@@ -89,7 +89,7 @@ def forward(apps: Apps, schema_editor: BaseDatabaseSchemaEditor) -> None:
class Migration(migrations.Migration):
dependencies = [
- ('api', '0085_add_thread_id_to_nominations'),
+ ('api', '0087_alter_mute_to_timeout'),
]
operations = [
@@ -114,7 +114,7 @@ class Migration(migrations.Migration):
('enabled', models.BooleanField(help_text='Whether this filter is currently enabled.', null=True)),
('dm_content', models.CharField(help_text='The DM to send to a user triggering this filter.', max_length=1000, null=True, blank=True)),
('dm_embed', models.CharField(help_text='The content of the DM embed', max_length=2000, null=True, blank=True)),
- ('infraction_type', models.CharField(choices=[('NONE', 'None'), ('NOTE', 'Note'), ('WARNING', 'Warning'), ('WATCH', 'Watch'), ('MUTE', 'Mute'), ('KICK', 'Kick'), ('BAN', 'Ban'), ('SUPERSTAR', 'Superstar'), ('VOICE_BAN', 'Voice Ban'), ('VOICE_MUTE', 'Voice Mute')], help_text='The infraction to apply to this user.', max_length=10, null=True)),
+ ('infraction_type', models.CharField(choices=[('NONE', 'None'), ('NOTE', 'Note'), ('WARNING', 'Warning'), ('WATCH', 'Watch'), ('TIMEOUT', 'Timeout'), ('KICK', 'Kick'), ('BAN', 'Ban'), ('SUPERSTAR', 'Superstar'), ('VOICE_BAN', 'Voice Ban'), ('VOICE_MUTE', 'Voice Mute')], help_text='The infraction to apply to this user.', max_length=10, null=True)),
('infraction_reason', models.CharField(help_text='The reason to give for the infraction.', max_length=1000, null=True, blank=True)),
('infraction_duration', models.DurationField(help_text='The duration of the infraction. 0 for permanent.', null=True)),
('infraction_channel', models.BigIntegerField(validators=(MinValueValidator(limit_value=0, message="Channel IDs cannot be negative."),), help_text="Channel in which to send the infraction.", null=True)),
@@ -141,7 +141,7 @@ class Migration(migrations.Migration):
('enabled', models.BooleanField(help_text='Whether this filter is currently enabled.')),
('dm_content', models.CharField(help_text='The DM to send to a user triggering this filter.', max_length=1000, blank=True)),
('dm_embed', models.CharField(help_text='The content of the DM embed', max_length=2000, blank=True)),
- ('infraction_type', models.CharField(choices=[('NONE', 'None'), ('NOTE', 'Note'), ('WARNING', 'Warning'), ('WATCH', 'Watch'), ('MUTE', 'Mute'), ('KICK', 'Kick'), ('BAN', 'Ban'), ('SUPERSTAR', 'Superstar'), ('VOICE_BAN', 'Voice Ban'), ('VOICE_MUTE', 'Voice Mute')], help_text='The infraction to apply to this user.', max_length=10)),
+ ('infraction_type', models.CharField(choices=[('NONE', 'None'), ('NOTE', 'Note'), ('WARNING', 'Warning'), ('WATCH', 'Watch'), ('TIMEOUT', 'Timeout'), ('KICK', 'Kick'), ('BAN', 'Ban'), ('SUPERSTAR', 'Superstar'), ('VOICE_BAN', 'Voice Ban'), ('VOICE_MUTE', 'Voice Mute')], help_text='The infraction to apply to this user.', max_length=10)),
('infraction_reason', models.CharField(help_text='The reason to give for the infraction.', max_length=1000, blank=True)),
('infraction_duration', models.DurationField(help_text='The duration of the infraction. 0 for permanent.')),
('infraction_channel', models.BigIntegerField(validators=(MinValueValidator(limit_value=0, message="Channel IDs cannot be negative."),), help_text="Channel in which to send the infraction.")),
diff --git a/pydis_site/apps/api/migrations/0087_unique_constraint_filters.py b/pydis_site/apps/api/migrations/0089_unique_constraint_filters.py
index 910e7b1b..d6f32342 100644
--- a/pydis_site/apps/api/migrations/0087_unique_constraint_filters.py
+++ b/pydis_site/apps/api/migrations/0089_unique_constraint_filters.py
@@ -4,7 +4,7 @@ from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
- ('api', '0086_new_filter_schema'),
+ ('api', '0088_new_filter_schema'),
]
operations = [
diff --git a/pydis_site/apps/api/migrations/0088_unique_filter_list.py b/pydis_site/apps/api/migrations/0090_unique_filter_list.py
index 98d14e2b..cef2faa3 100644
--- a/pydis_site/apps/api/migrations/0088_unique_filter_list.py
+++ b/pydis_site/apps/api/migrations/0090_unique_filter_list.py
@@ -91,7 +91,7 @@ def create_unique_list(apps: Apps, _):
class Migration(migrations.Migration):
dependencies = [
- ('api', '0087_unique_constraint_filters'),
+ ('api', '0089_unique_constraint_filters'),
]
operations = [
diff --git a/pydis_site/apps/api/migrations/0089_antispam_filter_list.py b/pydis_site/apps/api/migrations/0091_antispam_filter_list.py
index 284d87e7..58ffa4a4 100644
--- a/pydis_site/apps/api/migrations/0089_antispam_filter_list.py
+++ b/pydis_site/apps/api/migrations/0091_antispam_filter_list.py
@@ -22,7 +22,7 @@ def create_antispam_list(apps: Apps, _):
enabled=True,
dm_content="",
dm_embed="",
- infraction_type="MUTE",
+ infraction_type="TIMEOUT",
infraction_reason="",
infraction_duration=timedelta(seconds=600),
infraction_channel=0,
@@ -41,7 +41,7 @@ def create_antispam_list(apps: Apps, _):
class Migration(migrations.Migration):
dependencies = [
- ('api', '0088_unique_filter_list'),
+ ('api', '0090_unique_filter_list'),
]
operations = [
diff --git a/pydis_site/apps/api/models/bot/infraction.py b/pydis_site/apps/api/models/bot/infraction.py
index 218ee5ec..381b5b9d 100644
--- a/pydis_site/apps/api/models/bot/infraction.py
+++ b/pydis_site/apps/api/models/bot/infraction.py
@@ -12,7 +12,7 @@ class Infraction(ModelReprMixin, models.Model):
("note", "Note"),
("warning", "Warning"),
("watch", "Watch"),
- ("mute", "Mute"),
+ ("timeout", "Timeout"),
("kick", "Kick"),
("ban", "Ban"),
("superstar", "Superstar"),
@@ -69,6 +69,15 @@ class Infraction(ModelReprMixin, models.Model):
help_text="Whether a DM was sent to the user when infraction was applied."
)
+ jump_url = models.URLField(
+ default=None,
+ null=True,
+ max_length=88,
+ help_text=(
+ "The jump url to message invoking the infraction."
+ )
+ )
+
def __str__(self):
"""Returns some info on the current infraction, for display purposes."""
s = f"#{self.id}: {self.type} on {self.user_id}"
diff --git a/pydis_site/apps/api/serializers.py b/pydis_site/apps/api/serializers.py
index f4d64ad0..fe3c1dd2 100644
--- a/pydis_site/apps/api/serializers.py
+++ b/pydis_site/apps/api/serializers.py
@@ -427,7 +427,8 @@ class InfractionSerializer(ModelSerializer):
'type',
'reason',
'hidden',
- 'dm_sent'
+ 'dm_sent',
+ 'jump_url'
)
def validate(self, attrs: dict) -> dict:
diff --git a/pydis_site/apps/api/tests/test_filters.py b/pydis_site/apps/api/tests/test_filters.py
index 62de23c4..f36e0617 100644
--- a/pydis_site/apps/api/tests/test_filters.py
+++ b/pydis_site/apps/api/tests/test_filters.py
@@ -74,7 +74,7 @@ def get_test_sequences() -> Dict[str, TestSequence]:
"enabled": False,
"dm_content": "testing testing",
"dm_embed": "one two three",
- "infraction_type": "MUTE",
+ "infraction_type": "TIMEOUT",
"infraction_reason": "stop testing",
"infraction_duration": timedelta(seconds=10.5),
"infraction_channel": 123,
@@ -274,7 +274,7 @@ class FilterValidationTests(AuthenticatedAPITestCase):
({"infraction_reason": "hi"}, {}, 400),
({"infraction_duration": timedelta(seconds=10)}, {}, 400),
({"infraction_reason": "hi"}, {"infraction_type": "NOTE"}, 200),
- ({"infraction_duration": timedelta(seconds=10)}, {"infraction_type": "MUTE"}, 200),
+ ({"infraction_duration": timedelta(seconds=10)}, {"infraction_type": "TIMEOUT"}, 200),
({"enabled_channels": ["admins"]}, {}, 200),
({"disabled_channels": ["123"]}, {}, 200),
({"enabled_categories": ["CODE JAM"]}, {}, 200),
@@ -314,7 +314,7 @@ class FilterValidationTests(AuthenticatedAPITestCase):
({"infraction_reason": "hi"}, 400),
({"infraction_duration": timedelta(seconds=10)}, 400),
({"infraction_reason": "hi", "infraction_type": "NOTE"}, 200),
- ({"infraction_duration": timedelta(seconds=10), "infraction_type": "MUTE"}, 200),
+ ({"infraction_duration": timedelta(seconds=10), "infraction_type": "TIMEOUT"}, 200),
({"enabled_channels": ["admins"]}, 200), ({"disabled_channels": ["123"]}, 200),
({"enabled_categories": ["CODE JAM"]}, 200),
({"disabled_categories": ["CODE JAM"]}, 200),
diff --git a/pydis_site/apps/api/tests/test_infractions.py b/pydis_site/apps/api/tests/test_infractions.py
index 89ee4e23..ceb5591b 100644
--- a/pydis_site/apps/api/tests/test_infractions.py
+++ b/pydis_site/apps/api/tests/test_infractions.py
@@ -68,10 +68,10 @@ class InfractionTests(AuthenticatedAPITestCase):
active=False,
inserted_at=dt(2020, 10, 10, 0, 1, 0, tzinfo=timezone.utc),
)
- cls.mute_permanent = Infraction.objects.create(
+ cls.timeout_permanent = Infraction.objects.create(
user_id=cls.user.id,
actor_id=cls.user.id,
- type='mute',
+ type='timeout',
reason='He has a filthy mouth and I am his soap.',
active=True,
inserted_at=dt(2020, 10, 10, 0, 2, 0, tzinfo=timezone.utc),
@@ -107,7 +107,7 @@ class InfractionTests(AuthenticatedAPITestCase):
self.assertEqual(len(infractions), 5)
self.assertEqual(infractions[0]['id'], self.voiceban_expires_later.id)
self.assertEqual(infractions[1]['id'], self.superstar_expires_soon.id)
- self.assertEqual(infractions[2]['id'], self.mute_permanent.id)
+ self.assertEqual(infractions[2]['id'], self.timeout_permanent.id)
self.assertEqual(infractions[3]['id'], self.ban_inactive.id)
self.assertEqual(infractions[4]['id'], self.ban_hidden.id)
@@ -134,7 +134,7 @@ class InfractionTests(AuthenticatedAPITestCase):
def test_filter_permanent_false(self):
url = reverse('api:bot:infraction-list')
- response = self.client.get(f'{url}?type=mute&permanent=false')
+ response = self.client.get(f'{url}?type=timeout&permanent=false')
self.assertEqual(response.status_code, 200)
infractions = response.json()
@@ -143,12 +143,12 @@ class InfractionTests(AuthenticatedAPITestCase):
def test_filter_permanent_true(self):
url = reverse('api:bot:infraction-list')
- response = self.client.get(f'{url}?type=mute&permanent=true')
+ response = self.client.get(f'{url}?type=timeout&permanent=true')
self.assertEqual(response.status_code, 200)
infractions = response.json()
- self.assertEqual(infractions[0]['id'], self.mute_permanent.id)
+ self.assertEqual(infractions[0]['id'], self.timeout_permanent.id)
def test_filter_after(self):
url = reverse('api:bot:infraction-list')
@@ -241,7 +241,7 @@ class InfractionTests(AuthenticatedAPITestCase):
def test_filter_manytypes(self):
url = reverse('api:bot:infraction-list')
- response = self.client.get(f'{url}?types=mute,ban')
+ response = self.client.get(f'{url}?types=timeout,ban')
self.assertEqual(response.status_code, 200)
infractions = response.json()
@@ -249,7 +249,7 @@ class InfractionTests(AuthenticatedAPITestCase):
def test_types_type_invalid(self):
url = reverse('api:bot:infraction-list')
- response = self.client.get(f'{url}?types=mute,ban&type=superstar')
+ response = self.client.get(f'{url}?types=timeout,ban&type=superstar')
self.assertEqual(response.status_code, 400)
errors = list(response.json())
@@ -519,7 +519,7 @@ class CreationTests(AuthenticatedAPITestCase):
def test_returns_400_for_second_active_infraction_of_the_same_type(self):
"""Test if the API rejects a second active infraction of the same type for a given user."""
url = reverse('api:bot:infraction-list')
- active_infraction_types = ('mute', 'ban', 'superstar')
+ active_infraction_types = ('timeout', 'ban', 'superstar')
for infraction_type in active_infraction_types:
with self.subTest(infraction_type=infraction_type):
@@ -562,7 +562,7 @@ class CreationTests(AuthenticatedAPITestCase):
first_active_infraction = {
'user': self.user.id,
'actor': self.user.id,
- 'type': 'mute',
+ 'type': 'timeout',
'reason': 'Be silent!',
'hidden': True,
'active': True,
@@ -649,9 +649,9 @@ class CreationTests(AuthenticatedAPITestCase):
Infraction.objects.create(
user=self.user,
actor=self.user,
- type="mute",
+ type="timeout",
active=True,
- reason="The first active mute"
+ reason="The first active timeout"
)
def test_unique_constraint_accepts_active_infractions_for_different_users(self):
diff --git a/pydis_site/apps/api/viewsets/bot/infraction.py b/pydis_site/apps/api/viewsets/bot/infraction.py
index 93d29391..ec8b83a1 100644
--- a/pydis_site/apps/api/viewsets/bot/infraction.py
+++ b/pydis_site/apps/api/viewsets/bot/infraction.py
@@ -72,7 +72,8 @@ class InfractionViewSet(
... 'type': 'ban',
... 'reason': 'He terk my jerb!',
... 'hidden': True,
- ... 'dm_sent': True
+ ... 'dm_sent': True,
+ ... 'jump_url': '<discord message link>'
... }
... ]
@@ -103,7 +104,8 @@ class InfractionViewSet(
... 'type': 'ban',
... 'reason': 'He terk my jerb!',
... 'user': 172395097705414656,
- ... 'dm_sent': False
+ ... 'dm_sent': False,
+ ... 'jump_url': '<discord message link>'
... }
#### Response format
@@ -138,7 +140,7 @@ class InfractionViewSet(
#### Status codes
- 204: returned on success
- - 404: if a infraction with the given `id` does not exist
+ - 404: if an infraction with the given `id` does not exist
### Expanded routes
All routes support expansion of `user` and `actor` in responses. To use an expanded route,
diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md
index c9566d23..edfd7ac1 100644
--- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md
+++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot.md
@@ -10,7 +10,7 @@ You should have already forked the [`sir-lancebot`](https://github.com/python-di
Remember to ensure that you have read the [contributing guidelines](../contributing-guidelines) in full before you start contributing.
### Requirements
-- [Python 3.9](https://www.python.org/downloads/)
+- [Python 3.10.*](https://www.python.org/downloads/)
- [Poetry](https://github.com/python-poetry/poetry#installation)
- [Git](https://git-scm.com/downloads)
- [Windows Installer](https://git-scm.com/download/win)
@@ -59,7 +59,7 @@ You will need your own test server and bot account on Discord to test your chang
* `#dev-log`
* `#sir-lancebot-commands`
4. Create the following roles:
- * `@Admin`
+ * `@Admins`
5. Note down the IDs for your server, as well as any channels and roles created.
* [**Learn how to obtain the ID of a server, channel or role here.**](../setting-test-server-and-bot-account#obtain-the-ids)
diff --git a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md
index 51587aac..3862fb2e 100644
--- a/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md
+++ b/pydis_site/apps/content/resources/guides/pydis-guides/contributing/sir-lancebot/env-var-reference.md
@@ -10,12 +10,12 @@ The following variables are needed for running Sir Lancebot:
| -------- | -------- |
| `BOT_TOKEN` | Bot Token from the [Discord developer portal](https://discord.com/developers/applications) |
| `BOT_GUILD` | ID of the Discord Server |
-| `BOT_ADMIN_ROLE_ID` | ID of the role @Admins |
-| `ROLE_HELPERS` | ID of the role @Helpers |
-| `CHANNEL_ANNOUNCEMENTS` | ID of the #announcements channel |
-| `CHANNEL_DEVLOG` | ID of the #dev-log channel |
-| `CHANNEL_COMMUNITY_BOT_COMMANDS` | ID of the #sir-lancebot-commands channel |
-| `CHANNEL_REDDIT` | ID of the #reddit channel |
+| `BOT_ADMIN_ROLE_ID` | ID of the role `@Admins` |
+| `ROLE_HELPERS` | ID of the role `@Helpers` |
+| `CHANNEL_ANNOUNCEMENTS` | ID of the `#announcements` channel |
+| `CHANNEL_DEVLOG` | ID of the `#dev-log` channel |
+| `CHANNEL_COMMUNITY_BOT_COMMANDS` | ID of the `#sir-lancebot-commands` channel |
+| `CHANNEL_REDDIT` | ID of the `#reddit` channel |
---
## Debug Variables
@@ -32,8 +32,7 @@ Additionally, you may find the following environment variables useful during dev
| `REDIS_PASSWORD` | |
| `USE_FAKEREDIS` | If the FakeRedis module should be used. Set this to true if you don't have a Redis database setup. |
| `BOT_SENTRY_DSN` | The DSN of the sentry monitor. |
-| `TRASHCAN_EMOJI` | The full emoji to use for the trashcan. Format should be like the output of `\:emoji:`. |
-
+| `TRASHCAN_EMOJI` | The full emoji to use for the trashcan. Format should be like the output of sending `\:emoji:` on discord. |
---
## Tokens/APIs
@@ -66,8 +65,8 @@ These variables might come in handy while working on certain cogs:
| Advent of Code | `AOC_ROLE_ID` | ID of the advent of code role.
| Advent of Code | `AOC_IGNORED_DAYS` | Comma separated list of days to ignore while calculating score. |
| Advent of Code | `AOC_YEAR` | Debug variable to change the year used for AoC. |
-| Advent of Code | `AOC_CHANNEL_ID` | The ID of the #advent-of-code channel |
-| Advent of Code | `AOC_COMMANDS_CHANNEL_ID` | The ID of the #advent-of-code-commands channel |
+| Advent of Code | `AOC_CHANNEL_ID` | The ID of the `#advent-of-code` channel |
+| Advent of Code | `AOC_COMMANDS_CHANNEL_ID` | The ID of the `#advent-of-code-commands` channel |
| Advent of Code | `AOC_FALLBACK_SESSION` | |
| Advent of Code | `AOC_SESSION_COOKIE` | |
| Valentines | `LOVEFEST_ROLE_ID` | |
diff --git a/pydis_site/apps/content/resources/guides/python-guides/keeping-tokens-safe.md b/pydis_site/apps/content/resources/guides/python-guides/keeping-tokens-safe.md
index 9d523b4b..92eb52a3 100644
--- a/pydis_site/apps/content/resources/guides/python-guides/keeping-tokens-safe.md
+++ b/pydis_site/apps/content/resources/guides/python-guides/keeping-tokens-safe.md
@@ -11,7 +11,7 @@ To help prevent leaking your token,
you should ensure that you don't upload it to an open source program/website,
such as replit and github, as they show your code publicly.
The best practice for storing tokens is generally utilising .env files
-([click here](https://vcokltfre.dev/tips/tokens/.) for more information on storing tokens safely).
+([click here](https://tutorial.vco.sh/tips/tokens/) for more information on storing tokens safely).
# What should I do if my token does get leaked?
diff --git a/pydis_site/apps/content/resources/guides/python-guides/why-not-json-as-database.md b/pydis_site/apps/content/resources/guides/python-guides/why-not-json-as-database.md
index ae34c2b4..6d9f433e 100644
--- a/pydis_site/apps/content/resources/guides/python-guides/why-not-json-as-database.md
+++ b/pydis_site/apps/content/resources/guides/python-guides/why-not-json-as-database.md
@@ -2,7 +2,7 @@
title: Why JSON is unsuitable as a database
description: The many reasons why you shouldn't use JSON as a database, and instead opt for SQL.
relevant_links:
- Tips on Storing Data: https://tutorial.vcokltfre.dev/tips/storage/
+ Tips on Storing Data: https://tutorial.vco.sh/tips/storage/
---
JSON, quite simply, is not a database. It's not designed to be a data storage format,
diff --git a/pydis_site/apps/resources/resources/vcokltfre_discord_bot_tutorial.yaml b/pydis_site/apps/resources/resources/vcokltfre_discord_bot_tutorial.yaml
index 12f2a154..482cdf91 100644
--- a/pydis_site/apps/resources/resources/vcokltfre_discord_bot_tutorial.yaml
+++ b/pydis_site/apps/resources/resources/vcokltfre_discord_bot_tutorial.yaml
@@ -2,7 +2,7 @@ description: This tutorial, written by vcokltfre,
will walk you through all the aspects of creating your own Discord bot,
starting from creating the bot user itself.
name: vcokltfre's Discord Bot Tutorial
-title_url: https://tutorial.vcokltfre.dev/
+title_url: https://tutorial.vco.sh/
tags:
topics:
- discord bots