diff --git a/fedireads/activitypub/__init__.py b/fedireads/activitypub/__init__.py index b75eca7ee..33aefac32 100644 --- a/fedireads/activitypub/__init__.py +++ b/fedireads/activitypub/__init__.py @@ -1,6 +1,6 @@ ''' bring activitypub functions into the namespace ''' from .actor import get_actor -from .book import get_book, get_author +from .book import get_book, get_author, get_shelf from .create import get_create, get_update from .follow import get_following, get_followers from .follow import get_follow_request, get_unfollow, get_accept, get_reject diff --git a/fedireads/activitypub/book.py b/fedireads/activitypub/book.py index 04e8d1931..e3c0e6bfc 100644 --- a/fedireads/activitypub/book.py +++ b/fedireads/activitypub/book.py @@ -86,3 +86,42 @@ def get_author(author): if hasattr(author, field): activity[field] = author.__getattribute__(field) return activity + + +def get_shelf(shelf, page=None): + ''' serialize shelf object ''' + id_slug = shelf.absolute_id + if page: + return get_shelf_page(shelf, page) + count = shelf.books.count() + return { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': id_slug, + 'type': 'OrderedCollection', + 'totalItems': count, + 'first': '%s?page=1' % id_slug, + } + + +def get_shelf_page(shelf, page): + ''' list of books on a shelf ''' + page = int(page) + page_length = 10 + start = (page - 1) * page_length + end = start + page_length + shelf_page = shelf.books.all()[start:end] + id_slug = shelf.absolute_id + data = { + '@context': 'https://www.w3.org/ns/activitystreams', + 'id': '%s?page=%d' % (id_slug, page), + 'type': 'OrderedCollectionPage', + 'totalItems': shelf.books.count(), + 'partOf': id_slug, + 'orderedItems': [get_book(b) for b in shelf_page], + } + if end <= shelf.books.count(): + # there are still more pages + data['next'] = '%s?page=%d' % (id_slug, page + 1) + if start > 0: + data['prev'] = '%s?page=%d' % (id_slug, page - 1) + return data diff --git a/fedireads/models/book.py b/fedireads/models/book.py index a3510397a..24ef34082 100644 --- a/fedireads/models/book.py +++ b/fedireads/models/book.py @@ -3,6 +3,7 @@ from django.utils import timezone from django.db import models from model_utils.managers import InheritanceManager +from fedireads import activitypub from fedireads.settings import DOMAIN from fedireads.utils.fields import JSONField, ArrayField from fedireads.utils.models import FedireadsModel @@ -110,6 +111,10 @@ class Book(FedireadsModel): self.title, ) + @property + def activitypub_serialize(self): + return activitypub.get_book(self) + class Work(Book): ''' a work (an abstract concept of a book that manifests in an edition) ''' @@ -165,3 +170,7 @@ class Author(FedireadsModel): models.CharField(max_length=255), blank=True, default=list ) bio = models.TextField(null=True, blank=True) + + @property + def activitypub_serialize(self): + return activitypub.get_author(self) diff --git a/fedireads/models/shelf.py b/fedireads/models/shelf.py index 32ea7273e..993c7b7a2 100644 --- a/fedireads/models/shelf.py +++ b/fedireads/models/shelf.py @@ -1,6 +1,7 @@ ''' puttin' books on shelves ''' from django.db import models +from fedireads import activitypub from fedireads.utils.models import FedireadsModel @@ -23,6 +24,10 @@ class Shelf(FedireadsModel): model_name = type(self).__name__.lower() return '%s/%s/%s' % (base_path, model_name, self.identifier) + @property + def activitypub_serialize(self): + return activitypub.get_shelf(self) + class Meta: unique_together = ('user', 'identifier') diff --git a/fedireads/urls.py b/fedireads/urls.py index 1fe18507b..67109fe64 100644 --- a/fedireads/urls.py +++ b/fedireads/urls.py @@ -65,8 +65,8 @@ urlpatterns = [ re_path(r'^author/(?P[\w\-]+)(.json)?/?$', views.author_page), re_path(r'^tag/(?P.+)/?$', views.tag_page), - re_path(r'^shelf/%s/(?P[\w-]+)(.json)?/?$' % username_regex, views.shelf_page), - re_path(r'^shelf/%s/(?P[\w-]+)(.json)?/?$' % localname_regex, views.shelf_page), + re_path(r'^%s/shelf/(?P[\w-]+)(.json)?/?$' % user_path, views.shelf_page), + re_path(r'^%s/shelf/(?P[\w-]+)(.json)?/?$' % local_user_path, views.shelf_page), re_path(r'^search/?$', views.search), diff --git a/fedireads/views.py b/fedireads/views.py index a1201297d..6cb1dbe4a 100644 --- a/fedireads/views.py +++ b/fedireads/views.py @@ -539,7 +539,8 @@ def shelf_page(request, username, shelf_identifier): shelf = models.Shelf.objects.get(user=user, identifier=shelf_identifier) if is_api_request(request): - return activitypub.get_shelf(shelf) + page = request.GET.get('page') + return JsonResponse(activitypub.get_shelf(shelf, page=page)) data = { 'shelf': shelf,