From 8da376b0ebff72db9f72b7026b6f2fef4dff4f13 Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Thu, 22 Aug 2019 15:44:06 +0200 Subject: Making the deleted-messages-frontend functional with changes, including: - Adding support for embeds to both the template and the css; - Adding Discord fonts to create a Discord-realistic rendering; - Adding Discord color int to html hex filter for use in templates; - Removing unnecessary int -> hex property from role model (see previous point); - Adding support to compute timestamp from snowflake int in the message model; - Forcing the order of deleted messages list view to snowflake `id` to guarantee chronological order. --- pydis_site/apps/api/models/bot/deleted_message.py | 5 +++++ pydis_site/apps/api/models/bot/message.py | 12 ++++++++++++ 2 files changed, 17 insertions(+) (limited to 'pydis_site/apps/api') diff --git a/pydis_site/apps/api/models/bot/deleted_message.py b/pydis_site/apps/api/models/bot/deleted_message.py index eb7f4c89..1eb4516e 100644 --- a/pydis_site/apps/api/models/bot/deleted_message.py +++ b/pydis_site/apps/api/models/bot/deleted_message.py @@ -12,3 +12,8 @@ class DeletedMessage(Message): help_text="The deletion context this message is part of.", on_delete=models.CASCADE ) + + class Meta: + """Sets the default ordering for list views to oldest first.""" + + ordering = ["id"] diff --git a/pydis_site/apps/api/models/bot/message.py b/pydis_site/apps/api/models/bot/message.py index 6b566620..0713b9d2 100644 --- a/pydis_site/apps/api/models/bot/message.py +++ b/pydis_site/apps/api/models/bot/message.py @@ -1,6 +1,11 @@ +from datetime import datetime + +import pytz from django.contrib.postgres import fields as pgfields from django.core.validators import MinValueValidator from django.db import models +from django.utils import timezone + from pydis_site.apps.api.models.bot.tag import validate_tag_embed from pydis_site.apps.api.models.bot.user import User @@ -49,6 +54,13 @@ class Message(ModelReprMixin, models.Model): help_text="Embeds attached to this message." ) + @property + def timestamp(self) -> datetime: + """Attribute that represents the message timestamp as derived from the snowflake id.""" + tz_naive_datetime = datetime.utcfromtimestamp(((self.id >> 22) + 1420070400000) / 1000) + tz_aware_datetime = timezone.make_aware(tz_naive_datetime, timezone=pytz.timezone("UTC")) + return tz_aware_datetime + class Meta: """Metadata provided for Django's ORM.""" -- cgit v1.2.3 From ea8c1fb0680baa2f1e13a283ea36fffc8e15b0e1 Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Thu, 22 Aug 2019 15:49:56 +0200 Subject: Adding missing 'inline' parameter to embed fields attribute validator --- pydis_site/apps/api/models/bot/tag.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'pydis_site/apps/api') diff --git a/pydis_site/apps/api/models/bot/tag.py b/pydis_site/apps/api/models/bot/tag.py index 01b49525..0dc4830c 100644 --- a/pydis_site/apps/api/models/bot/tag.py +++ b/pydis_site/apps/api/models/bot/tag.py @@ -1,4 +1,5 @@ from collections.abc import Mapping +from typing import Any from django.contrib.postgres import fields as pgfields from django.core.exceptions import ValidationError @@ -8,11 +9,18 @@ from django.db import models from pydis_site.apps.api.models.utils import ModelReprMixin +def is_bool_validator(value: Any) -> None: + """Validates if a given value is of type bool.""" + if not isinstance(value, bool): + raise ValidationError(f"This field must be of type bool, not {type(value)}.") + + def validate_tag_embed_fields(fields): """Raises a ValidationError if any of the given embed fields is invalid.""" field_validators = { 'name': (MaxLengthValidator(limit_value=256),), - 'value': (MaxLengthValidator(limit_value=1024),) + 'value': (MaxLengthValidator(limit_value=1024),), + 'inline': (is_bool_validator,), } for field in fields: -- cgit v1.2.3 From 8066a3360b23508d3fb2da3d37d2c63f2630faff Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Thu, 22 Aug 2019 20:38:51 +0200 Subject: Adding required fields validator and tests to embed fields --- pydis_site/apps/api/models/bot/tag.py | 5 ++++ pydis_site/apps/api/tests/test_validators.py | 39 ++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) (limited to 'pydis_site/apps/api') diff --git a/pydis_site/apps/api/models/bot/tag.py b/pydis_site/apps/api/models/bot/tag.py index 0dc4830c..fc0db4e4 100644 --- a/pydis_site/apps/api/models/bot/tag.py +++ b/pydis_site/apps/api/models/bot/tag.py @@ -23,10 +23,15 @@ def validate_tag_embed_fields(fields): 'inline': (is_bool_validator,), } + required_fields = ('name', 'value') + for field in fields: if not isinstance(field, Mapping): raise ValidationError("Embed fields must be a mapping.") + if not all(required_field in field for required_field in required_fields): + raise ValidationError("Embed fields must contain both a 'name' and a 'value' field.") + for field_name, value in field.items(): if field_name not in field_validators: raise ValidationError(f"Unknown embed field field: {field_name!r}.") diff --git a/pydis_site/apps/api/tests/test_validators.py b/pydis_site/apps/api/tests/test_validators.py index ffa2f61e..4222f0c0 100644 --- a/pydis_site/apps/api/tests/test_validators.py +++ b/pydis_site/apps/api/tests/test_validators.py @@ -119,18 +119,53 @@ class TagEmbedValidatorTests(TestCase): 'value': "LOOK AT ME" }, { + 'name': "Totally valid", + 'value': "LOOK AT ME", 'oh': "what is this key?" } ] }) + def test_rejects_missing_required_field_field(self): + with self.assertRaises(ValidationError): + validate_tag_embed({ + 'fields': [ + { + 'name': "Totally valid", + 'inline': True, + } + ] + }) + + def test_rejects_invalid_inline_field_field(self): + with self.assertRaises(ValidationError): + validate_tag_embed({ + 'fields': [ + { + 'name': "Totally valid", + 'value': "LOOK AT ME", + 'inline': "Totally not a boolean", + } + ] + }) + def test_allows_valid_fields(self): validate_tag_embed({ 'fields': [ { 'name': "valid", - 'value': "field" - } + 'value': "field", + }, + { + 'name': "valid", + 'value': "field", + 'inline': False, + }, + { + 'name': "valid", + 'value': "field", + 'inline': True, + }, ] }) -- cgit v1.2.3 From a756fb69d30a1fb522ff0658f2e2843d1d283490 Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Sat, 24 Aug 2019 12:35:29 +0200 Subject: Apply suggestions from code review Co-Authored-By: Johannes Christ --- pydis_site/apps/api/models/bot/message.py | 3 +-- pydis_site/apps/api/models/bot/tag.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'pydis_site/apps/api') diff --git a/pydis_site/apps/api/models/bot/message.py b/pydis_site/apps/api/models/bot/message.py index 0713b9d2..ac4b40a3 100644 --- a/pydis_site/apps/api/models/bot/message.py +++ b/pydis_site/apps/api/models/bot/message.py @@ -1,6 +1,5 @@ from datetime import datetime -import pytz from django.contrib.postgres import fields as pgfields from django.core.validators import MinValueValidator from django.db import models @@ -58,7 +57,7 @@ class Message(ModelReprMixin, models.Model): def timestamp(self) -> datetime: """Attribute that represents the message timestamp as derived from the snowflake id.""" tz_naive_datetime = datetime.utcfromtimestamp(((self.id >> 22) + 1420070400000) / 1000) - tz_aware_datetime = timezone.make_aware(tz_naive_datetime, timezone=pytz.timezone("UTC")) + tz_aware_datetime = timezone.make_aware(tz_naive_datetime, timezone=timezone.utc) return tz_aware_datetime class Meta: diff --git a/pydis_site/apps/api/models/bot/tag.py b/pydis_site/apps/api/models/bot/tag.py index fc0db4e4..8e7643ce 100644 --- a/pydis_site/apps/api/models/bot/tag.py +++ b/pydis_site/apps/api/models/bot/tag.py @@ -30,7 +30,7 @@ def validate_tag_embed_fields(fields): raise ValidationError("Embed fields must be a mapping.") if not all(required_field in field for required_field in required_fields): - raise ValidationError("Embed fields must contain both a 'name' and a 'value' field.") + raise ValidationError(f"Embed fields must contain the following fields: {', '.join(required_fields)}.") for field_name, value in field.items(): if field_name not in field_validators: -- cgit v1.2.3 From 1432092ae5f2c9f643abb4ff91eb3969195aad3e Mon Sep 17 00:00:00 2001 From: Sebastiaan Zeeff <33516116+SebastiaanZ@users.noreply.github.com> Date: Sat, 24 Aug 2019 12:42:18 +0200 Subject: Removing incorrect double newline between imports and PEP8-ing committed GH code suggestion --- pydis_site/apps/api/models/bot/message.py | 1 - pydis_site/apps/api/models/bot/tag.py | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'pydis_site/apps/api') diff --git a/pydis_site/apps/api/models/bot/message.py b/pydis_site/apps/api/models/bot/message.py index ac4b40a3..31316a01 100644 --- a/pydis_site/apps/api/models/bot/message.py +++ b/pydis_site/apps/api/models/bot/message.py @@ -5,7 +5,6 @@ from django.core.validators import MinValueValidator from django.db import models from django.utils import timezone - from pydis_site.apps.api.models.bot.tag import validate_tag_embed from pydis_site.apps.api.models.bot.user import User from pydis_site.apps.api.models.utils import ModelReprMixin diff --git a/pydis_site/apps/api/models/bot/tag.py b/pydis_site/apps/api/models/bot/tag.py index 8e7643ce..de4eab30 100644 --- a/pydis_site/apps/api/models/bot/tag.py +++ b/pydis_site/apps/api/models/bot/tag.py @@ -30,7 +30,9 @@ def validate_tag_embed_fields(fields): raise ValidationError("Embed fields must be a mapping.") if not all(required_field in field for required_field in required_fields): - raise ValidationError(f"Embed fields must contain the following fields: {', '.join(required_fields)}.") + raise ValidationError( + f"Embed fields must contain the following fields: {', '.join(required_fields)}." + ) for field_name, value in field.items(): if field_name not in field_validators: -- cgit v1.2.3