@@ -49,7 +54,8 @@
{% if goal %}
-
{% now 'Y' %} Reading Goal
+ {% now 'Y' as current_year%}
+ {% blocktrans %}{{ current_year }} Reading Goal{% endblocktrans %}
{% include 'snippets/goal_progress.html' with goal=goal %}
{% endif %}
diff --git a/bookwyrm/templatetags/bookwyrm_tags.py b/bookwyrm/templatetags/bookwyrm_tags.py
index bccd8c75..9d84d1ff 100644
--- a/bookwyrm/templatetags/bookwyrm_tags.py
+++ b/bookwyrm/templatetags/bookwyrm_tags.py
@@ -77,7 +77,12 @@ def related_status(notification):
def active_shelf(context, book):
"""check what shelf a user has a book on, if any"""
if hasattr(book, "current_shelves"):
- return book.current_shelves[0] if len(book.current_shelves) else {"book": book}
+ read_shelves = [
+ s
+ for s in book.current_shelves
+ if s.shelf.identifier in models.Shelf.READ_STATUS_IDENTIFIERS
+ ]
+ return read_shelves[0] if len(read_shelves) else {"book": book}
shelf = (
models.ShelfBook.objects.filter(
diff --git a/bookwyrm/tests/views/test_updates.py b/bookwyrm/tests/views/test_updates.py
index 27181fc9..e7b466cc 100644
--- a/bookwyrm/tests/views/test_updates.py
+++ b/bookwyrm/tests/views/test_updates.py
@@ -50,10 +50,17 @@ class UpdateViews(TestCase):
request = self.factory.get("")
request.user = self.local_user
- with patch("bookwyrm.activitystreams.ActivityStream.get_unread_count") as mock:
- mock.return_value = 3
- result = views.get_unread_status_count(request, "home")
+ with patch(
+ "bookwyrm.activitystreams.ActivityStream.get_unread_count"
+ ) as mock_count:
+ with patch(
+ "bookwyrm.activitystreams.ActivityStream.get_unread_count_by_status_type"
+ ) as mock_count_by_status:
+ mock_count.return_value = 3
+ mock_count_by_status.return_value = {"review": 5}
+ result = views.get_unread_status_count(request, "home")
self.assertIsInstance(result, JsonResponse)
data = json.loads(result.getvalue())
self.assertEqual(data["count"], 3)
+ self.assertEqual(data["count_by_type"]["review"], 5)
diff --git a/bookwyrm/utils/isni.py b/bookwyrm/utils/isni.py
index a35c3f24..65d20c85 100644
--- a/bookwyrm/utils/isni.py
+++ b/bookwyrm/utils/isni.py
@@ -19,7 +19,7 @@ def request_isni_data(search_index, search_term, max_records=5):
"recordPacking": "xml",
"sortKeys": "RLV,pica,0,,",
}
- result = requests.get("http://isni.oclc.org/sru/", params=query_params, timeout=10)
+ result = requests.get("http://isni.oclc.org/sru/", params=query_params, timeout=15)
# the OCLC ISNI server asserts the payload is encoded
# in latin1, but we know better
result.encoding = "utf-8"
diff --git a/bookwyrm/views/books/edit_book.py b/bookwyrm/views/books/edit_book.py
index fc13aa6c..755c25b4 100644
--- a/bookwyrm/views/books/edit_book.py
+++ b/bookwyrm/views/books/edit_book.py
@@ -51,13 +51,14 @@ class EditBook(View):
if not form.is_valid():
return TemplateResponse(request, "book/edit/edit_book.html", data)
- add_author = request.POST.get("add_author")
- # we're adding an author through a free text field
+ # filter out empty author fields
+ add_author = [author for author in request.POST.getlist("add_author") if author]
if add_author:
data["add_author"] = add_author
data["author_matches"] = []
data["isni_matches"] = []
- for author in add_author.split(","):
+
+ for author in add_author:
if not author:
continue
# check for existing authors
diff --git a/bookwyrm/views/feed.py b/bookwyrm/views/feed.py
index 1e44884f..7cf56d48 100644
--- a/bookwyrm/views/feed.py
+++ b/bookwyrm/views/feed.py
@@ -10,10 +10,11 @@ from django.utils.decorators import method_decorator
from django.views import View
from bookwyrm import activitystreams, forms, models
+from bookwyrm.models.user import FeedFilterChoices
from bookwyrm.activitypub import ActivitypubResponse
from bookwyrm.settings import PAGE_LENGTH, STREAMS
from bookwyrm.suggested_users import suggested_users
-from .helpers import get_user_from_username
+from .helpers import filter_stream_by_status_type, get_user_from_username
from .helpers import is_api_request, is_bookwyrm_request
@@ -22,7 +23,17 @@ from .helpers import is_api_request, is_bookwyrm_request
class Feed(View):
"""activity stream"""
- def get(self, request, tab):
+ def post(self, request, tab):
+ """save feed settings form, with a silent validation fail"""
+ settings_saved = False
+ form = forms.FeedStatusTypesForm(request.POST, instance=request.user)
+ if form.is_valid():
+ form.save()
+ settings_saved = True
+
+ return self.get(request, tab, settings_saved)
+
+ def get(self, request, tab, settings_saved=False):
"""user's homepage with activity feed"""
tab = [s for s in STREAMS if s["key"] == tab]
tab = tab[0] if tab else STREAMS[0]
@@ -30,7 +41,11 @@ class Feed(View):
activities = activitystreams.streams[tab["key"]].get_activity_stream(
request.user
)
- paginated = Paginator(activities, PAGE_LENGTH)
+ filtered_activities = filter_stream_by_status_type(
+ activities,
+ allowed_types=request.user.feed_status_types,
+ )
+ paginated = Paginator(filtered_activities, PAGE_LENGTH)
suggestions = suggested_users.get_suggestions(request.user)
@@ -43,6 +58,9 @@ class Feed(View):
"tab": tab,
"streams": STREAMS,
"goal_form": forms.GoalForm(),
+ "feed_status_types_options": FeedFilterChoices,
+ "allowed_status_types": request.user.feed_status_types,
+ "settings_saved": settings_saved,
"path": f"/{tab['key']}",
},
}
diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py
index f28d0102..173cb85b 100644
--- a/bookwyrm/views/helpers.py
+++ b/bookwyrm/views/helpers.py
@@ -6,6 +6,7 @@ import dateutil.tz
from dateutil.parser import ParserError
from requests import HTTPError
+from django.db.models import Q
from django.http import Http404
from django.utils import translation
@@ -153,3 +154,29 @@ def set_language(user, response):
translation.activate(user.preferred_language)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user.preferred_language)
return response
+
+
+def filter_stream_by_status_type(activities, allowed_types=None):
+ """filter out activities based on types"""
+ if not allowed_types:
+ allowed_types = []
+
+ if "review" not in allowed_types:
+ activities = activities.filter(
+ Q(review__isnull=True), Q(boost__boosted_status__review__isnull=True)
+ )
+ if "comment" not in allowed_types:
+ activities = activities.filter(
+ Q(comment__isnull=True), Q(boost__boosted_status__comment__isnull=True)
+ )
+ if "quotation" not in allowed_types:
+ activities = activities.filter(
+ Q(quotation__isnull=True), Q(boost__boosted_status__quotation__isnull=True)
+ )
+ if "everything" not in allowed_types:
+ activities = activities.filter(
+ Q(generatednote__isnull=True),
+ Q(boost__boosted_status__generatednote__isnull=True),
+ )
+
+ return activities
diff --git a/bookwyrm/views/reading.py b/bookwyrm/views/reading.py
index 54427ffb..35847558 100644
--- a/bookwyrm/views/reading.py
+++ b/bookwyrm/views/reading.py
@@ -9,6 +9,7 @@ from django.views import View
from django.views.decorators.http import require_POST
from bookwyrm import models
+from bookwyrm.views.shelf.shelf_actions import unshelve
from .status import CreateStatus
from .helpers import get_edition, handle_reading_status, is_api_request
from .helpers import load_date_in_user_tz_as_utc
@@ -16,6 +17,7 @@ from .helpers import load_date_in_user_tz_as_utc
@method_decorator(login_required, name="dispatch")
# pylint: disable=no-self-use
+# pylint: disable=too-many-return-statements
class ReadingStatus(View):
"""consider reading a book"""
@@ -89,8 +91,21 @@ class ReadingStatus(View):
privacy = request.POST.get("privacy")
handle_reading_status(request.user, desired_shelf, book, privacy)
+ # if the request includes a "shelf" value we are using the 'move' button
+ if bool(request.POST.get("shelf")):
+ # unshelve the existing shelf
+ this_shelf = request.POST.get("shelf")
+ if (
+ bool(current_status_shelfbook)
+ and int(this_shelf) != int(current_status_shelfbook.shelf.id)
+ and current_status_shelfbook.shelf.identifier
+ != desired_shelf.identifier
+ ):
+ return unshelve(request, book_id=book_id)
+
if is_api_request(request):
return HttpResponse()
+
return redirect(referer)
diff --git a/bookwyrm/views/shelf/shelf_actions.py b/bookwyrm/views/shelf/shelf_actions.py
index 702b72c1..5e7e6c0c 100644
--- a/bookwyrm/views/shelf/shelf_actions.py
+++ b/bookwyrm/views/shelf/shelf_actions.py
@@ -91,13 +91,13 @@ def shelve(request):
@login_required
@require_POST
-def unshelve(request):
+def unshelve(request, book_id=False):
"""remove a book from a user's shelf"""
- book = get_object_or_404(models.Edition, id=request.POST.get("book"))
+ identity = book_id if book_id else request.POST.get("book")
+ book = get_object_or_404(models.Edition, id=identity)
shelf_book = get_object_or_404(
models.ShelfBook, book=book, shelf__id=request.POST["shelf"]
)
shelf_book.raise_not_deletable(request.user)
-
shelf_book.delete()
return redirect(request.headers.get("Referer", "/"))
diff --git a/bookwyrm/views/status.py b/bookwyrm/views/status.py
index 8e487bf9..bb69d30c 100644
--- a/bookwyrm/views/status.py
+++ b/bookwyrm/views/status.py
@@ -54,6 +54,7 @@ class CreateStatus(View):
data = {"book": book}
return TemplateResponse(request, "compose.html", data)
+ # pylint: disable=too-many-branches
def post(self, request, status_type, existing_status_id=None):
"""create status of whatever type"""
created = not existing_status_id
@@ -117,11 +118,12 @@ class CreateStatus(View):
status.save(created=created)
- # update a readthorugh, if needed
- try:
- edit_readthrough(request)
- except Http404:
- pass
+ # update a readthrough, if needed
+ if bool(request.POST.get("id")):
+ try:
+ edit_readthrough(request)
+ except Http404:
+ pass
if is_api_request(request):
return HttpResponse()
diff --git a/bookwyrm/views/updates.py b/bookwyrm/views/updates.py
index 72614562..2bbc5477 100644
--- a/bookwyrm/views/updates.py
+++ b/bookwyrm/views/updates.py
@@ -22,4 +22,9 @@ def get_unread_status_count(request, stream="home"):
stream = activitystreams.streams.get(stream)
if not stream:
return JsonResponse({})
- return JsonResponse({"count": stream.get_unread_count(request.user)})
+ return JsonResponse(
+ {
+ "count": stream.get_unread_count(request.user),
+ "count_by_type": stream.get_unread_count_by_status_type(request.user),
+ }
+ )
diff --git a/bw-dev b/bw-dev
index 75c69662..cfe8747f 100755
--- a/bw-dev
+++ b/bw-dev
@@ -118,6 +118,7 @@ case "$CMD" in
git checkout l10n_main locale/pt_BR
git checkout l10n_main locale/zh_Hans
git checkout l10n_main locale/zh_Hant
+ runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@
runweb django-admin compilemessages --ignore venv
;;
build)
diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po
index f5df1265..b931da69 100644
--- a/locale/en_US/LC_MESSAGES/django.po
+++ b/locale/en_US/LC_MESSAGES/django.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-11-17 18:03+0000\n"
+"POT-Creation-Date: 2021-12-02 18:24+0000\n"
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
"Last-Translator: Mouse Reeve
\n"
"Language-Team: English \n"
@@ -18,58 +18,58 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-#: bookwyrm/forms.py:248
+#: bookwyrm/forms.py:262
msgid "A user with this email already exists."
msgstr ""
-#: bookwyrm/forms.py:262
+#: bookwyrm/forms.py:276
msgid "One Day"
msgstr ""
-#: bookwyrm/forms.py:263
+#: bookwyrm/forms.py:277
msgid "One Week"
msgstr ""
-#: bookwyrm/forms.py:264
+#: bookwyrm/forms.py:278
msgid "One Month"
msgstr ""
-#: bookwyrm/forms.py:265
+#: bookwyrm/forms.py:279
msgid "Does Not Expire"
msgstr ""
-#: bookwyrm/forms.py:269
+#: bookwyrm/forms.py:283
#, python-brace-format
msgid "{i} uses"
msgstr ""
-#: bookwyrm/forms.py:270
+#: bookwyrm/forms.py:284
msgid "Unlimited"
msgstr ""
-#: bookwyrm/forms.py:338
+#: bookwyrm/forms.py:352
msgid "List Order"
msgstr ""
-#: bookwyrm/forms.py:339
+#: bookwyrm/forms.py:353
msgid "Book Title"
msgstr ""
-#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149
+#: bookwyrm/forms.py:354 bookwyrm/templates/shelf/shelf.html:149
#: bookwyrm/templates/shelf/shelf.html:181
#: bookwyrm/templates/snippets/create_status/review.html:33
msgid "Rating"
msgstr ""
-#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110
+#: bookwyrm/forms.py:356 bookwyrm/templates/lists/list.html:110
msgid "Sort By"
msgstr ""
-#: bookwyrm/forms.py:346
+#: bookwyrm/forms.py:360
msgid "Ascending"
msgstr ""
-#: bookwyrm/forms.py:347
+#: bookwyrm/forms.py:361
msgid "Descending"
msgstr ""
@@ -153,6 +153,22 @@ msgstr ""
msgid "A user with that username already exists."
msgstr ""
+#: bookwyrm/models/user.py:32 bookwyrm/templates/book/book.html:218
+msgid "Reviews"
+msgstr ""
+
+#: bookwyrm/models/user.py:33
+msgid "Comments"
+msgstr ""
+
+#: bookwyrm/models/user.py:34
+msgid "Quotations"
+msgstr ""
+
+#: bookwyrm/models/user.py:35
+msgid "Everything else"
+msgstr ""
+
#: bookwyrm/settings.py:118
msgid "Home Timeline"
msgstr ""
@@ -227,47 +243,51 @@ msgstr ""
msgid "Something went wrong! Sorry about that."
msgstr ""
-#: bookwyrm/templates/author/author.html:17
#: bookwyrm/templates/author/author.html:18
+#: bookwyrm/templates/author/author.html:19
msgid "Edit Author"
msgstr ""
-#: bookwyrm/templates/author/author.html:34
+#: bookwyrm/templates/author/author.html:35
#: bookwyrm/templates/author/edit_author.html:43
msgid "Aliases:"
msgstr ""
-#: bookwyrm/templates/author/author.html:45
+#: bookwyrm/templates/author/author.html:46
msgid "Born:"
msgstr ""
-#: bookwyrm/templates/author/author.html:52
+#: bookwyrm/templates/author/author.html:53
msgid "Died:"
msgstr ""
-#: bookwyrm/templates/author/author.html:61
+#: bookwyrm/templates/author/author.html:62
msgid "Wikipedia"
msgstr ""
-#: bookwyrm/templates/author/author.html:69
+#: bookwyrm/templates/author/author.html:70
+msgid "View ISNI record"
+msgstr ""
+
+#: bookwyrm/templates/author/author.html:78
#: bookwyrm/templates/book/book.html:94
msgid "View on OpenLibrary"
msgstr ""
-#: bookwyrm/templates/author/author.html:77
+#: bookwyrm/templates/author/author.html:86
#: bookwyrm/templates/book/book.html:97
msgid "View on Inventaire"
msgstr ""
-#: bookwyrm/templates/author/author.html:85
+#: bookwyrm/templates/author/author.html:94
msgid "View on LibraryThing"
msgstr ""
-#: bookwyrm/templates/author/author.html:93
+#: bookwyrm/templates/author/author.html:102
msgid "View on Goodreads"
msgstr ""
-#: bookwyrm/templates/author/author.html:108
+#: bookwyrm/templates/author/author.html:117
#, python-format
msgid "Books by %(name)s"
msgstr ""
@@ -277,17 +297,17 @@ msgid "Edit Author:"
msgstr ""
#: bookwyrm/templates/author/edit_author.html:13
-#: bookwyrm/templates/book/edit/edit_book.html:18
+#: bookwyrm/templates/book/edit/edit_book.html:19
msgid "Added:"
msgstr ""
#: bookwyrm/templates/author/edit_author.html:14
-#: bookwyrm/templates/book/edit/edit_book.html:21
+#: bookwyrm/templates/book/edit/edit_book.html:22
msgid "Updated:"
msgstr ""
#: bookwyrm/templates/author/edit_author.html:16
-#: bookwyrm/templates/book/edit/edit_book.html:25
+#: bookwyrm/templates/book/edit/edit_book.html:26
msgid "Last edited by:"
msgstr ""
@@ -347,7 +367,7 @@ msgstr ""
#: bookwyrm/templates/author/edit_author.html:118
#: bookwyrm/templates/book/book.html:140
-#: bookwyrm/templates/book/edit/edit_book.html:110
+#: bookwyrm/templates/book/edit/edit_book.html:121
#: bookwyrm/templates/book/readthrough.html:76
#: bookwyrm/templates/groups/form.html:24
#: bookwyrm/templates/lists/bookmark_button.html:15
@@ -366,8 +386,8 @@ msgstr ""
#: bookwyrm/templates/author/edit_author.html:119
#: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190
#: bookwyrm/templates/book/cover_modal.html:32
-#: bookwyrm/templates/book/edit/edit_book.html:112
-#: bookwyrm/templates/book/edit/edit_book.html:115
+#: bookwyrm/templates/book/edit/edit_book.html:123
+#: bookwyrm/templates/book/edit/edit_book.html:126
#: bookwyrm/templates/book/readthrough.html:77
#: bookwyrm/templates/groups/delete_group_modal.html:17
#: bookwyrm/templates/lists/delete_list_modal.html:17
@@ -445,10 +465,6 @@ msgstr ""
msgid "You don't have any reading activity for this book."
msgstr ""
-#: bookwyrm/templates/book/book.html:218
-msgid "Reviews"
-msgstr ""
-
#: bookwyrm/templates/book/book.html:223
msgid "Your reviews"
msgstr ""
@@ -513,56 +529,60 @@ msgstr ""
msgid "Load cover from url:"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:5
-#: bookwyrm/templates/book/edit/edit_book.html:11
+#: bookwyrm/templates/book/edit/edit_book.html:6
+#: bookwyrm/templates/book/edit/edit_book.html:12
#, python-format
msgid "Edit \"%(book_title)s\""
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:5
-#: bookwyrm/templates/book/edit/edit_book.html:13
+#: bookwyrm/templates/book/edit/edit_book.html:6
+#: bookwyrm/templates/book/edit/edit_book.html:14
msgid "Add Book"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:47
+#: bookwyrm/templates/book/edit/edit_book.html:48
msgid "Confirm Book Info"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:55
+#: bookwyrm/templates/book/edit/edit_book.html:56
#, python-format
-msgid "Is \"%(name)s\" an existing author?"
+msgid "Is \"%(name)s\" one of these authors?"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:64
-#, python-format
-msgid "Author of %(book_title)s"
+#: bookwyrm/templates/book/edit/edit_book.html:67
+#: bookwyrm/templates/book/edit/edit_book.html:69
+msgid "Author of "
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:68
+#: bookwyrm/templates/book/edit/edit_book.html:69
+msgid "Find more information at isni.org"
+msgstr ""
+
+#: bookwyrm/templates/book/edit/edit_book.html:79
msgid "This is a new author"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:75
+#: bookwyrm/templates/book/edit/edit_book.html:86
#, python-format
msgid "Creating a new author: %(name)s"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:82
+#: bookwyrm/templates/book/edit/edit_book.html:93
msgid "Is this an edition of an existing work?"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:90
+#: bookwyrm/templates/book/edit/edit_book.html:101
msgid "This is a new work"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:97
+#: bookwyrm/templates/book/edit/edit_book.html:108
#: bookwyrm/templates/groups/members.html:16
#: bookwyrm/templates/landing/password_reset.html:30
#: bookwyrm/templates/snippets/remove_from_group_button.html:16
msgid "Confirm"
msgstr ""
-#: bookwyrm/templates/book/edit/edit_book.html:99
+#: bookwyrm/templates/book/edit/edit_book.html:110
#: bookwyrm/templates/feed/status.html:9
msgid "Back"
msgstr ""
@@ -1016,6 +1036,22 @@ msgstr ""
msgid "Learn more about %(site_name)s:"
msgstr ""
+#: bookwyrm/templates/email/moderation_report/html_content.html:6
+#: bookwyrm/templates/email/moderation_report/text_content.html:5
+#, python-format
+msgid "@%(reporter)s has flagged behavior by @%(reportee)s for moderation. "
+msgstr ""
+
+#: bookwyrm/templates/email/moderation_report/html_content.html:9
+#: bookwyrm/templates/email/moderation_report/text_content.html:7
+msgid "View report"
+msgstr ""
+
+#: bookwyrm/templates/email/moderation_report/subject.html:2
+#, python-format
+msgid "New report for %(site_name)s"
+msgstr ""
+
#: bookwyrm/templates/email/password_reset/html_content.html:6
#: bookwyrm/templates/email/password_reset/text_content.html:4
#, python-format
@@ -1058,15 +1094,31 @@ msgstr ""
msgid "You have no messages right now."
msgstr ""
-#: bookwyrm/templates/feed/feed.html:22
+#: bookwyrm/templates/feed/feed.html:23
+msgid "Feed settings"
+msgstr ""
+
+#: bookwyrm/templates/feed/feed.html:26
+msgid "Saved!"
+msgstr ""
+
+#: bookwyrm/templates/feed/feed.html:47
+msgid "Save settings"
+msgstr ""
+
+#: bookwyrm/templates/feed/feed.html:56
#, python-format
msgid "load 0 unread status(es)"
msgstr ""
-#: bookwyrm/templates/feed/feed.html:38
+#: bookwyrm/templates/feed/feed.html:72
msgid "There aren't any activities right now! Try following a user to get started"
msgstr ""
+#: bookwyrm/templates/feed/feed.html:73
+msgid "Alternatively, you can try enabling more status types"
+msgstr ""
+
#: bookwyrm/templates/feed/goal_card.html:6
#: bookwyrm/templates/feed/layout.html:90
#: bookwyrm/templates/user/goal_form.html:6
@@ -3842,7 +3894,7 @@ msgstr ""
msgid "File exceeds maximum size: 10MB"
msgstr ""
-#: bookwyrm/templatetags/utilities.py:31
+#: bookwyrm/templatetags/utilities.py:34
#, python-format
msgid "%(title)s: %(subtitle)s"
msgstr ""
diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo
index 4cdcbf8e..cc69e82c 100644
Binary files a/locale/fr_FR/LC_MESSAGES/django.mo and b/locale/fr_FR/LC_MESSAGES/django.mo differ
diff --git a/locale/lt_LT/LC_MESSAGES/django.mo b/locale/lt_LT/LC_MESSAGES/django.mo
index 728d0e90..51e78110 100644
Binary files a/locale/lt_LT/LC_MESSAGES/django.mo and b/locale/lt_LT/LC_MESSAGES/django.mo differ
diff --git a/locale/lt_LT/LC_MESSAGES/django.po b/locale/lt_LT/LC_MESSAGES/django.po
index 16110b06..d2ec3298 100644
--- a/locale/lt_LT/LC_MESSAGES/django.po
+++ b/locale/lt_LT/LC_MESSAGES/django.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n"
-"PO-Revision-Date: 2021-11-22 08:50\n"
+"PO-Revision-Date: 2021-11-29 13:53\n"
"Last-Translator: Mouse Reeve \n"
"Language-Team: Lithuanian\n"
"Language: lt\n"
@@ -591,7 +591,7 @@ msgstr "Kalbos:"
#: bookwyrm/templates/book/edit/edit_book_form.html:74
msgid "Publication"
-msgstr "Paskelbimas"
+msgstr "Leidimas"
#: bookwyrm/templates/book/edit/edit_book_form.html:77
msgid "Publisher:"
@@ -930,7 +930,7 @@ msgstr "%(username)s įvertino %(username)s reviewed %(book_title)s"
-msgstr "%(username)s peržiūrėjo %(book_title)s"
+msgstr "%(username)s apžvelgė %(book_title)s"
#: bookwyrm/templates/discover/card-header.html:31
#, python-format
@@ -1114,7 +1114,7 @@ msgstr "Šiuo metu skaitoma"
#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12
#: bookwyrm/templates/user/books_header.html:8
msgid "Read"
-msgstr "Perskaičiau"
+msgstr "Perskaityta"
#: bookwyrm/templates/feed/suggested_users.html:5
#: bookwyrm/templates/get_started/users.html:6
@@ -1483,7 +1483,7 @@ msgstr "Lentyna"
#: bookwyrm/templates/import/manual_review.html:13
#: bookwyrm/templates/snippets/create_status.html:17
msgid "Review"
-msgstr "Peržiūra"
+msgstr "Apžvalga"
#: bookwyrm/templates/import/import_status.html:119
msgid "Book"
@@ -1513,7 +1513,7 @@ msgstr "Importuota"
#: bookwyrm/templates/import/import_status.html:182
msgid "Needs manual review"
-msgstr "Reikalingas manualus atsiliepimas"
+msgstr "Reikalinga peržvelgti"
#: bookwyrm/templates/import/import_status.html:195
msgid "Retry"
@@ -2416,7 +2416,7 @@ msgstr[3] "%(display_count)s prašymai pakviesti"
#: bookwyrm/templates/settings/dashboard/dashboard.html:65
msgid "Instance Activity"
-msgstr "Pavyzdinė veikla"
+msgstr "Serverio statistika"
#: bookwyrm/templates/settings/dashboard/dashboard.html:83
msgid "Interval:"
@@ -2436,7 +2436,7 @@ msgstr "Naudotojo prisijungimo veikla"
#: bookwyrm/templates/settings/dashboard/dashboard.html:112
msgid "Status activity"
-msgstr "Būsenos veikla"
+msgstr "Būsenos"
#: bookwyrm/templates/settings/dashboard/dashboard.html:118
msgid "Works created"
@@ -3467,7 +3467,7 @@ msgstr "%(percent)s%% baigta!"
#: bookwyrm/templates/snippets/goal_progress.html:12
#, python-format
msgid "You've read %(read_count)s of %(goal_count)s books."
-msgstr "Perskaitėte %(read_count)s iš %(goal_count)s knygų."
+msgstr "Perskaityta %(read_count)s iš %(goal_count)s knygų."
#: bookwyrm/templates/snippets/goal_progress.html:14
#, python-format
@@ -3504,7 +3504,7 @@ msgstr "Viešas"
#: bookwyrm/templates/snippets/privacy_select.html:14
#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14
msgid "Unlisted"
-msgstr "Nėra sąraše"
+msgstr "Slaptas"
#: bookwyrm/templates/snippets/privacy-icons.html:12
msgid "Followers-only"
@@ -3873,7 +3873,7 @@ msgstr[3] "%(mutuals_display)s sekėjai, kuriuos sekate jūs"
#: bookwyrm/templates/user/user_preview.html:38
msgid "No followers you follow"
-msgstr "Jūs nieko nesekate"
+msgstr "Jūs kartu nieko nesekate"
#: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28
msgid "File exceeds maximum size: 10MB"
diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo
index 1d1227f8..3e559018 100644
Binary files a/locale/zh_Hans/LC_MESSAGES/django.mo and b/locale/zh_Hans/LC_MESSAGES/django.mo differ
diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po
index 1b86621d..e52dfc4f 100644
--- a/locale/zh_Hans/LC_MESSAGES/django.po
+++ b/locale/zh_Hans/LC_MESSAGES/django.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n"
-"PO-Revision-Date: 2021-11-17 18:42\n"
+"PO-Revision-Date: 2021-11-29 09:31\n"
"Last-Translator: Mouse Reeve \n"
"Language-Team: Chinese Simplified\n"
"Language: zh\n"
@@ -184,7 +184,7 @@ msgstr "Español(西班牙语)"
#: bookwyrm/settings.py:168
msgid "Galego (Galician)"
-msgstr ""
+msgstr "Galego(加利西亚语)"
#: bookwyrm/settings.py:169
msgid "Français (French)"
@@ -192,11 +192,11 @@ msgstr "Français(法语)"
#: bookwyrm/settings.py:170
msgid "Lietuvių (Lithuanian)"
-msgstr ""
+msgstr "Lietuvių(立陶宛语)"
#: bookwyrm/settings.py:171
msgid "Português - Brasil (Brazilian Portuguese)"
-msgstr "葡萄牙语-巴西(巴西的葡语)"
+msgstr "Português - Brasil(巴西葡萄牙语)"
#: bookwyrm/settings.py:172
msgid "简体中文 (Simplified Chinese)"
@@ -906,12 +906,12 @@ msgstr "%(username)s 想要阅读 %(username)s finished reading %(book_title)s"
-msgstr ""
+msgstr "%(username)s 完成了 %(book_title)s 的阅读"
#: bookwyrm/templates/discover/card-header.html:18
#, python-format
msgid "%(username)s started reading %(book_title)s"
-msgstr ""
+msgstr "%(username)s 开始阅读 %(book_title)s"
#: bookwyrm/templates/discover/card-header.html:23
#, python-format
@@ -1395,11 +1395,11 @@ msgstr "导入状态"
#: bookwyrm/templates/import/import_status.html:13
#: bookwyrm/templates/import/import_status.html:27
msgid "Retry Status"
-msgstr ""
+msgstr "重试状态"
#: bookwyrm/templates/import/import_status.html:22
msgid "Imports"
-msgstr ""
+msgstr "导入"
#: bookwyrm/templates/import/import_status.html:39
msgid "Import started:"
@@ -1407,36 +1407,36 @@ msgstr "导入开始:"
#: bookwyrm/templates/import/import_status.html:48
msgid "In progress"
-msgstr ""
+msgstr "正在进行"
#: bookwyrm/templates/import/import_status.html:50
msgid "Refresh"
-msgstr ""
+msgstr "刷新"
#: bookwyrm/templates/import/import_status.html:71
#, python-format
msgid "%(display_counter)s item needs manual approval."
msgid_plural "%(display_counter)s items need manual approval."
-msgstr[0] ""
+msgstr[0] "%(display_counter)s 项需要手动批准。"
#: bookwyrm/templates/import/import_status.html:76
#: bookwyrm/templates/import/manual_review.html:8
msgid "Review items"
-msgstr ""
+msgstr "审阅项目"
#: bookwyrm/templates/import/import_status.html:82
#, python-format
msgid "%(display_counter)s item failed to import."
msgid_plural "%(display_counter)s items failed to import."
-msgstr[0] ""
+msgstr[0] "%(display_counter)s 项导入失败。"
#: bookwyrm/templates/import/import_status.html:88
msgid "View and troubleshoot failed items"
-msgstr ""
+msgstr "查看并排查失败项目"
#: bookwyrm/templates/import/import_status.html:100
msgid "Row"
-msgstr ""
+msgstr "行"
#: bookwyrm/templates/import/import_status.html:103
#: bookwyrm/templates/shelf/shelf.html:141
@@ -1446,7 +1446,7 @@ msgstr "标题"
#: bookwyrm/templates/import/import_status.html:106
msgid "ISBN"
-msgstr ""
+msgstr "ISBN"
#: bookwyrm/templates/import/import_status.html:109
#: bookwyrm/templates/shelf/shelf.html:142
@@ -1456,7 +1456,7 @@ msgstr "作者"
#: bookwyrm/templates/import/import_status.html:112
msgid "Shelf"
-msgstr ""
+msgstr "书架"
#: bookwyrm/templates/import/import_status.html:115
#: bookwyrm/templates/import/manual_review.html:13
@@ -1480,11 +1480,11 @@ msgstr "状态"
#: bookwyrm/templates/import/import_status.html:130
msgid "Import preview unavailable."
-msgstr ""
+msgstr "导入预览不可用。"
#: bookwyrm/templates/import/import_status.html:162
msgid "View imported review"
-msgstr ""
+msgstr "查看已导入的书评"
#: bookwyrm/templates/import/import_status.html:176
msgid "Imported"
@@ -1492,28 +1492,28 @@ msgstr "已导入"
#: bookwyrm/templates/import/import_status.html:182
msgid "Needs manual review"
-msgstr ""
+msgstr "需要手动批准"
#: bookwyrm/templates/import/import_status.html:195
msgid "Retry"
-msgstr ""
+msgstr "重试"
#: bookwyrm/templates/import/import_status.html:213
msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format."
-msgstr ""
+msgstr "此导入所用格式已不再受支持。 如果您想要在此次导入中排查缺失的项目,请点击下面的按钮来更新导入格式。"
#: bookwyrm/templates/import/import_status.html:215
msgid "Update import"
-msgstr ""
+msgstr "更新导入"
#: bookwyrm/templates/import/manual_review.html:5
#: bookwyrm/templates/import/troubleshoot.html:4
msgid "Import Troubleshooting"
-msgstr ""
+msgstr "导入排查"
#: bookwyrm/templates/import/manual_review.html:21
msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book."
-msgstr ""
+msgstr "批准建议后,被提议的书将会永久添加到您的书架上并与您的阅读日期、书评、评分联系起来。"
#: bookwyrm/templates/import/manual_review.html:58
#: bookwyrm/templates/lists/curate.html:57
@@ -1522,7 +1522,7 @@ msgstr "批准"
#: bookwyrm/templates/import/manual_review.html:66
msgid "Reject"
-msgstr ""
+msgstr "驳回"
#: bookwyrm/templates/import/tooltip.html:6
msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account."
@@ -1530,31 +1530,31 @@ msgstr "您可以从 open an issue if you are seeing unexpected failed items."
-msgstr ""
+msgstr "如果您看到意外失败的项目,请联系您的管理员或 发起一个 issue。"
#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230
#, python-format