diff --git a/bookwyrm/templates/book.html b/bookwyrm/templates/book.html index 4bbc8d10..dc8ffe91 100644 --- a/bookwyrm/templates/book.html +++ b/bookwyrm/templates/book.html @@ -9,6 +9,9 @@

{{ book.title }}{% if book.subtitle %}: {{ book.subtitle }}{% endif %} + {% if book.series %} + ({{ book.series }}{% if book.series_number %} #{{ book.series_number }}{% endif %})
+ {% endif %}

{% if book.authors %}

@@ -49,19 +52,44 @@ {% endif %} -
- {% for field in info_fields %} - {% if field.value %} -
{{ field.name }}:
-
{{ field.value }}
+
+
+ {% if book.isbn_13 %} +
+
ISBN:
+
{{ book.isbn_13 }}
+
+ {% endif %} + + {% if book.oclc_number %} +
+
OCLC Number:
+
{{ book.oclc_number }}
+
+ {% endif %} + + {% if book.asin %} +
+
ASIN:
+
{{ book.asin }}
+
+ {% endif %} +
+ +

+ {% if book.physical_format %}{{ book.physical_format | title }}{% if book.pages %},
{% endif %}{% endif %} + {% if book.pages %}{{ book.pages }} pages{% endif %} +

+ + {% if book.openlibrary_key %} +

View on OpenLibrary

{% endif %} - {% endfor %} -
+
-

{% include 'snippets/stars.html' with rating=rating %} ({{ reviews|length }} review{{ reviews|length|pluralize }})

+

{% include 'snippets/stars.html' with rating=rating %} ({{ review_count }} review{{ reviews|length|pluralize }})

{% include 'snippets/trimmed_text.html' with full=book|book_description %} @@ -145,16 +173,32 @@
+
+ {% if book.subjects %} +
+

Subjects

+
    + {% for subject in book.subjects %} +
  • {{ subject }}
  • + {% endfor %} +
+
+ {% endif %} + + {% if book.subject_places %} +
+

Places

+
    + {% for place in book.subject_placess %} +
  • {{ place }}
  • + {% endfor %} +
+
+ {% endif %} +
- -{% if not reviews %} -
-

No reviews yet!

-
-{% endif %} -
{% for review in reviews %}
@@ -162,9 +206,9 @@
{% endfor %} -
+
{% for rating in ratings %} -
+
{% include 'snippets/avatar.html' with user=rating.user %}
@@ -185,6 +229,5 @@
- {% endblock %} diff --git a/bookwyrm/templates/edit_book.html b/bookwyrm/templates/edit_book.html index b730f3e4..b0e262dd 100644 --- a/bookwyrm/templates/edit_book.html +++ b/bookwyrm/templates/edit_book.html @@ -37,10 +37,6 @@ {% for error in form.title.errors %}

{{ error | escape }}

{% endfor %} -

{{ form.sort_title }}

- {% for error in form.sort_title.errors %} -

{{ error | escape }}

- {% endfor %}

{{ form.subtitle }}

{% for error in form.subtitle.errors %}

{{ error | escape }}

@@ -113,12 +109,12 @@ {% for error in form.openlibrary_key.errors %}

{{ error | escape }}

{% endfor %} -

{{ form.librarything_key }}

- {% for error in form.librarything_key.errors %} +

{{ form.oclc_number }}

+ {% for error in form.oclc_number.errors %}

{{ error | escape }}

{% endfor %} -

{{ form.goodreads_key }}

- {% for error in form.goodreads_key.errors %} +

{{ form.asin }}

+ {% for error in form.ASIN.errors %}

{{ error | escape }}

{% endfor %}
diff --git a/bookwyrm/templates/snippets/rate_action.html b/bookwyrm/templates/snippets/rate_action.html index 49cb87ed..b5a599b1 100644 --- a/bookwyrm/templates/snippets/rate_action.html +++ b/bookwyrm/templates/snippets/rate_action.html @@ -1,8 +1,9 @@ {% load bookwyrm_tags %} +{% if request.user.is_authenticated %} Leave a rating
{% for i in '12345'|make_list %} -
+ {% csrf_token %} @@ -14,3 +15,4 @@
{% endfor %}
+{% endif %} diff --git a/bookwyrm/tests/test_views.py b/bookwyrm/tests/test_views.py index e94affb2..9dced9c5 100644 --- a/bookwyrm/tests/test_views.py +++ b/bookwyrm/tests/test_views.py @@ -116,17 +116,20 @@ class Views(TestCase): content='blah blah blah', user=rat, privacy='followers') rat_mention.mention_users.set([self.local_user]) - statuses = views.get_activity_feed(self.local_user, 'home') - self.assertEqual(len(statuses), 2) - self.assertEqual(statuses[1], public_status) - self.assertEqual(statuses[0], rat_mention) - statuses = views.get_activity_feed( - self.local_user, 'home', model=models.Comment) + self.local_user, + ['public', 'unlisted', 'followers'], + following_only=True, + queryset=models.Comment.objects + ) self.assertEqual(len(statuses), 1) self.assertEqual(statuses[0], public_status) - statuses = views.get_activity_feed(self.local_user, 'local') + statuses = views.get_activity_feed( + self.local_user, + ['public', 'followers'], + local_only=True + ) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[1], public_status) self.assertEqual(statuses[0], rat_public) @@ -135,19 +138,30 @@ class Views(TestCase): self.assertEqual(len(statuses), 1) self.assertEqual(statuses[0], direct_status) - statuses = views.get_activity_feed(self.local_user, 'federated') + statuses = views.get_activity_feed( + self.local_user, + ['public', 'followers'], + ) self.assertEqual(len(statuses), 3) self.assertEqual(statuses[2], public_status) self.assertEqual(statuses[1], rat_public) self.assertEqual(statuses[0], remote_status) - statuses = views.get_activity_feed(self.local_user, 'friends') + statuses = views.get_activity_feed( + self.local_user, + ['public', 'unlisted', 'followers'], + following_only=True + ) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[1], public_status) self.assertEqual(statuses[0], rat_mention) rat.followers.add(self.local_user) - statuses = views.get_activity_feed(self.local_user, 'friends') + statuses = views.get_activity_feed( + self.local_user, + ['public', 'unlisted', 'followers'], + following_only=True + ) self.assertEqual(len(statuses), 5) self.assertEqual(statuses[4], public_status) self.assertEqual(statuses[3], rat_public) diff --git a/bookwyrm/views.py b/bookwyrm/views.py index d493d9ae..9a6461de 100644 --- a/bookwyrm/views.py +++ b/bookwyrm/views.py @@ -83,7 +83,16 @@ def home_tab(request, tab): suggested_books = get_suggested_books(request.user) - activities = get_activity_feed(request.user, tab) + if tab == 'home': + activities = get_activity_feed( + request.user, ['public', 'unlisted', 'followers'], + following_only=True) + elif tab == 'local': + activities = get_activity_feed( + request.user, ['public', 'followers'], local_only=True) + else: + activities = get_activity_feed( + request.user, ['public', 'followers']) paginated = Paginator(activities, PAGE_LENGTH) activity_page = paginated.page(page) @@ -151,7 +160,7 @@ def discover_page(request): book__in=book.parent_work.editions.all() ) reviews = get_activity_feed( - request.user, 'federated', model=reviews) + request.user, ['public', 'unlisted'], queryset=reviews) ratings[book.id] = reviews.aggregate(Avg('rating'))['rating__avg'] data = { 'title': 'Discover', @@ -187,68 +196,62 @@ def direct_messages_page(request, page=1): return TemplateResponse(request, 'direct_messages.html', data) -def get_activity_feed(user, filter_level, model=models.Status): +def get_activity_feed( + user, privacy, local_only=False, following_only=False, + queryset=models.Status.objects): ''' get a filtered queryset of statuses ''' + privacy = privacy if isinstance(privacy, list) else [privacy] + # if we're looking at Status, we need this. We don't if it's Comment + if hasattr(queryset, 'select_subclasses'): + queryset = queryset.select_subclasses() + + # exclude deleted + queryset = queryset.exclude(deleted=True).order_by('-published_date') + + # you can't see followers only or direct messages if you're not logged in if user.is_anonymous: - user = None + privacy = [p for p in privacy if not p in ['followers', 'direct']] - if user: - following = models.User.objects.filter( - Q(followers=user) | Q(id=user.id) + # filter to only privided privacy levels + queryset = queryset.filter(privacy__in=privacy) + + # only include statuses the user follows + if following_only: + queryset = queryset.exclude( + ~Q(# remove everythign except + Q(user__in=user.following.all()) | # user follwoing + Q(user=user) |# is self + Q(mention_users=user)# mentions user + ), ) - else: - following = [] - - activities = model - if hasattr(model, 'objects'): - activities = model.objects - - activities = activities.filter( - deleted=False, - ).order_by( - '-published_date' - ) - - if filter_level == 'direct': - return activities.filter( - Q(user=user) | Q(mention_users=user), - privacy='direct' - ).distinct() - - # never show DMs in the regular feed - activities = activities.filter(~Q(privacy='direct')) - - - if hasattr(activities, 'select_subclasses'): - activities = activities.select_subclasses() - - if filter_level in ['friends', 'home']: - # people you follow and direct mentions - activities = activities.filter( - Q(user__in=following, privacy__in=[ - 'public', 'unlisted', 'followers' - ]) | Q(mention_users=user) | Q(user=user) - ).distinct() - elif filter_level == 'self': - activities = activities.filter(user=user, privacy='public') - elif filter_level == 'local': - # everyone on this instance except unlisted - activities = activities.filter( - Q(user__in=following, privacy='followers') | Q(privacy='public'), - user__local=True - ) - else: - # all activities from everyone you federate with - activities = activities.filter( - Q(user__in=following, privacy='followers') | Q(privacy='public') + # exclude followers-only statuses the user doesn't follow + elif 'followers' in privacy: + queryset = queryset.exclude( + ~Q(# user isn't following and it isn't their own status + Q(user__in=user.following.all()) | Q(user=user) + ), + privacy='followers' # and the status is followers only ) + # exclude direct messages not intended for the user + if 'direct' in privacy: + queryset = queryset.exclude( + ~Q( + Q(user=user) | Q(mention_users=user) + ), privacy='direct' + ) + + # filter for only local status + if local_only: + queryset = queryset.filter(user__local=True) + + # remove statuses that have boosts in the same queryset try: - activities = activities.filter(~Q(boosters__in=activities)) + queryset = queryset.filter(~Q(boosters__in=queryset)) except ValueError: pass - return activities + return queryset @require_GET @@ -462,7 +465,11 @@ def user_page(request, username): break # user's posts - activities = get_activity_feed(user, 'self') + activities = get_activity_feed( + user, + ['public', 'unlisted', 'followers'], + queryset=models.Status.objects.filter(user=request.user) + ) paginated = Paginator(activities, PAGE_LENGTH) activity_page = paginated.page(page) @@ -629,10 +636,16 @@ def book_page(request, book_id): book__in=work.editions.all(), ) # all reviews for the book - reviews = get_activity_feed(request.user, 'federated', model=reviews) + reviews = get_activity_feed( + request.user, + ['public', 'unlisted', 'followers', 'direct'], + queryset=reviews + ) # the reviews to show - paginated = Paginator(reviews.filter(content__isnull=False), PAGE_LENGTH) + paginated = Paginator(reviews.exclude( + Q(content__isnull=True) | Q(content='') + ), PAGE_LENGTH) reviews_page = paginated.page(page) prev_page = next_page = None @@ -668,7 +681,8 @@ def book_page(request, book_id): 'title': book.title, 'book': book, 'reviews': reviews_page, - 'ratings': reviews.filter(content__isnull=True), + 'review_count': reviews.count(), + 'ratings': reviews.filter(Q(content__isnull=True) | Q(content='')), 'rating': reviews.aggregate(Avg('rating'))['rating__avg'], 'tags': models.UserTag.objects.filter(book=book), 'user_tags': user_tags, @@ -676,14 +690,6 @@ def book_page(request, book_id): 'other_edition_shelves': other_edition_shelves, 'readthroughs': readthroughs, 'path': '/book/%s' % book_id, - 'info_fields': [ - {'name': 'ISBN', 'value': book.isbn_13}, - {'name': 'OCLC number', 'value': book.oclc_number}, - {'name': 'OpenLibrary ID', 'value': book.openlibrary_key}, - {'name': 'Goodreads ID', 'value': book.goodreads_key}, - {'name': 'Format', 'value': book.physical_format}, - {'name': 'Pages', 'value': book.pages}, - ], 'next': next_page, 'prev': prev_page, }