From 5d7b2a6ae990dacf69bc6af7941912aa417fc8e9 Mon Sep 17 00:00:00 2001
From: Andreas Hubel <andi@saerdnaer.de>
Date: Sat, 21 Dec 2024 20:49:56 +0100
Subject: [PATCH] chore(api): expose slug + links on room

---
 src/api/serializers.py   | 18 +++++++++++++++++-
 src/core/models/links.py |  8 ++++++++
 src/core/models/rooms.py |  8 ++++++++
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/src/api/serializers.py b/src/api/serializers.py
index e0a344ae4..fc125a402 100644
--- a/src/api/serializers.py
+++ b/src/api/serializers.py
@@ -11,6 +11,7 @@ from core.models.assemblies import Assembly
 from core.models.badges import Badge, BadgeToken, BadgeTokenTimeConstraint
 from core.models.conference import Conference, ConferenceMember, ConferenceTrack
 from core.models.events import Event
+from core.models.links import Link
 from core.models.messages import DirectMessage
 from core.models.metanavi import MetaNavItem
 from core.models.rooms import Room
@@ -50,6 +51,20 @@ class ParameterisedHyperlinkedIdentityField(HyperlinkedIdentityField):
         return reverse(view_name, kwargs=kwargs, request=request, format=format)
 
 
+class LinkRelatedField(serializers.RelatedField):
+    """
+    A read only field that represents its targets using their
+    plain string representation.
+    """
+
+    def __init__(self, **kwargs):
+        kwargs['read_only'] = True
+        super().__init__(**kwargs)
+
+    def to_representation(self, value: Link):
+        return value.to_dict()
+
+
 class ValidatingModelSerializer(serializers.ModelSerializer):
     def validate(self, data):
         instance = self.Meta.model(**{field: value for field, value in data.items() if field in self.Meta.model._meta.fields})
@@ -217,7 +232,7 @@ class BadgeTokenUpdateSerializer(BadgeTokenSerializer):
 class RoomSerializer(HubModelSerializer):
     assembly = serializers.SlugRelatedField(read_only=True, slug_field='slug')
 
-    links = serializers.StringRelatedField(
+    links = LinkRelatedField(
         many=True,
         read_only=True,
     )
@@ -228,6 +243,7 @@ class RoomSerializer(HubModelSerializer):
         fields = [
             'id',
             'name',
+            'slug',
             'blocked',
             'room_type',
             'capacity',
diff --git a/src/core/models/links.py b/src/core/models/links.py
index 86764e7e4..b349a28fe 100644
--- a/src/core/models/links.py
+++ b/src/core/models/links.py
@@ -62,6 +62,14 @@ class Link(models.Model):
             except ValidationError:
                 raise ValidationError({'link': _('Link__link__must_be_url')})
 
+    def to_dict(self):
+        return {
+            'type': self.link_type,
+            'name': self.name,
+            'uri': self.link,
+            'url': self.link,
+        }
+
     def __str__(self) -> str:
         return self.name
 
diff --git a/src/core/models/rooms.py b/src/core/models/rooms.py
index b54819c25..f614d7ee2 100644
--- a/src/core/models/rooms.py
+++ b/src/core/models/rooms.py
@@ -501,5 +501,13 @@ class RoomLink(models.Model):
             if not resolve_internal_url(self.link, fallback_as_is=False):
                 raise ValidationError({'link': _('RoomLink__link__must_be_url')})
 
+    def to_dict(self):
+        return {
+            'type': self.link_type,
+            'name': self.name,
+            'uri': self.link,
+            'url': self.link,  # TODO rendered URL without local hub specific prefixes
+        }
+
     def __str__(self):
         return self.name
-- 
GitLab