moviewyrm/fedireads/activitypub/collection.py
2020-03-06 22:58:51 -08:00

133 lines
3.8 KiB
Python

''' activitypub json for collections '''
from uuid import uuid4
from urllib.parse import urlencode
from .status import get_status, get_review
def get_outbox(user, size):
''' helper function for creating an outbox '''
return get_ordered_collection(user.outbox, size)
def get_outbox_page(user, page_id, statuses, max_id, min_id):
''' helper for formatting outbox pages '''
# not generalizing this more because the format varies for some reason
page = {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': page_id,
'type': 'OrderedCollectionPage',
'partOf': user.outbox,
'orderedItems': [],
}
for status in statuses:
if status.status_type == 'Review':
status_activity = get_review(status)
else:
status_activity = get_status(status)
page['orderedItems'].append(status_activity)
if max_id:
page['next'] = user.outbox + '?' + \
urlencode({'min_id': max_id, 'page': 'true'})
if min_id:
page['prev'] = user.outbox + '?' + \
urlencode({'max_id': min_id, 'page': 'true'})
return page
def get_followers(user, page, follow_queryset):
''' list of people who follow a user '''
id_slug = '%s/followers' % user.actor
return get_follow_info(id_slug, page, follow_queryset)
def get_following(user, page, follow_queryset):
''' list of people who follow a user '''
id_slug = '%s/following' % user.actor
return get_follow_info(id_slug, page, follow_queryset)
def get_follow_info(id_slug, page, follow_queryset):
''' a list of followers or following '''
if page:
return get_follow_page(follow_queryset, id_slug, page)
count = follow_queryset.count()
return {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': id_slug,
'type': 'OrderedCollection',
'totalItems': count,
'first': '%s?page=1' % id_slug,
}
# TODO: generalize these pagination functions
def get_follow_page(user_list, id_slug, page):
''' format a list of followers/following '''
page = int(page)
page_length = 10
start = (page - 1) * page_length
end = start + page_length
follower_page = user_list.all()[start:end]
data = {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': '%s?page=%d' % (id_slug, page),
'type': 'OrderedCollectionPage',
'totalItems': user_list.count(),
'partOf': id_slug,
'orderedItems': [u.actor for u in follower_page],
}
if end <= user_list.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
def get_ordered_collection(id_slug, size):
''' create an ordered collection '''
return {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': id_slug,
'type': 'OrderedCollection',
'totalItems': size,
'first': '%s?page=true' % id_slug,
'last': '%s?min_id=0&page=true' % id_slug
}
def get_add(*args):
''' activitypub Add activity '''
return get_add_remove(*args, action='Add')
def get_remove(*args):
''' activitypub Add activity '''
return get_add_remove(*args, action='Remove')
def get_add_remove(user, book, shelf, action='Add'):
''' format an Add or Remove json blob '''
uuid = uuid4()
return {
'@context': 'https://www.w3.org/ns/activitystreams',
'id': str(uuid),
'type': action,
'actor': user.actor,
'object': {
# TODO: document??
'type': 'Document',
'name': book.title,
'url': book.openlibrary_key
},
'target': {
'type': 'Collection',
'name': shelf.name,
'id': shelf.absolute_id,
}
}