From d26e2ec69bf22d8169d2d55132b37e4d43aef98d Mon Sep 17 00:00:00 2001 From: Dhruv Bhanushali Date: Fri, 18 Mar 2022 23:03:01 +0400 Subject: [PATCH 1/2] Provide mechanism to change URL schemes on `HyperlinkedIdentityField` --- .../api/serializers/audio_serializers.py | 9 +++++---- api/catalog/api/serializers/base.py | 19 +++++++++++++++++++ .../api/serializers/image_serializers.py | 7 ++++--- api/catalog/settings.py | 3 +++ api/env.docker | 2 ++ api/env.template | 2 ++ 6 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 api/catalog/api/serializers/base.py diff --git a/api/catalog/api/serializers/audio_serializers.py b/api/catalog/api/serializers/audio_serializers.py index 7bc7e4559..e1a6eea00 100644 --- a/api/catalog/api/serializers/audio_serializers.py +++ b/api/catalog/api/serializers/audio_serializers.py @@ -1,6 +1,7 @@ from catalog.api.docs.media_docs import fields_to_md from catalog.api.models import AudioReport from catalog.api.models.audio import Audio +from catalog.api.serializers.base import SchemableHyperlinkedIdentityField from catalog.api.serializers.media_serializers import ( MediaSearchRequestSerializer, MediaSearchSerializer, @@ -142,25 +143,25 @@ class AudioSerializer(MediaSerializer): ) # Hyperlinks - thumbnail = serializers.HyperlinkedIdentityField( + thumbnail = SchemableHyperlinkedIdentityField( read_only=True, view_name="audio-thumb", lookup_field="identifier", help_text="A direct link to the miniature artwork.", ) - waveform = serializers.HyperlinkedIdentityField( + waveform = SchemableHyperlinkedIdentityField( read_only=True, view_name="audio-waveform", lookup_field="identifier", help_text="A direct link to the waveform peaks.", ) - detail_url = serializers.HyperlinkedIdentityField( + detail_url = SchemableHyperlinkedIdentityField( read_only=True, view_name="audio-detail", lookup_field="identifier", help_text="A direct link to the detail view of this audio file.", ) - related_url = serializers.HyperlinkedIdentityField( + related_url = SchemableHyperlinkedIdentityField( read_only=True, view_name="audio-related", lookup_field="identifier", diff --git a/api/catalog/api/serializers/base.py b/api/catalog/api/serializers/base.py new file mode 100644 index 000000000..df04a8125 --- /dev/null +++ b/api/catalog/api/serializers/base.py @@ -0,0 +1,19 @@ +import re + +from django.conf import settings +from rest_framework import serializers + + +class SchemableHyperlinkedIdentityField(serializers.HyperlinkedIdentityField): + """ + This field returns the link but allows the option to replace the URL scheme. + """ + + def __init__(self, scheme=settings.API_LINK_SCHEME, *args, **kwargs): + super().__init__(*args, **kwargs) + + self.scheme = scheme + + def get_url(self, *args, **kwargs): + url = super().get_url(*args, **kwargs) + return re.sub(r"\w+://", f"{self.scheme}://", url, 1) diff --git a/api/catalog/api/serializers/image_serializers.py b/api/catalog/api/serializers/image_serializers.py index 3575bb9a0..3def2a669 100644 --- a/api/catalog/api/serializers/image_serializers.py +++ b/api/catalog/api/serializers/image_serializers.py @@ -1,5 +1,6 @@ from catalog.api.docs.media_docs import fields_to_md from catalog.api.models import Image, ImageReport +from catalog.api.serializers.base import SchemableHyperlinkedIdentityField from catalog.api.serializers.media_serializers import ( MediaSearchRequestSerializer, MediaSearchSerializer, @@ -94,19 +95,19 @@ class ImageSerializer(MediaSerializer): ) # Hyperlinks - thumbnail = serializers.HyperlinkedIdentityField( + thumbnail = SchemableHyperlinkedIdentityField( read_only=True, view_name="image-thumb", lookup_field="identifier", help_text="A direct link to the miniature image.", ) - detail_url = serializers.HyperlinkedIdentityField( + detail_url = SchemableHyperlinkedIdentityField( read_only=True, view_name="image-detail", lookup_field="identifier", help_text="A direct link to the detail view of this image.", ) - related_url = serializers.HyperlinkedIdentityField( + related_url = SchemableHyperlinkedIdentityField( view_name="image-related", lookup_field="identifier", read_only=True, diff --git a/api/catalog/settings.py b/api/catalog/settings.py index 6c726f9f8..16e92888a 100644 --- a/api/catalog/settings.py +++ b/api/catalog/settings.py @@ -306,6 +306,9 @@ # Whether to boost results by authority and popularity USE_RANK_FEATURES = config("USE_RANK_FEATURES", default=True, cast=bool) +# The scheme to use for the hyperlinks in the API responses +API_LINK_SCHEME = config("API_LINK_SCHEME", default="https") + SENTRY_DSN = config( "SENTRY_DSN", default="https://08f4706d16004f57bcd37eb907bfc2e7@o787041.ingest.sentry.io/6107216", diff --git a/api/env.docker b/api/env.docker index e76c27c5a..9bdd68123 100644 --- a/api/env.docker +++ b/api/env.docker @@ -16,3 +16,5 @@ UPSTREAM_DATABASE_PORT="5432" SEMANTIC_VERSION="1.0.0" ELASTICSEARCH_URL="es" + +API_LINK_SCHEME="http" diff --git a/api/env.template b/api/env.template index 60ab0cbc1..d911f5ff1 100644 --- a/api/env.template +++ b/api/env.template @@ -51,5 +51,7 @@ SEMANTIC_VERSION="1.0.0" #DEBUG_SCORES="False" #USE_RANK_FEATURES="True" +API_LINK_SCHEME="http" + #SENTRY_SAMPLE_RATE=1.0 #SENTRY_DSN="https://08f4706d16004f57bcd37eb907bfc2e7@o787041.ingest.sentry.io/6107216" From 5839c3eeabfdfd7e156c730f37252bb13a61f198 Mon Sep 17 00:00:00 2001 From: Dhruv Bhanushali Date: Fri, 18 Mar 2022 23:27:40 +0400 Subject: [PATCH 2/2] Anchor the regex against the start of the string Co-authored-by: Madison Swain-Bowden --- api/catalog/api/serializers/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/catalog/api/serializers/base.py b/api/catalog/api/serializers/base.py index df04a8125..1bd6dfa73 100644 --- a/api/catalog/api/serializers/base.py +++ b/api/catalog/api/serializers/base.py @@ -16,4 +16,4 @@ def __init__(self, scheme=settings.API_LINK_SCHEME, *args, **kwargs): def get_url(self, *args, **kwargs): url = super().get_url(*args, **kwargs) - return re.sub(r"\w+://", f"{self.scheme}://", url, 1) + return re.sub(r"^\w+://", f"{self.scheme}://", url, 1)