Skip to content
Snippets Groups Projects
Verified Commit 393110a7 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Serializers for paginated collections

parent 4ce9f9bf
No related branches found
No related tags found
No related merge requests found
......@@ -30,6 +30,9 @@ FUNKWHALE_HOSTNAME = urlsplit(FUNKWHALE_URL).netloc
FEDERATION_ENABLED = env.bool('FEDERATION_ENABLED', default=True)
FEDERATION_HOSTNAME = env('FEDERATION_HOSTNAME', default=FUNKWHALE_HOSTNAME)
FEDERATION_COLLECTION_PAGE_SIZE = env.int(
'FEDERATION_COLLECTION_PAGE_SIZE', default=50
)
FEDERATION_MUSIC_NEEDS_APPROVAL = env.bool(
'FEDERATION_MUSIC_NEEDS_APPROVAL', default=True
)
......
......@@ -2,10 +2,13 @@ import urllib.parse
from django.urls import reverse
from django.conf import settings
from django.core.paginator import Paginator
from rest_framework import serializers
from dynamic_preferences.registries import global_preferences_registry
from funkwhale_api.common.utils import set_query_parameter
from . import activity
from . import models
from . import utils
......@@ -199,3 +202,66 @@ OBJECT_SERIALIZERS = {
t: ObjectSerializer
for t in activity.OBJECT_TYPES
}
class PaginatedCollectionSerializer(serializers.Serializer):
def to_representation(self, conf):
paginator = Paginator(
conf['items'],
conf.get('page_size', 20)
)
first = set_query_parameter(conf['id'], page=1)
current = first
last = set_query_parameter(conf['id'], page=paginator.num_pages)
d = {
'id': conf['id'],
'actor': conf['actor'].url,
'totalItems': paginator.count,
'type': 'Collection',
'current': current,
'first': first,
'last': last,
}
if self.context.get('include_ap_context', True):
d['@context'] = AP_CONTEXT
return d
class CollectionPageSerializer(serializers.Serializer):
def to_representation(self, conf):
page = conf['page']
first = set_query_parameter(conf['id'], page=1)
last = set_query_parameter(conf['id'], page=page.paginator.num_pages)
id = set_query_parameter(conf['id'], page=page.number)
d = {
'id': id,
'partOf': conf['id'],
'actor': conf['actor'].url,
'totalItems': page.paginator.count,
'type': 'CollectionPage',
'first': first,
'last': last,
'items': [
conf['item_serializer'](
i,
context={
'actor': conf['actor'],
'include_ap_context': False}
).data
for i in page.object_list
]
}
if page.has_previous():
d['prev'] = set_query_parameter(
conf['id'], page=page.previous_page_number())
if page.has_previous():
d['next'] = set_query_parameter(
conf['id'], page=page.next_page_number())
if self.context.get('include_ap_context', True):
d['@context'] = AP_CONTEXT
return d
from django.urls import reverse
from django.core.paginator import Paginator
from funkwhale_api.federation import keys
from funkwhale_api.federation import models
from funkwhale_api.federation import serializers
from funkwhale_api.music.serializers import AudioSerializer
def test_actor_serializer_from_ap(db):
......@@ -163,3 +165,73 @@ def test_follow_serializer_to_ap(factories):
}
assert serializer.data == expected
def test_paginated_collection_serializer(factories):
tfs = factories['music.TrackFile'].create_batch(size=5)
actor = factories['federation.Actor'](local=True)
conf = {
'id': 'https://test.federation/test',
'items': tfs,
'item_serializer': AudioSerializer,
'actor': actor,
'page_size': 2,
}
expected = {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
{},
],
'type': 'Collection',
'id': conf['id'],
'actor': actor.url,
'totalItems': len(tfs),
'current': conf['id'] + '?page=1',
'last': conf['id'] + '?page=3',
'first': conf['id'] + '?page=1',
}
serializer = serializers.PaginatedCollectionSerializer(conf)
assert serializer.data == expected
def test_collection_page_serializer(factories):
tfs = factories['music.TrackFile'].create_batch(size=5)
actor = factories['federation.Actor'](local=True)
conf = {
'id': 'https://test.federation/test',
'item_serializer': AudioSerializer,
'actor': actor,
'page': Paginator(tfs, 2).page(2),
}
expected = {
'@context': [
'https://www.w3.org/ns/activitystreams',
'https://w3id.org/security/v1',
{},
],
'type': 'CollectionPage',
'id': conf['id'] + '?page=2',
'actor': actor.url,
'totalItems': len(tfs),
'partOf': conf['id'],
'prev': conf['id'] + '?page=1',
'next': conf['id'] + '?page=3',
'first': conf['id'] + '?page=1',
'last': conf['id'] + '?page=3',
'items': [
conf['item_serializer'](
i,
context={'actor': actor, 'include_ap_context': False}
).data
for i in conf['page'].object_list
]
}
serializer = serializers.CollectionPageSerializer(conf)
assert serializer.data == expected
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment