diff --git a/bookwyrm/connectors/bookwyrm_connector.py b/bookwyrm/connectors/bookwyrm_connector.py index 6a1432f8..5ad795cd 100644 --- a/bookwyrm/connectors/bookwyrm_connector.py +++ b/bookwyrm/connectors/bookwyrm_connector.py @@ -84,7 +84,7 @@ class Connector(AbstractConnector): if not response.ok: response.raise_for_status() - image_name = str(uuid4()) + cover_url.split('.')[-1] + image_name = str(uuid4()) + '.' + cover_url.split('.')[-1] image_content = ContentFile(response.content) return [image_name, image_content] diff --git a/bookwyrm/incoming.py b/bookwyrm/incoming.py index a91193e4..a7823f43 100644 --- a/bookwyrm/incoming.py +++ b/bookwyrm/incoming.py @@ -32,7 +32,6 @@ def inbox(request, username): @csrf_exempt def shared_inbox(request): ''' incoming activitypub events ''' - # TODO: should this be functionally different from the non-shared inbox?? if request.method == 'GET': return HttpResponseNotFound() @@ -217,6 +216,11 @@ def handle_create(activity): # we really oughtn't even be sending in this case return + # deduplicate incoming activities + status_id = activity['object']['id'] + if models.Status.objects.filter(remote_id=status_id).count(): + return + status = status_builder.create_status(activity['object']) # create a notification if this is a reply diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index f9a217e7..efe1a58f 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -75,6 +75,16 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): )) return tags + @property + def ap_status_image(self): + ''' attach a book cover, if relevent ''' + if hasattr(self, 'book'): + return self.book.ap_cover + if self.mention_books.first(): + return self.mention_books.first().ap_cover + return None + + shared_mappings = [ ActivityMapping('url', 'remote_id', lambda x: None), ActivityMapping('id', 'remote_id'), @@ -100,6 +110,7 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): pure_activity_mappings = shared_mappings + [ ActivityMapping('name', 'ap_pure_name'), ActivityMapping('content', 'ap_pure_content'), + ActivityMapping('attachment', 'ap_status_image'), ] activity_serializer = activitypub.Note diff --git a/bookwyrm/status.py b/bookwyrm/status.py index ed1befac..4baaed6d 100644 --- a/bookwyrm/status.py +++ b/bookwyrm/status.py @@ -2,7 +2,6 @@ from datetime import datetime from bookwyrm import activitypub, books_manager, models -from bookwyrm.books_manager import get_or_create_book from bookwyrm.sanitize_html import InputHtmlParser diff --git a/bookwyrm/views.py b/bookwyrm/views.py index 1f7cd527..de3bac6c 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -60,23 +60,7 @@ def home_tab(request, tab): except ValueError: page = 1 - max_books = 5 - book_count = 0 - preset_shelves = ['reading', 'read', 'to-read'] - suggested_books = [] - for preset in preset_shelves: - limit = max_books - book_count - shelf = request.user.shelf_set.get(identifier=preset) - - shelf_books = shelf.shelfbook_set.order_by( - '-updated_date' - ).all()[:limit] - shelf_preview = { - 'name': shelf.name, - 'books': [s.book for s in shelf_books] - } - suggested_books.append(shelf_preview) - book_count += len(shelf_preview['books']) + suggested_books = get_suggested_books(request.user) activities = get_activity_feed(request.user, tab) @@ -100,6 +84,29 @@ def home_tab(request, tab): return TemplateResponse(request, 'feed.html', data) +def get_suggested_books(user, max_books=5): + ''' helper to get a user's recent books ''' + book_count = 0 + preset_shelves = ['reading', 'read', 'to-read'] + suggested_books = [] + for preset in preset_shelves: + limit = max_books - book_count + shelf = user.shelf_set.get(identifier=preset) + + shelf_books = shelf.shelfbook_set.order_by( + '-updated_date' + ).all()[:limit] + if not shelf_books: + continue + shelf_preview = { + 'name': shelf.name, + 'books': [s.book for s in shelf_books] + } + suggested_books.append(shelf_preview) + book_count += len(shelf_preview['books']) + return suggested_books + + def get_activity_feed(user, filter_level, model=models.Status): ''' get a filtered queryset of statuses ''' # status updates for your follow network