From b8b491bbf2d488655f83263b7b3bb4096a72180a Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 16:55:12 +0200 Subject: [PATCH 001/134] Add get_absolute_url to ImageField --- bookwyrm/models/fields.py | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 3b369e84e..e57374d58 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -3,6 +3,7 @@ from dataclasses import MISSING import imghdr import re from uuid import uuid4 +from urllib.parse import urljoin import dateutil.parser from dateutil.parser import ParserError @@ -13,11 +14,12 @@ from django.db import models from django.forms import ClearableFileInput, ImageField as DjangoImageField from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from django.utils.encoding import filepath_to_uri from bookwyrm import activitypub from bookwyrm.connectors import get_image from bookwyrm.sanitize_html import InputHtmlParser -from bookwyrm.settings import DOMAIN +from bookwyrm.settings import MEDIA_FULL_URL def validate_remote_id(value): @@ -355,8 +357,6 @@ def image_serializer(value, alt): url = value.url else: return None - if not url[:4] == "http": - url = "https://{:s}{:s}".format(DOMAIN, url) return activitypub.Document(url=url, name=alt) @@ -423,6 +423,19 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) + def get_absolute_url(self, instance): + """returns an absolute URL for the image""" + value = getattr(instance, self.name) + if value is None: + return + + url = filepath_to_uri(value) + if url is not None: + url = url.lstrip('/') + url = urljoin(MEDIA_FULL_URL, url) + + return url + class DateTimeField(ActivitypubFieldMixin, models.DateTimeField): """activitypub-aware datetime field""" From 7a716db48aad0093b1429bd66f360fb22ff258c4 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 16:56:07 +0200 Subject: [PATCH 002/134] lint --- bookwyrm/models/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index e57374d58..3baf3734e 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -431,7 +431,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): url = filepath_to_uri(value) if url is not None: - url = url.lstrip('/') + url = url.lstrip("/") url = urljoin(MEDIA_FULL_URL, url) return url From 60e805ac2b1faaeb977d03397880d3939dc17674 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 17:39:46 +0200 Subject: [PATCH 003/134] Fix tests --- bookwyrm/models/fields.py | 8 ++++---- bookwyrm/tests/models/test_fields.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 3baf3734e..1a8c082a3 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -423,13 +423,13 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) - def get_absolute_url(self, instance): + def get_absolute_url(self, value): """returns an absolute URL for the image""" - value = getattr(instance, self.name) - if value is None: + name = getattr(value, self.name) + if name is None: return - url = filepath_to_uri(value) + url = filepath_to_uri(name) if url is not None: url = url.lstrip("/") url = urljoin(MEDIA_FULL_URL, url) diff --git a/bookwyrm/tests/models/test_fields.py b/bookwyrm/tests/models/test_fields.py index c234ffd08..083e8a1b0 100644 --- a/bookwyrm/tests/models/test_fields.py +++ b/bookwyrm/tests/models/test_fields.py @@ -429,7 +429,7 @@ class ActivitypubFields(TestCase): def test_image_serialize(self): """make sure we're creating sensible image paths""" ValueMock = namedtuple("ValueMock", ("url")) - value_mock = ValueMock("/images/fish.jpg") + value_mock = ValueMock("https://your.domain.here/images/fish.jpg") result = fields.image_serializer(value_mock, "hello") self.assertEqual(result.type, "Document") self.assertEqual(result.url, "https://your.domain.here/images/fish.jpg") From bc7710a4a71e115d9eb6b7f88793acdf66f09d9c Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 18:18:18 +0200 Subject: [PATCH 004/134] Update Status Model Test --- bookwyrm/models/fields.py | 2 +- bookwyrm/tests/models/test_status_model.py | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 1a8c082a3..0e2a42e51 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -427,7 +427,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): """returns an absolute URL for the image""" name = getattr(value, self.name) if name is None: - return + return None url = filepath_to_uri(name) if url is not None: diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index 355caab9b..a01d86799 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -177,7 +177,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -208,7 +208,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -246,7 +246,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -287,7 +287,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -309,7 +309,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -331,7 +331,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://%s%s" % (settings.DOMAIN, self.book.cover.url), + "https://%s%s" % (settings.MEDIA_FULL_URL, self.book.cover.url), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") From c6f8236b07806edc596713cd82dfb172f6aea6a6 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 19:11:57 +0200 Subject: [PATCH 005/134] Fix tests --- bookwyrm/models/fields.py | 5 +++-- bookwyrm/tests/models/test_fields.py | 14 ++++++-------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 0e2a42e51..2069ed1b8 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -387,7 +387,8 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): activity[key] = formatted def field_to_activity(self, value, alt=None): - return image_serializer(value, alt) + url = self.get_absolute_url(value) + return activitypub.Document(url=url, name=alt) def field_from_activity(self, value): image_slug = value @@ -425,7 +426,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): def get_absolute_url(self, value): """returns an absolute URL for the image""" - name = getattr(value, self.name) + name = getattr(value, "name") if name is None: return None diff --git a/bookwyrm/tests/models/test_fields.py b/bookwyrm/tests/models/test_fields.py index 083e8a1b0..d9c470e02 100644 --- a/bookwyrm/tests/models/test_fields.py +++ b/bookwyrm/tests/models/test_fields.py @@ -22,6 +22,7 @@ from bookwyrm.activitypub.base_activity import ActivityObject from bookwyrm.models import fields, User, Status from bookwyrm.models.base_model import BookWyrmModel from bookwyrm.models.activitypub_mixin import ActivitypubMixin +from bookwyrm.settings import DOMAIN # pylint: disable=too-many-public-methods class ActivitypubFields(TestCase): @@ -401,21 +402,18 @@ class ActivitypubFields(TestCase): image.save(output, format=image.format) user.avatar.save("test.jpg", ContentFile(output.getvalue())) - output = fields.image_serializer(user.avatar, alt="alt text") + instance = fields.ImageField() + + output = instance.field_to_activity(user.avatar) self.assertIsNotNone( re.match( - r".*\.jpg", + fr"https:\/\/{DOMAIN}\/.*\.jpg", output.url, ) ) - self.assertEqual(output.name, "alt text") + self.assertEqual(output.name, "") self.assertEqual(output.type, "Document") - instance = fields.ImageField() - - output = fields.image_serializer(user.avatar, alt=None) - self.assertEqual(instance.field_to_activity(user.avatar), output) - responses.add( responses.GET, "http://www.example.com/image.jpg", From ee39e8c036299cc3670f154324192b3131586880 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 19:16:24 +0200 Subject: [PATCH 006/134] Fix R0201: Method could be a function (no-self-use) --- bookwyrm/models/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 2069ed1b8..cc9e0ec45 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -424,7 +424,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) - def get_absolute_url(self, value): + def get_absolute_url(value): """returns an absolute URL for the image""" name = getattr(value, "name") if name is None: From 0db3512eb3deca2f4be422d4274412d1794b35b3 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 19:21:56 +0200 Subject: [PATCH 007/134] Revert previous commit --- bookwyrm/models/fields.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index cc9e0ec45..2069ed1b8 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -424,7 +424,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) - def get_absolute_url(value): + def get_absolute_url(self, value): """returns an absolute URL for the image""" name = getattr(value, "name") if name is None: From c1673ef7174381ddfdccb1e8d33bd07db9ca5c4e Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 4 Aug 2021 19:25:19 +0200 Subject: [PATCH 008/134] Update fields.py --- bookwyrm/models/fields.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 2069ed1b8..57b364c9a 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -424,6 +424,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) + # pylint: disable=no-self-use def get_absolute_url(self, value): """returns an absolute URL for the image""" name = getattr(value, "name") From 35bd4a4071a13047c2c52ef51ef42616b48447d1 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 27 Oct 2021 18:13:47 +0200 Subject: [PATCH 009/134] Apply review suggestion --- bookwyrm/models/fields.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 7d4981e34..489ed0618 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -425,6 +425,10 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): def field_to_activity(self, value, alt=None): url = self.get_absolute_url(value) + + if not url: + return None + return activitypub.Document(url=url, name=alt) def field_from_activity(self, value): @@ -465,7 +469,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): def get_absolute_url(self, value): """returns an absolute URL for the image""" name = getattr(value, "name") - if name is None: + if not name: return None url = filepath_to_uri(name) From b956b79bd03dc844ac7d94755edd7e0e8ee9ae90 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 27 Oct 2021 18:56:37 +0200 Subject: [PATCH 010/134] Add full URL generation to image_serializer --- bookwyrm/models/fields.py | 4 ++++ bookwyrm/tests/models/test_status_model.py | 13 +++++++------ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 489ed0618..a490c1336 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -389,6 +389,10 @@ def image_serializer(value, alt): url = value.url else: return None + if url is not None: + url = url.lstrip("/") + url = urljoin(MEDIA_FULL_URL, url) + return activitypub.Document(url=url, name=alt) diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index cbec151b2..a46abe3b6 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -2,6 +2,7 @@ from unittest.mock import patch from io import BytesIO import pathlib +from urllib.parse import urljoin from django.http import Http404 from django.core.files.base import ContentFile @@ -192,7 +193,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -222,7 +223,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL,self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -259,7 +260,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - "https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -300,7 +301,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -322,7 +323,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -343,7 +344,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - f"https://{settings.MEDIA_FULL_URL}{self.book.cover.url}", + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") From 56fd147c883a6f2d5823edd5dc8a18ecc8e87145 Mon Sep 17 00:00:00 2001 From: Joachim Date: Wed, 27 Oct 2021 19:00:09 +0200 Subject: [PATCH 011/134] Update test_status_model.py --- bookwyrm/tests/models/test_status_model.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index a46abe3b6..f5013422c 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -223,7 +223,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL,self.book.cover.url.lstrip("/")), + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -301,7 +301,7 @@ class Status(TestCase): self.assertEqual(activity["attachment"][0].type, "Document") self.assertEqual( activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")) + urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), ) self.assertEqual(activity["attachment"][0].name, "Test Edition") From 07446fa7d207857d0997753df4c5a5b746f94fac Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 27 Oct 2021 10:03:09 -0700 Subject: [PATCH 012/134] Adds more tests for the inventaire connector --- bookwyrm/connectors/inventaire.py | 5 +- .../connectors/test_inventaire_connector.py | 119 ++++++++++++++++++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index faed5429a..43aee2f43 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -104,9 +104,7 @@ class Connector(AbstractConnector): def parse_isbn_search_data(self, data): """got some daaaata""" - results = data.get("entities") - if not results: - return [] + results = data.get("entities", []) return list(results.values()) def format_isbn_search_result(self, search_result): @@ -128,6 +126,7 @@ class Connector(AbstractConnector): def load_edition_data(self, work_uri): """get a list of editions for a work""" + # pylint: disable=line-too-long url = f"{self.books_url}?action=reverse-claims&property=wdt:P629&value={work_uri}&sort=true" return get_data(url) diff --git a/bookwyrm/tests/connectors/test_inventaire_connector.py b/bookwyrm/tests/connectors/test_inventaire_connector.py index 381017727..6536bae71 100644 --- a/bookwyrm/tests/connectors/test_inventaire_connector.py +++ b/bookwyrm/tests/connectors/test_inventaire_connector.py @@ -1,11 +1,14 @@ """ testing book data connectors """ import json import pathlib +from unittest.mock import patch + from django.test import TestCase import responses from bookwyrm import models from bookwyrm.connectors.inventaire import Connector, get_language_code +from bookwyrm.connectors.connector_manager import ConnectorException class Inventaire(TestCase): @@ -48,6 +51,44 @@ class Inventaire(TestCase): self.assertEqual(result["wdt:P31"], ["wd:Q3331189"]) self.assertEqual(result["uri"], "isbn:9780375757853") + @responses.activate + def test_get_book_data_invalid(self): + """error if there isn't any entity data""" + responses.add( + responses.GET, + "https://test.url/ok", + json={ + "entities": {}, + "redirects": {}, + }, + ) + + with self.assertRaises(ConnectorException): + self.connector.get_book_data("https://test.url/ok") + + @responses.activate + def test_search(self): + """min confidence filtering""" + responses.add( + responses.GET, + "https://inventaire.io/search?q=hi", + json={ + "results": [ + { + "_score": 200, + "label": "hello", + }, + { + "_score": 100, + "label": "hi", + }, + ], + }, + ) + results = self.connector.search("hi", min_confidence=0.5) + self.assertEqual(len(results), 1) + self.assertEqual(results[0].title, "hello") + def test_format_search_result(self): """json to search result objs""" search_file = pathlib.Path(__file__).parent.joinpath( @@ -157,6 +198,84 @@ class Inventaire(TestCase): "https://covers.inventaire.io/img/entities/12345", ) + def test_isbn_search_empty(self): + """another search type""" + search_results = {} + results = self.connector.parse_isbn_search_data(search_results) + self.assertEqual(results, []) + + def test_isbn_search_no_title(self): + """another search type""" + search_file = pathlib.Path(__file__).parent.joinpath( + "../data/inventaire_isbn_search.json" + ) + search_results = json.loads(search_file.read_bytes()) + search_results["entities"]["isbn:9782290349229"]["claims"]["wdt:P1476"] = None + + result = self.connector.format_isbn_search_result( + search_results.get("entities") + ) + self.assertIsNone(result) + + def test_is_work_data(self): + """is it a work""" + work_file = pathlib.Path(__file__).parent.joinpath( + "../data/inventaire_work.json" + ) + work_data = json.loads(work_file.read_bytes()) + with patch("bookwyrm.connectors.inventaire.get_data") as get_data_mock: + get_data_mock.return_value = work_data + formatted = self.connector.get_book_data("hi") + self.assertTrue(self.connector.is_work_data(formatted)) + + edition_file = pathlib.Path(__file__).parent.joinpath( + "../data/inventaire_edition.json" + ) + edition_data = json.loads(edition_file.read_bytes()) + with patch("bookwyrm.connectors.inventaire.get_data") as get_data_mock: + get_data_mock.return_value = edition_data + formatted = self.connector.get_book_data("hi") + self.assertFalse(self.connector.is_work_data(formatted)) + + @responses.activate + def test_get_edition_from_work_data(self): + """load edition""" + responses.add( + responses.GET, + "https://inventaire.io/?action=by-uris&uris=hello", + json={"entities": {}}, + ) + data = {"uri": "blah"} + with patch( + "bookwyrm.connectors.inventaire.Connector.load_edition_data" + ) as loader_mock, patch( + "bookwyrm.connectors.inventaire.Connector.get_book_data" + ) as getter_mock: + loader_mock.return_value = {"uris": ["hello"]} + self.connector.get_edition_from_work_data(data) + self.assertTrue(getter_mock.called) + + with patch( + "bookwyrm.connectors.inventaire.Connector.load_edition_data" + ) as loader_mock: + loader_mock.return_value = {"uris": []} + with self.assertRaises(ConnectorException): + self.connector.get_edition_from_work_data(data) + + @responses.activate + def test_get_work_from_edition_data(self): + """load work""" + responses.add( + responses.GET, + "https://inventaire.io/?action=by-uris&uris=hello", + ) + data = {"wdt:P629": "hello"} + self.connector.get_work_from_edition_data(data) + + data = {"wdt:P629": None} + with self.assertRaises(ConnectorException): + self.connector.get_work_from_edition_data(data) + def test_get_language_code(self): """get english or whatever is in reach""" options = { From d3e4c7e8d9c8c1cf98e07bafd9108553aa90551d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 27 Oct 2021 10:40:37 -0700 Subject: [PATCH 013/134] Removes change to boolean logic --- bookwyrm/connectors/inventaire.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index 43aee2f43..e180dc62f 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -104,7 +104,9 @@ class Connector(AbstractConnector): def parse_isbn_search_data(self, data): """got some daaaata""" - results = data.get("entities", []) + results = data.get("entities") + if not results: + return [] return list(results.values()) def format_isbn_search_result(self, search_result): From d8098357e605eef0468326937cfeeb5487e5dc1d Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Sat, 6 Nov 2021 10:53:41 +1100 Subject: [PATCH 014/134] match page title to active shelf resolves #1586 --- bookwyrm/templates/shelf/shelf.html | 2 +- bookwyrm/templates/user/books_header.html | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/shelf/shelf.html b/bookwyrm/templates/shelf/shelf.html index 662d75073..02e58ea38 100644 --- a/bookwyrm/templates/shelf/shelf.html +++ b/bookwyrm/templates/shelf/shelf.html @@ -5,7 +5,7 @@ {% load i18n %} {% block title %} -{% include 'user/books_header.html' %} +{% include 'user/books_header.html' with shelfname=shelf.identifier %} {% endblock %} {% block opengraph_images %} diff --git a/bookwyrm/templates/user/books_header.html b/bookwyrm/templates/user/books_header.html index 8fea84c7a..84493b9ca 100644 --- a/bookwyrm/templates/user/books_header.html +++ b/bookwyrm/templates/user/books_header.html @@ -1,6 +1,16 @@ {% load i18n %} {% if is_self %} +{% if shelfname == 'to-read' %} +{% trans "To Read" %} +{% elif shelfname == 'reading' %} +{% trans "Currently Reading" %} +{% elif shelfname == 'read' %} +{% trans "Read" %} +{% elif shelfname == 'all' %} {% trans "Your books" %} {% else %} +{{ shelfname }} +{% endif %} +{% else %} {% blocktrans with username=user.display_name %}{{ username }}'s books{% endblocktrans %} {% endif %} From dfe92a27c074239f41784966d3213b26f3e3b673 Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Sat, 6 Nov 2021 11:10:58 +1100 Subject: [PATCH 015/134] use shelf name if not default shelf (instead of shelf.identifier) --- bookwyrm/templates/shelf/shelf.html | 2 +- bookwyrm/templates/user/books_header.html | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/bookwyrm/templates/shelf/shelf.html b/bookwyrm/templates/shelf/shelf.html index 02e58ea38..01d41aa07 100644 --- a/bookwyrm/templates/shelf/shelf.html +++ b/bookwyrm/templates/shelf/shelf.html @@ -5,7 +5,7 @@ {% load i18n %} {% block title %} -{% include 'user/books_header.html' with shelfname=shelf.identifier %} +{% include 'user/books_header.html' with shelf=shelf %} {% endblock %} {% block opengraph_images %} diff --git a/bookwyrm/templates/user/books_header.html b/bookwyrm/templates/user/books_header.html index 84493b9ca..7311e2425 100644 --- a/bookwyrm/templates/user/books_header.html +++ b/bookwyrm/templates/user/books_header.html @@ -1,15 +1,15 @@ {% load i18n %} {% if is_self %} -{% if shelfname == 'to-read' %} +{% if shelf.identifier == 'to-read' %} {% trans "To Read" %} -{% elif shelfname == 'reading' %} +{% elif shelf.identifier == 'reading' %} {% trans "Currently Reading" %} -{% elif shelfname == 'read' %} +{% elif shelf.identifier == 'read' %} {% trans "Read" %} -{% elif shelfname == 'all' %} +{% elif shelf.identifier == 'all' %} {% trans "Your books" %} {% else %} -{{ shelfname }} +{{ shelf.name }} {% endif %} {% else %} {% blocktrans with username=user.display_name %}{{ username }}'s books{% endblocktrans %} From 1dec882dba5770a4266f9501bea274c88a9a9eeb Mon Sep 17 00:00:00 2001 From: nycterent Date: Sun, 7 Nov 2021 16:06:20 +0200 Subject: [PATCH 016/134] removed quotes from the host - fixes connecting to smtp server --- .env.dev.example | 2 +- .env.prod.example | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.dev.example b/.env.dev.example index 1e4fb9812..9a4366e02 100644 --- a/.env.dev.example +++ b/.env.dev.example @@ -36,7 +36,7 @@ FLOWER_PORT=8888 #FLOWER_USER=mouse #FLOWER_PASSWORD=changeme -EMAIL_HOST="smtp.mailgun.org" +EMAIL_HOST=smtp.mailgun.org EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here EMAIL_HOST_PASSWORD=emailpassword123 diff --git a/.env.prod.example b/.env.prod.example index 49729d533..56f52a286 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -36,7 +36,7 @@ FLOWER_PORT=8888 FLOWER_USER=mouse FLOWER_PASSWORD=changeme -EMAIL_HOST="smtp.mailgun.org" +EMAIL_HOST=smtp.mailgun.org EMAIL_PORT=587 EMAIL_HOST_USER=mail@your.domain.here EMAIL_HOST_PASSWORD=emailpassword123 From 67d830e327a7a16709b7be8f3a5760ac06fdc1e0 Mon Sep 17 00:00:00 2001 From: nycterent Date: Sun, 7 Nov 2021 16:07:21 +0200 Subject: [PATCH 017/134] fixed typo for the domain placeholder for easier substitution --- nginx/production | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx/production b/nginx/production index 3c8b2ea7d..8a13413a6 100644 --- a/nginx/production +++ b/nginx/production @@ -27,7 +27,7 @@ server { # # client_max_body_size 3M; # -# if ($host != "you-domain.com") { +# if ($host != "your-domain.com") { # return 301 $scheme://your-domain.com$request_uri; # } # From 23549c7fdb89de3343ccfc2ad62e529589420313 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 7 Nov 2021 06:13:44 -0800 Subject: [PATCH 018/134] Removes unused `rundb` command --- bw-dev | 4 ---- 1 file changed, 4 deletions(-) diff --git a/bw-dev b/bw-dev index 6c9def8ff..256418e2f 100755 --- a/bw-dev +++ b/bw-dev @@ -148,9 +148,6 @@ case "$CMD" in runweb) runweb "$@" ;; - rundb) - rundb "$@" - ;; *) set +x # No need to echo echo echo "Unrecognised command. Try:" @@ -180,6 +177,5 @@ case "$CMD" in echo " copy_media_to_s3" echo " set_cors_to_s3 [cors file]" echo " runweb [command]" - echo " rundb [command]" ;; esac From b2dea343af8dca6b10fdf315c8c8a390612bf911 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 7 Nov 2021 06:17:04 -0800 Subject: [PATCH 019/134] Removes outdated test command --- bw-dev | 4 ---- requirements.txt | 1 - 2 files changed, 5 deletions(-) diff --git a/bw-dev b/bw-dev index 256418e2f..195aa0619 100755 --- a/bw-dev +++ b/bw-dev @@ -96,9 +96,6 @@ case "$CMD" in restart_celery) docker-compose restart celery_worker ;; - test) - runweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@" - ;; pytest) execweb pytest --no-cov-on-fail "$@" ;; @@ -161,7 +158,6 @@ case "$CMD" in echo " shell" echo " dbshell" echo " restart_celery" - echo " test [path]" echo " pytest [path]" echo " collectstatic" echo " add_locale [locale]" diff --git a/requirements.txt b/requirements.txt index 7cf1c68a0..2cb1eec97 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,6 @@ django-storages==1.11.1 # Dev black==21.4b0 -coverage==5.1 pytest-django==4.1.0 pytest==6.1.2 pytest-cov==2.10.1 From c2f44a9f1e0e27698707157592722b712268b4a7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 7 Nov 2021 06:19:38 -0800 Subject: [PATCH 020/134] Removed outdated `add_locales` command from doc --- bw-dev | 1 - 1 file changed, 1 deletion(-) diff --git a/bw-dev b/bw-dev index 195aa0619..e442d3bce 100755 --- a/bw-dev +++ b/bw-dev @@ -160,7 +160,6 @@ case "$CMD" in echo " restart_celery" echo " pytest [path]" echo " collectstatic" - echo " add_locale [locale]" echo " makemessages" echo " compilemessages [locale]" echo " build" From 3f5fe839502042881f4fa0d413a838a4ec1efb56 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 7 Nov 2021 06:20:38 -0800 Subject: [PATCH 021/134] Renames run web with service ports command --- bw-dev | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bw-dev b/bw-dev index e442d3bce..35f3694ee 100755 --- a/bw-dev +++ b/bw-dev @@ -61,7 +61,7 @@ case "$CMD" in up) docker-compose up --build "$@" ;; - run) + service_ports_web) docker-compose run --rm --service-ports web ;; initdb) @@ -149,7 +149,7 @@ case "$CMD" in set +x # No need to echo echo echo "Unrecognised command. Try:" echo " up [container]" - echo " run" + echo " service_ports_web" echo " initdb" echo " resetdb" echo " makemigrations [migration]" From e19c4620ceab8197436fefca6f7841c362f65155 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 8 Nov 2021 12:00:08 -0800 Subject: [PATCH 022/134] Don't broadcast imported reviews outside bookwyrm --- bookwyrm/importers/importer.py | 6 ++++-- bookwyrm/models/activitypub_mixin.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 6d898a2a3..a5243cd3f 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -136,7 +136,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy): if item.review else "" ) - models.Review.objects.create( + review = models.Review( user=user, book=item.book, name=review_title, @@ -147,10 +147,12 @@ def handle_imported_book(source, user, item, include_reviews, privacy): ) else: # just a rating - models.ReviewRating.objects.create( + review = models.ReviewRating( user=user, book=item.book, rating=item.rating, published_date=published_date_guess, privacy=privacy, ) + # only broadcast this review to other bookwyrm instances + review.save(software="bookwyrm") diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 3a88c5249..031963aad 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -195,7 +195,7 @@ class ActivitypubMixin: class ObjectMixin(ActivitypubMixin): """add this mixin for object models that are AP serializable""" - def save(self, *args, created=None, **kwargs): + def save(self, *args, created=None, software=None, **kwargs): """broadcast created/updated/deleted objects as appropriate""" broadcast = kwargs.get("broadcast", True) # this bonus kwarg would cause an error in the base save method @@ -219,15 +219,16 @@ class ObjectMixin(ActivitypubMixin): return try: - software = None # do we have a "pure" activitypub version of this for mastodon? - if hasattr(self, "pure_content"): + if not software and hasattr(self, "pure_content"): pure_activity = self.to_create_activity(user, pure=True) self.broadcast(pure_activity, user, software="other") + # set bookwyrm so that that type is also sent software = "bookwyrm" - # sends to BW only if we just did a pure version for masto - activity = self.to_create_activity(user) - self.broadcast(activity, user, software=software) + if software == "bookwyrm": + # sends to BW only if we just did a pure version for masto + activity = self.to_create_activity(user) + self.broadcast(activity, user, software=software) except AttributeError: # janky as heck, this catches the mutliple inheritence chain # for boosts and ignores this auxilliary broadcast @@ -241,8 +242,7 @@ class ObjectMixin(ActivitypubMixin): if isinstance(self, user_model): user = self # book data tracks last editor - elif hasattr(self, "last_edited_by"): - user = self.last_edited_by + user = user or getattr(self, "last_edited_by", None) # again, if we don't know the user or they're remote, don't bother if not user or not user.local: return From 3f6b0608b2157f17ebccf761384d3dd1c4631b6f Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Wed, 10 Nov 2021 21:37:16 +1100 Subject: [PATCH 023/134] Show user and book names for reading actions in Discover fixes #1596 This uses the same technique as #1572 to ensure read statuses from GeneratedNotes are translated. --- bookwyrm/templates/discover/card-header.html | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/discover/card-header.html b/bookwyrm/templates/discover/card-header.html index 0eb9a678c..56d412ea2 100644 --- a/bookwyrm/templates/discover/card-header.html +++ b/bookwyrm/templates/discover/card-header.html @@ -4,7 +4,21 @@ {% with user_path=status.user.local_path username=status.user.display_name book_path=status.book.local_poth book_title=book|book_title %} {% if status.status_type == 'GeneratedNote' %} - {{ status.content|safe }} + {% if status.content == 'wants to read' %} + {% blocktrans trimmed %} + {{ username }} wants to read {{ book_title }} + {% endblocktrans %} + {% endif %} + {% if status.content == 'finished reading' %} + {% blocktrans trimmed %} + {{ username }} finished reading {{ book_title }} + {% endblocktrans %} + {% endif %} + {% if status.content == 'started reading' %} + {% blocktrans trimmed %} + {{ username }} started reading {{ book_title }} + {% endblocktrans %} + {% endif %} {% elif status.status_type == 'Rating' %} {% blocktrans trimmed %} {{ username }} rated {{ book_title }} From eb62474b97535cb097631868eb67e4aeaaf175bf Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Wed, 10 Nov 2021 22:04:19 +1100 Subject: [PATCH 024/134] fix broken book links in Discover --- bookwyrm/templates/discover/card-header.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/discover/card-header.html b/bookwyrm/templates/discover/card-header.html index 56d412ea2..8b9f6fc17 100644 --- a/bookwyrm/templates/discover/card-header.html +++ b/bookwyrm/templates/discover/card-header.html @@ -1,7 +1,7 @@ {% load i18n %} {% load utilities %} -{% with user_path=status.user.local_path username=status.user.display_name book_path=status.book.local_poth book_title=book|book_title %} +{% with user_path=status.user.local_path username=status.user.display_name book_path=book.local_path book_title=book|book_title %} {% if status.status_type == 'GeneratedNote' %} {% if status.content == 'wants to read' %} From 20c6a3ea1c7e32055e1bbfea9b69a3d18c79495b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 08:56:28 -0800 Subject: [PATCH 025/134] Creates generic importer test file And removes some tests that duplicate the generic tests --- .../tests/importers/test_goodreads_import.py | 123 +------- bookwyrm/tests/importers/test_importer.py | 289 ++++++++++++++++++ .../importers/test_librarything_import.py | 50 --- 3 files changed, 290 insertions(+), 172 deletions(-) create mode 100644 bookwyrm/tests/importers/test_importer.py diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index d2b0ea7d3..a24512921 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -1,5 +1,4 @@ """ testing import """ -from collections import namedtuple import csv import pathlib from unittest.mock import patch @@ -7,11 +6,10 @@ import datetime import pytz from django.test import TestCase -import responses from bookwyrm import models from bookwyrm.importers import GoodreadsImporter -from bookwyrm.importers.importer import import_data, handle_imported_book +from bookwyrm.importers.importer import handle_imported_book def make_date(*args): @@ -48,9 +46,6 @@ class GoodreadsImport(TestCase): def test_create_job(self, *_): """creates the import job entry and checks csv""" import_job = self.importer.create_job(self.user, self.csv, False, "public") - self.assertEqual(import_job.user, self.user) - self.assertEqual(import_job.include_reviews, False) - self.assertEqual(import_job.privacy, "public") import_items = models.ImportItem.objects.filter(job=import_job).all() self.assertEqual(len(import_items), 3) @@ -79,33 +74,6 @@ class GoodreadsImport(TestCase): self.assertEqual(retry_items[1].index, 1) self.assertEqual(retry_items[1].data["Book Id"], "52691223") - def test_start_import(self, *_): - """begin loading books""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") - MockTask = namedtuple("Task", ("id")) - mock_task = MockTask(7) - with patch("bookwyrm.importers.importer.import_data.delay") as start: - start.return_value = mock_task - self.importer.start_import(import_job) - import_job.refresh_from_db() - self.assertEqual(import_job.task_id, "7") - - @responses.activate - def test_import_data(self, *_): - """resolve entry""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") - book = models.Edition.objects.create(title="Test Book") - - with patch( - "bookwyrm.models.import_job.ImportItem.get_book_from_isbn" - ) as resolve: - resolve.return_value = book - with patch("bookwyrm.importers.importer.handle_imported_book"): - import_data(self.importer.service, import_job.id) - - import_item = models.ImportItem.objects.get(job=import_job, index=0) - self.assertEqual(import_item.book.id, book.id) - def test_handle_imported_book(self, *_): """goodreads import added a book, this adds related connections""" shelf = self.user.shelf_set.filter(identifier="read").first() @@ -137,76 +105,6 @@ class GoodreadsImport(TestCase): self.assertEqual(readthrough.start_date, make_date(2020, 10, 21)) self.assertEqual(readthrough.finish_date, make_date(2020, 10, 25)) - def test_handle_imported_book_already_shelved(self, *_): - """goodreads import added a book, this adds related connections""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - shelf = self.user.shelf_set.filter(identifier="to-read").first() - models.ShelfBook.objects.create( - shelf=shelf, - user=self.user, - book=self.book, - shelved_date=make_date(2020, 2, 2), - ) - - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break - - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - handle_imported_book( - self.importer.service, self.user, import_item, False, "public" - ) - - shelf.refresh_from_db() - self.assertEqual(shelf.books.first(), self.book) - self.assertEqual( - shelf.shelfbook_set.first().shelved_date, make_date(2020, 2, 2) - ) - self.assertIsNone(self.user.shelf_set.get(identifier="read").books.first()) - - readthrough = models.ReadThrough.objects.get(user=self.user) - self.assertEqual(readthrough.book, self.book) - self.assertEqual(readthrough.start_date, make_date(2020, 10, 21)) - self.assertEqual(readthrough.finish_date, make_date(2020, 10, 25)) - - def test_handle_import_twice(self, *_): - """re-importing books""" - shelf = self.user.shelf_set.filter(identifier="read").first() - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break - - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - handle_imported_book( - self.importer.service, self.user, import_item, False, "public" - ) - handle_imported_book( - self.importer.service, self.user, import_item, False, "public" - ) - - shelf.refresh_from_db() - self.assertEqual(shelf.books.first(), self.book) - self.assertEqual( - shelf.shelfbook_set.first().shelved_date, make_date(2020, 10, 21) - ) - - readthrough = models.ReadThrough.objects.get(user=self.user) - self.assertEqual(readthrough.book, self.book) - self.assertEqual(readthrough.start_date, make_date(2020, 10, 21)) - self.assertEqual(readthrough.finish_date, make_date(2020, 10, 25)) - @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """goodreads review import""" @@ -252,22 +150,3 @@ class GoodreadsImport(TestCase): self.assertEqual(review.rating, 2) self.assertEqual(review.published_date, make_date(2019, 7, 8)) self.assertEqual(review.privacy, "unlisted") - - def test_handle_imported_book_reviews_disabled(self, *_): - """goodreads review import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[2] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book - ) - - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - handle_imported_book( - self.importer.service, self.user, import_item, False, "unlisted" - ) - self.assertFalse( - models.Review.objects.filter(book=self.book, user=self.user).exists() - ) diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py new file mode 100644 index 000000000..f5d9af302 --- /dev/null +++ b/bookwyrm/tests/importers/test_importer.py @@ -0,0 +1,289 @@ +""" testing import """ +from collections import namedtuple +import csv +import pathlib +from unittest.mock import patch +import datetime +import pytz + +from django.test import TestCase +import responses + +from bookwyrm import models +from bookwyrm.importers import Importer +from bookwyrm.importers.importer import import_data, handle_imported_book + + +def make_date(*args): + """helper function to easily generate a date obj""" + return datetime.datetime(*args, tzinfo=pytz.UTC) + + +# pylint: disable=consider-using-with +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +class GenericImporter(TestCase): + """importing from csv""" + + def setUp(self): + """use a test csv""" + + class TestImporter(Importer): + """basic importer""" + + mandatory_fields = ["title", "author"] + + def parse_fields(self, entry): + return { + "id": entry["id"], + "Title": entry["title"], + "Author": entry["author"], + "ISBN13": entry["ISBN"], + "Star Rating": entry["rating"], + "My Rating": entry["rating"], + "My Review": entry["review"], + "Exclusive Shelf": entry["shelf"], + "Date Added": entry["added"], + "Date Read": None, + } + + self.importer = TestImporter() + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + self.csv = open(datafile, "r", encoding=self.importer.encoding) + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True + ) + + work = models.Work.objects.create(title="Test Work") + self.book = models.Edition.objects.create( + title="Example Edition", + remote_id="https://example.com/book/1", + parent_work=work, + ) + + def test_create_job(self, *_): + """creates the import job entry and checks csv""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + self.assertEqual(import_job.user, self.local_user) + self.assertEqual(import_job.include_reviews, False) + self.assertEqual(import_job.privacy, "public") + + import_items = models.ImportItem.objects.filter(job=import_job).all() + self.assertEqual(len(import_items), 4) + self.assertEqual(import_items[0].index, 0) + self.assertEqual(import_items[0].data["id"], "38") + self.assertEqual(import_items[1].index, 1) + self.assertEqual(import_items[1].data["id"], "48") + self.assertEqual(import_items[2].index, 2) + self.assertEqual(import_items[2].data["id"], "23") + self.assertEqual(import_items[3].index, 3) + self.assertEqual(import_items[3].data["id"], "10") + + def test_create_retry_job(self, *_): + """trying again with items that didn't import""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] + + retry = self.importer.create_retry_job( + self.local_user, import_job, import_items + ) + self.assertNotEqual(import_job, retry) + self.assertEqual(retry.user, self.local_user) + self.assertEqual(retry.include_reviews, False) + self.assertEqual(retry.privacy, "unlisted") + + retry_items = models.ImportItem.objects.filter(job=retry).all() + self.assertEqual(len(retry_items), 2) + self.assertEqual(retry_items[0].index, 0) + self.assertEqual(retry_items[0].data["id"], "38") + self.assertEqual(retry_items[1].index, 1) + self.assertEqual(retry_items[1].data["id"], "48") + + def test_start_import(self, *_): + """check that a task was created""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + MockTask = namedtuple("Task", ("id")) + mock_task = MockTask(7) + with patch("bookwyrm.importers.importer.import_data.delay") as start: + start.return_value = mock_task + self.importer.start_import(import_job) + import_job.refresh_from_db() + self.assertEqual(import_job.task_id, "7") + + @responses.activate + def test_import_data(self, *_): + """resolve entry""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + book = models.Edition.objects.create(title="Test Book") + + with patch( + "bookwyrm.models.import_job.ImportItem.get_book_from_isbn" + ) as resolve: + resolve.return_value = book + with patch("bookwyrm.importers.importer.handle_imported_book"): + import_data(self.importer.service, import_job.id) + + import_item = models.ImportItem.objects.get(job=import_job, index=0) + self.assertEqual(import_item.book.id, book.id) + + def test_handle_imported_book(self, *_): + """import added a book, this adds related connections""" + shelf = self.local_user.shelf_set.filter(identifier="read").first() + self.assertIsNone(shelf.books.first()) + + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + for index, entry in enumerate(list(csv.DictReader(csv_file))): + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=index, data=entry, book=self.book + ) + break + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.local_user, import_item, False, "public" + ) + + shelf.refresh_from_db() + self.assertEqual(shelf.books.first(), self.book) + + def test_handle_imported_book_already_shelved(self, *_): + """import added a book, this adds related connections""" + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + shelf = self.local_user.shelf_set.filter(identifier="to-read").first() + models.ShelfBook.objects.create( + shelf=shelf, + user=self.local_user, + book=self.book, + shelved_date=make_date(2020, 2, 2), + ) + + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + for index, entry in enumerate(list(csv.DictReader(csv_file))): + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=index, data=entry, book=self.book + ) + break + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.local_user, import_item, False, "public" + ) + + shelf.refresh_from_db() + self.assertEqual(shelf.books.first(), self.book) + self.assertEqual( + shelf.shelfbook_set.first().shelved_date, make_date(2020, 2, 2) + ) + self.assertIsNone( + self.local_user.shelf_set.get(identifier="read").books.first() + ) + + def test_handle_import_twice(self, *_): + """re-importing books""" + shelf = self.local_user.shelf_set.filter(identifier="read").first() + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + for index, entry in enumerate(list(csv.DictReader(csv_file))): + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=index, data=entry, book=self.book + ) + break + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.local_user, import_item, False, "public" + ) + handle_imported_book( + self.importer.service, self.local_user, import_item, False, "public" + ) + + shelf.refresh_from_db() + self.assertEqual(shelf.books.first(), self.book) + + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_handle_imported_book_review(self, *_): + """review import""" + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + entry = list(csv.DictReader(csv_file))[3] + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=0, data=entry, book=self.book + ) + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.Status.broadcast") as broadcast_mock: + handle_imported_book( + self.importer.service, + self.local_user, + import_item, + True, + "unlisted", + ) + kwargs = broadcast_mock.call_args.kwargs + self.assertEqual(kwargs["software"], "bookwyrm") + review = models.Review.objects.get(book=self.book, user=self.local_user) + self.assertEqual(review.content, "mixed feelings") + self.assertEqual(review.rating, 2.0) + self.assertEqual(review.privacy, "unlisted") + + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_handle_imported_book_rating(self, *_): + """rating import""" + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + entry = list(csv.DictReader(csv_file))[1] + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=0, data=entry, book=self.book + ) + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.local_user, import_item, True, "unlisted" + ) + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) + self.assertIsInstance(review, models.ReviewRating) + self.assertEqual(review.rating, 3.0) + self.assertEqual(review.privacy, "unlisted") + + def test_handle_imported_book_reviews_disabled(self, *_): + """review import""" + import_job = models.ImportJob.objects.create(user=self.local_user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + entry = list(csv.DictReader(csv_file))[2] + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=0, data=entry, book=self.book + ) + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.local_user, import_item, False, "unlisted" + ) + self.assertFalse( + models.Review.objects.filter(book=self.book, user=self.local_user).exists() + ) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index ab92c11b1..f76666a78 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -157,37 +157,6 @@ class LibrarythingImport(TestCase): self.assertEqual(readthrough.start_date, make_date(2007, 4, 16)) self.assertEqual(readthrough.finish_date, make_date(2007, 5, 8)) - def test_handle_import_twice(self, *_): - """re-importing books""" - shelf = self.user.shelf_set.filter(identifier="read").first() - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/librarything.tsv") - csv_file = open(datafile, "r", encoding=self.importer.encoding) - for index, entry in enumerate( - list(csv.DictReader(csv_file, delimiter=self.importer.delimiter)) - ): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break - - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - handle_imported_book( - self.importer.service, self.user, import_item, False, "public" - ) - handle_imported_book( - self.importer.service, self.user, import_item, False, "public" - ) - - shelf.refresh_from_db() - self.assertEqual(shelf.books.first(), self.book) - - readthrough = models.ReadThrough.objects.get(user=self.user) - self.assertEqual(readthrough.book, self.book) - self.assertEqual(readthrough.start_date, make_date(2007, 4, 16)) - self.assertEqual(readthrough.finish_date, make_date(2007, 5, 8)) - @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """librarything review import""" @@ -209,22 +178,3 @@ class LibrarythingImport(TestCase): self.assertEqual(review.rating, 5) self.assertEqual(review.published_date, make_date(2007, 5, 8)) self.assertEqual(review.privacy, "unlisted") - - def test_handle_imported_book_reviews_disabled(self, *_): - """librarything review import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/librarything.tsv") - csv_file = open(datafile, "r", encoding=self.importer.encoding) - entry = list(csv.DictReader(csv_file, delimiter=self.importer.delimiter))[2] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book - ) - - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - handle_imported_book( - self.importer.service, self.user, import_item, False, "unlisted" - ) - self.assertFalse( - models.Review.objects.filter(book=self.book, user=self.user).exists() - ) From aeef472ee1542e01e6d7e0d204faab725c39a43e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 09:33:00 -0800 Subject: [PATCH 026/134] Fixes flow in checking software for broadcast --- bookwyrm/models/activitypub_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 031963aad..fb2771ae6 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -220,7 +220,7 @@ class ObjectMixin(ActivitypubMixin): try: # do we have a "pure" activitypub version of this for mastodon? - if not software and hasattr(self, "pure_content"): + if not software == "bookwyrm" and hasattr(self, "pure_content"): pure_activity = self.to_create_activity(user, pure=True) self.broadcast(pure_activity, user, software="other") # set bookwyrm so that that type is also sent From 1b9d08414f729857a2ba9080ea86de74cb53033f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 09:53:52 -0800 Subject: [PATCH 027/134] Adds storygraph tests --- bookwyrm/importers/storygraph_import.py | 2 +- bookwyrm/tests/data/generic.csv | 5 + bookwyrm/tests/data/storygraph.csv | 3 + .../tests/importers/test_storygraph_import.py | 122 ++++++++++++++++++ 4 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/tests/data/generic.csv create mode 100644 bookwyrm/tests/data/storygraph.csv create mode 100644 bookwyrm/tests/importers/test_storygraph_import.py diff --git a/bookwyrm/importers/storygraph_import.py b/bookwyrm/importers/storygraph_import.py index 25498432c..bf532e58e 100644 --- a/bookwyrm/importers/storygraph_import.py +++ b/bookwyrm/importers/storygraph_import.py @@ -21,7 +21,7 @@ class StorygraphImporter(Importer): data["ISBN13"] = entry["ISBN"] data["My Review"] = entry["Review"] if entry["Star Rating"]: - data["My Rating"] = math.ceil(float(entry["Star Rating"])) + data["My Rating"] = float(entry["Star Rating"]) else: data["My Rating"] = "" diff --git a/bookwyrm/tests/data/generic.csv b/bookwyrm/tests/data/generic.csv new file mode 100644 index 000000000..a081a6421 --- /dev/null +++ b/bookwyrm/tests/data/generic.csv @@ -0,0 +1,5 @@ +id,title,author,ISBN,rating,shelf,review,added +38,Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,"9781250313195",,read,,2021-11-10 +48,Harrow the Ninth (The Locked Tomb #2),Tamsyn Muir,,3,read,,2021-11-10 +23,Subcutanean,Aaron A. Reed,,,read,,2021-11-10 +10,Patisserie at Home,Mélanie Dupuis,"9780062445315",2,read,"mixed feelings",2021-11-10 diff --git a/bookwyrm/tests/data/storygraph.csv b/bookwyrm/tests/data/storygraph.csv new file mode 100644 index 000000000..4dd0b16e4 --- /dev/null +++ b/bookwyrm/tests/data/storygraph.csv @@ -0,0 +1,3 @@ +Title,Authors,Contributors,ISBN,Format,Read Status,Date Added,Last Date Read,Dates Read,Read Count,Moods,Pace,Character- or Plot-Driven?,Strong Character Development?,Loveable Characters?,Diverse Characters?,Flawed Characters?,Star Rating,Review,Content Warnings,Content Warning Description,Tags,Owned? +Always Coming Home,"Ursula K. Le Guin, Todd Barton, Margaret Chodos-Irvine","",,,to-read,2021/05/10,"","",0,"",,,,,,,,,"",,"",No +Subprime Attention Crisis,Tim Hwang,"",,,read,2021/05/10,"","",1,informative,fast,,,,,,5.0,"","","","",No diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py new file mode 100644 index 000000000..addf362cb --- /dev/null +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -0,0 +1,122 @@ +""" testing import """ +import csv +import pathlib +from unittest.mock import patch +import datetime +import pytz + +from django.test import TestCase + +from bookwyrm import models +from bookwyrm.importers import StorygraphImporter +from bookwyrm.importers.importer import handle_imported_book + + +def make_date(*args): + """helper function to easily generate a date obj""" + return datetime.datetime(*args, tzinfo=pytz.UTC) + + +# pylint: disable=consider-using-with +@patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") +@patch("bookwyrm.activitystreams.populate_stream_task.delay") +@patch("bookwyrm.activitystreams.add_book_statuses_task.delay") +class StorygraphImport(TestCase): + """importing from storygraph csv""" + + def setUp(self): + """use a test csv""" + self.importer = StorygraphImporter() + datafile = pathlib.Path(__file__).parent.joinpath("../data/storygraph.csv") + self.csv = open(datafile, "r", encoding=self.importer.encoding) + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True + ) + + work = models.Work.objects.create(title="Test Work") + self.book = models.Edition.objects.create( + title="Example Edition", + remote_id="https://example.com/book/1", + parent_work=work, + ) + + def test_create_job(self, *_): + """creates the import job entry and checks csv""" + import_job = self.importer.create_job(self.user, self.csv, False, "public") + + import_items = models.ImportItem.objects.filter(job=import_job).all() + self.assertEqual(len(import_items), 2) + self.assertEqual(import_items[0].index, 0) + self.assertEqual(import_items[0].data["Title"], "Always Coming Home") + self.assertEqual(import_items[1].index, 1) + self.assertEqual(import_items[1].data["Title"], "Subprime Attention Crisis") + self.assertEqual(import_items[1].data["My Rating"], 5.0) + + def test_create_retry_job(self, *_): + """trying again with items that didn't import""" + import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") + import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] + + retry = self.importer.create_retry_job(self.user, import_job, import_items) + self.assertNotEqual(import_job, retry) + self.assertEqual(retry.user, self.user) + self.assertEqual(retry.include_reviews, False) + self.assertEqual(retry.privacy, "unlisted") + + retry_items = models.ImportItem.objects.filter(job=retry).all() + self.assertEqual(len(retry_items), 2) + self.assertEqual(retry_items[0].index, 0) + self.assertEqual(retry_items[0].data["Title"], "Always Coming Home") + self.assertEqual(retry_items[1].index, 1) + self.assertEqual(retry_items[1].data["Title"], "Subprime Attention Crisis") + + def test_handle_imported_book(self, *_): + """storygraph import added a book, this adds related connections""" + shelf = self.user.shelf_set.filter(identifier="to-read").first() + self.assertIsNone(shelf.books.first()) + + import_job = models.ImportJob.objects.create(user=self.user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/storygraph.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + for index, entry in enumerate(list(csv.DictReader(csv_file))): + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=index, data=entry, book=self.book + ) + break + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.user, import_item, False, "public" + ) + + shelf.refresh_from_db() + self.assertEqual(shelf.books.first(), self.book) + self.assertEqual( + shelf.shelfbook_set.first().shelved_date, make_date(2021, 5, 10) + ) + + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_handle_imported_book_rating(self, *_): + """storygraph rating import""" + import_job = models.ImportJob.objects.create(user=self.user) + datafile = pathlib.Path(__file__).parent.joinpath("../data/storygraph.csv") + csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding + entry = list(csv.DictReader(csv_file))[1] + entry = self.importer.parse_fields(entry) + import_item = models.ImportItem.objects.create( + job_id=import_job.id, index=0, data=entry, book=self.book + ) + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + handle_imported_book( + self.importer.service, self.user, import_item, True, "unlisted" + ) + review = models.ReviewRating.objects.get(book=self.book, user=self.user) + self.assertIsInstance(review, models.ReviewRating) + self.assertEqual(review.rating, 5.0) + self.assertEqual(review.published_date, make_date(2021, 5, 10)) + self.assertEqual(review.privacy, "unlisted") From 97a71f5e39ea4cee4d96af9f7f6b3b7971aee27f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 09:55:56 -0800 Subject: [PATCH 028/134] Cleans up software check syntax --- bookwyrm/models/activitypub_mixin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index fb2771ae6..0cb8a2cce 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -220,7 +220,7 @@ class ObjectMixin(ActivitypubMixin): try: # do we have a "pure" activitypub version of this for mastodon? - if not software == "bookwyrm" and hasattr(self, "pure_content"): + if software != "bookwyrm" and hasattr(self, "pure_content"): pure_activity = self.to_create_activity(user, pure=True) self.broadcast(pure_activity, user, software="other") # set bookwyrm so that that type is also sent From 4f5d23e785dc8f070bfcf36fe075115a275c03df Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:28:43 -0800 Subject: [PATCH 029/134] Replace image_serialzier helper with built-in serializers --- bookwyrm/models/fields.py | 13 ------------- bookwyrm/models/status.py | 12 ++---------- bookwyrm/tests/models/test_fields.py | 9 --------- 3 files changed, 2 insertions(+), 32 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index a490c1336..03305f6bc 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -383,19 +383,6 @@ class CustomImageField(DjangoImageField): widget = ClearableFileInputWithWarning -def image_serializer(value, alt): - """helper for serializing images""" - if value and hasattr(value, "url"): - url = value.url - else: - return None - if url is not None: - url = url.lstrip("/") - url = urljoin(MEDIA_FULL_URL, url) - - return activitypub.Document(url=url, name=alt) - - class ImageField(ActivitypubFieldMixin, models.ImageField): """activitypub-aware image field""" diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 2b395ec8b..a298b132f 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -19,7 +19,6 @@ from bookwyrm.settings import ENABLE_PREVIEW_IMAGES from .activitypub_mixin import ActivitypubMixin, ActivityMixin from .activitypub_mixin import OrderedCollectionPageMixin from .base_model import BookWyrmModel -from .fields import image_serializer from .readthrough import ProgressMode from . import fields @@ -190,15 +189,8 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): if hasattr(activity, "name"): activity.name = self.pure_name activity.type = self.pure_type - activity.attachment = [ - image_serializer(b.cover, b.alt_text) - for b in self.mention_books.all()[:4] - if b.cover - ] - if hasattr(self, "book") and self.book.cover: - activity.attachment.append( - image_serializer(self.book.cover, self.book.alt_text) - ) + covers = [b.to_activity().get("cover") for b in [getattr(self, "book", None)] + list(self.mention_books.all()) if b] + activity.attachment = covers return activity def to_activity(self, pure=False): # pylint: disable=arguments-differ diff --git a/bookwyrm/tests/models/test_fields.py b/bookwyrm/tests/models/test_fields.py index 6796f8d3a..74f4c48bd 100644 --- a/bookwyrm/tests/models/test_fields.py +++ b/bookwyrm/tests/models/test_fields.py @@ -447,15 +447,6 @@ class ModelFields(TestCase): self.assertIsInstance(loaded_image, list) self.assertIsInstance(loaded_image[1], ContentFile) - def test_image_serialize(self, *_): - """make sure we're creating sensible image paths""" - ValueMock = namedtuple("ValueMock", ("url")) - value_mock = ValueMock("https://your.domain.here/images/fish.jpg") - result = fields.image_serializer(value_mock, "hello") - self.assertEqual(result.type, "Document") - self.assertEqual(result.url, "https://your.domain.here/images/fish.jpg") - self.assertEqual(result.name, "hello") - def test_datetime_field(self, *_): """this one is pretty simple, it just has to use isoformat""" instance = fields.DateTimeField() From 9815e9e1009db30b46c814238da949e99708bad2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:30:18 -0800 Subject: [PATCH 030/134] Python formatting --- bookwyrm/models/status.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index a298b132f..767841c86 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -189,7 +189,11 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): if hasattr(activity, "name"): activity.name = self.pure_name activity.type = self.pure_type - covers = [b.to_activity().get("cover") for b in [getattr(self, "book", None)] + list(self.mention_books.all()) if b] + covers = [ + b.to_activity().get("cover") + for b in [getattr(self, "book", None)] + list(self.mention_books.all()) + if b + ] activity.attachment = covers return activity From 7e784fa705521be9fa0688276918ca105e5ab20f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:35:37 -0800 Subject: [PATCH 031/134] Removes used import --- bookwyrm/importers/storygraph_import.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bookwyrm/importers/storygraph_import.py b/bookwyrm/importers/storygraph_import.py index bf532e58e..1333b8b9d 100644 --- a/bookwyrm/importers/storygraph_import.py +++ b/bookwyrm/importers/storygraph_import.py @@ -1,6 +1,5 @@ """ handle reading a csv from librarything """ import re -import math from . import Importer From cf477a03aee26373fa4105862100b904bfa17907 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:39:51 -0800 Subject: [PATCH 032/134] Corrects broadcast flow for objects --- bookwyrm/models/activitypub_mixin.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 0cb8a2cce..e1276d465 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -225,10 +225,9 @@ class ObjectMixin(ActivitypubMixin): self.broadcast(pure_activity, user, software="other") # set bookwyrm so that that type is also sent software = "bookwyrm" - if software == "bookwyrm": - # sends to BW only if we just did a pure version for masto - activity = self.to_create_activity(user) - self.broadcast(activity, user, software=software) + # sends to BW only if we just did a pure version for masto + activity = self.to_create_activity(user) + self.broadcast(activity, user, software=software) except AttributeError: # janky as heck, this catches the mutliple inheritence chain # for boosts and ignores this auxilliary broadcast From d61595abb9df3c816a60f60332aa07a3fbdadde8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:50:05 -0800 Subject: [PATCH 033/134] Clearer syntax --- bookwyrm/models/status.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index 767841c86..d3fcc2545 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -189,10 +189,9 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): if hasattr(activity, "name"): activity.name = self.pure_name activity.type = self.pure_type + books = [getattr(self, "book", None)] + list(self.mention_books.all()) covers = [ - b.to_activity().get("cover") - for b in [getattr(self, "book", None)] + list(self.mention_books.all()) - if b + b.to_activity().get("cover") for b in books if b ] activity.attachment = covers return activity From 717da918cfefdb1bb6586956028490e9ebce7d60 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 10:58:02 -0800 Subject: [PATCH 034/134] Use social media preview images --- bookwyrm/models/fields.py | 24 ++++++++++++------------ bookwyrm/models/status.py | 19 ++++++++++++++++--- 2 files changed, 28 insertions(+), 15 deletions(-) diff --git a/bookwyrm/models/fields.py b/bookwyrm/models/fields.py index 03305f6bc..361079906 100644 --- a/bookwyrm/models/fields.py +++ b/bookwyrm/models/fields.py @@ -415,7 +415,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): activity[key] = formatted def field_to_activity(self, value, alt=None): - url = self.get_absolute_url(value) + url = get_absolute_url(value) if not url: return None @@ -456,19 +456,19 @@ class ImageField(ActivitypubFieldMixin, models.ImageField): } ) - # pylint: disable=no-self-use - def get_absolute_url(self, value): - """returns an absolute URL for the image""" - name = getattr(value, "name") - if not name: - return None - url = filepath_to_uri(name) - if url is not None: - url = url.lstrip("/") - url = urljoin(MEDIA_FULL_URL, url) +def get_absolute_url(value): + """returns an absolute URL for the image""" + name = getattr(value, "name") + if not name: + return None - return url + url = filepath_to_uri(name) + if url is not None: + url = url.lstrip("/") + url = urljoin(MEDIA_FULL_URL, url) + + return url class DateTimeField(ActivitypubFieldMixin, models.DateTimeField): diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index d3fcc2545..a52af123c 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -190,9 +190,22 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): activity.name = self.pure_name activity.type = self.pure_type books = [getattr(self, "book", None)] + list(self.mention_books.all()) - covers = [ - b.to_activity().get("cover") for b in books if b - ] + if len(books) == 1 and books[0].preview_image: + covers = [ + activitypub.Document( + url=fields.get_absolute_url(books[0].preview_image), + name=books[0].alt_text, + ) + ] + else: + covers = [ + activitypub.Document( + url=fields.get_absolute_url(b.cover), + name=b.alt_text, + ) + for b in books + if b and b.cover + ] activity.attachment = covers return activity From 0736c7e160fe544db8f4be07840de2f197af4b68 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 11:10:09 -0800 Subject: [PATCH 035/134] Uses general names for fields in parsed csvs --- bookwyrm/models/import_job.py | 44 ++++++++++++++--------------------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 22253fef7..949e3edbf 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -10,14 +10,6 @@ from bookwyrm.models import ReadThrough, User, Book from .fields import PrivacyLevels -# Mapping goodreads -> bookwyrm shelf titles. -GOODREADS_SHELVES = { - "read": "read", - "currently-reading": "reading", - "to-read": "to-read", -} - - def unquote_string(text): """resolve csv quote weirdness""" match = re.match(r'="([^"]*)"', text) @@ -106,56 +98,56 @@ class ImportItem(models.Model): @property def title(self): """get the book title""" - return self.data["Title"] + return self.data["title"] @property def author(self): - """get the book title""" - return self.data["Author"] + """get the book's authors""" + return self.data["authors"] @property def isbn(self): """pulls out the isbn13 field from the csv line data""" - return unquote_string(self.data["ISBN13"]) + return unquote_string(self.data["isbn_13"]) @property def shelf(self): """the goodreads shelf field""" - if self.data["Exclusive Shelf"]: - return GOODREADS_SHELVES.get(self.data["Exclusive Shelf"]) - return None + return self.data.get("shelf") @property def review(self): """a user-written review, to be imported with the book data""" - return self.data["My Review"] + return self.data["review_body"] @property def rating(self): """x/5 star rating for a book""" - if self.data.get("My Rating", None): - return int(self.data["My Rating"]) + if self.data.get("rating"): + return float(self.data["rating"]) return None @property def date_added(self): """when the book was added to this dataset""" - if self.data["Date Added"]: - return timezone.make_aware(dateutil.parser.parse(self.data["Date Added"])) + if self.data.get("date_added"): + return timezone.make_aware(dateutil.parser.parse(self.data["date_added"])) return None @property def date_started(self): """when the book was started""" - if "Date Started" in self.data and self.data["Date Started"]: - return timezone.make_aware(dateutil.parser.parse(self.data["Date Started"])) + if self.data.get("date_started"): + return timezone.make_aware(dateutil.parser.parse(self.data["date_started"])) return None @property def date_read(self): """the date a book was completed""" - if self.data["Date Read"]: - return timezone.make_aware(dateutil.parser.parse(self.data["Date Read"])) + if self.data.get("date_finished"): + return timezone.make_aware( + dateutil.parser.parse(self.data["date_finished"]) + ) return None @property @@ -185,8 +177,8 @@ class ImportItem(models.Model): def __repr__(self): # pylint: disable=consider-using-f-string - return "<{!r}Item {!r}>".format(self.data["import_source"], self.data["Title"]) + return "<{!r}Item {!r}>".format(self.data["import_source"], self.data["title"]) def __str__(self): # pylint: disable=consider-using-f-string - return "{} by {}".format(self.data["Title"], self.data["Author"]) + return "{} by {}".format(self.data["title"], self.data["authors"]) From 4ccd9fc633321970d2ecaf64631bf19282852e69 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 10 Nov 2021 16:49:54 -0800 Subject: [PATCH 036/134] Use generalized mappings to handle import --- bookwyrm/importers/goodreads_import.py | 7 -- bookwyrm/importers/importer.py | 87 ++++++++++++--- bookwyrm/importers/librarything_import.py | 34 +----- bookwyrm/importers/storygraph_import.py | 27 +---- bookwyrm/models/import_job.py | 40 ++++--- bookwyrm/tests/data/generic.csv | 8 +- bookwyrm/tests/importers/test_importer.py | 127 +++++++++------------- 7 files changed, 152 insertions(+), 178 deletions(-) diff --git a/bookwyrm/importers/goodreads_import.py b/bookwyrm/importers/goodreads_import.py index c62e65827..c0dc0ea28 100644 --- a/bookwyrm/importers/goodreads_import.py +++ b/bookwyrm/importers/goodreads_import.py @@ -7,10 +7,3 @@ class GoodreadsImporter(Importer): For a more complete example of overriding see librarything_import.py""" service = "Goodreads" - - def parse_fields(self, entry): - """handle the specific fields in goodreads csvs""" - entry.update({"import_source": self.service}) - # add missing 'Date Started' field - entry.update({"Date Started": None}) - return entry diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index a5243cd3f..b0458bab1 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -1,5 +1,6 @@ """ handle reading a csv from an external service, defaults are from Goodreads """ import csv +from dataclasses import dataclass import logging from django.utils import timezone @@ -18,30 +19,59 @@ class Importer: service = "Unknown" delimiter = "," encoding = "UTF-8" - mandatory_fields = ["Title", "Author"] + + # these are from Goodreads + row_mappings_guesses = { + "id": ["id", "book id"], + "title": ["title"], + "authors": ["author", "authors", "primary author"], + "isbn_13": ["isbn13", "isbn"], + "isbn_10": ["isbn10", "isbn"], + "shelf": ["shelf", "exclusive shelf", "read status"], + "review_name": [], + "review_body": ["my review"], + "rating": ["my rating", "rating", "star rating"], + "date_added": ["date added", "entry date", "added"], + "date_started": ["date started", "started"], + "date_finished": ["date finished", "last date read", "date read", "finished"], + } def create_job(self, user, csv_file, include_reviews, privacy): """check over a csv and creates a database entry for the job""" + csv_reader = csv.DictReader(csv_file, delimiter=self.delimiter) + rows = enumerate(list(csv_reader)) job = ImportJob.objects.create( - user=user, include_reviews=include_reviews, privacy=privacy + user=user, + include_reviews=include_reviews, + privacy=privacy, + mappings=self.create_row_mappings(csv_reader.fieldnames), ) - for index, entry in enumerate( - list(csv.DictReader(csv_file, delimiter=self.delimiter)) - ): - if not all(x in entry for x in self.mandatory_fields): - raise ValueError("Author and title must be in data.") - entry = self.parse_fields(entry) - self.save_item(job, index, entry) + + for index, entry in rows: + print(index, entry) + self.create_item(job, index, entry) return job - def save_item(self, job, index, data): # pylint: disable=no-self-use - """creates and saves an import item""" - ImportItem(job=job, index=index, data=data).save() + def create_row_mappings(self, headers): + """guess what the headers mean""" + mappings = {} + for (key, guesses) in self.row_mappings_guesses.items(): + value = [h for h in headers if h.lower() in guesses] + value = value[0] if len(value) else None + if value: + headers.remove(value) + mappings[key] = value + return mappings - def parse_fields(self, entry): - """updates csv data with additional info""" - entry.update({"import_source": self.service}) - return entry + def create_item(self, job, index, data): + """creates and saves an import item""" + print(data) + normalized = self.normalize_row(data, job.mappings) + ImportItem(job=job, index=index, data=data, normalized_data=normalized).save() + + def normalize_row(self, entry, mappings): # pylint: disable=no-self-use + """use the dataclass to create the formatted row of data""" + return {k: entry.get(v) for k, v in mappings.items()} def create_retry_job(self, user, original_job, items): """retry items that didn't import""" @@ -49,10 +79,13 @@ class Importer: user=user, include_reviews=original_job.include_reviews, privacy=original_job.privacy, + # TODO: allow users to adjust mappings + mappings=original_job.mappings, retry=True, ) for item in items: - self.save_item(job, item.index, item.data) + # this will re-normalize the raw data + self.create_item(job, item.index, item.data) return job def start_import(self, job): @@ -156,3 +189,23 @@ def handle_imported_book(source, user, item, include_reviews, privacy): ) # only broadcast this review to other bookwyrm instances review.save(software="bookwyrm") + + +@dataclass +class ImportEntry: + """data extracted from a line in a csv""" + + title: str + authors: str = None + isbn_13: str = None + isbn_10: str = None + shelf: str = None + review_name: str = None + review_rating: float = None + review_body: str = None + review_cw: str = None + rating: float = None + date_added: str = None + date_started: str = None + date_finished: str = None + import_source: str = "Unknown" diff --git a/bookwyrm/importers/librarything_import.py b/bookwyrm/importers/librarything_import.py index b3175a82d..3d42e5392 100644 --- a/bookwyrm/importers/librarything_import.py +++ b/bookwyrm/importers/librarything_import.py @@ -1,7 +1,4 @@ -""" handle reading a csv from librarything """ -import re -import math - +""" handle reading a tsv from librarything """ from . import Importer @@ -11,32 +8,3 @@ class LibrarythingImporter(Importer): service = "LibraryThing" delimiter = "\t" encoding = "ISO-8859-1" - # mandatory_fields : fields matching the book title and author - mandatory_fields = ["Title", "Primary Author"] - - def parse_fields(self, entry): - """custom parsing for librarything""" - data = {} - data["import_source"] = self.service - data["Book Id"] = entry["Book Id"] - data["Title"] = entry["Title"] - data["Author"] = entry["Primary Author"] - data["ISBN13"] = entry["ISBN"] - data["My Review"] = entry["Review"] - if entry["Rating"]: - data["My Rating"] = math.ceil(float(entry["Rating"])) - else: - data["My Rating"] = "" - data["Date Added"] = re.sub(r"\[|\]", "", entry["Entry Date"]) - data["Date Started"] = re.sub(r"\[|\]", "", entry["Date Started"]) - data["Date Read"] = re.sub(r"\[|\]", "", entry["Date Read"]) - - data["Exclusive Shelf"] = None - if data["Date Read"]: - data["Exclusive Shelf"] = "read" - elif data["Date Started"]: - data["Exclusive Shelf"] = "reading" - else: - data["Exclusive Shelf"] = "to-read" - - return data diff --git a/bookwyrm/importers/storygraph_import.py b/bookwyrm/importers/storygraph_import.py index 1333b8b9d..9368115d4 100644 --- a/bookwyrm/importers/storygraph_import.py +++ b/bookwyrm/importers/storygraph_import.py @@ -1,6 +1,4 @@ -""" handle reading a csv from librarything """ -import re - +""" handle reading a csv from storygraph""" from . import Importer @@ -8,26 +6,3 @@ class StorygraphImporter(Importer): """csv downloads from librarything""" service = "Storygraph" - # mandatory_fields : fields matching the book title and author - mandatory_fields = ["Title"] - - def parse_fields(self, entry): - """custom parsing for storygraph""" - data = {} - data["import_source"] = self.service - data["Title"] = entry["Title"] - data["Author"] = entry["Authors"] if "Authors" in entry else entry["Author"] - data["ISBN13"] = entry["ISBN"] - data["My Review"] = entry["Review"] - if entry["Star Rating"]: - data["My Rating"] = float(entry["Star Rating"]) - else: - data["My Rating"] = "" - - data["Date Added"] = re.sub(r"[/]", "-", entry["Date Added"]) - data["Date Read"] = re.sub(r"[/]", "-", entry["Last Date Read"]) - - data["Exclusive Shelf"] = ( - {"read": "read", "currently-reading": "reading", "to-read": "to-read"} - ).get(entry["Read Status"], None) - return data diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 949e3edbf..6bca57f88 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -35,6 +35,7 @@ class ImportJob(models.Model): created_date = models.DateTimeField(default=timezone.now) task_id = models.CharField(max_length=100, null=True) include_reviews = models.BooleanField(default=True) + mappings = models.JSONField() complete = models.BooleanField(default=False) privacy = models.CharField( max_length=255, default="public", choices=PrivacyLevels.choices @@ -48,6 +49,7 @@ class ImportItem(models.Model): job = models.ForeignKey(ImportJob, on_delete=models.CASCADE, related_name="items") index = models.IntegerField() data = models.JSONField() + normalized_data = models.JSONField() book = models.ForeignKey(Book, on_delete=models.SET_NULL, null=True, blank=True) book_guess = models.ForeignKey( Book, @@ -98,55 +100,59 @@ class ImportItem(models.Model): @property def title(self): """get the book title""" - return self.data["title"] + return self.normalized_data["title"] @property def author(self): """get the book's authors""" - return self.data["authors"] + return self.normalized_data["authors"] @property def isbn(self): """pulls out the isbn13 field from the csv line data""" - return unquote_string(self.data["isbn_13"]) + return unquote_string(self.normalized_data["isbn_13"]) @property def shelf(self): """the goodreads shelf field""" - return self.data.get("shelf") + return self.normalized_data.get("shelf") @property def review(self): """a user-written review, to be imported with the book data""" - return self.data["review_body"] + return self.normalized_data["review_body"] @property def rating(self): """x/5 star rating for a book""" - if self.data.get("rating"): - return float(self.data["rating"]) + if self.normalized_data.get("rating"): + return float(self.normalized_data["rating"]) return None @property def date_added(self): """when the book was added to this dataset""" - if self.data.get("date_added"): - return timezone.make_aware(dateutil.parser.parse(self.data["date_added"])) + if self.normalized_data.get("date_added"): + return timezone.make_aware( + dateutil.parser.parse(self.normalized_data["date_added"]) + ) return None @property def date_started(self): """when the book was started""" - if self.data.get("date_started"): - return timezone.make_aware(dateutil.parser.parse(self.data["date_started"])) + if self.normalized_data.get("date_started"): + return timezone.make_aware( + dateutil.parser.parse(self.normalized_data["date_started"]) + ) return None @property def date_read(self): """the date a book was completed""" - if self.data.get("date_finished"): + if self.normalized_data.get("date_finished"): return timezone.make_aware( - dateutil.parser.parse(self.data["date_finished"]) + dateutil.parser.parse(self.normalized_data["date_finished"]) ) return None @@ -177,8 +183,12 @@ class ImportItem(models.Model): def __repr__(self): # pylint: disable=consider-using-f-string - return "<{!r}Item {!r}>".format(self.data["import_source"], self.data["title"]) + return "<{!r}Item {!r}>".format( + self.normalized_data["import_source"], self.normalized_data["title"] + ) def __str__(self): # pylint: disable=consider-using-f-string - return "{} by {}".format(self.data["title"], self.data["authors"]) + return "{} by {}".format( + self.normalized_data["title"], self.normalized_data["authors"] + ) diff --git a/bookwyrm/tests/data/generic.csv b/bookwyrm/tests/data/generic.csv index a081a6421..9c5b6f023 100644 --- a/bookwyrm/tests/data/generic.csv +++ b/bookwyrm/tests/data/generic.csv @@ -1,5 +1,5 @@ -id,title,author,ISBN,rating,shelf,review,added -38,Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,"9781250313195",,read,,2021-11-10 -48,Harrow the Ninth (The Locked Tomb #2),Tamsyn Muir,,3,read,,2021-11-10 +id,title,author,ISBN,rating,shelf,review,added,finished +38,Gideon the Ninth,Tamsyn Muir,"9781250313195",,read,,2021-11-10,2021-11-11 +48,Harrow the Ninth,Tamsyn Muir,,3,read,,2021-11-10 23,Subcutanean,Aaron A. Reed,,,read,,2021-11-10 -10,Patisserie at Home,Mélanie Dupuis,"9780062445315",2,read,"mixed feelings",2021-11-10 +10,Patisserie at Home,Mélanie Dupuis,"9780062445315",2,read,"mixed feelings",2021-11-10,2021-11-11 diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index f5d9af302..b2f0284d4 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -1,6 +1,5 @@ """ testing import """ from collections import namedtuple -import csv import pathlib from unittest.mock import patch import datetime @@ -29,26 +28,7 @@ class GenericImporter(TestCase): def setUp(self): """use a test csv""" - class TestImporter(Importer): - """basic importer""" - - mandatory_fields = ["title", "author"] - - def parse_fields(self, entry): - return { - "id": entry["id"], - "Title": entry["title"], - "Author": entry["author"], - "ISBN13": entry["ISBN"], - "Star Rating": entry["rating"], - "My Rating": entry["rating"], - "My Review": entry["review"], - "Exclusive Shelf": entry["shelf"], - "Date Added": entry["added"], - "Date Read": None, - } - - self.importer = TestImporter() + self.importer = Importer() datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") self.csv = open(datafile, "r", encoding=self.importer.encoding) with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( @@ -77,13 +57,24 @@ class GenericImporter(TestCase): import_items = models.ImportItem.objects.filter(job=import_job).all() self.assertEqual(len(import_items), 4) self.assertEqual(import_items[0].index, 0) - self.assertEqual(import_items[0].data["id"], "38") + self.assertEqual(import_items[0].normalized_data["id"], "38") + self.assertEqual(import_items[0].normalized_data["title"], "Gideon the Ninth") + self.assertEqual(import_items[0].normalized_data["authors"], "Tamsyn Muir") + self.assertEqual(import_items[0].normalized_data["isbn_13"], "9781250313195") + self.assertIsNone(import_items[0].normalized_data["isbn_10"]) + self.assertEqual(import_items[0].normalized_data["shelf"], "read") + self.assertEqual(import_items[1].index, 1) - self.assertEqual(import_items[1].data["id"], "48") + self.assertEqual(import_items[1].normalized_data["id"], "48") + self.assertEqual(import_items[1].normalized_data["title"], "Harrow the Ninth") + self.assertEqual(import_items[2].index, 2) - self.assertEqual(import_items[2].data["id"], "23") + self.assertEqual(import_items[2].normalized_data["id"], "23") + self.assertEqual(import_items[2].normalized_data["title"], "Subcutanean") + self.assertEqual(import_items[3].index, 3) - self.assertEqual(import_items[3].data["id"], "10") + self.assertEqual(import_items[3].normalized_data["id"], "10") + self.assertEqual(import_items[3].normalized_data["title"], "Patisserie at Home") def test_create_retry_job(self, *_): """trying again with items that didn't import""" @@ -103,9 +94,9 @@ class GenericImporter(TestCase): retry_items = models.ImportItem.objects.filter(job=retry).all() self.assertEqual(len(retry_items), 2) self.assertEqual(retry_items[0].index, 0) - self.assertEqual(retry_items[0].data["id"], "38") + self.assertEqual(retry_items[0].normalized_data["id"], "38") self.assertEqual(retry_items[1].index, 1) - self.assertEqual(retry_items[1].data["id"], "48") + self.assertEqual(retry_items[1].normalized_data["id"], "48") def test_start_import(self, *_): """check that a task was created""" @@ -143,15 +134,12 @@ class GenericImporter(TestCase): shelf = self.local_user.shelf_set.filter(identifier="read").first() self.assertIsNone(shelf.books.first()) - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( @@ -172,15 +160,12 @@ class GenericImporter(TestCase): shelved_date=make_date(2020, 2, 2), ) - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( @@ -199,15 +184,12 @@ class GenericImporter(TestCase): def test_handle_import_twice(self, *_): """re-importing books""" shelf = self.local_user.shelf_set.filter(identifier="read").first() - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( @@ -219,18 +201,15 @@ class GenericImporter(TestCase): shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) + self.assertEqual(models.ReadThrough.objects.count(), 1) @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """review import""" - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[3] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book - ) + import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_item = import_job.items.filter(index=3).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): with patch("bookwyrm.models.Status.broadcast") as broadcast_mock: @@ -251,14 +230,12 @@ class GenericImporter(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_rating(self, *_): """rating import""" - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[1] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" ) + import_item = import_job.items.filter(index=1).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( @@ -271,14 +248,12 @@ class GenericImporter(TestCase): def test_handle_imported_book_reviews_disabled(self, *_): """review import""" - import_job = models.ImportJob.objects.create(user=self.local_user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/generic.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[2] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" ) + import_item = import_job.items.filter(index=3).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( From 20baf9385d2253a328a69cf599a4b49e0dbf8b72 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 09:21:28 -0800 Subject: [PATCH 037/134] Updates goodreads tests --- bookwyrm/importers/importer.py | 6 +- bookwyrm/tests/data/goodreads-rating.csv | 5 - bookwyrm/tests/data/goodreads.csv | 2 +- .../tests/importers/test_goodreads_import.py | 76 +++++++-------- .../importers/test_librarything_import.py | 92 +++++++++---------- .../tests/importers/test_storygraph_import.py | 51 +++++----- 6 files changed, 109 insertions(+), 123 deletions(-) delete mode 100644 bookwyrm/tests/data/goodreads-rating.csv diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index b0458bab1..f6abef0ee 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -28,8 +28,8 @@ class Importer: "isbn_13": ["isbn13", "isbn"], "isbn_10": ["isbn10", "isbn"], "shelf": ["shelf", "exclusive shelf", "read status"], - "review_name": [], - "review_body": ["my review"], + "review_name": ["review name"], + "review_body": ["my review", "review"], "rating": ["my rating", "rating", "star rating"], "date_added": ["date added", "entry date", "added"], "date_started": ["date started", "started"], @@ -48,7 +48,6 @@ class Importer: ) for index, entry in rows: - print(index, entry) self.create_item(job, index, entry) return job @@ -65,7 +64,6 @@ class Importer: def create_item(self, job, index, data): """creates and saves an import item""" - print(data) normalized = self.normalize_row(data, job.mappings) ImportItem(job=job, index=index, data=data, normalized_data=normalized).save() diff --git a/bookwyrm/tests/data/goodreads-rating.csv b/bookwyrm/tests/data/goodreads-rating.csv deleted file mode 100644 index fec0c77d5..000000000 --- a/bookwyrm/tests/data/goodreads-rating.csv +++ /dev/null @@ -1,5 +0,0 @@ -Book Id,Title,Author,Author l-f,Additional Authors,ISBN,ISBN13,My Rating,Average Rating,Publisher,Binding,Number of Pages,Year Published,Original Publication Year,Date Read,Date Added,Bookshelves,Bookshelves with positions,Exclusive Shelf,My Review,Spoiler,Private Notes,Read Count,Recommended For,Recommended By,Owned Copies,Original Purchase Date,Original Purchase Location,Condition,Condition Description,BCID -42036538,Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,"Muir, Tamsyn",,"=""1250313198""","=""9781250313195""",0,4.20,Tor,Hardcover,448,2019,2019,2020/10/25,2020/10/21,,,read,,,,1,,,0,,,,, -52691223,Subcutanean,Aaron A. Reed,"Reed, Aaron A.",,"=""""","=""""",0,4.45,,Paperback,232,2020,,2020/03/06,2020/03/05,,,read,,,,1,,,0,,,,, -28694510,Patisserie at Home,Mélanie Dupuis,"Dupuis, Mélanie",Anne Cazor,"=""0062445316""","=""9780062445315""",2,4.60,Harper Design,Hardcover,288,2016,,,2019/07/08,,,read,,,,2,,,0,,,,, - diff --git a/bookwyrm/tests/data/goodreads.csv b/bookwyrm/tests/data/goodreads.csv index 5f124edc9..a0a8232e1 100644 --- a/bookwyrm/tests/data/goodreads.csv +++ b/bookwyrm/tests/data/goodreads.csv @@ -1,4 +1,4 @@ Book Id,Title,Author,Author l-f,Additional Authors,ISBN,ISBN13,My Rating,Average Rating,Publisher,Binding,Number of Pages,Year Published,Original Publication Year,Date Read,Date Added,Bookshelves,Bookshelves with positions,Exclusive Shelf,My Review,Spoiler,Private Notes,Read Count,Recommended For,Recommended By,Owned Copies,Original Purchase Date,Original Purchase Location,Condition,Condition Description,BCID -42036538,Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,"Muir, Tamsyn",,"=""1250313198""","=""9781250313195""",0,4.20,Tor,Hardcover,448,2019,2019,2020/10/25,2020/10/21,,,read,,,,1,,,0,,,,, +42036538,Gideon the Ninth (The Locked Tomb #1),Tamsyn Muir,"Muir, Tamsyn",,"=""1250313198""","=""9781250313195""",3,4.20,Tor,Hardcover,448,2019,2019,2020/10/25,2020/10/21,,,read,,,,1,,,0,,,,, 52691223,Subcutanean,Aaron A. Reed,"Reed, Aaron A.",,"=""""","=""""",0,4.45,,Paperback,232,2020,,2020/03/06,2020/03/05,,,read,,,,1,,,0,,,,, 28694510,Patisserie at Home,Mélanie Dupuis,"Dupuis, Mélanie",Anne Cazor,"=""0062445316""","=""9780062445315""",2,4.60,Harper Design,Hardcover,288,2016,,,2019/07/08,,,read,"mixed feelings",,,2,,,0,,,,, diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index a24512921..87624a0e5 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -1,5 +1,4 @@ """ testing import """ -import csv import pathlib from unittest.mock import patch import datetime @@ -32,7 +31,7 @@ class GoodreadsImport(TestCase): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ): - self.user = models.User.objects.create_user( + self.local_user = models.User.objects.create_user( "mouse", "mouse@mouse.mouse", "password", local=True ) @@ -45,7 +44,9 @@ class GoodreadsImport(TestCase): def test_create_job(self, *_): """creates the import job entry and checks csv""" - import_job = self.importer.create_job(self.user, self.csv, False, "public") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) import_items = models.ImportItem.objects.filter(job=import_job).all() self.assertEqual(len(import_items), 3) @@ -58,12 +59,16 @@ class GoodreadsImport(TestCase): def test_create_retry_job(self, *_): """trying again with items that didn't import""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] - retry = self.importer.create_retry_job(self.user, import_job, import_items) + retry = self.importer.create_retry_job( + self.local_user, import_job, import_items + ) self.assertNotEqual(import_job, retry) - self.assertEqual(retry.user, self.user) + self.assertEqual(retry.user, self.local_user) self.assertEqual(retry.include_reviews, False) self.assertEqual(retry.privacy, "unlisted") @@ -76,22 +81,19 @@ class GoodreadsImport(TestCase): def test_handle_imported_book(self, *_): """goodreads import added a book, this adds related connections""" - shelf = self.user.shelf_set.filter(identifier="read").first() + shelf = self.local_user.shelf_set.filter(identifier="read").first() self.assertIsNone(shelf.books.first()) - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, False, "public" + self.importer.service, self.local_user, import_item, False, "public" ) shelf.refresh_from_db() @@ -100,7 +102,7 @@ class GoodreadsImport(TestCase): shelf.shelfbook_set.first().shelved_date, make_date(2020, 10, 21) ) - readthrough = models.ReadThrough.objects.get(user=self.user) + readthrough = models.ReadThrough.objects.get(user=self.local_user) self.assertEqual(readthrough.book, self.book) self.assertEqual(readthrough.start_date, make_date(2020, 10, 21)) self.assertEqual(readthrough.finish_date, make_date(2020, 10, 25)) @@ -108,20 +110,16 @@ class GoodreadsImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """goodreads review import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[2] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book - ) + import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_item = import_job.items.get(index=2) + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, True, "unlisted" + self.importer.service, self.local_user, import_item, True, "unlisted" ) - review = models.Review.objects.get(book=self.book, user=self.user) + review = models.Review.objects.get(book=self.book, user=self.local_user) self.assertEqual(review.content, "mixed feelings") self.assertEqual(review.rating, 2) self.assertEqual(review.published_date, make_date(2019, 7, 8)) @@ -130,23 +128,19 @@ class GoodreadsImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_rating(self, *_): """goodreads rating import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath( - "../data/goodreads-rating.csv" - ) - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[2] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" ) + import_item = import_job.items.filter(index=0).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, True, "unlisted" + self.importer.service, self.local_user, import_item, True, "unlisted" ) - review = models.ReviewRating.objects.get(book=self.book, user=self.user) + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) self.assertIsInstance(review, models.ReviewRating) - self.assertEqual(review.rating, 2) - self.assertEqual(review.published_date, make_date(2019, 7, 8)) + self.assertEqual(review.rating, 3) + self.assertEqual(review.published_date, make_date(2020, 10, 25)) self.assertEqual(review.privacy, "unlisted") diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index f76666a78..00bb0ffa0 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -35,7 +35,7 @@ class LibrarythingImport(TestCase): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ): - self.user = models.User.objects.create_user( + self.local_user = models.User.objects.create_user( "mmai", "mmai@mmai.mmai", "password", local=True ) work = models.Work.objects.create(title="Test Work") @@ -47,8 +47,10 @@ class LibrarythingImport(TestCase): def test_create_job(self, *_): """creates the import job entry and checks csv""" - import_job = self.importer.create_job(self.user, self.csv, False, "public") - self.assertEqual(import_job.user, self.user) + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + self.assertEqual(import_job.user, self.local_user) self.assertEqual(import_job.include_reviews, False) self.assertEqual(import_job.privacy, "public") @@ -63,12 +65,16 @@ class LibrarythingImport(TestCase): def test_create_retry_job(self, *_): """trying again with items that didn't import""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] - retry = self.importer.create_retry_job(self.user, import_job, import_items) + retry = self.importer.create_retry_job( + self.local_user, import_job, import_items + ) self.assertNotEqual(import_job, retry) - self.assertEqual(retry.user, self.user) + self.assertEqual(retry.user, self.local_user) self.assertEqual(retry.include_reviews, False) self.assertEqual(retry.privacy, "unlisted") @@ -82,7 +88,9 @@ class LibrarythingImport(TestCase): @responses.activate def test_import_data(self, *_): """resolve entry""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) book = models.Edition.objects.create(title="Test Book") with patch( @@ -97,30 +105,25 @@ class LibrarythingImport(TestCase): def test_handle_imported_book(self, *_): """librarything import added a book, this adds related connections""" - shelf = self.user.shelf_set.filter(identifier="read").first() + shelf = self.local_user.shelf_set.filter(identifier="read").first() self.assertIsNone(shelf.books.first()) - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/librarything.tsv") - csv_file = open(datafile, "r", encoding=self.importer.encoding) - for index, entry in enumerate( - list(csv.DictReader(csv_file, delimiter=self.importer.delimiter)) - ): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, False, "public" + self.importer.service, self.local_user, import_item, False, "public" ) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) - readthrough = models.ReadThrough.objects.get(user=self.user) + readthrough = models.ReadThrough.objects.get(user=self.local_user) self.assertEqual(readthrough.book, self.book) self.assertEqual(readthrough.start_date, make_date(2007, 4, 16)) self.assertEqual(readthrough.finish_date, make_date(2007, 5, 8)) @@ -128,31 +131,30 @@ class LibrarythingImport(TestCase): def test_handle_imported_book_already_shelved(self, *_): """librarything import added a book, this adds related connections""" with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): - shelf = self.user.shelf_set.filter(identifier="to-read").first() - models.ShelfBook.objects.create(shelf=shelf, user=self.user, book=self.book) - - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/librarything.tsv") - csv_file = open(datafile, "r", encoding=self.importer.encoding) - for index, entry in enumerate( - list(csv.DictReader(csv_file, delimiter=self.importer.delimiter)) - ): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book + shelf = self.local_user.shelf_set.filter(identifier="to-read").first() + models.ShelfBook.objects.create( + shelf=shelf, user=self.local_user, book=self.book ) - break + + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, False, "public" + self.importer.service, self.local_user, import_item, False, "public" ) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) - self.assertIsNone(self.user.shelf_set.get(identifier="read").books.first()) + self.assertIsNone( + self.local_user.shelf_set.get(identifier="read").books.first() + ) - readthrough = models.ReadThrough.objects.get(user=self.user) + readthrough = models.ReadThrough.objects.get(user=self.local_user) self.assertEqual(readthrough.book, self.book) self.assertEqual(readthrough.start_date, make_date(2007, 4, 16)) self.assertEqual(readthrough.finish_date, make_date(2007, 5, 8)) @@ -160,20 +162,16 @@ class LibrarythingImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """librarything review import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/librarything.tsv") - csv_file = open(datafile, "r", encoding=self.importer.encoding) - entry = list(csv.DictReader(csv_file, delimiter=self.importer.delimiter))[0] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book - ) + import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_item = import_job.items.filter(index=0).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, True, "unlisted" + self.importer.service, self.local_user, import_item, True, "unlisted" ) - review = models.Review.objects.get(book=self.book, user=self.user) + review = models.Review.objects.get(book=self.book, user=self.local_user) self.assertEqual(review.content, "chef d'oeuvre") self.assertEqual(review.rating, 5) self.assertEqual(review.published_date, make_date(2007, 5, 8)) diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index addf362cb..91a5dfa61 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -32,7 +32,7 @@ class StorygraphImport(TestCase): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ): - self.user = models.User.objects.create_user( + self.local_user = models.User.objects.create_user( "mouse", "mouse@mouse.mouse", "password", local=True ) @@ -45,7 +45,9 @@ class StorygraphImport(TestCase): def test_create_job(self, *_): """creates the import job entry and checks csv""" - import_job = self.importer.create_job(self.user, self.csv, False, "public") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) import_items = models.ImportItem.objects.filter(job=import_job).all() self.assertEqual(len(import_items), 2) @@ -57,12 +59,16 @@ class StorygraphImport(TestCase): def test_create_retry_job(self, *_): """trying again with items that didn't import""" - import_job = self.importer.create_job(self.user, self.csv, False, "unlisted") + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] - retry = self.importer.create_retry_job(self.user, import_job, import_items) + retry = self.importer.create_retry_job( + self.local_user, import_job, import_items + ) self.assertNotEqual(import_job, retry) - self.assertEqual(retry.user, self.user) + self.assertEqual(retry.user, self.local_user) self.assertEqual(retry.include_reviews, False) self.assertEqual(retry.privacy, "unlisted") @@ -75,22 +81,19 @@ class StorygraphImport(TestCase): def test_handle_imported_book(self, *_): """storygraph import added a book, this adds related connections""" - shelf = self.user.shelf_set.filter(identifier="to-read").first() + shelf = self.local_user.shelf_set.filter(identifier="to-read").first() self.assertIsNone(shelf.books.first()) - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/storygraph.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - for index, entry in enumerate(list(csv.DictReader(csv_file))): - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=index, data=entry, book=self.book - ) - break + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" + ) + import_item = import_job.items.first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, False, "public" + self.importer.service, self.local_user, import_item, False, "public" ) shelf.refresh_from_db() @@ -102,20 +105,18 @@ class StorygraphImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_rating(self, *_): """storygraph rating import""" - import_job = models.ImportJob.objects.create(user=self.user) - datafile = pathlib.Path(__file__).parent.joinpath("../data/storygraph.csv") - csv_file = open(datafile, "r") # pylint: disable=unspecified-encoding - entry = list(csv.DictReader(csv_file))[1] - entry = self.importer.parse_fields(entry) - import_item = models.ImportItem.objects.create( - job_id=import_job.id, index=0, data=entry, book=self.book + import_job = self.importer.create_job( + self.local_user, self.csv, False, "public" ) + import_item = import_job.items.filter(index=1).first() + import_item.book = self.book + import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): handle_imported_book( - self.importer.service, self.user, import_item, True, "unlisted" + self.importer.service, self.local_user, import_item, True, "unlisted" ) - review = models.ReviewRating.objects.get(book=self.book, user=self.user) + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) self.assertIsInstance(review, models.ReviewRating) self.assertEqual(review.rating, 5.0) self.assertEqual(review.published_date, make_date(2021, 5, 10)) From 4d574a3536c88d1a51307b4e288ef2185ed71b13 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 09:54:36 -0800 Subject: [PATCH 038/134] Process dates in librarything import --- bookwyrm/importers/importer.py | 1 + bookwyrm/importers/librarything_import.py | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index f6abef0ee..8acfb1473 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -35,6 +35,7 @@ class Importer: "date_started": ["date started", "started"], "date_finished": ["date finished", "last date read", "date read", "finished"], } + date_fields = ["date_added", "date_started", "date_finished"] def create_job(self, user, csv_file, include_reviews, privacy): """check over a csv and creates a database entry for the job""" diff --git a/bookwyrm/importers/librarything_import.py b/bookwyrm/importers/librarything_import.py index 3d42e5392..12d841e9e 100644 --- a/bookwyrm/importers/librarything_import.py +++ b/bookwyrm/importers/librarything_import.py @@ -1,4 +1,5 @@ """ handle reading a tsv from librarything """ +import re from . import Importer @@ -8,3 +9,11 @@ class LibrarythingImporter(Importer): service = "LibraryThing" delimiter = "\t" encoding = "ISO-8859-1" + + def normalize_row(self, entry, mappings): # pylint: disable=no-self-use + """use the dataclass to create the formatted row of data""" + normalized = {k: entry.get(v) for k, v in mappings.items()} + for date_field in self.date_fields: + date = normalized[date_field] + normalized[date_field] = re.sub(r"\[|\]", "", date) + return normalized From a95e031140bc188e172523add8d201034f75f534 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 11:33:12 -0800 Subject: [PATCH 039/134] Validate html in unit tests --- bookwyrm/tests/views/test_import.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index 2027d2845..b29190e72 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -5,6 +5,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory +from bookwyrm.tests.validate_html import validate_html from bookwyrm import forms, models, views @@ -34,7 +35,7 @@ class ImportViews(TestCase): request.user = self.local_user result = view(request) self.assertIsInstance(result, TemplateResponse) - result.render() + validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_import_status(self): @@ -47,7 +48,7 @@ class ImportViews(TestCase): async_result.return_value = [] result = view(request, import_job.id) self.assertIsInstance(result, TemplateResponse) - result.render() + validate_html(result.render()) self.assertEqual(result.status_code, 200) def test_start_import(self): @@ -58,7 +59,9 @@ class ImportViews(TestCase): form.data["privacy"] = "public" form.data["include_reviews"] = False csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - form.data["csv_file"] = SimpleUploadedFile( + form.data[ + "csv_file" + ] = SimpleUploadedFile( # pylint: disable=consider-using-with csv_file, open(csv_file, "rb").read(), content_type="text/csv" ) From 147dd95e8d00a209ac1af1f87f36175a8da1afca Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 11:59:15 -0800 Subject: [PATCH 040/134] Removes unused import --- bookwyrm/tests/importers/test_librarything_import.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index 00bb0ffa0..aa52e2f13 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -1,5 +1,4 @@ """ testing import """ -import csv import pathlib from unittest.mock import patch import datetime From f3bcced0a019b119e02d2d191af41f49f9a65af8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 12:29:38 -0800 Subject: [PATCH 041/134] Adds shelf mappings --- bookwyrm/importers/importer.py | 12 ++++++++++++ bookwyrm/importers/librarything_import.py | 7 +++++++ bookwyrm/tests/importers/test_librarything_import.py | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 8acfb1473..0233ee3d3 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -36,6 +36,11 @@ class Importer: "date_finished": ["date finished", "last date read", "date read", "finished"], } date_fields = ["date_added", "date_started", "date_finished"] + shelf_mapping_guesses = { + "to-read": ["to-read"], + "read": ["read"], + "reading": ["currently-reading", "reading"], + } def create_job(self, user, csv_file, include_reviews, privacy): """check over a csv and creates a database entry for the job""" @@ -66,8 +71,15 @@ class Importer: def create_item(self, job, index, data): """creates and saves an import item""" normalized = self.normalize_row(data, job.mappings) + normalized["shelf"] = self.get_shelf(normalized) ImportItem(job=job, index=index, data=data, normalized_data=normalized).save() + def get_shelf(self, normalized_row): + """determine which shelf to use""" + shelf_name = normalized_row["shelf"] + shelf = [s for (s, gs) in self.shelf_mapping_guesses if shelf_name in gs] + return shelf[0] if shelf else None + def normalize_row(self, entry, mappings): # pylint: disable=no-self-use """use the dataclass to create the formatted row of data""" return {k: entry.get(v) for k, v in mappings.items()} diff --git a/bookwyrm/importers/librarything_import.py b/bookwyrm/importers/librarything_import.py index 12d841e9e..d6426de6e 100644 --- a/bookwyrm/importers/librarything_import.py +++ b/bookwyrm/importers/librarything_import.py @@ -17,3 +17,10 @@ class LibrarythingImporter(Importer): date = normalized[date_field] normalized[date_field] = re.sub(r"\[|\]", "", date) return normalized + + def get_shelf(self, normalized_row): + if normalized_row["date_finished"]: + return "read" + if normalized_row["date_started"]: + return "reading" + return "to-read" diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index aa52e2f13..e93528963 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -172,6 +172,6 @@ class LibrarythingImport(TestCase): ) review = models.Review.objects.get(book=self.book, user=self.local_user) self.assertEqual(review.content, "chef d'oeuvre") - self.assertEqual(review.rating, 5) + self.assertEqual(review.rating, 4.5) self.assertEqual(review.published_date, make_date(2007, 5, 8)) self.assertEqual(review.privacy, "unlisted") From 59678348053f43f83912fa4e4ea11f046844f534 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 12:29:51 -0800 Subject: [PATCH 042/134] Adds migration --- .../migrations/0113_auto_20211110_2104.py | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 bookwyrm/migrations/0113_auto_20211110_2104.py diff --git a/bookwyrm/migrations/0113_auto_20211110_2104.py b/bookwyrm/migrations/0113_auto_20211110_2104.py new file mode 100644 index 000000000..572ba280c --- /dev/null +++ b/bookwyrm/migrations/0113_auto_20211110_2104.py @@ -0,0 +1,25 @@ +# Generated by Django 3.2.5 on 2021-11-10 21:04 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0112_auto_20211022_0844"), + ] + + operations = [ + migrations.AddField( + model_name="importitem", + name="normalized_data", + field=models.JSONField(default={}), + preserve_default=False, + ), + migrations.AddField( + model_name="importjob", + name="mappings", + field=models.JSONField(default={}), + preserve_default=False, + ), + ] From efcf7824dd47de77c3cc2e0bcc972bbd131b05af Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 12:39:12 -0800 Subject: [PATCH 043/134] iUpdates storygraph tests --- bookwyrm/importers/importer.py | 4 +++- bookwyrm/tests/importers/test_storygraph_import.py | 14 +++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 0233ee3d3..cf7841e6f 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -77,7 +77,9 @@ class Importer: def get_shelf(self, normalized_row): """determine which shelf to use""" shelf_name = normalized_row["shelf"] - shelf = [s for (s, gs) in self.shelf_mapping_guesses if shelf_name in gs] + shelf = [ + s for (s, gs) in self.shelf_mapping_guesses.items() if shelf_name in gs + ] return shelf[0] if shelf else None def normalize_row(self, entry, mappings): # pylint: disable=no-self-use diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index 91a5dfa61..2f0fd7ef3 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -52,10 +52,12 @@ class StorygraphImport(TestCase): import_items = models.ImportItem.objects.filter(job=import_job).all() self.assertEqual(len(import_items), 2) self.assertEqual(import_items[0].index, 0) - self.assertEqual(import_items[0].data["Title"], "Always Coming Home") + self.assertEqual(import_items[0].normalized_data["title"], "Always Coming Home") self.assertEqual(import_items[1].index, 1) - self.assertEqual(import_items[1].data["Title"], "Subprime Attention Crisis") - self.assertEqual(import_items[1].data["My Rating"], 5.0) + self.assertEqual( + import_items[1].normalized_data["title"], "Subprime Attention Crisis" + ) + self.assertEqual(import_items[1].normalized_data["rating"], "5.0") def test_create_retry_job(self, *_): """trying again with items that didn't import""" @@ -75,9 +77,11 @@ class StorygraphImport(TestCase): retry_items = models.ImportItem.objects.filter(job=retry).all() self.assertEqual(len(retry_items), 2) self.assertEqual(retry_items[0].index, 0) - self.assertEqual(retry_items[0].data["Title"], "Always Coming Home") + self.assertEqual(retry_items[0].normalized_data["title"], "Always Coming Home") self.assertEqual(retry_items[1].index, 1) - self.assertEqual(retry_items[1].data["Title"], "Subprime Attention Crisis") + self.assertEqual( + retry_items[1].normalized_data["title"], "Subprime Attention Crisis" + ) def test_handle_imported_book(self, *_): """storygraph import added a book, this adds related connections""" From d807774c2d00fa5c3320b7be473330e4aee86161 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 12:53:48 -0800 Subject: [PATCH 044/134] Fixes label for privacy field --- bookwyrm/templates/import/import.html | 6 +++--- bookwyrm/tests/views/test_import.py | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/bookwyrm/templates/import/import.html b/bookwyrm/templates/import/import.html index 81f0daa54..314a6861f 100644 --- a/bookwyrm/templates/import/import.html +++ b/bookwyrm/templates/import/import.html @@ -46,10 +46,10 @@
-
diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index b29190e72..29f4902d7 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -61,7 +61,8 @@ class ImportViews(TestCase): csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") form.data[ "csv_file" - ] = SimpleUploadedFile( # pylint: disable=consider-using-with + ] = SimpleUploadedFile( + # pylint: disable=consider-using-with csv_file, open(csv_file, "rb").read(), content_type="text/csv" ) From c744faf393c1b354781e65a3a28927176b7f07fd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 13:00:34 -0800 Subject: [PATCH 045/134] Fixes dictionary list html validity --- bookwyrm/templates/import/import_status.html | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 1c0739444..91e48e34e 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -10,18 +10,17 @@

{% trans "Import Status" %}

{% trans "Back to imports" %} + {% if task.failed %} +
{% trans "TASK FAILED" %}
+ {% endif %} +
-
-
{% trans "Import started:" %}
-
{{ job.created_date | naturaltime }}
-
+
{% trans "Import started:" %}
+
{{ job.created_date | naturaltime }}
+ {% if job.complete %} -
-
{% trans "Import completed:" %}
-
{{ task.date_done | naturaltime }}
-
- {% elif task.failed %} -
{% trans "TASK FAILED" %}
+
{% trans "Import completed:" %}
+
{{ task.date_done | naturaltime }}
{% endif %}
From 8c4e8361f2c69041c58dd28889da1405578a5e18 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 13:35:56 -0800 Subject: [PATCH 046/134] Fixes tests --- bookwyrm/tests/models/test_status_model.py | 50 ++++++++++++++-------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index f5013422c..7d0dd138b 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -2,7 +2,7 @@ from unittest.mock import patch from io import BytesIO import pathlib -from urllib.parse import urljoin +import re from django.http import Http404 from django.core.files.base import ContentFile @@ -191,9 +191,11 @@ class Status(TestCase): self.assertEqual(activity["sensitive"], False) self.assertIsInstance(activity["attachment"], list) self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -221,9 +223,11 @@ class Status(TestCase): f'test content

(comment on "Test Edition")

', ) self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -258,9 +262,11 @@ class Status(TestCase): f'a sickening sense

-- "Test Edition"

test content', ) self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -299,9 +305,11 @@ class Status(TestCase): ) self.assertEqual(activity["content"], "test content") self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -321,9 +329,11 @@ class Status(TestCase): ) self.assertEqual(activity["content"], "test content") self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") @@ -342,9 +352,11 @@ class Status(TestCase): f'rated {self.book.title}: 3 stars', ) self.assertEqual(activity["attachment"][0].type, "Document") - self.assertEqual( - activity["attachment"][0].url, - urljoin(settings.MEDIA_FULL_URL, self.book.cover.url.lstrip("/")), + self.assertTrue( + re.match( + r"https:\/\/your.domain.here\/images\/covers\/test_[A-z0-9]+.jpg", + activity["attachment"][0].url, + ) ) self.assertEqual(activity["attachment"][0].name, "Test Edition") From ffcaef055959b64576b9b01bbc0f84715cafb248 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 13:39:58 -0800 Subject: [PATCH 047/134] Python formatting --- bookwyrm/tests/views/test_import.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index 29f4902d7..1411a5a89 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -59,11 +59,11 @@ class ImportViews(TestCase): form.data["privacy"] = "public" form.data["include_reviews"] = False csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") - form.data[ - "csv_file" - ] = SimpleUploadedFile( + form.data["csv_file"] = SimpleUploadedFile( # pylint: disable=consider-using-with - csv_file, open(csv_file, "rb").read(), content_type="text/csv" + csv_file, + open(csv_file, "rb").read(), + content_type="text/csv", ) request = self.factory.post("", form.data) From 50ab4e8248bbcb740292d50e4b4459f8eddffa7b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 14:08:00 -0800 Subject: [PATCH 048/134] Updates model tests --- bookwyrm/tests/models/test_import_model.py | 154 ++++++++++++--------- 1 file changed, 87 insertions(+), 67 deletions(-) diff --git a/bookwyrm/tests/models/test_import_model.py b/bookwyrm/tests/models/test_import_model.py index 0e5d6760a..f48143d0d 100644 --- a/bookwyrm/tests/models/test_import_model.py +++ b/bookwyrm/tests/models/test_import_model.py @@ -18,83 +18,68 @@ class ImportJob(TestCase): def setUp(self): """data is from a goodreads export of The Raven Tower""" - read_data = { - "Book Id": 39395857, - "Title": "The Raven Tower", - "Author": "Ann Leckie", - "Author l-f": "Leckie, Ann", - "Additional Authors": "", - "ISBN": '="0356506991"', - "ISBN13": '="9780356506999"', - "My Rating": 0, - "Average Rating": 4.06, - "Publisher": "Orbit", - "Binding": "Hardcover", - "Number of Pages": 416, - "Year Published": 2019, - "Original Publication Year": 2019, - "Date Read": "2019/04/12", - "Date Added": "2019/04/09", - "Bookshelves": "", - "Bookshelves with positions": "", - "Exclusive Shelf": "read", - "My Review": "", - "Spoiler": "", - "Private Notes": "", - "Read Count": 1, - "Recommended For": "", - "Recommended By": "", - "Owned Copies": 0, - "Original Purchase Date": "", - "Original Purchase Location": "", - "Condition": "", - "Condition Description": "", - "BCID": "", - } - currently_reading_data = read_data.copy() - currently_reading_data["Exclusive Shelf"] = "currently-reading" - currently_reading_data["Date Read"] = "" - - unknown_read_data = currently_reading_data.copy() - unknown_read_data["Exclusive Shelf"] = "read" - unknown_read_data["Date Read"] = "" - with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( "bookwyrm.activitystreams.populate_stream_task.delay" ): - user = models.User.objects.create_user( - "mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse" + self.local_user = models.User.objects.create_user( + "mouse", "mouse@mouse.mouse", "password", local=True ) - job = models.ImportJob.objects.create(user=user) - self.item_1 = models.ImportItem.objects.create( - job=job, index=1, data=currently_reading_data - ) - self.item_2 = models.ImportItem.objects.create(job=job, index=2, data=read_data) - self.item_3 = models.ImportItem.objects.create( - job=job, index=3, data=unknown_read_data - ) + self.job = models.ImportJob.objects.create(user=self.local_user, mappings={}) def test_isbn(self): """it unquotes the isbn13 field from data""" - expected = "9780356506999" - item = models.ImportItem.objects.get(index=1) - self.assertEqual(item.isbn, expected) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + }, + ) + self.assertEqual(item.isbn, "9780356506999") def test_shelf(self): """converts to the local shelf typology""" - expected = "reading" - self.assertEqual(self.item_1.shelf, expected) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + }, + ) + self.assertEqual(item.shelf, "reading") def test_date_added(self): """converts to the local shelf typology""" expected = datetime.datetime(2019, 4, 9, 0, 0, tzinfo=timezone.utc) - item = models.ImportItem.objects.get(index=1) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + "date_added": "2019/04/09", + }, + ) self.assertEqual(item.date_added, expected) def test_date_read(self): """converts to the local shelf typology""" expected = datetime.datetime(2019, 4, 12, 0, 0, tzinfo=timezone.utc) - item = models.ImportItem.objects.get(index=2) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + "date_added": "2019/04/09", + "date_finished": "2019/04/12", + }, + ) self.assertEqual(item.date_read, expected) def test_currently_reading_reads(self): @@ -104,31 +89,66 @@ class ImportJob(TestCase): start_date=datetime.datetime(2019, 4, 9, 0, 0, tzinfo=timezone.utc) ) ] - actual = models.ImportItem.objects.get(index=1) - self.assertEqual(actual.reads[0].start_date, expected[0].start_date) - self.assertEqual(actual.reads[0].finish_date, expected[0].finish_date) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + "date_added": "2019/04/09", + }, + ) + self.assertEqual(item.reads[0].start_date, expected[0].start_date) + self.assertIsNone(item.reads[0].finish_date) def test_read_reads(self): """infer read dates where available""" - actual = self.item_2 + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + "date_added": "2019/04/09", + "date_finished": "2019/04/12", + }, + ) self.assertEqual( - actual.reads[0].start_date, + item.reads[0].start_date, datetime.datetime(2019, 4, 9, 0, 0, tzinfo=timezone.utc), ) self.assertEqual( - actual.reads[0].finish_date, + item.reads[0].finish_date, datetime.datetime(2019, 4, 12, 0, 0, tzinfo=timezone.utc), ) def test_unread_reads(self): """handle books with no read dates""" expected = [] - actual = models.ImportItem.objects.get(index=3) - self.assertEqual(actual.reads, expected) + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + "shelf": "reading", + }, + ) + self.assertEqual(item.reads, expected) @responses.activate def test_get_book_from_isbn(self): """search and load books by isbn (9780356506999)""" + item = models.ImportItem.objects.create( + index=1, + job=self.job, + data={}, + normalized_data={ + "isbn_13": '="9780356506999"', + }, + ) connector_info = models.Connector.objects.create( identifier="openlibrary.org", name="OpenLibrary", @@ -177,6 +197,6 @@ class ImportJob(TestCase): with patch( "bookwyrm.connectors.openlibrary.Connector." "get_authors_from_data" ): - book = self.item_1.get_book_from_isbn() + book = item.get_book_from_isbn() self.assertEqual(book.title, "Sabriel") From be94818a10aa049ffc8e3ff0789dddd7a9706f72 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 14:27:29 -0800 Subject: [PATCH 049/134] Fixes views tests --- bookwyrm/tests/views/test_import.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index 1411a5a89..54f11f038 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -41,7 +41,7 @@ class ImportViews(TestCase): def test_import_status(self): """there are so many views, this just makes sure it LOADS""" view = views.ImportStatus.as_view() - import_job = models.ImportJob.objects.create(user=self.local_user) + import_job = models.ImportJob.objects.create(user=self.local_user, mappings={}) request = self.factory.get("") request.user = self.local_user with patch("bookwyrm.tasks.app.AsyncResult") as async_result: @@ -55,7 +55,7 @@ class ImportViews(TestCase): """retry failed items""" view = views.Import.as_view() form = forms.ImportForm() - form.data["source"] = "LibraryThing" + form.data["source"] = "Goodreads" form.data["privacy"] = "public" form.data["include_reviews"] = False csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") @@ -79,7 +79,7 @@ class ImportViews(TestCase): """retry failed items""" view = views.ImportStatus.as_view() import_job = models.ImportJob.objects.create( - user=self.local_user, privacy="unlisted" + user=self.local_user, privacy="unlisted", mappings={} ) request = self.factory.post("") request.user = self.local_user From f0ce236ffc4a17ea34d32f00065fdf727b6665c7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 14:28:01 -0800 Subject: [PATCH 050/134] Removes unused code --- bookwyrm/importers/importer.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index cf7841e6f..69391e945 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -1,6 +1,5 @@ """ handle reading a csv from an external service, defaults are from Goodreads """ import csv -from dataclasses import dataclass import logging from django.utils import timezone @@ -202,23 +201,3 @@ def handle_imported_book(source, user, item, include_reviews, privacy): ) # only broadcast this review to other bookwyrm instances review.save(software="bookwyrm") - - -@dataclass -class ImportEntry: - """data extracted from a line in a csv""" - - title: str - authors: str = None - isbn_13: str = None - isbn_10: str = None - shelf: str = None - review_name: str = None - review_rating: float = None - review_body: str = None - review_cw: str = None - rating: float = None - date_added: str = None - date_started: str = None - date_finished: str = None - import_source: str = "Unknown" From 908c9dc689aefd70c278254b81611515e7ad67a9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 14:39:53 -0800 Subject: [PATCH 051/134] Use many small tasks instead of one big task --- bookwyrm/importers/importer.py | 49 +++++++++++++++++----------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 69391e945..8ad4cd2e4 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -102,39 +102,40 @@ class Importer: def start_import(self, job): """initalizes a csv import job""" - result = import_data.delay(self.service, job.id) + result = start_import_task.delay(self.service, job.id) job.task_id = result.id job.save() @app.task(queue="low_priority") -def import_data(source, job_id): - """does the actual lookup work in a celery task""" +def start_import_task(source, job_id): + """trigger the child tasks for each row""" job = ImportJob.objects.get(id=job_id) + # these are sub-tasks so that one big task doesn't use up all the memory in celery + for item in job.items.values("id").all(): + import_item_task.delay(source, item.id) + + +@app.task(queue="low_priority") +def import_item_task(source, item_id): + """resolve a row into a book""" + item = models.ImportItem.objets.get(id=item_id) try: - for item in job.items.all(): - try: - item.resolve() - except Exception as err: # pylint: disable=broad-except - logger.exception(err) - item.fail_reason = _("Error loading book") - item.save() - continue + item.resolve() + except Exception as err: # pylint: disable=broad-except + logger.exception(err) + item.fail_reason = _("Error loading book") + item.save() + return - if item.book or item.book_guess: - item.save() + if item.book: + job = item.job + # shelves book and handles reviews + handle_imported_book(source, job.user, item, job.include_reviews, job.privacy) + else: + item.fail_reason = _("Could not find a match for book") - if item.book: - # shelves book and handles reviews - handle_imported_book( - source, job.user, item, job.include_reviews, job.privacy - ) - else: - item.fail_reason = _("Could not find a match for book") - item.save() - finally: - job.complete = True - job.save() + item.save() def handle_imported_book(source, user, item, include_reviews, privacy): From c33d791974df8a37de257baae37cf7fc86be88c9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 15:17:32 -0800 Subject: [PATCH 052/134] adds tests for new task system --- bookwyrm/importers/importer.py | 6 ++--- bookwyrm/tests/importers/test_importer.py | 30 ++++++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 8ad4cd2e4..d7f32c88e 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -112,14 +112,14 @@ def start_import_task(source, job_id): """trigger the child tasks for each row""" job = ImportJob.objects.get(id=job_id) # these are sub-tasks so that one big task doesn't use up all the memory in celery - for item in job.items.values("id").all(): - import_item_task.delay(source, item.id) + for item in job.items.values_list("id", flat=True).all(): + import_item_task.delay(source, item) @app.task(queue="low_priority") def import_item_task(source, item_id): """resolve a row into a book""" - item = models.ImportItem.objets.get(id=item_id) + item = models.ImportItem.objects.get(id=item_id) try: item.resolve() except Exception as err: # pylint: disable=broad-except diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index b2f0284d4..05377cced 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -10,7 +10,8 @@ import responses from bookwyrm import models from bookwyrm.importers import Importer -from bookwyrm.importers.importer import import_data, handle_imported_book +from bookwyrm.importers.importer import start_import_task, import_item_task +from bookwyrm.importers.importer import handle_imported_book def make_date(*args): @@ -105,29 +106,40 @@ class GenericImporter(TestCase): ) MockTask = namedtuple("Task", ("id")) mock_task = MockTask(7) - with patch("bookwyrm.importers.importer.import_data.delay") as start: + with patch("bookwyrm.importers.importer.start_import_task.delay") as start: start.return_value = mock_task self.importer.start_import(import_job) import_job.refresh_from_db() self.assertEqual(import_job.task_id, "7") @responses.activate - def test_import_data(self, *_): + def test_start_import_task(self, *_): """resolve entry""" import_job = self.importer.create_job( self.local_user, self.csv, False, "unlisted" ) - book = models.Edition.objects.create(title="Test Book") + with patch("bookwyrm.importers.importer.import_item_task.delay") as mock: + start_import_task(self.importer.service, import_job.id) + + self.assertEqual(mock.call_count, 4) + + @responses.activate + def test_import_item_task(self, *_): + """resolve entry""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + + import_item = models.ImportItem.objects.get(job=import_job, index=0) with patch( "bookwyrm.models.import_job.ImportItem.get_book_from_isbn" ) as resolve: - resolve.return_value = book - with patch("bookwyrm.importers.importer.handle_imported_book"): - import_data(self.importer.service, import_job.id) + resolve.return_value = self.book + import_item_task(self.importer.service, import_item.id) + import_item.refresh_from_db() - import_item = models.ImportItem.objects.get(job=import_job, index=0) - self.assertEqual(import_item.book.id, book.id) + self.assertEqual(import_item.book.id, self.book.id) def test_handle_imported_book(self, *_): """import added a book, this adds related connections""" From 6aa57d4d34a441e38ccb00e435d0eb59beddca5a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 19:00:01 -0800 Subject: [PATCH 053/134] Set queue for broadcast task --- bookwyrm/models/activitypub_mixin.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index e1276d465..553b2a829 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -126,12 +126,15 @@ class ActivitypubMixin: # there OUGHT to be only one match return match.first() - def broadcast(self, activity, sender, software=None): + def broadcast(self, activity, sender, software=None, queue="medium_priority"): """send out an activity""" - broadcast_task.delay( - sender.id, - json.dumps(activity, cls=activitypub.ActivityEncoder), - self.get_recipients(software=software), + broadcast_task.apply_async( + args=( + sender.id, + json.dumps(activity, cls=activitypub.ActivityEncoder), + self.get_recipients(software=software), + ), + queue=queue, ) def get_recipients(self, software=None): @@ -374,9 +377,9 @@ class CollectionItemMixin(ActivitypubMixin): activity_serializer = activitypub.CollectionItem - def broadcast(self, activity, sender, software="bookwyrm"): + def broadcast(self, activity, sender, software="bookwyrm", queue="medium_priority"): """only send book collection updates to other bookwyrm instances""" - super().broadcast(activity, sender, software=software) + super().broadcast(activity, sender, software=software, queue=queue) @property def privacy(self): @@ -406,7 +409,7 @@ class CollectionItemMixin(ActivitypubMixin): # adding an obj to the collection activity = self.to_add_activity(self.user) - self.broadcast(activity, self.user) + self.broadcast(activity, self.user, queue="low_priority") def delete(self, *args, broadcast=True, **kwargs): """broadcast a remove activity""" From 9fee860b00899c56190c079e0f7bcb9134695295 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 19:10:22 -0800 Subject: [PATCH 054/134] Adds enum for queue names --- bookwyrm/models/activitypub_mixin.py | 27 ++++++++++++++------------- bookwyrm/tasks.py | 5 +++++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/bookwyrm/models/activitypub_mixin.py b/bookwyrm/models/activitypub_mixin.py index 553b2a829..402cb040b 100644 --- a/bookwyrm/models/activitypub_mixin.py +++ b/bookwyrm/models/activitypub_mixin.py @@ -20,7 +20,7 @@ from django.utils.http import http_date from bookwyrm import activitypub from bookwyrm.settings import USER_AGENT, PAGE_LENGTH from bookwyrm.signatures import make_signature, make_digest -from bookwyrm.tasks import app +from bookwyrm.tasks import app, MEDIUM from bookwyrm.models.fields import ImageField, ManyToManyField logger = logging.getLogger(__name__) @@ -29,7 +29,6 @@ logger = logging.getLogger(__name__) PropertyField = namedtuple("PropertyField", ("set_activity_from_field")) - # pylint: disable=invalid-name def set_activity_from_property_field(activity, obj, field): """assign a model property value to the activity json""" @@ -126,7 +125,7 @@ class ActivitypubMixin: # there OUGHT to be only one match return match.first() - def broadcast(self, activity, sender, software=None, queue="medium_priority"): + def broadcast(self, activity, sender, software=None, queue=MEDIUM): """send out an activity""" broadcast_task.apply_async( args=( @@ -198,7 +197,7 @@ class ActivitypubMixin: class ObjectMixin(ActivitypubMixin): """add this mixin for object models that are AP serializable""" - def save(self, *args, created=None, software=None, **kwargs): + def save(self, *args, created=None, software=None, priority=MEDIUM, **kwargs): """broadcast created/updated/deleted objects as appropriate""" broadcast = kwargs.get("broadcast", True) # this bonus kwarg would cause an error in the base save method @@ -225,12 +224,14 @@ class ObjectMixin(ActivitypubMixin): # do we have a "pure" activitypub version of this for mastodon? if software != "bookwyrm" and hasattr(self, "pure_content"): pure_activity = self.to_create_activity(user, pure=True) - self.broadcast(pure_activity, user, software="other") + self.broadcast( + pure_activity, user, software="other", queue=priority + ) # set bookwyrm so that that type is also sent software = "bookwyrm" # sends to BW only if we just did a pure version for masto activity = self.to_create_activity(user) - self.broadcast(activity, user, software=software) + self.broadcast(activity, user, software=software, queue=priority) except AttributeError: # janky as heck, this catches the mutliple inheritence chain # for boosts and ignores this auxilliary broadcast @@ -254,7 +255,7 @@ class ObjectMixin(ActivitypubMixin): activity = self.to_delete_activity(user) else: activity = self.to_update_activity(user) - self.broadcast(activity, user) + self.broadcast(activity, user, queue=priority) def to_create_activity(self, user, **kwargs): """returns the object wrapped in a Create activity""" @@ -377,7 +378,7 @@ class CollectionItemMixin(ActivitypubMixin): activity_serializer = activitypub.CollectionItem - def broadcast(self, activity, sender, software="bookwyrm", queue="medium_priority"): + def broadcast(self, activity, sender, software="bookwyrm", queue=MEDIUM): """only send book collection updates to other bookwyrm instances""" super().broadcast(activity, sender, software=software, queue=queue) @@ -398,7 +399,7 @@ class CollectionItemMixin(ActivitypubMixin): return [] return [collection_field.user] - def save(self, *args, broadcast=True, **kwargs): + def save(self, *args, broadcast=True, priority=MEDIUM, **kwargs): """broadcast updated""" # first off, we want to save normally no matter what super().save(*args, **kwargs) @@ -409,7 +410,7 @@ class CollectionItemMixin(ActivitypubMixin): # adding an obj to the collection activity = self.to_add_activity(self.user) - self.broadcast(activity, self.user, queue="low_priority") + self.broadcast(activity, self.user, queue=priority) def delete(self, *args, broadcast=True, **kwargs): """broadcast a remove activity""" @@ -442,12 +443,12 @@ class CollectionItemMixin(ActivitypubMixin): class ActivityMixin(ActivitypubMixin): """add this mixin for models that are AP serializable""" - def save(self, *args, broadcast=True, **kwargs): + def save(self, *args, broadcast=True, priority=MEDIUM, **kwargs): """broadcast activity""" super().save(*args, **kwargs) user = self.user if hasattr(self, "user") else self.user_subject if broadcast and user.local: - self.broadcast(self.to_activity(), user) + self.broadcast(self.to_activity(), user, queue=priority) def delete(self, *args, broadcast=True, **kwargs): """nevermind, undo that activity""" @@ -504,7 +505,7 @@ def unfurl_related_field(related_field, sort_field=None): return related_field.remote_id -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def broadcast_task(sender_id, activity, recipients): """the celery task for broadcast""" user_model = apps.get_model("bookwyrm.User", require_ready=True) diff --git a/bookwyrm/tasks.py b/bookwyrm/tasks.py index b860e0184..09e1d267e 100644 --- a/bookwyrm/tasks.py +++ b/bookwyrm/tasks.py @@ -9,3 +9,8 @@ os.environ.setdefault("DJANGO_SETTINGS_MODULE", "celerywyrm.settings") app = Celery( "tasks", broker=settings.CELERY_BROKER_URL, backend=settings.CELERY_RESULT_BACKEND ) + +# priorities +LOW = "low_priority" +MEDIUM = "medium_priority" +HIGH = "high_priority" From 3190ef4346f3a1a763bbf15ba05a69c00a138fd3 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 11 Nov 2021 19:16:36 -0800 Subject: [PATCH 055/134] Deprioritize adding old statuses to timelines --- bookwyrm/activitystreams.py | 31 +++++++++++++++++++++---------- bookwyrm/importers/importer.py | 4 ++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index 4896e07d9..a9ca17e24 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -7,7 +7,7 @@ from django.utils import timezone from bookwyrm import models from bookwyrm.redis_store import RedisStore, r -from bookwyrm.tasks import app +from bookwyrm.tasks import app, LOW, MEDIUM, HIGH class ActivityStream(RedisStore): @@ -277,7 +277,18 @@ def add_status_on_create(sender, instance, created, *args, **kwargs): def add_status_on_create_command(sender, instance, created): """runs this code only after the database commit completes""" - add_status_task.delay(instance.id, increment_unread=created) + priority=HIGH + # check if this is an old status, de-prioritize if so + # (this will happen if federation is very slow, or, more expectedly, on csv import) + one_day = 60 * 60 * 24 + if (instance.created_date - instance.published_date).seconds > one_day: + priority=LOW + + add_status_task.apply_async( + args=(instance.id,), + kwargs={"increment_unread": created}, + queue=priority, + ) if sender == models.Boost: handle_boost_task.delay(instance.id) @@ -409,7 +420,7 @@ def remove_statuses_on_unshelve(sender, instance, *args, **kwargs): # ---- TASKS -@app.task(queue="low_priority") +@app.task(queue=LOW) def add_book_statuses_task(user_id, book_id): """add statuses related to a book on shelve""" user = models.User.objects.get(id=user_id) @@ -417,7 +428,7 @@ def add_book_statuses_task(user_id, book_id): BooksStream().add_book_statuses(user, book) -@app.task(queue="low_priority") +@app.task(queue=LOW) def remove_book_statuses_task(user_id, book_id): """remove statuses about a book from a user's books feed""" user = models.User.objects.get(id=user_id) @@ -425,7 +436,7 @@ def remove_book_statuses_task(user_id, book_id): BooksStream().remove_book_statuses(user, book) -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def populate_stream_task(stream, user_id): """background task for populating an empty activitystream""" user = models.User.objects.get(id=user_id) @@ -433,7 +444,7 @@ def populate_stream_task(stream, user_id): stream.populate_streams(user) -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def remove_status_task(status_ids): """remove a status from any stream it might be in""" # this can take an id or a list of ids @@ -446,7 +457,7 @@ def remove_status_task(status_ids): stream.remove_object_from_related_stores(status) -@app.task(queue="high_priority") +@app.task(queue=HIGH) def add_status_task(status_id, increment_unread=False): """add a status to any stream it should be in""" status = models.Status.objects.get(id=status_id) @@ -458,7 +469,7 @@ def add_status_task(status_id, increment_unread=False): stream.add_status(status, increment_unread=increment_unread) -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def remove_user_statuses_task(viewer_id, user_id, stream_list=None): """remove all statuses by a user from a viewer's stream""" stream_list = [streams[s] for s in stream_list] if stream_list else streams.values() @@ -468,7 +479,7 @@ def remove_user_statuses_task(viewer_id, user_id, stream_list=None): stream.remove_user_statuses(viewer, user) -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def add_user_statuses_task(viewer_id, user_id, stream_list=None): """add all statuses by a user to a viewer's stream""" stream_list = [streams[s] for s in stream_list] if stream_list else streams.values() @@ -478,7 +489,7 @@ def add_user_statuses_task(viewer_id, user_id, stream_list=None): stream.add_user_statuses(viewer, user) -@app.task(queue="medium_priority") +@app.task(queue=MEDIUM) def handle_boost_task(boost_id): """remove the original post and other, earlier boosts""" instance = models.Status.objects.get(id=boost_id) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index d7f32c88e..3e0b0c282 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _ from bookwyrm import models from bookwyrm.models import ImportJob, ImportItem -from bookwyrm.tasks import app +from bookwyrm.tasks import app, LOW logger = logging.getLogger(__name__) @@ -201,4 +201,4 @@ def handle_imported_book(source, user, item, include_reviews, privacy): privacy=privacy, ) # only broadcast this review to other bookwyrm instances - review.save(software="bookwyrm") + review.save(software="bookwyrm", priority=LOW) From f71ef286b629c3e8744bb7d895b1a30f827ca484 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 08:55:47 -0800 Subject: [PATCH 056/134] Updates mocks --- bookwyrm/activitystreams.py | 4 ++-- bookwyrm/importers/importer.py | 4 ++-- bookwyrm/tests/importers/test_importer.py | 22 ++++++++++++------- .../importers/test_librarything_import.py | 6 ++--- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/bookwyrm/activitystreams.py b/bookwyrm/activitystreams.py index a9ca17e24..e1a52d263 100644 --- a/bookwyrm/activitystreams.py +++ b/bookwyrm/activitystreams.py @@ -277,12 +277,12 @@ def add_status_on_create(sender, instance, created, *args, **kwargs): def add_status_on_create_command(sender, instance, created): """runs this code only after the database commit completes""" - priority=HIGH + priority = HIGH # check if this is an old status, de-prioritize if so # (this will happen if federation is very slow, or, more expectedly, on csv import) one_day = 60 * 60 * 24 if (instance.created_date - instance.published_date).seconds > one_day: - priority=LOW + priority = LOW add_status_task.apply_async( args=(instance.id,), diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 3e0b0c282..b32e2df70 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -151,9 +151,9 @@ def handle_imported_book(source, user, item, include_reviews, privacy): if item.shelf and not existing_shelf: desired_shelf = models.Shelf.objects.get(identifier=item.shelf, user=user) shelved_date = item.date_added or timezone.now() - models.ShelfBook.objects.create( + models.ShelfBook( book=item.book, shelf=desired_shelf, user=user, shelved_date=shelved_date - ) + ).save(priority=LOW) for read in item.reads: # check for an existing readthrough with the same dates diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 05377cced..963eca54e 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -136,7 +136,13 @@ class GenericImporter(TestCase): "bookwyrm.models.import_job.ImportItem.get_book_from_isbn" ) as resolve: resolve.return_value = self.book - import_item_task(self.importer.service, import_item.id) + + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: + import_item_task(self.importer.service, import_item.id) + kwargs = mock.call_args.kwargs + self.assertEqual(kwargs["queue"], "low_priority") import_item.refresh_from_db() self.assertEqual(import_item.book.id, self.book.id) @@ -153,7 +159,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -163,7 +169,7 @@ class GenericImporter(TestCase): def test_handle_imported_book_already_shelved(self, *_): """import added a book, this adds related connections""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = self.local_user.shelf_set.filter(identifier="to-read").first() models.ShelfBook.objects.create( shelf=shelf, @@ -179,7 +185,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -203,7 +209,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -223,7 +229,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): with patch("bookwyrm.models.Status.broadcast") as broadcast_mock: handle_imported_book( self.importer.service, @@ -249,7 +255,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, True, "unlisted" ) @@ -267,7 +273,7 @@ class GenericImporter(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "unlisted" ) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index e93528963..55bfef728 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -9,7 +9,7 @@ import responses from bookwyrm import models from bookwyrm.importers import LibrarythingImporter -from bookwyrm.importers.importer import import_data, handle_imported_book +from bookwyrm.importers.importer import start_import_task, handle_imported_book def make_date(*args): @@ -85,7 +85,7 @@ class LibrarythingImport(TestCase): self.assertEqual(retry_items[1].data["Book Id"], "5015319") @responses.activate - def test_import_data(self, *_): + def test_start_import_task(self, *_): """resolve entry""" import_job = self.importer.create_job( self.local_user, self.csv, False, "unlisted" @@ -97,7 +97,7 @@ class LibrarythingImport(TestCase): ) as resolve: resolve.return_value = book with patch("bookwyrm.importers.importer.handle_imported_book"): - import_data(self.importer.service, import_job.id) + start_import_task(self.importer.service, import_job.id) import_item = models.ImportItem.objects.get(job=import_job, index=0) self.assertEqual(import_item.book.id, book.id) From e6a251fdad509285139c5a0484c80182c7827856 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 09:17:00 -0800 Subject: [PATCH 057/134] Updates mocks across tests --- bookwyrm/models/book.py | 5 +- .../tests/activitypub/test_base_activity.py | 8 +-- .../activitystreams/test_abstractstream.py | 2 +- .../tests/activitystreams/test_booksstream.py | 2 +- .../tests/activitystreams/test_homestream.py | 2 +- .../tests/activitystreams/test_localstream.py | 2 +- .../tests/activitystreams/test_signals.py | 2 +- bookwyrm/tests/activitystreams/test_tasks.py | 10 +-- .../tests/importers/test_goodreads_import.py | 6 +- .../importers/test_librarything_import.py | 8 +-- .../tests/importers/test_storygraph_import.py | 4 +- .../tests/management/test_populate_streams.py | 2 +- .../tests/models/test_activitypub_mixin.py | 2 +- bookwyrm/tests/models/test_group.py | 6 +- bookwyrm/tests/models/test_list.py | 10 +-- .../tests/models/test_relationship_models.py | 20 +++--- bookwyrm/tests/models/test_shelf_model.py | 30 +++++---- bookwyrm/tests/models/test_user_model.py | 4 +- bookwyrm/tests/test_postgres.py | 2 +- bookwyrm/tests/test_suggested_users.py | 6 +- bookwyrm/tests/test_templatetags.py | 14 ++-- bookwyrm/tests/views/admin/test_reports.py | 6 +- bookwyrm/tests/views/admin/test_user_admin.py | 2 +- bookwyrm/tests/views/books/test_book.py | 8 +-- bookwyrm/tests/views/books/test_edit_book.py | 8 +-- bookwyrm/tests/views/books/test_editions.py | 4 +- .../tests/views/inbox/test_inbox_announce.py | 2 +- .../tests/views/inbox/test_inbox_block.py | 2 +- .../tests/views/inbox/test_inbox_create.py | 2 +- .../tests/views/inbox/test_inbox_follow.py | 24 ++++--- bookwyrm/tests/views/inbox/test_inbox_like.py | 2 +- .../tests/views/inbox/test_inbox_remove.py | 2 +- .../tests/views/inbox/test_inbox_update.py | 4 +- .../tests/views/preferences/test_block.py | 2 +- .../views/preferences/test_delete_user.py | 10 +-- .../tests/views/preferences/test_edit_user.py | 10 +-- bookwyrm/tests/views/shelf/test_shelf.py | 8 +-- .../tests/views/shelf/test_shelf_actions.py | 28 ++++---- bookwyrm/tests/views/test_author.py | 2 +- bookwyrm/tests/views/test_discover.py | 2 +- bookwyrm/tests/views/test_feed.py | 10 +-- bookwyrm/tests/views/test_follow.py | 16 +++-- bookwyrm/tests/views/test_get_started.py | 4 +- bookwyrm/tests/views/test_goal.py | 2 +- bookwyrm/tests/views/test_group.py | 2 +- bookwyrm/tests/views/test_helpers.py | 10 +-- bookwyrm/tests/views/test_interaction.py | 8 +-- bookwyrm/tests/views/test_list.py | 32 +++++---- bookwyrm/tests/views/test_list_actions.py | 66 +++++++++++-------- bookwyrm/tests/views/test_notifications.py | 2 +- bookwyrm/tests/views/test_outbox.py | 2 +- bookwyrm/tests/views/test_reading.py | 12 ++-- bookwyrm/tests/views/test_readthrough.py | 4 +- bookwyrm/tests/views/test_rss_feed.py | 2 +- bookwyrm/tests/views/test_search.py | 2 +- bookwyrm/tests/views/test_status.py | 8 +-- bookwyrm/tests/views/test_user.py | 8 ++- 57 files changed, 253 insertions(+), 212 deletions(-) diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index 8ae75baf9..d97a1b8a6 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -66,9 +66,10 @@ class BookDataModel(ObjectMixin, BookWyrmModel): self.remote_id = None return super().save(*args, **kwargs) - def broadcast(self, activity, sender, software="bookwyrm"): + # pylint: disable=arguments-differ + def broadcast(self, activity, sender, software="bookwyrm", **kwargs): """only send book data updates to other bookwyrm instances""" - super().broadcast(activity, sender, software=software) + super().broadcast(activity, sender, software=software, **kwargs) class Book(BookDataModel): diff --git a/bookwyrm/tests/activitypub/test_base_activity.py b/bookwyrm/tests/activitypub/test_base_activity.py index 7117eb52a..b951c7ab4 100644 --- a/bookwyrm/tests/activitypub/test_base_activity.py +++ b/bookwyrm/tests/activitypub/test_base_activity.py @@ -146,7 +146,7 @@ class BaseActivity(TestCase): self.user.avatar.file # pylint: disable=pointless-statement # this would trigger a broadcast because it's a local user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): activity.to_model(model=models.User, instance=self.user) self.assertIsNotNone(self.user.avatar.file) self.assertEqual(self.user.name, "New Name") @@ -154,7 +154,7 @@ class BaseActivity(TestCase): def test_to_model_many_to_many(self, *_): """annoying that these all need special handling""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create( content="test status", user=self.user, @@ -186,7 +186,7 @@ class BaseActivity(TestCase): def test_to_model_one_to_many(self, *_): """these are reversed relationships, where the secondary object keys the primary object but not vice versa""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create( content="test status", user=self.user, @@ -224,7 +224,7 @@ class BaseActivity(TestCase): @responses.activate def test_set_related_field(self, *_): """celery task to add back-references to created objects""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create( content="test status", user=self.user, diff --git a/bookwyrm/tests/activitystreams/test_abstractstream.py b/bookwyrm/tests/activitystreams/test_abstractstream.py index f96742865..17a1b587f 100644 --- a/bookwyrm/tests/activitystreams/test_abstractstream.py +++ b/bookwyrm/tests/activitystreams/test_abstractstream.py @@ -4,7 +4,7 @@ from django.test import TestCase from bookwyrm import activitystreams, models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") diff --git a/bookwyrm/tests/activitystreams/test_booksstream.py b/bookwyrm/tests/activitystreams/test_booksstream.py index d6d94b738..347e7a942 100644 --- a/bookwyrm/tests/activitystreams/test_booksstream.py +++ b/bookwyrm/tests/activitystreams/test_booksstream.py @@ -4,7 +4,7 @@ from django.test import TestCase from bookwyrm import activitystreams, models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") diff --git a/bookwyrm/tests/activitystreams/test_homestream.py b/bookwyrm/tests/activitystreams/test_homestream.py index 42a73f3cf..d48bdfbab 100644 --- a/bookwyrm/tests/activitystreams/test_homestream.py +++ b/bookwyrm/tests/activitystreams/test_homestream.py @@ -4,7 +4,7 @@ from django.test import TestCase from bookwyrm import activitystreams, models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") diff --git a/bookwyrm/tests/activitystreams/test_localstream.py b/bookwyrm/tests/activitystreams/test_localstream.py index e6b05557f..fa1a67417 100644 --- a/bookwyrm/tests/activitystreams/test_localstream.py +++ b/bookwyrm/tests/activitystreams/test_localstream.py @@ -4,7 +4,7 @@ from django.test import TestCase from bookwyrm import activitystreams, models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py index eb70d28e4..b3a996207 100644 --- a/bookwyrm/tests/activitystreams/test_signals.py +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -4,7 +4,7 @@ from django.test import TestCase from bookwyrm import activitystreams, models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class ActivitystreamsSignals(TestCase): """using redis to build activity streams""" diff --git a/bookwyrm/tests/activitystreams/test_tasks.py b/bookwyrm/tests/activitystreams/test_tasks.py index 80b0b771d..f57507632 100644 --- a/bookwyrm/tests/activitystreams/test_tasks.py +++ b/bookwyrm/tests/activitystreams/test_tasks.py @@ -34,7 +34,7 @@ class Activitystreams(TestCase): ) work = models.Work.objects.create(title="test work") self.book = models.Edition.objects.create(title="test book", parent_work=work) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.status = models.Status.objects.create( content="hi", user=self.local_user ) @@ -133,7 +133,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_boost_to_another_timeline(self, *_): """boost from a non-follower doesn't remove original status from feed""" status = models.Status.objects.create(user=self.local_user, content="hi") @@ -155,7 +155,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_boost_to_another_timeline_remote(self, *_): """boost from a remote non-follower doesn't remove original status from feed""" status = models.Status.objects.create(user=self.local_user, content="hi") @@ -177,7 +177,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_boost_to_following_timeline(self, *_): """add a boost and deduplicate the boosted status on the timeline""" self.local_user.following.add(self.another_user) @@ -199,7 +199,7 @@ class Activitystreams(TestCase): @patch("bookwyrm.activitystreams.LocalStream.remove_object_from_related_stores") @patch("bookwyrm.activitystreams.BooksStream.remove_object_from_related_stores") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_boost_to_same_timeline(self, *_): """add a boost and deduplicate the boosted status on the timeline""" status = models.Status.objects.create(user=self.local_user, content="hi") diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index 87624a0e5..12b5578ba 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -91,7 +91,7 @@ class GoodreadsImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -115,7 +115,7 @@ class GoodreadsImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, True, "unlisted" ) @@ -135,7 +135,7 @@ class GoodreadsImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, True, "unlisted" ) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index 55bfef728..ed081aa21 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -114,7 +114,7 @@ class LibrarythingImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -129,7 +129,7 @@ class LibrarythingImport(TestCase): def test_handle_imported_book_already_shelved(self, *_): """librarything import added a book, this adds related connections""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = self.local_user.shelf_set.filter(identifier="to-read").first() models.ShelfBook.objects.create( shelf=shelf, user=self.local_user, book=self.book @@ -142,7 +142,7 @@ class LibrarythingImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -166,7 +166,7 @@ class LibrarythingImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, True, "unlisted" ) diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index 2f0fd7ef3..8002a3e10 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -95,7 +95,7 @@ class StorygraphImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, False, "public" ) @@ -116,7 +116,7 @@ class StorygraphImport(TestCase): import_item.book = self.book import_item.save() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): handle_imported_book( self.importer.service, self.local_user, import_item, True, "unlisted" ) diff --git a/bookwyrm/tests/management/test_populate_streams.py b/bookwyrm/tests/management/test_populate_streams.py index ca21b0ee8..5be1774da 100644 --- a/bookwyrm/tests/management/test_populate_streams.py +++ b/bookwyrm/tests/management/test_populate_streams.py @@ -6,7 +6,7 @@ from bookwyrm import models from bookwyrm.management.commands.populate_streams import populate_streams -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class Activitystreams(TestCase): """using redis to build activity streams""" diff --git a/bookwyrm/tests/models/test_activitypub_mixin.py b/bookwyrm/tests/models/test_activitypub_mixin.py index 911cca5cc..91a1fe7c8 100644 --- a/bookwyrm/tests/models/test_activitypub_mixin.py +++ b/bookwyrm/tests/models/test_activitypub_mixin.py @@ -21,7 +21,7 @@ from bookwyrm.settings import PAGE_LENGTH # pylint: disable=invalid-name @patch("bookwyrm.activitystreams.add_status_task.delay") -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class ActivitypubMixins(TestCase): """functionality shared across models""" diff --git a/bookwyrm/tests/models/test_group.py b/bookwyrm/tests/models/test_group.py index 33341d192..2dd3cee18 100644 --- a/bookwyrm/tests/models/test_group.py +++ b/bookwyrm/tests/models/test_group.py @@ -5,7 +5,7 @@ from django.test import TestCase from bookwyrm import models, settings -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class Group(TestCase): """some activitypub oddness ahead""" @@ -87,7 +87,7 @@ class Group(TestCase): def test_group_members_can_see_followers_only_lists(self, _): """follower-only group booklists should not be excluded from group booklist listing for group members who do not follower list owner""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): followers_list = models.List.objects.create( name="Followers List", curation="group", @@ -107,7 +107,7 @@ class Group(TestCase): def test_group_members_can_see_private_lists(self, _): """private group booklists should not be excluded from group booklist listing for group members""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): private_list = models.List.objects.create( name="Private List", diff --git a/bookwyrm/tests/models/test_list.py b/bookwyrm/tests/models/test_list.py index 0d749453e..254005bc3 100644 --- a/bookwyrm/tests/models/test_list.py +++ b/bookwyrm/tests/models/test_list.py @@ -5,7 +5,7 @@ from django.test import TestCase from bookwyrm import models, settings -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class List(TestCase): """some activitypub oddness ahead""" @@ -22,7 +22,7 @@ class List(TestCase): def test_remote_id(self, _): """shelves use custom remote ids""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): book_list = models.List.objects.create( name="Test List", user=self.local_user ) @@ -31,7 +31,7 @@ class List(TestCase): def test_to_activity(self, _): """jsonify it""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): book_list = models.List.objects.create( name="Test List", user=self.local_user ) @@ -45,7 +45,7 @@ class List(TestCase): def test_list_item(self, _): """a list entry""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): book_list = models.List.objects.create( name="Test List", user=self.local_user, privacy="unlisted" ) @@ -63,7 +63,7 @@ class List(TestCase): def test_list_item_pending(self, _): """a list entry""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): book_list = models.List.objects.create( name="Test List", user=self.local_user ) diff --git a/bookwyrm/tests/models/test_relationship_models.py b/bookwyrm/tests/models/test_relationship_models.py index 04dbe1a33..2b388398c 100644 --- a/bookwyrm/tests/models/test_relationship_models.py +++ b/bookwyrm/tests/models/test_relationship_models.py @@ -33,11 +33,13 @@ class Relationship(TestCase): def test_user_follows_from_request(self, _): """convert a follow request into a follow""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: request = models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user ) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Follow") self.assertEqual( request.remote_id, "http://local.com/user/mouse#follows/%d" % request.id @@ -54,7 +56,7 @@ class Relationship(TestCase): def test_user_follows_from_request_custom_remote_id(self, _): """store a specific remote id for a relationship provided by remote""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): request = models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user, @@ -69,19 +71,19 @@ class Relationship(TestCase): self.assertEqual(rel.user_subject, self.local_user) self.assertEqual(rel.user_object, self.remote_user) - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_follow_request_activity(self, broadcast_mock, _): """accept a request and make it a relationship""" models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user, ) - activity = json.loads(broadcast_mock.call_args[0][1]) + activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"], self.remote_user.remote_id) self.assertEqual(activity["type"], "Follow") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_follow_request_accept(self, broadcast_mock, _): """accept a request and make it a relationship""" self.local_user.manually_approves_followers = True @@ -96,7 +98,7 @@ class Relationship(TestCase): ) request.accept() - activity = json.loads(broadcast_mock.call_args[0][1]) + activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Accept") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], "https://www.hi.com/") @@ -107,7 +109,7 @@ class Relationship(TestCase): self.assertEqual(rel.user_subject, self.remote_user) self.assertEqual(rel.user_object, self.local_user) - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_follow_request_reject(self, broadcast_mock, _): """accept a request and make it a relationship""" self.local_user.manually_approves_followers = True @@ -120,7 +122,7 @@ class Relationship(TestCase): ) request.reject() - activity = json.loads(broadcast_mock.call_args[0][1]) + activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Reject") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], request.remote_id) diff --git a/bookwyrm/tests/models/test_shelf_model.py b/bookwyrm/tests/models/test_shelf_model.py index fe179e883..0683fbeff 100644 --- a/bookwyrm/tests/models/test_shelf_model.py +++ b/bookwyrm/tests/models/test_shelf_model.py @@ -27,7 +27,7 @@ class Shelf(TestCase): def test_remote_id(self, *_): """shelves use custom remote ids""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) @@ -36,7 +36,7 @@ class Shelf(TestCase): def test_to_activity(self, *_): """jsonify it""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) @@ -51,19 +51,23 @@ class Shelf(TestCase): def test_create_update_shelf(self, *_): """create and broadcast shelf creation""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Create") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["name"], "Test Shelf") shelf.name = "arthur russel" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: shelf.save() - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["name"], "arthur russel") @@ -71,27 +75,31 @@ class Shelf(TestCase): def test_shelve(self, *_): """create and broadcast shelf creation""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: shelf_book = models.ShelfBook.objects.create( shelf=shelf, user=self.local_user, book=self.book ) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], shelf_book.remote_id) self.assertEqual(activity["target"], shelf.remote_id) self.assertEqual(shelf.books.first(), self.book) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: shelf_book.delete() self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Remove") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], shelf_book.remote_id) diff --git a/bookwyrm/tests/models/test_user_model.py b/bookwyrm/tests/models/test_user_model.py index 528d3fdc4..389928cda 100644 --- a/bookwyrm/tests/models/test_user_model.py +++ b/bookwyrm/tests/models/test_user_model.py @@ -165,12 +165,12 @@ class User(TestCase): """deactivate a user""" self.assertTrue(self.user.is_active) with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as broadcast_mock: self.user.delete() self.assertEqual(broadcast_mock.call_count, 1) - activity = json.loads(broadcast_mock.call_args[0][1]) + activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["object"], self.user.remote_id) self.assertFalse(self.user.is_active) diff --git a/bookwyrm/tests/test_postgres.py b/bookwyrm/tests/test_postgres.py index 70775d47e..624512575 100644 --- a/bookwyrm/tests/test_postgres.py +++ b/bookwyrm/tests/test_postgres.py @@ -5,7 +5,7 @@ from django.test import TestCase from bookwyrm import models -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class PostgresTriggers(TestCase): """special migrations, fancy stuff ya know""" diff --git a/bookwyrm/tests/test_suggested_users.py b/bookwyrm/tests/test_suggested_users.py index f625ac10c..dce5d7704 100644 --- a/bookwyrm/tests/test_suggested_users.py +++ b/bookwyrm/tests/test_suggested_users.py @@ -9,7 +9,7 @@ from bookwyrm import models from bookwyrm.suggested_users import suggested_users, get_annotated_users -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") @patch("bookwyrm.activitystreams.populate_stream_task.delay") @@ -168,7 +168,7 @@ class SuggestedUsers(TestCase): remote_id="https://example.com/book/1", parent_work=work, ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): # 1 shared follow self.local_user.following.add(user_2) user_1.followers.add(user_2) @@ -213,7 +213,7 @@ class SuggestedUsers(TestCase): user.following.add(user_1) user.followers.add(self.local_user) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): for i in range(3): book = models.Edition.objects.create( title=i, diff --git a/bookwyrm/tests/test_templatetags.py b/bookwyrm/tests/test_templatetags.py index 5954ce271..ed4466f58 100644 --- a/bookwyrm/tests/test_templatetags.py +++ b/bookwyrm/tests/test_templatetags.py @@ -44,7 +44,7 @@ class TemplateTags(TestCase): def test_get_user_rating(self, *_): """get a user's most recent rating of a book""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.Review.objects.create(user=self.user, book=self.book, rating=3) self.assertEqual(bookwyrm_tags.get_user_rating(self.book, self.user), 3) @@ -63,7 +63,7 @@ class TemplateTags(TestCase): utilities.get_user_identifier(self.remote_user), "rat@example.com" ) - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") def test_get_replies(self, *_): """direct replies to a status""" parent = models.Review.objects.create( @@ -90,7 +90,7 @@ class TemplateTags(TestCase): def test_get_parent(self, *_): """get the reply parent of a status""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): parent = models.Review.objects.create( user=self.user, book=self.book, content="hi" ) @@ -107,7 +107,7 @@ class TemplateTags(TestCase): status = models.Review.objects.create(user=self.remote_user, book=self.book) self.assertFalse(interaction.get_user_liked(self.user, status)) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.Favorite.objects.create(user=self.user, status=status) self.assertTrue(interaction.get_user_liked(self.user, status)) @@ -116,13 +116,13 @@ class TemplateTags(TestCase): status = models.Review.objects.create(user=self.remote_user, book=self.book) self.assertFalse(interaction.get_user_boosted(self.user, status)) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.Boost.objects.create(user=self.user, boosted_status=status) self.assertTrue(interaction.get_user_boosted(self.user, status)) def test_get_boosted(self, *_): """load a boosted status""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Review.objects.create(user=self.remote_user, book=self.book) boost = models.Boost.objects.create(user=self.user, boosted_status=status) boosted = status_display.get_boosted(boost) @@ -166,7 +166,7 @@ class TemplateTags(TestCase): def test_related_status(self, *_): """gets the subclass model for a notification status""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create(content="hi", user=self.user) notification = models.Notification.objects.create( user=self.user, notification_type="MENTION", related_status=status diff --git a/bookwyrm/tests/views/admin/test_reports.py b/bookwyrm/tests/views/admin/test_reports.py index 2b063446a..8b9fe9f5d 100644 --- a/bookwyrm/tests/views/admin/test_reports.py +++ b/bookwyrm/tests/views/admin/test_reports.py @@ -151,10 +151,12 @@ class ReportViews(TestCase): request.user.is_superuser = True # de-activate - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.moderator_delete_user(request, self.rat.id) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.rat.refresh_from_db() diff --git a/bookwyrm/tests/views/admin/test_user_admin.py b/bookwyrm/tests/views/admin/test_user_admin.py index ef35c220d..486fe45e2 100644 --- a/bookwyrm/tests/views/admin/test_user_admin.py +++ b/bookwyrm/tests/views/admin/test_user_admin.py @@ -67,7 +67,7 @@ class UserAdminViews(TestCase): request.user = self.local_user request.user.is_superuser = True - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): result = view(request, self.local_user.id) self.assertIsInstance(result, TemplateResponse) diff --git a/bookwyrm/tests/views/books/test_book.py b/bookwyrm/tests/views/books/test_book.py index a078f1616..561e21928 100644 --- a/bookwyrm/tests/views/books/test_book.py +++ b/bookwyrm/tests/views/books/test_book.py @@ -78,7 +78,7 @@ class BookViews(TestCase): self.assertIsInstance(result, ActivitypubResponse) self.assertEqual(result.status_code, 200) - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") def test_book_page_statuses(self, *_): """there are so many views, this just makes sure it LOADS""" @@ -169,7 +169,7 @@ class BookViews(TestCase): request.user = self.local_user with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: views.upload_cover(request, self.book.id) self.assertEqual(delay_mock.call_count, 1) @@ -188,7 +188,7 @@ class BookViews(TestCase): request.user = self.local_user with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: views.upload_cover(request, self.book.id) self.assertEqual(delay_mock.call_count, 1) @@ -202,7 +202,7 @@ class BookViews(TestCase): request = self.factory.post("", {"description": "new description hi"}) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.add_description(request, self.book.id) self.book.refresh_from_db() diff --git a/bookwyrm/tests/views/books/test_edit_book.py b/bookwyrm/tests/views/books/test_edit_book.py index 7bf5708f8..cd9578583 100644 --- a/bookwyrm/tests/views/books/test_edit_book.py +++ b/bookwyrm/tests/views/books/test_edit_book.py @@ -79,7 +79,7 @@ class EditBookViews(TestCase): request = self.factory.post("", form.data) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, self.book.id) self.book.refresh_from_db() @@ -115,7 +115,7 @@ class EditBookViews(TestCase): request = self.factory.post("", form.data) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, self.book.id) self.book.refresh_from_db() @@ -136,7 +136,7 @@ class EditBookViews(TestCase): request = self.factory.post("", form.data) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, self.book.id) self.book.refresh_from_db() self.assertEqual(self.book.title, "New Title") @@ -207,7 +207,7 @@ class EditBookViews(TestCase): request.user = self.local_user with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: views.upload_cover(request, self.book.id) self.assertEqual(delay_mock.call_count, 1) diff --git a/bookwyrm/tests/views/books/test_editions.py b/bookwyrm/tests/views/books/test_editions.py index 2f41fe66d..17f15654d 100644 --- a/bookwyrm/tests/views/books/test_editions.py +++ b/bookwyrm/tests/views/books/test_editions.py @@ -111,7 +111,7 @@ class BookViews(TestCase): work = models.Work.objects.create(title="test work") edition1 = models.Edition.objects.create(title="first ed", parent_work=work) edition2 = models.Edition.objects.create(title="second ed", parent_work=work) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): shelf = models.Shelf.objects.create(name="Test Shelf", user=self.local_user) models.ShelfBook.objects.create( book=edition1, @@ -124,7 +124,7 @@ class BookViews(TestCase): self.assertEqual(models.ReadThrough.objects.get().book, edition1) request = self.factory.post("", {"edition": edition2.id}) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.switch_edition(request) self.assertEqual(models.ShelfBook.objects.get().book, edition2) diff --git a/bookwyrm/tests/views/inbox/test_inbox_announce.py b/bookwyrm/tests/views/inbox/test_inbox_announce.py index 3a108878c..a291552d5 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_announce.py +++ b/bookwyrm/tests/views/inbox/test_inbox_announce.py @@ -36,7 +36,7 @@ class InboxActivities(TestCase): outbox="https://example.com/users/rat/outbox", ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): with patch("bookwyrm.activitystreams.add_status_task.delay"): self.status = models.Status.objects.create( user=self.local_user, diff --git a/bookwyrm/tests/views/inbox/test_inbox_block.py b/bookwyrm/tests/views/inbox/test_inbox_block.py index ffd74dbde..f6898fc65 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_block.py +++ b/bookwyrm/tests/views/inbox/test_inbox_block.py @@ -40,7 +40,7 @@ class InboxBlock(TestCase): def test_handle_blocks(self): """create a "block" database entry from an activity""" self.local_user.followers.add(self.remote_user) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user ) diff --git a/bookwyrm/tests/views/inbox/test_inbox_create.py b/bookwyrm/tests/views/inbox/test_inbox_create.py index 76fd366ca..53b17d68a 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_create.py +++ b/bookwyrm/tests/views/inbox/test_inbox_create.py @@ -10,7 +10,7 @@ from bookwyrm.activitypub import ActivitySerializerError # pylint: disable=too-many-public-methods -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") class InboxCreate(TestCase): """readthrough tests""" diff --git a/bookwyrm/tests/views/inbox/test_inbox_follow.py b/bookwyrm/tests/views/inbox/test_inbox_follow.py index 6b629c2f0..71f101caa 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_follow.py +++ b/bookwyrm/tests/views/inbox/test_inbox_follow.py @@ -49,10 +49,12 @@ class InboxRelationships(TestCase): } self.assertFalse(models.UserFollowRequest.objects.exists()) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.inbox.activity_task(activity) self.assertEqual(mock.call_count, 1) - response_activity = json.loads(mock.call_args[0][1]) + response_activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(response_activity["type"], "Accept") # notification created @@ -77,17 +79,19 @@ class InboxRelationships(TestCase): "object": "https://example.com/user/mouse", } - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.inbox.activity_task(activity) # the follow relationship should exist follow = models.UserFollows.objects.get(user_object=self.local_user) self.assertEqual(follow.user_subject, self.remote_user) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.inbox.activity_task(activity) self.assertEqual(mock.call_count, 1) - response_activity = json.loads(mock.call_args[0][1]) + response_activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(response_activity["type"], "Accept") # the follow relationship should STILL exist @@ -109,7 +113,7 @@ class InboxRelationships(TestCase): broadcast=False, update_fields=["manually_approves_followers"] ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.inbox.activity_task(activity) # notification created @@ -132,7 +136,7 @@ class InboxRelationships(TestCase): self.local_user.save( broadcast=False, update_fields=["manually_approves_followers"] ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): request = models.UserFollowRequest.objects.create( user_subject=self.remote_user, user_object=self.local_user ) @@ -160,7 +164,7 @@ class InboxRelationships(TestCase): def test_unfollow(self): """remove a relationship""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): rel = models.UserFollows.objects.create( user_subject=self.remote_user, user_object=self.local_user ) @@ -186,7 +190,7 @@ class InboxRelationships(TestCase): @patch("bookwyrm.activitystreams.add_user_statuses_task.delay") def test_follow_accept(self, _): """a remote user approved a follow request from local""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): rel = models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user ) @@ -217,7 +221,7 @@ class InboxRelationships(TestCase): def test_follow_reject(self): """turn down a follow request""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): rel = models.UserFollowRequest.objects.create( user_subject=self.local_user, user_object=self.remote_user ) diff --git a/bookwyrm/tests/views/inbox/test_inbox_like.py b/bookwyrm/tests/views/inbox/test_inbox_like.py index db8f1fca8..2f1b6629d 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_like.py +++ b/bookwyrm/tests/views/inbox/test_inbox_like.py @@ -35,7 +35,7 @@ class InboxActivities(TestCase): outbox="https://example.com/users/rat/outbox", ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): with patch("bookwyrm.activitystreams.add_status_task.delay"): self.status = models.Status.objects.create( user=self.local_user, diff --git a/bookwyrm/tests/views/inbox/test_inbox_remove.py b/bookwyrm/tests/views/inbox/test_inbox_remove.py index cb4e4a16f..55cc81202 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_remove.py +++ b/bookwyrm/tests/views/inbox/test_inbox_remove.py @@ -75,7 +75,7 @@ class InboxRemove(TestCase): def test_handle_remove_book_from_list(self): """listing a book""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): booklist = models.List.objects.create( name="test list", user=self.local_user, diff --git a/bookwyrm/tests/views/inbox/test_inbox_update.py b/bookwyrm/tests/views/inbox/test_inbox_update.py index 0efeac0c8..248c1ad2c 100644 --- a/bookwyrm/tests/views/inbox/test_inbox_update.py +++ b/bookwyrm/tests/views/inbox/test_inbox_update.py @@ -50,7 +50,7 @@ class InboxUpdate(TestCase): def test_update_list(self): """a new list""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): book_list = models.List.objects.create( name="hi", remote_id="https://example.com/list/22", user=self.local_user ) @@ -171,7 +171,7 @@ class InboxUpdate(TestCase): book = models.Work.objects.get(id=book.id) self.assertEqual(book.title, "Piranesi") - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") def test_update_status(self, *_): """edit a status""" diff --git a/bookwyrm/tests/views/preferences/test_block.py b/bookwyrm/tests/views/preferences/test_block.py index b23a6cbc4..975142a1f 100644 --- a/bookwyrm/tests/views/preferences/test_block.py +++ b/bookwyrm/tests/views/preferences/test_block.py @@ -9,7 +9,7 @@ from bookwyrm import models, views from bookwyrm.tests.validate_html import validate_html -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class BlockViews(TestCase): """view user and edit profile""" diff --git a/bookwyrm/tests/views/preferences/test_delete_user.py b/bookwyrm/tests/views/preferences/test_delete_user.py index 09f722f70..b6d87ccde 100644 --- a/bookwyrm/tests/views/preferences/test_delete_user.py +++ b/bookwyrm/tests/views/preferences/test_delete_user.py @@ -35,9 +35,9 @@ class DeleteUserViews(TestCase): self.book = models.Edition.objects.create( title="test", parent_work=models.Work.objects.create(title="test work") ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"), patch( - "bookwyrm.activitystreams.add_book_statuses_task.delay" - ): + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ), patch("bookwyrm.activitystreams.add_book_statuses_task.delay"): models.ShelfBook.objects.create( book=self.book, user=self.local_user, @@ -70,11 +70,11 @@ class DeleteUserViews(TestCase): self.assertIsNone(self.local_user.name) with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: view(request) self.assertEqual(delay_mock.call_count, 1) - activity = json.loads(delay_mock.call_args[0][1]) + activity = json.loads(delay_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual( diff --git a/bookwyrm/tests/views/preferences/test_edit_user.py b/bookwyrm/tests/views/preferences/test_edit_user.py index b52875a9a..7a845fbe3 100644 --- a/bookwyrm/tests/views/preferences/test_edit_user.py +++ b/bookwyrm/tests/views/preferences/test_edit_user.py @@ -38,9 +38,9 @@ class EditUserViews(TestCase): self.book = models.Edition.objects.create( title="test", parent_work=models.Work.objects.create(title="test work") ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"), patch( - "bookwyrm.activitystreams.add_book_statuses_task.delay" - ): + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ), patch("bookwyrm.activitystreams.add_book_statuses_task.delay"): models.ShelfBook.objects.create( book=self.book, user=self.local_user, @@ -74,7 +74,7 @@ class EditUserViews(TestCase): self.assertIsNone(self.local_user.name) with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: view(request) self.assertEqual(delay_mock.call_count, 1) @@ -100,7 +100,7 @@ class EditUserViews(TestCase): request.user = self.local_user with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: view(request) self.assertEqual(delay_mock.call_count, 1) diff --git a/bookwyrm/tests/views/shelf/test_shelf.py b/bookwyrm/tests/views/shelf/test_shelf.py index 71df3631f..ab88de0a0 100644 --- a/bookwyrm/tests/views/shelf/test_shelf.py +++ b/bookwyrm/tests/views/shelf/test_shelf.py @@ -11,7 +11,7 @@ from bookwyrm.activitypub import ActivitypubResponse from bookwyrm.tests.validate_html import validate_html -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") @patch("bookwyrm.activitystreams.populate_stream_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @@ -39,7 +39,7 @@ class ShelfViews(TestCase): remote_id="https://example.com/book/1", parent_work=self.work, ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) @@ -142,7 +142,7 @@ class ShelfViews(TestCase): "", {"privacy": "public", "user": self.local_user.id, "name": "cool name"} ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, request.user.username, shelf.identifier) shelf.refresh_from_db() @@ -159,7 +159,7 @@ class ShelfViews(TestCase): "", {"privacy": "public", "user": self.local_user.id, "name": "cool name"} ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, request.user.username, shelf.identifier) self.assertEqual(shelf.name, "To Read") diff --git a/bookwyrm/tests/views/shelf/test_shelf_actions.py b/bookwyrm/tests/views/shelf/test_shelf_actions.py index 3efae0f45..1a7d56fdd 100644 --- a/bookwyrm/tests/views/shelf/test_shelf_actions.py +++ b/bookwyrm/tests/views/shelf/test_shelf_actions.py @@ -9,7 +9,7 @@ from django.test.client import RequestFactory from bookwyrm import forms, models, views -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") @patch("bookwyrm.activitystreams.populate_stream_task.delay") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @@ -37,7 +37,7 @@ class ShelfActionViews(TestCase): remote_id="https://example.com/book/1", parent_work=self.work, ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) @@ -49,11 +49,13 @@ class ShelfActionViews(TestCase): "", {"book": self.book.id, "shelf": self.shelf.identifier} ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.shelve(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") item = models.ShelfBook.objects.get() @@ -69,7 +71,7 @@ class ShelfActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.shelve(request) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -82,7 +84,7 @@ class ShelfActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.shelve(request) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -95,7 +97,7 @@ class ShelfActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.shelve(request) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -118,7 +120,7 @@ class ShelfActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.shelve(request) # make sure the book is on the shelf self.assertEqual(shelf.books.get(), self.book) @@ -126,7 +128,7 @@ class ShelfActionViews(TestCase): def test_unshelve(self, *_): """remove a book from a shelf""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ShelfBook.objects.create( book=self.book, user=self.local_user, shelf=self.shelf ) @@ -136,9 +138,11 @@ class ShelfActionViews(TestCase): self.assertEqual(self.shelf.books.count(), 1) request = self.factory.post("", {"book": self.book.id, "shelf": self.shelf.id}) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.unshelve(request) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Remove") self.assertEqual(activity["object"]["id"], item.remote_id) self.assertEqual(self.shelf.books.count(), 0) @@ -192,7 +196,7 @@ class ShelfActionViews(TestCase): def test_delete_shelf_has_book(self, *_): """delete a brand new custom shelf""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ShelfBook.objects.create( book=self.book, user=self.local_user, shelf=self.shelf ) diff --git a/bookwyrm/tests/views/test_author.py b/bookwyrm/tests/views/test_author.py index ccbfe5493..32b1565e3 100644 --- a/bookwyrm/tests/views/test_author.py +++ b/bookwyrm/tests/views/test_author.py @@ -111,7 +111,7 @@ class AuthorViews(TestCase): request = self.factory.post("", form.data) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, author.id) author.refresh_from_db() self.assertEqual(author.name, "New Name") diff --git a/bookwyrm/tests/views/test_discover.py b/bookwyrm/tests/views/test_discover.py index 4b8927bca..b2a82241f 100644 --- a/bookwyrm/tests/views/test_discover.py +++ b/bookwyrm/tests/views/test_discover.py @@ -41,7 +41,7 @@ class DiscoverViews(TestCase): self.assertEqual(result.status_code, 200) result.render() - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_status_task.delay") def test_discover_page(self, *_): """there are so many views, this just makes sure it LOADS""" diff --git a/bookwyrm/tests/views/test_feed.py b/bookwyrm/tests/views/test_feed.py index a6f220b58..5c6a4dd37 100644 --- a/bookwyrm/tests/views/test_feed.py +++ b/bookwyrm/tests/views/test_feed.py @@ -57,7 +57,7 @@ class FeedViews(TestCase): def test_status_page(self, *_): """there are so many views, this just makes sure it LOADS""" view = views.Status.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create(content="hi", user=self.local_user) request = self.factory.get("") request.user = self.local_user @@ -95,7 +95,7 @@ class FeedViews(TestCase): local=True, localname="rat", ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create(content="hi", user=another_user) request = self.factory.get("") @@ -115,7 +115,7 @@ class FeedViews(TestCase): image = Image.open(image_file) output = BytesIO() image.save(output, format=image.format) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Review.objects.create( content="hi", user=self.local_user, @@ -144,7 +144,7 @@ class FeedViews(TestCase): def test_replies_page(self, *_): """there are so many views, this just makes sure it LOADS""" view = views.Replies.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): status = models.Status.objects.create(content="hi", user=self.local_user) request = self.factory.get("") request.user = self.local_user @@ -171,7 +171,7 @@ class FeedViews(TestCase): result.render() self.assertEqual(result.status_code, 200) - @patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") + @patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") def test_get_suggested_book(self, *_): """gets books the ~*~ algorithm ~*~ thinks you want to post about""" diff --git a/bookwyrm/tests/views/test_follow.py b/bookwyrm/tests/views/test_follow.py index 947c55cf0..25b5a0146 100644 --- a/bookwyrm/tests/views/test_follow.py +++ b/bookwyrm/tests/views/test_follow.py @@ -59,7 +59,7 @@ class FollowViews(TestCase): request.user = self.local_user self.assertEqual(models.UserFollowRequest.objects.count(), 0) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.follow(request) rel = models.UserFollowRequest.objects.get() @@ -86,7 +86,7 @@ class FollowViews(TestCase): request.user = self.local_user self.assertEqual(models.UserFollowRequest.objects.count(), 0) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.follow(request) rel = models.UserFollowRequest.objects.get() @@ -111,7 +111,7 @@ class FollowViews(TestCase): request.user = self.local_user self.assertEqual(models.UserFollowRequest.objects.count(), 0) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.follow(request) rel = models.UserFollows.objects.get() @@ -127,10 +127,12 @@ class FollowViews(TestCase): request.user = self.local_user self.remote_user.followers.add(self.local_user) self.assertEqual(self.remote_user.followers.count(), 1) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.unfollow(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args_list[0][0][1]) + activity = json.loads(mock.call_args_list[0][1]["args"][1]) self.assertEqual(activity["type"], "Undo") self.assertEqual(self.remote_user.followers.count(), 0) @@ -147,7 +149,7 @@ class FollowViews(TestCase): user_subject=self.remote_user, user_object=self.local_user ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.accept_follow_request(request) # request should be deleted self.assertEqual(models.UserFollowRequest.objects.filter(id=rel.id).count(), 0) @@ -166,7 +168,7 @@ class FollowViews(TestCase): user_subject=self.remote_user, user_object=self.local_user ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.delete_follow_request(request) # request should be deleted self.assertEqual(models.UserFollowRequest.objects.filter(id=rel.id).count(), 0) diff --git a/bookwyrm/tests/views/test_get_started.py b/bookwyrm/tests/views/test_get_started.py index ff441b578..6d1819a4b 100644 --- a/bookwyrm/tests/views/test_get_started.py +++ b/bookwyrm/tests/views/test_get_started.py @@ -56,7 +56,7 @@ class GetStartedViews(TestCase): self.assertIsNone(self.local_user.name) with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: view(request) self.assertEqual(delay_mock.call_count, 1) @@ -98,7 +98,7 @@ class GetStartedViews(TestCase): self.assertFalse(self.local_user.shelfbook_set.exists()) with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as delay_mock: view(request) self.assertEqual(delay_mock.call_count, 1) diff --git a/bookwyrm/tests/views/test_goal.py b/bookwyrm/tests/views/test_goal.py index 557510d75..732072406 100644 --- a/bookwyrm/tests/views/test_goal.py +++ b/bookwyrm/tests/views/test_goal.py @@ -123,7 +123,7 @@ class GoalViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, self.local_user.localname, self.year) goal = models.AnnualGoal.objects.get() diff --git a/bookwyrm/tests/views/test_group.py b/bookwyrm/tests/views/test_group.py index c7e0a0f76..b18ce6b4f 100644 --- a/bookwyrm/tests/views/test_group.py +++ b/bookwyrm/tests/views/test_group.py @@ -10,7 +10,7 @@ from bookwyrm import models, views, forms from bookwyrm.tests.validate_html import validate_html -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class GroupViews(TestCase): """view group and edit details""" diff --git a/bookwyrm/tests/views/test_helpers.py b/bookwyrm/tests/views/test_helpers.py index 8f7b45a35..1aae830f6 100644 --- a/bookwyrm/tests/views/test_helpers.py +++ b/bookwyrm/tests/views/test_helpers.py @@ -55,7 +55,7 @@ class ViewsHelpers(TestCase): datafile = pathlib.Path(__file__).parent.joinpath("../data/ap_user.json") self.userdata = json.loads(datafile.read_bytes()) del self.userdata["icon"] - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.shelf = models.Shelf.objects.create( name="Test Shelf", identifier="test-shelf", user=self.local_user ) @@ -166,7 +166,7 @@ class ViewsHelpers(TestCase): def test_handle_reading_status_to_read(self, *_): """posts shelve activities""" shelf = self.local_user.shelf_set.get(identifier="to-read") - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.helpers.handle_reading_status( self.local_user, shelf, self.book, "public" ) @@ -178,7 +178,7 @@ class ViewsHelpers(TestCase): def test_handle_reading_status_reading(self, *_): """posts shelve activities""" shelf = self.local_user.shelf_set.get(identifier="reading") - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.helpers.handle_reading_status( self.local_user, shelf, self.book, "public" ) @@ -190,7 +190,7 @@ class ViewsHelpers(TestCase): def test_handle_reading_status_read(self, *_): """posts shelve activities""" shelf = self.local_user.shelf_set.get(identifier="read") - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.helpers.handle_reading_status( self.local_user, shelf, self.book, "public" ) @@ -201,7 +201,7 @@ class ViewsHelpers(TestCase): def test_handle_reading_status_other(self, *_): """posts shelve activities""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.helpers.handle_reading_status( self.local_user, self.shelf, self.book, "public" ) diff --git a/bookwyrm/tests/views/test_interaction.py b/bookwyrm/tests/views/test_interaction.py index e8b9353ed..aa402952c 100644 --- a/bookwyrm/tests/views/test_interaction.py +++ b/bookwyrm/tests/views/test_interaction.py @@ -7,7 +7,7 @@ from django.test.client import RequestFactory from bookwyrm import models, views -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.remove_status_task.delay") class InteractionViews(TestCase): """viewing and creating statuses""" @@ -74,7 +74,7 @@ class InteractionViews(TestCase): self.assertEqual(models.Favorite.objects.count(), 1) self.assertEqual(models.Notification.objects.count(), 1) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, status.id) self.assertEqual(models.Favorite.objects.count(), 0) self.assertEqual(models.Notification.objects.count(), 0) @@ -110,12 +110,12 @@ class InteractionViews(TestCase): status = models.Status.objects.create(user=self.local_user, content="hi") with patch( - "bookwyrm.models.activitypub_mixin.broadcast_task.delay" + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as broadcast_mock: view(request, status.id) self.assertEqual(broadcast_mock.call_count, 1) - activity = json.loads(broadcast_mock.call_args[0][1]) + activity = json.loads(broadcast_mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Announce") boost = models.Boost.objects.get() diff --git a/bookwyrm/tests/views/test_list.py b/bookwyrm/tests/views/test_list.py index 35befec6b..c670ad188 100644 --- a/bookwyrm/tests/views/test_list.py +++ b/bookwyrm/tests/views/test_list.py @@ -61,7 +61,7 @@ class ListViews(TestCase): parent_work=work_four, ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.list = models.List.objects.create( name="Test List", user=self.local_user ) @@ -73,7 +73,7 @@ class ListViews(TestCase): def test_lists_page(self): """there are so many views, this just makes sure it LOADS""" view = views.Lists.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.List.objects.create(name="Public list", user=self.local_user) models.List.objects.create( name="Private list", privacy="direct", user=self.local_user @@ -96,7 +96,7 @@ class ListViews(TestCase): def test_saved_lists_page(self): """there are so many views, this just makes sure it LOADS""" view = views.SavedLists.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): booklist = models.List.objects.create( name="Public list", user=self.local_user ) @@ -116,7 +116,7 @@ class ListViews(TestCase): def test_saved_lists_page_empty(self): """there are so many views, this just makes sure it LOADS""" view = views.SavedLists.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.List.objects.create(name="Public list", user=self.local_user) models.List.objects.create( name="Private list", privacy="direct", user=self.local_user @@ -153,11 +153,13 @@ class ListViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: result = view(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Create") self.assertEqual(activity["actor"], self.local_user.remote_id) @@ -172,7 +174,7 @@ class ListViews(TestCase): view = views.List.as_view() request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -191,7 +193,7 @@ class ListViews(TestCase): def test_list_page_sorted(self): """there are so many views, this just makes sure it LOADS""" view = views.List.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): for (i, book) in enumerate([self.book, self.book_two, self.book_three]): models.ListItem.objects.create( book_list=self.list, @@ -253,7 +255,7 @@ class ListViews(TestCase): def test_list_page_logged_out(self): """there are so many views, this just makes sure it LOADS""" view = views.List.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -276,7 +278,7 @@ class ListViews(TestCase): view = views.List.as_view() request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -320,11 +322,13 @@ class ListViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: result = view(request, self.list.id) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], self.list.remote_id) @@ -340,7 +344,7 @@ class ListViews(TestCase): def test_curate_page(self): """there are so many views, this just makes sure it LOADS""" view = views.Curate.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.List.objects.create(name="Public list", user=self.local_user) models.List.objects.create( name="Private list", privacy="direct", user=self.local_user @@ -360,7 +364,7 @@ class ListViews(TestCase): def test_user_lists_page(self): """there are so many views, this just makes sure it LOADS""" view = views.UserLists.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.List.objects.create(name="Public list", user=self.local_user) models.List.objects.create( name="Private list", privacy="direct", user=self.local_user diff --git a/bookwyrm/tests/views/test_list_actions.py b/bookwyrm/tests/views/test_list_actions.py index f7775d19f..1d9f46b3a 100644 --- a/bookwyrm/tests/views/test_list_actions.py +++ b/bookwyrm/tests/views/test_list_actions.py @@ -61,7 +61,7 @@ class ListActionViews(TestCase): parent_work=work_four, ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.list = models.List.objects.create( name="Test List", user=self.local_user ) @@ -71,7 +71,7 @@ class ListActionViews(TestCase): def test_delete_list(self): """delete an entire list""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -88,9 +88,11 @@ class ListActionViews(TestCase): ) request = self.factory.post("") request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.delete_list(request, self.list.id) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"]["id"], self.list.remote_id) @@ -110,7 +112,7 @@ class ListActionViews(TestCase): def test_curate_approve(self): """approve a pending item""" view = views.Curate.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): pending = models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -128,11 +130,13 @@ class ListActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: view(request, self.list.id) self.assertEqual(mock.call_count, 2) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["target"], self.list.remote_id) @@ -145,7 +149,7 @@ class ListActionViews(TestCase): def test_curate_reject(self): """approve a pending item""" view = views.Curate.as_view() - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): pending = models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -179,10 +183,12 @@ class ListActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.list.add_book(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["target"], self.list.remote_id) @@ -214,7 +220,7 @@ class ListActionViews(TestCase): }, ) request_two.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.add_book(request_one) views.list.add_book(request_two) @@ -256,7 +262,7 @@ class ListActionViews(TestCase): ) request_three.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.add_book(request_one) views.list.add_book(request_two) views.list.add_book(request_three) @@ -271,7 +277,7 @@ class ListActionViews(TestCase): remove_request = self.factory.post("", {"item": items[1].id}) remove_request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.remove_book(remove_request, self.list.id) items = self.list.listitem_set.order_by("order").all() self.assertEqual(items[0].book, self.book) @@ -293,7 +299,7 @@ class ListActionViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -330,7 +336,7 @@ class ListActionViews(TestCase): its order should be at the end of the approved books and before the remaining pending books. """ - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -370,7 +376,7 @@ class ListActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): view(request, self.list.id) items = self.list.listitem_set.order_by("order").all() @@ -422,7 +428,7 @@ class ListActionViews(TestCase): ) request_three.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.add_book(request_one) views.list.add_book(request_two) views.list.add_book(request_three) @@ -437,7 +443,7 @@ class ListActionViews(TestCase): set_position_request = self.factory.post("", {"position": 1}) set_position_request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.set_book_position(set_position_request, items[2].id) items = self.list.listitem_set.order_by("order").all() self.assertEqual(items[0].book, self.book_three) @@ -460,10 +466,12 @@ class ListActionViews(TestCase): ) request.user = self.rat - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.list.add_book(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.rat.remote_id) self.assertEqual(activity["target"], self.list.remote_id) @@ -486,11 +494,13 @@ class ListActionViews(TestCase): ) request.user = self.rat - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.list.add_book(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.rat.remote_id) @@ -516,10 +526,12 @@ class ListActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") as mock: + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ) as mock: views.list.add_book(request) self.assertEqual(mock.call_count, 1) - activity = json.loads(mock.call_args[0][1]) + activity = json.loads(mock.call_args[1]["args"][1]) self.assertEqual(activity["type"], "Add") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["target"], self.list.remote_id) @@ -532,7 +544,7 @@ class ListActionViews(TestCase): def test_remove_book(self): """take an item off a list""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): item = models.ListItem.objects.create( book_list=self.list, user=self.local_user, @@ -549,13 +561,13 @@ class ListActionViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.list.remove_book(request, self.list.id) self.assertFalse(self.list.listitem_set.exists()) def test_remove_book_unauthorized(self): """take an item off a list""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): item = models.ListItem.objects.create( book_list=self.list, user=self.local_user, book=self.book, order=1 ) diff --git a/bookwyrm/tests/views/test_notifications.py b/bookwyrm/tests/views/test_notifications.py index dd28a811b..5df62b1da 100644 --- a/bookwyrm/tests/views/test_notifications.py +++ b/bookwyrm/tests/views/test_notifications.py @@ -25,7 +25,7 @@ class NotificationViews(TestCase): local=True, localname="mouse", ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.status = models.Status.objects.create( content="hi", user=self.local_user, diff --git a/bookwyrm/tests/views/test_outbox.py b/bookwyrm/tests/views/test_outbox.py index a1f62cc61..5c5d47b08 100644 --- a/bookwyrm/tests/views/test_outbox.py +++ b/bookwyrm/tests/views/test_outbox.py @@ -11,7 +11,7 @@ from bookwyrm.settings import USER_AGENT # pylint: disable=too-many-public-methods -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class OutboxView(TestCase): """sends out activities""" diff --git a/bookwyrm/tests/views/test_reading.py b/bookwyrm/tests/views/test_reading.py index 4e5206f63..4ec50165f 100644 --- a/bookwyrm/tests/views/test_reading.py +++ b/bookwyrm/tests/views/test_reading.py @@ -64,7 +64,7 @@ class ReadingViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.ReadingStatus.as_view()(request, "start", self.book.id) self.assertEqual(shelf.books.get(), self.book) @@ -100,7 +100,7 @@ class ReadingViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.ReadingStatus.as_view()(request, "start", self.book.id) self.assertEqual(shelf.books.get(), self.book) @@ -124,7 +124,7 @@ class ReadingViews(TestCase): def test_start_reading_reshelve(self, *_): """begin a book""" to_read_shelf = self.local_user.shelf_set.get(identifier=models.Shelf.TO_READ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): models.ShelfBook.objects.create( shelf=to_read_shelf, book=self.book, user=self.local_user ) @@ -135,7 +135,7 @@ class ReadingViews(TestCase): request = self.factory.post("") request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.ReadingStatus.as_view()(request, "start", self.book.id) self.assertFalse(to_read_shelf.books.exists()) @@ -162,7 +162,7 @@ class ReadingViews(TestCase): ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.ReadingStatus.as_view()(request, "finish", self.book.id) self.assertEqual(shelf.books.get(), self.book) @@ -267,7 +267,7 @@ class ReadingViews(TestCase): }, ) request.user = self.local_user - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): views.update_progress(request, self.book.id) status = models.Comment.objects.get() diff --git a/bookwyrm/tests/views/test_readthrough.py b/bookwyrm/tests/views/test_readthrough.py index ef149ce30..5b554748f 100644 --- a/bookwyrm/tests/views/test_readthrough.py +++ b/bookwyrm/tests/views/test_readthrough.py @@ -9,7 +9,7 @@ from bookwyrm import models @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") @patch("bookwyrm.activitystreams.populate_stream_task.delay") -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.add_book_statuses_task.delay") @patch("bookwyrm.activitystreams.remove_book_statuses_task.delay") class ReadThrough(TestCase): @@ -32,7 +32,7 @@ class ReadThrough(TestCase): "cinco", "cinco@example.com", "seissiete", local=True, localname="cinco" ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): self.client.force_login(self.user) @patch("bookwyrm.activitystreams.remove_user_statuses_task.delay") diff --git a/bookwyrm/tests/views/test_rss_feed.py b/bookwyrm/tests/views/test_rss_feed.py index d4d112618..409c306dc 100644 --- a/bookwyrm/tests/views/test_rss_feed.py +++ b/bookwyrm/tests/views/test_rss_feed.py @@ -6,7 +6,7 @@ from bookwyrm import models from bookwyrm.views import rss_feed -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") @patch("bookwyrm.activitystreams.ActivityStream.get_activity_stream") @patch("bookwyrm.activitystreams.add_status_task.delay") class RssFeedView(TestCase): diff --git a/bookwyrm/tests/views/test_search.py b/bookwyrm/tests/views/test_search.py index 3299249a0..f80455113 100644 --- a/bookwyrm/tests/views/test_search.py +++ b/bookwyrm/tests/views/test_search.py @@ -139,7 +139,7 @@ class Views(TestCase): def test_search_lists(self): """searches remote connectors""" - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"): + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): booklist = models.List.objects.create( user=self.local_user, name="test list" ) diff --git a/bookwyrm/tests/views/test_status.py b/bookwyrm/tests/views/test_status.py index db61b1528..b5d7ac162 100644 --- a/bookwyrm/tests/views/test_status.py +++ b/bookwyrm/tests/views/test_status.py @@ -14,7 +14,7 @@ from bookwyrm.tests.validate_html import validate_html @patch("bookwyrm.suggested_users.rerank_suggestions_task.delay") @patch("bookwyrm.activitystreams.populate_stream_task.delay") @patch("bookwyrm.activitystreams.remove_status_task.delay") -@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay") +@patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async") class StatusViews(TestCase): """viewing and creating statuses""" @@ -310,7 +310,7 @@ http://www.fish.com/""" with patch("bookwyrm.activitystreams.remove_status_task.delay") as redis_mock: view(request, status.id) self.assertTrue(redis_mock.called) - activity = json.loads(mock.call_args_list[1][0][1]) + activity = json.loads(mock.call_args_list[1][1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["object"]["type"], "Tombstone") status.refresh_from_db() @@ -344,7 +344,7 @@ http://www.fish.com/""" with patch("bookwyrm.activitystreams.remove_status_task.delay") as redis_mock: view(request, status.id) self.assertTrue(redis_mock.called) - activity = json.loads(mock.call_args_list[1][0][1]) + activity = json.loads(mock.call_args_list[1][1]["args"][1]) self.assertEqual(activity["type"], "Delete") self.assertEqual(activity["object"]["type"], "Tombstone") status.refresh_from_db() @@ -396,7 +396,7 @@ http://www.fish.com/""" request.user = self.local_user view(request, "comment", existing_status_id=status.id) - activity = json.loads(mock.call_args_list[1][0][1]) + activity = json.loads(mock.call_args_list[1][1]["args"][1]) self.assertEqual(activity["type"], "Update") self.assertEqual(activity["object"]["id"], status.remote_id) diff --git a/bookwyrm/tests/views/test_user.py b/bookwyrm/tests/views/test_user.py index 1183fa247..ddb029cc9 100644 --- a/bookwyrm/tests/views/test_user.py +++ b/bookwyrm/tests/views/test_user.py @@ -34,9 +34,11 @@ class UserViews(TestCase): self.book = models.Edition.objects.create( title="test", parent_work=models.Work.objects.create(title="test work") ) - with patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay"), patch( - "bookwyrm.suggested_users.rerank_suggestions_task.delay" - ), patch("bookwyrm.activitystreams.add_book_statuses_task.delay"): + with patch( + "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" + ), patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.add_book_statuses_task.delay" + ): models.ShelfBook.objects.create( book=self.book, user=self.local_user, From cad5a128ac94b76e0b59763ba6e934ec1946100a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 10:19:13 -0800 Subject: [PATCH 058/134] Fixes call to add_status signal --- bookwyrm/tests/activitystreams/test_signals.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bookwyrm/tests/activitystreams/test_signals.py b/bookwyrm/tests/activitystreams/test_signals.py index b3a996207..34aeb947c 100644 --- a/bookwyrm/tests/activitystreams/test_signals.py +++ b/bookwyrm/tests/activitystreams/test_signals.py @@ -53,11 +53,12 @@ class ActivitystreamsSignals(TestCase): status = models.Status.objects.create( user=self.remote_user, content="hi", privacy="public" ) - with patch("bookwyrm.activitystreams.add_status_task.delay") as mock: + with patch("bookwyrm.activitystreams.add_status_task.apply_async") as mock: activitystreams.add_status_on_create_command(models.Status, status, False) self.assertEqual(mock.call_count, 1) - args = mock.call_args[0] - self.assertEqual(args[0], status.id) + args = mock.call_args[1] + self.assertEqual(args["args"][0], status.id) + self.assertEqual(args["queue"], "high_priority") def test_populate_streams_on_account_create(self, _): """create streams for a user""" From 309d289a6515a1da8e12874127c5ce2505979877 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 10:49:49 -0800 Subject: [PATCH 059/134] A few more mocks --- .../importers/test_librarything_import.py | 18 ------------------ bookwyrm/tests/models/test_status_model.py | 17 ++++++----------- 2 files changed, 6 insertions(+), 29 deletions(-) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index ed081aa21..1ec94bbb2 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -84,24 +84,6 @@ class LibrarythingImport(TestCase): self.assertEqual(retry_items[1].index, 1) self.assertEqual(retry_items[1].data["Book Id"], "5015319") - @responses.activate - def test_start_import_task(self, *_): - """resolve entry""" - import_job = self.importer.create_job( - self.local_user, self.csv, False, "unlisted" - ) - book = models.Edition.objects.create(title="Test Book") - - with patch( - "bookwyrm.models.import_job.ImportItem.get_book_from_isbn" - ) as resolve: - resolve.return_value = book - with patch("bookwyrm.importers.importer.handle_imported_book"): - start_import_task(self.importer.service, import_job.id) - - import_item = models.ImportItem.objects.get(job=import_job, index=0) - self.assertEqual(import_item.book.id, book.id) - def test_handle_imported_book(self, *_): """librarything import added a book, this adds related connections""" shelf = self.local_user.shelf_set.filter(identifier="read").first() diff --git a/bookwyrm/tests/models/test_status_model.py b/bookwyrm/tests/models/test_status_model.py index 7d0dd138b..822d837a7 100644 --- a/bookwyrm/tests/models/test_status_model.py +++ b/bookwyrm/tests/models/test_status_model.py @@ -362,19 +362,15 @@ class Status(TestCase): def test_favorite(self, *_): """fav a status""" - real_broadcast = models.Favorite.broadcast - - def fav_broadcast_mock(_, activity, user): - """ok""" - self.assertEqual(user.remote_id, self.local_user.remote_id) - self.assertEqual(activity["type"], "Like") - - models.Favorite.broadcast = fav_broadcast_mock - status = models.Status.objects.create( content="test content", user=self.local_user ) - fav = models.Favorite.objects.create(status=status, user=self.local_user) + + with patch("bookwyrm.models.Favorite.broadcast") as mock: + fav = models.Favorite.objects.create(status=status, user=self.local_user) + args = mock.call_args[0] + self.assertEqual(args[1].remote_id, self.local_user.remote_id) + self.assertEqual(args[0]["type"], "Like") # can't fav a status twice with self.assertRaises(IntegrityError): @@ -384,7 +380,6 @@ class Status(TestCase): self.assertEqual(activity["type"], "Like") self.assertEqual(activity["actor"], self.local_user.remote_id) self.assertEqual(activity["object"], status.remote_id) - models.Favorite.broadcast = real_broadcast def test_boost(self, *_): """boosting, this one's a bit fussy""" From 843e9a7b320b0d2613805b700ccf78728b2e4275 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 11:03:47 -0800 Subject: [PATCH 060/134] Updates existing locales --- locale/de_DE/LC_MESSAGES/django.mo | Bin 57136 -> 61566 bytes locale/de_DE/LC_MESSAGES/django.po | 923 ++++++++++++++++----------- locale/es_ES/LC_MESSAGES/django.mo | Bin 57328 -> 61028 bytes locale/es_ES/LC_MESSAGES/django.po | 657 ++++++++++++------- locale/fr_FR/LC_MESSAGES/django.mo | Bin 52510 -> 62690 bytes locale/fr_FR/LC_MESSAGES/django.po | 713 +++++++++++++-------- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 44096 -> 56859 bytes locale/zh_Hans/LC_MESSAGES/django.po | 587 +++++++++++------ locale/zh_Hant/LC_MESSAGES/django.mo | Bin 38249 -> 38249 bytes locale/zh_Hant/LC_MESSAGES/django.po | 553 ++++++++++------ 10 files changed, 2184 insertions(+), 1249 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.mo b/locale/de_DE/LC_MESSAGES/django.mo index 516685a0ec3dd82a26bd6b98ded4e934ba7e7bc8..19aa94f8fc132c768e7691d5fc774579469219ee 100644 GIT binary patch delta 24108 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 JHu?QMM*#EGHWvT@ delta 20239 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

2CKjLCv~jMzX)h{11i{2sB% zhxf=xf(u%O+{C=n)SMiJq}1Y)!%Ips(^K;%|KFp>>6DsRT2fV-mp-|BuO6e-EB?@J! zMa8Ayz=2e=sdQm{Ha|_v-%kuLkmldi^-hYaFa>(g>g2AQ98Hq(D z48h46iKRLU<%yH?&xnaDIOpf)mgZ%aR4U}9mMUZxmw;=M$%oHW^8}|BWv1rkmFDKA z7EKO38^c&MdHq=>5pV^lUaa7im{FvVnXBMfnw~oO%~>CINF`o8+5Mb>TofpuD!^I_ zx{gU{MTzODAmwhUsVS2uoU_qHRL7Zl3T634;EEPp?Wg8}OYuAfNYOl*?|hD5PG)MF z0;ncVP193w%>y+xN^?>&(@XQx6&Zr_i;5~065>rx>^HWkm9#Y6n z%_vexKfEWWBr{zPqIUBA^VQNAWo=SwIyfi6%h{4c@LDi-zAj&`g8+D9+lP}zmoBZ*H zr!*)FfNBhdd{7|)Yfvc^XXd3$4!>D8`NB;_6-atY1m!ho>xTg%6qZ_4m71BHk(XIK zS^8FqvS*%xe?e-VPi9h4Vo{|+VqS4-Mrs~Ia7kiGX)%O5dCM&|K?d~LpZwvL7$dBL z{cuZcvgPev0kBdD+N>+l1En!gKq0k7%QK5o6pHgfH4WGy&bsf$s4#is z{TNWeT2-2ppPmk?*<4D&DMBF?oKTBEK{8q4fu4bN0yKR^82F&lb(1nDowudUXxL2a^;ih zEG4O#Ig=;6(wJ=bbS0wMzvHRkodLPU_^h&wSZ4^AbVj z_vX@y;UEYH{l1m)(Z^AXUYwd8rDJq%v9V^=q)PoB7|&V$#e=1hcRiz3!sh|=ZCTz&)I9c!gU5JOoKBzH< JO}72u2mrm&PL2Qo diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index 8fd930fee..d83524666 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-15 22:03+0000\n" -"PO-Revision-Date: 2021-10-20 17:38\n" +"POT-Creation-Date: 2021-10-24 14:09+0000\n" +"PO-Revision-Date: 2021-10-26 22:29\n" "Last-Translator: Mouse Reeve \n" "Language-Team: German\n" "Language: de\n" @@ -19,7 +19,7 @@ msgstr "" #: bookwyrm/forms.py:242 msgid "A user with this email already exists." -msgstr "Es existiert bereits ein Account mit dieser E-Mail-Adresse." +msgstr "Es existiert bereits ein Benutzer*inkonto mit dieser E-Mail-Adresse." #: bookwyrm/forms.py:256 msgid "One Day" @@ -35,7 +35,7 @@ msgstr "Ein Monat" #: bookwyrm/forms.py:259 msgid "Does Not Expire" -msgstr "Läuft nicht aus" +msgstr "Läuft nicht ab" #: bookwyrm/forms.py:263 #, python-brace-format @@ -46,29 +46,29 @@ msgstr "{i}-mal verwendbar" msgid "Unlimited" msgstr "Unbegrenzt" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "Reihenfolge der Liste" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "Buchtitel" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Bewertung" -#: bookwyrm/forms.py:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Sortieren nach" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "Aufsteigend" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "Absteigend" @@ -141,15 +141,15 @@ msgstr "%(value)s ist keine gültige remote_id" #: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 #, python-format msgid "%(value)s is not a valid username" -msgstr "%(value)s ist kein gültiger Username" +msgstr "%(value)s ist kein gültiger Benutzer*inname" #: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 msgid "username" -msgstr "Username" +msgstr "Benutzer*inname" #: bookwyrm/models/fields.py:186 msgid "A user with that username already exists." -msgstr "Dieser Benutzename ist bereits vergeben." +msgstr "Dieser Benutzer*inname ist bereits vergeben." #: bookwyrm/settings.py:118 msgid "Home Timeline" @@ -161,11 +161,11 @@ msgstr "Startseite" #: bookwyrm/settings.py:119 msgid "Books Timeline" -msgstr "Bücher-Zeitachse" +msgstr "Bücher-Zeitleiste" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "Bücher" @@ -191,7 +191,7 @@ msgstr "Português (Portugiesisch)" #: bookwyrm/settings.py:170 msgid "简体中文 (Simplified Chinese)" -msgstr "简体中文 (Vereinfachtes Chinesisch)" +msgstr "简体中文 (vereinfachtes Chinesisch)" #: bookwyrm/settings.py:171 msgid "繁體中文 (Traditional Chinese)" @@ -203,7 +203,7 @@ msgstr "Nicht gefunden" #: bookwyrm/templates/404.html:9 msgid "The page you requested doesn't seem to exist!" -msgstr "Die Seite die du angefordert hast scheint nicht zu existieren!" +msgstr "Die Seite, die du angefordert hast, scheint nicht zu existieren!" #: bookwyrm/templates/500.html:4 msgid "Oops!" @@ -215,25 +215,25 @@ msgstr "Serverfehler" #: bookwyrm/templates/500.html:9 msgid "Something went wrong! Sorry about that." -msgstr "Etwas lief schief. Entschuldigung!" +msgstr "Etwas ist schief gelaufen! Tut uns leid." #: bookwyrm/templates/author/author.html:17 #: bookwyrm/templates/author/author.html:18 msgid "Edit Author" -msgstr "Autor*in editieren" +msgstr "Autor*in bearbeiten" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "Alternative Namen:" #: bookwyrm/templates/author/author.html:45 msgid "Born:" -msgstr "Geboren" +msgstr "Geboren:" #: bookwyrm/templates/author/author.html:52 msgid "Died:" -msgstr "Gestorben" +msgstr "Gestorben:" #: bookwyrm/templates/author/author.html:61 msgid "Wikipedia" @@ -242,7 +242,7 @@ msgstr "Wikipedia" #: bookwyrm/templates/author/author.html:69 #: bookwyrm/templates/book/book.html:94 msgid "View on OpenLibrary" -msgstr "In OpenLibrary ansehen" +msgstr "Auf OpenLibrary ansehen" #: bookwyrm/templates/author/author.html:77 #: bookwyrm/templates/book/book.html:97 @@ -276,71 +276,72 @@ msgstr "Hinzugefügt:" msgid "Updated:" msgstr "Aktualisiert:" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "Zuletzt bearbeitet von:" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "Metadaten" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "Name:" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "Mehrere Werte durch Kommas getrennt eingeben." -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "Über mich:" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "Wikipedialink:" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "Geburtsdatum:" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "Todesdatum:" -#: bookwyrm/templates/author/edit_author.html:79 -msgid "Author Identifiers" -msgstr "Autor*innenidentifikatoren" - #: bookwyrm/templates/author/edit_author.html:81 +msgid "Author Identifiers" +msgstr "Autor*in-Identifikatoren" + +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Openlibrary-Schlüssel:" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "Inventaire-ID:" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Librarything-Schlüssel:" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Goodreads-Schlüssel:" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +353,13 @@ msgstr "Goodreads-Schlüssel:" msgid "Save" msgstr "Speichern" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -373,12 +376,12 @@ msgstr "von" #: bookwyrm/templates/book/book.html:55 bookwyrm/templates/book/book.html:56 msgid "Edit Book" -msgstr "Buch editieren" +msgstr "Buch bearbeiten" #: bookwyrm/templates/book/book.html:73 #: bookwyrm/templates/book/cover_modal.html:5 msgid "Add cover" -msgstr "Cover hinzufügen" +msgstr "Titelbild hinzufügen" #: bookwyrm/templates/book/book.html:77 msgid "Failed to load cover" @@ -388,8 +391,8 @@ msgstr "Fehler beim Laden des Titelbilds" #, python-format msgid "(%(review_count)s review)" msgid_plural "(%(review_count)s reviews)" -msgstr[0] "(%(review_count)s Bewertung)" -msgstr[1] "(%(review_count)s Bewertungen)" +msgstr[0] "(%(review_count)s Besprechung)" +msgstr[1] "(%(review_count)s Besprechungen)" #: bookwyrm/templates/book/book.html:129 msgid "Add Description" @@ -397,7 +400,7 @@ msgstr "Beschreibung hinzufügen" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "Beschreibung:" @@ -460,7 +463,7 @@ msgstr "Orte" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "Listen" @@ -470,7 +473,7 @@ msgstr "Zur Liste hinzufügen" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -483,7 +486,7 @@ msgstr "ISBN:" #: bookwyrm/templates/book/book_identifiers.html:15 #: bookwyrm/templates/book/edit/edit_book_form.html:232 msgid "OCLC Number:" -msgstr "OCLC Nummer:" +msgstr "OCLC-Nummer:" #: bookwyrm/templates/book/book_identifiers.html:22 #: bookwyrm/templates/book/edit/edit_book_form.html:240 @@ -498,13 +501,13 @@ msgstr "Titelbild hochladen:" #: bookwyrm/templates/book/cover_modal.html:23 #: bookwyrm/templates/book/edit/edit_book_form.html:148 msgid "Load cover from url:" -msgstr "Cover von URL laden:" +msgstr "Titelbild von URL laden:" #: bookwyrm/templates/book/edit/edit_book.html:5 #: bookwyrm/templates/book/edit/edit_book.html:11 #, python-format msgid "Edit \"%(book_title)s\"" -msgstr "\"%(book_title)s \" bearbeiten" +msgstr "„%(book_title)s“ bearbeiten" #: bookwyrm/templates/book/edit/edit_book.html:5 #: bookwyrm/templates/book/edit/edit_book.html:13 @@ -518,7 +521,7 @@ msgstr "Buchinfo bestätigen" #: bookwyrm/templates/book/edit/edit_book.html:55 #, python-format msgid "Is \"%(name)s\" an existing author?" -msgstr "Existiert \"%(name)s\" bereits als Autor:in?" +msgstr "Existiert „%(name)s“ bereits als Autor*in?" #: bookwyrm/templates/book/edit/edit_book.html:64 #, python-format @@ -527,23 +530,25 @@ msgstr "Autor*in von %(book_title)s" #: bookwyrm/templates/book/edit/edit_book.html:68 msgid "This is a new author" -msgstr "Neue:r Autor:in" +msgstr "Neue*r Autor*in" #: bookwyrm/templates/book/edit/edit_book.html:75 #, python-format msgid "Creating a new author: %(name)s" -msgstr "Neu als Autor:in erstellen: %(name)s" +msgstr "Als neue*r Autor*in erstellen: %(name)s" #: bookwyrm/templates/book/edit/edit_book.html:82 msgid "Is this an edition of an existing work?" -msgstr "Ist das eine Edition eines vorhandenen Werkes?" +msgstr "Ist das eine Ausgabe eines vorhandenen Werkes?" #: bookwyrm/templates/book/edit/edit_book.html:90 msgid "This is a new work" msgstr "Dies ist ein neues Werk." #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "Bestätigen" @@ -567,7 +572,7 @@ msgstr "Serie:" #: bookwyrm/templates/book/edit/edit_book_form.html:53 msgid "Series number:" -msgstr "Seriennummer:" +msgstr "Nummer in der Serie:" #: bookwyrm/templates/book/edit/edit_book_form.html:63 msgid "Languages:" @@ -601,7 +606,7 @@ msgstr "%(name)s entfernen" #: bookwyrm/templates/book/edit/edit_book_form.html:115 #, python-format msgid "Author page for %(name)s" -msgstr "Autor*innenseite für %(name)s" +msgstr "Autor*inseite für %(name)s" #: bookwyrm/templates/book/edit/edit_book_form.html:122 msgid "Add Authors:" @@ -612,7 +617,7 @@ msgid "John Doe, Jane Smith" msgstr "Max Mustermann, Maria Musterfrau" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "Titelbild" @@ -635,7 +640,7 @@ msgstr "Seiten:" #: bookwyrm/templates/book/edit/edit_book_form.html:197 msgid "Book Identifiers" -msgstr "Buchidentifikatoren" +msgstr "Buch-Identifikatoren" #: bookwyrm/templates/book/edit/edit_book_form.html:200 msgid "ISBN 13:" @@ -652,22 +657,22 @@ msgstr "OpenLibrary-ID:" #: bookwyrm/templates/book/editions/editions.html:4 #, python-format msgid "Editions of %(book_title)s" -msgstr "Editionen von %(book_title)s" +msgstr "Ausgaben von %(book_title)s" #: bookwyrm/templates/book/editions/editions.html:8 #, python-format msgid "Editions of \"%(work_title)s\"" -msgstr "Editionen von \"%(work_title)s\"" +msgstr "Ausgaben von \"%(work_title)s\"" #: bookwyrm/templates/book/editions/format_filter.html:8 #: bookwyrm/templates/book/editions/language_filter.html:8 msgid "Any" -msgstr "Beliebig" +msgstr "Beliebig(e)" #: bookwyrm/templates/book/editions/language_filter.html:5 #: bookwyrm/templates/preferences/edit_user.html:95 msgid "Language:" -msgstr "Sprache" +msgstr "Sprache:" #: bookwyrm/templates/book/editions/search_filter.html:5 msgid "Search editions" @@ -709,23 +714,23 @@ msgstr "bewertet" #: bookwyrm/templates/book/readthrough.html:8 msgid "Progress Updates:" -msgstr "Fortschrittsupdates:" +msgstr "Zwischenstände:" #: bookwyrm/templates/book/readthrough.html:13 msgid "finished" -msgstr "Abgeschlossen" +msgstr "abgeschlossen" #: bookwyrm/templates/book/readthrough.html:24 msgid "Show all updates" -msgstr "Zeige alle Updates" +msgstr "Zeige alle Zwischenstände" #: bookwyrm/templates/book/readthrough.html:40 msgid "Delete this progress update" -msgstr "Dieses Fortschrittsupdate löschen" +msgstr "Diesen Zwischenstand löschen" #: bookwyrm/templates/book/readthrough.html:51 msgid "started" -msgstr "Angefangen" +msgstr "angefangen" #: bookwyrm/templates/book/readthrough.html:58 #: bookwyrm/templates/book/readthrough.html:72 @@ -765,11 +770,11 @@ msgstr "Bestätige deine E-Mail-Adresse" #: bookwyrm/templates/confirm_email/confirm_email.html:13 msgid "A confirmation code has been sent to the email address you used to register your account." -msgstr "Der Bestätigungscode um deinen Account zu registrieren wurde an die E-Mail-Adresse gesendet." +msgstr "Der Bestätigungscode zur Registrierung eines Benutzer*inkontos wurde an deine E-Mail-Adresse gesendet." #: bookwyrm/templates/confirm_email/confirm_email.html:15 msgid "Sorry! We couldn't find that code." -msgstr "Sorry! Dieser Code ist uns nicht bekannt." +msgstr "Tut uns leid! Dieser Code ist uns nicht bekannt." #: bookwyrm/templates/confirm_email/confirm_email.html:19 #: bookwyrm/templates/settings/users/user_info.html:85 @@ -793,11 +798,11 @@ msgstr "Bestätigungslink erneut senden" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" -msgstr "E-Mail Adresse" +msgstr "E-Mail-Adresse:" #: bookwyrm/templates/confirm_email/resend_form.html:17 msgid "Resend link" @@ -823,7 +828,7 @@ msgstr "Verzeichnis" #: bookwyrm/templates/directory/directory.html:17 msgid "Make your profile discoverable to other BookWyrm users." -msgstr "Mach dein Profil entdeckbar für andere User" +msgstr "Mach dein Profil entdeckbar für andere BookWyrm-Benutzer*innen." #: bookwyrm/templates/directory/directory.html:24 #, python-format @@ -834,7 +839,7 @@ msgstr "Du kannst dich jederzeit in deinen Profileinstellun #: bookwyrm/templates/feed/goal_card.html:17 #: bookwyrm/templates/snippets/announcement.html:34 msgid "Dismiss message" -msgstr "Nachricht verwerfen" +msgstr "Nachricht schließen" #: bookwyrm/templates/directory/sort_filter.html:5 msgid "Order by" @@ -881,11 +886,11 @@ msgstr "Benutzer*in-Typ" #: bookwyrm/templates/directory/user_type_filter.html:8 msgid "BookWyrm users" -msgstr "Bookwyrmnutzer*innen" +msgstr "Bookwyrm-Benutzer*innen" #: bookwyrm/templates/directory/user_type_filter.html:12 msgid "All known users" -msgstr "Alle bekannten Nutzer*innen" +msgstr "Alle bekannten Benutzer*innen" #: bookwyrm/templates/discover/card-header.html:9 #, python-format @@ -916,18 +921,18 @@ msgstr "Entdecken" #: bookwyrm/templates/discover/discover.html:12 #, python-format msgid "See what's new in the local %(site_name)s community" -msgstr "Schau, was in der %(site_name)s Community neu ist" +msgstr "Was gibt es Neues in der %(site_name)s-Gemeinschaft" #: bookwyrm/templates/discover/large-book.html:52 #: bookwyrm/templates/discover/small-book.html:36 msgid "View status" -msgstr "Status ansehen" +msgstr "Status anzeigen" #: bookwyrm/templates/email/confirm/html_content.html:6 #: bookwyrm/templates/email/confirm/text_content.html:4 #, python-format msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" -msgstr "Als letzten Schritt bevor du %(site_name)s beitrittst - bestätige bitte deine Emailadresse indem du den Link klickst" +msgstr "Als letzten Schritt bevor du %(site_name)s beitrittst bestätige bitte deine E-Mail-Adresse, indem du den folgenden Link klickst:" #: bookwyrm/templates/email/confirm/html_content.html:11 msgid "Confirm Email" @@ -936,7 +941,7 @@ msgstr "E-Mail-Adresse bestätigen" #: bookwyrm/templates/email/confirm/html_content.html:15 #, python-format msgid "Or enter the code \"%(confirmation_code)s\" at login." -msgstr "Oder gibt den code \"%(confirmation_code)s\" beim Login ein." +msgstr "Oder gibt den Code „%(confirmation_code)s“ bei der Anmeldung ein." #: bookwyrm/templates/email/confirm/subject.html:2 msgid "Please confirm your email" @@ -945,12 +950,12 @@ msgstr "Bitte bestätige deine E-Mail-Adresse" #: bookwyrm/templates/email/confirm/text_content.html:10 #, python-format msgid "Or enter the code \"%(confirmation_code)s\" at login." -msgstr "Oder gibt den code \"%(confirmation_code)s\" beim Login ein." +msgstr "Oder gibt den Code „%(confirmation_code)s“ bei der Anmeldung ein." #: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/text_layout.html:2 msgid "Hi there," -msgstr "Moin," +msgstr "Hallo," #: bookwyrm/templates/email/html_layout.html:21 #, python-format @@ -959,7 +964,7 @@ msgstr "BookWyrm wird auf über %(site_n #: bookwyrm/templates/email/invite/text_content.html:4 #, python-format msgid "You're invited to join %(site_name)s! Click the link below to create an account." -msgstr "Du bist eingeladen, %(site_name)s beizutreten! Klicke auf den Link unten um einen Account zu erstellen." +msgstr "Du bist eingeladen, %(site_name)s beizutreten! Klicke auf den Link unten, um ein Benutzer*inkonto zu erstellen." #: bookwyrm/templates/email/invite/text_content.html:8 #, python-format @@ -990,15 +995,15 @@ msgstr "Erfahre mehr über %(site_name)s:" #: bookwyrm/templates/email/password_reset/text_content.html:4 #, python-format msgid "You requested to reset your %(site_name)s password. Click the link below to set a new password and log in to your account." -msgstr "Du hast beantragt, dein %(site_name)s Passwort zu ändern. Klicke auf den Link unten, um ein neues Passwort zu erstellen und dich einzuloggen." +msgstr "Du hast beantragt, dein %(site_name)s-Passwort zu ändern. Klicke auf den Link unten, um ein neues Passwort zu erstellen und dich anzumelden." #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" -msgstr "Passwort zurücksetzen!" +msgstr "Passwort zurücksetzen" #: bookwyrm/templates/email/password_reset/html_content.html:13 #: bookwyrm/templates/email/password_reset/text_content.html:8 @@ -1008,7 +1013,7 @@ msgstr "Falls du dein Passwort gar nicht zurücksetzen wolltest, kannst du diese #: bookwyrm/templates/email/password_reset/subject.html:2 #, python-format msgid "Reset your %(site_name)s password" -msgstr "Dein Passwort für %(site_name)s zurücksetzen" +msgstr "Passwort für %(site_name)s zurücksetzen" #: bookwyrm/templates/feed/direct_messages.html:8 #, python-format @@ -1031,23 +1036,23 @@ msgstr "Du hast momentan keine Nachrichten." #: bookwyrm/templates/feed/feed.html:22 #, python-format msgid "load 0 unread status(es)" -msgstr "lese 0 ungelesene Status" +msgstr "lade 0 ungelesene Statusmeldung(en)" #: bookwyrm/templates/feed/feed.html:38 msgid "There aren't any activities right now! Try following a user to get started" -msgstr "Hier sind noch keine Aktivitäten! Folge anderen, um loszulegen" +msgstr "Hier sind noch keine Aktivitäten! Folge Anderen, um loszulegen" #: bookwyrm/templates/feed/goal_card.html:6 #: bookwyrm/templates/feed/layout.html:90 #: bookwyrm/templates/user/goal_form.html:6 #, python-format msgid "%(year)s Reading Goal" -msgstr "%(year)s Leseziel" +msgstr "Leseziel für %(year)s" #: bookwyrm/templates/feed/goal_card.html:18 #, python-format msgid "You can set or change your reading goal any time from your profile page" -msgstr "Du kannst dein Leseziel jederzeit auf deiner Profilseite setzen oder ändern." +msgstr "Du kannst dein Leseziel jederzeit auf deiner Profilseite festlegen oder ändern" #: bookwyrm/templates/feed/layout.html:5 msgid "Updates" @@ -1060,7 +1065,7 @@ msgstr "Deine Bücher" #: bookwyrm/templates/feed/layout.html:14 msgid "There are no books here right now! Try searching for a book to get started" -msgstr "Hier sind noch keine Bücher! Versuche nach Büchern zu suchen um loszulegen" +msgstr "Hier sind noch keine Bücher! Versuche, nach Büchern zu suchen, um loszulegen" #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 @@ -1086,11 +1091,11 @@ msgstr "Wem noch folgen?" #: bookwyrm/templates/feed/suggested_users.html:9 msgid "Don't show suggested users" -msgstr "Keine vorgeschlagenen User anzeigen" +msgstr "Keine vorgeschlagenen Benutzer*innen anzeigen" #: bookwyrm/templates/feed/suggested_users.html:14 msgid "View directory" -msgstr "Zeige Verzeichnis" +msgstr "Verzeichnis anzeigen" #: bookwyrm/templates/get_started/book_preview.html:6 #, python-format @@ -1102,14 +1107,14 @@ msgid "What are you reading?" msgstr "Was liest du gerade?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "Nach einem Buch suchen" #: bookwyrm/templates/get_started/books.html:11 #, python-format msgid "No books found for \"%(query)s\"" -msgstr "Keine Bücher für \"%(query)s\" gefunden" +msgstr "Keine Bücher für „%(query)s“ gefunden" #: bookwyrm/templates/get_started/books.html:11 #, python-format @@ -1120,8 +1125,9 @@ msgstr "Du kannst Bücher hinzufügen, wenn du %(site_name)s benutzt." #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1137,7 +1143,7 @@ msgid "Popular on %(site_name)s" msgstr "Auf %(site_name)s beliebt" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "Keine Bücher gefunden" @@ -1184,16 +1190,16 @@ msgstr "Fertigstellen" #: bookwyrm/templates/get_started/profile.html:15 #: bookwyrm/templates/preferences/edit_user.html:42 msgid "Display name:" -msgstr "Displayname:" +msgstr "Anzeigename:" #: bookwyrm/templates/get_started/profile.html:22 #: bookwyrm/templates/preferences/edit_user.html:49 msgid "Summary:" -msgstr "Bio:" +msgstr "Zusammenfassung:" #: bookwyrm/templates/get_started/profile.html:23 msgid "A little bit about you" -msgstr "Etwas über dich" +msgstr "Einige Angaben zu dir" #: bookwyrm/templates/get_started/profile.html:32 #: bookwyrm/templates/preferences/edit_user.html:27 @@ -1203,16 +1209,16 @@ msgstr "Avatar:" #: bookwyrm/templates/get_started/profile.html:42 #: bookwyrm/templates/preferences/edit_user.html:110 msgid "Manually approve followers:" -msgstr "Folgende manuell bestätigen" +msgstr "Follower*innen manuell bestätigen:" #: bookwyrm/templates/get_started/profile.html:48 #: bookwyrm/templates/preferences/edit_user.html:80 msgid "Show this account in suggested users:" -msgstr "Diesen Account in vorgeschlagenen Usern zeigen" +msgstr "Dieses Benutzer*inkonto in vorgeschlagene Benutzer*innen einschließen:" #: bookwyrm/templates/get_started/profile.html:52 msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." -msgstr "Dein Account wird im Verzeichnis gezeigt und möglicherweise anderen Usern vorgeschlagen." +msgstr "Dein Benutzer*inkonto wird im Verzeichnis gezeigt und möglicherweise anderen Benutzer*innen vorgeschlagen." #: bookwyrm/templates/get_started/users.html:11 msgid "Search for a user" @@ -1221,11 +1227,112 @@ msgstr "Benutzer*in suchen" #: bookwyrm/templates/get_started/users.html:13 #, python-format msgid "No users found for \"%(query)s\"" -msgstr "Keine Nutzer*innen für \"%(query)s\" gefunden" +msgstr "Keine Benutzer*innen für „%(query)s“ gefunden" + +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Gruppe erstellen" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Administriert von %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "Diese Gruppe löschen?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Diese Aktion kann nicht rückgängig gemacht werden" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Löschen" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Gruppe bearbeiten" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "Mitglieder hinzufügen!" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Gruppenname:" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Gruppenbeschreibung:" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Gruppe löschen" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Hinzuzufügende*n Benutzer*in suchen" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Diese Gruppe enthält keine Listen" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Gruppe bearbeiten" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Mitglieder können Bücher in den Buchlisten einer Gruppe hinzufügen und entfernen" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Gruppe verlassen" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Folgt dir" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s Follower*in, der*die du folgst" +msgstr[1] "%(mutuals)s Follower*innen, denen du folgst" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s Buch in deinen Regalen" +msgstr[1] "%(shared_books)s Bücher in deinen Regalen" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "Keine potentiellen Mitglieder für „%(user_query)s“ gefunden" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Gruppenadministrator*in" #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "Bücher importieren" @@ -1239,11 +1346,11 @@ msgstr "Datei:" #: bookwyrm/templates/import/import.html:45 msgid "Include reviews" -msgstr "Bewertungen importieren" +msgstr "Besprechungen einschließen" #: bookwyrm/templates/import/import.html:50 msgid "Privacy setting for imported reviews:" -msgstr "Datenschutzeinstellung für importierte Bewertungen" +msgstr "Datenschutzeinstellung für importierte Besprechungen:" #: bookwyrm/templates/import/import.html:56 #: bookwyrm/templates/settings/federation/instance_blocklist.html:64 @@ -1252,7 +1359,7 @@ msgstr "Importieren" #: bookwyrm/templates/import/import.html:61 msgid "Recent Imports" -msgstr "Aktuelle Importe" +msgstr "Zuletzt importiert" #: bookwyrm/templates/import/import.html:63 msgid "No recent imports" @@ -1265,7 +1372,7 @@ msgstr "Importstatus" #: bookwyrm/templates/import/import_status.html:11 msgid "Back to imports" -msgstr "Zurück zu Importen" +msgstr "Zurück zu den Importen" #: bookwyrm/templates/import/import_status.html:15 msgid "Import started:" @@ -1277,7 +1384,7 @@ msgstr "Import abgeschlossen:" #: bookwyrm/templates/import/import_status.html:24 msgid "TASK FAILED" -msgstr "AUFGABE GESCHEITERT" +msgstr "IMPORTSCHRITT-FEHLER" #: bookwyrm/templates/import/import_status.html:32 msgid "Import still in progress." @@ -1285,7 +1392,7 @@ msgstr "Import läuft noch." #: bookwyrm/templates/import/import_status.html:34 msgid "(Hit reload to update!)" -msgstr "(Aktualisiere für ein Update!)" +msgstr "(Zur Aktualisierung „Neu laden” wählen)" #: bookwyrm/templates/import/import_status.html:41 msgid "Failed to load" @@ -1294,7 +1401,7 @@ msgstr "Laden fehlgeschlagen" #: bookwyrm/templates/import/import_status.html:50 #, python-format msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "Zum Ende der Liste springen, um die %(failed_count)s Einträge, deren Import fehlschlug, auszuwählen." +msgstr "Zum Ende der Liste springen, um die %(failed_count)s Einträge, die nicht importiert werden konnten, auszuwählen." #: bookwyrm/templates/import/import_status.html:62 #, python-format @@ -1303,11 +1410,11 @@ msgstr "Zeile %(index)s: %(title)s von %(author)s" #: bookwyrm/templates/import/import_status.html:82 msgid "Select all" -msgstr "Alle auswählen" +msgstr "Alle(s) auswählen" #: bookwyrm/templates/import/import_status.html:85 msgid "Retry items" -msgstr "Punkte erneut versuchen" +msgstr "Erneut versuchen" #: bookwyrm/templates/import/import_status.html:112 msgid "Successfully imported" @@ -1322,14 +1429,14 @@ msgid "Book" msgstr "Buch" #: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titel" #: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor*in" @@ -1341,19 +1448,6 @@ msgstr "Importiert" msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Du kannst deine Goodreads-Daten von der Import/Export-Seite deines Goodreads-Kontos downloaden." -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "Erstelle einen Account" - -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "Zugiff verweigert" - -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "Sorry! Dieser Einladecode ist mehr gültig." - #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1369,9 +1463,23 @@ msgstr "Verhaltenskodex" msgid "Privacy Policy" msgstr "Datenschutzerklärung" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Erstelle ein Benutzer*inkonto" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Zugiff verweigert" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "Tut uns leid! Dieser Einladungscode ist mehr gültig." + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" -msgstr "Aktive Bücher" +msgstr "Zuletzt aktive Bücher" #: bookwyrm/templates/landing/layout.html:17 msgid "Decentralized" @@ -1388,7 +1496,7 @@ msgstr "Nichtkommerziell" #: bookwyrm/templates/landing/layout.html:45 #, python-format msgid "Join %(name)s" -msgstr "Tritt %(name)s bei" +msgstr "%(name)s beitreten" #: bookwyrm/templates/landing/layout.html:47 msgid "Request an Invitation" @@ -1405,7 +1513,54 @@ msgstr "Danke! Deine Anfrage ist eingegangen." #: bookwyrm/templates/landing/layout.html:82 msgid "Your Account" -msgstr "Dein Account" +msgstr "Dein Benutzer*inkonto" + +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Anmeldung" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Anmelden" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "Alles klar! E-Mail-Adresse bestätigt." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Benutzer*inname:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Passwort:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "Passwort vergessen?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "Mehr über diese Seite" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Passwort bestätigen:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Ein Link zum Zurücksetzen deines Passworts wird an deine E-Mail-Adresse geschickt" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Passwort zurücksetzen" #: bookwyrm/templates/layout.html:13 #, python-format @@ -1418,7 +1573,7 @@ msgstr "Nach einem Buch, einem*r Benutzer*in oder einer Liste suchen" #: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62 msgid "Main navigation menu" -msgstr "Navigationshauptmenü" +msgstr "Navigations-Hauptmenü" #: bookwyrm/templates/layout.html:72 msgid "Feed" @@ -1454,25 +1609,10 @@ msgstr "Abmelden" msgid "Notifications" msgstr "Benachrichtigungen" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "Benutzer*inname:" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "Passwort" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "Passwort vergessen?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "Anmelden" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "Beitreten" @@ -1487,7 +1627,7 @@ msgstr "Fehler beim veröffentlichen des Status" #: bookwyrm/templates/layout.html:234 msgid "Contact site admin" -msgstr "Admin kontaktieren" +msgstr "Administrator*in kontaktieren" #: bookwyrm/templates/layout.html:238 msgid "Documentation" @@ -1513,10 +1653,15 @@ msgstr "Liste erstellen" #: bookwyrm/templates/lists/created_text.html:5 #, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Erstellt von %(username)s und administriert von %(groupname)s" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format msgid "Created and curated by %(username)s" msgstr "Erstellt und betreut von %(username)s" -#: bookwyrm/templates/lists/created_text.html:7 +#: bookwyrm/templates/lists/created_text.html:9 #, python-format msgid "Created by %(username)s" msgstr "Erstellt von %(username)s" @@ -1549,118 +1694,130 @@ msgstr "Ablehnen" msgid "Delete this list?" msgstr "Diese Liste löschen?" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "Diese Aktion kann nicht rückgängig gemacht werden" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Löschen" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Liste bearbeiten" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" msgstr "Listenkuratierung:" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "Geschlossen" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" msgstr "Nur du kannst Bücher hinzufügen oder entfernen" -#: bookwyrm/templates/lists/form.html:26 +#: bookwyrm/templates/lists/form.html:27 msgid "Curated" msgstr "Kuratiert" -#: bookwyrm/templates/lists/form.html:27 +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" -msgstr "Alle können Bücher vorschlagen, du kannst diese bestätigen" +msgstr "Jede*r kann Bücher vorschlagen, du musst diese bestätigen" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "Offen" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" -msgstr "Alle können Bücher hinzufügen" +msgstr "Jede*r kann Bücher hinzufügen" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Gruppe" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "Gruppenmitglieder können Bücher zu dieser Liste hinzufügen und von dieser entfernen" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Gruppe auswählen" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Eine Gruppe auswählen" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "Du hast noch keine Gruppen!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Gruppe erstellen" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "Liste löschen" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" -msgstr "Du hast erfolgreich ein Buch für diese Liste vorgeschlagen!" +msgstr "Dein Buchvorschlag wurde dieser Liste hinzugefügt!" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" -msgstr "Du hast erfolgreich ein Buch zu dieser Liste hinzugefügt!" +msgstr "Du hast ein Buch zu dieser Liste hinzugefügt!" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "Diese Liste ist momentan leer" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "Hinzugefügt von %(username)s" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "Listenposition" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "Übernehmen" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "Entfernen" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "Liste sortieren" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" msgstr "Reihenfolge" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "Bücher hinzufügen" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "Bücher vorschlagen" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "suchen" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" -msgstr "Suche leeren" +msgstr "Suche zurücksetzen" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" -msgstr "Keine passenden Bücher zu \"%(query)s\" gefunden" +msgstr "Keine passenden Bücher zu „%(query)s“ gefunden" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "Vorschlagen" @@ -1672,35 +1829,23 @@ msgstr "Gespeichert" msgid "Your Lists" msgstr "Deine Listen" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "Alle Listen" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "Gespeicherte Listen" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "Anmeldung" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." -msgstr "Alles klar! E-Mai- Adresse bestätigt." - -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "Passwort:" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "Mehr über diese Seite" +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "hat deine Einladung angenommen, der Gruppe „%(group_name)s“ beizutreten" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format msgid "added %(book_title)s to your list \"%(list_name)s\"" -msgstr "%(book_title)s zu deiner Liste \"%(list_name)s\" hinzugefügt" +msgstr "%(book_title)s zu deiner Liste „%(list_name)s“ hinzugefügt" #: bookwyrm/templates/notifications/items/add.html:31 #, python-format @@ -1710,7 +1855,7 @@ msgstr "hat vorgeschlagen, %(book_title)s #: bookwyrm/templates/notifications/items/boost.html:19 #, python-format msgid "boosted your review of %(book_title)s" -msgstr "hat deine Bewertung von %(book_title)s geteilt" +msgstr "hat deine Besprechung von %(book_title)s geteilt" #: bookwyrm/templates/notifications/items/boost.html:25 #, python-format @@ -1730,11 +1875,11 @@ msgstr "hat deinen Status geteilt" #: bookwyrm/templates/notifications/items/fav.html:19 #, python-format msgid "liked your review of %(book_title)s" -msgstr "hat deine Besprechung von %(book_title)s favorisiert" +msgstr "hat deine Besprechung von %(book_title)s favorisiert" #: bookwyrm/templates/notifications/items/fav.html:25 #, python-format -msgid "liked your comment on%(book_title)s" +msgid "liked your comment on %(book_title)s" msgstr "hat deinen Kommentar zu %(book_title)s favorisiert" #: bookwyrm/templates/notifications/items/fav.html:31 @@ -1753,17 +1898,32 @@ msgstr "folgt dir" #: bookwyrm/templates/notifications/items/follow_request.html:11 msgid "sent you a follow request" -msgstr "hat dir eine Folgeanfrage geschickt" +msgstr "möchte dir folgen" #: bookwyrm/templates/notifications/items/import.html:14 #, python-format msgid "Your import completed." msgstr "Dein Import ist fertig." +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "hat dich eingeladen, der Gruppe „%(group_name)s“ beizutreten" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "ist deiner Gruppe „%(group_name)s“ beigetreten" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "hat deine Gruppe „%(group_name)s“ verlassen" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" -msgstr "hat dich in einer Bewertung von %(book_title)s erwähnt" +msgstr "hat dich in einer Besprechung von %(book_title)s erwähnt" #: bookwyrm/templates/notifications/items/mention.html:26 #, python-format @@ -1780,10 +1940,20 @@ msgstr "hat dich in einem Zitat von %(book_titl msgid "mentioned you in a status" msgstr "hat dich in einem Status erwähnt" +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "wurde aus deiner Gruppe „%(group_name)s“ entfernt" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "Du wurdest aus der Gruppe „%(group_name)s“ entfernt" + #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" -msgstr "hat auf deine Bewertung von %(book_title)s geantwortet " +msgstr "hat auf deine Besprechung von %(book_title)s geantwortet" #: bookwyrm/templates/notifications/items/reply.html:27 #, python-format @@ -1805,6 +1975,21 @@ msgstr "hat auf deinen Status report needs moderation." msgstr "Eine neue Meldung muss moderiert werden." +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "hat die Sichtbarkeit von %(group_name)s geändert" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "hat den Namen von %(group_name)s geändert" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "hat die Beschreibung von %(group_name)s geändert" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" msgstr "Benachrichtigungen löschen" @@ -1821,29 +2006,15 @@ msgstr "Erwähnungen" msgid "You're all caught up!" msgstr "Du bist auf dem neusten Stand!" -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "Passwort bestätigen:" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "Ein Link zum Zurücksetzen deines Passworts wird an deine Mailadresse geschickt" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "Passwort zurücksetzen" - #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 #: bookwyrm/templates/preferences/layout.html:31 msgid "Blocked Users" -msgstr "Blockierte Nutzer*innen" +msgstr "Gesperrte Benutzer*innen" #: bookwyrm/templates/preferences/blocks.html:12 msgid "No users currently blocked." -msgstr "Momentan keine Nutzer*innen blockiert." +msgstr "Momentan keine Benutzer*innen gesperrt." #: bookwyrm/templates/preferences/change_password.html:4 #: bookwyrm/templates/preferences/change_password.html:7 @@ -1866,11 +2037,11 @@ msgstr "Benutzer*inkonto löschen" #: bookwyrm/templates/preferences/delete_user.html:12 msgid "Permanently delete account" -msgstr "Account permanent löschen" +msgstr "Benutzer*inkonto dauerhaft löschen" #: bookwyrm/templates/preferences/delete_user.html:14 msgid "Deleting your account cannot be undone. The username will not be available to register in the future." -msgstr "Das Löschen des Accounts kann nicht rückgängig gemacht werden. Der Username kann nicht erneut registriert werden." +msgstr "Das Löschen des Benutzer*inkonto kann nicht rückgängig gemacht werden. Der Benutzer*inname kann nicht erneut registriert werden." #: bookwyrm/templates/preferences/edit_user.html:4 #: bookwyrm/templates/preferences/edit_user.html:7 @@ -1896,7 +2067,7 @@ msgstr "Privatsphäre" #: bookwyrm/templates/preferences/edit_user.html:72 msgid "Show reading goal prompt in feed:" -msgstr "Zeige Leseziel-Abfrage im Feed:" +msgstr "Frage Leseziel im Feed ab:" #: bookwyrm/templates/preferences/edit_user.html:76 msgid "Show suggested users:" @@ -1905,7 +2076,7 @@ msgstr "Zeige vorgeschlagene Benutzer*innen:" #: bookwyrm/templates/preferences/edit_user.html:85 #, python-format msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." -msgstr "Dein Account wird im directory angezeigt und eventuell anderen Usern empfohlen." +msgstr "Dein Benutzer*inkonto wird im Verzeichnis angezeigt und eventuell anderen Benutzer*innen empfohlen." #: bookwyrm/templates/preferences/edit_user.html:89 msgid "Preferred Timezone: " @@ -1926,17 +2097,17 @@ msgstr "Beziehungen" #: bookwyrm/templates/reading_progress/finish.html:5 #, python-format msgid "Finish \"%(book_title)s\"" -msgstr "\"%(book_title)s\" abschließen" +msgstr "„%(book_title)s“ abschließen" #: bookwyrm/templates/reading_progress/start.html:5 #, python-format msgid "Start \"%(book_title)s\"" -msgstr "\"%(book_title)s\" beginnen" +msgstr "„%(book_title)s“ beginnen" #: bookwyrm/templates/reading_progress/want.html:5 #, python-format msgid "Want to Read \"%(book_title)s\"" -msgstr "\"%(book_title)s\" auf Leseliste setzen" +msgstr "„%(book_title)s“ auf Leseliste setzen" #: bookwyrm/templates/search/book.html:47 #: bookwyrm/templates/settings/reports/reports.html:25 @@ -1958,7 +2129,7 @@ msgstr "Buch manuell hinzufügen" #: bookwyrm/templates/search/book.html:116 msgid "Log in to import or add books." -msgstr "Log dich ein, um Bücher zu importieren oder hinzuzufügen." +msgstr "Melde dich an, um Bücher zu importieren oder hinzuzufügen." #: bookwyrm/templates/search/layout.html:16 msgid "Search query" @@ -2000,7 +2171,7 @@ msgstr "Ankündigung bearbeiten" #: bookwyrm/templates/settings/announcements/announcement.html:35 msgid "Visible:" -msgstr "Sichtbar" +msgstr "Sichtbar:" #: bookwyrm/templates/settings/announcements/announcement.html:38 msgid "True" @@ -2184,7 +2355,7 @@ msgstr "E-Mail-Sperrliste" #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:18 msgid "When someone tries to register with an email from this domain, no account will be created. The registration process will appear to have worked." -msgstr "Wenn sich jemand mit einer E-Mail-Adresse von dieser Domain zu registrieren versucht, wird kein Account erstellt. Die Registrierung wird so aussehen als hätte sie funktioniert." +msgstr "Wenn sich jemand mit einer E-Mail-Adresse von dieser Domain zu registrieren versucht, wird kein Benutzer*inkonto erstellt. Es wird aber so aussehen, als ob die Registrierung funktioniert hätte." #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:25 msgid "Domain" @@ -2257,7 +2428,7 @@ msgid "Details" msgstr "Details" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "Aktivität" @@ -2268,7 +2439,7 @@ msgstr "Benutzer*innen:" #: bookwyrm/templates/settings/federation/instance.html:41 #: bookwyrm/templates/settings/federation/instance.html:47 msgid "View all" -msgstr "Alle anzeigen" +msgstr "Alle(s) anzeigen" #: bookwyrm/templates/settings/federation/instance.html:44 #: bookwyrm/templates/settings/users/user_info.html:56 @@ -2281,7 +2452,7 @@ msgstr "Folgen wir:" #: bookwyrm/templates/settings/federation/instance.html:55 msgid "Followed by them:" -msgstr "Folgen:" +msgstr "Folgen uns:" #: bookwyrm/templates/settings/federation/instance.html:60 msgid "Blocked by us:" @@ -2331,7 +2502,7 @@ msgstr "Sperrliste importieren" #: bookwyrm/templates/settings/federation/instance_blocklist.html:26 #: bookwyrm/templates/snippets/goal_progress.html:7 msgid "Success!" -msgstr "Erfolg!" +msgstr "Hat funktioniert!" #: bookwyrm/templates/settings/federation/instance_blocklist.html:30 msgid "Successfully blocked:" @@ -2339,7 +2510,7 @@ msgstr "Erfolgreich gesperrt:" #: bookwyrm/templates/settings/federation/instance_blocklist.html:32 msgid "Failed:" -msgstr "Fehlgeschlagen" +msgstr "Fehlgeschlagen:" #: bookwyrm/templates/settings/federation/instance_list.html:3 #: bookwyrm/templates/settings/federation/instance_list.html:5 @@ -2420,11 +2591,11 @@ msgstr "Ignorieren" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:97 msgid "Un-ignore" -msgstr "Un-ignorieren" +msgstr "Doch nicht ignorieren" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:108 msgid "Back to pending requests" -msgstr "Zurück zu ausstehenden Anfragen" +msgstr "Zurück zu den ausstehenden Anfragen" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:110 msgid "View ignored requests" @@ -2436,11 +2607,11 @@ msgstr "Neue Einladung erzeugen" #: bookwyrm/templates/settings/invites/manage_invites.html:27 msgid "Expiry:" -msgstr "Ablaufen:" +msgstr "Ablaufdatum:" #: bookwyrm/templates/settings/invites/manage_invites.html:33 msgid "Use limit:" -msgstr "Begrenzte Benutzung" +msgstr "Verwendungslimit:" #: bookwyrm/templates/settings/invites/manage_invites.html:40 msgid "Create Invite" @@ -2452,15 +2623,15 @@ msgstr "Link" #: bookwyrm/templates/settings/invites/manage_invites.html:48 msgid "Expires" -msgstr "Läuft aus" +msgstr "Läuft ab am" #: bookwyrm/templates/settings/invites/manage_invites.html:49 msgid "Max uses" -msgstr "Maximale Benutzungen" +msgstr "Maximale Verwendungen" #: bookwyrm/templates/settings/invites/manage_invites.html:50 msgid "Times used" -msgstr "Mal benutzt" +msgstr "Anzahl Verwendungen" #: bookwyrm/templates/settings/invites/manage_invites.html:53 msgid "No active invites" @@ -2487,7 +2658,7 @@ msgstr "IP-Addressen-Sperrliste" #: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:18 msgid "Any traffic from this IP address will get a 404 response when trying to access any part of the application." -msgstr "Jeder Datenverkehr von dieser IP-Adresse erhält eine 404-Antwort, wenn versucht wird, auf einen beliebigen Teil der Anwendung zuzugreifen." +msgstr "Datenverkehr von dieser IP-Adresse erhält eine 404-Antwort, wenn versucht wird, auf einen beliebigen Teil der Anwendung zuzugreifen." #: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:24 msgid "Address" @@ -2499,7 +2670,7 @@ msgstr "Derzeit sind keine IP-Adressen gesperrt" #: bookwyrm/templates/settings/ip_blocklist/ip_tooltip.html:6 msgid "You can block IP ranges using CIDR syntax." -msgstr "Du kannst IP-Bereiche mittels CIDR-Syntax blockieren." +msgstr "Du kannst IP-Bereiche mittels CIDR-Syntax sperren." #: bookwyrm/templates/settings/layout.html:4 msgid "Administration" @@ -2507,7 +2678,7 @@ msgstr "Administration" #: bookwyrm/templates/settings/layout.html:29 msgid "Manage Users" -msgstr "Nutzer*innen verwalten" +msgstr "Benutzer*innen verwalten" #: bookwyrm/templates/settings/layout.html:51 msgid "Moderation" @@ -2542,7 +2713,7 @@ msgstr "Zurück zu den Meldungen" #: bookwyrm/templates/settings/reports/report.html:23 msgid "Moderator Comments" -msgstr "Moderator:innenkommentare" +msgstr "Moderator*innenkommentare" #: bookwyrm/templates/settings/reports/report.html:41 #: bookwyrm/templates/snippets/create_status.html:28 @@ -2555,7 +2726,7 @@ msgstr "Gemeldete Statusmeldungen" #: bookwyrm/templates/settings/reports/report.html:48 msgid "No statuses reported" -msgstr "Keine Beiträge gemeldet" +msgstr "Keine Statusmeldungen gemeldet" #: bookwyrm/templates/settings/reports/report.html:54 msgid "Status has been deleted" @@ -2572,11 +2743,11 @@ msgstr "Gemeldet von %(username)s" #: bookwyrm/templates/settings/reports/report_preview.html:30 msgid "Re-open" -msgstr "Wiedereröffnen" +msgstr "Erneut öffnen" #: bookwyrm/templates/settings/reports/report_preview.html:32 msgid "Resolve" -msgstr "Lösen" +msgstr "Beheben" #: bookwyrm/templates/settings/reports/reports.html:6 #, python-format @@ -2609,7 +2780,7 @@ msgstr "Bilder" #: bookwyrm/templates/settings/site.html:12 #: bookwyrm/templates/settings/site.html:74 msgid "Footer Content" -msgstr "Inhalt des Footers" +msgstr "Inhalt der Fußzeile" #: bookwyrm/templates/settings/site.html:13 #: bookwyrm/templates/settings/site.html:98 @@ -2618,7 +2789,7 @@ msgstr "Registrierung" #: bookwyrm/templates/settings/site.html:24 msgid "Instance Name:" -msgstr "Instanzname" +msgstr "Instanzname:" #: bookwyrm/templates/settings/site.html:28 msgid "Tagline:" @@ -2626,7 +2797,7 @@ msgstr "Motto:" #: bookwyrm/templates/settings/site.html:32 msgid "Instance description:" -msgstr "Instanzbeschreibung" +msgstr "Instanzbeschreibung:" #: bookwyrm/templates/settings/site.html:36 msgid "Short description:" @@ -2642,7 +2813,7 @@ msgstr "Verhaltenskodex:" #: bookwyrm/templates/settings/site.html:45 msgid "Privacy Policy:" -msgstr "Datenschutzerklärung" +msgstr "Datenschutzerklärung:" #: bookwyrm/templates/settings/site.html:57 msgid "Logo:" @@ -2650,7 +2821,7 @@ msgstr "Logo:" #: bookwyrm/templates/settings/site.html:61 msgid "Logo small:" -msgstr "Logo klein" +msgstr "Kleines Logo:" #: bookwyrm/templates/settings/site.html:65 msgid "Favicon:" @@ -2658,11 +2829,11 @@ msgstr "Favicon:" #: bookwyrm/templates/settings/site.html:77 msgid "Support link:" -msgstr "Unterstützungslink" +msgstr "Support-Link:" #: bookwyrm/templates/settings/site.html:81 msgid "Support title:" -msgstr "Unterstützungstitel" +msgstr "Support-Titel:" #: bookwyrm/templates/settings/site.html:85 msgid "Admin email:" @@ -2670,7 +2841,7 @@ msgstr "E-Mail-Adresse des*r Administrator*in:" #: bookwyrm/templates/settings/site.html:89 msgid "Additional info:" -msgstr "Zusätzliche Info:" +msgstr "Zusätzliche Angaben:" #: bookwyrm/templates/settings/site.html:103 msgid "Allow registration" @@ -2682,15 +2853,15 @@ msgstr "Einladungsanfragen zulassen" #: bookwyrm/templates/settings/site.html:115 msgid "Require users to confirm email address" -msgstr "User müssen ihre E-Mail-Adresse bestätigen" +msgstr "Benutzer*innen müssen ihre E-Mail-Adresse bestätigen" #: bookwyrm/templates/settings/site.html:117 msgid "(Recommended if registration is open)" -msgstr "(Vorschlagen falls die Registrierung offen ist)" +msgstr "(empfohlen, falls Selbstregistrierung zulässig ist)" #: bookwyrm/templates/settings/site.html:120 msgid "Registration closed text:" -msgstr "Registrierungen geschlossen text" +msgstr "Hinweis, wenn Selbtregistrierung nicht erlaubt ist:" #: bookwyrm/templates/settings/site.html:124 msgid "Invite request text:" @@ -2699,12 +2870,12 @@ msgstr "Hinweis für Einladungsanfragen:" #: bookwyrm/templates/settings/users/delete_user_form.html:5 #: bookwyrm/templates/settings/users/user_moderation_actions.html:31 msgid "Permanently delete user" -msgstr "User permanent löschen" +msgstr "Benutzer*in dauerhaft löschen" #: bookwyrm/templates/settings/users/delete_user_form.html:12 #, python-format msgid "Are you sure you want to delete %(username)s's account? This action cannot be undone. To proceed, please enter your password to confirm deletion." -msgstr "Bist du sicher, dass du %(username)ss Account löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden. Zur Bestätigung gib bitte dein Passwort ein." +msgstr "Bist du sicher, dass du das Benutzer*inkonto „%(username)s“ löschen möchtest? Diese Aktion kann nicht rückgängig gemacht werden. Zur Bestätigung gib bitte dein Passwort ein." #: bookwyrm/templates/settings/users/delete_user_form.html:17 msgid "Your password:" @@ -2712,7 +2883,7 @@ msgstr "Dein Passwort:" #: bookwyrm/templates/settings/users/user.html:7 msgid "Back to users" -msgstr "Zurück zu Benutzer*innen" +msgstr "Zurück zu den Benutzer*innen" #: bookwyrm/templates/settings/users/user_admin.html:7 #, python-format @@ -2749,7 +2920,7 @@ msgstr "Inaktiv" #: bookwyrm/templates/settings/users/user_admin.html:52 #: bookwyrm/templates/settings/users/user_info.html:120 msgid "Not set" -msgstr "Nicht gesetzt" +msgstr "Nicht festgelegt" #: bookwyrm/templates/settings/users/user_info.html:16 msgid "View user profile" @@ -2805,7 +2976,7 @@ msgstr "Instanz anzeigen" #: bookwyrm/templates/settings/users/user_moderation_actions.html:5 msgid "Permanently deleted" -msgstr "Permanent gelöscht" +msgstr "Dauerhaft gelöscht" #: bookwyrm/templates/settings/users/user_moderation_actions.html:13 #: bookwyrm/templates/snippets/status/status_options.html:32 @@ -2833,57 +3004,70 @@ msgstr "Regal erstellen" msgid "Edit Shelf" msgstr "Regal bearbeiten" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "Alle Bücher" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "Regal erstellen" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "%(formatted_count)s Buch" msgstr[1] "%(formatted_count)s Bücher" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" -msgstr "(zeige %(start)s-%(end)s)" +msgstr "(Anzeige: %(start)s&endash;%(end)s)" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "Regal bearbeiten" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "Regal löschen" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "Ins Regal gestellt" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "Gestartet" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "Abgeschlossen" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "Dieses Regal ist leer." +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "Einladen" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "Einladung stornieren" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "@%(username)s entfernen" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" -msgstr "Von %(username)s veröffentlicht" +msgstr "Veröffentlicht von %(username)s" #: bookwyrm/templates/snippets/authors.html:22 #, python-format @@ -2913,7 +3097,7 @@ msgstr "Teilen zurücknehmen" #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" -msgstr "Bewerten" +msgstr "Besprechen" #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" @@ -2948,7 +3132,7 @@ msgstr "von %(pages)s Seiten" #: bookwyrm/templates/snippets/status/layout.html:52 #: bookwyrm/templates/snippets/status/layout.html:53 msgid "Reply" -msgstr "Antwort" +msgstr "Antworten" #: bookwyrm/templates/snippets/create_status/content_field.html:17 msgid "Content" @@ -2975,12 +3159,13 @@ msgstr "Kommentar:" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "Privat" #: bookwyrm/templates/snippets/create_status/post_options_block.html:21 msgid "Post" -msgstr "Absenden" +msgstr "Veröffentlichen" #: bookwyrm/templates/snippets/create_status/quotation.html:17 msgid "Quote:" @@ -3019,7 +3204,7 @@ msgstr "Diese Lesedaten löschen?" #: bookwyrm/templates/snippets/delete_readthrough_modal.html:7 #, python-format msgid "You are deleting this readthrough and its %(count)s associated progress updates." -msgstr "Du löscht diesen Leseforschritt und %(count)s zugehörige Fortschrittsupdates." +msgstr "Du löscht diesen Leseforschritt und %(count)s zugehörige Zwischenstände." #: bookwyrm/templates/snippets/fav_button.html:16 #: bookwyrm/templates/snippets/fav_button.html:17 @@ -3070,13 +3255,14 @@ msgid "Unfollow" msgstr "Entfolgen" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "Annehmen" #: bookwyrm/templates/snippets/form_rate_stars.html:20 #: bookwyrm/templates/snippets/stars.html:13 msgid "No rating" -msgstr "Kein Rating" +msgstr "Keine Bewertung" #: bookwyrm/templates/snippets/form_rate_stars.html:28 #, python-format @@ -3097,8 +3283,8 @@ msgstr[1] "%(rating)s Sterne" #, python-format msgid "set a goal to read %(counter)s book in %(year)s" msgid_plural "set a goal to read %(counter)s books in %(year)s" -msgstr[0] "Setze das Ziel, %(year)s %(counter)s Buch zu lesen" -msgstr[1] "Setze das Ziel, %(year)s %(counter)s Bücher zu lesen" +msgstr[0] "setze dir das Ziel, %(year)s %(counter)s Buch zu lesen" +msgstr[1] "setze dir das Ziel, %(year)s %(counter)s Bücher zu lesen" #: bookwyrm/templates/snippets/generated_status/rating.html:3 #, python-format @@ -3117,12 +3303,12 @@ msgstr[1] "Besprechung von „%(book_title)s“ (%(display_rating)s Sterne): %(r #: bookwyrm/templates/snippets/generated_status/review_pure_name.html:8 #, python-format msgid "Review of \"%(book_title)s\": %(review_title)s" -msgstr "Review von \"%(book_title)s\": %(review_title)s" +msgstr "Besprechung von „%(book_title)s“: %(review_title)s" #: bookwyrm/templates/snippets/goal_form.html:4 #, python-format msgid "Set a goal for how many books you'll finish reading in %(year)s, and track your progress throughout the year." -msgstr "Setze dir ein Ziel, wie viele Bücher du %(year)s lesen wirst und behalte deinen Fortschritt über's Jahr im Auge." +msgstr "Setze dir ein Ziel, wie viele Bücher du %(year)s lesen willst und behalte deinen Fortschritt während des Jahrs im Blick." #: bookwyrm/templates/snippets/goal_form.html:16 msgid "Reading goal:" @@ -3134,12 +3320,12 @@ msgstr "Bücher" #: bookwyrm/templates/snippets/goal_form.html:26 msgid "Goal privacy:" -msgstr "Sichtbarkeit des Ziels" +msgstr "Sichtbarkeit des Ziels:" #: bookwyrm/templates/snippets/goal_form.html:33 #: bookwyrm/templates/snippets/reading_modals/layout.html:13 msgid "Post to feed" -msgstr "Posten" +msgstr "Im Feed veröffentlichen" #: bookwyrm/templates/snippets/goal_form.html:37 msgid "Set goal" @@ -3148,7 +3334,7 @@ msgstr "Ziel setzen" #: bookwyrm/templates/snippets/goal_progress.html:9 #, python-format msgid "%(percent)s%% complete!" -msgstr "%(percent)s%% komplett!" +msgstr "%(percent)s%% geschafft!" #: bookwyrm/templates/snippets/goal_progress.html:12 #, python-format @@ -3181,20 +3367,23 @@ msgstr "Weiter" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "Öffentlich" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "Ungelistet" #: bookwyrm/templates/snippets/privacy-icons.html:12 msgid "Followers-only" -msgstr "Nur für Folgende" +msgstr "Nur für Follower*innen" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "Beitragssichtbarkeit" @@ -3202,11 +3391,11 @@ msgstr "Beitragssichtbarkeit" #: bookwyrm/templates/user/relationships/followers.html:6 #: bookwyrm/templates/user/relationships/layout.html:11 msgid "Followers" -msgstr "Folgende" +msgstr "Follower*innen" #: bookwyrm/templates/snippets/rate_action.html:4 msgid "Leave a rating" -msgstr "Raten" +msgstr "Bewerten" #: bookwyrm/templates/snippets/rate_action.html:19 msgid "Rate" @@ -3215,7 +3404,7 @@ msgstr "Bewerten" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:6 #, python-format msgid "Finish \"%(book_title)s\"" -msgstr "\"%(book_title)s\" abschließen" +msgstr "„%(book_title)s“ abschließen" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:23 #: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:20 @@ -3226,7 +3415,7 @@ msgstr "Zu lesen angefangen" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:31 #: bookwyrm/templates/snippets/readthrough_form.html:20 msgid "Finished reading" -msgstr "Zu Ende gelesen" +msgstr "Lesen abgeschlossen" #: bookwyrm/templates/snippets/reading_modals/form.html:9 msgid "(Optional)" @@ -3235,17 +3424,17 @@ msgstr "(Optional)" #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 msgid "Update progress" -msgstr "Update-Fortschritt" +msgstr "Zwischenstand" #: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:6 #, python-format msgid "Start \"%(book_title)s\"" -msgstr "\"%(book_title)s\" beginnen" +msgstr "„%(book_title)s“ beginnen" #: bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html:6 #, python-format msgid "Want to Read \"%(book_title)s\"" -msgstr "\"%(book_title)s\" auf Leseliste setzen" +msgstr "„%(book_title)s“ auf Leseliste setzen" #: bookwyrm/templates/snippets/readthrough_form.html:14 msgid "Progress" @@ -3267,11 +3456,11 @@ msgstr "@%(username)s melden" #: bookwyrm/templates/snippets/report_modal.html:23 #, python-format msgid "This report will be sent to %(site_name)s's moderators for review." -msgstr "Diese Meldung wird an die Moderator:innen von %(site_name)s weitergeletiet." +msgstr "Diese Meldung wird an die Moderato*innen von %(site_name)s weitergeleitet." #: bookwyrm/templates/snippets/report_modal.html:24 msgid "More info about this report:" -msgstr "Weitere Angeben zu dieser Meldung:" +msgstr "Weitere Angaben zu dieser Meldung:" #: bookwyrm/templates/snippets/shelf_selector.html:4 msgid "Move book" @@ -3354,7 +3543,7 @@ msgstr "hat %(book)s bewertet:" #: bookwyrm/templates/snippets/status/headers/read.html:7 #, python-format msgid "finished reading %(book)s" -msgstr "hat %(book)s ausgelesen" +msgstr "hat %(book)s abgeschlossen" #: bookwyrm/templates/snippets/status/headers/reading.html:7 #, python-format @@ -3374,7 +3563,7 @@ msgstr "%(username)s hat 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 delta 17735 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\n" "Language-Team: Spanish\n" "Language: es\n" @@ -35,7 +35,7 @@ msgstr "Un mes" #: bookwyrm/forms.py:259 msgid "Does Not Expire" -msgstr "Nunca se vence" +msgstr "No expira" #: bookwyrm/forms.py:263 #, python-brace-format @@ -46,29 +46,29 @@ msgstr "{i} usos" msgid "Unlimited" msgstr "Sin límite" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "Orden de la lista" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "Título" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Calificación" -#: bookwyrm/forms.py:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Ordenar por" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "Ascendente" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "Descendente" @@ -165,7 +165,7 @@ msgstr "Línea temporal de libros" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "Libros" @@ -223,7 +223,7 @@ msgid "Edit Author" msgstr "Editar Autor/Autora" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "Alias:" @@ -276,71 +276,72 @@ msgstr "Agregado:" msgid "Updated:" msgstr "Actualizado:" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "Editado más recientemente por:" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "Metadatos" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "Nombre:" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "Separar varios valores con comas." -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "Biografía:" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "Enlace de Wikipedia:" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "Fecha de nacimiento:" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "Fecha de muerte:" -#: bookwyrm/templates/author/edit_author.html:79 +#: bookwyrm/templates/author/edit_author.html:81 msgid "Author Identifiers" msgstr "Identificadores de autor/autora" -#: bookwyrm/templates/author/edit_author.html:81 +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Clave OpenLibrary:" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "ID Inventaire:" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Clave Librarything:" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Clave Goodreads:" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +353,13 @@ msgstr "Clave Goodreads:" msgid "Save" msgstr "Guardar" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -397,7 +400,7 @@ msgstr "Agregar descripción" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "Descripción:" @@ -460,7 +463,7 @@ msgstr "Lugares" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "Listas" @@ -470,7 +473,7 @@ msgstr "Agregar a lista" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -543,7 +546,9 @@ msgid "This is a new work" msgstr "Esta es una obra nueva" #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "Confirmar" @@ -612,7 +617,7 @@ msgid "John Doe, Jane Smith" msgstr "Juan Nadie, Natalia Natalia" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "Portada" @@ -686,17 +691,17 @@ msgstr "%(pages)s páginas" #: bookwyrm/templates/book/publisher_info.html:38 #, python-format msgid "%(languages)s language" -msgstr "idioma %(languages)s" +msgstr "Idioma %(languages)s" #: bookwyrm/templates/book/publisher_info.html:65 #, python-format msgid "Published %(date)s by %(publisher)s." -msgstr "Publicado %(date)s por %(publisher)s." +msgstr "Publicado el %(date)s por %(publisher)s." #: bookwyrm/templates/book/publisher_info.html:67 #, python-format msgid "Published %(date)s" -msgstr "Publicado %(date)s" +msgstr "Publicado el %(date)s" #: bookwyrm/templates/book/publisher_info.html:69 #, python-format @@ -793,7 +798,7 @@ msgstr "Reenviar enlace de confirmación" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" @@ -842,7 +847,7 @@ msgstr "Ordenar por" #: bookwyrm/templates/directory/sort_filter.html:8 msgid "Recently active" -msgstr "Activ@ recientemente" +msgstr "Activo recientemente" #: bookwyrm/templates/directory/sort_filter.html:9 msgid "Suggested" @@ -921,7 +926,7 @@ msgstr "Ver que es nuevo en la comunidad local de %(site_name)s" #: bookwyrm/templates/discover/large-book.html:52 #: bookwyrm/templates/discover/small-book.html:36 msgid "View status" -msgstr "Ver status" +msgstr "Ver estado" #: bookwyrm/templates/email/confirm/html_content.html:6 #: bookwyrm/templates/email/confirm/text_content.html:4 @@ -993,10 +998,10 @@ msgid "You requested to reset your %(site_name)s password. Click the link below msgstr "Tú solicitaste reestablecer tu %(site_name)s contraseña. Haz clic en el enlace a continuación para establecer una nueva contraseña e ingresar a tu cuenta." #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" msgstr "Restablecer contraseña" @@ -1031,7 +1036,7 @@ msgstr "No tienes ningún mensaje en este momento." #: bookwyrm/templates/feed/feed.html:22 #, python-format msgid "load 0 unread status(es)" -msgstr "cargar 0 status(es) no leído(s)" +msgstr "cargar 0 estado(s) no leído(s)" #: bookwyrm/templates/feed/feed.html:38 msgid "There aren't any activities right now! Try following a user to get started" @@ -1042,12 +1047,12 @@ msgstr "¡No hay actividad ahora mismo! Sigue a otro usuario para empezar" #: bookwyrm/templates/user/goal_form.html:6 #, python-format msgid "%(year)s Reading Goal" -msgstr "%(year)s Meta de lectura" +msgstr "Objetivo de lectura de %(year)s" #: bookwyrm/templates/feed/goal_card.html:18 #, python-format msgid "You can set or change your reading goal any time from your profile page" -msgstr "Puedes establecer o cambiar tu meta de lectura en cualquier momento que desees desde tu perfil" +msgstr "Puedes establecer o cambiar tu objetivo de lectura en cualquier momento desde tu página de perfil" #: bookwyrm/templates/feed/layout.html:5 msgid "Updates" @@ -1077,7 +1082,7 @@ msgstr "Leyendo actualmente" #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 msgid "Read" -msgstr "Leido" +msgstr "Leído" #: bookwyrm/templates/feed/suggested_users.html:5 #: bookwyrm/templates/get_started/users.html:6 @@ -1102,7 +1107,7 @@ msgid "What are you reading?" msgstr "¿Qué estás leyendo?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "Buscar libros" @@ -1120,8 +1125,9 @@ msgstr "Puedes agregar libros cuando comiences a usar %(site_name)s." #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1137,7 +1143,7 @@ msgid "Popular on %(site_name)s" msgstr "Popular en %(site_name)s" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "No se encontró ningún libro" @@ -1223,9 +1229,110 @@ msgstr "Buscar un usuario" msgid "No users found for \"%(query)s\"" msgstr "No se encontró ningún usuario correspondiente a \"%(query)s\"" +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Crear grupo" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Gestionado por %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "¿Eliminar este grupo?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Esta acción no se puede deshacer" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Eliminar" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Editar Grupo" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "¡Agrega nuevos miembros!" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Nombre del grupo:" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Descripción del grupo:" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Eliminar grupo" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Buscar para agregar un usuario" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Este grupo no tiene listas" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Editar grupo" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Los miembros pueden agregar y eliminar libros en las listas de libros de un grupo" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Dejar grupo" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Te sigue" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s seguidor que sigues" +msgstr[1] "%(mutuals)s seguidores que sigues" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s libro en tus estantes" +msgstr[1] "%(shared_books)s libros en tus estantes" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "No se encontraron miembros potenciales para «%(user_query)s»" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Gestor" + #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "Importar libros" @@ -1261,7 +1368,7 @@ msgstr "No hay ninguna importación reciente" #: bookwyrm/templates/import/import_status.html:6 #: bookwyrm/templates/import/import_status.html:10 msgid "Import Status" -msgstr "Status de importación" +msgstr "Importar estado" #: bookwyrm/templates/import/import_status.html:11 msgid "Back to imports" @@ -1322,14 +1429,14 @@ msgid "Book" msgstr "Libro" #: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" #: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor/Autora" @@ -1341,19 +1448,6 @@ msgstr "Importado" msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Puede descargar sus datos de Goodreads desde la página de Importación/Exportación de su cuenta de Goodreads." -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "Crear una cuenta" - -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "Permiso denegado" - -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "¡Disculpa! Este código de invitación no queda válido." - #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1369,6 +1463,20 @@ msgstr "Código de conducta" msgid "Privacy Policy" msgstr "Política de privacidad" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Crear una cuenta" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Permiso denegado" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "¡Disculpa! Este código de invitación no queda válido." + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" msgstr "Libros recientes" @@ -1407,6 +1515,53 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido." msgid "Your Account" msgstr "Tu cuenta" +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Iniciar sesión" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Iniciar sesión" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "¡Éxito! Dirección de correo electrónico confirmada." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Nombre de usuario:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Contraseña:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "¿Olvidaste tu contraseña?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "Más sobre este sitio" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Confirmar contraseña:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Un enlace para restablecer tu contraseña se enviará a tu dirección de correo electrónico" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Restablecer contraseña" + #: bookwyrm/templates/layout.html:13 #, python-format msgid "%(site_name)s search" @@ -1454,40 +1609,25 @@ msgstr "Cerrar sesión" msgid "Notifications" msgstr "Notificaciones" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "Nombre de usuario:" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "contraseña" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "¿Olvidaste tu contraseña?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "Iniciar sesión" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "Unirse" #: bookwyrm/templates/layout.html:221 msgid "Successfully posted status" -msgstr "Status publicado exitosamente" +msgstr "Estado publicado con éxito" #: bookwyrm/templates/layout.html:222 msgid "Error posting status" -msgstr "Error en publicar status" +msgstr "Error al publicar el estado" #: bookwyrm/templates/layout.html:234 msgid "Contact site admin" -msgstr "Contactarse con administradores del sitio" +msgstr "Comuníquese con el administrador del sitio" #: bookwyrm/templates/layout.html:238 msgid "Documentation" @@ -1513,10 +1653,15 @@ msgstr "Crear lista" #: bookwyrm/templates/lists/created_text.html:5 #, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Creado por %(username)s y gestionado por %(groupname)s" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format msgid "Created and curated by %(username)s" msgstr "Agregado y comisariado por %(username)s" -#: bookwyrm/templates/lists/created_text.html:7 +#: bookwyrm/templates/lists/created_text.html:9 #, python-format msgid "Created by %(username)s" msgstr "Creado por %(username)s" @@ -1549,118 +1694,130 @@ msgstr "Desechar" msgid "Delete this list?" msgstr "¿Eliminar esta lista?" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "Esta acción no se puede deshacer" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Eliminar" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Editar lista" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" msgstr "Enumerar lista de comisariado:" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "Cerrado" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" msgstr "Solo tú puedes agregar a y sacar libros de esta lista" -#: bookwyrm/templates/lists/form.html:26 +#: bookwyrm/templates/lists/form.html:27 msgid "Curated" msgstr "De comisariado" -#: bookwyrm/templates/lists/form.html:27 +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" msgstr "Cualquier usuario puede sugerir libros, en cuanto lo hayas aprobado" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "Abrir" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" msgstr "Cualquer usuario puede agregar libros a esta lista" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Grupo" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "Los miembros del grupo pueden agregar y eliminar de esta lista" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Seleccionar grupo" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Seleccionar un grupo" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "¡Aún no tienes ningún grupo!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Crear un grupo" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "Eliminar lista" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" msgstr "¡Has sugerido un libro para esta lista exitosamente!" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" msgstr "¡Has agregado un libro a esta lista exitosamente!" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "Esta lista está vacia" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "Agregado por %(username)s" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "Posición" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "Establecido" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "Quitar" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "Ordena la lista" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" msgstr "Dirección" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "Agregar libros" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "Sugerir libros" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "buscar" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" msgstr "Borrar búsqueda" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" msgstr "No se encontró ningún libro correspondiente a la búsqueda: \"%(query)s\"" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "Sugerir" @@ -1672,30 +1829,18 @@ msgstr "Guardado" msgid "Your Lists" msgstr "Tus listas" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "Todas las listas" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "Listas guardadas" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "Iniciar sesión" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." -msgstr "¡Éxito! Dirección de correo electrónico confirmada." - -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "Contraseña:" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "Más sobre este sitio" +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "aceptó su invitación para unirse al grupo «%(group_name)s»" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format @@ -1710,22 +1855,22 @@ msgstr "sugirió agregar %(book_title)s a #: bookwyrm/templates/notifications/items/boost.html:19 #, python-format msgid "boosted your review of %(book_title)s" -msgstr "respaldó tu reseña de %(book_title)s" +msgstr "impulsó tu reseña de %(book_title)s" #: bookwyrm/templates/notifications/items/boost.html:25 #, python-format msgid "boosted your comment on%(book_title)s" -msgstr "respaldó tu comentario en%(book_title)s" +msgstr "impulsó tu comentario en%(book_title)s" #: bookwyrm/templates/notifications/items/boost.html:31 #, python-format msgid "boosted your quote from %(book_title)s" -msgstr "respaldó tucita de %(book_title)s" +msgstr "impulsó tucita de %(book_title)s" #: bookwyrm/templates/notifications/items/boost.html:37 #, python-format msgid "boosted your status" -msgstr "respaldó tu status" +msgstr "impulsó tu estado" #: bookwyrm/templates/notifications/items/fav.html:19 #, python-format @@ -1734,7 +1879,7 @@ msgstr "le gustó tu reseña de %(book_title)s< #: bookwyrm/templates/notifications/items/fav.html:25 #, python-format -msgid "liked your comment on%(book_title)s" +msgid "liked your comment on %(book_title)s" msgstr "le gustó tu comentario sobre %(book_title)s" #: bookwyrm/templates/notifications/items/fav.html:31 @@ -1760,6 +1905,21 @@ msgstr "te quiere seguir" msgid "Your import completed." msgstr "Tu importación ha terminado." +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "te invitó a unirte al grupo «%(group_name)s»" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "se ha unido a tu grupo «%(group_name)s»" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "ha dejado tu grupo «%(group_name)s»" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" @@ -1778,7 +1938,17 @@ msgstr "te mencionó en una cita de %(book_titl #: bookwyrm/templates/notifications/items/mention.html:38 #, python-format msgid "mentioned you in a status" -msgstr "te mencionó en un status" +msgstr "te mencionó en un estado" + +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "ha sido eliminado de tu grupo «%(group_name)s»" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "Te han eliminado del grupo «%(group_name)s»" #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format @@ -1798,13 +1968,28 @@ msgstr "respondió a tu replied to your status" -msgstr "respondió a tu status" +msgstr "respondió a tu estado" #: bookwyrm/templates/notifications/items/report.html:15 #, python-format msgid "A new report needs moderation." msgstr "Un informe nuevo se requiere moderación." +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "ha cambiado el nivel de privacidad del grupo «%(group_name)s»" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "ha cambiado el nombre del grupo «%(group_name)s»" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "ha cambiado la descripción del grupo «%(group_name)s»" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" msgstr "Borrar notificaciones" @@ -1821,20 +2006,6 @@ msgstr "Menciones" msgid "You're all caught up!" msgstr "¡Estás al día!" -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "Confirmar contraseña:" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "Un enlace para restablecer tu contraseña se enviará a tu dirección de correo electrónico" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "Restablecer contraseña" - #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 #: bookwyrm/templates/preferences/layout.html:31 @@ -1870,7 +2041,7 @@ msgstr "Eliminar cuenta permanentemente" #: bookwyrm/templates/preferences/delete_user.html:14 msgid "Deleting your account cannot be undone. The username will not be available to register in the future." -msgstr "Eliminar tu cuenta no puede ser deshecho. El nombre de usuario no será disponible para registrar en el futuro." +msgstr "La eliminación de tu cuenta no se puede deshacer. El nombre de usuario no estará disponible para registrarse en el futuro." #: bookwyrm/templates/preferences/edit_user.html:4 #: bookwyrm/templates/preferences/edit_user.html:7 @@ -1896,7 +2067,7 @@ msgstr "Privacidad" #: bookwyrm/templates/preferences/edit_user.html:72 msgid "Show reading goal prompt in feed:" -msgstr "Mostrar sugerencia de meta de lectura en el feed:" +msgstr "Mostrar indicador de objetivo de lectura en el feed:" #: bookwyrm/templates/preferences/edit_user.html:76 msgid "Show suggested users:" @@ -2025,7 +2196,7 @@ msgstr "Fecha final:" #: bookwyrm/templates/settings/announcements/announcement.html:60 #: bookwyrm/templates/settings/announcements/announcement_form.html:58 msgid "Active:" -msgstr "Activ@:" +msgstr "Activo:" #: bookwyrm/templates/settings/announcements/announcement_form.html:8 #: bookwyrm/templates/settings/announcements/announcements.html:8 @@ -2149,7 +2320,7 @@ msgstr "Actividad de inscripciones de usuarios" #: bookwyrm/templates/settings/dashboard/dashboard.html:112 msgid "Status activity" -msgstr "Actividad de status" +msgstr "Actividad de estado" #: bookwyrm/templates/settings/dashboard/dashboard.html:118 msgid "Works created" @@ -2161,7 +2332,7 @@ msgstr "Inscripciones" #: bookwyrm/templates/settings/dashboard/status_chart.html:11 msgid "Statuses posted" -msgstr "Statuses publicados" +msgstr "Estados publicados" #: bookwyrm/templates/settings/dashboard/user_chart.html:11 msgid "Total" @@ -2257,7 +2428,7 @@ msgid "Details" msgstr "Detalles" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "Actividad" @@ -2551,15 +2722,15 @@ msgstr "Comentario" #: bookwyrm/templates/settings/reports/report.html:46 msgid "Reported statuses" -msgstr "Statuses reportados" +msgstr "Estados reportados" #: bookwyrm/templates/settings/reports/report.html:48 msgid "No statuses reported" -msgstr "Ningún estatus reportado" +msgstr "No se reportaron estados" #: bookwyrm/templates/settings/reports/report.html:54 msgid "Status has been deleted" -msgstr "Status ha sido eliminado" +msgstr "El estado ha sido eliminado" #: bookwyrm/templates/settings/reports/report_preview.html:13 msgid "No notes provided" @@ -2833,53 +3004,66 @@ msgstr "Crear estante" msgid "Edit Shelf" msgstr "Editar estante" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "Todos los libros" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "Crear estante" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "%(formatted_count)s libro" msgstr[1] "%(formatted_count)s libros" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" msgstr "(mostrando %(start)s-%(end)s)" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "Editar estante" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "Eliminar estante" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "Archivado" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "Empezado" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "Terminado" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "Este estante está vacio." +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "Invitar" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "Anular la invitación" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "Eliminar a @%(username)s" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" @@ -2904,12 +3088,12 @@ msgstr "%(title)s por" #: bookwyrm/templates/snippets/boost_button.html:20 #: bookwyrm/templates/snippets/boost_button.html:21 msgid "Boost" -msgstr "Respaldar" +msgstr "Impulsar" #: bookwyrm/templates/snippets/boost_button.html:33 #: bookwyrm/templates/snippets/boost_button.html:34 msgid "Un-boost" -msgstr "Des-respaldar" +msgstr "Des-impulsar" #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" @@ -2948,7 +3132,7 @@ msgstr "de %(pages)s páginas" #: bookwyrm/templates/snippets/status/layout.html:52 #: bookwyrm/templates/snippets/status/layout.html:53 msgid "Reply" -msgstr "Respuesta" +msgstr "Responder" #: bookwyrm/templates/snippets/create_status/content_field.html:17 msgid "Content" @@ -2975,6 +3159,7 @@ msgstr "Comentario:" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "Privada" @@ -3050,7 +3235,7 @@ msgstr "Borrar filtros" #: bookwyrm/templates/snippets/follow_button.html:14 #, python-format msgid "Follow @%(username)s" -msgstr "Seguir @%(username)s" +msgstr "Seguir a @%(username)s" #: bookwyrm/templates/snippets/follow_button.html:16 msgid "Follow" @@ -3063,13 +3248,14 @@ msgstr "Des-enviar solicitud de seguidor" #: bookwyrm/templates/snippets/follow_button.html:30 #, python-format msgid "Unfollow @%(username)s" -msgstr "Dejar de seguir @%(username)s" +msgstr "Dejar de seguir a @%(username)s" #: bookwyrm/templates/snippets/follow_button.html:32 msgid "Unfollow" msgstr "Dejar de seguir" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "Aceptar" @@ -3097,7 +3283,7 @@ msgstr[1] "%(rating)s estrellas" #, python-format msgid "set a goal to read %(counter)s book in %(year)s" msgid_plural "set a goal to read %(counter)s books in %(year)s" -msgstr[0] "estableció una meta de leer %(counter)s libro en %(year)s" +msgstr[0] "establecer el objetivo de leer %(counter)s libro en %(year)s" msgstr[1] "estableció una meta de leer %(counter)s libros en %(year)s" #: bookwyrm/templates/snippets/generated_status/rating.html:3 @@ -3126,7 +3312,7 @@ msgstr "Establece una meta para cuantos libros leerás en %(year)s, y seguir tu #: bookwyrm/templates/snippets/goal_form.html:16 msgid "Reading goal:" -msgstr "Meta de lectura:" +msgstr "Objetivo de lectura:" #: bookwyrm/templates/snippets/goal_form.html:21 msgid "books" @@ -3134,12 +3320,12 @@ msgstr "libros" #: bookwyrm/templates/snippets/goal_form.html:26 msgid "Goal privacy:" -msgstr "Privacidad de meta:" +msgstr "Privacidad del objetivo:" #: bookwyrm/templates/snippets/goal_form.html:33 #: bookwyrm/templates/snippets/reading_modals/layout.html:13 msgid "Post to feed" -msgstr "Compartir con tu feed" +msgstr "Publicar en el feed" #: bookwyrm/templates/snippets/goal_form.html:37 msgid "Set goal" @@ -3148,7 +3334,7 @@ msgstr "Establecer meta" #: bookwyrm/templates/snippets/goal_progress.html:9 #, python-format msgid "%(percent)s%% complete!" -msgstr "%(percent)s%% terminado!" +msgstr "¡%(percent)s%% terminado!" #: bookwyrm/templates/snippets/goal_progress.html:12 #, python-format @@ -3181,12 +3367,14 @@ msgstr "Siguiente" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "Público" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "Privado" @@ -3195,6 +3383,7 @@ msgid "Followers-only" msgstr "Solo seguidores" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "Privacidad de publicación" @@ -3235,7 +3424,7 @@ msgstr "(Opcional)" #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 msgid "Update progress" -msgstr "Progreso de actualización" +msgstr "Actualizar progreso" #: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:6 #, python-format @@ -3306,7 +3495,7 @@ msgstr "Advertencia de contenido" #: bookwyrm/templates/snippets/status/content_status.html:79 msgid "Show status" -msgstr "Ver status" +msgstr "Mostrar estado" #: bookwyrm/templates/snippets/status/content_status.html:101 #, python-format @@ -3324,7 +3513,7 @@ msgstr "Abrir imagen en una nueva ventana" #: bookwyrm/templates/snippets/status/content_status.html:144 msgid "Hide status" -msgstr "Ocultar status" +msgstr "Ocultar estado" #: bookwyrm/templates/snippets/status/header.html:45 #, python-format @@ -3339,7 +3528,7 @@ msgstr "comentó en \"%(book)s\"" #: bookwyrm/templates/snippets/status/headers/note.html:15 #, python-format msgid "replied to %(username)s's status" -msgstr "respondió al status de %(username)s" +msgstr "respondió al estado de %(username)s" #: bookwyrm/templates/snippets/status/headers/quotation.html:2 #, python-format @@ -3379,12 +3568,12 @@ msgstr "Eliminar status" #: bookwyrm/templates/snippets/status/layout.html:56 #: bookwyrm/templates/snippets/status/layout.html:57 msgid "Boost status" -msgstr "Respaldar status" +msgstr "Impulsar estado" #: bookwyrm/templates/snippets/status/layout.html:60 #: bookwyrm/templates/snippets/status/layout.html:61 msgid "Like status" -msgstr "Me gusta status" +msgstr "Me gusta estado" #: bookwyrm/templates/snippets/status/status.html:10 msgid "boosted" @@ -3395,25 +3584,6 @@ msgstr "respaldó" msgid "More options" msgstr "Más opciones" -#: bookwyrm/templates/snippets/suggested_users.html:16 -#, python-format -msgid "%(mutuals)s follower you follow" -msgid_plural "%(mutuals)s followers you follow" -msgstr[0] "%(mutuals)s seguidor que sigues" -msgstr[1] "%(mutuals)s seguidores que sigues" - -#: bookwyrm/templates/snippets/suggested_users.html:23 -#, python-format -msgid "%(shared_books)s book on your shelves" -msgid_plural "%(shared_books)s books on your shelves" -msgstr[0] "%(shared_books)s libro en tus estantes" -msgstr[1] "%(shared_books)s libros en tus estantes" - -#: bookwyrm/templates/snippets/suggested_users.html:31 -#: bookwyrm/templates/user/user_preview.html:36 -msgid "Follows you" -msgstr "Te sigue" - #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" msgstr "Cambiar a esta edición" @@ -3442,7 +3612,7 @@ msgstr "Los libros de %(username)s" #: bookwyrm/templates/user/goal.html:8 #, python-format msgid "%(year)s Reading Progress" -msgstr "%(year)s Progreso de la meta de lectura" +msgstr "Progreso de lectura de %(year)s" #: bookwyrm/templates/user/goal.html:12 msgid "Edit Goal" @@ -3451,7 +3621,7 @@ msgstr "Editar meta" #: bookwyrm/templates/user/goal.html:28 #, python-format msgid "%(name)s hasn't set a reading goal for %(year)s." -msgstr "%(name)s no ha establecido una meta de lectura para %(year)s." +msgstr "%(name)s no se ha fijado un objetivo de lectura para %(year)s." #: bookwyrm/templates/user/goal.html:40 #, python-format @@ -3463,17 +3633,34 @@ msgstr "Tus libros de %(year)s" msgid "%(username)s's %(year)s Books" msgstr "Los libros de %(username)s para %(year)s" -#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10 +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "Tus grupos" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "Grupos: %(username)s" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "Crear grupo" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 msgid "User Profile" msgstr "Perfil de usuario" -#: bookwyrm/templates/user/layout.html:44 +#: bookwyrm/templates/user/layout.html:45 msgid "Follow Requests" msgstr "Solicitudes de seguidor" -#: bookwyrm/templates/user/layout.html:69 +#: bookwyrm/templates/user/layout.html:70 msgid "Reading Goal" -msgstr "Meta de lectura" +msgstr "Objetivo de lectura" + +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "Grupos" #: bookwyrm/templates/user/lists.html:11 #, python-format @@ -3506,7 +3693,7 @@ msgstr "Editar perfil" #: bookwyrm/templates/user/user.html:33 #, python-format msgid "View all %(size)s" -msgstr "Ver todos los %(size)s" +msgstr "Ver los %(size)s" #: bookwyrm/templates/user/user.html:46 msgid "View all books" @@ -3514,7 +3701,7 @@ msgstr "Ver todos los libros" #: bookwyrm/templates/user/user.html:59 msgid "User Activity" -msgstr "Actividad de usuario" +msgstr "Actividad del usuario" #: bookwyrm/templates/user/user.html:63 msgid "RSS feed" @@ -3565,15 +3752,15 @@ msgstr "%(title)s: %(subtitle)s" msgid "Not a valid csv file" msgstr "No un archivo csv válido" -#: bookwyrm/views/login.py:69 +#: bookwyrm/views/landing/login.py:69 msgid "Username or password are incorrect" msgstr "Nombre de usuario o contraseña es incorrecta" -#: bookwyrm/views/password.py:32 +#: bookwyrm/views/landing/password.py:32 msgid "No user with that email address was found." msgstr "No se pudo encontrar un usuario con esa dirección de correo electrónico." -#: bookwyrm/views/password.py:41 +#: bookwyrm/views/landing/password.py:43 #, python-brace-format msgid "A password reset link was sent to {email}" msgstr "Un enlace para reestablecer tu contraseña se envió a {email}" diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo index 5e8dfa6646b38fbed1bbc9159b926c2d9839f176..0bc2fb3dad8abed5091b5b7d7746a492e681d9cc 100644 GIT binary patch delta 24283 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 Gr~&{=I{exI diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index 141bd894b..5f9bc8b24 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-15 22:03+0000\n" -"PO-Revision-Date: 2021-10-16 14:36\n" +"POT-Creation-Date: 2021-10-24 14:09+0000\n" +"PO-Revision-Date: 2021-11-12 17:16\n" "Last-Translator: Mouse Reeve \n" "Language-Team: French\n" "Language: fr\n" @@ -40,35 +40,35 @@ msgstr "Sans expiration" #: bookwyrm/forms.py:263 #, python-brace-format msgid "{i} uses" -msgstr "" +msgstr "{i} utilisations" #: bookwyrm/forms.py:264 msgid "Unlimited" msgstr "Sans limite" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "Ordre de la liste" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "Titre du livre" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Note" -#: bookwyrm/forms.py:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Trier par" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "Ordre croissant" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "Ordre décroissant" @@ -98,7 +98,7 @@ msgstr "Suppression du modérateur" #: bookwyrm/models/base_model.py:21 msgid "Domain block" -msgstr "" +msgstr "Bloc de domaine" #: bookwyrm/models/book.py:232 msgid "Audiobook" @@ -118,7 +118,7 @@ msgstr "Couverture rigide" #: bookwyrm/models/book.py:236 msgid "Paperback" -msgstr "" +msgstr "Couverture souple" #: bookwyrm/models/federated_server.py:11 #: bookwyrm/templates/settings/federation/edit_instance.html:42 @@ -161,11 +161,11 @@ msgstr "Accueil" #: bookwyrm/settings.py:119 msgid "Books Timeline" -msgstr "" +msgstr "Actualité de mes livres" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "Livres" @@ -187,7 +187,7 @@ msgstr "Français" #: bookwyrm/settings.py:169 msgid "Português - Brasil (Brazilian Portuguese)" -msgstr "" +msgstr "Português - Brasil (Portugais brésilien)" #: bookwyrm/settings.py:170 msgid "简体中文 (Simplified Chinese)" @@ -223,7 +223,7 @@ msgid "Edit Author" msgstr "Modifier l’auteur ou autrice" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "Pseudonymes :" @@ -260,7 +260,7 @@ msgstr "Voir sur Goodreads" #: bookwyrm/templates/author/author.html:108 #, python-format msgid "Books by %(name)s" -msgstr "Livres par %(name)s" +msgstr "Livres de %(name)s" #: bookwyrm/templates/author/edit_author.html:5 msgid "Edit Author:" @@ -276,71 +276,72 @@ msgstr "Ajouté :" msgid "Updated:" msgstr "Mis à jour :" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "Dernière modification par :" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "Métadonnées" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "Nom :" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "Séparez plusieurs valeurs par une virgule." -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "Bio :" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "Wikipedia :" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "Date de naissance :" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "Date de décès :" -#: bookwyrm/templates/author/edit_author.html:79 +#: bookwyrm/templates/author/edit_author.html:81 msgid "Author Identifiers" msgstr "Identifiants de l’auteur ou autrice" -#: bookwyrm/templates/author/edit_author.html:81 +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Clé Openlibrary :" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "Identifiant Inventaire :" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Clé Librarything :" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Clé Goodreads :" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +353,13 @@ msgstr "Clé Goodreads :" msgid "Save" msgstr "Enregistrer" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -369,7 +372,7 @@ msgstr "Annuler" #: bookwyrm/templates/landing/large-book.html:25 #: bookwyrm/templates/landing/small-book.html:18 msgid "by" -msgstr "par" +msgstr "de" #: bookwyrm/templates/book/book.html:55 bookwyrm/templates/book/book.html:56 msgid "Edit Book" @@ -397,7 +400,7 @@ msgstr "Ajouter une description" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "Description :" @@ -460,7 +463,7 @@ msgstr "Lieux" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "Listes" @@ -470,7 +473,7 @@ msgstr "Ajouter à la liste" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -543,7 +546,9 @@ msgid "This is a new work" msgstr "Il s’agit d’un nouvel ouvrage." #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "Confirmer" @@ -612,7 +617,7 @@ msgid "John Doe, Jane Smith" msgstr "Claude Dupont, Dominique Durand" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "Couverture" @@ -753,7 +758,7 @@ msgstr "Aide" #: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8 msgid "Edit status" -msgstr "" +msgstr "Modifier le statut" #: bookwyrm/templates/confirm_email/confirm_email.html:4 msgid "Confirm email" @@ -793,7 +798,7 @@ msgstr "Envoyer le lien de confirmation de nouveau" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" @@ -890,22 +895,22 @@ msgstr "Tous les comptes connus" #: bookwyrm/templates/discover/card-header.html:9 #, python-format msgid "%(username)s rated %(book_title)s" -msgstr "" +msgstr "%(username)s a noté %(book_title)s" #: bookwyrm/templates/discover/card-header.html:13 #, python-format msgid "%(username)s reviewed %(book_title)s" -msgstr "" +msgstr "%(username)s a critiqué %(book_title)s" #: bookwyrm/templates/discover/card-header.html:17 #, python-format msgid "%(username)s commented on %(book_title)s" -msgstr "" +msgstr "%(username)s a commenté %(book_title)s" #: bookwyrm/templates/discover/card-header.html:21 #, python-format msgid "%(username)s quoted %(book_title)s" -msgstr "" +msgstr "%(username)s a cité un passage de %(book_title)s" #: bookwyrm/templates/discover/discover.html:4 #: bookwyrm/templates/discover/discover.html:10 @@ -921,7 +926,7 @@ msgstr "Voir les nouveautés de la communauté locale %(site_name)s" #: bookwyrm/templates/discover/large-book.html:52 #: bookwyrm/templates/discover/small-book.html:36 msgid "View status" -msgstr "Afficher tous les status" +msgstr "Afficher le statut" #: bookwyrm/templates/email/confirm/html_content.html:6 #: bookwyrm/templates/email/confirm/text_content.html:4 @@ -974,7 +979,7 @@ msgstr "S’enregistrer maintenant" #: bookwyrm/templates/email/invite/html_content.html:15 #, python-format msgid "Learn more about %(site_name)s." -msgstr "" +msgstr "En savoir plus sur %(site_name)s." #: bookwyrm/templates/email/invite/text_content.html:4 #, python-format @@ -984,7 +989,7 @@ msgstr "Vous avez reçu une invitation à rejoindre %(site_name)s ! Cliquez le #: bookwyrm/templates/email/invite/text_content.html:8 #, python-format msgid "Learn more about %(site_name)s:" -msgstr "" +msgstr "En savoir plus sur %(site_name)s :" #: bookwyrm/templates/email/password_reset/html_content.html:6 #: bookwyrm/templates/email/password_reset/text_content.html:4 @@ -993,10 +998,10 @@ msgid "You requested to reset your %(site_name)s password. Click the link below msgstr "Une demande de réinitialisation de votre mot de passe sur %(site_name)s a été initialisée. Cliquez le lien suivant pour définir un nouveau mot de passe et vous connecter à votre compte." #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" msgstr "Changez le mot de passe" @@ -1102,7 +1107,7 @@ msgid "What are you reading?" msgstr "Que lisez‑vous ?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "Chercher un livre" @@ -1120,8 +1125,9 @@ msgstr "Vous pourrez ajouter des livres lorsque vous commencerez à utiliser %(s #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1137,7 +1143,7 @@ msgid "Popular on %(site_name)s" msgstr "Populaire sur %(site_name)s" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "Aucun livre trouvé" @@ -1223,9 +1229,110 @@ msgstr "Chercher un compte" msgid "No users found for \"%(query)s\"" msgstr "Aucun compte trouvé pour « %(query)s »" +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Créer un Groupe" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Géré par %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "Supprimer ce groupe ?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Cette action ne peut pas être annulée" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Supprimer" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Modifier le Groupe" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "Ajouter de nouveaux membres !" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Nom du groupe :" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Description du groupe :" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Supprimer le groupe" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Chercher et ajouter un·e utilisateur·rice" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Ce groupe n'a pas de liste" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Modifier le groupe" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Les membres peuvent ajouter et supprimer des livres sur les listes de livres d'un groupe" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Quitter le groupe" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Vous suit" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s abonné(e) que vous suivez" +msgstr[1] "%(mutuals)s abonné(e)s que vous suivez" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s livre sur vos étagères" +msgstr[1] "%(shared_books)s livres sur vos étagères" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "Aucun membre potentiel trouvé pour \"%(user_query)s\"" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Responsable" + #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "Importer des livres" @@ -1299,7 +1406,7 @@ msgstr "Sauter en bas de liste pour sélectionner les %(failed_count)s items n #: bookwyrm/templates/import/import_status.html:62 #, python-format msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "Ligne %(index)s : %(title)s par %(author)s" +msgstr "Ligne %(index)s : %(title)s de %(author)s" #: bookwyrm/templates/import/import_status.html:82 msgid "Select all" @@ -1322,14 +1429,14 @@ msgid "Book" msgstr "Livre" #: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titre" #: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Auteur/autrice" @@ -1339,20 +1446,7 @@ msgstr "Importé" #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." -msgstr "" - -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "Créer un compte" - -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "Autorisation refusée" - -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "Cette invitation n’est plus valide ; désolé !" +msgstr "Vous pouvez télécharger vos données GoodReads depuis la page Import/Export de votre compte GoodReads." #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format @@ -1369,6 +1463,20 @@ msgstr "Code de conduite" msgid "Privacy Policy" msgstr "Politique de vie privée" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Créer un compte" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Autorisation refusée" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "Cette invitation n’est plus valide ; désolé !" + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" msgstr "Livres récents" @@ -1407,6 +1515,53 @@ msgstr "Merci ! Votre demande a bien été reçue." msgid "Your Account" msgstr "Votre compte" +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Connexion" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Se connecter" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "Bravo ! L’adresse email a été confirmée." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Nom du compte :" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Mot de passe :" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "Mot de passe oublié ?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "En savoir plus sur ce site" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Confirmez le mot de passe :" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Un lien pour changer votre mot de passe sera envoyé à votre addresse email" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Changer de mot de passe" + #: bookwyrm/templates/layout.html:13 #, python-format msgid "%(site_name)s search" @@ -1454,25 +1609,10 @@ msgstr "Se déconnecter" msgid "Notifications" msgstr "Notifications" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "Nom du compte :" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "Mot de passe" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "Mot de passe oublié ?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "Se connecter" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "Rejoindre" @@ -1513,10 +1653,15 @@ msgstr "Créer une liste" #: bookwyrm/templates/lists/created_text.html:5 #, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Créé par %(username)s et géré par %(groupname)s" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format msgid "Created and curated by %(username)s" msgstr "Créée et modérée par %(username)s" -#: bookwyrm/templates/lists/created_text.html:7 +#: bookwyrm/templates/lists/created_text.html:9 #, python-format msgid "Created by %(username)s" msgstr "Créée par %(username)s" @@ -1549,118 +1694,130 @@ msgstr "Rejeter" msgid "Delete this list?" msgstr "Supprimer cette liste ?" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "Cette action ne peut pas être annulée" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Supprimer" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Modifier la liste" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" msgstr "Modération de la liste :" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "Fermée" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" msgstr "Vous seulement pouvez ajouter ou retirer des livres dans cette liste" -#: bookwyrm/templates/lists/form.html:26 +#: bookwyrm/templates/lists/form.html:27 msgid "Curated" msgstr "Modérée" -#: bookwyrm/templates/lists/form.html:27 +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" msgstr "N’importe qui peut suggérer des livres, soumis à votre approbation" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "Ouvrir" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" msgstr "N’importe qui peut suggérer des livres" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Groupe" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "Les membres du groupe peuvent ajouter et supprimer des livres de cette liste" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Sélectionner un Groupe" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Sélectionner un groupe" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "Vous n'avez pas encore de Groupe !" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Créer un Groupe" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "Supprimer la liste" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" msgstr "Vous avez suggéré un livre à cette liste !" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" msgstr "Vous avez ajouté un livre à cette liste !" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "Cette liste est actuellement vide" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "Ajouté par %(username)s" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "Position" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "Appliquer" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "Retirer" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "Trier la liste" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" msgstr "Direction" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "Ajouter des livres" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "Suggérer des livres" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "chercher" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" msgstr "Vider la requête" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" msgstr "Aucun livre trouvé pour la requête « %(query)s »" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "Suggérer" @@ -1672,30 +1829,18 @@ msgstr "Sauvegardé" msgid "Your Lists" msgstr "Vos listes" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "Toutes les listes" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "Listes sauvegardées" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "Connexion" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." -msgstr "Bravo ! L’adresse email a été confirmée." - -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "Mot de passe :" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "En savoir plus sur ce site" +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "a accepté votre invitation à rejoindre le groupe \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format @@ -1730,22 +1875,22 @@ msgstr "a partagé votre statut" #: bookwyrm/templates/notifications/items/fav.html:19 #, python-format msgid "liked your review of %(book_title)s" -msgstr "" +msgstr "a ajouté votre critique de %(book_title)s à ses favoris" #: bookwyrm/templates/notifications/items/fav.html:25 #, python-format -msgid "liked your comment on%(book_title)s" -msgstr "" +msgid "liked your comment on %(book_title)s" +msgstr "a ajouté votre commentaire sur %(book_title)s à ses favoris" #: bookwyrm/templates/notifications/items/fav.html:31 #, python-format msgid "liked your quote from %(book_title)s" -msgstr "" +msgstr "a ajouté votre citation de %(book_title)s à ses favoris" #: bookwyrm/templates/notifications/items/fav.html:37 #, python-format msgid "liked your status" -msgstr "" +msgstr "a ajouté votre statut à ses favoris" #: bookwyrm/templates/notifications/items/follow.html:15 msgid "followed you" @@ -1760,6 +1905,21 @@ msgstr "vous a envoyé une demande d’abonnement" msgid "Your import completed." msgstr "Votre importation est terminée." +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "vous a invité·e à rejoindre le groupe \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "a rejoint votre groupe \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "a quitté votre groupe \"%(group_name)s\"" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" @@ -1780,6 +1940,16 @@ msgstr "vous a mentionné dans sa citation de % msgid "mentioned you in a status" msgstr "vous a mentionné dans son statut" +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "a été retiré·e de votre groupe \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "Vous avez été retiré·e du groupe \"%(group_name)s\"" + #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" @@ -1805,6 +1975,21 @@ msgstr "a répondu à votre report needs moderation." msgstr "Un nouveau signalement a besoin d’être traité." +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "a changé le niveau de confidentialité du groupe %(group_name)s" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "a changé le nom du groupe %(group_name)s" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "a changé la description du groupe %(group_name)s" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" msgstr "Supprimer les notifications" @@ -1821,20 +2006,6 @@ msgstr "Mentions" msgid "You're all caught up!" msgstr "Aucune nouvelle notification !" -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "Confirmez le mot de passe :" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "Un lien pour changer votre mot de passe sera envoyé à votre addresse email" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "Changer de mot de passe" - #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 #: bookwyrm/templates/preferences/layout.html:31 @@ -1896,7 +2067,7 @@ msgstr "Confidentialité" #: bookwyrm/templates/preferences/edit_user.html:72 msgid "Show reading goal prompt in feed:" -msgstr "" +msgstr "Afficher l'invite d'objectif de lecture dans le fil d'actualité :" #: bookwyrm/templates/preferences/edit_user.html:76 msgid "Show suggested users:" @@ -1936,7 +2107,7 @@ msgstr "Commencer \"%(book_title)s\"" #: bookwyrm/templates/reading_progress/want.html:5 #, python-format msgid "Want to Read \"%(book_title)s\"" -msgstr "" +msgstr "Je veux lire \"%(book_title)s\"" #: bookwyrm/templates/search/book.html:47 #: bookwyrm/templates/settings/reports/reports.html:25 @@ -2042,7 +2213,7 @@ msgstr "Contenu :" #: bookwyrm/templates/settings/announcements/announcement_form.html:30 msgid "Event date:" -msgstr "" +msgstr "Date de l'événement :" #: bookwyrm/templates/settings/announcements/announcements.html:3 #: bookwyrm/templates/settings/announcements/announcements.html:5 @@ -2086,54 +2257,54 @@ msgstr "inactive" #: bookwyrm/templates/settings/announcements/announcements.html:52 msgid "No announcements found" -msgstr "" +msgstr "Aucune annonce trouvée" #: bookwyrm/templates/settings/dashboard/dashboard.html:6 #: bookwyrm/templates/settings/dashboard/dashboard.html:8 #: bookwyrm/templates/settings/layout.html:26 msgid "Dashboard" -msgstr "" +msgstr "Tableau de bord" #: bookwyrm/templates/settings/dashboard/dashboard.html:15 #: bookwyrm/templates/settings/dashboard/dashboard.html:100 msgid "Total users" -msgstr "" +msgstr "Nombre total d'utilisateurs·rices" #: bookwyrm/templates/settings/dashboard/dashboard.html:21 #: bookwyrm/templates/settings/dashboard/user_chart.html:16 msgid "Active this month" -msgstr "" +msgstr "Actifs ce mois" #: bookwyrm/templates/settings/dashboard/dashboard.html:27 msgid "Statuses" -msgstr "" +msgstr "Statuts" #: bookwyrm/templates/settings/dashboard/dashboard.html:33 #: bookwyrm/templates/settings/dashboard/works_chart.html:11 msgid "Works" -msgstr "" +msgstr "Œuvres" #: bookwyrm/templates/settings/dashboard/dashboard.html:43 #, python-format msgid "%(display_count)s open report" msgid_plural "%(display_count)s open reports" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(display_count)s signalement ouvert" +msgstr[1] "%(display_count)s signalements ouverts" #: bookwyrm/templates/settings/dashboard/dashboard.html:54 #, python-format msgid "%(display_count)s invite request" msgid_plural "%(display_count)s invite requests" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(display_count)s demande d'invitation" +msgstr[1] "%(display_count)s demandes d'invitation" #: bookwyrm/templates/settings/dashboard/dashboard.html:65 msgid "Instance Activity" -msgstr "" +msgstr "Activité de l'instance" #: bookwyrm/templates/settings/dashboard/dashboard.html:83 msgid "Interval:" -msgstr "" +msgstr "Intervalle :" #: bookwyrm/templates/settings/dashboard/dashboard.html:87 msgid "Days" @@ -2145,15 +2316,15 @@ msgstr "Semaines" #: bookwyrm/templates/settings/dashboard/dashboard.html:106 msgid "User signup activity" -msgstr "" +msgstr "Nouvelles inscriptions" #: bookwyrm/templates/settings/dashboard/dashboard.html:112 msgid "Status activity" -msgstr "" +msgstr "Nouveaux statuts" #: bookwyrm/templates/settings/dashboard/dashboard.html:118 msgid "Works created" -msgstr "" +msgstr "Œuvres créées" #: bookwyrm/templates/settings/dashboard/registration_chart.html:10 msgid "Registrations" @@ -2161,26 +2332,26 @@ msgstr "Inscriptions" #: bookwyrm/templates/settings/dashboard/status_chart.html:11 msgid "Statuses posted" -msgstr "" +msgstr "Statuts publiés" #: bookwyrm/templates/settings/dashboard/user_chart.html:11 msgid "Total" -msgstr "" +msgstr "Total" #: bookwyrm/templates/settings/email_blocklist/domain_form.html:5 #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:10 msgid "Add domain" -msgstr "" +msgstr "Ajouter un domaine" #: bookwyrm/templates/settings/email_blocklist/domain_form.html:11 msgid "Domain:" -msgstr "" +msgstr "Domaine :" #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:5 #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:7 #: bookwyrm/templates/settings/layout.html:59 msgid "Email Blocklist" -msgstr "" +msgstr "Liste des e-mails bloqués" #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:18 msgid "When someone tries to register with an email from this domain, no account will be created. The registration process will appear to have worked." @@ -2188,7 +2359,7 @@ msgstr "Quand quelqu'un essaiera de s'inscrire avec un e-mail de ce domaine, auc #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:25 msgid "Domain" -msgstr "" +msgstr "Domaine" #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:29 #: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:27 @@ -2199,12 +2370,12 @@ msgstr "Options" #, python-format msgid "%(display_count)s user" msgid_plural "%(display_count)s users" -msgstr[0] "%(display_count)s utilisateur" -msgstr[1] "%(display_count)s utilisateurs" +msgstr[0] "%(display_count)s utilisateur·rice" +msgstr[1] "%(display_count)s utilisateurs·rices" #: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:59 msgid "No email domains currently blocked" -msgstr "" +msgstr "Aucun domaine de messagerie n’est actuellement bloqué" #: bookwyrm/templates/settings/federation/edit_instance.html:3 #: bookwyrm/templates/settings/federation/edit_instance.html:6 @@ -2257,7 +2428,7 @@ msgid "Details" msgstr "Détails" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "Activité" @@ -2299,7 +2470,7 @@ msgstr "Modifier" #: bookwyrm/templates/settings/federation/instance.html:79 msgid "No notes" -msgstr "" +msgstr "Aucune note" #: bookwyrm/templates/settings/federation/instance.html:94 #: bookwyrm/templates/settings/users/user_moderation_actions.html:8 @@ -2499,7 +2670,7 @@ msgstr "Aucune adresse IP n'est actuellement bloquée" #: bookwyrm/templates/settings/ip_blocklist/ip_tooltip.html:6 msgid "You can block IP ranges using CIDR syntax." -msgstr "" +msgstr "Vous pouvez bloquer des plages d'adresses IP en utilisant la syntaxe CIDR." #: bookwyrm/templates/settings/layout.html:4 msgid "Administration" @@ -2634,7 +2805,7 @@ msgstr "Description courte :" #: bookwyrm/templates/settings/site.html:37 msgid "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." -msgstr "" +msgstr "Utilisé dans l'aperçu de l'instance sur joinbookwyrm.com. Ne prend pas en charge l'HTML ou le Markdown." #: bookwyrm/templates/settings/site.html:41 msgid "Code of conduct:" @@ -2761,7 +2932,7 @@ msgstr "Local" #: bookwyrm/templates/settings/users/user_info.html:38 msgid "Remote" -msgstr "" +msgstr "Distant·e" #: bookwyrm/templates/settings/users/user_info.html:47 msgid "User details" @@ -2789,7 +2960,7 @@ msgstr "Abonné(e)s approuvés manuellement :" #: bookwyrm/templates/settings/users/user_info.html:76 msgid "Discoverable:" -msgstr "" +msgstr "Visible publiquement :" #: bookwyrm/templates/settings/users/user_info.html:80 msgid "Deactivation reason:" @@ -2833,53 +3004,66 @@ msgstr "Créer une étagère" msgid "Edit Shelf" msgstr "Modifier l’étagère" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "Tous les livres" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "Créer une étagère" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "%(formatted_count)s livre" msgstr[1] "%(formatted_count)s livres" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" -msgstr "" +msgstr "(affichage de %(start)s-%(end)s)" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "Modifier l’étagère" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "Supprimer l’étagère" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "Date d’ajout" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "Commencé" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "Terminé" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "Cette étagère est vide" +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "Inviter" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "Annuler l'invitation" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "Retirer @%(username)s" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" @@ -2899,7 +3083,7 @@ msgstr "Pas de couverture" #: bookwyrm/templates/snippets/book_titleby.html:6 #, python-format msgid "%(title)s by" -msgstr "" +msgstr "%(title)s de" #: bookwyrm/templates/snippets/boost_button.html:20 #: bookwyrm/templates/snippets/boost_button.html:21 @@ -2921,7 +3105,7 @@ msgstr "Citation" #: bookwyrm/templates/snippets/create_status/comment.html:15 msgid "Some thoughts on the book" -msgstr "" +msgstr "Quelques réflexions sur ce livre" #: bookwyrm/templates/snippets/create_status/comment.html:27 #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:15 @@ -2956,7 +3140,7 @@ msgstr "Contenu" #: bookwyrm/templates/snippets/create_status/content_warning_field.html:10 msgid "Content warning:" -msgstr "" +msgstr "Avertissement sur le contenu :" #: bookwyrm/templates/snippets/create_status/content_warning_field.html:18 msgid "Spoilers ahead!" @@ -2975,6 +3159,7 @@ msgstr "Commentaire :" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "Privé" @@ -2989,24 +3174,24 @@ msgstr "Citation :" #: bookwyrm/templates/snippets/create_status/quotation.html:25 #, python-format msgid "An excerpt from '%(book_title)s'" -msgstr "" +msgstr "Un extrait de '%(book_title)s'" #: bookwyrm/templates/snippets/create_status/quotation.html:32 msgid "Position:" -msgstr "" +msgstr "Emplacement :" #: bookwyrm/templates/snippets/create_status/quotation.html:45 msgid "On page:" -msgstr "" +msgstr "À la page :" #: bookwyrm/templates/snippets/create_status/quotation.html:51 msgid "At percent:" -msgstr "" +msgstr "Au pourcentage :" #: bookwyrm/templates/snippets/create_status/review.html:25 #, python-format msgid "Your review of '%(book_title)s'" -msgstr "" +msgstr "Votre critique de '%(book_title)s'" #: bookwyrm/templates/snippets/create_status/review.html:40 msgid "Review:" @@ -3050,7 +3235,7 @@ msgstr "Annuler les filtres" #: bookwyrm/templates/snippets/follow_button.html:14 #, python-format msgid "Follow @%(username)s" -msgstr "" +msgstr "S'abonner à @%(username)s" #: bookwyrm/templates/snippets/follow_button.html:16 msgid "Follow" @@ -3063,13 +3248,14 @@ msgstr "Annuler la demande d’abonnement" #: bookwyrm/templates/snippets/follow_button.html:30 #, python-format msgid "Unfollow @%(username)s" -msgstr "" +msgstr "Se désabonner de @%(username)s" #: bookwyrm/templates/snippets/follow_button.html:32 msgid "Unfollow" msgstr "Se désabonner" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "Accepter" @@ -3082,8 +3268,8 @@ msgstr "Aucune note" #, python-format msgid "%(half_rating)s star" msgid_plural "%(half_rating)s stars" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(half_rating)s étoile" +msgstr[1] "%(half_rating)s étoiles" #: bookwyrm/templates/snippets/form_rate_stars.html:64 #: bookwyrm/templates/snippets/stars.html:7 @@ -3104,8 +3290,8 @@ msgstr[1] "souhaite lire %(counter)s livres en %(year)s" #, python-format msgid "rated %(title)s: %(display_rating)s star" msgid_plural "rated %(title)s: %(display_rating)s stars" -msgstr[0] "" -msgstr[1] "" +msgstr[0] "a noté %(title)s : %(display_rating)s étoile" +msgstr[1] "a noté %(title)s : %(display_rating)s étoiles" #: bookwyrm/templates/snippets/generated_status/review_pure_name.html:4 #, python-format @@ -3153,7 +3339,7 @@ msgstr "%(percent)s%% terminé !" #: bookwyrm/templates/snippets/goal_progress.html:12 #, python-format msgid "You've read %(read_count)s of %(goal_count)s books." -msgstr "Vous avez lu %(read_count)s sur %(goal_count)s livres." +msgstr "Vous avez lu %(read_count)s livres sur %(goal_count)s." #: bookwyrm/templates/snippets/goal_progress.html:14 #, python-format @@ -3181,12 +3367,14 @@ msgstr "Suivante" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "Public" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "Non listé" @@ -3195,6 +3383,7 @@ msgid "Followers-only" msgstr "Abonnemé(e)s uniquement" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "Confidentialité du statut" @@ -3230,7 +3419,7 @@ msgstr "Lecture terminée le" #: bookwyrm/templates/snippets/reading_modals/form.html:9 msgid "(Optional)" -msgstr "" +msgstr "(Facultatif)" #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 @@ -3302,21 +3491,21 @@ msgstr "Terminer la lecture" #: bookwyrm/templates/snippets/status/content_status.html:72 msgid "Content warning" -msgstr "" +msgstr "Avertissement sur le contenu" #: bookwyrm/templates/snippets/status/content_status.html:79 msgid "Show status" -msgstr "" +msgstr "Afficher le statut" #: bookwyrm/templates/snippets/status/content_status.html:101 #, python-format msgid "(Page %(page)s)" -msgstr "" +msgstr "(Page %(page)s)" #: bookwyrm/templates/snippets/status/content_status.html:103 #, python-format msgid "(%(percent)s%%)" -msgstr "" +msgstr "(%(percent)s%%)" #: bookwyrm/templates/snippets/status/content_status.html:125 msgid "Open image in new window" @@ -3324,12 +3513,12 @@ msgstr "Ouvrir l’image dans une nouvelle fenêtre" #: bookwyrm/templates/snippets/status/content_status.html:144 msgid "Hide status" -msgstr "" +msgstr "Masquer le statut" #: bookwyrm/templates/snippets/status/header.html:45 #, python-format msgid "edited %(date)s" -msgstr "" +msgstr "modifié le %(date)s" #: bookwyrm/templates/snippets/status/headers/comment.html:2 #, python-format @@ -3395,25 +3584,6 @@ msgstr "a partagé" msgid "More options" msgstr "Plus d’options" -#: bookwyrm/templates/snippets/suggested_users.html:16 -#, python-format -msgid "%(mutuals)s follower you follow" -msgid_plural "%(mutuals)s followers you follow" -msgstr[0] "%(mutuals)s abonné(e) que vous suivez" -msgstr[1] "%(mutuals)s abonné(e)s que vous suivez" - -#: bookwyrm/templates/snippets/suggested_users.html:23 -#, python-format -msgid "%(shared_books)s book on your shelves" -msgid_plural "%(shared_books)s books on your shelves" -msgstr[0] "%(shared_books)s livre sur vos étagères" -msgstr[1] "%(shared_books)s livres sur vos étagères" - -#: bookwyrm/templates/snippets/suggested_users.html:31 -#: bookwyrm/templates/user/user_preview.html:36 -msgid "Follows you" -msgstr "Vous suit" - #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" msgstr "Changer vers cette édition" @@ -3463,18 +3633,35 @@ msgstr "Vos livres en %(year)s" msgid "%(username)s's %(year)s Books" msgstr "Livres de %(username)s en %(year)s" -#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10 +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "Vos Groupes" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "Groupes : %(username)s" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "Créer un groupe" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 msgid "User Profile" msgstr "Profil" -#: bookwyrm/templates/user/layout.html:44 +#: bookwyrm/templates/user/layout.html:45 msgid "Follow Requests" msgstr "Demandes d’abonnement" -#: bookwyrm/templates/user/layout.html:69 +#: bookwyrm/templates/user/layout.html:70 msgid "Reading Goal" msgstr "Défi lecture" +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "Groupes" + #: bookwyrm/templates/user/lists.html:11 #, python-format msgid "Lists: %(username)s" @@ -3565,15 +3752,15 @@ msgstr "%(title)s (%(subtitle)s)" msgid "Not a valid csv file" msgstr "Fichier CSV non valide" -#: bookwyrm/views/login.py:69 +#: bookwyrm/views/landing/login.py:69 msgid "Username or password are incorrect" msgstr "Identifiant ou mot de passe incorrect" -#: bookwyrm/views/password.py:32 +#: bookwyrm/views/landing/password.py:32 msgid "No user with that email address was found." msgstr "Aucun compte avec cette adresse email n’a été trouvé." -#: bookwyrm/views/password.py:41 +#: bookwyrm/views/landing/password.py:43 #, python-brace-format msgid "A password reset link was sent to {email}" msgstr "Un lien de réinitialisation a été envoyé à {email}." @@ -3581,5 +3768,5 @@ msgstr "Un lien de réinitialisation a été envoyé à {email}." #: bookwyrm/views/rss_feed.py:35 #, python-brace-format msgid "Status updates from {obj.display_name}" -msgstr "" +msgstr "Mises à jour de statut de {obj.display_name}" diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 1d1227f8092b70c68bb692fb532759090142aa83..fbb1986cf8b43b014b8909367d9d5bc656e798f6 100644 GIT binary patch delta 27406 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\n" "Language-Team: Chinese Simplified\n" "Language: zh\n" @@ -46,29 +46,29 @@ msgstr "{i} 次使用" msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "列表顺序" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "书名" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 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:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "降序" @@ -114,7 +114,7 @@ msgstr "图像小说" #: bookwyrm/models/book.py:235 msgid "Hardcover" -msgstr "硬封面" +msgstr "精装" #: bookwyrm/models/book.py:236 msgid "Paperback" @@ -165,7 +165,7 @@ msgstr "书目时间线" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "书目" @@ -187,7 +187,7 @@ msgstr "Français(法语)" #: bookwyrm/settings.py:169 msgid "Português - Brasil (Brazilian Portuguese)" -msgstr "" +msgstr "葡萄牙语-巴西(巴西的葡语)" #: bookwyrm/settings.py:170 msgid "简体中文 (Simplified Chinese)" @@ -223,7 +223,7 @@ msgid "Edit Author" msgstr "编辑作者" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "别名:" @@ -276,71 +276,72 @@ msgstr "添加了:" msgid "Updated:" msgstr "更新了:" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "最后编辑人:" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "元数据" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "名称:" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "请用英文逗号(,)分隔多个值。" -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "简介:" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "维基百科链接:" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "出生日期:" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "死亡日期:" -#: bookwyrm/templates/author/edit_author.html:79 +#: bookwyrm/templates/author/edit_author.html:81 msgid "Author Identifiers" msgstr "作者标识号:" -#: bookwyrm/templates/author/edit_author.html:81 +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Openlibrary key:" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "Inventaire ID:" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Librarything key:" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Goodreads key:" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +353,13 @@ msgstr "Goodreads key:" msgid "Save" msgstr "保存" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -396,7 +399,7 @@ msgstr "添加描述" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "描述:" @@ -459,7 +462,7 @@ msgstr "地点" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "列表" @@ -469,7 +472,7 @@ msgstr "添加到列表" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -542,7 +545,9 @@ msgid "This is a new work" msgstr "这是一个新的作品。" #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "确认" @@ -611,7 +616,7 @@ msgid "John Doe, Jane Smith" msgstr "张三, 李四" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "封面" @@ -752,7 +757,7 @@ msgstr "帮助" #: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8 msgid "Edit status" -msgstr "" +msgstr "设置状态" #: bookwyrm/templates/confirm_email/confirm_email.html:4 msgid "Confirm email" @@ -792,7 +797,7 @@ msgstr "重新发送确认链接" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" @@ -887,22 +892,22 @@ msgstr "所有已知用户" #: bookwyrm/templates/discover/card-header.html:9 #, python-format msgid "%(username)s rated %(book_title)s" -msgstr "" +msgstr "%(username)s%(book_title)s 留下了评分" #: bookwyrm/templates/discover/card-header.html:13 #, python-format msgid "%(username)s reviewed %(book_title)s" -msgstr "" +msgstr "%(username)s 已评价 %(book_title)s" #: bookwyrm/templates/discover/card-header.html:17 #, python-format msgid "%(username)s commented on %(book_title)s" -msgstr "" +msgstr "%(username)s 评论了 %(book_title)s" #: bookwyrm/templates/discover/card-header.html:21 #, python-format msgid "%(username)s quoted %(book_title)s" -msgstr "" +msgstr "%(username)s 引用了 %(book_title)s" #: bookwyrm/templates/discover/discover.html:4 #: bookwyrm/templates/discover/discover.html:10 @@ -971,7 +976,7 @@ msgstr "立即加入" #: bookwyrm/templates/email/invite/html_content.html:15 #, python-format msgid "Learn more about %(site_name)s." -msgstr "" +msgstr "了解更多 关于 %(site_name)s" #: bookwyrm/templates/email/invite/text_content.html:4 #, python-format @@ -981,7 +986,7 @@ msgstr "你受邀请加入 %(site_name)s!点击下面的连接来创建帐号 #: bookwyrm/templates/email/invite/text_content.html:8 #, python-format msgid "Learn more about %(site_name)s:" -msgstr "" +msgstr "进一步了解 %(site_name)s" #: bookwyrm/templates/email/password_reset/html_content.html:6 #: bookwyrm/templates/email/password_reset/text_content.html:4 @@ -990,10 +995,10 @@ msgid "You requested to reset your %(site_name)s password. Click the link below msgstr "你请求重置你在 %(site_name)s 的密码。点击下面的链接来设置新密码并登录你的帐号。" #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" msgstr "重设密码" @@ -1099,7 +1104,7 @@ msgid "What are you reading?" msgstr "你在阅读什么?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "搜索书目" @@ -1117,8 +1122,9 @@ msgstr "你可以在开始使用 %(site_name)s 后添加书目。" #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1134,7 +1140,7 @@ msgid "Popular on %(site_name)s" msgstr "%(site_name)s 上的热门" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "没有找到书目" @@ -1220,9 +1226,108 @@ msgstr "搜索用户" msgid "No users found for \"%(query)s\"" msgstr "没有找到 \"%(query)s\" 的用户" +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "创建群组" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "由 %(username)s 创建并策展" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "删除该群组" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "此操作无法被撤销" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "删除" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "编辑群组" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "添加新成员" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "群组名称" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "群组描述" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "删除群组" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "搜索或添加用户" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "这个群组没有任何列表" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "编辑群组" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "会员可以在群组的书籍列表中添加和删除书" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "退出群组" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "正在关注着你" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s 个你也关注的关注者" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s 本在你书架上也有的书" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "未找到可能的成员 \"%(user_query)s\"" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "管理员" + #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "导入书目" @@ -1319,14 +1424,14 @@ msgid "Book" msgstr "书目" #: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "标题" #: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" @@ -1336,20 +1441,7 @@ msgstr "已导入" #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." -msgstr "" - -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "创建帐号" - -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "没有权限" - -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "抱歉!此邀请码已不再有效。" +msgstr "您可以从 导入/导出页面 下载或导出您的 Goodread 数据。" #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format @@ -1366,6 +1458,20 @@ msgstr "行为准则" msgid "Privacy Policy" msgstr "隐私政策" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "创建帐号" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "没有权限" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "抱歉!此邀请码已不再有效。" + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" msgstr "最近书目" @@ -1404,6 +1510,53 @@ msgstr "谢谢你!我们已经收到了你的请求。" msgid "Your Account" msgstr "你的帐号" +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "登录" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "登录" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "成功!邮箱地址已确认。" + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "用户名:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "密码:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "忘记了密码?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "更多关于本站点的信息" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "确认密码:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "重设你的密码的链接将会被发送到你的邮箱地址" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "重设密码" + #: bookwyrm/templates/layout.html:13 #, python-format msgid "%(site_name)s search" @@ -1451,25 +1604,10 @@ msgstr "登出" msgid "Notifications" msgstr "通知" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "用户名:" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "密码" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "忘记了密码?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "登录" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "加入" @@ -1510,10 +1648,15 @@ msgstr "创建列表" #: bookwyrm/templates/lists/created_text.html:5 #, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "由 %(username)s 创建,由 %(groupname)s 管理" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format msgid "Created and curated by %(username)s" msgstr "由 %(username)s 创建并策展" -#: bookwyrm/templates/lists/created_text.html:7 +#: bookwyrm/templates/lists/created_text.html:9 #, python-format msgid "Created by %(username)s" msgstr "由 %(username)s 创建" @@ -1546,118 +1689,130 @@ msgstr "削除" msgid "Delete this list?" msgstr "删除此列表?" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "此操作无法被撤销" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "删除" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "编辑列表" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" msgstr "列表策展:" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "已关闭" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" msgstr "只有你可以在此列表中添加或移除书目" -#: bookwyrm/templates/lists/form.html:26 +#: bookwyrm/templates/lists/form.html:27 msgid "Curated" msgstr "策展" -#: bookwyrm/templates/lists/form.html:27 +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" msgstr "任何人都可以推荐书目、主题让你批准" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "开放" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" msgstr "任何人都可以向此列表中添加书目" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "组(Group)" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "群组成员可以添加并从列表中移除" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "选择群组" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "选择一个组" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "您目前尚未拥有任何群组!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "创建一个群组" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "删除列表" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" msgstr "你成功向该列表推荐了一本书!" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" msgstr "你成功向此列表添加了一本书!" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "此列表当前是空的" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "由 %(username)s 添加" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "列表位置:" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "设定" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "移除" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "排序列表" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" msgstr "方向" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "添加书目" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "推荐书目" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "搜索" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" msgstr "清除搜索" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" msgstr "没有符合 “%(query)s” 请求的书目" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "推荐" @@ -1669,30 +1824,18 @@ msgstr "已保存" msgid "Your Lists" msgstr "你的列表" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "所有列表" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "保存的列表" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "登录" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." -msgstr "成功!邮箱地址已确认。" - -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "密码:" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "更多关于本站点的信息" +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "接受了您的邀请,加入 \"%(group_name)s\" 群组" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format @@ -1727,22 +1870,22 @@ msgstr "转发了你的 状态" #: bookwyrm/templates/notifications/items/fav.html:19 #, python-format msgid "liked your review of %(book_title)s" -msgstr "" +msgstr "喜欢了你 %(book_title)s 的书评" #: bookwyrm/templates/notifications/items/fav.html:25 #, python-format -msgid "liked your comment on%(book_title)s" -msgstr "" +msgid "liked your comment on %(book_title)s" +msgstr "喜欢了你的 %(book_title)s 的评论" #: bookwyrm/templates/notifications/items/fav.html:31 #, python-format msgid "liked your quote from %(book_title)s" -msgstr "" +msgstr "喜欢了你对 %(book_title)s 的引用" #: bookwyrm/templates/notifications/items/fav.html:37 #, python-format msgid "liked your status" -msgstr "" +msgstr "喜欢了你的 状态" #: bookwyrm/templates/notifications/items/follow.html:15 msgid "followed you" @@ -1757,6 +1900,21 @@ msgstr "向你发送了关注请求" msgid "Your import completed." msgstr "你的 导入 已完成。" +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "邀请您加入群组 \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "已加入您的群組 \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "退出了了您的群组 \"%(group_name)s\"" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" @@ -1777,6 +1935,16 @@ msgstr "在 %(book_title)s 的引用status" msgstr "在 状态 中提到了你" +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "已经从您的群组中将 \"%(group_name)s\" 移除" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "您已经被从 \"%(group_name)s\" 组中移除" + #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" @@ -1802,6 +1970,21 @@ msgstr "回复 了你的 report needs moderation." msgstr "有新的 报告 需要仲裁。" +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "更改了 %(group_name)s的隐私级别" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "更改了 %(group_name)s的名称" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "更改了 %(group_name)s的描述" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" msgstr "删除通知" @@ -1818,20 +2001,6 @@ msgstr "提及" msgid "You're all caught up!" msgstr "你什么也没错过!" -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "确认密码:" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "重设你的密码的链接将会被发送到你的邮箱地址" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "重设密码" - #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 #: bookwyrm/templates/preferences/layout.html:31 @@ -2251,7 +2420,7 @@ msgid "Details" msgstr "详细" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "活动" @@ -2628,7 +2797,7 @@ msgstr "简要描述:" #: bookwyrm/templates/settings/site.html:37 msgid "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." -msgstr "" +msgstr "在 joinbookwyrm.com 上预览实例时使用。不支持 HTML 或 Markdown。" #: bookwyrm/templates/settings/site.html:41 msgid "Code of conduct:" @@ -2827,52 +2996,65 @@ msgstr "创建书架" msgid "Edit Shelf" msgstr "编辑书架" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "所有书目" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "创建书架" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "%(formatted_count)s 本书籍" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" msgstr "(正在显示 %(start)s 到 %(end)s)" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "编辑书架" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "删除书架" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "上架时间" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "开始时间" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "完成时间" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "此书架是空的。" +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "邀请" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "移除邀请" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "移除 @%(username)s" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" @@ -2967,6 +3149,7 @@ msgstr "评论:" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "私密" @@ -3062,6 +3245,7 @@ msgid "Unfollow" msgstr "取消关注" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "接受" @@ -3168,12 +3352,14 @@ msgstr "往后" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "公开" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "不公开" @@ -3182,6 +3368,7 @@ msgid "Followers-only" msgstr "仅关注者" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "发文隐私" @@ -3316,7 +3503,7 @@ msgstr "隐藏状态" #: bookwyrm/templates/snippets/status/header.html:45 #, python-format msgid "edited %(date)s" -msgstr "" +msgstr "在 %(date)s 已编辑" #: bookwyrm/templates/snippets/status/headers/comment.html:2 #, python-format @@ -3382,23 +3569,6 @@ msgstr "转发了" msgid "More options" msgstr "更多选项" -#: bookwyrm/templates/snippets/suggested_users.html:16 -#, python-format -msgid "%(mutuals)s follower you follow" -msgid_plural "%(mutuals)s followers you follow" -msgstr[0] "%(mutuals)s 个你也关注的关注者" - -#: bookwyrm/templates/snippets/suggested_users.html:23 -#, python-format -msgid "%(shared_books)s book on your shelves" -msgid_plural "%(shared_books)s books on your shelves" -msgstr[0] "%(shared_books)s 本在你书架上也有的书" - -#: bookwyrm/templates/snippets/suggested_users.html:31 -#: bookwyrm/templates/user/user_preview.html:36 -msgid "Follows you" -msgstr "正在关注着你" - #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" msgstr "切换到此版本" @@ -3448,18 +3618,35 @@ msgstr "你 %(year)s 的书目" msgid "%(username)s's %(year)s Books" msgstr "%(username)s 在 %(year)s 的书目" -#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10 +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "您的群组" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "群组: %(username)s" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "创建群组" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 msgid "User Profile" msgstr "用户个人资料" -#: bookwyrm/templates/user/layout.html:44 +#: bookwyrm/templates/user/layout.html:45 msgid "Follow Requests" msgstr "关注请求" -#: bookwyrm/templates/user/layout.html:69 +#: bookwyrm/templates/user/layout.html:70 msgid "Reading Goal" msgstr "阅读目标" +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "群组" + #: bookwyrm/templates/user/lists.html:11 #, python-format msgid "Lists: %(username)s" @@ -3548,15 +3735,15 @@ msgstr "%(title)s:%(subtitle)s" msgid "Not a valid csv file" msgstr "不是有效的 csv 文件" -#: bookwyrm/views/login.py:69 +#: bookwyrm/views/landing/login.py:69 msgid "Username or password are incorrect" msgstr "用户名或密码不正确" -#: bookwyrm/views/password.py:32 +#: bookwyrm/views/landing/password.py:32 msgid "No user with that email address was found." msgstr "没有找到使用该邮箱的用户。" -#: bookwyrm/views/password.py:41 +#: bookwyrm/views/landing/password.py:43 #, python-brace-format msgid "A password reset link was sent to {email}" msgstr "密码重置连接已发送给 {email}" diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo index 0bd0ad46e02da915244e3efe4ba13fe687a55bad..1f615988e85b86ceed992fb8f9eeca9fa4068e0d 100644 GIT binary patch delta 20 ccmaF4is|JlrVTHWSdB~+3@tXlO{y^h0Ay+i$p8QV delta 20 ccmaF4is|JlrVTHWSPjh-3{5t_O{y^h0AyMS#sB~S diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 7b9d3b778..cdaa1f81a 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-15 22:03+0000\n" -"PO-Revision-Date: 2021-10-16 14:36\n" +"POT-Creation-Date: 2021-10-24 14:09+0000\n" +"PO-Revision-Date: 2021-10-24 18:36\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Chinese Traditional\n" "Language: zh\n" @@ -46,29 +46,29 @@ msgstr "" msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "列表順序" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "書名" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 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:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "降序" @@ -165,7 +165,7 @@ msgstr "" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "書目" @@ -223,7 +223,7 @@ msgid "Edit Author" msgstr "編輯作者" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "別名:" @@ -276,71 +276,72 @@ msgstr "新增了:" msgid "Updated:" msgstr "更新了:" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "最後編輯者:" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "元資料" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "名稱:" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "請用逗號(,)分隔多個值。" -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "簡介:" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "維基百科連結:" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "出生日期:" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "死亡日期:" -#: bookwyrm/templates/author/edit_author.html:79 +#: bookwyrm/templates/author/edit_author.html:81 msgid "Author Identifiers" msgstr "作者標識號:" -#: bookwyrm/templates/author/edit_author.html:81 +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Openlibrary key:" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "Inventaire ID:" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Librarything key:" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Goodreads key:" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +353,13 @@ msgstr "Goodreads key:" msgid "Save" msgstr "儲存" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -396,7 +399,7 @@ msgstr "新增描述" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "描述:" @@ -459,7 +462,7 @@ msgstr "地點" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "列表" @@ -469,7 +472,7 @@ msgstr "新增到列表" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -542,7 +545,9 @@ msgid "This is a new work" msgstr "這是一個新的作品。" #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "確認" @@ -611,7 +616,7 @@ msgid "John Doe, Jane Smith" msgstr "John Doe, Jane Smith" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "封面" @@ -792,7 +797,7 @@ msgstr "" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" @@ -990,10 +995,10 @@ msgid "You requested to reset your %(site_name)s password. Click the link below msgstr "你請求重置你在 %(site_name)s 的密碼。點選下面的連結來設定新密碼並登入你的帳號。" #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" msgstr "重設密碼" @@ -1099,7 +1104,7 @@ msgid "What are you reading?" msgstr "你在閱讀什麼?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "搜尋書目" @@ -1117,8 +1122,9 @@ msgstr "你可以在開始使用 %(site_name)s 後新增書目。" #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1134,7 +1140,7 @@ msgid "Popular on %(site_name)s" msgstr "%(site_name)s 上的熱門" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "沒有找到書目" @@ -1220,9 +1226,108 @@ msgstr "搜尋使用者" msgid "No users found for \"%(query)s\"" msgstr "沒有找到 \"%(query)s\" 的使用者" +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "刪除" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s 個你也關注的關注者" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s 本在你書架上也有的書" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "" + #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "匯入書目" @@ -1319,14 +1424,14 @@ msgid "Book" msgstr "書目" #: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "標題" #: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" @@ -1338,19 +1443,6 @@ msgstr "已匯入" msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "" -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "建立帳號" - -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "沒有權限" - -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "抱歉!此邀請碼已不再有效。" - #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1366,6 +1458,20 @@ msgstr "行為準則" msgid "Privacy Policy" msgstr "隱私政策" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "建立帳號" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "沒有權限" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "抱歉!此邀請碼已不再有效。" + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" msgstr "最近書目" @@ -1404,6 +1510,53 @@ msgstr "謝謝你!我們已經受到了你的請求。" msgid "Your Account" msgstr "你的帳號" +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "登入" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "登入" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "" + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "使用者名稱:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "密碼:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "忘記了密碼?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "關於本網站的更多" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "確認密碼:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "重設你的密碼的連結將會被發送到你的郵箱地址" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "重設密碼" + #: bookwyrm/templates/layout.html:13 #, python-format msgid "%(site_name)s search" @@ -1451,25 +1604,10 @@ msgstr "登出" msgid "Notifications" msgstr "通知" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "使用者名稱:" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "密碼" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "忘記了密碼?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "登入" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "加入" @@ -1510,10 +1648,15 @@ msgstr "建立列表" #: bookwyrm/templates/lists/created_text.html:5 #, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format msgid "Created and curated by %(username)s" msgstr "由 %(username)s 建立並管理" -#: bookwyrm/templates/lists/created_text.html:7 +#: bookwyrm/templates/lists/created_text.html:9 #, python-format msgid "Created by %(username)s" msgstr "由 %(username)s 建立" @@ -1546,118 +1689,130 @@ msgstr "放棄" msgid "Delete this list?" msgstr "" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "刪除" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "編輯列表" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" msgstr "列表管理:" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "已關閉" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" msgstr "只有你可以在此列表中新增或移除書目" -#: bookwyrm/templates/lists/form.html:26 +#: bookwyrm/templates/lists/form.html:27 msgid "Curated" msgstr "管理" -#: bookwyrm/templates/lists/form.html:27 +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" msgstr "任何人都可以推薦書目、主題,但須經你的批准。" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" msgstr "任何人都可以向此列表新增書目" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" msgstr "你成功!向該列表推薦了一本書" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" msgstr "你成功在此列表新增了一本書!" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "此列表當前是空的" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "由 %(username)s 新增" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "列表位置:" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "設定" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "移除" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "排序列表" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" msgstr "方向" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "新增書目" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "推薦書目" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "搜尋" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" msgstr "清除搜尋" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" msgstr "沒有符合 \"%(query)s\" 請求的書目" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "推薦" @@ -1669,31 +1824,19 @@ msgstr "" msgid "Your Lists" msgstr "你的列表" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "登入" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" msgstr "" -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "密碼:" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "關於本網站的更多" - #: bookwyrm/templates/notifications/items/add.html:24 #, python-format msgid "added %(book_title)s to your list \"%(list_name)s\"" @@ -1731,7 +1874,7 @@ msgstr "" #: bookwyrm/templates/notifications/items/fav.html:25 #, python-format -msgid "liked your comment on%(book_title)s" +msgid "liked your comment on %(book_title)s" msgstr "" #: bookwyrm/templates/notifications/items/fav.html:31 @@ -1757,6 +1900,21 @@ msgstr "向你傳送了關注請求" msgid "Your import completed." msgstr "你的 匯入 已完成。" +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" @@ -1777,6 +1935,16 @@ msgstr "在 %(book_title)s 的引用status" msgstr "在 狀態 中提到了你" +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "" + #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" @@ -1802,6 +1970,21 @@ msgstr "回覆 了你的 report needs moderation." msgstr "有新的 舉報 需要仲裁。" +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" msgstr "刪除通知" @@ -1818,20 +2001,6 @@ msgstr "提及" msgid "You're all caught up!" msgstr "你什麼也沒錯過!" -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "確認密碼:" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "重設你的密碼的連結將會被發送到你的郵箱地址" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "重設密碼" - #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 #: bookwyrm/templates/preferences/layout.html:31 @@ -2251,7 +2420,7 @@ msgid "Details" msgstr "詳細" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "活動" @@ -2827,52 +2996,65 @@ msgstr "建立書架" msgid "Edit Shelf" msgstr "編輯書架" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "所有書目" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "建立書架" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" msgstr "" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "編輯書架" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "刪除書架" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "上架時間" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "開始時間" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "完成時間" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "此書架是空的。" +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" @@ -2967,6 +3149,7 @@ msgstr "評論:" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "私密" @@ -3062,6 +3245,7 @@ msgid "Unfollow" msgstr "取消關注" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "接受" @@ -3168,12 +3352,14 @@ msgstr "往後" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "公開" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "不公開" @@ -3182,6 +3368,7 @@ msgid "Followers-only" msgstr "僅關注者" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "發文隱私" @@ -3382,23 +3569,6 @@ msgstr "轉發了" msgid "More options" msgstr "更多選項" -#: bookwyrm/templates/snippets/suggested_users.html:16 -#, python-format -msgid "%(mutuals)s follower you follow" -msgid_plural "%(mutuals)s followers you follow" -msgstr[0] "%(mutuals)s 個你也關注的關注者" - -#: bookwyrm/templates/snippets/suggested_users.html:23 -#, python-format -msgid "%(shared_books)s book on your shelves" -msgid_plural "%(shared_books)s books on your shelves" -msgstr[0] "%(shared_books)s 本在你書架上也有的書" - -#: bookwyrm/templates/snippets/suggested_users.html:31 -#: bookwyrm/templates/user/user_preview.html:36 -msgid "Follows you" -msgstr "" - #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" msgstr "切換到此版本" @@ -3448,18 +3618,35 @@ msgstr "你 %(year)s 的書目" msgid "%(username)s's %(year)s Books" msgstr "%(username)s 在 %(year)s 的書目" -#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10 +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 msgid "User Profile" msgstr "使用者使用者資料" -#: bookwyrm/templates/user/layout.html:44 +#: bookwyrm/templates/user/layout.html:45 msgid "Follow Requests" msgstr "關注請求" -#: bookwyrm/templates/user/layout.html:69 +#: bookwyrm/templates/user/layout.html:70 msgid "Reading Goal" msgstr "閱讀目標" +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "" + #: bookwyrm/templates/user/lists.html:11 #, python-format msgid "Lists: %(username)s" @@ -3548,15 +3735,15 @@ msgstr "" msgid "Not a valid csv file" msgstr "不是有效的 csv 檔案" -#: bookwyrm/views/login.py:69 +#: bookwyrm/views/landing/login.py:69 msgid "Username or password are incorrect" msgstr "" -#: bookwyrm/views/password.py:32 +#: bookwyrm/views/landing/password.py:32 msgid "No user with that email address was found." msgstr "沒有找到使用該郵箱的使用者。" -#: bookwyrm/views/password.py:41 +#: bookwyrm/views/landing/password.py:43 #, python-brace-format msgid "A password reset link was sent to {email}" msgstr "密碼重置連結已傳送給 {email}" From 1e8269b6c9847df68ea12e1b5d361ac7898b92f2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 13:10:52 -0800 Subject: [PATCH 061/134] Refactors import status view --- bookwyrm/models/import_job.py | 2 +- bookwyrm/templates/import/import_status.html | 161 ++++++------------- bookwyrm/views/import_data.py | 36 +++-- 3 files changed, 75 insertions(+), 124 deletions(-) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 6bca57f88..61b818fe7 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -33,7 +33,7 @@ class ImportJob(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) created_date = models.DateTimeField(default=timezone.now) - task_id = models.CharField(max_length=100, null=True) + task_id = models.CharField(max_length=100, null=True) # TODO: deprecated include_reviews = models.BooleanField(default=True) mappings = models.JSONField() complete = models.BooleanField(default=False) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 91e48e34e..029b081d7 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -6,116 +6,42 @@ {% block title %}{% trans "Import Status" %}{% endblock %} {% block content %}{% spaceless %} -
+

{% trans "Import Status" %}

{% trans "Back to imports" %} - {% if task.failed %} -
{% trans "TASK FAILED" %}
+
+
+
{% trans "Import started:" %}
+
{{ job.created_date | naturaltime }}
+
+
+ + {% if not complete %} +
+
+ + {% trans "In progress" %} + + {% trans "Refresh" %} + +
+
+ {{ percent }}% + {{ percent }}% +
+
{% endif %} - -
-
{% trans "Import started:" %}
-
{{ job.created_date | naturaltime }}
- - {% if job.complete %} -
{% trans "Import completed:" %}
-
{{ task.date_done | naturaltime }}
- {% endif %} -
-
+
- {% if not job.complete %} -

- {% trans "Import still in progress." %} -
- {% trans "(Hit reload to update!)" %} -

- {% endif %} -
- -{% if failed_items %} -
-

{% trans "Failed to load" %}

- {% if not job.retry %} -
- {% csrf_token %} - - {% with failed_count=failed_items|length %} - {% if failed_count > 10 %} -

- - {% blocktrans %}Jump to the bottom of the list to select the {{ failed_count }} items which failed to import.{% endblocktrans %} - -

- {% endif %} - {% endwith %} - -
-
    - {% for item in failed_items %} -
  • - - -
  • - {% endfor %} -
-
- -
- - - - - -
-
- -
- - {% else %} -
    - {% for item in failed_items %} -
  • -

    - Line {{ item.index }}: - {{ item.data.Title }} by - {{ item.data.Author }} -

    -

    - {{ item.fail_reason }}. -

    -
  • - {% endfor %} -
- {% endif %} -
-{% endif %} - -
- {% if job.complete %} -

{% trans "Successfully imported" %}

- {% else %} -

{% trans "Import Progress" %}

- {% endif %} +

+ {% trans "Your Import" %} +

+ {% for item in items %} + {% endfor %}
- {% trans "Book" %} + {% trans "Row" %} {% trans "Title" %} @@ -124,16 +50,16 @@ {% trans "Author" %} + {% trans "Book" %} + + {% trans "Status" %}
- {% if item.book %} - - {% include 'snippets/book_cover.html' with book=item.book cover_class='is-h-s' size='small' %} - - {% endif %} + {{ item.index }} {{ item.data.Title }} @@ -143,15 +69,34 @@ {% if item.book %} - - {% trans "Imported" %} + + {% include 'snippets/book_cover.html' with book=item.book cover_class='is-h-s' size='small' %} + + {% endif %} + + {% if item.book %} + + {% trans "Imported" %} + + {% elif item.fail_reason %} + + + {{ item.fail_reason }} + {% else %} + + {% trans "Pending" %} {% endif %}
+ +
+ {% include 'snippets/pagination.html' with page=items %} +
{% endspaceless %}{% endblock %} {% block scripts %} diff --git a/bookwyrm/views/import_data.py b/bookwyrm/views/import_data.py index 5e113be88..1dc9e6d8c 100644 --- a/bookwyrm/views/import_data.py +++ b/bookwyrm/views/import_data.py @@ -1,8 +1,10 @@ """ import books from another app """ from io import TextIOWrapper +import math from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator from django.http import HttpResponseBadRequest from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse @@ -17,7 +19,7 @@ from bookwyrm.importers import ( GoodreadsImporter, StorygraphImporter, ) -from bookwyrm.tasks import app +from bookwyrm.settings import PAGE_LENGTH # pylint: disable= no-self-use @method_decorator(login_required, name="dispatch") @@ -82,21 +84,25 @@ class ImportStatus(View): if job.user != request.user: raise PermissionDenied() - try: - task = app.AsyncResult(job.task_id) - # triggers attribute error if the task won't load - task.status # pylint: disable=pointless-statement - except (ValueError, AttributeError): - task = None + items = job.items.order_by("index") + pending_items = items.filter(fail_reason__isnull=True, book__isnull=True) + item_count = items.count() or 1 - items = job.items.order_by("index").all() - failed_items = [i for i in items if i.fail_reason] - items = [i for i in items if not i.fail_reason] - return TemplateResponse( - request, - "import/import_status.html", - {"job": job, "items": items, "failed_items": failed_items, "task": task}, - ) + paginated = Paginator(items, PAGE_LENGTH) + page = paginated.get_page(request.GET.get("page")) + data = { + "job": job, + "items": page, + "page_range": paginated.get_elided_page_range( + page.number, on_each_side=2, on_ends=1 + ), + "complete": not pending_items.exists(), + "percent": math.floor( # pylint: disable=c-extension-no-member + (item_count - pending_items.count()) / item_count * 100 + ), + } + + return TemplateResponse(request, "import/import_status.html", data) def post(self, request, job_id): """retry lines from an import""" From 80c1954aa36398b096114816155b7d6ddbdb6afa Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 13:48:31 -0800 Subject: [PATCH 062/134] Fixes first_search_result behavior --- bookwyrm/book_search.py | 5 ++++- bookwyrm/models/import_job.py | 10 ++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py index 6c89b61fb..7b9b12309 100644 --- a/bookwyrm/book_search.py +++ b/bookwyrm/book_search.py @@ -82,6 +82,8 @@ def search_identifiers(query, *filters, return_first=False): *filters, reduce(operator.or_, (Q(**f) for f in or_filters)) ).distinct() if results.count() <= 1: + if return_first: + return results.first() return results # when there are multiple editions of the same work, pick the default. @@ -124,8 +126,9 @@ def search_title_author(query, min_confidence, *filters, return_first=False): result = default else: result = editions.first() + if return_first: - return result + return result[0] list_results.append(result) return list_results diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 61b818fe7..9f011f1ed 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -6,7 +6,7 @@ from django.db import models from django.utils import timezone from bookwyrm.connectors import connector_manager -from bookwyrm.models import ReadThrough, User, Book +from bookwyrm.models import ReadThrough, User, Book, Edition from .fields import PrivacyLevels @@ -79,6 +79,10 @@ class ImportItem(models.Model): self.isbn, min_confidence=0.999 ) if search_result: + # it's already in the right format + if isinstance(search_result, Edition): + return search_result + # it's just a search result, book needs to be created # raises ConnectorException return search_result.connector.get_or_create_book(search_result.key) return None @@ -183,9 +187,7 @@ class ImportItem(models.Model): def __repr__(self): # pylint: disable=consider-using-f-string - return "<{!r}Item {!r}>".format( - self.normalized_data["import_source"], self.normalized_data["title"] - ) + return "<{!r}Item {!r}>".format(self.index, self.normalized_data["title"]) def __str__(self): # pylint: disable=consider-using-f-string From 2a84c0a370e9adcc09d113bdcc831f270e38d36d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 13:59:54 -0800 Subject: [PATCH 063/134] title author search already working correctly with return first --- bookwyrm/book_search.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py index 7b9b12309..e42a6d8c3 100644 --- a/bookwyrm/book_search.py +++ b/bookwyrm/book_search.py @@ -128,7 +128,7 @@ def search_title_author(query, min_confidence, *filters, return_first=False): result = editions.first() if return_first: - return result[0] + return result list_results.append(result) return list_results From a65f07e0bff07493a8045a641fad75f2eda31cc0 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:36:28 -0800 Subject: [PATCH 064/134] Adds retry page --- bookwyrm/templates/import/import_status.html | 16 ++++++++++ bookwyrm/templates/import/troubleshoot.html | 30 +++++++++++++++++++ bookwyrm/urls.py | 1 + bookwyrm/views/__init__.py | 2 +- bookwyrm/views/import_data.py | 31 ++++++++++++++++++-- 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 bookwyrm/templates/import/troubleshoot.html diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 029b081d7..59bebb41a 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -32,12 +32,28 @@ {% endif %} + + {% if complete and fail_count %} +
+ {% blocktrans trimmed count counter=fail_count with display_counter=fail_count|intcomma %} + {{ display_counter }} item failed to import. + {% plural %} + {{ display_counter }} items failed to import. + {% endblocktrans %} + + {% trans "View and troubleshoot failed items." %} + +
+ {% endif %}

+ {% block page_title %} {% trans "Your Import" %} + {% endblock %}

+ {% block actions %}{% endblock %} + @@ -82,10 +85,13 @@ {{ item.index }} + + + + + + + +{% endblock %} + +{% block table_row %} + + + + + + + + + + +{% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 061163a14..1004e30bc 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -243,6 +243,11 @@ urlpatterns = [ views.ImportTroubleshoot.as_view(), name="import-troubleshoot", ), + re_path( + r"^import/(\d+)/review/?$", + views.ImportManualReview.as_view(), + name="import-review", + ), # users re_path(rf"{USER_PATH}\.json$", views.User.as_view()), re_path(rf"{USER_PATH}/?$", views.User.as_view(), name="user-feed"), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 21eeb39b2..9fe09795a 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -46,7 +46,8 @@ from .shelf.shelf_actions import shelve, unshelve # csv import from .imports.import_data import Import from .imports.import_status import ImportStatus -from .imports.troubelshoot import ImportTroubleshoot +from .imports.troubleshoot import ImportTroubleshoot +from .imports.manually_review import ImportManualReview # misc views from .author import Author, EditAuthor diff --git a/bookwyrm/views/imports/import_data.py b/bookwyrm/views/imports/import_data.py index 64cefc7f3..7f6a4d13f 100644 --- a/bookwyrm/views/imports/import_data.py +++ b/bookwyrm/views/imports/import_data.py @@ -10,7 +10,11 @@ from django.utils.translation import gettext_lazy as _ from django.views import View from bookwyrm import forms, models -from bookwyrm.importers import LibrarythingImporter, GoodreadsImporter, StorygraphImporter +from bookwyrm.importers import ( + LibrarythingImporter, + GoodreadsImporter, + StorygraphImporter, +) # pylint: disable= no-self-use @method_decorator(login_required, name="dispatch") diff --git a/bookwyrm/views/imports/manually_review.py b/bookwyrm/views/imports/manually_review.py new file mode 100644 index 000000000..286251d44 --- /dev/null +++ b/bookwyrm/views/imports/manually_review.py @@ -0,0 +1,39 @@ +""" verify books we're unsure about """ +from django.contrib.auth.decorators import login_required +from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator +from django.shortcuts import get_object_or_404 +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import models +from bookwyrm.settings import PAGE_LENGTH + +# pylint: disable= no-self-use +@method_decorator(login_required, name="dispatch") +class ImportManualReview(View): + """problems items in an existing import""" + + def get(self, request, job_id): + """status of an import job""" + job = get_object_or_404(models.ImportJob, id=job_id) + if job.user != request.user: + raise PermissionDenied() + + items = job.items.order_by("index").filter( + book__isnull=True, book_guess__isnull=False + ) + + paginated = Paginator(items, PAGE_LENGTH) + page = paginated.get_page(request.GET.get("page")) + data = { + "job": job, + "items": page, + "page_range": paginated.get_elided_page_range( + page.number, on_each_side=2, on_ends=1 + ), + "complete": True, + } + + return TemplateResponse(request, "import/manual_review.html", data) diff --git a/bookwyrm/views/imports/troubleshoot.py b/bookwyrm/views/imports/troubleshoot.py index 48f2b9986..f637b966b 100644 --- a/bookwyrm/views/imports/troubleshoot.py +++ b/bookwyrm/views/imports/troubleshoot.py @@ -23,7 +23,7 @@ class ImportTroubleshoot(View): raise PermissionDenied() items = job.items.order_by("index").filter( - fail_reason__isnull=False, book_guess__isnull=False + fail_reason__isnull=False, book_guess__isnull=True ) paginated = Paginator(items, PAGE_LENGTH) From 40fff02eec549fffe17b3073ff3cfe194f9abdd7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 17:10:47 -0800 Subject: [PATCH 077/134] Approve or delete import guesses --- bookwyrm/importers/importer.py | 24 +++++++------- bookwyrm/migrations/0114_importjob_source.py | 19 +++++++++++ bookwyrm/models/import_job.py | 6 ++++ bookwyrm/templates/import/import_status.html | 7 ++-- bookwyrm/templates/import/manual_review.html | 19 +++++++++-- bookwyrm/urls.py | 25 ++++++++++++-- bookwyrm/views/__init__.py | 6 +++- bookwyrm/views/imports/manually_review.py | 34 +++++++++++++++++++- 8 files changed, 118 insertions(+), 22 deletions(-) create mode 100644 bookwyrm/migrations/0114_importjob_source.py diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index b895d69a3..6d0f65531 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -15,7 +15,7 @@ logger = logging.getLogger(__name__) class Importer: """Generic class for csv data import from an outside service""" - service = "Unknown" + service = "Import" delimiter = "," encoding = "UTF-8" @@ -50,6 +50,7 @@ class Importer: include_reviews=include_reviews, privacy=privacy, mappings=self.create_row_mappings(csv_reader.fieldnames), + source=self.service, ) for index, entry in rows: @@ -108,16 +109,16 @@ class Importer: @app.task(queue="low_priority") -def start_import_task(source, job_id): +def start_import_task(job_id): """trigger the child tasks for each row""" job = ImportJob.objects.get(id=job_id) # these are sub-tasks so that one big task doesn't use up all the memory in celery for item in job.items.values_list("id", flat=True).all(): - import_item_task.delay(source, item) + import_item_task.delay(item) @app.task(queue="low_priority") -def import_item_task(source, item_id): +def import_item_task(item_id): """resolve a row into a book""" item = models.ImportItem.objects.get(id=item_id) try: @@ -128,17 +129,18 @@ def import_item_task(source, item_id): raise err if item.book: - job = item.job # shelves book and handles reviews - handle_imported_book(source, job.user, item, job.include_reviews, job.privacy) + handle_imported_book(item) else: item.fail_reason = _("Could not find a match for book") item.save() -def handle_imported_book(source, user, item, include_reviews, privacy): +def handle_imported_book(item): """process a csv and then post about it""" + job = item.job + user = job.user if isinstance(item.book, models.Work): item.book = item.book.default_edition if not item.book: @@ -167,7 +169,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy): read.user = user read.save() - if include_reviews and (item.rating or item.review): + if job.include_reviews and (item.rating or item.review): # we don't know the publication date of the review, # but "now" is a bad guess published_date_guess = item.date_read or item.date_added @@ -176,7 +178,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy): review_title = ( "Review of {!r} on {!r}".format( item.book.title, - source, + job.source, ) if item.review else "" @@ -188,7 +190,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy): content=item.review, rating=item.rating, published_date=published_date_guess, - privacy=privacy, + privacy=job.privacy, ) else: # just a rating @@ -197,7 +199,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy): book=item.book, rating=item.rating, published_date=published_date_guess, - privacy=privacy, + privacy=job.privacy, ) # only broadcast this review to other bookwyrm instances review.save(software="bookwyrm", priority=LOW) diff --git a/bookwyrm/migrations/0114_importjob_source.py b/bookwyrm/migrations/0114_importjob_source.py new file mode 100644 index 000000000..3ec1432e3 --- /dev/null +++ b/bookwyrm/migrations/0114_importjob_source.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.5 on 2021-11-13 00:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0113_auto_20211110_2104"), + ] + + operations = [ + migrations.AddField( + model_name="importjob", + name="source", + field=models.CharField(default="Import", max_length=100), + preserve_default=False, + ), + ] diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index aa86910c2..6b8f0b460 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -37,6 +37,7 @@ class ImportJob(models.Model): include_reviews = models.BooleanField(default=True) mappings = models.JSONField() complete = models.BooleanField(default=False) + source = models.CharField(max_length=100) privacy = models.CharField( max_length=255, default="public", choices=PrivacyLevels.choices ) @@ -62,6 +63,11 @@ class ImportItem(models.Model): def resolve(self): """try various ways to lookup a book""" + # we might be calling this after manually adding the book, + # so no need to do searches + if self.book: + return + if self.isbn: self.book = self.get_book_from_isbn() else: diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index b2e21d22c..12465bd73 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -40,10 +40,11 @@ {% if manual_review_count %}
{% blocktrans trimmed count counter=manual_review_count with display_counter=manual_review_count|intcomma %} - {{ display_counter }} item needs manual review. + {{ display_counter }} item needs manual approval. {% plural %} - {{ display_counter }} items need manual review. + {{ display_counter }} items need manual approval. {% endblocktrans %} + {% trans "Review items" %}
{% endif %} @@ -55,7 +56,7 @@ {{ display_counter }} items failed to import. {% endblocktrans %} - {% trans "View and troubleshoot failed items." %} + {% trans "View and troubleshoot failed items" %} {% endif %} diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index c9c038698..30274ca02 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -52,9 +52,22 @@
- diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 1004e30bc..d6a79c202 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -237,17 +237,36 @@ urlpatterns = [ re_path(r"^search/?$", views.Search.as_view(), name="search"), # imports re_path(r"^import/?$", views.Import.as_view(), name="import"), - re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"), re_path( - r"^import/(\d+)/failed/?$", + r"^import/(?P\d+)/?$", + views.ImportStatus.as_view(), + name="import-status", + ), + re_path( + r"^import/(?P\d+)/failed/?$", views.ImportTroubleshoot.as_view(), name="import-troubleshoot", ), re_path( - r"^import/(\d+)/review/?$", + r"^import/(?P\d+)/review/?$", views.ImportManualReview.as_view(), name="import-review", ), + re_path( + r"^import/(?P\d+)/review/?$", + views.ImportManualReview.as_view(), + name="import-review", + ), + re_path( + r"^import/(?P\d+)/review/(?P\d+)/approve/?$", + views.approve_import_item, + name="import-approve", + ), + re_path( + r"^import/(?P\d+)/review/(?P\d+)/delete/?$", + views.delete_import_item, + name="import-delete", + ), # users re_path(rf"{USER_PATH}\.json$", views.User.as_view()), re_path(rf"{USER_PATH}/?$", views.User.as_view(), name="user-feed"), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 9fe09795a..1a6fbdc69 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -47,7 +47,11 @@ from .shelf.shelf_actions import shelve, unshelve from .imports.import_data import Import from .imports.import_status import ImportStatus from .imports.troubleshoot import ImportTroubleshoot -from .imports.manually_review import ImportManualReview +from .imports.manually_review import ( + ImportManualReview, + approve_import_item, + delete_import_item, +) # misc views from .author import Author, EditAuthor diff --git a/bookwyrm/views/imports/manually_review.py b/bookwyrm/views/imports/manually_review.py index 286251d44..877e3ffc9 100644 --- a/bookwyrm/views/imports/manually_review.py +++ b/bookwyrm/views/imports/manually_review.py @@ -2,12 +2,14 @@ from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.core.paginator import Paginator -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.http import require_POST from bookwyrm import models +from bookwyrm.importers.importer import import_item_task from bookwyrm.settings import PAGE_LENGTH # pylint: disable= no-self-use @@ -37,3 +39,33 @@ class ImportManualReview(View): } return TemplateResponse(request, "import/manual_review.html", data) + + +@login_required +@require_POST +# pylint: disable=unused-argument +def approve_import_item(request, job_id, item_id): + """we guessed right""" + item = get_object_or_404( + models.ImportItem, id=item_id, job__id=job_id, book_guess__isnull=False + ) + item.fail_reason = None + item.book = item.book_guess + item.save() + + # the good stuff - actually import the data + import_item_task.delay(item.id) + return redirect("import-review", job_id) + + +@login_required +@require_POST +# pylint: disable=unused-argument +def delete_import_item(request, job_id, item_id): + """we guessed right""" + item = get_object_or_404( + models.ImportItem, id=item_id, job__id=job_id, book_guess__isnull=False + ) + item.book_guess = None + item.save() + return redirect("import-review", job_id) From 08f4ad6cd47e1804c95259c19397c297e9857a19 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:02:42 -0800 Subject: [PATCH 078/134] Fixes call to import task --- bookwyrm/importers/importer.py | 4 ++-- bookwyrm/tests/importers/test_importer.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 6d0f65531..4908e166a 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -101,9 +101,9 @@ class Importer: self.create_item(job, item.index, item.data) return job - def start_import(self, job): + def start_import(self, job): # pylint: disable=no-self-use """initalizes a csv import job""" - result = start_import_task.delay(self.service, job.id) + result = start_import_task.delay(job.id) job.task_id = result.id job.save() diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 963eca54e..b0863fbe1 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -120,7 +120,7 @@ class GenericImporter(TestCase): ) with patch("bookwyrm.importers.importer.import_item_task.delay") as mock: - start_import_task(self.importer.service, import_job.id) + start_import_task(import_job.id) self.assertEqual(mock.call_count, 4) From c245ad09bba4350b92c572bc8fc08eca0faa0a0e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:07:50 -0800 Subject: [PATCH 079/134] Make sure book is in the right format --- bookwyrm/importers/importer.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 4908e166a..71f02231c 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -145,6 +145,8 @@ def handle_imported_book(item): item.book = item.book.default_edition if not item.book: return + if not isinstance(item.book, models.Edition): + item.book = item.book.edition existing_shelf = models.ShelfBook.objects.filter(book=item.book, user=user).exists() From acc32d579e24c70ac1a46394d8c9bc2d8b11ce38 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:22:35 -0800 Subject: [PATCH 080/134] Preview review in import preview --- bookwyrm/templates/import/import_status.html | 7 ++++ bookwyrm/templates/import/manual_review.html | 39 ++++++++++++-------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 12465bd73..0a3c9b472 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -84,6 +84,9 @@ + @@ -107,6 +110,10 @@ + + @@ -52,22 +55,28 @@ - + From 60fb1ac2e6fd09da622de64cbecbc87126455408 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:34:10 -0800 Subject: [PATCH 081/134] More flexible templates --- bookwyrm/templates/import/import_status.html | 17 ++++++-- bookwyrm/templates/import/manual_review.html | 44 ++++---------------- 2 files changed, 22 insertions(+), 39 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 0a3c9b472..6c5560dcf 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -70,7 +70,6 @@ {% block actions %}{% endblock %}
diff --git a/bookwyrm/templates/import/troubleshoot.html b/bookwyrm/templates/import/troubleshoot.html new file mode 100644 index 000000000..9b9b48278 --- /dev/null +++ b/bookwyrm/templates/import/troubleshoot.html @@ -0,0 +1,30 @@ +{% extends 'import/import_status.html' %} +{% load i18n %} + +{% block title %}{% trans "Import Troubleshooting" %}{% endblock %} + +{% block page_title %} +{% trans "Failed items" %} +{% endblock %} + +{% block actions %} +
+
+

+ {% trans "Re-trying an import can fix missing items in cases such as:" %} +

    +
  • {% trans "The book has been added to the instance since this import" %}
  • +
  • {% trans "A transient error or timeout caused the external data source to be unavailable." %}
  • +
  • {% trans "BookWyrm has been updated since this import with a bug fix" %}
  • +
+

+

+ {% trans "Contact your admin or open an issue if you are seeing unexpected failed items." %} +

+
+
+ {% csrf_token %} + +
+
+{% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 839d783fd..350d60185 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -238,6 +238,7 @@ urlpatterns = [ # imports re_path(r"^import/?$", views.Import.as_view(), name="import"), re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"), + re_path(r"^import/(\d+)/failed/?$", views.ImportTroubleshoot.as_view(), name="import-troubleshoot"), # users re_path(rf"{USER_PATH}\.json$", views.User.as_view()), re_path(rf"{USER_PATH}/?$", views.User.as_view(), name="user-feed"), diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index e1dd83557..645b13074 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -62,7 +62,7 @@ from .group import ( accept_membership, reject_membership, ) -from .import_data import Import, ImportStatus +from .import_data import Import, ImportStatus, ImportTroubleshoot from .inbox import Inbox from .interaction import Favorite, Unfavorite, Boost, Unboost from .isbn import Isbn diff --git a/bookwyrm/views/import_data.py b/bookwyrm/views/import_data.py index 1dc9e6d8c..e0e90c2d8 100644 --- a/bookwyrm/views/import_data.py +++ b/bookwyrm/views/import_data.py @@ -93,6 +93,7 @@ class ImportStatus(View): data = { "job": job, "items": page, + "fail_count": items.filter(fail_reason__isnull=False).count(), "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), @@ -104,12 +105,36 @@ class ImportStatus(View): return TemplateResponse(request, "import/import_status.html", data) + +@method_decorator(login_required, name="dispatch") +class ImportTroubleshoot(View): + """problems items in an existing import""" + + def get(self, request, job_id): + """status of an import job""" + job = get_object_or_404(models.ImportJob, id=job_id) + if job.user != request.user: + raise PermissionDenied() + + items = job.items.order_by("index").filter(fail_reason__isnull=False) + + paginated = Paginator(items, PAGE_LENGTH) + page = paginated.get_page(request.GET.get("page")) + data = { + "job": job, + "items": page, + "page_range": paginated.get_elided_page_range( + page.number, on_each_side=2, on_ends=1 + ), + "complete": True, + } + + return TemplateResponse(request, "import/troubleshoot.html", data) + def post(self, request, job_id): """retry lines from an import""" job = get_object_or_404(models.ImportJob, id=job_id) - items = [] - for item in request.POST.getlist("import_item"): - items.append(get_object_or_404(models.ImportItem, id=item)) + items = job.items.filter(fail_reason__isnull=False) importer = Importer() job = importer.create_retry_job( From d8197cdcfab9bea1243d5a4d57bfad46c05dab01 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:38:41 -0800 Subject: [PATCH 065/134] Indicate retry on status page --- bookwyrm/templates/import/import_status.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 59bebb41a..ac8fead08 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -7,7 +7,11 @@ {% block content %}{% spaceless %}
+ {% if job.retry %} +

{% trans "Retry Status" %}

+ {% else %}

{% trans "Import Status" %}

+ {% endif %} {% trans "Back to imports" %}
@@ -33,7 +37,7 @@
{% endif %} - {% if complete and fail_count %} + {% if complete and fail_count and not job.retry %}
{% blocktrans trimmed count counter=fail_count with display_counter=fail_count|intcomma %} {{ display_counter }} item failed to import. From 60c777ed495c4d37ea615c2c1b258926f1335bcd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:41:25 -0800 Subject: [PATCH 066/134] Updates tests --- bookwyrm/tests/views/test_import.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/test_import.py index 54f11f038..4a6a8237e 100644 --- a/bookwyrm/tests/views/test_import.py +++ b/bookwyrm/tests/views/test_import.py @@ -51,6 +51,19 @@ class ImportViews(TestCase): validate_html(result.render()) self.assertEqual(result.status_code, 200) + def test_import_troubleshoot_get(self): + """there are so many views, this just makes sure it LOADS""" + view = views.ImportTroubleshoot.as_view() + import_job = models.ImportJob.objects.create(user=self.local_user, mappings={}) + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.tasks.app.AsyncResult") as async_result: + async_result.return_value = [] + result = view(request, import_job.id) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + self.assertEqual(result.status_code, 200) + def test_start_import(self): """retry failed items""" view = views.Import.as_view() @@ -77,7 +90,7 @@ class ImportViews(TestCase): def test_retry_import(self): """retry failed items""" - view = views.ImportStatus.as_view() + view = views.ImportTroubleshoot.as_view() import_job = models.ImportJob.objects.create( user=self.local_user, privacy="unlisted", mappings={} ) From e09c02017c7efb041c410668b042e52a88e26e2e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:46:39 -0800 Subject: [PATCH 067/134] Fixes title/author search handling --- bookwyrm/models/import_job.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 9f011f1ed..aa86910c2 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -94,6 +94,8 @@ class ImportItem(models.Model): search_term, min_confidence=0.1 ) if search_result: + if isinstance(search_result, Edition): + return (search_result, 1) # raises ConnectorException return ( search_result.connector.get_or_create_book(search_result.key), From 61eaf513105f7e413a81312d30c667e00f976b44 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:49:24 -0800 Subject: [PATCH 068/134] Fixes html validity --- bookwyrm/templates/import/troubleshoot.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bookwyrm/templates/import/troubleshoot.html b/bookwyrm/templates/import/troubleshoot.html index 9b9b48278..0be683832 100644 --- a/bookwyrm/templates/import/troubleshoot.html +++ b/bookwyrm/templates/import/troubleshoot.html @@ -12,12 +12,12 @@

{% trans "Re-trying an import can fix missing items in cases such as:" %} -

    -
  • {% trans "The book has been added to the instance since this import" %}
  • -
  • {% trans "A transient error or timeout caused the external data source to be unavailable." %}
  • -
  • {% trans "BookWyrm has been updated since this import with a bug fix" %}
  • -

+
    +
  • {% trans "The book has been added to the instance since this import" %}
  • +
  • {% trans "A transient error or timeout caused the external data source to be unavailable." %}
  • +
  • {% trans "BookWyrm has been updated since this import with a bug fix" %}
  • +

{% trans "Contact your admin or open an issue if you are seeing unexpected failed items." %}

From 6161f60695dced0368c92482369df27f1b359281 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 14:54:20 -0800 Subject: [PATCH 069/134] Use normalized data in table --- bookwyrm/templates/import/import_status.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index ac8fead08..5674aace6 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -66,6 +66,9 @@
{% trans "Title" %} + {% trans "ISBN" %} + {% trans "Author" %} - {{ item.data.Title }} + {{ item.normalized_data.title }} - {{ item.data.Author }} + {{ item.isbn }} + + {{ item.normalized_data.authors }} {% if item.book %} From 1d0f6d5243bca717e489dda97e20e921d89f9126 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:06:23 -0800 Subject: [PATCH 070/134] Python formatting --- bookwyrm/urls.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 350d60185..061163a14 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -238,7 +238,11 @@ urlpatterns = [ # imports re_path(r"^import/?$", views.Import.as_view(), name="import"), re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"), - re_path(r"^import/(\d+)/failed/?$", views.ImportTroubleshoot.as_view(), name="import-troubleshoot"), + re_path( + r"^import/(\d+)/failed/?$", + views.ImportTroubleshoot.as_view(), + name="import-troubleshoot", + ), # users re_path(rf"{USER_PATH}\.json$", views.User.as_view()), re_path(rf"{USER_PATH}/?$", views.User.as_view(), name="user-feed"), From b784dcdb46b70cf4f9e4567f27eae3dadea0aab7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:07:26 -0800 Subject: [PATCH 071/134] Removes uninformative test --- .../tests/importers/test_storygraph_import.py | 25 ------------------- 1 file changed, 25 deletions(-) diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index 8002a3e10..fdad5c71d 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -1,5 +1,4 @@ """ testing import """ -import csv import pathlib from unittest.mock import patch import datetime @@ -59,30 +58,6 @@ class StorygraphImport(TestCase): ) self.assertEqual(import_items[1].normalized_data["rating"], "5.0") - def test_create_retry_job(self, *_): - """trying again with items that didn't import""" - import_job = self.importer.create_job( - self.local_user, self.csv, False, "unlisted" - ) - import_items = models.ImportItem.objects.filter(job=import_job).all()[:2] - - retry = self.importer.create_retry_job( - self.local_user, import_job, import_items - ) - self.assertNotEqual(import_job, retry) - self.assertEqual(retry.user, self.local_user) - self.assertEqual(retry.include_reviews, False) - self.assertEqual(retry.privacy, "unlisted") - - retry_items = models.ImportItem.objects.filter(job=retry).all() - self.assertEqual(len(retry_items), 2) - self.assertEqual(retry_items[0].index, 0) - self.assertEqual(retry_items[0].normalized_data["title"], "Always Coming Home") - self.assertEqual(retry_items[1].index, 1) - self.assertEqual( - retry_items[1].normalized_data["title"], "Subprime Attention Crisis" - ) - def test_handle_imported_book(self, *_): """storygraph import added a book, this adds related connections""" shelf = self.local_user.shelf_set.filter(identifier="to-read").first() From 6a5a5983452769972c8a7a915060f7b9f67886c0 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:17:01 -0800 Subject: [PATCH 072/134] Raise errors when import items fail This should make is way easier to debug --- bookwyrm/importers/importer.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index b32e2df70..b895d69a3 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -123,10 +123,9 @@ def import_item_task(source, item_id): try: item.resolve() except Exception as err: # pylint: disable=broad-except - logger.exception(err) item.fail_reason = _("Error loading book") item.save() - return + raise err if item.book: job = item.job From 5558ed810ead73e34fb41d9ae76a7d1016465c84 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:34:48 -0800 Subject: [PATCH 073/134] Show manual review flag --- bookwyrm/templates/import/import_status.html | 10 ++++++++++ bookwyrm/views/import_data.py | 11 +++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 5674aace6..01a1fec6b 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -37,6 +37,16 @@ {% endif %} + {% if manual_review_count %} +
+ {% blocktrans trimmed count counter=manual_review_count with display_counter=manual_review_count|intcomma %} + {{ display_counter }} item needs manual review. + {% plural %} + {{ display_counter }} items need manual review. + {% endblocktrans %} +
+ {% endif %} + {% if complete and fail_count and not job.retry %}
{% blocktrans trimmed count counter=fail_count with display_counter=fail_count|intcomma %} diff --git a/bookwyrm/views/import_data.py b/bookwyrm/views/import_data.py index e0e90c2d8..907c77e20 100644 --- a/bookwyrm/views/import_data.py +++ b/bookwyrm/views/import_data.py @@ -93,7 +93,12 @@ class ImportStatus(View): data = { "job": job, "items": page, - "fail_count": items.filter(fail_reason__isnull=False).count(), + "manual_review_count": items.filter( + fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True + ).count(), + "fail_count": items.filter( + fail_reason__isnull=False, book_guess__isnull=True + ).count(), "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), @@ -116,7 +121,9 @@ class ImportTroubleshoot(View): if job.user != request.user: raise PermissionDenied() - items = job.items.order_by("index").filter(fail_reason__isnull=False) + items = job.items.order_by("index").filter( + fail_reason__isnull=False, book_guess__isnull=False + ) paginated = Paginator(items, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) From be26e8363a7d9d5dada60b3fbda1bbaaf16f677f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:43:15 -0800 Subject: [PATCH 074/134] Create import directory --- bookwyrm/views/__init__.py | 4 +++- bookwyrm/views/imports/__init__.py | 0 bookwyrm/views/{ => imports}/import_data.py | 0 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/views/imports/__init__.py rename bookwyrm/views/{ => imports}/import_data.py (100%) diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 645b13074..d169d1263 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -43,6 +43,9 @@ from .shelf.shelf import Shelf from .shelf.shelf_actions import create_shelf, delete_shelf from .shelf.shelf_actions import shelve, unshelve +# csv import +from .imports.import_data import Import, ImportStatus, ImportTroubleshoot + # misc views from .author import Author, EditAuthor from .directory import Directory @@ -62,7 +65,6 @@ from .group import ( accept_membership, reject_membership, ) -from .import_data import Import, ImportStatus, ImportTroubleshoot from .inbox import Inbox from .interaction import Favorite, Unfavorite, Boost, Unboost from .isbn import Isbn diff --git a/bookwyrm/views/imports/__init__.py b/bookwyrm/views/imports/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bookwyrm/views/import_data.py b/bookwyrm/views/imports/import_data.py similarity index 100% rename from bookwyrm/views/import_data.py rename to bookwyrm/views/imports/import_data.py From 9bff27e61f2106ad9709e7907b0680fd4fdbe9e0 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 15:50:33 -0800 Subject: [PATCH 075/134] Separate import classes into files --- bookwyrm/views/__init__.py | 4 +- bookwyrm/views/imports/import_data.py | 92 +------------------------ bookwyrm/views/imports/import_status.py | 50 ++++++++++++++ bookwyrm/views/imports/troubleshoot.py | 54 +++++++++++++++ 4 files changed, 109 insertions(+), 91 deletions(-) create mode 100644 bookwyrm/views/imports/import_status.py create mode 100644 bookwyrm/views/imports/troubleshoot.py diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index d169d1263..21eeb39b2 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -44,7 +44,9 @@ from .shelf.shelf_actions import create_shelf, delete_shelf from .shelf.shelf_actions import shelve, unshelve # csv import -from .imports.import_data import Import, ImportStatus, ImportTroubleshoot +from .imports.import_data import Import +from .imports.import_status import ImportStatus +from .imports.troubelshoot import ImportTroubleshoot # misc views from .author import Author, EditAuthor diff --git a/bookwyrm/views/imports/import_data.py b/bookwyrm/views/imports/import_data.py index 907c77e20..64cefc7f3 100644 --- a/bookwyrm/views/imports/import_data.py +++ b/bookwyrm/views/imports/import_data.py @@ -1,25 +1,16 @@ """ import books from another app """ from io import TextIOWrapper -import math from django.contrib.auth.decorators import login_required -from django.core.exceptions import PermissionDenied -from django.core.paginator import Paginator from django.http import HttpResponseBadRequest -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import redirect from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.utils.translation import gettext_lazy as _ from django.views import View from bookwyrm import forms, models -from bookwyrm.importers import ( - Importer, - LibrarythingImporter, - GoodreadsImporter, - StorygraphImporter, -) -from bookwyrm.settings import PAGE_LENGTH +from bookwyrm.importers import LibrarythingImporter, GoodreadsImporter, StorygraphImporter # pylint: disable= no-self-use @method_decorator(login_required, name="dispatch") @@ -72,82 +63,3 @@ class Import(View): return redirect(f"/import/{job.id}") return HttpResponseBadRequest() - - -@method_decorator(login_required, name="dispatch") -class ImportStatus(View): - """status of an existing import""" - - def get(self, request, job_id): - """status of an import job""" - job = get_object_or_404(models.ImportJob, id=job_id) - if job.user != request.user: - raise PermissionDenied() - - items = job.items.order_by("index") - pending_items = items.filter(fail_reason__isnull=True, book__isnull=True) - item_count = items.count() or 1 - - paginated = Paginator(items, PAGE_LENGTH) - page = paginated.get_page(request.GET.get("page")) - data = { - "job": job, - "items": page, - "manual_review_count": items.filter( - fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True - ).count(), - "fail_count": items.filter( - fail_reason__isnull=False, book_guess__isnull=True - ).count(), - "page_range": paginated.get_elided_page_range( - page.number, on_each_side=2, on_ends=1 - ), - "complete": not pending_items.exists(), - "percent": math.floor( # pylint: disable=c-extension-no-member - (item_count - pending_items.count()) / item_count * 100 - ), - } - - return TemplateResponse(request, "import/import_status.html", data) - - -@method_decorator(login_required, name="dispatch") -class ImportTroubleshoot(View): - """problems items in an existing import""" - - def get(self, request, job_id): - """status of an import job""" - job = get_object_or_404(models.ImportJob, id=job_id) - if job.user != request.user: - raise PermissionDenied() - - items = job.items.order_by("index").filter( - fail_reason__isnull=False, book_guess__isnull=False - ) - - paginated = Paginator(items, PAGE_LENGTH) - page = paginated.get_page(request.GET.get("page")) - data = { - "job": job, - "items": page, - "page_range": paginated.get_elided_page_range( - page.number, on_each_side=2, on_ends=1 - ), - "complete": True, - } - - return TemplateResponse(request, "import/troubleshoot.html", data) - - def post(self, request, job_id): - """retry lines from an import""" - job = get_object_or_404(models.ImportJob, id=job_id) - items = job.items.filter(fail_reason__isnull=False) - - importer = Importer() - job = importer.create_retry_job( - request.user, - job, - items, - ) - importer.start_import(job) - return redirect(f"/import/{job.id}") diff --git a/bookwyrm/views/imports/import_status.py b/bookwyrm/views/imports/import_status.py new file mode 100644 index 000000000..2d18d656a --- /dev/null +++ b/bookwyrm/views/imports/import_status.py @@ -0,0 +1,50 @@ +""" import books from another app """ +import math + +from django.contrib.auth.decorators import login_required +from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator +from django.shortcuts import get_object_or_404 +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import models +from bookwyrm.settings import PAGE_LENGTH + +# pylint: disable= no-self-use +@method_decorator(login_required, name="dispatch") +class ImportStatus(View): + """status of an existing import""" + + def get(self, request, job_id): + """status of an import job""" + job = get_object_or_404(models.ImportJob, id=job_id) + if job.user != request.user: + raise PermissionDenied() + + items = job.items.order_by("index") + pending_items = items.filter(fail_reason__isnull=True, book__isnull=True) + item_count = items.count() or 1 + + paginated = Paginator(items, PAGE_LENGTH) + page = paginated.get_page(request.GET.get("page")) + data = { + "job": job, + "items": page, + "manual_review_count": items.filter( + fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True + ).count(), + "fail_count": items.filter( + fail_reason__isnull=False, book_guess__isnull=True + ).count(), + "page_range": paginated.get_elided_page_range( + page.number, on_each_side=2, on_ends=1 + ), + "complete": not pending_items.exists(), + "percent": math.floor( # pylint: disable=c-extension-no-member + (item_count - pending_items.count()) / item_count * 100 + ), + } + + return TemplateResponse(request, "import/import_status.html", data) diff --git a/bookwyrm/views/imports/troubleshoot.py b/bookwyrm/views/imports/troubleshoot.py new file mode 100644 index 000000000..48f2b9986 --- /dev/null +++ b/bookwyrm/views/imports/troubleshoot.py @@ -0,0 +1,54 @@ +""" import books from another app """ +from django.contrib.auth.decorators import login_required +from django.core.exceptions import PermissionDenied +from django.core.paginator import Paginator +from django.shortcuts import get_object_or_404, redirect +from django.template.response import TemplateResponse +from django.utils.decorators import method_decorator +from django.views import View + +from bookwyrm import models +from bookwyrm.importers import Importer +from bookwyrm.settings import PAGE_LENGTH + +# pylint: disable= no-self-use +@method_decorator(login_required, name="dispatch") +class ImportTroubleshoot(View): + """problems items in an existing import""" + + def get(self, request, job_id): + """status of an import job""" + job = get_object_or_404(models.ImportJob, id=job_id) + if job.user != request.user: + raise PermissionDenied() + + items = job.items.order_by("index").filter( + fail_reason__isnull=False, book_guess__isnull=False + ) + + paginated = Paginator(items, PAGE_LENGTH) + page = paginated.get_page(request.GET.get("page")) + data = { + "job": job, + "items": page, + "page_range": paginated.get_elided_page_range( + page.number, on_each_side=2, on_ends=1 + ), + "complete": True, + } + + return TemplateResponse(request, "import/troubleshoot.html", data) + + def post(self, request, job_id): + """retry lines from an import""" + job = get_object_or_404(models.ImportJob, id=job_id) + items = job.items.filter(fail_reason__isnull=False) + + importer = Importer() + job = importer.create_retry_job( + request.user, + job, + items, + ) + importer.start_import(job) + return redirect(f"/import/{job.id}") From 221cde9be4a8e33d617326c508f52b309b545109 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 12 Nov 2021 16:23:56 -0800 Subject: [PATCH 076/134] Adds manual review view --- bookwyrm/templates/import/import_status.html | 4 ++ bookwyrm/templates/import/manual_review.html | 76 ++++++++++++++++++++ bookwyrm/urls.py | 5 ++ bookwyrm/views/__init__.py | 3 +- bookwyrm/views/imports/import_data.py | 6 +- bookwyrm/views/imports/manually_review.py | 39 ++++++++++ bookwyrm/views/imports/troubleshoot.py | 2 +- 7 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 bookwyrm/templates/import/manual_review.html create mode 100644 bookwyrm/views/imports/manually_review.py diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 01a1fec6b..b2e21d22c 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -69,6 +69,7 @@ {% block actions %}{% endblock %} + {% block table_headers %} + {% endblock %} {% for item in items %} + {% block table_row %} + {% endblock %} {% endfor %}
{% trans "Row" %} @@ -89,7 +90,9 @@ {% trans "Status" %}
{{ item.index }} @@ -126,6 +129,7 @@ {% endif %}
diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html new file mode 100644 index 000000000..c9c038698 --- /dev/null +++ b/bookwyrm/templates/import/manual_review.html @@ -0,0 +1,76 @@ +{% extends 'import/import_status.html' %} +{% load i18n %} +{% load utilities %} + +{% block title %}{% trans "Import Troubleshooting" %}{% endblock %} + +{% block page_title %} +{% trans "Review items" %} +{% endblock %} + +{% block actions %} +
+
+

+ {% trans "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book." %} +

+
+
+{% endblock %} + +{% block table_headers %} +
+ {% trans "Row" %} + + {% trans "Title" %} + + {% trans "ISBN" %} + + {% trans "Author" %} + + {% trans "Actions" %} +
+ {{ item.index }} + + {{ item.normalized_data.title }} + + {{ item.isbn }} + + {{ item.normalized_data.authors }} + + + +
+
+ {% with guess=item.book_guess %} + +
+ {% include 'snippets/book_titleby.html' with book=guess %} +
+ {% endwith %} +
+
{{ item.normalized_data.authors }} - - + +
+ {% csrf_token %} + +
+ +
+ {% csrf_token %} + +
{% trans "Author" %} + {% trans "Review" %} + {% trans "Book" %} {{ item.normalized_data.authors }} +

{% include 'snippets/stars.html' with rating=item.rating %}

+

{{ item.review|truncatechars:100 }}

+
{% if item.book %} diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index 30274ca02..b7c8e3b97 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -32,6 +32,9 @@ {% trans "Author" %} + {% trans "Review" %} + {% trans "Actions" %} {{ item.normalized_data.authors }} -
- {% csrf_token %} - -
+
+

{% include 'snippets/stars.html' with rating=item.rating %}

+

{{ item.review|truncatechars:100 }}

+
+
+
+ {% csrf_token %} + +
-
- {% csrf_token %} - -
+
+ {% csrf_token %} + +
+
- {% block table_headers %} + + {% block import_cols_headers %} + {% endblock %} - {% endblock %} {% for item in items %} - {% block table_row %} + {% block index_col %} + {% endblock %} @@ -110,10 +114,14 @@ + + {% block import_cols %} + {% endblock %} - {% endblock %} + {% block action_row %}{% endblock %} {% endfor %}
{% trans "Row" %} @@ -84,23 +83,28 @@ {% trans "Author" %} + {% trans "Shelf" %} + {% trans "Review" %} {% trans "Book" %} {% trans "Status" %}
{{ item.index }} {{ item.normalized_data.title }} {{ item.normalized_data.authors }} + {{ item.normalized_data.shelf }} +

{% include 'snippets/stars.html' with rating=item.rating %}

{{ item.review|truncatechars:100 }}

{% if item.book %} @@ -136,8 +144,9 @@ {% trans "Pending" %} {% endif %}
diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index b7c8e3b97..833e9d7fa 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -18,47 +18,19 @@ {% endblock %} -{% block table_headers %} - - - {% trans "Row" %} - - - {% trans "Title" %} - - - {% trans "ISBN" %} - - - {% trans "Author" %} - - - {% trans "Review" %} - +{% block import_cols_headers %} {% trans "Actions" %} - {% endblock %} -{% block table_row %} - +{% block index_col %} {{ item.index }} - - {{ item.normalized_data.title }} - - - {{ item.isbn }} - - - {{ item.normalized_data.authors }} - - -

{% include 'snippets/stars.html' with rating=item.rating %}

-

{{ item.review|truncatechars:100 }}

- +{% endblock %} + +{% block import_cols %}
@@ -78,9 +50,11 @@
- +{% endblock %} + +{% block action_row %} - +
{% with guess=item.book_guess %}
From 659d0f19ebdcbd4a5965abde30cefae5aab0d8b2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:43:52 -0800 Subject: [PATCH 082/134] Improves import table ui adds table container, plays with display a bit --- bookwyrm/templates/import/import_status.html | 164 ++++++++++--------- bookwyrm/templates/import/manual_review.html | 41 ++--- 2 files changed, 103 insertions(+), 102 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 6c5560dcf..5b33f3947 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -69,86 +69,92 @@ {% endblock %}

{% block actions %}{% endblock %} - - - - - - - - - {% block import_cols_headers %} - - - {% endblock %} - - {% for item in items %} - - {% block index_col %} - - {% endblock %} - - - - - - {% block import_cols %} - - + {% endblock %} + + {% block action_row %}{% endblock %} + {% endfor %} +
- {% trans "Row" %} - - {% trans "Title" %} - - {% trans "ISBN" %} - - {% trans "Author" %} - - {% trans "Shelf" %} - - {% trans "Review" %} - - {% trans "Book" %} - - {% trans "Status" %} -
- {{ item.index }} - - {{ item.normalized_data.title }} - - {{ item.isbn }} - - {{ item.normalized_data.authors }} - - {{ item.normalized_data.shelf }} - -

{% include 'snippets/stars.html' with rating=item.rating %}

-

{{ item.review|truncatechars:100 }}

-
- {% if item.book %} - - {% include 'snippets/book_cover.html' with book=item.book cover_class='is-h-s' size='small' %} - - {% endif %} - - {% if item.book %} - - {% trans "Imported" %} +
+ + + + + + + + + {% block import_cols_headers %} + + + {% endblock %} + + {% for item in items %} + + {% block index_col %} + + {% endblock %} + + + + + + {% block import_cols %} + + - {% endblock %} - - {% block action_row %}{% endblock %} - {% endfor %} -
+ {% trans "Row" %} + + {% trans "Title" %} + + {% trans "ISBN" %} + + {% trans "Author" %} + + {% trans "Shelf" %} + + {% trans "Review" %} + + {% trans "Book" %} + + {% trans "Status" %} +
+ {{ item.index }} + + {{ item.normalized_data.title }} + + {{ item.isbn }} + + {{ item.normalized_data.authors }} + + {{ item.normalized_data.shelf }} + +

{% include 'snippets/stars.html' with rating=item.rating %}

+

{{ item.review|truncatechars:100 }}

+
+ {% if item.book %} + + {% include 'snippets/book_cover.html' with book=item.book cover_class='is-h-s' size='small' %} + + {% endif %} + + {% if item.book %} + + {% trans "Imported" %} - {% elif item.fail_reason %} - - - {{ item.fail_reason }} - - {% else %} - - {% trans "Pending" %} - {% endif %} -
+ {% elif item.fail_reason %} + + + {% if item.book_guess %} + {% trans "Needs manual review" %} + {% else %} + {{ item.fail_reason }} + {% endif %} + + {% else %} + + {% trans "Pending" %} + {% endif %} +
+
diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index 833e9d7fa..4661520b7 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -19,9 +19,6 @@ {% endblock %} {% block import_cols_headers %} - - {% trans "Actions" %} - {% endblock %} {% block index_col %} @@ -31,30 +28,11 @@ {% endblock %} {% block import_cols %} - -
-
- {% csrf_token %} - -
- -
- {% csrf_token %} - -
-
- {% endblock %} {% block action_row %} - +
{% with guess=item.book_guess %}
@@ -64,6 +42,23 @@
{% include 'snippets/book_titleby.html' with book=guess %} +
+
+ {% csrf_token %} + +
+ +
+ {% csrf_token %} + +
+
{% endwith %}
From d3f23b4a0a5700b22107b13e800966906978b006 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:50:56 -0800 Subject: [PATCH 083/134] Updates calls in tests --- .../tests/importers/test_goodreads_import.py | 14 +++++--------- .../tests/importers/test_librarything_import.py | 16 +++++----------- .../tests/importers/test_storygraph_import.py | 9 +++------ 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index 12b5578ba..446057007 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -92,9 +92,7 @@ class GoodreadsImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -116,9 +114,8 @@ class GoodreadsImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, True, "unlisted" - ) + handle_imported_book(import_item) + review = models.Review.objects.get(book=self.book, user=self.local_user) self.assertEqual(review.content, "mixed feelings") self.assertEqual(review.rating, 2) @@ -136,9 +133,8 @@ class GoodreadsImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, True, "unlisted" - ) + handle_imported_book(import_item) + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) self.assertIsInstance(review, models.ReviewRating) self.assertEqual(review.rating, 3) diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index 1ec94bbb2..5745544e4 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -5,11 +5,10 @@ import datetime import pytz from django.test import TestCase -import responses from bookwyrm import models from bookwyrm.importers import LibrarythingImporter -from bookwyrm.importers.importer import start_import_task, handle_imported_book +from bookwyrm.importers.importer import handle_imported_book def make_date(*args): @@ -97,9 +96,7 @@ class LibrarythingImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -125,9 +122,7 @@ class LibrarythingImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -149,9 +144,8 @@ class LibrarythingImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, True, "unlisted" - ) + handle_imported_book(import_item) + review = models.Review.objects.get(book=self.book, user=self.local_user) self.assertEqual(review.content, "chef d'oeuvre") self.assertEqual(review.rating, 4.5) diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index fdad5c71d..d11a8d882 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -71,9 +71,7 @@ class StorygraphImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -92,9 +90,8 @@ class StorygraphImport(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, True, "unlisted" - ) + handle_imported_book(import_item) + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) self.assertIsInstance(review, models.ReviewRating) self.assertEqual(review.rating, 5.0) From 3bdda973bc620cd1c2f15125830ccb6acb1643c4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 09:52:09 -0800 Subject: [PATCH 084/134] Creates subdirectory for import views tests --- bookwyrm/tests/views/imports/__init__.py | 1 + bookwyrm/tests/views/{ => imports}/test_import.py | 0 2 files changed, 1 insertion(+) create mode 100644 bookwyrm/tests/views/imports/__init__.py rename bookwyrm/tests/views/{ => imports}/test_import.py (100%) diff --git a/bookwyrm/tests/views/imports/__init__.py b/bookwyrm/tests/views/imports/__init__.py new file mode 100644 index 000000000..b6e690fd5 --- /dev/null +++ b/bookwyrm/tests/views/imports/__init__.py @@ -0,0 +1 @@ +from . import * diff --git a/bookwyrm/tests/views/test_import.py b/bookwyrm/tests/views/imports/test_import.py similarity index 100% rename from bookwyrm/tests/views/test_import.py rename to bookwyrm/tests/views/imports/test_import.py From 232e051dcb51976086204b63da0237ce4675ff9a Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 10:16:05 -0800 Subject: [PATCH 085/134] Fixes import job creates in tests --- bookwyrm/tests/importers/test_goodreads_import.py | 6 ++++-- bookwyrm/tests/importers/test_librarything_import.py | 4 +++- bookwyrm/tests/importers/test_storygraph_import.py | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index 446057007..b1600659e 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -108,7 +108,9 @@ class GoodreadsImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """goodreads review import""" - import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_job = self.importer.create_job( + self.local_user, self.csv, True, "unlisted" + ) import_item = import_job.items.get(index=2) import_item.book = self.book import_item.save() @@ -126,7 +128,7 @@ class GoodreadsImport(TestCase): def test_handle_imported_book_rating(self, *_): """goodreads rating import""" import_job = self.importer.create_job( - self.local_user, self.csv, False, "public" + self.local_user, self.csv, True, "unlisted" ) import_item = import_job.items.filter(index=0).first() import_item.book = self.book diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index 5745544e4..804118eff 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -138,7 +138,9 @@ class LibrarythingImport(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """librarything review import""" - import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_job = self.importer.create_job( + self.local_user, self.csv, True, "unlisted" + ) import_item = import_job.items.filter(index=0).first() import_item.book = self.book import_item.save() diff --git a/bookwyrm/tests/importers/test_storygraph_import.py b/bookwyrm/tests/importers/test_storygraph_import.py index d11a8d882..09cf32dc1 100644 --- a/bookwyrm/tests/importers/test_storygraph_import.py +++ b/bookwyrm/tests/importers/test_storygraph_import.py @@ -83,7 +83,7 @@ class StorygraphImport(TestCase): def test_handle_imported_book_rating(self, *_): """storygraph rating import""" import_job = self.importer.create_job( - self.local_user, self.csv, False, "public" + self.local_user, self.csv, True, "unlisted" ) import_item = import_job.items.filter(index=1).first() import_item.book = self.book From 628f104b13e52a571eb2b88d095f42b9c778fb54 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 10:16:25 -0800 Subject: [PATCH 086/134] Separates out imports views tests --- bookwyrm/tests/views/imports/test_import.py | 32 ---------- .../views/imports/test_import_troubleshoot.py | 59 +++++++++++++++++++ 2 files changed, 59 insertions(+), 32 deletions(-) create mode 100644 bookwyrm/tests/views/imports/test_import_troubleshoot.py diff --git a/bookwyrm/tests/views/imports/test_import.py b/bookwyrm/tests/views/imports/test_import.py index 4a6a8237e..7de5e8c8a 100644 --- a/bookwyrm/tests/views/imports/test_import.py +++ b/bookwyrm/tests/views/imports/test_import.py @@ -51,19 +51,6 @@ class ImportViews(TestCase): validate_html(result.render()) self.assertEqual(result.status_code, 200) - def test_import_troubleshoot_get(self): - """there are so many views, this just makes sure it LOADS""" - view = views.ImportTroubleshoot.as_view() - import_job = models.ImportJob.objects.create(user=self.local_user, mappings={}) - request = self.factory.get("") - request.user = self.local_user - with patch("bookwyrm.tasks.app.AsyncResult") as async_result: - async_result.return_value = [] - result = view(request, import_job.id) - self.assertIsInstance(result, TemplateResponse) - validate_html(result.render()) - self.assertEqual(result.status_code, 200) - def test_start_import(self): """retry failed items""" view = views.Import.as_view() @@ -87,22 +74,3 @@ class ImportViews(TestCase): job = models.ImportJob.objects.get() self.assertFalse(job.include_reviews) self.assertEqual(job.privacy, "public") - - def test_retry_import(self): - """retry failed items""" - view = views.ImportTroubleshoot.as_view() - import_job = models.ImportJob.objects.create( - user=self.local_user, privacy="unlisted", mappings={} - ) - request = self.factory.post("") - request.user = self.local_user - - with patch("bookwyrm.importers.Importer.start_import"): - view(request, import_job.id) - - self.assertEqual(models.ImportJob.objects.count(), 2) - retry_job = models.ImportJob.objects.last() - - self.assertTrue(retry_job.retry) - self.assertEqual(retry_job.user, self.local_user) - self.assertEqual(retry_job.privacy, "unlisted") diff --git a/bookwyrm/tests/views/imports/test_import_troubleshoot.py b/bookwyrm/tests/views/imports/test_import_troubleshoot.py new file mode 100644 index 000000000..5359cc1ea --- /dev/null +++ b/bookwyrm/tests/views/imports/test_import_troubleshoot.py @@ -0,0 +1,59 @@ +""" test for app action functionality """ +from unittest.mock import patch +from django.template.response import TemplateResponse +from django.test import TestCase +from django.test.client import RequestFactory +from bookwyrm.tests.validate_html import validate_html + +from bookwyrm import models, views + + +class ImportTroubleshootViews(TestCase): + """goodreads import views""" + + def setUp(self): + """we need basic test data and mocks""" + self.factory = RequestFactory() + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse@local.com", + "mouse@mouse.mouse", + "password", + local=True, + localname="mouse", + ) + models.SiteSettings.objects.create() + + def test_import_troubleshoot_get(self): + """there are so many views, this just makes sure it LOADS""" + view = views.ImportTroubleshoot.as_view() + import_job = models.ImportJob.objects.create(user=self.local_user, mappings={}) + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.tasks.app.AsyncResult") as async_result: + async_result.return_value = [] + result = view(request, import_job.id) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + self.assertEqual(result.status_code, 200) + + def test_retry_import(self): + """retry failed items""" + view = views.ImportTroubleshoot.as_view() + import_job = models.ImportJob.objects.create( + user=self.local_user, privacy="unlisted", mappings={} + ) + request = self.factory.post("") + request.user = self.local_user + + with patch("bookwyrm.importers.Importer.start_import"): + view(request, import_job.id) + + self.assertEqual(models.ImportJob.objects.count(), 2) + retry_job = models.ImportJob.objects.last() + + self.assertTrue(retry_job.retry) + self.assertEqual(retry_job.user, self.local_user) + self.assertEqual(retry_job.privacy, "unlisted") From c3156a1de50e6d2376a749afd9e8830e965cd5fd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 10:22:28 -0800 Subject: [PATCH 087/134] Fixes import path in test --- bookwyrm/tests/views/imports/test_import.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/views/imports/test_import.py b/bookwyrm/tests/views/imports/test_import.py index 7de5e8c8a..b8b8b328d 100644 --- a/bookwyrm/tests/views/imports/test_import.py +++ b/bookwyrm/tests/views/imports/test_import.py @@ -58,7 +58,7 @@ class ImportViews(TestCase): form.data["source"] = "Goodreads" form.data["privacy"] = "public" form.data["include_reviews"] = False - csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv") + csv_file = pathlib.Path(__file__).parent.joinpath("../../data/goodreads.csv") form.data["csv_file"] = SimpleUploadedFile( # pylint: disable=consider-using-with csv_file, From e77eea9c817ec9b836c370a632f2946b241677e2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 10:52:11 -0800 Subject: [PATCH 088/134] Adds tests for import manual review --- .../tests/views/imports/test_import_review.py | 87 +++++++++++++++++++ bookwyrm/views/imports/manually_review.py | 1 + 2 files changed, 88 insertions(+) create mode 100644 bookwyrm/tests/views/imports/test_import_review.py diff --git a/bookwyrm/tests/views/imports/test_import_review.py b/bookwyrm/tests/views/imports/test_import_review.py new file mode 100644 index 000000000..2ab48468b --- /dev/null +++ b/bookwyrm/tests/views/imports/test_import_review.py @@ -0,0 +1,87 @@ +""" test for app action functionality """ +from unittest.mock import patch +from django.template.response import TemplateResponse +from django.test import TestCase +from django.test.client import RequestFactory +from bookwyrm.tests.validate_html import validate_html + +from bookwyrm import models, views + + +class ImportManualReviewViews(TestCase): + """goodreads import views""" + + def setUp(self): + """we need basic test data and mocks""" + self.factory = RequestFactory() + with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch( + "bookwyrm.activitystreams.populate_stream_task.delay" + ): + self.local_user = models.User.objects.create_user( + "mouse@local.com", + "mouse@mouse.mouse", + "password", + local=True, + localname="mouse", + ) + models.SiteSettings.objects.create() + self.job = models.ImportJob.objects.create(user=self.local_user, mappings={}) + + work = models.Work.objects.create(title="Test Work") + self.book = models.Edition.objects.create( + title="Example Edition", + remote_id="https://example.com/book/1", + parent_work=work, + ) + + def test_import_troubleshoot_get(self): + """there are so many views, this just makes sure it LOADS""" + view = views.ImportManualReview.as_view() + request = self.factory.get("") + request.user = self.local_user + with patch("bookwyrm.tasks.app.AsyncResult") as async_result: + async_result.return_value = [] + result = view(request, self.job.id) + self.assertIsInstance(result, TemplateResponse) + validate_html(result.render()) + self.assertEqual(result.status_code, 200) + + def test_approve_item(self): + """a guess is correct""" + import_item = models.ImportItem.objects.create( + index=0, + job=self.job, + book_guess=self.book, + fail_reason="no match", + data={}, + normalized_data={}, + ) + request = self.factory.post("") + request.user = self.local_user + + with patch("bookwyrm.importers.importer.import_item_task.delay") as mock: + views.approve_import_item(request, self.job.id, import_item.id) + self.assertEqual(mock.call_count, 1) + import_item.refresh_from_db() + self.assertIsNone(import_item.fail_reason) + self.assertIsNone(import_item.book_guess) + self.assertEqual(import_item.book.id, self.book.id) + + def test_delete_item(self): + """a guess is correct""" + import_item = models.ImportItem.objects.create( + index=0, + job=self.job, + book_guess=self.book, + fail_reason="no match", + data={}, + normalized_data={}, + ) + request = self.factory.post("") + request.user = self.local_user + + views.delete_import_item(request, self.job.id, import_item.id) + import_item.refresh_from_db() + self.assertEqual(import_item.fail_reason, "no match") + self.assertIsNone(import_item.book_guess) + self.assertIsNone(import_item.book) diff --git a/bookwyrm/views/imports/manually_review.py b/bookwyrm/views/imports/manually_review.py index 877e3ffc9..723fd4bba 100644 --- a/bookwyrm/views/imports/manually_review.py +++ b/bookwyrm/views/imports/manually_review.py @@ -51,6 +51,7 @@ def approve_import_item(request, job_id, item_id): ) item.fail_reason = None item.book = item.book_guess + item.book_guess = None item.save() # the good stuff - actually import the data From 4dae851da0b2d85cc35a08c05f34ec9bcedec66d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:15:58 -0800 Subject: [PATCH 089/134] Adds breadcrumbs --- bookwyrm/templates/feed/layout.html | 2 +- bookwyrm/templates/import/import_status.html | 37 ++++++++++++++------ bookwyrm/templates/import/manual_review.html | 6 ++++ bookwyrm/templates/import/troubleshoot.html | 6 ++++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/bookwyrm/templates/feed/layout.html b/bookwyrm/templates/feed/layout.html index 8d79781b3..6e7ec849f 100644 --- a/bookwyrm/templates/feed/layout.html +++ b/bookwyrm/templates/feed/layout.html @@ -9,7 +9,7 @@ {% if user.is_authenticated %}
-

{% trans "Your books" %}

+

{% trans "Your Books" %}

{% if not suggested_books %}

{% trans "There are no books here right now! Try searching for a book to get started" %}

{% else %} diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 5b33f3947..f5f590e1a 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -7,12 +7,32 @@ {% block content %}{% spaceless %}
- {% if job.retry %} -

{% trans "Retry Status" %}

- {% else %} -

{% trans "Import Status" %}

- {% endif %} - {% trans "Back to imports" %} +

+ {% block page_title %} + {% if job.retry %} + {% trans "Retry Status" %} + {% else %} + {% trans "Import Status" %} + {% endif %} + {% endblock %} +

+ +
@@ -63,11 +83,6 @@
-

- {% block page_title %} - {% trans "Your Import" %} - {% endblock %} -

{% block actions %}{% endblock %}
diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index 4661520b7..53601fd13 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -8,6 +8,12 @@ {% trans "Review items" %} {% endblock %} +{% block breadcrumbs %} +
  • + {% trans "Review" %} +
  • +{% endblock %} + {% block actions %}
    diff --git a/bookwyrm/templates/import/troubleshoot.html b/bookwyrm/templates/import/troubleshoot.html index 0be683832..a96aaaea7 100644 --- a/bookwyrm/templates/import/troubleshoot.html +++ b/bookwyrm/templates/import/troubleshoot.html @@ -7,6 +7,12 @@ {% trans "Failed items" %} {% endblock %} +{% block breadcrumbs %} +
  • + {% trans "Troubleshooting" %} +
  • +{% endblock %} + {% block actions %}
    From 644d9693300a73e66a40e4c9438bf7afbe411ea4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:22:07 -0800 Subject: [PATCH 090/134] Fixes importer tests --- bookwyrm/tests/importers/test_importer.py | 42 +++++++---------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index b0863fbe1..45d87171b 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -140,7 +140,7 @@ class GenericImporter(TestCase): with patch( "bookwyrm.models.activitypub_mixin.broadcast_task.apply_async" ) as mock: - import_item_task(self.importer.service, import_item.id) + import_item_task(import_item.id) kwargs = mock.call_args.kwargs self.assertEqual(kwargs["queue"], "low_priority") import_item.refresh_from_db() @@ -160,9 +160,7 @@ class GenericImporter(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -179,16 +177,14 @@ class GenericImporter(TestCase): ) import_job = self.importer.create_job( - self.local_user, self.csv, False, "unlisted" + self.local_user, self.csv, False, "public" ) import_item = import_job.items.first() import_item.book = self.book import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -210,12 +206,8 @@ class GenericImporter(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "public" - ) + handle_imported_book(import_item) + handle_imported_book(import_item) shelf.refresh_from_db() self.assertEqual(shelf.books.first(), self.book) @@ -224,20 +216,16 @@ class GenericImporter(TestCase): @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_review(self, *_): """review import""" - import_job = self.importer.create_job(self.local_user, self.csv, True, "public") + import_job = self.importer.create_job( + self.local_user, self.csv, True, "unlisted" + ) import_item = import_job.items.filter(index=3).first() import_item.book = self.book import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): with patch("bookwyrm.models.Status.broadcast") as broadcast_mock: - handle_imported_book( - self.importer.service, - self.local_user, - import_item, - True, - "unlisted", - ) + handle_imported_book(import_item) kwargs = broadcast_mock.call_args.kwargs self.assertEqual(kwargs["software"], "bookwyrm") review = models.Review.objects.get(book=self.book, user=self.local_user) @@ -249,16 +237,14 @@ class GenericImporter(TestCase): def test_handle_imported_book_rating(self, *_): """rating import""" import_job = self.importer.create_job( - self.local_user, self.csv, False, "public" + self.local_user, self.csv, True, "unlisted" ) import_item = import_job.items.filter(index=1).first() import_item.book = self.book import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, True, "unlisted" - ) + handle_imported_book(import_item) review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) self.assertIsInstance(review, models.ReviewRating) self.assertEqual(review.rating, 3.0) @@ -274,9 +260,7 @@ class GenericImporter(TestCase): import_item.save() with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): - handle_imported_book( - self.importer.service, self.local_user, import_item, False, "unlisted" - ) + handle_imported_book(import_item) self.assertFalse( models.Review.objects.filter(book=self.book, user=self.local_user).exists() ) From 1e2dca402b251fc9ae969516d26de7294fd72af5 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:40:19 -0800 Subject: [PATCH 091/134] Adds null value to breadcrumb links --- bookwyrm/templates/import/manual_review.html | 2 +- bookwyrm/templates/import/troubleshoot.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index 53601fd13..2c4875634 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -10,7 +10,7 @@ {% block breadcrumbs %}
  • - {% trans "Review" %} + {% trans "Review" %}
  • {% endblock %} diff --git a/bookwyrm/templates/import/troubleshoot.html b/bookwyrm/templates/import/troubleshoot.html index a96aaaea7..d73be6d0c 100644 --- a/bookwyrm/templates/import/troubleshoot.html +++ b/bookwyrm/templates/import/troubleshoot.html @@ -9,7 +9,7 @@ {% block breadcrumbs %}
  • - {% trans "Troubleshooting" %} + {% trans "Troubleshooting" %}
  • {% endblock %} From 1e46de4c9d4a184dedf127a4245fb75254a21b3f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:44:05 -0800 Subject: [PATCH 092/134] Associate imported review with import item --- bookwyrm/importers/importer.py | 2 ++ .../0115_importitem_linked_review.py | 24 +++++++++++++++++++ bookwyrm/models/import_job.py | 3 +++ bookwyrm/tests/importers/test_importer.py | 6 +++++ 4 files changed, 35 insertions(+) create mode 100644 bookwyrm/migrations/0115_importitem_linked_review.py diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 71f02231c..a1c35ef7a 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -205,3 +205,5 @@ def handle_imported_book(item): ) # only broadcast this review to other bookwyrm instances review.save(software="bookwyrm", priority=LOW) + item.linked_review = review + item.save() diff --git a/bookwyrm/migrations/0115_importitem_linked_review.py b/bookwyrm/migrations/0115_importitem_linked_review.py new file mode 100644 index 000000000..8cff9b8c0 --- /dev/null +++ b/bookwyrm/migrations/0115_importitem_linked_review.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.5 on 2021-11-13 19:35 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0114_importjob_source"), + ] + + operations = [ + migrations.AddField( + model_name="importitem", + name="linked_review", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + to="bookwyrm.review", + ), + ), + ] diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 6b8f0b460..ddd9eaec8 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -60,6 +60,9 @@ class ImportItem(models.Model): related_name="book_guess", ) fail_reason = models.TextField(null=True) + linked_review = models.ForeignKey( + "Review", on_delete=models.SET_NULL, null=True, blank=True + ) def resolve(self): """try various ways to lookup a book""" diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 45d87171b..99cdcd289 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -233,6 +233,9 @@ class GenericImporter(TestCase): self.assertEqual(review.rating, 2.0) self.assertEqual(review.privacy, "unlisted") + import_item.refresh_from_db() + self.assertEqual(import_item.linked_review, review) + @patch("bookwyrm.activitystreams.add_status_task.delay") def test_handle_imported_book_rating(self, *_): """rating import""" @@ -250,6 +253,9 @@ class GenericImporter(TestCase): self.assertEqual(review.rating, 3.0) self.assertEqual(review.privacy, "unlisted") + import_item.refresh_from_db() + self.assertEqual(import_item.linked_review.id, review.id) + def test_handle_imported_book_reviews_disabled(self, *_): """review import""" import_job = self.importer.create_job( From 712d8ecfb437fcafafbfc971e796b8b01895c72b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:52:08 -0800 Subject: [PATCH 093/134] Don't show empty stars when there's no review --- bookwyrm/templates/import/import_status.html | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index f5f590e1a..4871a4c70 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -134,8 +134,15 @@ {{ item.normalized_data.shelf }}
    {% block import_cols %} {% endblock %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index d6a79c202..6f6580167 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -242,6 +242,11 @@ urlpatterns = [ views.ImportStatus.as_view(), name="import-status", ), + re_path( + r"^import/(?P\d+)/retry/(?P\d+)/?$", + views.ImportStatus.as_view(), + name="import-item-retry", + ), re_path( r"^import/(?P\d+)/failed/?$", views.ImportTroubleshoot.as_view(), diff --git a/bookwyrm/views/imports/import_status.py b/bookwyrm/views/imports/import_status.py index 7e7d51792..541740821 100644 --- a/bookwyrm/views/imports/import_status.py +++ b/bookwyrm/views/imports/import_status.py @@ -4,12 +4,14 @@ import math from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.core.paginator import Paginator -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, redirect from django.template.response import TemplateResponse +from django.utils import timezone from django.utils.decorators import method_decorator from django.views import View from bookwyrm import models +from bookwyrm.importers.importer import import_item_task from bookwyrm.settings import PAGE_LENGTH # pylint: disable= no-self-use @@ -40,10 +42,19 @@ class ImportStatus(View): "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), - "complete": not job.pending_items.exists(), "percent": math.floor( # pylint: disable=c-extension-no-member (item_count - job.pending_items.count()) / item_count * 100 ), + # hours since last import item update + "inactive_time": (job.updated_date - timezone.now()).seconds / 60 / 60, } return TemplateResponse(request, "import/import_status.html", data) + + def post(self, request, job_id, item_id): + """retry an item""" + item = get_object_or_404( + models.ImportItem, id=item_id, job__id=job_id, job__user=request.user + ) + import_item_task.delay(item.id) + return redirect("import-status", job_id) From 31f33518545453a5002c56e03a6da8968eff2633 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 10:22:26 -0800 Subject: [PATCH 109/134] Fixes bug comparing dates to nonetype --- bookwyrm/models/import_job.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 387261f09..97b93b971 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -205,7 +205,9 @@ class ImportItem(models.Model): if start_date and start_date is not None and not self.date_read: return [ReadThrough(start_date=start_date)] if self.date_read: - start_date = start_date if start_date < self.date_read else None + start_date = ( + start_date if start_date and start_date < self.date_read else None + ) return [ ReadThrough( start_date=start_date, From 9f6796bbf58b8831dc0e65b8ff472d98720c45f7 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 10:29:12 -0800 Subject: [PATCH 110/134] Safer request for normalized data --- bookwyrm/models/import_job.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 97b93b971..c46795856 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -131,18 +131,18 @@ class ImportItem(models.Model): @property def title(self): """get the book title""" - return self.normalized_data["title"] + return self.normalized_data.get("title") @property def author(self): """get the book's authors""" - return self.normalized_data["authors"] + return self.normalized_data.get("authors") @property def isbn(self): """pulls out the isbn13 field from the csv line data""" - return unquote_string(self.normalized_data["isbn_13"]) or unquote_string( - self.normalized_data["isbn_10"] + return unquote_string(self.normalized_data.get("isbn_13")) or unquote_string( + self.normalized_data.get("isbn_10") ) @property @@ -153,13 +153,13 @@ class ImportItem(models.Model): @property def review(self): """a user-written review, to be imported with the book data""" - return self.normalized_data["review_body"] + return self.normalized_data.get("review_body") @property def rating(self): """x/5 star rating for a book""" if self.normalized_data.get("rating"): - return float(self.normalized_data["rating"]) + return float(self.normalized_data.get("rating")) return None @property @@ -167,7 +167,7 @@ class ImportItem(models.Model): """when the book was added to this dataset""" if self.normalized_data.get("date_added"): return timezone.make_aware( - dateutil.parser.parse(self.normalized_data["date_added"]) + dateutil.parser.parse(self.normalized_data.get("date_added")) ) return None @@ -176,7 +176,7 @@ class ImportItem(models.Model): """when the book was started""" if self.normalized_data.get("date_started"): return timezone.make_aware( - dateutil.parser.parse(self.normalized_data["date_started"]) + dateutil.parser.parse(self.normalized_data.get("date_started")) ) return None @@ -185,7 +185,7 @@ class ImportItem(models.Model): """the date a book was completed""" if self.normalized_data.get("date_finished"): return timezone.make_aware( - dateutil.parser.parse(self.normalized_data["date_finished"]) + dateutil.parser.parse(self.normalized_data.get("date_finished")) ) return None @@ -218,10 +218,10 @@ class ImportItem(models.Model): def __repr__(self): # pylint: disable=consider-using-f-string - return "<{!r} Item {!r}>".format(self.index, self.normalized_data["title"]) + return "<{!r} Item {!r}>".format(self.index, self.normalized_data.get("title")) def __str__(self): # pylint: disable=consider-using-f-string return "{} by {}".format( - self.normalized_data["title"], self.normalized_data["authors"] + self.normalized_data.get("title"), self.normalized_data.get("authors") ) From 14e2960d063a71471b52edbd8df9548d429d5559 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 10:58:46 -0800 Subject: [PATCH 111/134] Update legacy jobs --- bookwyrm/importers/importer.py | 14 ++++++++++ bookwyrm/templates/import/import_status.html | 29 ++++++++++++++++++-- bookwyrm/urls.py | 2 +- bookwyrm/views/__init__.py | 2 +- bookwyrm/views/imports/import_status.py | 26 ++++++++++++++---- 5 files changed, 62 insertions(+), 11 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 438ff7dbb..94e6734e7 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -57,6 +57,20 @@ class Importer: self.create_item(job, index, entry) return job + def update_legacy_job(self, job): + """patch up a job that was in the old format""" + items = job.items + headers = list(items.first().data.keys()) + job.mappings = self.create_row_mappings(headers) + job.updated_date = timezone.now() + job.save() + + for item in items.all(): + normalized = self.normalize_row(item.data, job.mappings) + normalized["shelf"] = self.get_shelf(normalized) + item.normalized_data = normalized + item.save() + def create_row_mappings(self, headers): """guess what the headers mean""" mappings = {} diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 6c7d54b93..6370b866a 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -57,7 +57,7 @@ {% endif %} - {% if manual_review_count %} + {% if manual_review_count and not legacy %}
    {% blocktrans trimmed count counter=manual_review_count with display_counter=manual_review_count|intcomma %} {{ display_counter }} item needs manual approval. @@ -68,7 +68,7 @@
    {% endif %} - {% if complete and fail_count and not job.retry %} + {% if job.complete and fail_count and not job.retry and not legacy %}
    {% blocktrans trimmed count counter=fail_count with display_counter=fail_count|intcomma %} {{ display_counter }} item failed to import. @@ -114,6 +114,15 @@ {% endblock %}
    + {% if legacy %} + + + + {% else %} {% for item in items %} {% block index_col %} @@ -171,7 +180,7 @@ {% trans "Pending" %} {# retry option if an item appears to be hanging #} - {% if job.created_date != job.updated_date and inactive_time > 0.24 %} + {% if job.created_date != job.updated_date and inactive_time > 24 %} {% csrf_token %} @@ -184,13 +193,27 @@ {% block action_row %}{% endblock %} {% endfor %} + {% endif %}
    + {% if item.rating %}

    {% include 'snippets/stars.html' with rating=item.rating %}

    + {% endif %} + {% if item.review %}

    {{ item.review|truncatechars:100 }}

    + {% endif %} + {% if item.linked_review %} + {% trans "View imported review" %} + {% endif %}
    From 8b7720c8b85264e533bc160991f36e533ed46461 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 11:54:28 -0800 Subject: [PATCH 094/134] Use "reject" instead of "delete" on review page --- bookwyrm/templates/import/manual_review.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index 2c4875634..b6c2b6b26 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -61,7 +61,7 @@ {% csrf_token %} From a9622942cd71ebbc8ac2bf048ecd81e8e3bcb9db Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 12:11:07 -0800 Subject: [PATCH 095/134] Test correctly adding goodreads isbns --- bookwyrm/tests/importers/test_goodreads_import.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index b1600659e..a51eca895 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -52,6 +52,11 @@ class GoodreadsImport(TestCase): self.assertEqual(len(import_items), 3) self.assertEqual(import_items[0].index, 0) self.assertEqual(import_items[0].data["Book Id"], "42036538") + self.assertEqual( + import_items[0].normalized_data["isbn_13"], '=""9781250313195"' + ) + self.assertEqual(import_items[0].normalized_data["isbn_10"], '=""1250313198"') + self.assertEqual(import_items[1].index, 1) self.assertEqual(import_items[1].data["Book Id"], "52691223") self.assertEqual(import_items[2].index, 2) From fb91c33682c2e42d8b365a24209aa41d7678301f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 12:24:16 -0800 Subject: [PATCH 096/134] Fixes isbn assignment for goodreads --- bookwyrm/importers/importer.py | 30 +++++++++---------- bookwyrm/models/import_job.py | 4 ++- bookwyrm/templates/import/import_status.html | 2 +- .../tests/importers/test_goodreads_import.py | 4 +-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 71f02231c..db13b6524 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -20,20 +20,20 @@ class Importer: encoding = "UTF-8" # these are from Goodreads - row_mappings_guesses = { - "id": ["id", "book id"], - "title": ["title"], - "authors": ["author", "authors", "primary author"], - "isbn_13": ["isbn13", "isbn"], - "isbn_10": ["isbn10", "isbn"], - "shelf": ["shelf", "exclusive shelf", "read status"], - "review_name": ["review name"], - "review_body": ["my review", "review"], - "rating": ["my rating", "rating", "star rating"], - "date_added": ["date added", "entry date", "added"], - "date_started": ["date started", "started"], - "date_finished": ["date finished", "last date read", "date read", "finished"], - } + row_mappings_guesses = [ + ("id", ["id", "book id"]), + ("title", ["title"]), + ("authors", ["author", "authors", "primary author"]), + ("isbn_10", ["isbn10", "isbn"]), + ("isbn_13", ["isbn13", "isbn"]), + ("shelf", ["shelf", "exclusive shelf", "read status"]), + ("review_name", ["review name"]), + ("review_body", ["my review", "review"]), + ("rating", ["my rating", "rating", "star rating"]), + ("date_added", ["date added", "entry date", "added"]), + ("date_started", ["date started", "started"]), + ("date_finished", ["date finished", "last date read", "date read", "finished"]), + ] date_fields = ["date_added", "date_started", "date_finished"] shelf_mapping_guesses = { "to-read": ["to-read"], @@ -60,7 +60,7 @@ class Importer: def create_row_mappings(self, headers): """guess what the headers mean""" mappings = {} - for (key, guesses) in self.row_mappings_guesses.items(): + for (key, guesses) in self.row_mappings_guesses: value = [h for h in headers if h.lower() in guesses] value = value[0] if len(value) else None if value: diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 6b8f0b460..185650171 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -12,6 +12,8 @@ from .fields import PrivacyLevels def unquote_string(text): """resolve csv quote weirdness""" + if not text: + return None match = re.match(r'="([^"]*)"', text) if match: return match.group(1) @@ -122,7 +124,7 @@ class ImportItem(models.Model): @property def isbn(self): """pulls out the isbn13 field from the csv line data""" - return unquote_string(self.normalized_data["isbn_13"]) + return unquote_string(self.normalized_data["isbn_13"]) or unquote_string(self.normalized_data["isbn_10"]) @property def shelf(self): diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index f5f590e1a..8208a2fa7 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -125,7 +125,7 @@ {{ item.normalized_data.title }} - {{ item.isbn }} + {{ item.isbn|default:'' }} {{ item.normalized_data.authors }} diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index a51eca895..4a043b599 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -53,9 +53,9 @@ class GoodreadsImport(TestCase): self.assertEqual(import_items[0].index, 0) self.assertEqual(import_items[0].data["Book Id"], "42036538") self.assertEqual( - import_items[0].normalized_data["isbn_13"], '=""9781250313195"' + import_items[0].normalized_data["isbn_13"], '="9781250313195"' ) - self.assertEqual(import_items[0].normalized_data["isbn_10"], '=""1250313198"') + self.assertEqual(import_items[0].normalized_data["isbn_10"], '="1250313198"') self.assertEqual(import_items[1].index, 1) self.assertEqual(import_items[1].data["Book Id"], "52691223") From 7f06ee3844d0704bfa3947c0e70f623b70556dec Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 12:46:27 -0800 Subject: [PATCH 097/134] Fixes getting isbn for librarything imports --- bookwyrm/importers/importer.py | 2 +- bookwyrm/importers/librarything_import.py | 10 ++++++---- bookwyrm/tests/importers/test_librarything_import.py | 3 +++ 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index db13b6524..ca63ae4aa 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -25,7 +25,7 @@ class Importer: ("title", ["title"]), ("authors", ["author", "authors", "primary author"]), ("isbn_10", ["isbn10", "isbn"]), - ("isbn_13", ["isbn13", "isbn"]), + ("isbn_13", ["isbn13", "isbn", "isbns"]), ("shelf", ["shelf", "exclusive shelf", "read status"]), ("review_name", ["review name"]), ("review_body", ["my review", "review"]), diff --git a/bookwyrm/importers/librarything_import.py b/bookwyrm/importers/librarything_import.py index d6426de6e..cff6ba7db 100644 --- a/bookwyrm/importers/librarything_import.py +++ b/bookwyrm/importers/librarything_import.py @@ -12,10 +12,12 @@ class LibrarythingImporter(Importer): def normalize_row(self, entry, mappings): # pylint: disable=no-self-use """use the dataclass to create the formatted row of data""" - normalized = {k: entry.get(v) for k, v in mappings.items()} - for date_field in self.date_fields: - date = normalized[date_field] - normalized[date_field] = re.sub(r"\[|\]", "", date) + remove_brackets = lambda v: re.sub(r"\[|\]", "", v) if v else None + normalized = { + k: remove_brackets(entry.get(v)) for k, v in mappings.items() + } + isbn_13 = normalized["isbn_13"].split(', ') + normalized["isbn_13"] = isbn_13[1] if len(isbn_13) > 0 else None return normalized def get_shelf(self, normalized_row): diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index 804118eff..f5d8d6694 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -56,6 +56,9 @@ class LibrarythingImport(TestCase): self.assertEqual(len(import_items), 3) self.assertEqual(import_items[0].index, 0) self.assertEqual(import_items[0].data["Book Id"], "5498194") + self.assertEqual(import_items[0].normalized_data["isbn_13"], "9782070291342") + self.assertEqual(import_items[0].normalized_data["isbn_10"], "2070291340") + self.assertEqual(import_items[1].index, 1) self.assertEqual(import_items[1].data["Book Id"], "5015319") self.assertEqual(import_items[2].index, 2) From 32d0d8d0274150f5e10e28f81e7f73cd06265f26 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 13 Nov 2021 13:04:54 -0800 Subject: [PATCH 098/134] Expand librarything csv processing tests --- bookwyrm/tests/data/librarything.tsv | 2 +- bookwyrm/tests/importers/test_librarything_import.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bookwyrm/tests/data/librarything.tsv b/bookwyrm/tests/data/librarything.tsv index a707f2a9b..68bbe48e9 100644 --- a/bookwyrm/tests/data/librarything.tsv +++ b/bookwyrm/tests/data/librarything.tsv @@ -1,4 +1,4 @@ Book Id Title Sort Character Primary Author Primary Author Role Secondary Author Secondary Author Roles Publication Date Review Rating Comment Private Comment Summary Media Physical Description Weight Height Thickness Length Dimensions Page Count LCCN Acquired Date Started Date Read Barcode BCID Tags Collections Languages Original Languages LC Classification ISBN ISBNs Subjects Dewey Decimal Dewey Wording Other Call Number Copies Source Entry Date From Where OCLC Work id Lending Patron Lending Status Lending Start Lending End -5498194 Marelle 1 Cortázar, Julio Gallimard (1979), Poche 1979 chef d'oeuvre 4.5 Marelle by Julio Cortázar (1979) Broché 590 p.; 7.24 inches 1.28 pounds 7.24 inches 1.26 inches 4.96 inches 7.24 x 4.96 x 1.26 inches 590 [2007-04-16] [2007-05-08] roman, espagnol, expérimental, bohème, philosophie Your library French Spanish PQ7797 .C7145 [2070291340] 2070291340, 9782070291342 Cortazar, Julio. Rayuela 863 Literature > Spanish And Portuguese > Spanish fiction 1 Amazon.fr [2006-08-09] 57814 +5498194 Marelle 1 Cortazar, Julio Gallimard (1979), Poche 1979 chef d'oeuvre 4.5 Marelle by Julio Cortázar (1979) Broché 590 p.; 7.24 inches 1.28 pounds 7.24 inches 1.26 inches 4.96 inches 7.24 x 4.96 x 1.26 inches 590 [2007-04-16] [2007-05-08] roman, espagnol, expérimental, bohème, philosophie Your library French Spanish PQ7797 .C7145 [2070291340] 2070291340, 9782070291342 Cortazar, Julio. Rayuela 863 Literature > Spanish And Portuguese > Spanish fiction 1 Amazon.fr [2006-08-09] 57814 5015319 Le grand incendie de Londres: Récit, avec incises et bifurcations, 1985-1987 (Fiction & Cie) 1 Roubaud, Jacques Seuil (1989), Unknown Binding 1989 5 Le grand incendie de Londres: Récit, avec incises et bifurcations, 1985-1987 (Fiction & Cie) by Jacques Roubaud (1989) Broché 411 p.; 7.72 inches 0.88 pounds 7.72 inches 1.02 inches 5.43 inches 7.72 x 5.43 x 1.02 inches 411 Your library English PQ2678 .O77 [2020104725] 2020104725, 9782020104722 Autobiographical fiction|Roubaud, Jacques > Fiction 813 American And Canadian > Fiction > Literature 1 Amazon.com [2006-07-25] 478910 5015399 Le Maître et Marguerite 1 Boulgakov, Mikhaïl Pocket (1994), Poche 1994 Le Maître et Marguerite by Mikhaïl Boulgakov (1994) Broché 579 p.; 7.09 inches 0.66 pounds 7.09 inches 1.18 inches 4.33 inches 7.09 x 4.33 x 1.18 inches 579 Your library French PG3476 .B78 [2266062328] 2266062328, 9782266062329 Allegories|Bulgakov|Good and evil > Fiction|Humanities|Jerusalem > Fiction|Jesus Christ > Fiction|Literature|Mental illness > Fiction|Moscow (Russia) > Fiction|Novel|Pilate, Pontius, 1st cent. > Fiction|Political fiction|Russia > Fiction|Russian fiction|Russian publications (Form Entry)|Soviet Union > History > 1925-1953 > Fiction|literature 891.7342 1917-1945 > 1917-1991 (USSR) > Literature > Literature of other Indo-European languages > Other Languages > Russian > Russian Fiction 1 Amazon.fr [2006-07-25] 10151 diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index f5d8d6694..49354b368 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -58,6 +58,11 @@ class LibrarythingImport(TestCase): self.assertEqual(import_items[0].data["Book Id"], "5498194") self.assertEqual(import_items[0].normalized_data["isbn_13"], "9782070291342") self.assertEqual(import_items[0].normalized_data["isbn_10"], "2070291340") + self.assertEqual(import_items[0].normalized_data["title"], "Marelle") + self.assertEqual(import_items[0].normalized_data["authors"], "Cortazar, Julio") + self.assertEqual(import_items[0].normalized_data["date_added"], "2006-08-09") + self.assertEqual(import_items[0].normalized_data["date_started"], "2007-04-16") + self.assertEqual(import_items[0].normalized_data["date_finished"], "2007-05-08") self.assertEqual(import_items[1].index, 1) self.assertEqual(import_items[1].data["Book Id"], "5015319") From 8495cf8a45e90b463e0e70b10956957f90ff4365 Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Sun, 14 Nov 2021 21:21:37 +1100 Subject: [PATCH 099/134] don't delete non-form data when editing authors fixes #1584 This is a temporary fix. As Mouse has suggested, ultimately it would be good to re-import data from one or more of the linked data sources if there is anything missing. --- bookwyrm/forms.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 298f73da9..1ec51df96 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -201,12 +201,17 @@ class EditionForm(CustomForm): class AuthorForm(CustomForm): class Meta: model = models.Author - exclude = [ - "remote_id", - "origin_id", - "created_date", - "updated_date", - "search_vector", + fields = [ + "last_edited_by", + "name", + "aliases", + "bio", + "wikipedia_link", + "born", + "died", + "openlibrary_key", + "librarything_key", + "goodreads_key", ] From 3357953a538e070e3cc8515234aa4c18b9a74b03 Mon Sep 17 00:00:00 2001 From: Hugh Rundle Date: Sun, 14 Nov 2021 21:26:23 +1100 Subject: [PATCH 100/134] whoops forgot inventaire_id --- bookwyrm/forms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/forms.py b/bookwyrm/forms.py index 1ec51df96..847ca05c0 100644 --- a/bookwyrm/forms.py +++ b/bookwyrm/forms.py @@ -210,6 +210,7 @@ class AuthorForm(CustomForm): "born", "died", "openlibrary_key", + "inventaire_id", "librarything_key", "goodreads_key", ] From 66ad8c3b25114977134269c8dcb0ce3d3bdc14f4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 07:11:33 -0800 Subject: [PATCH 101/134] Updates locale --- locale/en_US/LC_MESSAGES/django.po | 248 +++++++++++++++++++---------- 1 file changed, 161 insertions(+), 87 deletions(-) diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index 7d8fc801a..14bbb1b96 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-10-24 14:09+0000\n" +"POT-Creation-Date: 2021-11-14 15:08+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -73,15 +73,16 @@ msgstr "" msgid "Descending" msgstr "" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "" @@ -101,23 +102,23 @@ msgstr "" msgid "Domain block" msgstr "" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "" @@ -134,21 +135,21 @@ msgstr "" msgid "Blocked" msgstr "" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "" @@ -893,22 +894,37 @@ msgstr "" msgid "All known users" msgstr "" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 #, python-format -msgid "%(username)s rated %(book_title)s" +msgid "%(username)s wants to read %(book_title)s" msgstr "" #: bookwyrm/templates/discover/card-header.html:13 #, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 +#, python-format +msgid "%(username)s rated %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:27 +#, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "" @@ -1059,9 +1075,8 @@ msgstr "" msgid "Updates" msgstr "" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "" #: bookwyrm/templates/feed/layout.html:14 @@ -1070,11 +1085,13 @@ msgstr "" #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "" @@ -1082,6 +1099,7 @@ msgstr "" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "" @@ -1367,88 +1385,161 @@ msgid "No recent imports" msgstr "" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "" - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." +msgid "Refresh" msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "" - -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "" +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1580,10 +1671,6 @@ msgstr "" msgid "Feed" msgstr "" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "" @@ -1683,10 +1770,6 @@ msgstr "" msgid "Suggested by" msgstr "" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "" @@ -2239,15 +2322,6 @@ msgstr "" msgid "End date" msgstr "" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "" @@ -3096,10 +3170,6 @@ msgstr "" msgid "Un-boost" msgstr "" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "" @@ -3526,7 +3596,7 @@ msgstr "" msgid "commented on %(book)s" msgstr "" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "" @@ -3605,7 +3675,11 @@ msgstr "" msgid "Show less" msgstr "" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "" @@ -3749,7 +3823,7 @@ msgstr "" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "" From bdc3f6828ba476e4855f0b7922bd599240490182 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 07:11:48 -0800 Subject: [PATCH 102/134] Python formatting --- bookwyrm/importers/librarything_import.py | 6 ++---- bookwyrm/models/import_job.py | 6 ++++-- bookwyrm/tests/importers/test_goodreads_import.py | 4 +--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/bookwyrm/importers/librarything_import.py b/bookwyrm/importers/librarything_import.py index cff6ba7db..1b61a6f17 100644 --- a/bookwyrm/importers/librarything_import.py +++ b/bookwyrm/importers/librarything_import.py @@ -13,10 +13,8 @@ class LibrarythingImporter(Importer): def normalize_row(self, entry, mappings): # pylint: disable=no-self-use """use the dataclass to create the formatted row of data""" remove_brackets = lambda v: re.sub(r"\[|\]", "", v) if v else None - normalized = { - k: remove_brackets(entry.get(v)) for k, v in mappings.items() - } - isbn_13 = normalized["isbn_13"].split(', ') + normalized = {k: remove_brackets(entry.get(v)) for k, v in mappings.items()} + isbn_13 = normalized["isbn_13"].split(", ") normalized["isbn_13"] = isbn_13[1] if len(isbn_13) > 0 else None return normalized diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index b47379bb7..753662d65 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -127,7 +127,9 @@ class ImportItem(models.Model): @property def isbn(self): """pulls out the isbn13 field from the csv line data""" - return unquote_string(self.normalized_data["isbn_13"]) or unquote_string(self.normalized_data["isbn_10"]) + return unquote_string(self.normalized_data["isbn_13"]) or unquote_string( + self.normalized_data["isbn_10"] + ) @property def shelf(self): @@ -200,7 +202,7 @@ class ImportItem(models.Model): def __repr__(self): # pylint: disable=consider-using-f-string - return "<{!r}Item {!r}>".format(self.index, self.normalized_data["title"]) + return "<{!r} Item {!r}>".format(self.index, self.normalized_data["title"]) def __str__(self): # pylint: disable=consider-using-f-string diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index 4a043b599..0a421df43 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -52,9 +52,7 @@ class GoodreadsImport(TestCase): self.assertEqual(len(import_items), 3) self.assertEqual(import_items[0].index, 0) self.assertEqual(import_items[0].data["Book Id"], "42036538") - self.assertEqual( - import_items[0].normalized_data["isbn_13"], '="9781250313195"' - ) + self.assertEqual(import_items[0].normalized_data["isbn_13"], '="9781250313195"') self.assertEqual(import_items[0].normalized_data["isbn_10"], '="1250313198"') self.assertEqual(import_items[1].index, 1) From 2748e0a8249fd6c04594093339d6faf22cb1141f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 07:50:19 -0800 Subject: [PATCH 103/134] Check for existing reviews/ratings on import items --- bookwyrm/importers/importer.py | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 1d350c6d3..657ede05e 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -171,21 +171,25 @@ def handle_imported_book(item): read.user = user read.save() - if job.include_reviews and (item.rating or item.review): + if job.include_reviews and (item.rating or item.review) and not item.linked_review: # we don't know the publication date of the review, # but "now" is a bad guess published_date_guess = item.date_read or item.date_added if item.review: # pylint: disable=consider-using-f-string - review_title = ( - "Review of {!r} on {!r}".format( - item.book.title, - job.source, - ) - if item.review - else "" + review_title = "Review of {!r} on {!r}".format( + item.book.title, + job.source, ) - review = models.Review( + existing = models.Review.objects.filter( + user=user, + book=item.book, + name=review_title, + rating=item.rating, + published_date=published_date_guess, + ).first() + + review = existing or models.Review( user=user, book=item.book, name=review_title, @@ -196,13 +200,20 @@ def handle_imported_book(item): ) else: # just a rating - review = models.ReviewRating( + existing = models.ReviewRating.objects.filter( + user=user, + book=item.book, + published_date=published_date_guess, + rating=item.rating, + ).first() + review = existing or models.ReviewRating( user=user, book=item.book, rating=item.rating, published_date=published_date_guess, privacy=job.privacy, ) + # only broadcast this review to other bookwyrm instances review.save(software="bookwyrm", priority=LOW) item.linked_review = review From 6cca3f97724dbab6eae49bb2d0a55c02b39b1347 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 07:57:13 -0800 Subject: [PATCH 104/134] Updates test data --- bookwyrm/tests/data/generic.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/tests/data/generic.csv b/bookwyrm/tests/data/generic.csv index 9c5b6f023..470ce7a80 100644 --- a/bookwyrm/tests/data/generic.csv +++ b/bookwyrm/tests/data/generic.csv @@ -1,4 +1,4 @@ -id,title,author,ISBN,rating,shelf,review,added,finished +id,title,author,ISBN13,rating,shelf,review,added,finished 38,Gideon the Ninth,Tamsyn Muir,"9781250313195",,read,,2021-11-10,2021-11-11 48,Harrow the Ninth,Tamsyn Muir,,3,read,,2021-11-10 23,Subcutanean,Aaron A. Reed,,,read,,2021-11-10 From 9e673834dc9294262acda328cba48cf371c022f6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 08:23:26 -0800 Subject: [PATCH 105/134] Check for duplicates --- bookwyrm/importers/importer.py | 44 ++++++++++---------- bookwyrm/tests/importers/test_importer.py | 49 +++++++++++++++++++++++ 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 657ede05e..05550429b 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -181,40 +181,42 @@ def handle_imported_book(item): item.book.title, job.source, ) - existing = models.Review.objects.filter( + review = models.Review.objects.filter( user=user, book=item.book, name=review_title, rating=item.rating, published_date=published_date_guess, ).first() - - review = existing or models.Review( - user=user, - book=item.book, - name=review_title, - content=item.review, - rating=item.rating, - published_date=published_date_guess, - privacy=job.privacy, - ) + if not review: + review = models.Review( + user=user, + book=item.book, + name=review_title, + content=item.review, + rating=item.rating, + published_date=published_date_guess, + privacy=job.privacy, + ) + review.save(software="bookwyrm", priority=LOW) else: # just a rating - existing = models.ReviewRating.objects.filter( + review = models.ReviewRating.objects.filter( user=user, book=item.book, published_date=published_date_guess, rating=item.rating, ).first() - review = existing or models.ReviewRating( - user=user, - book=item.book, - rating=item.rating, - published_date=published_date_guess, - privacy=job.privacy, - ) + if not review: + review = models.ReviewRating( + user=user, + book=item.book, + rating=item.rating, + published_date=published_date_guess, + privacy=job.privacy, + ) + review.save(software="bookwyrm", priority=LOW) # only broadcast this review to other bookwyrm instances - review.save(software="bookwyrm", priority=LOW) item.linked_review = review - item.save() + item.save() diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 99cdcd289..6996a92b5 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -256,6 +256,55 @@ class GenericImporter(TestCase): import_item.refresh_from_db() self.assertEqual(import_item.linked_review.id, review.id) + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_handle_imported_book_rating_duplicate_with_link(self, *_): + """rating import twice""" + import_job = self.importer.create_job( + self.local_user, self.csv, True, "unlisted" + ) + import_item = import_job.items.filter(index=1).first() + import_item.book = self.book + import_item.save() + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): + handle_imported_book(import_item) + handle_imported_book(import_item) + + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) + self.assertIsInstance(review, models.ReviewRating) + self.assertEqual(review.rating, 3.0) + self.assertEqual(review.privacy, "unlisted") + + import_item.refresh_from_db() + self.assertEqual(import_item.linked_review.id, review.id) + + @patch("bookwyrm.activitystreams.add_status_task.delay") + def test_handle_imported_book_rating_duplicate_without_link(self, *_): + """rating import twice""" + import_job = self.importer.create_job( + self.local_user, self.csv, True, "unlisted" + ) + import_item = import_job.items.filter(index=1).first() + import_item.book = self.book + import_item.save() + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): + handle_imported_book(import_item) + import_item.refresh_from_db() + import_item.linked_review = None + import_item.save() + + with patch("bookwyrm.models.activitypub_mixin.broadcast_task.apply_async"): + handle_imported_book(import_item) + + review = models.ReviewRating.objects.get(book=self.book, user=self.local_user) + self.assertIsInstance(review, models.ReviewRating) + self.assertEqual(review.rating, 3.0) + self.assertEqual(review.privacy, "unlisted") + + import_item.refresh_from_db() + self.assertEqual(import_item.linked_review.id, review.id) + def test_handle_imported_book_reviews_disabled(self, *_): """review import""" import_job = self.importer.create_job( From 47b98ad0d9e87f05eb569cb278772a2c3a91042f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 09:04:12 -0800 Subject: [PATCH 106/134] Track completed items on job --- bookwyrm/importers/importer.py | 4 +++ .../migrations/0116_auto_20211114_1700.py | 32 +++++++++++++++++++ bookwyrm/models/import_job.py | 10 ++++-- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 bookwyrm/migrations/0116_auto_20211114_1700.py diff --git a/bookwyrm/importers/importer.py b/bookwyrm/importers/importer.py index 05550429b..438ff7dbb 100644 --- a/bookwyrm/importers/importer.py +++ b/bookwyrm/importers/importer.py @@ -126,6 +126,7 @@ def import_item_task(item_id): except Exception as err: # pylint: disable=broad-except item.fail_reason = _("Error loading book") item.save() + item.update_job() raise err if item.book: @@ -135,6 +136,7 @@ def import_item_task(item_id): item.fail_reason = _("Could not find a match for book") item.save() + item.update_job() def handle_imported_book(item): @@ -144,6 +146,8 @@ def handle_imported_book(item): if isinstance(item.book, models.Work): item.book = item.book.default_edition if not item.book: + item.fail_reason = _("Error loading book") + item.save() return if not isinstance(item.book, models.Edition): item.book = item.book.edition diff --git a/bookwyrm/migrations/0116_auto_20211114_1700.py b/bookwyrm/migrations/0116_auto_20211114_1700.py new file mode 100644 index 000000000..ff71b89ce --- /dev/null +++ b/bookwyrm/migrations/0116_auto_20211114_1700.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.5 on 2021-11-14 17:00 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('bookwyrm', '0115_importitem_linked_review'), + ] + + operations = [ + migrations.RemoveField( + model_name='importjob', + name='complete', + ), + migrations.RemoveField( + model_name='importjob', + name='task_id', + ), + migrations.AddField( + model_name='importjob', + name='completed_count', + field=models.IntegerField(default=0), + ), + migrations.AddField( + model_name='importjob', + name='updated_date', + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 753662d65..953ae3946 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -35,10 +35,10 @@ class ImportJob(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) created_date = models.DateTimeField(default=timezone.now) - task_id = models.CharField(max_length=100, null=True) # TODO: deprecated include_reviews = models.BooleanField(default=True) mappings = models.JSONField() - complete = models.BooleanField(default=False) + updated_date = models.DateTimeField(default=timezone.now) + completed_count = models.IntegerField(default=0) source = models.CharField(max_length=100) privacy = models.CharField( max_length=255, default="public", choices=PrivacyLevels.choices @@ -66,6 +66,12 @@ class ImportItem(models.Model): "Review", on_delete=models.SET_NULL, null=True, blank=True ) + def update_job(self): + """this user is here! they are doing things!""" + self.job.completed_count += 1 + self.job.updated_date = timezone.now() + self.job.save() + def resolve(self): """try various ways to lookup a book""" # we might be calling this after manually adding the book, From f92863ad3ec562feed8baf88e9bcac4db463fbd1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 09:56:23 -0800 Subject: [PATCH 107/134] Notify when import completes --- .../migrations/0116_auto_20211114_1700.py | 32 ----------------- .../migrations/0116_auto_20211114_1734.py | 23 ++++++++++++ bookwyrm/models/import_job.py | 18 +++++++--- bookwyrm/models/notification.py | 7 ++-- bookwyrm/tests/importers/test_importer.py | 35 ++++++++++++++++++- bookwyrm/views/imports/import_status.py | 5 ++- 6 files changed, 77 insertions(+), 43 deletions(-) delete mode 100644 bookwyrm/migrations/0116_auto_20211114_1700.py create mode 100644 bookwyrm/migrations/0116_auto_20211114_1734.py diff --git a/bookwyrm/migrations/0116_auto_20211114_1700.py b/bookwyrm/migrations/0116_auto_20211114_1700.py deleted file mode 100644 index ff71b89ce..000000000 --- a/bookwyrm/migrations/0116_auto_20211114_1700.py +++ /dev/null @@ -1,32 +0,0 @@ -# Generated by Django 3.2.5 on 2021-11-14 17:00 - -from django.db import migrations, models -import django.utils.timezone - - -class Migration(migrations.Migration): - - dependencies = [ - ('bookwyrm', '0115_importitem_linked_review'), - ] - - operations = [ - migrations.RemoveField( - model_name='importjob', - name='complete', - ), - migrations.RemoveField( - model_name='importjob', - name='task_id', - ), - migrations.AddField( - model_name='importjob', - name='completed_count', - field=models.IntegerField(default=0), - ), - migrations.AddField( - model_name='importjob', - name='updated_date', - field=models.DateTimeField(default=django.utils.timezone.now), - ), - ] diff --git a/bookwyrm/migrations/0116_auto_20211114_1734.py b/bookwyrm/migrations/0116_auto_20211114_1734.py new file mode 100644 index 000000000..1da001bdc --- /dev/null +++ b/bookwyrm/migrations/0116_auto_20211114_1734.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.5 on 2021-11-14 17:34 + +from django.db import migrations, models +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0115_importitem_linked_review"), + ] + + operations = [ + migrations.RemoveField( + model_name="importjob", + name="task_id", + ), + migrations.AddField( + model_name="importjob", + name="updated_date", + field=models.DateTimeField(default=django.utils.timezone.now), + ), + ] diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index 953ae3946..fbec88cae 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -38,13 +38,18 @@ class ImportJob(models.Model): include_reviews = models.BooleanField(default=True) mappings = models.JSONField() updated_date = models.DateTimeField(default=timezone.now) - completed_count = models.IntegerField(default=0) + complete = models.BooleanField(default=False) source = models.CharField(max_length=100) privacy = models.CharField( max_length=255, default="public", choices=PrivacyLevels.choices ) retry = models.BooleanField(default=False) + @property + def pending_items(self): + """items that haven't been processed yet""" + return self.items.filter(fail_reason__isnull=True, book__isnull=True) + class ImportItem(models.Model): """a single line of a csv being imported""" @@ -67,10 +72,13 @@ class ImportItem(models.Model): ) def update_job(self): - """this user is here! they are doing things!""" - self.job.completed_count += 1 - self.job.updated_date = timezone.now() - self.job.save() + """let the job know when the items get work done""" + job = self.job + job.updated_date = timezone.now() + job.save() + if not job.pending_items.exists() and not job.complete: + job.complete = True + job.save(update_fields=["complete"]) def resolve(self): """try various ways to lookup a book""" diff --git a/bookwyrm/models/notification.py b/bookwyrm/models/notification.py index 2f1aae4f3..417bf7591 100644 --- a/bookwyrm/models/notification.py +++ b/bookwyrm/models/notification.py @@ -157,9 +157,12 @@ def notify_user_on_unboost(sender, instance, *args, **kwargs): @receiver(models.signals.post_save, sender=ImportJob) # pylint: disable=unused-argument -def notify_user_on_import_complete(sender, instance, *args, **kwargs): +def notify_user_on_import_complete( + sender, instance, *args, update_fields=None, **kwargs +): """we imported your books! aren't you proud of us""" - if not instance.complete: + update_fields = update_fields or [] + if not instance.complete or "complete" not in update_fields: return Notification.objects.create( user=instance.user, diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 6996a92b5..3fbfa2648 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -145,7 +145,40 @@ class GenericImporter(TestCase): self.assertEqual(kwargs["queue"], "low_priority") import_item.refresh_from_db() - self.assertEqual(import_item.book.id, self.book.id) + def test_complete_job(self, *_): + """test notification""" + import_job = self.importer.create_job( + self.local_user, self.csv, False, "unlisted" + ) + item = import_job.items[0] + item.update_job() + self.assertFalse( + models.Notification.objects.filter( + user=self.local_user, + related_import=import_job, + notification_type="IMPORT", + ).exists() + ) + + item = import_job.items[1] + item.update_job() + self.assertFalse( + models.Notification.objects.filter( + user=self.local_user, + related_import=import_job, + notification_type="IMPORT", + ).exists() + ) + + item = import_job.items[2] + item.update_job() + self.assertTrue( + models.Notification.objects.filter( + user=self.local_user, + related_import=import_job, + notification_type="IMPORT", + ).exists() + ) def test_handle_imported_book(self, *_): """import added a book, this adds related connections""" diff --git a/bookwyrm/views/imports/import_status.py b/bookwyrm/views/imports/import_status.py index 2d18d656a..7e7d51792 100644 --- a/bookwyrm/views/imports/import_status.py +++ b/bookwyrm/views/imports/import_status.py @@ -24,7 +24,6 @@ class ImportStatus(View): raise PermissionDenied() items = job.items.order_by("index") - pending_items = items.filter(fail_reason__isnull=True, book__isnull=True) item_count = items.count() or 1 paginated = Paginator(items, PAGE_LENGTH) @@ -41,9 +40,9 @@ class ImportStatus(View): "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), - "complete": not pending_items.exists(), + "complete": not job.pending_items.exists(), "percent": math.floor( # pylint: disable=c-extension-no-member - (item_count - pending_items.count()) / item_count * 100 + (item_count - job.pending_items.count()) / item_count * 100 ), } From 8cede05d32895d2a4c73e3f208b13841651a881f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 10:20:14 -0800 Subject: [PATCH 108/134] Retry hanging items --- bookwyrm/models/import_job.py | 2 +- bookwyrm/templates/import/import_status.html | 15 ++++++++++++--- bookwyrm/urls.py | 5 +++++ bookwyrm/views/imports/import_status.py | 15 +++++++++++++-- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/bookwyrm/models/import_job.py b/bookwyrm/models/import_job.py index fbec88cae..387261f09 100644 --- a/bookwyrm/models/import_job.py +++ b/bookwyrm/models/import_job.py @@ -35,9 +35,9 @@ class ImportJob(models.Model): user = models.ForeignKey(User, on_delete=models.CASCADE) created_date = models.DateTimeField(default=timezone.now) + updated_date = models.DateTimeField(default=timezone.now) include_reviews = models.BooleanField(default=True) mappings = models.JSONField() - updated_date = models.DateTimeField(default=timezone.now) complete = models.BooleanField(default=False) source = models.CharField(max_length=100) privacy = models.CharField( diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 61b7b5cf5..6c7d54b93 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -41,7 +41,7 @@ - {% if not complete %} + {% if not job.complete %}
    @@ -167,8 +167,17 @@ {% endif %} {% else %} - - {% trans "Pending" %} +
    + + {% trans "Pending" %} + {# retry option if an item appears to be hanging #} + {% if job.created_date != job.updated_date and inactive_time > 0.24 %} +
    + {% csrf_token %} + +
    + {% endif %} +
    {% endif %}
    +

    + {% trans "Import preview unavailable." %} +

    +
    + {% if legacy %} +
    + + {% csrf_token %} +

    + {% trans "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." %} +

    + + +
    + {% endif %}
    +{% if not legacy %}
    {% include 'snippets/pagination.html' with page=items %}
    +{% endif %} {% endspaceless %}{% endblock %} {% block scripts %} diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 6f6580167..514bb7e60 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -244,7 +244,7 @@ urlpatterns = [ ), re_path( r"^import/(?P\d+)/retry/(?P\d+)/?$", - views.ImportStatus.as_view(), + views.retry_item, name="import-item-retry", ), re_path( diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index 1a6fbdc69..d79de4248 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -45,7 +45,7 @@ from .shelf.shelf_actions import shelve, unshelve # csv import from .imports.import_data import Import -from .imports.import_status import ImportStatus +from .imports.import_status import ImportStatus, retry_item from .imports.troubleshoot import ImportTroubleshoot from .imports.manually_review import ( ImportManualReview, diff --git a/bookwyrm/views/imports/import_status.py b/bookwyrm/views/imports/import_status.py index 541740821..8e07a1715 100644 --- a/bookwyrm/views/imports/import_status.py +++ b/bookwyrm/views/imports/import_status.py @@ -9,8 +9,10 @@ from django.template.response import TemplateResponse from django.utils import timezone from django.utils.decorators import method_decorator from django.views import View +from django.views.decorators.http import require_POST from bookwyrm import models +from bookwyrm.importers import GoodreadsImporter from bookwyrm.importers.importer import import_item_task from bookwyrm.settings import PAGE_LENGTH @@ -47,14 +49,26 @@ class ImportStatus(View): ), # hours since last import item update "inactive_time": (job.updated_date - timezone.now()).seconds / 60 / 60, + "legacy": not job.mappings, } return TemplateResponse(request, "import/import_status.html", data) - def post(self, request, job_id, item_id): - """retry an item""" - item = get_object_or_404( - models.ImportItem, id=item_id, job__id=job_id, job__user=request.user - ) - import_item_task.delay(item.id) + def post(self, request, job_id): + """bring a legacy import into the latest format""" + job = get_object_or_404(models.ImportJob, id=job_id) + if job.user != request.user: + raise PermissionDenied() + GoodreadsImporter().update_legacy_job(job) return redirect("import-status", job_id) + + +@login_required +@require_POST +def retry_item(request, job_id, item_id): + """retry an item""" + item = get_object_or_404( + models.ImportItem, id=item_id, job__id=job_id, job__user=request.user + ) + import_item_task.delay(item.id) + return redirect("import-status", job_id) From 8612cf654d2edec8b06abbf837bb4094d4673507 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sun, 14 Nov 2021 11:31:47 -0800 Subject: [PATCH 112/134] Invalid href --- bookwyrm/templates/import/import_status.html | 2 +- bookwyrm/tests/importers/test_importer.py | 46 ++++++++------------ 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 6370b866a..ddeeeb310 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -47,7 +47,7 @@ {% trans "In progress" %} - {% trans "Refresh" %} + {% trans "Refresh" %}
    diff --git a/bookwyrm/tests/importers/test_importer.py b/bookwyrm/tests/importers/test_importer.py index 3fbfa2648..5c3b20310 100644 --- a/bookwyrm/tests/importers/test_importer.py +++ b/bookwyrm/tests/importers/test_importer.py @@ -1,5 +1,4 @@ """ testing import """ -from collections import namedtuple import pathlib from unittest.mock import patch import datetime @@ -104,13 +103,9 @@ class GenericImporter(TestCase): import_job = self.importer.create_job( self.local_user, self.csv, False, "unlisted" ) - MockTask = namedtuple("Task", ("id")) - mock_task = MockTask(7) - with patch("bookwyrm.importers.importer.start_import_task.delay") as start: - start.return_value = mock_task + with patch("bookwyrm.importers.importer.start_import_task.delay") as mock: self.importer.start_import(import_job) - import_job.refresh_from_db() - self.assertEqual(import_job.task_id, "7") + self.assertEqual(mock.call_count, 1) @responses.activate def test_start_import_task(self, *_): @@ -150,28 +145,25 @@ class GenericImporter(TestCase): import_job = self.importer.create_job( self.local_user, self.csv, False, "unlisted" ) - item = import_job.items[0] - item.update_job() - self.assertFalse( - models.Notification.objects.filter( - user=self.local_user, - related_import=import_job, - notification_type="IMPORT", - ).exists() - ) + items = import_job.items.all() + for item in items[:3]: + item.fail_reason = "hello" + item.save() + item.update_job() + self.assertFalse( + models.Notification.objects.filter( + user=self.local_user, + related_import=import_job, + notification_type="IMPORT", + ).exists() + ) - item = import_job.items[1] - item.update_job() - self.assertFalse( - models.Notification.objects.filter( - user=self.local_user, - related_import=import_job, - notification_type="IMPORT", - ).exists() - ) - - item = import_job.items[2] + item = items[3] + item.fail_reason = "hello" + item.save() item.update_job() + import_job.refresh_from_db() + self.assertTrue(import_job.complete) self.assertTrue( models.Notification.objects.filter( user=self.local_user, From 77ee1147d52133a02e4e0a9647fb892f6859bfba Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 09:03:00 -0800 Subject: [PATCH 113/134] Adds return_first tests to book_search --- bookwyrm/tests/test_book_search.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bookwyrm/tests/test_book_search.py b/bookwyrm/tests/test_book_search.py index 4b9a06811..16435ffff 100644 --- a/bookwyrm/tests/test_book_search.py +++ b/bookwyrm/tests/test_book_search.py @@ -57,12 +57,24 @@ class BookSearch(TestCase): self.assertEqual(len(results), 1) self.assertEqual(results[0], self.second_edition) + def test_search_identifiers_return_first(self): + """search by unique identifiers""" + result = book_search.search_identifiers("hello", return_first=True) + self.assertEqual(result, self.second_edition) + def test_search_title_author(self): """search by unique identifiers""" results = book_search.search_title_author("Another", min_confidence=0) self.assertEqual(len(results), 1) self.assertEqual(results[0], self.second_edition) + def test_search_title_author_return_first(self): + """search by unique identifiers""" + results = book_search.search_title_author( + "Another", min_confidence=0, return_first=True + ) + self.assertEqual(results, self.second_edition) + def test_format_search_result(self): """format a search result""" result = book_search.format_search_result(self.first_edition) From 83e468a4f817ffcb00324ef099a8c8db1fe7e240 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 09:34:36 -0800 Subject: [PATCH 114/134] Fixes "indeterminate" state of progress indicator on screen reader --- bookwyrm/templates/import/import_status.html | 2 +- bookwyrm/views/imports/import_status.py | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index ddeeeb310..61763ec2c 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -51,7 +51,7 @@
    - {{ percent }}% + {{ percent }} % {{ percent }}%
    diff --git a/bookwyrm/views/imports/import_status.py b/bookwyrm/views/imports/import_status.py index 8e07a1715..26ff8cdec 100644 --- a/bookwyrm/views/imports/import_status.py +++ b/bookwyrm/views/imports/import_status.py @@ -32,20 +32,25 @@ class ImportStatus(View): paginated = Paginator(items, PAGE_LENGTH) page = paginated.get_page(request.GET.get("page")) + manual_review_count = items.filter( + fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True + ).count() + fail_count = items.filter( + fail_reason__isnull=False, book_guess__isnull=True + ).count() + pending_item_count = job.pending_items.count() data = { "job": job, "items": page, - "manual_review_count": items.filter( - fail_reason__isnull=False, book_guess__isnull=False, book__isnull=True - ).count(), - "fail_count": items.filter( - fail_reason__isnull=False, book_guess__isnull=True - ).count(), + "manual_review_count": manual_review_count, + "fail_count": fail_count, "page_range": paginated.get_elided_page_range( page.number, on_each_side=2, on_ends=1 ), + "item_count": item_count, + "complete_count": item_count - pending_item_count, "percent": math.floor( # pylint: disable=c-extension-no-member - (item_count - job.pending_items.count()) / item_count * 100 + (item_count - pending_item_count) / item_count * 100 ), # hours since last import item update "inactive_time": (job.updated_date - timezone.now()).seconds / 60 / 60, From 30afe42b3ad0b6c78615187bc246d17b9e90f9f4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 09:41:05 -0800 Subject: [PATCH 115/134] Removes extra space in progress bar --- bookwyrm/templates/import/import_status.html | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/bookwyrm/templates/import/import_status.html b/bookwyrm/templates/import/import_status.html index 61763ec2c..9b4379693 100644 --- a/bookwyrm/templates/import/import_status.html +++ b/bookwyrm/templates/import/import_status.html @@ -51,7 +51,16 @@
    - {{ percent }} % + + {{ percent }} % + {{ percent }}%
    From 905035011343cf4c45b8819af7a1d3229c417db1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 10:18:46 -0800 Subject: [PATCH 116/134] Adds lithuanian locale --- locale/lt_LT/LC_MESSAGES/django.mo | Bin 0 -> 61077 bytes locale/lt_LT/LC_MESSAGES/django.po | 3884 ++++++++++++++++++++++++++++ 2 files changed, 3884 insertions(+) create mode 100644 locale/lt_LT/LC_MESSAGES/django.mo create mode 100644 locale/lt_LT/LC_MESSAGES/django.po diff --git a/locale/lt_LT/LC_MESSAGES/django.mo b/locale/lt_LT/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..9d11576fd32656bb9d97df42d532f370e888691f GIT binary patch literal 61077 zcmca7#4?qEfq_AWnSnuufq~(V1OtOA3j@O)Ly#x~LxB?mgBAk=L!lD`gD3+7!yG3D z1}6pvhD}Zk3^oi53}2lX81xtz7>t}57^E2(7!sWs7>pPg7;2p%`ZhQ-Fo-cQFx+-# zU~phyVEE+Bz!1Q|z+mjcz+k|@z|i8tz#z}Sz_8VYfq|caf#IqP1A{mN1H)4n1_lKN z28O>b3=BRD3=DFv3=AR+3=G+>5cvjI1_oIM28J1~3=AO*3=G>`85q1f_#K7#Q*x z7#I$DFfar&FfbT;GB6}CFfg=wGB89jFfcsxWMGJ7U|?|cVql12U|^W-#lR5Fz`*ds zi-AFqfq@~!n}MNBn><4k*Td2OjPbm__r|-Vt+><#Jt&o3=9&Wa1Vr-a}7%03uItm0i~-zh`V10 zLfpw11X0fy1o5wW5X2qkK@jz>K@fYrf*|1-76dUj2C6P42onEAK@fkoK=n-yg2dO1 zAV@r}41%Q7El_oQ!3+!&7#J92gCXXw3x??55)3i#FjV|%FvOj=q5K!Y5cj_ehWMW) z1mbS)5Qw{_Lm=ukLm=jwg+SEVK-D>iK-?7^0`W&m2qYckgh0Zz6e?aH0&zz>)ZCd+ zdO1{lYX}2_6axdp@eoM(KZ4RhD1HzkrJWh3e;ufRyVJ5s>t15CI8y&j^US zVpqW35h55NCpNA1_lQ6NCt5E zQ~;%`A|d)(A|dhD6AAJERH(kiQ2ypfNc1#aB+!-sP~G7#BWqIB-}EiA^xd~hJ;6BG{jw9(U5SO5)Fx$Inj`G zupY`k5)JXsb*Q?>Q2I4g-DfDDBL-r>Kn%ouu^5Q?@-dL`)r8WvF_3TzjDe)%uoy@< zmBm2Z*Bk>$FI_Q^a(Ph<#2<&D=3a_{_~&*EB;4OX^)bal+|3ya@xNRwBtG<@e1}+w zdjeu1=0!pInXwT66+^}AV+(g@n(RSV;KniG}#@d@RIYH)0|2`6d>UzP>}v zVU2_EMdBdgq7(xCKac^ZJ#Jx?45c?)2LgIH$BE+A|6Cv*33{`hDkpa~7VYr$INzW=t z5dXL&LDUB)LDa`5LF_ApikCt8O-T^*+oAdyseqY-i1whq@LHS9^5OXt<85qn#?fYa%Ja0{g z)H{cu`adQ^{P8mxQeJbXK>8KxDUfh;Nr99@zEFM}lgXj(%VuX_MU{& z_n_u|PJ!4jkP4w?Qz7x7l?rjcNh&0KtWqK2>5&SFU*A-S`|?vE_B5tK+S5}~A>pz* z6%ro1QW+R@85kIDrb67!o(2g|fiy_^H%^1-_fCVD7njDspwGa-P>=?3#{#JMDk!}t z4HEw6(jev4tu%G({DzRXOBI}0-*^8E|pgt&`03ld&xSrB^yvmow{&Vu+q0ZQj)LCVdlEJ*mR z&4Re&P!`0!r=av@sQ8^MNc=y^g82J$7NpZ38f9QA^I(|A?|g`hPWdn8{+@C zY)Cw(W<%0PVKxJU3IhW}OEx5aS7t-ZKbj3m?^m-S;r{@t{~6T$x7iSXeS?bshT6}R z192x;4n$ru2jXwJ97ybAnsoQRlgp}-w)*< z%YlUBH7NZ$2jXsqT!=olTu6VIHy5JLFc*>^+;Sn|RF(?~$BtY`_)W-#q=T8ckpAnI zTu8ZpFBcM?UveS+*nhc@cvsDXgsWX1#Q$DUIx-KEuQT!>=6B^m%%7A8ao6lT28KQc z28Km>3=BG;et14aT^y87%ZG$xUOprp7Ux6!)t(QruQwlJ&dhvBI4;PC_-8{tBp)Aw z@*n3z;^AvP#Q#hM5dGo>ko=-t0Fe(bfVe-U01{ut1rU21q3Wj=K-{yi0FwTeLDior zfVlfM)SSl!kpAX}0tQeNFnlS1_&cc(LT493)Rz=O(qT;@Bp>$|Lfo;S5E9O7q4f4b zNH`uWgt+^0AtXND7ed^@S_Cmqy9nZL<06PZ9E%|K1r$Ndi!6equjC>~Jz87Dz@W{* zz_7FkQhr{9n)3y!{!bCaU2MgWa1}3xgtKNbq+GTvhSZk<#gP0`Pz-Tjbuq*p?Zpsx zO@->4TMUV>wNU<+Vn{i2q!^N(?m*Qumq6UjT>`OB1j<(_f#}yQf%wM+DsEQ-2_N?o zNVsH{K++cB@p*4g6i7KYzLbH%i-CdRE|k_NgOuaNWsr8@qA~^s7tpv?8N}bL<&g9!TMkJF zM&*$D*tHxoj+X?LUs?_c-(BU9^nbJ*5)P-!A^y7r6~9#u3I7M>kaYT{9OBN8Q2JLn zB;1%QAo_Trv}gq+oMkH@>0P%1qR+7c;$JT)Kd}O$KMTq)f$FP;@_V7?O{;)}_q+-Q zhNBD&3~MSN?k}o@jHA_7Lga5&Lc;Yql>Sl)2@l39h&^Ie5O*k4LDHutRNSWu5)NTi zkZ_2pf~4nUsQPXwJ*5hgZs%4(;&DBc-d6=lCugf5?syDU_pu5R56smNcZgL(!b7_n z60Y{u5c9mNA?}K;hQw=HH6;DER73o;x*FoX9o3L<-d7FDcgLzB_CBa)VCZLHVE9%I zvA?Yb;@>GXka(C^1JS>(1|q+u1~M*ts0K2wC|nCkcb>Hj3>z327)oj(II4UqC> zN(03HT@8@*&D{tIm#{`ixt-Mr@%QvbNIWlTgoM|6D1Ub&149u51H-XKNc>wiLDWrc zg7|Mi6C{4tH9_?4ZGyPtWD~@__nRQ*|8IhfC-XEz;ytk$Vs1t=#Q(ROA>pFY0tvt1 z7D)I^EqK@ax(c7#u<4&+QQN zSUMOOycrl6csn5ekL-Z>ClyL>g3ABzfW(t`C!`#y>4b#GK`1TO1sTuI?t--A_jf`3 z@uLe8&fMLQdQq|);xDUii2V-TkZ|&ZiU)Q>(nUCwZtiAan8d)qupX-3sRuGn?%e|^ z_m=fQ;^RsWB%R;xfsChr?SYsZ)(aWGkLzV%s0EFS_d@Iy?1Ru!eUS27xet=hUHcdq zBA6H$GWsC?IXD4Q4~b4>V3^Lpz@Rpffng$Oe0CxOLlOf6L%<|RdB1rQr2Twu5(7gu z0|SHQWJo&QI+=l?7c>q(8B!jFPl1G^>{Lj*$Zskn{S{4xq`Stc3=HWE3=Gq!LdJpr zPlc3&i>5)!?VZyg<@CjA3=9zr3=Hq4LHzAL9b#VMbcnjv>5%+0cRD1W9G(tQ_hC9D ze{#)$q$|xC3=H)k_s)RC|4yj*(HW5Ny*dNpKjxVbd*xo6P|3i+;6E1<{wL=$Ft~!oi|0YYGkG2)KFjAZFqnbL_jwS1KAs1u?>Of}(wD`2 zNcyvz4@n1sP&#rxBt8?N{G$1gbWjDQo1x-8^C96r11XpH?)(O&xfVd=<flggp;lb1lk zWzG^vd@ox9DX-TofrRs!B@lPtUjnI5nU+H8OYx-;cbG1Pgp=b^h<$!g@$jV(_a;N- zi=pBTOCk33EQQ3=q@|GfTeTFLu9rgculOcKSdX_`nGj};89M><0_;c5C zi2cW){L9NB;dFmF#2^2mwD<~0yz8%kgtzAki2Yem@wycdcg|P=$)^jT;yYJB!te45 zNcnJQ1;qV7S3tsxc_qXg&Xo{<$U^x#DRgiGGxC&z59jN%*RgidLTn%xb;A#k8 zVKt=QGFT0XN4wRK@N$KU$3oR*uZDzY^=gQHvsXjxTe=!z&rT@+)M`ljxVIXTKEFU| z_BD|FE42nxde{Z!A72Y`_xZJu@VU7bQvN(y3ki?kYa#K(wGI*}D7|Do#NO@eA?>AW>mlLAvjHM5u>oSf`38u8yf;9? zC2<49pLrV~{;$~p3D52gka(H20ph<^8zAmF0abq+s{SQZ{Kp1J`Nh2v5)Nt`A>n1P z5n`{!Mo4)3Y=p#H_(q63a-iy(HbVLpT^k|p*|ZVjjsqJZ?mrHdf3^`4o_w1i@^YIX zeAP{m^kcdSk`MhiLF^5M%4b5wD>p&hRlf-mf9;zf;V=Pe-dw2ol1&i*uH6I)?*p44 z{=2ye;=eDOAnD-WCP+AoZicv1aWf=d9X3Ps2W^IgW9nu|Jl1Z8xVvvN#C=mYL&9U_ zW=K81Z!^SwpEpCo=l5oazXZ2H^11dFh`iqxh&f?fApVct0x>^#3&cHjTOjV}+5(Bc zIZ*LkTOj^E2Bpt$frQtMEes593=9nSwm|%+x)oBs>2HOk3!kl!_>0~ODKFEuLd1__7MZ4iG~ZG)IQ0V=)( zO7Dcy=e9x2d%O+e-?vclpHOkW?U3-7*ba#|?d=eCZrdU4?V#8~Rd_Ql8gg5gJNceN@fW(W?4v6_WJ0RiZz5~)vNZA2tr|sMUG5`J!h=0C7 z)pP8Gn5VoGV!qZ+h`ClfA?lousFLpuN zO@DSl+^N1B;%@!jkZ`cy4T-nN-4OfpcSHJ34Z9)sAKeYf*Ozuf?0v8sl0M$-hNK79 zJrG)E4Jb zL1Hh&9PPc3^lZNu(th@X(zSab=C0WbX=m?&s{gzf5q+Xpc>b05UL zHBkAP`yl45+XqSC`}RS?=gmGy|Cen)B>pV-L*xVZL;O*{9}<4;`yt^qcRwV)SM7(y z*OvW|aNEBh5{{>#;y3q0{QYDN^pBGdLc)K;L5O<}9)$S&%t45IULJ(l`~4uKd|)^P zsoxb3LHe7Hhamn=J_Lz}>O+ul?LP!@_rgOE_pE@bJ9h{Y|IZFV+$(e#Vz10$NVuyX zhJ>5dVMw?-9frhf>0yX_S`I_PYZ6r7JSe>qs(;I2h&zrShQz~dsCk@6ApQ_M0 z2&6rtas*<(!x4zR-bWzj2Ooi$6MqEKA1yutN!QblK>W7>s_)Pdh(FIl^@dy7gi2Id~LE_8i7(`#lF-UmC9)rY7`Y}lSPd)|-zYS3R z_l`lr<Qj(#+6NWC1XcI@6vThrry>5cJPk3&8%oEWhQw3hX^8%w z(-8M8I1R}!t4~AX_snTX`nr1>V*k_AkZ}Kc8q(kV4>dpe3`BqF8HjlePdXICEdL{N8Bz~)*{8>WA@QRJ<(r>}gp=oah`K#T!6S+=K{ojuL}_Sf-gYAKluX0pLrJ`@l+2L@4Nt6&pHJv|M3FE zex{2M^TaPg(u3(mh<^hvLduW$i;#F|z6hzGR$qkFH@7ZA%16;lkbGc$iGjhBfq^0R z5+wYWUxLKf@k@~Kx_t=}&TlV4#+7(3L(2Jt%Mkm@E<^HB>t#rMPlWR4U55B`)n$lz zn=eDd>oUZ@XQBFUT!w_(bEx=NsD6ekknrHS0!;^3AmL(u1rnZ)S0Ls_UV+$?dj;yA zE0FMMy#jI9tSbg1HI=&l_e5iT@Vz1i`Nc#7?0huo@y#cXz z=?zHuZNC8tr-M*^7j8hp|Kkk?hBgKUhW}7?Z8st6C)|X%bJk6W|2Ex(=-+u0(#}6| z6Ea@Ke+$xI^u5KvaEpO~q4^dhUB%sIU`SzLU|4Y*l5TkKK*|Z_JCOMan>!Hy_ugS( zr~}O_-+{PW@h&9Y2Hu6(-*6Wa{xj}En0xF6#D0mFkoIuiONjfIzJ!GL zj+c;f=-5k$y)Rxu^6Muk|Nl!!{^5KD$!|ih7{L1+99}UnBr`HF6uyG!yZRb3Pj&w_ z#NXC$Ao{Z3K;p0D4Fkh_P`ZSQ7r%wLr{*mKLn8wN!{)b;bYc1q53wmm>3xLF)}cSLG>SGfP~Q-1_p*F3=9mc%nS?{p>iOz1(+aZ$SEcUhCoJ0 zc?Ft7RA6FY*bO!N79#^gFB4?$4y4D0iGd*-Y6fUu%1QKPaqjxaDVoMnQvZIW6*prlwZ%pz`)1Mz+eN_+rh}da2?9t!vLAv z0x1QJeSm1tnu3jt3=Hy6w}JM|fW$#*Z8=m7#J|nRz_1L2nHU)EK+Ssqnpb3k)E^)< zAneD;z);BqnX3ft<@#mK;*#l*mHn~8zpH7KnxGB89lF)%z~VqlmLHBXs|fgzNMfkBRufq|Ks zfx!~Aj)IYa;T0nT0~cts3j+f~KNADPY|uU(sNW5k7#JLx7#PB!W`OKk$OM@i+s?qi z-~m$4#K4dXRX-U@|7L`YOK>nUFx+KeVA#dTz#zy7sS|ja85o2a85nG#W}aYTV3@=F3}#FW41G+HJzYl`85qi8`aod}N~fT7$;iNPgpq+^ zDO663k%7S(Y6i%BCPoGZ2dEr~|B8u$A(4rJ;Xe}t!wg0ShR0C3FetsAiGiVuiGd-K z2{JDt%gDfRl!<}iJOcxRH3I{KD%9+WObiScLFEw>1H&f<28Jn2kn*(^DxU$RL34rU zLGj7Nz@X2_z>vViz%UKu5C#T@3MK{yf2h4sA%=7)A2e4BTEAP%$iTo2DvzMzFm>}m zVa>$AFc%a)P{D9U28PQ}d$k!E7?v|IFic=#VCZ0CV0ZylqYIS>ac6+i4I=|X4S<(R zVA#sQz)-^onQN^Ana{+)aEpn7K^#;Df-GlXV2Ed6U|?osU|7${z`(}Lz+leA!0?NK zfq@a~4kIX?&&0rx%E-VV4N}L*z!1y?X?ry@GBA`t)y#(49mmALa1E5FL1UqekT%I# zMh1q{3=9kgj0_A?j0_B?7#J8%L)Cv}g3Nz|oFv1@!0;I=4%+)C&dk7Y9Lk>swdW9M z?;t2Vm>3uyF)=V~hsuNWH$&Bc*dQDP%A1S~4DUeYA0q=p5fcN00}}(oTd2Cl43M@6 zNG%9wGcquIV`N}h0m>s#HK0B*NG=`92eCIZF)-|8WMFWD+WiwstAWZOM#y@Z22dUW z?XO~BV2A|edqxI^c}xrp??C~7#JRa@-3)rVPIgm#>l|n3JL=T z28Q>H3=AI`AnlViObiSQ7$IwIKu&35WMEjr#K2(9$iT3hiGg81NRRK7b*m& zxEUdBmI6iwhGz^63?~>MZKidM3=H={YagKcK11CJ(l`$)2HLYZ1>`1BdC$baaDoxi zUIfk2UjdaVOpyHo8K6B$AdR5CfJ_VwdQh|0fa(E828NqZInbU<5L2Itf#EMG4KqU4 z4RnCkUNA8*xP#`9L3Tmy7iMN)h-G46;AdoDux5hv(O8%udo87z85kBp)q(b6g3QH+ zmw@(HGB7agWPvfng6L1H*Z!8|H%2 z7PPJrfQo_I=O#>${>Wz3381^$VFoZHPF#Lj=4N|rms-}qnvKAU7CcwwW@Khy*w4hkuo7xFNXap%yFu(}pz<43j)Lkq1_p*ICI*HOsJt$eKE}kr z@Cvlo8MHp0iGjg_k%7S+RR1EG`5B}awC)E~_d)eZKB*A0q?9Cq@PaMrH+V2}m12|#UP1_lOO zMh1pbXn0I#VqoxuvMoV<6i~P@LHdlK^_s^SApOgeOptzbCL;qwCaBzi>bcLzz;GDU zz6I?~U}9h}g^JgL_PT@eFaraF9n>9n85tPPK;`d&@+%``tyeq91E4kaObiTLKzqa( z85s6K#oQSg7^)c|V+^HGvFA`)9BOVR0|Ub(klhRn3|~O@GB7aA1MR5?r8y=B1`a03 z+zm+EQziz6FN_QfeT)nYGePZSCI*JdAPEKr26iR}hA2kJIJy}l1A_=714BN@4kiYM zIwl4NHxL`tXJ&+~wTfY4U^vCdz;FQ6&jYP3gUW-9(*%{rObiT4j0_B4Ky3~N1_lXc z28Nvs3=A7V^);w%1hRvPfkBFyfng~F1H&0m-;$Am;Vj4i1_p*sDE%0eUzr#fHi7o> zGchp4LhYFkr9sL-Yc%&VGBEgo?1Y9fNL(HicAz#nh{M3ZFc;KsVq{>jXJTO30BYAV zFfgoTfQ<2g*4IImF-&KKtWP|~z`(!;gN%PdJ%C`v6XO)V}Vr~qUzx)J#Wsd)-TsRj8(*z_aGV$)n&4E6%LnIK`1 z^0fS-+{6;iVjTrlje^AV)MCwI1u)H^ssWKJNlk%!CMiEZ8>a-wxQxV{wD_XLlFYnx z&0>Y(l0;DOVG4qj<|O8&mqKlXu^Ch~a!X4}6LUb$fJJ~pWqv6%Hn7SUV^t6j^)XUR z5~~i)z`VrVRLx?AjKtzR^%8~R)Dne6g`(8Nl+3(zh4lQy9EG&}A_Y~A%GAUn&0;+U zRSl?yqSW-v;u26`$Ev8t*PHIW2B7>?1 zNGozUqVPdMSe%hql$sI`iWN|RfoO&NJdihw6pAxabIMY2s4B*$EVCpv9_sYs)Wo9X z351yzmW(j+L4K~)2ke4uJG5{nh`@}UuwS_HBYO%@bb3O0!f8AYjS zwn`xXmt<%bE7_@PfMno_D?d#^RRa{Da1oG)if!~0?LeW5WN0QhCLrkp6bp%Yl?otf zRJ+xS;jyCNl%JoCAqzI1K~z{lE@nU`=Vaz(Lll6j z?8^MoB87s);^OlBq7;Sl%$yvBq*S;SU|AG97#tOHGD}KwQWcUiOB525@=HrVHZV9U zC`GB|=f zR-{m#S(2epl95;f=7IuFAu$IO$(0JJ6`92)#UL|5*%78Pvltde=*ogU{j3-q!5&c6 zC`MHB435dksRboaDm4YnC@xmWNi9pwu>$cxO<@MdWKanXrHa9HSt^uL0H=f8{JfG3 zs0c`3NoHAQNhO10N(u-oIF^=VZKiZVUobQGoPqH4)6N9(YF-H{J!Bp@2I432pU zsTIkoMFk}g=cuEW>go)Rd3pJzdC94u`T&Jf%;1<;lBw&QUsR9}Dsvee^D04Dp`<7= zEiE${VjkFgh;#t)U^=+rZDL@eP?TC+ke^qas!*Phnx{}wR0(Rcl;ndle`;~D0;n}u zkXTd#sw_ceM`A%iPG)iiU4?8?teRY*?E1En%>83ryu!B#>NM_wgNMR93*dTMbA zM3s(0acNRkYBIP?0v8yG1qDUuOnDEmBFzn6;xy>6qiC7 zpwb#tBBi8)TKEb!#U(}gdFghj6)99uy%^*jP!60$wPJ8AP07p$B}xWJ-i1;Mo++t$C7EfNU{8W`H7JO2G=E^4K%Gfw4+)Z=pc2Il zj%A4@iA7cnPKn9cU;-32@I(!c3y>5@6opd&aWbq+T@2R?DS{DvaE4)U%FMT7aLOzy z$pDuGRt!!#`5+5HWNHe8mztswS`6|QSPoJ)fGZNHYKTZ_u@wWj00R*yp#c^M0ri!@ z3c@RkauqW2ixF+1;*!doR9mIw{G9wED+Og^BXi@FWNRg8mnfs8q@dVJUtd)NQnEoh zM@VHgs9Hgo4E0xjem2M=^jZ2;nt2%t7gyB^jkjddc~@`nma~#i_bQsi|eD z`k=H?URji@Wapk);!&Cea-JU8eZ>$`AtW<5H77GK70OMjRDgAhK_bN^5E3*%P*Mug zQ;Ucb}W(k}JuEOCwSk42P2yWv*d<9knDto~72GnS9;RNm$cZ~Y6^HR5dQAEa7An2@pn%t=*nOi4)vD@g^_CaDD_a2`Se zIx-2CsVru2fi)sP4f3MY#NzxsE07?(_;g7H4OSH;=44iZ^rWUGmgbZw6yz6|C=?WB zmL(=vg4Ba*I0hF;MF)$1C>IMnfwu(W)S(2EU1M**K zNpW(9f`)r)QEpg+8ETZutT?C|5iAa#3WDRmEw3Q3dn3{Ciy2%~GE2aOf)Z+5R0$%AQnrB2A!P_qiv8z@ppQCXf} zlnw8-D5+|I`Or}>C2$!7siMH70=RVpO6&{}ej=nlZ3X2bVhJK(#o(F;$y#s*NGLrg zvp9pnwWuh+NFgU5G7b)|R3Jj2k^q!bpn27`xFGTH#{3)wjo^aByv*VZO$OI8P|qHe zudEm#(OwLpE3FvZ5;JpB!5w>$(F%|x2N48G<`kzgxFwclCWA^Pw^VQsJ2iy?&QkD% z_6LiR#6V+%kQ&`B6{I*bCl%a(0r%1qD>8FSa}|m+t5U5L3=Mpp7~DWDkhG%A)V!2p z5C`O2H&9nD12b{K#Bnr&m7w}z^94{Y*b$(xNCk~DgF}$PEwczzf|e$MLN^r>>{bkJ z;7KSbrQm>Exxoa3ATvwFP(Gv%D#=LAh3STffEuq5(?IQ9I7>G_FQ*c!71X4FNPuTR z7~JynOHzwKO($^c!!5rkJs&&@f*47$XK({gAStAzf{Q4SouJViD+afs#Jt1H6Elky zG~9|(^O7?(8Qj2Onp4T(o|*?58c9{~OD$J`wkq87K_w$Naf0$4qAqdI&rbnmonnRT z)JiJ`_oBptjLc+(y!^7%90o|n1d|G&(i2`}LWKMhb5lWD@=FU8paTP-LL1cl0@(&? zO@K!E%b+8KbBITNZYl$aK(v}Y13*XAy!{44%PGehP*LForRN zVa4E?25Mz0q-3Umib`nJ4)Q8w*a=*F!5XGIV5Oj*aAta5eo-o9GzZ*1)no7k3qh$A zXe24X)0$^4cv!+S7d$Bmp^%*l76&(&iy5G@!H_Zz$^)0|kkJ^J2xx8*$_7tAfT}hK zKQ)EHGY`}OE=y(b%uCKGO#xN=py`rgIKQ|cKQkw_NFgyNwWx#vRtzYBhOfZGQE(A( z10K$Uq!2haIJE>ccL_2UGOnbMf*78%LKq88?g#-;eFx`(6qckGl_lnYSfJ7_F|#OD z!P5oI%`5@=0z4~>2v2a+8rG#%C`qj-fvGKK@GJ%uJRlo1iz_K%xrVD1*v^#*e|} zkQIYZYGP5ILM|x5!7DOYe-qIGR@DHHxx(uXVt5%>b(M75s}*Qi~u=a0et4 zR0Dx!3i6A=gMwhmVh9Op#3L0MKKY3$kh%;qz*Sn5W5oa#EJ`gd%_#x(+4FN1@=G#O zixiR*OA>SP(@Rr}8GQ1S6LTOWw4vjZpPZeV0&2~J#)cSt^3xSE^Pm(cpJzgHUVag{ zj0086#d=`r{L&H-4N;u0P@J2X19n4tz7>OSVrHH~USe5hI=E4$keixU%HW%r4KCb@ zK*LL*PMAUpvd?szP;CU# zm@d&_PhL96_#$w>SOJm&!9fR!HmG%a5H;XcKu}p|&Ibh;%zR{{AB!WN= zfOP1L6Zfv zKLeWCNzTbk&W0r^@N8RBYEFJR$Q3!2AU(Ltfs%YkO9+(v8T|7LiWM3B3sUpIghD2$ z;iCX5E>p`D$}{s)^2@;zIgq*pT*re{!}#E81+q?~n8CjYIy4VT=itdsCD7tB@aQ18 z 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\n" +"Language-Team: Lithuanian\n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%10==1 && (n%100>19 || n%100<11) ? 0 : (n%10>=2 && n%10<=9) && (n%100>19 || n%100<11) ? 1 : n%1!=0 ? 2: 3);\n" +"X-Crowdin-Project: bookwyrm\n" +"X-Crowdin-Project-ID: 479239\n" +"X-Crowdin-Language: lt\n" +"X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" +"X-Crowdin-File-ID: 1553\n" + +#: bookwyrm/forms.py:242 +msgid "A user with this email already exists." +msgstr "Vartotojas su šiuo el. pašto adresu jau yra." + +#: bookwyrm/forms.py:256 +msgid "One Day" +msgstr "Diena" + +#: bookwyrm/forms.py:257 +msgid "One Week" +msgstr "Savaitė" + +#: bookwyrm/forms.py:258 +msgid "One Month" +msgstr "Mėnuo" + +#: bookwyrm/forms.py:259 +msgid "Does Not Expire" +msgstr "Galiojimas nesibaigia" + +#: bookwyrm/forms.py:263 +#, python-brace-format +msgid "{i} uses" +msgstr "{i} naudoja" + +#: bookwyrm/forms.py:264 +msgid "Unlimited" +msgstr "Neribota" + +#: bookwyrm/forms.py:332 +msgid "List Order" +msgstr "Sąrašo užsakymas" + +#: bookwyrm/forms.py:333 +msgid "Book Title" +msgstr "Knygos antraštė" + +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 +#: bookwyrm/templates/snippets/create_status/review.html:33 +msgid "Rating" +msgstr "Įvertinimas" + +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +msgid "Sort By" +msgstr "Rūšiuoti pagal" + +#: bookwyrm/forms.py:340 +msgid "Ascending" +msgstr "Didėjančia tvarka" + +#: bookwyrm/forms.py:341 +msgid "Descending" +msgstr "Mažėjančia tvarka" + +#: bookwyrm/importers/importer.py:127 +msgid "Error loading book" +msgstr "Klaida įkeliant knygą" + +#: bookwyrm/importers/importer.py:135 +msgid "Could not find a match for book" +msgstr "Nepavyko rasti tokios knygos" + +#: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 +msgid "Pending" +msgstr "Laukiama" + +#: bookwyrm/models/base_model.py:18 +msgid "Self deletion" +msgstr "Išsitrina savaime" + +#: bookwyrm/models/base_model.py:19 +msgid "Moderator suspension" +msgstr "Moderatorius nutraukė" + +#: bookwyrm/models/base_model.py:20 +msgid "Moderator deletion" +msgstr "Moderatorius ištrynė" + +#: bookwyrm/models/base_model.py:21 +msgid "Domain block" +msgstr "Blokuoti pagal domeną" + +#: bookwyrm/models/book.py:233 +msgid "Audiobook" +msgstr "Audioknyga" + +#: bookwyrm/models/book.py:234 +msgid "eBook" +msgstr "Elektroninė knyga" + +#: bookwyrm/models/book.py:235 +msgid "Graphic novel" +msgstr "Grafinė novelė" + +#: bookwyrm/models/book.py:236 +msgid "Hardcover" +msgstr "Knyga kietais viršeliais" + +#: bookwyrm/models/book.py:237 +msgid "Paperback" +msgstr "Knyga minkštais viršeliais" + +#: bookwyrm/models/federated_server.py:11 +#: bookwyrm/templates/settings/federation/edit_instance.html:42 +#: bookwyrm/templates/settings/federation/instance_list.html:19 +msgid "Federated" +msgstr "Susijungę" + +#: bookwyrm/models/federated_server.py:12 +#: bookwyrm/templates/settings/federation/edit_instance.html:43 +#: bookwyrm/templates/settings/federation/instance.html:10 +#: bookwyrm/templates/settings/federation/instance_list.html:23 +msgid "Blocked" +msgstr "Užblokuota" + +#: bookwyrm/models/fields.py:29 +#, python-format +msgid "%(value)s is not a valid remote_id" +msgstr "%(value)s yra negaliojantis remote_id" + +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 +#, python-format +msgid "%(value)s is not a valid username" +msgstr "%(value)s yra negaliojantis naudotojo vardas" + +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 +msgid "username" +msgstr "naudotojo vardas" + +#: bookwyrm/models/fields.py:188 +msgid "A user with that username already exists." +msgstr "Toks naudotojo vardas jau egzistuoja." + +#: bookwyrm/settings.py:118 +msgid "Home Timeline" +msgstr "Pagrindinė siena" + +#: bookwyrm/settings.py:118 +msgid "Home" +msgstr "Pagrindinis" + +#: bookwyrm/settings.py:119 +msgid "Books Timeline" +msgstr "Knygų siena" + +#: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 +#: bookwyrm/templates/search/layout.html:42 +#: bookwyrm/templates/user/layout.html:88 +msgid "Books" +msgstr "Knygos" + +#: bookwyrm/settings.py:165 +msgid "English" +msgstr "Anglų" + +#: bookwyrm/settings.py:166 +msgid "Deutsch (German)" +msgstr "Deutsch (Vokiečių)" + +#: bookwyrm/settings.py:167 +msgid "Español (Spanish)" +msgstr "Español (Ispanų)" + +#: bookwyrm/settings.py:168 +msgid "Français (French)" +msgstr "Français (Prancūzų)" + +#: bookwyrm/settings.py:169 +msgid "Português - Brasil (Brazilian Portuguese)" +msgstr "Português - Brasil (Portugalų–brazilų)" + +#: bookwyrm/settings.py:170 +msgid "简体中文 (Simplified Chinese)" +msgstr "简体中文 (Supaprastinta kinų)" + +#: bookwyrm/settings.py:171 +msgid "繁體中文 (Traditional Chinese)" +msgstr "繁體中文 (Tradicinė kinų)" + +#: bookwyrm/templates/404.html:4 bookwyrm/templates/404.html:8 +msgid "Not Found" +msgstr "Nerasta" + +#: bookwyrm/templates/404.html:9 +msgid "The page you requested doesn't seem to exist!" +msgstr "Jūsų ieškomas puslapis neegzistuoja." + +#: bookwyrm/templates/500.html:4 +msgid "Oops!" +msgstr "Oi!" + +#: bookwyrm/templates/500.html:8 +msgid "Server Error" +msgstr "Serverio klaida" + +#: bookwyrm/templates/500.html:9 +msgid "Something went wrong! Sorry about that." +msgstr "Kažkas nepavyko. Atsiprašome." + +#: bookwyrm/templates/author/author.html:17 +#: bookwyrm/templates/author/author.html:18 +msgid "Edit Author" +msgstr "Keisti autorių" + +#: bookwyrm/templates/author/author.html:34 +#: bookwyrm/templates/author/edit_author.html:43 +msgid "Aliases:" +msgstr "Pseudonimai:" + +#: bookwyrm/templates/author/author.html:45 +msgid "Born:" +msgstr "Gimęs:" + +#: bookwyrm/templates/author/author.html:52 +msgid "Died:" +msgstr "Mirė:" + +#: bookwyrm/templates/author/author.html:61 +msgid "Wikipedia" +msgstr "Wikipedia" + +#: bookwyrm/templates/author/author.html:69 +#: bookwyrm/templates/book/book.html:94 +msgid "View on OpenLibrary" +msgstr "Žiūrėti „OpenLibrary“" + +#: bookwyrm/templates/author/author.html:77 +#: bookwyrm/templates/book/book.html:97 +msgid "View on Inventaire" +msgstr "Žiūrėti „Inventaire“" + +#: bookwyrm/templates/author/author.html:85 +msgid "View on LibraryThing" +msgstr "Žiūrėti „LibraryThing“" + +#: bookwyrm/templates/author/author.html:93 +msgid "View on Goodreads" +msgstr "Žiūrėti „Goodreads“" + +#: bookwyrm/templates/author/author.html:108 +#, python-format +msgid "Books by %(name)s" +msgstr "%(name)s knygos" + +#: bookwyrm/templates/author/edit_author.html:5 +msgid "Edit Author:" +msgstr "Keisti autorių:" + +#: bookwyrm/templates/author/edit_author.html:13 +#: bookwyrm/templates/book/edit/edit_book.html:18 +msgid "Added:" +msgstr "Pridėta:" + +#: bookwyrm/templates/author/edit_author.html:14 +#: bookwyrm/templates/book/edit/edit_book.html:21 +msgid "Updated:" +msgstr "Atnaujinta:" + +#: bookwyrm/templates/author/edit_author.html:16 +#: bookwyrm/templates/book/edit/edit_book.html:25 +msgid "Last edited by:" +msgstr "Pastarąjį kartą redagavo:" + +#: bookwyrm/templates/author/edit_author.html:33 +#: bookwyrm/templates/book/edit/edit_book_form.html:15 +msgid "Metadata" +msgstr "Meta duomenys" + +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 +msgid "Name:" +msgstr "Vardas:" + +#: bookwyrm/templates/author/edit_author.html:45 +#: bookwyrm/templates/book/edit/edit_book_form.html:65 +#: bookwyrm/templates/book/edit/edit_book_form.html:79 +#: bookwyrm/templates/book/edit/edit_book_form.html:124 +msgid "Separate multiple values with commas." +msgstr "Reikšmes atskirkite kableliais." + +#: bookwyrm/templates/author/edit_author.html:52 +msgid "Bio:" +msgstr "Biografija:" + +#: bookwyrm/templates/author/edit_author.html:59 +msgid "Wikipedia link:" +msgstr "Nuoroda į wikipediją:" + +#: bookwyrm/templates/author/edit_author.html:65 +msgid "Birth date:" +msgstr "Gimimo data:" + +#: bookwyrm/templates/author/edit_author.html:73 +msgid "Death date:" +msgstr "Mirties data:" + +#: bookwyrm/templates/author/edit_author.html:81 +msgid "Author Identifiers" +msgstr "Autoriaus identifikatoriai" + +#: bookwyrm/templates/author/edit_author.html:83 +msgid "Openlibrary key:" +msgstr "„Openlibrary“ raktas:" + +#: bookwyrm/templates/author/edit_author.html:91 +#: bookwyrm/templates/book/edit/edit_book_form.html:224 +msgid "Inventaire ID:" +msgstr "„Inventaire“ ID:" + +#: bookwyrm/templates/author/edit_author.html:99 +msgid "Librarything key:" +msgstr "„Librarything“ raktas:" + +#: bookwyrm/templates/author/edit_author.html:107 +msgid "Goodreads key:" +msgstr "„Goodreads“ raktas:" + +#: bookwyrm/templates/author/edit_author.html:118 +#: bookwyrm/templates/book/book.html:140 +#: bookwyrm/templates/book/edit/edit_book.html:110 +#: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 +#: bookwyrm/templates/lists/bookmark_button.html:15 +#: bookwyrm/templates/lists/form.html:75 +#: bookwyrm/templates/preferences/edit_user.html:124 +#: bookwyrm/templates/settings/announcements/announcement_form.html:69 +#: bookwyrm/templates/settings/federation/edit_instance.html:74 +#: bookwyrm/templates/settings/federation/instance.html:87 +#: bookwyrm/templates/settings/site.html:134 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:64 +#: bookwyrm/templates/shelf/form.html:25 +#: bookwyrm/templates/snippets/reading_modals/layout.html:18 +msgid "Save" +msgstr "Išsaugoti" + +#: 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/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 +#: bookwyrm/templates/lists/delete_list_modal.html:17 +#: bookwyrm/templates/settings/federation/instance.html:88 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 +#: bookwyrm/templates/snippets/report_modal.html:34 +msgid "Cancel" +msgstr "Atšaukti" + +#: bookwyrm/templates/book/book.html:47 +#: bookwyrm/templates/discover/large-book.html:22 +#: bookwyrm/templates/landing/large-book.html:25 +#: bookwyrm/templates/landing/small-book.html:18 +msgid "by" +msgstr " " + +#: bookwyrm/templates/book/book.html:55 bookwyrm/templates/book/book.html:56 +msgid "Edit Book" +msgstr "Redaguoti knygą" + +#: bookwyrm/templates/book/book.html:73 +#: bookwyrm/templates/book/cover_modal.html:5 +msgid "Add cover" +msgstr "Pridėti viršelį" + +#: bookwyrm/templates/book/book.html:77 +msgid "Failed to load cover" +msgstr "Nepavyko įkelti viršelio" + +#: bookwyrm/templates/book/book.html:117 +#, python-format +msgid "(%(review_count)s review)" +msgid_plural "(%(review_count)s reviews)" +msgstr[0] "(%(review_count)s atsiliepimas)" +msgstr[1] "(%(review_count)s atsiliepimai)" +msgstr[2] "(%(review_count)s atsiliepimų)" +msgstr[3] "(%(review_count)s atsiliepimai)" + +#: bookwyrm/templates/book/book.html:129 +msgid "Add Description" +msgstr "Pridėti aprašymą" + +#: bookwyrm/templates/book/book.html:136 +#: bookwyrm/templates/book/edit/edit_book_form.html:34 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 +msgid "Description:" +msgstr "Aprašymas:" + +#: bookwyrm/templates/book/book.html:150 +#, python-format +msgid "%(count)s editions" +msgstr "%(count)s leidimai (-ų)" + +#: bookwyrm/templates/book/book.html:158 +#, python-format +msgid "This edition is on your %(shelf_name)s shelf." +msgstr "Šis leidimas yra jūsų %(shelf_name)s lentynoje." + +#: bookwyrm/templates/book/book.html:164 +#, python-format +msgid "A different edition of this book is on your %(shelf_name)s shelf." +msgstr "kitas šios knygos leidimas yra jūsų %(shelf_name)s lentynoje." + +#: bookwyrm/templates/book/book.html:175 +msgid "Your reading activity" +msgstr "Jūsų skaitymo veikla" + +#: bookwyrm/templates/book/book.html:178 +msgid "Add read dates" +msgstr "Pridėti skaitymo datas" + +#: bookwyrm/templates/book/book.html:187 +msgid "Create" +msgstr "Kurti" + +#: bookwyrm/templates/book/book.html:197 +msgid "You don't have any reading activity for this book." +msgstr "Šios knygos neskaitote." + +#: bookwyrm/templates/book/book.html:218 +msgid "Reviews" +msgstr "Apžvalgos" + +#: bookwyrm/templates/book/book.html:223 +msgid "Your reviews" +msgstr "Tavo atsiliepimai" + +#: bookwyrm/templates/book/book.html:229 +msgid "Your comments" +msgstr "Tavo komentarai" + +#: bookwyrm/templates/book/book.html:235 +msgid "Your quotes" +msgstr "Jūsų citatos" + +#: bookwyrm/templates/book/book.html:271 +msgid "Subjects" +msgstr "Temos" + +#: bookwyrm/templates/book/book.html:283 +msgid "Places" +msgstr "Vietos" + +#: bookwyrm/templates/book/book.html:294 bookwyrm/templates/layout.html:75 +#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 +#: bookwyrm/templates/search/layout.html:25 +#: bookwyrm/templates/search/layout.html:50 +#: bookwyrm/templates/user/layout.html:82 +msgid "Lists" +msgstr "Sąrašai" + +#: bookwyrm/templates/book/book.html:305 +msgid "Add to list" +msgstr "Pridėti prie sąrašo" + +#: bookwyrm/templates/book/book.html:315 +#: bookwyrm/templates/book/cover_modal.html:31 +#: bookwyrm/templates/lists/list.html:182 +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 +msgid "Add" +msgstr "Pridėti" + +#: bookwyrm/templates/book/book_identifiers.html:8 +msgid "ISBN:" +msgstr "ISBN:" + +#: bookwyrm/templates/book/book_identifiers.html:15 +#: bookwyrm/templates/book/edit/edit_book_form.html:232 +msgid "OCLC Number:" +msgstr "OCLC numeris:" + +#: bookwyrm/templates/book/book_identifiers.html:22 +#: bookwyrm/templates/book/edit/edit_book_form.html:240 +msgid "ASIN:" +msgstr "ASIN:" + +#: bookwyrm/templates/book/cover_modal.html:17 +#: bookwyrm/templates/book/edit/edit_book_form.html:143 +msgid "Upload cover:" +msgstr "Įkelti viršelį:" + +#: bookwyrm/templates/book/cover_modal.html:23 +#: bookwyrm/templates/book/edit/edit_book_form.html:148 +msgid "Load cover from url:" +msgstr "Įkelti viršelį iš url:" + +#: bookwyrm/templates/book/edit/edit_book.html:5 +#: bookwyrm/templates/book/edit/edit_book.html:11 +#, python-format +msgid "Edit \"%(book_title)s\"" +msgstr "Redaguoti „%(book_title)s“" + +#: bookwyrm/templates/book/edit/edit_book.html:5 +#: bookwyrm/templates/book/edit/edit_book.html:13 +msgid "Add Book" +msgstr "Pridėti knygą" + +#: bookwyrm/templates/book/edit/edit_book.html:47 +msgid "Confirm Book Info" +msgstr "Patvirtinti knygos informaciją" + +#: bookwyrm/templates/book/edit/edit_book.html:55 +#, python-format +msgid "Is \"%(name)s\" an existing author?" +msgstr "Yra „%(name)s“ egzistuojantis autorius?" + +#: bookwyrm/templates/book/edit/edit_book.html:64 +#, python-format +msgid "Author of %(book_title)s" +msgstr "%(book_title)s autorius" + +#: bookwyrm/templates/book/edit/edit_book.html:68 +msgid "This is a new author" +msgstr "Tai naujas autorius" + +#: bookwyrm/templates/book/edit/edit_book.html:75 +#, python-format +msgid "Creating a new author: %(name)s" +msgstr "Kuriamas naujas autorius: %(name)s" + +#: bookwyrm/templates/book/edit/edit_book.html:82 +msgid "Is this an edition of an existing work?" +msgstr "Ar tai egzistuojančio darbo leidimas?" + +#: bookwyrm/templates/book/edit/edit_book.html:90 +msgid "This is a new work" +msgstr "Tai naujas darbas" + +#: bookwyrm/templates/book/edit/edit_book.html:97 +#: 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 "Patvirtinti" + +#: bookwyrm/templates/book/edit/edit_book.html:99 +#: bookwyrm/templates/feed/status.html:9 +msgid "Back" +msgstr "Atgal" + +#: bookwyrm/templates/book/edit/edit_book_form.html:18 +#: bookwyrm/templates/snippets/create_status/review.html:16 +msgid "Title:" +msgstr "Pavadinimas:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:26 +msgid "Subtitle:" +msgstr "Paantraštė:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:44 +msgid "Series:" +msgstr "Serija:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:53 +msgid "Series number:" +msgstr "Serijos numeris:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:63 +msgid "Languages:" +msgstr "Kalbos:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:74 +msgid "Publication" +msgstr "Paskelbimas" + +#: bookwyrm/templates/book/edit/edit_book_form.html:77 +msgid "Publisher:" +msgstr "Leidėjas:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:86 +msgid "First published date:" +msgstr "Pirmoji publikavimo data:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:94 +msgid "Published date:" +msgstr "Publikavimo data:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:104 +msgid "Authors" +msgstr "Autoriai" + +#: bookwyrm/templates/book/edit/edit_book_form.html:112 +#, python-format +msgid "Remove %(name)s" +msgstr "Pašalinti %(name)s" + +#: bookwyrm/templates/book/edit/edit_book_form.html:115 +#, python-format +msgid "Author page for %(name)s" +msgstr "Autoriaus puslapis %(name)s" + +#: bookwyrm/templates/book/edit/edit_book_form.html:122 +msgid "Add Authors:" +msgstr "Pridėti autorius:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:123 +msgid "John Doe, Jane Smith" +msgstr "John Doe, Jane Smith" + +#: bookwyrm/templates/book/edit/edit_book_form.html:132 +#: bookwyrm/templates/shelf/shelf.html:140 +msgid "Cover" +msgstr "Viršelis" + +#: bookwyrm/templates/book/edit/edit_book_form.html:161 +msgid "Physical Properties" +msgstr "Fizinės savybės" + +#: bookwyrm/templates/book/edit/edit_book_form.html:166 +#: bookwyrm/templates/book/editions/format_filter.html:5 +msgid "Format:" +msgstr "Formatas:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:177 +msgid "Format details:" +msgstr "Informacija apie formatą:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:187 +msgid "Pages:" +msgstr "Puslapiai:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:197 +msgid "Book Identifiers" +msgstr "Knygos identifikatoriai" + +#: bookwyrm/templates/book/edit/edit_book_form.html:200 +msgid "ISBN 13:" +msgstr "ISBN 13:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:208 +msgid "ISBN 10:" +msgstr "ISBN 10:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:216 +msgid "Openlibrary ID:" +msgstr "„Openlibrary“ ID:" + +#: bookwyrm/templates/book/editions/editions.html:4 +#, python-format +msgid "Editions of %(book_title)s" +msgstr "Knygos %(book_title)s leidimai" + +#: bookwyrm/templates/book/editions/editions.html:8 +#, python-format +msgid "Editions of \"%(work_title)s\"" +msgstr "\"%(work_title)s\" leidimai" + +#: bookwyrm/templates/book/editions/format_filter.html:8 +#: bookwyrm/templates/book/editions/language_filter.html:8 +msgid "Any" +msgstr "Bet kas" + +#: bookwyrm/templates/book/editions/language_filter.html:5 +#: bookwyrm/templates/preferences/edit_user.html:95 +msgid "Language:" +msgstr "Kalba:" + +#: bookwyrm/templates/book/editions/search_filter.html:5 +msgid "Search editions" +msgstr "Paieškos leidimai" + +#: bookwyrm/templates/book/publisher_info.html:23 +#, python-format +msgid "%(format)s, %(pages)s pages" +msgstr "%(format)s, %(pages)s psl." + +#: bookwyrm/templates/book/publisher_info.html:25 +#, python-format +msgid "%(pages)s pages" +msgstr "%(pages)s psl." + +#: bookwyrm/templates/book/publisher_info.html:38 +#, python-format +msgid "%(languages)s language" +msgstr "%(languages)s kalba" + +#: bookwyrm/templates/book/publisher_info.html:65 +#, python-format +msgid "Published %(date)s by %(publisher)s." +msgstr "Publikuota %(date)s, %(publisher)s." + +#: bookwyrm/templates/book/publisher_info.html:67 +#, python-format +msgid "Published %(date)s" +msgstr "Publikuota %(date)s" + +#: bookwyrm/templates/book/publisher_info.html:69 +#, python-format +msgid "Published by %(publisher)s." +msgstr "Publikavo %(publisher)s." + +#: bookwyrm/templates/book/rating.html:13 +msgid "rated it" +msgstr "įvertino" + +#: bookwyrm/templates/book/readthrough.html:8 +msgid "Progress Updates:" +msgstr "Informacija apie progresą:" + +#: bookwyrm/templates/book/readthrough.html:13 +msgid "finished" +msgstr "baigta" + +#: bookwyrm/templates/book/readthrough.html:24 +msgid "Show all updates" +msgstr "Rodyti visus naujinius" + +#: bookwyrm/templates/book/readthrough.html:40 +msgid "Delete this progress update" +msgstr "Ištrinti progreso naujinį" + +#: bookwyrm/templates/book/readthrough.html:51 +msgid "started" +msgstr "pradėta" + +#: bookwyrm/templates/book/readthrough.html:58 +#: bookwyrm/templates/book/readthrough.html:72 +msgid "Edit read dates" +msgstr "Redaguoti skaitymo datas" + +#: bookwyrm/templates/book/readthrough.html:62 +msgid "Delete these read dates" +msgstr "Ištrinti šias skaitymo datas" + +#: bookwyrm/templates/components/inline_form.html:8 +#: bookwyrm/templates/components/modal.html:11 +#: bookwyrm/templates/components/tooltip.html:7 +#: bookwyrm/templates/feed/layout.html:71 +#: bookwyrm/templates/get_started/layout.html:20 +#: bookwyrm/templates/get_started/layout.html:53 +#: bookwyrm/templates/search/book.html:49 +#: bookwyrm/templates/snippets/announcement.html:18 +msgid "Close" +msgstr "Uždaryti" + +#: bookwyrm/templates/components/tooltip.html:3 +msgid "Help" +msgstr "Pagalba" + +#: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8 +msgid "Edit status" +msgstr "Redagavimo būsena" + +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +msgid "Confirm email" +msgstr "Patvirtinti el. paštą" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +msgid "Confirm your email address" +msgstr "Patvirtinkite el. pašto adresą" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "Į paskyros registracijai naudotą el. paštą buvo išsiųstas patvirtinimo kodas." + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "Deja, šio kodo neradome." + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/settings/users/user_info.html:85 +msgid "Confirmation code:" +msgstr "Patvirtinimo kodas:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/landing/layout.html:73 +#: bookwyrm/templates/settings/dashboard/dashboard.html:93 +#: bookwyrm/templates/snippets/report_modal.html:33 +msgid "Submit" +msgstr "Siųsti" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "Nerandate savo kodo?" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "Dar kartą išsiųsti patvirtinimo nuorodą" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/landing/layout.html:67 +#: bookwyrm/templates/landing/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:56 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "El. pašto adresas:" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +msgid "Resend link" +msgstr "Dar kartą išsiųsti nuorodą" + +#: bookwyrm/templates/directory/community_filter.html:5 +msgid "Community" +msgstr "Bendruomenė" + +#: bookwyrm/templates/directory/community_filter.html:8 +msgid "Local users" +msgstr "Vietiniai nariai" + +#: bookwyrm/templates/directory/community_filter.html:12 +msgid "Federated community" +msgstr "Sujungta bendruomenė" + +#: bookwyrm/templates/directory/directory.html:4 +#: bookwyrm/templates/directory/directory.html:9 +#: bookwyrm/templates/layout.html:101 +msgid "Directory" +msgstr "Bendruomenė" + +#: bookwyrm/templates/directory/directory.html:17 +msgid "Make your profile discoverable to other BookWyrm users." +msgstr "Savo paskyrą leiskite atrasti kitiems „BookWyrm“ nariems." + +#: bookwyrm/templates/directory/directory.html:24 +#, python-format +msgid "You can opt-out at any time in your profile settings." +msgstr "Tai galite visada atšaukti paskyros nustatymuose." + +#: bookwyrm/templates/directory/directory.html:29 +#: bookwyrm/templates/feed/goal_card.html:17 +#: bookwyrm/templates/snippets/announcement.html:34 +msgid "Dismiss message" +msgstr "Pašalinti pranešimą" + +#: bookwyrm/templates/directory/sort_filter.html:5 +msgid "Order by" +msgstr "Rūšiuoti pagal" + +#: bookwyrm/templates/directory/sort_filter.html:8 +msgid "Recently active" +msgstr "Neseniai aktyvus" + +#: bookwyrm/templates/directory/sort_filter.html:9 +msgid "Suggested" +msgstr "Pasiūlyta" + +#: bookwyrm/templates/directory/user_card.html:17 +#: bookwyrm/templates/directory/user_card.html:18 +#: bookwyrm/templates/user/user_preview.html:16 +#: bookwyrm/templates/user/user_preview.html:17 +msgid "Locked account" +msgstr "Užrakinta paskyra" + +#: bookwyrm/templates/directory/user_card.html:40 +msgid "follower you follow" +msgid_plural "followers you follow" +msgstr[0] "jūs sekate" +msgstr[1] "jūs sekate" +msgstr[2] "jūs sekate" +msgstr[3] "jūs sekate" + +#: bookwyrm/templates/directory/user_card.html:47 +msgid "book on your shelves" +msgid_plural "books on your shelves" +msgstr[0] "jūsų lentynoje esanti knyga" +msgstr[1] "jūsų lentynose esančios knygos" +msgstr[2] "jūsų lentynose esančios knygos" +msgstr[3] "jūsų lentynose esančios knygos" + +#: bookwyrm/templates/directory/user_card.html:55 +msgid "posts" +msgstr "įrašai" + +#: bookwyrm/templates/directory/user_card.html:61 +msgid "last active" +msgstr "pastarąjį kartą aktyvus" + +#: bookwyrm/templates/directory/user_type_filter.html:5 +msgid "User type" +msgstr "Naudotojo tipas" + +#: bookwyrm/templates/directory/user_type_filter.html:8 +msgid "BookWyrm users" +msgstr "„BookWyrm“ nariai" + +#: bookwyrm/templates/directory/user_type_filter.html:12 +msgid "All known users" +msgstr "Visi žinomi nariai" + +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 +#, python-format +msgid "%(username)s rated %(book_title)s" +msgstr "%(username)s įvertino %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:27 +#, python-format +msgid "%(username)s reviewed %(book_title)s" +msgstr "%(username)s peržiūrėjo %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:31 +#, python-format +msgid "%(username)s commented on %(book_title)s" +msgstr "%(username)s pakomentavo prie knygos %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:35 +#, python-format +msgid "%(username)s quoted %(book_title)s" +msgstr "%(username)s citavo %(book_title)s" + +#: bookwyrm/templates/discover/discover.html:4 +#: bookwyrm/templates/discover/discover.html:10 +#: bookwyrm/templates/layout.html:78 +msgid "Discover" +msgstr "Atraskite" + +#: bookwyrm/templates/discover/discover.html:12 +#, python-format +msgid "See what's new in the local %(site_name)s community" +msgstr "Kas naujo mūsų %(site_name)s bendruomenėje" + +#: bookwyrm/templates/discover/large-book.html:52 +#: bookwyrm/templates/discover/small-book.html:36 +msgid "View status" +msgstr "Peržiūrėti būseną" + +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "Paskutinis žingsnis prieš prisijungiant prie %(site_name)s! Patvirtinkite el. pašto adresą spausdami nuorodą žemiau:" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +msgid "Confirm Email" +msgstr "Patvirtinti el. paštą" + +#: bookwyrm/templates/email/confirm/html_content.html:15 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "Arba suveskite kodą \"%(confirmation_code)s\" prisijungimo metu." + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "Patvirtinkite savo el. pašto adresą" + +#: bookwyrm/templates/email/confirm/text_content.html:10 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "Arba suveskite kodą \"%(confirmation_code)s\" prisijungimo metu." + +#: bookwyrm/templates/email/html_layout.html:15 +#: bookwyrm/templates/email/text_layout.html:2 +msgid "Hi there," +msgstr "Labas!" + +#: bookwyrm/templates/email/html_layout.html:21 +#, python-format +msgid "BookWyrm hosted on %(site_name)s" +msgstr "BookWyrm talpinamas %(site_name)s" + +#: bookwyrm/templates/email/html_layout.html:23 +msgid "Email preference" +msgstr "El. pašto nustatymai" + +#: bookwyrm/templates/email/invite/html_content.html:6 +#: bookwyrm/templates/email/invite/subject.html:2 +#, python-format +msgid "You're invited to join %(site_name)s!" +msgstr "Esate pakviesti prisijungti prie %(site_name)s!" + +#: bookwyrm/templates/email/invite/html_content.html:9 +msgid "Join Now" +msgstr "Prisijungti dabar" + +#: bookwyrm/templates/email/invite/html_content.html:15 +#, python-format +msgid "Learn more about %(site_name)s." +msgstr "Sužinoti daugiau apie %(site_name)s." + +#: bookwyrm/templates/email/invite/text_content.html:4 +#, python-format +msgid "You're invited to join %(site_name)s! Click the link below to create an account." +msgstr "Esate pakviesti prisijungti prie %(site_name)s! Spauskite nuorodą žemiau, kad sukurtumėte paskyrą." + +#: bookwyrm/templates/email/invite/text_content.html:8 +#, python-format +msgid "Learn more about %(site_name)s:" +msgstr "Sužinoti daugiau apie %(site_name)s:" + +#: bookwyrm/templates/email/password_reset/html_content.html:6 +#: bookwyrm/templates/email/password_reset/text_content.html:4 +#, python-format +msgid "You requested to reset your %(site_name)s password. Click the link below to set a new password and log in to your account." +msgstr "Prašėte pakeisti %(site_name)s slaptažodį. Spauskite žemiau, kad pakeisti slaptažodį ir prisijungti prie savo paskyros." + +#: bookwyrm/templates/email/password_reset/html_content.html:9 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 +msgid "Reset Password" +msgstr "Atstatyti slaptažodį" + +#: bookwyrm/templates/email/password_reset/html_content.html:13 +#: bookwyrm/templates/email/password_reset/text_content.html:8 +msgid "If you didn't request to reset your password, you can ignore this email." +msgstr "Jei nenorite pakeisti savo slaptažodžio - ignoruokite šį laišką." + +#: bookwyrm/templates/email/password_reset/subject.html:2 +#, python-format +msgid "Reset your %(site_name)s password" +msgstr "Keisti %(site_name)s slaptažodį" + +#: bookwyrm/templates/feed/direct_messages.html:8 +#, python-format +msgid "Direct Messages with %(username)s" +msgstr "Asmeninis susirašinėjimas su %(username)s" + +#: bookwyrm/templates/feed/direct_messages.html:10 +#: bookwyrm/templates/layout.html:111 +msgid "Direct Messages" +msgstr "Asmeninės žinutės" + +#: bookwyrm/templates/feed/direct_messages.html:13 +msgid "All messages" +msgstr "Visos žinutės" + +#: bookwyrm/templates/feed/direct_messages.html:22 +msgid "You have no messages right now." +msgstr "Neturite žinučių." + +#: bookwyrm/templates/feed/feed.html:22 +#, python-format +msgid "load 0 unread status(es)" +msgstr "įkelti 0 neperskaitytų būsena" + +#: bookwyrm/templates/feed/feed.html:38 +msgid "There aren't any activities right now! Try following a user to get started" +msgstr "Šiuo metu įrašų nėra. Norėdami matyti, sekite narį." + +#: bookwyrm/templates/feed/goal_card.html:6 +#: bookwyrm/templates/feed/layout.html:90 +#: bookwyrm/templates/user/goal_form.html:6 +#, python-format +msgid "%(year)s Reading Goal" +msgstr "%(year)s skaitymo tikslas" + +#: bookwyrm/templates/feed/goal_card.html:18 +#, python-format +msgid "You can set or change your reading goal any time from your profile page" +msgstr "Bet kuriuo metu galite pakeisti savo skaitymo tikslą savo paskyros puslapyje" + +#: bookwyrm/templates/feed/layout.html:5 +msgid "Updates" +msgstr "Atnaujinimai" + +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" +msgstr "Jūsų knygos" + +#: bookwyrm/templates/feed/layout.html:14 +msgid "There are no books here right now! Try searching for a book to get started" +msgstr "Knygų neturite. Raskite knygą ir pradėkite." + +#: bookwyrm/templates/feed/layout.html:25 +#: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 +msgid "To Read" +msgstr "Perskaityti" + +#: bookwyrm/templates/feed/layout.html:26 +#: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 +msgid "Currently Reading" +msgstr "Šiuo metu skaitoma" + +#: bookwyrm/templates/feed/layout.html:27 +#: bookwyrm/templates/shelf/shelf.html:42 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 +msgid "Read" +msgstr "Perskaičiau" + +#: bookwyrm/templates/feed/suggested_users.html:5 +#: bookwyrm/templates/get_started/users.html:6 +msgid "Who to follow" +msgstr "Ką sekti" + +#: bookwyrm/templates/feed/suggested_users.html:9 +msgid "Don't show suggested users" +msgstr "Nerodyti siūlomų vartotojų" + +#: bookwyrm/templates/feed/suggested_users.html:14 +msgid "View directory" +msgstr "Žiūrėti katalogą" + +#: bookwyrm/templates/get_started/book_preview.html:6 +#, python-format +msgid "Have you read %(book_title)s?" +msgstr "Ar skaitėte „%(book_title)s“?" + +#: bookwyrm/templates/get_started/books.html:6 +msgid "What are you reading?" +msgstr "Ką skaitome?" + +#: bookwyrm/templates/get_started/books.html:9 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 +msgid "Search for a book" +msgstr "Ieškoti knygos" + +#: bookwyrm/templates/get_started/books.html:11 +#, python-format +msgid "No books found for \"%(query)s\"" +msgstr "Pagal paiešką „%(query)s“ knygos nerasta" + +#: bookwyrm/templates/get_started/books.html:11 +#, python-format +msgid "You can add books when you start using %(site_name)s." +msgstr "Kai pradedate naudotis %(site_name)s, galite pridėti knygų." + +#: bookwyrm/templates/get_started/books.html:16 +#: bookwyrm/templates/get_started/books.html:17 +#: bookwyrm/templates/get_started/users.html:18 +#: bookwyrm/templates/get_started/users.html:19 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/search/layout.html:4 +#: bookwyrm/templates/search/layout.html:9 +msgid "Search" +msgstr "Paieška" + +#: bookwyrm/templates/get_started/books.html:27 +msgid "Suggested Books" +msgstr "Siūlomos knygos" + +#: bookwyrm/templates/get_started/books.html:46 +#, python-format +msgid "Popular on %(site_name)s" +msgstr "%(site_name)s populiaru" + +#: bookwyrm/templates/get_started/books.html:58 +#: bookwyrm/templates/lists/list.html:155 +msgid "No books found" +msgstr "Knygų nerasta" + +#: bookwyrm/templates/get_started/books.html:63 +#: bookwyrm/templates/get_started/profile.html:54 +msgid "Save & continue" +msgstr "Išsaugoti ir tęsti" + +#: bookwyrm/templates/get_started/layout.html:5 +#: bookwyrm/templates/landing/layout.html:5 +msgid "Welcome" +msgstr "Sveiki atvykę" + +#: bookwyrm/templates/get_started/layout.html:15 +#, python-format +msgid "Welcome to %(site_name)s!" +msgstr "Sveiki atvykę į %(site_name)s!" + +#: bookwyrm/templates/get_started/layout.html:17 +msgid "These are some first steps to get you started." +msgstr "Pirmieji žingsniai, norint pradėti." + +#: bookwyrm/templates/get_started/layout.html:31 +#: bookwyrm/templates/get_started/profile.html:6 +msgid "Create your profile" +msgstr "Susikurkite paskyrą" + +#: bookwyrm/templates/get_started/layout.html:35 +msgid "Add books" +msgstr "Pridėti knygas" + +#: bookwyrm/templates/get_started/layout.html:39 +msgid "Find friends" +msgstr "Rasti draugų" + +#: bookwyrm/templates/get_started/layout.html:45 +msgid "Skip this step" +msgstr "Praleisti šį žingsnį" + +#: bookwyrm/templates/get_started/layout.html:49 +msgid "Finish" +msgstr "Baigti" + +#: bookwyrm/templates/get_started/profile.html:15 +#: bookwyrm/templates/preferences/edit_user.html:42 +msgid "Display name:" +msgstr "Rodyti vardą:" + +#: bookwyrm/templates/get_started/profile.html:22 +#: bookwyrm/templates/preferences/edit_user.html:49 +msgid "Summary:" +msgstr "Santrauka:" + +#: bookwyrm/templates/get_started/profile.html:23 +msgid "A little bit about you" +msgstr "Šiek tiek apie jus" + +#: bookwyrm/templates/get_started/profile.html:32 +#: bookwyrm/templates/preferences/edit_user.html:27 +msgid "Avatar:" +msgstr "Avataras:" + +#: bookwyrm/templates/get_started/profile.html:42 +#: bookwyrm/templates/preferences/edit_user.html:110 +msgid "Manually approve followers:" +msgstr "Noriu tvirtinti sekėjus:" + +#: bookwyrm/templates/get_started/profile.html:48 +#: bookwyrm/templates/preferences/edit_user.html:80 +msgid "Show this account in suggested users:" +msgstr "Paskyrą įtraukti į siūlomus narius:" + +#: bookwyrm/templates/get_started/profile.html:52 +msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." +msgstr "Jūsų paskyra atsiras kataloge ir gali būti rekomenduota kitiems „BookWyrm“ nariams." + +#: bookwyrm/templates/get_started/users.html:11 +msgid "Search for a user" +msgstr "Ieškoti naudotojo" + +#: bookwyrm/templates/get_started/users.html:13 +#, python-format +msgid "No users found for \"%(query)s\"" +msgstr "Pagal paiešką „%(query)s“ nieko nerasta" + +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Sukurti grupę" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Tvarko %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "Ištrinti šią grupę?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Nebegalite atšaukti šio veiksmo" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Ištrinti" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Redaguoti grupę" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "Pridėkite naujų narių!" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Grupės pavadinimas:" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Grupės aprašymas:" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Ištrinti grupę" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Ieškokite, kad pridėtumėte naudotoją" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Šioje grupėje nėra sąrašų" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Redaguoti grupę" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Nariai gali pridėti ir pašalinti knygas grupės knygų sąrašuose" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Išeiti iš grupės" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Jus seka" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "Sekate %(mutuals)s bendrą žmogų" +msgstr[1] "Sekate %(mutuals)s bendrus žmones" +msgstr[2] "Sekate %(mutuals)s bendrų žmonių" +msgstr[3] "Sekate %(mutuals)s bendrų žmonių" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s knyga jūsų lentynoje" +msgstr[1] "%(shared_books)s knygos jūsų lentynose" +msgstr[2] "%(shared_books)s knygų jūsų lentynose" +msgstr[3] "%(shared_books)s knygų jūsų lentynose" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "Užklausa „%(user_query)s“ nerasta potencialių narių" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Vadovas" + +#: bookwyrm/templates/import/import.html:5 +#: bookwyrm/templates/import/import.html:9 +#: bookwyrm/templates/shelf/shelf.html:61 +msgid "Import Books" +msgstr "Importuoti knygas" + +#: bookwyrm/templates/import/import.html:18 +msgid "Data source:" +msgstr "Duomenų šaltinis:" + +#: bookwyrm/templates/import/import.html:37 +msgid "Data file:" +msgstr "Duomenų failas:" + +#: bookwyrm/templates/import/import.html:45 +msgid "Include reviews" +msgstr "Įtraukti atsiliepimus" + +#: bookwyrm/templates/import/import.html:50 +msgid "Privacy setting for imported reviews:" +msgstr "Privatumo nustatymai svarbiems atsiliepimams:" + +#: bookwyrm/templates/import/import.html:56 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:64 +msgid "Import" +msgstr "Importuoti" + +#: bookwyrm/templates/import/import.html:61 +msgid "Recent Imports" +msgstr "Pastaruoju metu importuota" + +#: bookwyrm/templates/import/import.html:63 +msgid "No recent imports" +msgstr "Pastaruoju metu neimportuota" + +#: bookwyrm/templates/import/import_status.html:6 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 +msgid "Import Status" +msgstr "Importavimo būsena" + +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 +msgid "Import started:" +msgstr "Importavimas prasidėjo:" + +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:50 +msgid "Refresh" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:62 +#, python-format +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" +msgstr[3] "" + +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 +msgid "Title" +msgstr "Pavadinimas" + +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 +msgid "Author" +msgstr "Autorius" + +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "Peržiūra" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Knyga" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Būsena" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 +msgid "Imported" +msgstr "Importuota" + +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Patvirtinti" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + +#: bookwyrm/templates/import/tooltip.html:6 +msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." +msgstr "Galite atsisiųsti savo „Goodreads“ duomenis iš Importavimo ir eksportavimo puslapio, esančio jūsų „Goodreads“ paskyroje." + +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + +#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 +#, python-format +msgid "About %(site_name)s" +msgstr "Apie %(site_name)s" + +#: bookwyrm/templates/landing/about.html:10 +#: bookwyrm/templates/landing/about.html:20 +msgid "Code of Conduct" +msgstr "Elgesio kodeksas" + +#: bookwyrm/templates/landing/about.html:13 +#: bookwyrm/templates/landing/about.html:29 +msgid "Privacy Policy" +msgstr "Privatumo politika" + +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Kurti paskyrą" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Prieiga draudžiama" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "Deja, šis pakvietimo kodas nebegalioja." + +#: bookwyrm/templates/landing/landing.html:6 +msgid "Recent Books" +msgstr "Naujos knygos" + +#: bookwyrm/templates/landing/layout.html:17 +msgid "Decentralized" +msgstr "Decentralizuota" + +#: bookwyrm/templates/landing/layout.html:23 +msgid "Friendly" +msgstr "Draugiškas" + +#: bookwyrm/templates/landing/layout.html:29 +msgid "Anti-Corporate" +msgstr "Nekorporacinis" + +#: bookwyrm/templates/landing/layout.html:45 +#, python-format +msgid "Join %(name)s" +msgstr "Prisijunkite prie %(name)s" + +#: bookwyrm/templates/landing/layout.html:47 +msgid "Request an Invitation" +msgstr "Prašyti kvietimo" + +#: bookwyrm/templates/landing/layout.html:49 +#, python-format +msgid "%(name)s registration is closed" +msgstr "%(name)s – registracija uždaryta" + +#: bookwyrm/templates/landing/layout.html:60 +msgid "Thank you! Your request has been received." +msgstr "Dėkojame, jūsų prašymas gautas." + +#: bookwyrm/templates/landing/layout.html:82 +msgid "Your Account" +msgstr "Jūsų paskyra" + +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Prisijungti" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Prisijunkite" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "Džiugu, el. pašto adresas patvirtintas." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Naudotojo vardas:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Slaptažodis:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "Pamiršote slaptažodį?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "Daugiau apie šią svetainę" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Patvirtinti slaptažodį:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Jūsų el. pašto adresu bus išsiųsta nuoroda pakeisti slaptažodį" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Atstatyti slaptažodį" + +#: bookwyrm/templates/layout.html:13 +#, python-format +msgid "%(site_name)s search" +msgstr "%(site_name)s paieška" + +#: bookwyrm/templates/layout.html:43 +msgid "Search for a book, user, or list" +msgstr "Ieškoti knygos, naudotojo arba sąrašo" + +#: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62 +msgid "Main navigation menu" +msgstr "Pagrindinis navigacijos meniu" + +#: bookwyrm/templates/layout.html:72 +msgid "Feed" +msgstr "Srautas" + +#: bookwyrm/templates/layout.html:116 +msgid "Settings" +msgstr "Nustatymai" + +#: bookwyrm/templates/layout.html:125 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:15 +#: bookwyrm/templates/settings/invites/manage_invites.html:3 +#: bookwyrm/templates/settings/invites/manage_invites.html:15 +#: bookwyrm/templates/settings/layout.html:40 +msgid "Invites" +msgstr "Pakvietimai" + +#: bookwyrm/templates/layout.html:132 +msgid "Admin" +msgstr "Administratorius" + +#: bookwyrm/templates/layout.html:139 +msgid "Log out" +msgstr "Atsijungti" + +#: bookwyrm/templates/layout.html:147 bookwyrm/templates/layout.html:148 +#: bookwyrm/templates/notifications/notifications_page.html:5 +#: bookwyrm/templates/notifications/notifications_page.html:10 +msgid "Notifications" +msgstr "Pranešimai" + +#: bookwyrm/templates/layout.html:175 +msgid "password" +msgstr "slaptažodis" + +#: bookwyrm/templates/layout.html:187 +msgid "Join" +msgstr "Prisijungti" + +#: bookwyrm/templates/layout.html:221 +msgid "Successfully posted status" +msgstr "Būsena publikuota sėkmingai" + +#: bookwyrm/templates/layout.html:222 +msgid "Error posting status" +msgstr "Klaida, publikuojant būseną" + +#: bookwyrm/templates/layout.html:234 +msgid "Contact site admin" +msgstr "Puslapio administratorius" + +#: bookwyrm/templates/layout.html:238 +msgid "Documentation" +msgstr "Dokumentacija" + +#: bookwyrm/templates/layout.html:245 +#, python-format +msgid "Support %(site_name)s on %(support_title)s" +msgstr "Paremkite %(site_name)s per %(support_title)s" + +#: bookwyrm/templates/layout.html:249 +msgid "BookWyrm's source code is freely available. You can contribute or report issues on GitHub." +msgstr "„BookWyrm“ šaltinio kodas yra laisvai prieinamas. Galite prisidėti arba pranešti apie klaidas per GitHub." + +#: bookwyrm/templates/lists/bookmark_button.html:30 +msgid "Un-save" +msgstr "Nebesaugoti" + +#: bookwyrm/templates/lists/create_form.html:5 +#: bookwyrm/templates/lists/lists.html:20 +msgid "Create List" +msgstr "Sukurti sąrašą" + +#: bookwyrm/templates/lists/created_text.html:5 +#, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Sukūrė %(username)s, tvarko %(groupname)s" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format +msgid "Created and curated by %(username)s" +msgstr "Sukūrė ir kuruoja %(username)s" + +#: bookwyrm/templates/lists/created_text.html:9 +#, python-format +msgid "Created by %(username)s" +msgstr "Sukūrė %(username)s" + +#: bookwyrm/templates/lists/curate.html:8 +msgid "Pending Books" +msgstr "Patvirtinimo laukiančios knygos" + +#: bookwyrm/templates/lists/curate.html:11 +msgid "Go to list" +msgstr "Eiti į sąrašą" + +#: bookwyrm/templates/lists/curate.html:15 +msgid "You're all set!" +msgstr "Viskas atlikta!" + +#: bookwyrm/templates/lists/curate.html:45 +msgid "Suggested by" +msgstr "Pasiūlė" + +#: bookwyrm/templates/lists/curate.html:63 +msgid "Discard" +msgstr "Atmesti" + +#: bookwyrm/templates/lists/delete_list_modal.html:4 +msgid "Delete this list?" +msgstr "Ištrinti šį sąrašą?" + +#: bookwyrm/templates/lists/edit_form.html:5 +#: bookwyrm/templates/lists/layout.html:16 +msgid "Edit List" +msgstr "Redaguoti sąrašą" + +#: bookwyrm/templates/lists/form.html:19 +msgid "List curation:" +msgstr "Sąrašo kuravimas:" + +#: bookwyrm/templates/lists/form.html:22 +msgid "Closed" +msgstr "Uždaryta" + +#: bookwyrm/templates/lists/form.html:23 +msgid "Only you can add and remove books to this list" +msgstr "Tik jūs galite pridėti ar pašalinti knygas iš šio sąrašo" + +#: bookwyrm/templates/lists/form.html:27 +msgid "Curated" +msgstr "Kuruojama" + +#: bookwyrm/templates/lists/form.html:28 +msgid "Anyone can suggest books, subject to your approval" +msgstr "Knygas gali siūlyti visi, tačiau jūs turėsite patvirtinti" + +#: bookwyrm/templates/lists/form.html:32 +msgctxt "curation type" +msgid "Open" +msgstr "Atidaryti" + +#: bookwyrm/templates/lists/form.html:33 +msgid "Anyone can add books to this list" +msgstr "Visi gali pridėti knygų į sąrašą" + +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Grupė" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "Grupės nariai gali pridėti ir išimti iš sąrašo" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Pasirinkti grupę" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Pasirinkite grupę" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "Dar neturite grupių!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Sukurti grupę" + +#: bookwyrm/templates/lists/form.html:81 +msgid "Delete list" +msgstr "Ištrinti sąrašą" + +#: bookwyrm/templates/lists/list.html:21 +msgid "You successfully suggested a book for this list!" +msgstr "Sėkmingai pasiūlėte knygą šiam sąrašui!" + +#: bookwyrm/templates/lists/list.html:23 +msgid "You successfully added a book to this list!" +msgstr "Sėkmingai pridėjote knygą į šį sąrašą!" + +#: bookwyrm/templates/lists/list.html:29 +msgid "This list is currently empty" +msgstr "Šiuo metu sąrašas tuščias" + +#: bookwyrm/templates/lists/list.html:67 +#, python-format +msgid "Added by %(username)s" +msgstr "Pridėjo %(username)s" + +#: bookwyrm/templates/lists/list.html:76 +msgid "List position" +msgstr "Sąrašo pozicija" + +#: bookwyrm/templates/lists/list.html:82 +msgid "Set" +msgstr "Nustatyti" + +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 +#: bookwyrm/templates/snippets/shelf_selector.html:26 +msgid "Remove" +msgstr "Pašalinti" + +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 +msgid "Sort List" +msgstr "Rūšiuoti sąrašą" + +#: bookwyrm/templates/lists/list.html:116 +msgid "Direction" +msgstr "Kryptis" + +#: bookwyrm/templates/lists/list.html:130 +msgid "Add Books" +msgstr "Pridėti knygų" + +#: bookwyrm/templates/lists/list.html:132 +msgid "Suggest Books" +msgstr "Siūlyti knygų" + +#: bookwyrm/templates/lists/list.html:143 +msgid "search" +msgstr "paieška" + +#: bookwyrm/templates/lists/list.html:149 +msgid "Clear search" +msgstr "Išvalyti paiešką" + +#: bookwyrm/templates/lists/list.html:154 +#, python-format +msgid "No books found matching the query \"%(query)s\"" +msgstr "Pagal paiešką „%(query)s“ knygų nerasta" + +#: bookwyrm/templates/lists/list.html:182 +msgid "Suggest" +msgstr "Siūlyti" + +#: bookwyrm/templates/lists/list_items.html:15 +msgid "Saved" +msgstr "Išsaugota" + +#: bookwyrm/templates/lists/lists.html:14 bookwyrm/templates/user/lists.html:9 +msgid "Your Lists" +msgstr "Jūsų sąrašai" + +#: bookwyrm/templates/lists/lists.html:36 +msgid "All Lists" +msgstr "Visi sąrašai" + +#: bookwyrm/templates/lists/lists.html:40 +msgid "Saved Lists" +msgstr "Išsaugoti sąrašai" + +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "priėmė jūsų kvietimą prisijungti prie grupės „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/add.html:24 +#, python-format +msgid "added %(book_title)s to your list \"%(list_name)s\"" +msgstr "į jūsų sąrašą „%(list_name)s“ pridėta %(book_title)s" + +#: bookwyrm/templates/notifications/items/add.html:31 +#, python-format +msgid "suggested adding %(book_title)s to your list \"%(list_name)s\"" +msgstr "į sąrašą „%(list_name)s\" patariama pridėti %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:19 +#, python-format +msgid "boosted your review of %(book_title)s" +msgstr "populiarėja jūsų atsiliepimas apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:25 +#, python-format +msgid "boosted your comment on%(book_title)s" +msgstr "populiarėja jūsų komentaras apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:31 +#, python-format +msgid "boosted your quote from %(book_title)s" +msgstr "populiarėja jūsų citata iš %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:37 +#, python-format +msgid "boosted your status" +msgstr "populiarėja jūsų būsena" + +#: bookwyrm/templates/notifications/items/fav.html:19 +#, python-format +msgid "liked your review of %(book_title)s" +msgstr "patiko jūsų atsiliepimas apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:25 +#, python-format +msgid "liked your comment on %(book_title)s" +msgstr "patiko jūsų komentaras apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:31 +#, python-format +msgid "liked your quote from %(book_title)s" +msgstr "patiko jūsų citata iš %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:37 +#, python-format +msgid "liked your status" +msgstr "patiko jūsų būsena" + +#: bookwyrm/templates/notifications/items/follow.html:15 +msgid "followed you" +msgstr "pradėjo jus sekti" + +#: bookwyrm/templates/notifications/items/follow_request.html:11 +msgid "sent you a follow request" +msgstr "nori jus sekti" + +#: bookwyrm/templates/notifications/items/import.html:14 +#, python-format +msgid "Your import completed." +msgstr "Jūsų importas baigtas." + +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "jus pakvietė prisijungti prie grupės „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "prisijungė prie jūsų grupės „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "paliko jūsų grupę „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/mention.html:20 +#, python-format +msgid "mentioned you in a review of %(book_title)s" +msgstr "paminėjo jus atsiliepime apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:26 +#, python-format +msgid "mentioned you in a comment on %(book_title)s" +msgstr "paminėjo jus komentare apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:32 +#, python-format +msgid "mentioned you in a quote from %(book_title)s" +msgstr "paminėjo jus citatoje iš %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:38 +#, python-format +msgid "mentioned you in a status" +msgstr "paminėjo jus būsenoje" + +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "buvo pašalintas iš jūsų grupės „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "Buvote pašalintas iš grupės „%(group_name)s“" + +#: bookwyrm/templates/notifications/items/reply.html:21 +#, python-format +msgid "replied to your review of %(book_title)s" +msgstr "atsakė į jūsų atsiliepimą apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/reply.html:27 +#, python-format +msgid "replied to your comment on %(book_title)s" +msgstr "atsakė į jūsų komentarą apie %(book_title)s" + +#: bookwyrm/templates/notifications/items/reply.html:33 +#, python-format +msgid "replied to your quote from %(book_title)s" +msgstr "atsakė į jūsų citatą iš %(book_title)s" + +#: bookwyrm/templates/notifications/items/reply.html:39 +#, python-format +msgid "replied to your status" +msgstr "atsakė į jūsų būseną" + +#: bookwyrm/templates/notifications/items/report.html:15 +#, python-format +msgid "A new report needs moderation." +msgstr "Reikia moderuoti pranešimą." + +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "pakeitė privatumo lygį grupei %(group_name)s" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "pakeitė %(group_name)s pavadinimą" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "pakeitė %(group_name)s aprašymą" + +#: bookwyrm/templates/notifications/notifications_page.html:18 +msgid "Delete notifications" +msgstr "Ištrinti pranešimus" + +#: bookwyrm/templates/notifications/notifications_page.html:29 +msgid "All" +msgstr "Visi" + +#: bookwyrm/templates/notifications/notifications_page.html:33 +msgid "Mentions" +msgstr "Paminėjimai" + +#: bookwyrm/templates/notifications/notifications_page.html:45 +msgid "You're all caught up!" +msgstr "Viską peržiūrėjote!" + +#: bookwyrm/templates/preferences/blocks.html:4 +#: bookwyrm/templates/preferences/blocks.html:7 +#: bookwyrm/templates/preferences/layout.html:31 +msgid "Blocked Users" +msgstr "Blokuoti nariai" + +#: bookwyrm/templates/preferences/blocks.html:12 +msgid "No users currently blocked." +msgstr "Blokuotų narių nėra." + +#: bookwyrm/templates/preferences/change_password.html:4 +#: bookwyrm/templates/preferences/change_password.html:7 +#: bookwyrm/templates/preferences/change_password.html:21 +#: bookwyrm/templates/preferences/layout.html:20 +msgid "Change Password" +msgstr "Keisti slaptažodį" + +#: bookwyrm/templates/preferences/change_password.html:14 +msgid "New password:" +msgstr "Naujas slaptažodis:" + +#: bookwyrm/templates/preferences/delete_user.html:4 +#: bookwyrm/templates/preferences/delete_user.html:7 +#: bookwyrm/templates/preferences/delete_user.html:26 +#: bookwyrm/templates/preferences/layout.html:24 +#: bookwyrm/templates/settings/users/delete_user_form.html:23 +msgid "Delete Account" +msgstr "Pašalinti paskyrą" + +#: bookwyrm/templates/preferences/delete_user.html:12 +msgid "Permanently delete account" +msgstr "Visam laikui ištrinti paskyrą" + +#: bookwyrm/templates/preferences/delete_user.html:14 +msgid "Deleting your account cannot be undone. The username will not be available to register in the future." +msgstr "Nebegalėsite atstatyti ištrintos paskyros. Ateityje nebegalėsite naudoti šio naudotojo vardo." + +#: bookwyrm/templates/preferences/edit_user.html:4 +#: bookwyrm/templates/preferences/edit_user.html:7 +#: bookwyrm/templates/preferences/layout.html:15 +msgid "Edit Profile" +msgstr "Redaguoti profilį" + +#: bookwyrm/templates/preferences/edit_user.html:12 +#: bookwyrm/templates/preferences/edit_user.html:25 +#: bookwyrm/templates/settings/users/user_info.html:7 +msgid "Profile" +msgstr "Profilis" + +#: bookwyrm/templates/preferences/edit_user.html:13 +#: bookwyrm/templates/preferences/edit_user.html:68 +msgid "Display preferences" +msgstr "Vaizdo nustatymai" + +#: bookwyrm/templates/preferences/edit_user.html:14 +#: bookwyrm/templates/preferences/edit_user.html:106 +msgid "Privacy" +msgstr "Privatumas" + +#: bookwyrm/templates/preferences/edit_user.html:72 +msgid "Show reading goal prompt in feed:" +msgstr "Rodyti skaitymo tikslą sienoje:" + +#: bookwyrm/templates/preferences/edit_user.html:76 +msgid "Show suggested users:" +msgstr "Rodyti siūlomus narius:" + +#: bookwyrm/templates/preferences/edit_user.html:85 +#, python-format +msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." +msgstr "Jūsų paskyra atsiras kataloge ir gali būti rekomenduota kitiems „BookWyrm“ nariams." + +#: bookwyrm/templates/preferences/edit_user.html:89 +msgid "Preferred Timezone: " +msgstr "Laiko juosta: " + +#: bookwyrm/templates/preferences/edit_user.html:116 +msgid "Default post privacy:" +msgstr "Numatytasis įrašo privatumas:" + +#: bookwyrm/templates/preferences/layout.html:11 +msgid "Account" +msgstr "Paskyra" + +#: bookwyrm/templates/preferences/layout.html:27 +msgid "Relationships" +msgstr "Sąsajos" + +#: bookwyrm/templates/reading_progress/finish.html:5 +#, python-format +msgid "Finish \"%(book_title)s\"" +msgstr "Užbaigti „%(book_title)s“" + +#: bookwyrm/templates/reading_progress/start.html:5 +#, python-format +msgid "Start \"%(book_title)s\"" +msgstr "Pradėti „%(book_title)s“" + +#: bookwyrm/templates/reading_progress/want.html:5 +#, python-format +msgid "Want to Read \"%(book_title)s\"" +msgstr "Noriu perskaityti „%(book_title)s“" + +#: bookwyrm/templates/search/book.html:47 +#: bookwyrm/templates/settings/reports/reports.html:25 +#: bookwyrm/templates/snippets/announcement.html:16 +msgid "Open" +msgstr "Atidaryti" + +#: bookwyrm/templates/search/book.html:85 +msgid "Import book" +msgstr "Importuoti knygą" + +#: bookwyrm/templates/search/book.html:107 +msgid "Load results from other catalogues" +msgstr "Įkelti rezultatus iš kitų katalogų" + +#: bookwyrm/templates/search/book.html:111 +msgid "Manually add book" +msgstr "Pridėti knygą" + +#: bookwyrm/templates/search/book.html:116 +msgid "Log in to import or add books." +msgstr "Prisijunkite, kad importuotumėte arba pridėtumėte knygas." + +#: bookwyrm/templates/search/layout.html:16 +msgid "Search query" +msgstr "Paieškos užklausa" + +#: bookwyrm/templates/search/layout.html:19 +msgid "Search type" +msgstr "Paieškos tipas" + +#: bookwyrm/templates/search/layout.html:23 +#: bookwyrm/templates/search/layout.html:46 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:27 +#: bookwyrm/templates/settings/federation/instance_list.html:44 +#: bookwyrm/templates/settings/layout.html:34 +#: bookwyrm/templates/settings/users/user_admin.html:3 +#: bookwyrm/templates/settings/users/user_admin.html:10 +msgid "Users" +msgstr "Nariai" + +#: bookwyrm/templates/search/layout.html:58 +#, python-format +msgid "No results found for \"%(query)s\"" +msgstr "Pagal paiešką „%(query)s“ nieko nerasta" + +#: bookwyrm/templates/settings/announcements/announcement.html:3 +#: bookwyrm/templates/settings/announcements/announcement.html:6 +msgid "Announcement" +msgstr "Pranešimas" + +#: bookwyrm/templates/settings/announcements/announcement.html:7 +#: bookwyrm/templates/settings/federation/instance.html:13 +msgid "Back to list" +msgstr "Atgal į sąrašą" + +#: bookwyrm/templates/settings/announcements/announcement.html:11 +#: bookwyrm/templates/settings/announcements/announcement_form.html:6 +msgid "Edit Announcement" +msgstr "Redaguoti pranešimą" + +#: bookwyrm/templates/settings/announcements/announcement.html:35 +msgid "Visible:" +msgstr "Matoma:" + +#: bookwyrm/templates/settings/announcements/announcement.html:38 +msgid "True" +msgstr "Tiesa" + +#: bookwyrm/templates/settings/announcements/announcement.html:40 +msgid "False" +msgstr "Netiesa" + +#: bookwyrm/templates/settings/announcements/announcement.html:47 +#: bookwyrm/templates/settings/announcements/announcement_form.html:40 +#: bookwyrm/templates/settings/dashboard/dashboard.html:71 +msgid "Start date:" +msgstr "Pradžios data:" + +#: bookwyrm/templates/settings/announcements/announcement.html:54 +#: bookwyrm/templates/settings/announcements/announcement_form.html:49 +#: bookwyrm/templates/settings/dashboard/dashboard.html:77 +msgid "End date:" +msgstr "Pabaigos data:" + +#: bookwyrm/templates/settings/announcements/announcement.html:60 +#: bookwyrm/templates/settings/announcements/announcement_form.html:58 +msgid "Active:" +msgstr "Aktyvu:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:8 +#: bookwyrm/templates/settings/announcements/announcements.html:8 +msgid "Create Announcement" +msgstr "Sukurti pranešimą" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:16 +msgid "Preview:" +msgstr "Peržiūra:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:23 +msgid "Content:" +msgstr "Turinys:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:30 +msgid "Event date:" +msgstr "Įvykio data:" + +#: bookwyrm/templates/settings/announcements/announcements.html:3 +#: bookwyrm/templates/settings/announcements/announcements.html:5 +#: bookwyrm/templates/settings/layout.html:72 +msgid "Announcements" +msgstr "Pranešimai" + +#: bookwyrm/templates/settings/announcements/announcements.html:22 +#: bookwyrm/templates/settings/federation/instance_list.html:36 +msgid "Date added" +msgstr "Pridėjimo data" + +#: bookwyrm/templates/settings/announcements/announcements.html:26 +msgid "Preview" +msgstr "Peržiūrėti" + +#: bookwyrm/templates/settings/announcements/announcements.html:30 +msgid "Start date" +msgstr "Pradžios data" + +#: bookwyrm/templates/settings/announcements/announcements.html:34 +msgid "End date" +msgstr "Pabaigos data" + +#: bookwyrm/templates/settings/announcements/announcements.html:48 +msgid "active" +msgstr "aktyvus" + +#: bookwyrm/templates/settings/announcements/announcements.html:48 +msgid "inactive" +msgstr "neaktyvus" + +#: bookwyrm/templates/settings/announcements/announcements.html:52 +msgid "No announcements found" +msgstr "Pranešimų nerasta" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:6 +#: bookwyrm/templates/settings/dashboard/dashboard.html:8 +#: bookwyrm/templates/settings/layout.html:26 +msgid "Dashboard" +msgstr "Suvestinė" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:15 +#: bookwyrm/templates/settings/dashboard/dashboard.html:100 +msgid "Total users" +msgstr "Iš viso naudotojų" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:21 +#: bookwyrm/templates/settings/dashboard/user_chart.html:16 +msgid "Active this month" +msgstr "Aktyvūs šį mėnesį" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:27 +msgid "Statuses" +msgstr "Būsenos" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:33 +#: bookwyrm/templates/settings/dashboard/works_chart.html:11 +msgid "Works" +msgstr "Darbai" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:43 +#, python-format +msgid "%(display_count)s open report" +msgid_plural "%(display_count)s open reports" +msgstr[0] "%(display_count)s atvira ataskaita" +msgstr[1] "%(display_count)s atviros ataskaitos" +msgstr[2] "%(display_count)s atviros ataskaitos" +msgstr[3] "%(display_count)s atvirų ataskaitų" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:54 +#, python-format +msgid "%(display_count)s invite request" +msgid_plural "%(display_count)s invite requests" +msgstr[0] "%(display_count)s prašymas pakviesti" +msgstr[1] "%(display_count)s prašymai pakviesti" +msgstr[2] "%(display_count)s prašymų pakviesti" +msgstr[3] "%(display_count)s prašymai pakviesti" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:65 +msgid "Instance Activity" +msgstr "Pavyzdinė veikla" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:83 +msgid "Interval:" +msgstr "Intervalas:" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:87 +msgid "Days" +msgstr "Dienos" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:88 +msgid "Weeks" +msgstr "Savaitės" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:106 +msgid "User signup activity" +msgstr "Naudotojo prisijungimo veikla" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:112 +msgid "Status activity" +msgstr "Būsenos veikla" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:118 +msgid "Works created" +msgstr "Darbai sukurti" + +#: bookwyrm/templates/settings/dashboard/registration_chart.html:10 +msgid "Registrations" +msgstr "Registracijos" + +#: bookwyrm/templates/settings/dashboard/status_chart.html:11 +msgid "Statuses posted" +msgstr "Būsenos publikuotos" + +#: bookwyrm/templates/settings/dashboard/user_chart.html:11 +msgid "Total" +msgstr "Iš viso" + +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:5 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:10 +msgid "Add domain" +msgstr "Pridėti domeną" + +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:11 +msgid "Domain:" +msgstr "Domenas:" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:5 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:7 +#: bookwyrm/templates/settings/layout.html:59 +msgid "Email Blocklist" +msgstr "El. pašto blokavimo sąrašas" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:18 +msgid "When someone tries to register with an email from this domain, no account will be created. The registration process will appear to have worked." +msgstr "Jei kažkas bandys registruotis prie šio domeno šiuo el. pašto adresu, paskyra nebus sukurta. Registracijos pricesas bus suveikęs." + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:25 +msgid "Domain" +msgstr "Domenas" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:29 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:27 +msgid "Options" +msgstr "Parinktys" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:38 +#, python-format +msgid "%(display_count)s user" +msgid_plural "%(display_count)s users" +msgstr[0] "%(display_count)s narys" +msgstr[1] "%(display_count)s nariai" +msgstr[2] "%(display_count)s narių" +msgstr[3] "%(display_count)s nariai" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:59 +msgid "No email domains currently blocked" +msgstr "Šiuo metu neblokuojamas nė vienas el. pašto domenas" + +#: bookwyrm/templates/settings/federation/edit_instance.html:3 +#: bookwyrm/templates/settings/federation/edit_instance.html:6 +#: bookwyrm/templates/settings/federation/edit_instance.html:20 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:3 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:20 +#: bookwyrm/templates/settings/federation/instance_list.html:9 +#: bookwyrm/templates/settings/federation/instance_list.html:10 +msgid "Add instance" +msgstr "Pridėti serverį" + +#: bookwyrm/templates/settings/federation/edit_instance.html:7 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:7 +msgid "Back to instance list" +msgstr "Grįžti į serverių sąrašą" + +#: bookwyrm/templates/settings/federation/edit_instance.html:16 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:16 +msgid "Import block list" +msgstr "Importuoti blokuojamų sąrašą" + +#: bookwyrm/templates/settings/federation/edit_instance.html:30 +msgid "Instance:" +msgstr "Serveris:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:39 +#: bookwyrm/templates/settings/federation/instance.html:28 +#: bookwyrm/templates/settings/users/user_info.html:106 +msgid "Status:" +msgstr "Būsena:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:52 +#: bookwyrm/templates/settings/federation/instance.html:22 +#: bookwyrm/templates/settings/users/user_info.html:100 +msgid "Software:" +msgstr "Programinė įranga:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:61 +#: bookwyrm/templates/settings/federation/instance.html:25 +#: bookwyrm/templates/settings/users/user_info.html:103 +msgid "Version:" +msgstr "Versija:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:70 +msgid "Notes:" +msgstr "Užrašai:" + +#: bookwyrm/templates/settings/federation/instance.html:19 +msgid "Details" +msgstr "Išsami informacija" + +#: bookwyrm/templates/settings/federation/instance.html:35 +#: bookwyrm/templates/user/layout.html:64 +msgid "Activity" +msgstr "Veikla" + +#: bookwyrm/templates/settings/federation/instance.html:38 +msgid "Users:" +msgstr "Nariai:" + +#: bookwyrm/templates/settings/federation/instance.html:41 +#: bookwyrm/templates/settings/federation/instance.html:47 +msgid "View all" +msgstr "Žiūrėti viską" + +#: bookwyrm/templates/settings/federation/instance.html:44 +#: bookwyrm/templates/settings/users/user_info.html:56 +msgid "Reports:" +msgstr "Pranešimai:" + +#: bookwyrm/templates/settings/federation/instance.html:50 +msgid "Followed by us:" +msgstr "Sekame:" + +#: bookwyrm/templates/settings/federation/instance.html:55 +msgid "Followed by them:" +msgstr "Seka:" + +#: bookwyrm/templates/settings/federation/instance.html:60 +msgid "Blocked by us:" +msgstr "Blokuojame:" + +#: bookwyrm/templates/settings/federation/instance.html:72 +#: bookwyrm/templates/settings/users/user_info.html:110 +msgid "Notes" +msgstr "Užrašai" + +#: bookwyrm/templates/settings/federation/instance.html:75 +#: bookwyrm/templates/snippets/status/status_options.html:24 +msgid "Edit" +msgstr "Redaguoti" + +#: bookwyrm/templates/settings/federation/instance.html:79 +msgid "No notes" +msgstr "Užrašų nėra" + +#: bookwyrm/templates/settings/federation/instance.html:94 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:8 +msgid "Actions" +msgstr "Veiksmai" + +#: bookwyrm/templates/settings/federation/instance.html:98 +#: bookwyrm/templates/snippets/block_button.html:5 +msgid "Block" +msgstr "Blokuoti" + +#: bookwyrm/templates/settings/federation/instance.html:99 +msgid "All users from this instance will be deactivated." +msgstr "Visi šio serverio nariai bus deaktyvuoti." + +#: bookwyrm/templates/settings/federation/instance.html:104 +#: bookwyrm/templates/snippets/block_button.html:10 +msgid "Un-block" +msgstr "Atblokuoti" + +#: bookwyrm/templates/settings/federation/instance.html:105 +msgid "All users from this instance will be re-activated." +msgstr "Visi šio serverio nariai bus vėl aktyvuoti." + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:6 +msgid "Import Blocklist" +msgstr "Importuoti blokuojamų sąrašą" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:26 +#: bookwyrm/templates/snippets/goal_progress.html:7 +msgid "Success!" +msgstr "Valio!" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:30 +msgid "Successfully blocked:" +msgstr "Sėkmingai užblokuota:" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:32 +msgid "Failed:" +msgstr "Nepavyko:" + +#: bookwyrm/templates/settings/federation/instance_list.html:3 +#: bookwyrm/templates/settings/federation/instance_list.html:5 +#: bookwyrm/templates/settings/layout.html:45 +msgid "Federated Instances" +msgstr "Susijungę serveriai" + +#: bookwyrm/templates/settings/federation/instance_list.html:32 +#: bookwyrm/templates/settings/users/server_filter.html:5 +msgid "Instance name" +msgstr "Serverio pavadinimas" + +#: bookwyrm/templates/settings/federation/instance_list.html:40 +msgid "Software" +msgstr "Programinė įranga" + +#: bookwyrm/templates/settings/federation/instance_list.html:63 +msgid "No instances found" +msgstr "Serverių nerasta" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:4 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:11 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:25 +#: bookwyrm/templates/settings/invites/manage_invites.html:11 +msgid "Invite Requests" +msgstr "Kvietimo prašymai" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:23 +msgid "Ignored Invite Requests" +msgstr "Ignoruoti kvietimo prašymai" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:35 +msgid "Date requested" +msgstr "Prašymo data" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:39 +msgid "Date accepted" +msgstr "Priėmimo data" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:42 +msgid "Email" +msgstr "El. paštas" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:47 +msgid "Action" +msgstr "Veiksmas" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:50 +msgid "No requests" +msgstr "Prašymų nėra" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:59 +#: bookwyrm/templates/settings/invites/status_filter.html:16 +msgid "Accepted" +msgstr "Priimta" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:61 +#: bookwyrm/templates/settings/invites/status_filter.html:12 +msgid "Sent" +msgstr "Išsiųsta" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:63 +#: bookwyrm/templates/settings/invites/status_filter.html:8 +msgid "Requested" +msgstr "Užklausta" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:73 +msgid "Send invite" +msgstr "Siųsti pakvietimą" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:75 +msgid "Re-send invite" +msgstr "Pakartotinai siųsti pakvietimą" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:95 +msgid "Ignore" +msgstr "Ignoruoti" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:97 +msgid "Un-ignore" +msgstr "Nebeignoruoti" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:108 +msgid "Back to pending requests" +msgstr "Grįžti į laukiančius prašymus" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:110 +msgid "View ignored requests" +msgstr "Žiūrėti ignoruotus prašymus" + +#: bookwyrm/templates/settings/invites/manage_invites.html:21 +msgid "Generate New Invite" +msgstr "Sugeneruoti naują pakvietimą" + +#: bookwyrm/templates/settings/invites/manage_invites.html:27 +msgid "Expiry:" +msgstr "Galiojimo pabaiga:" + +#: bookwyrm/templates/settings/invites/manage_invites.html:33 +msgid "Use limit:" +msgstr "Naudojimo limitas:" + +#: bookwyrm/templates/settings/invites/manage_invites.html:40 +msgid "Create Invite" +msgstr "Sukurti pakvietimą" + +#: bookwyrm/templates/settings/invites/manage_invites.html:47 +msgid "Link" +msgstr "Nuoroda" + +#: bookwyrm/templates/settings/invites/manage_invites.html:48 +msgid "Expires" +msgstr "Baigia galioti" + +#: bookwyrm/templates/settings/invites/manage_invites.html:49 +msgid "Max uses" +msgstr "Maks. naudojimų" + +#: bookwyrm/templates/settings/invites/manage_invites.html:50 +msgid "Times used" +msgstr "Kartų naudota" + +#: bookwyrm/templates/settings/invites/manage_invites.html:53 +msgid "No active invites" +msgstr "Nėra aktyvių pakvietimų" + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:5 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:10 +msgid "Add IP address" +msgstr "Pridėti IP adresą" + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:11 +msgid "Use IP address blocks with caution, and consider using blocks only temporarily, as IP addresses are often shared or change hands. If you block your own IP, you will not be able to access this page." +msgstr "Atsargiai naudokite IP adresų blokus. Rekomenduojame juos naudoti tik laikinai, nes IP adresai dažnu atveju yra bendrinami arba pereina kitiems. Jei užblokuosite savo IP, nebegalėsite pasiekti šio puslapio." + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:18 +msgid "IP Address:" +msgstr "IP adresas:" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:5 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:7 +#: bookwyrm/templates/settings/layout.html:63 +msgid "IP Address Blocklist" +msgstr "Juodasis IP adresų sąrašas" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:18 +msgid "Any traffic from this IP address will get a 404 response when trying to access any part of the application." +msgstr "Bandant pasiekti bet kurią programėlės dalį, šiam IP adresui visada matysis 404 klaidos kodas." + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:24 +msgid "Address" +msgstr "Adresas" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:46 +msgid "No IP addresses currently blocked" +msgstr "Šiuo metu neblokuojamas joks IP adresas" + +#: bookwyrm/templates/settings/ip_blocklist/ip_tooltip.html:6 +msgid "You can block IP ranges using CIDR syntax." +msgstr "IP rėžius galite blokuoti naudodami CIDR sintaksę." + +#: bookwyrm/templates/settings/layout.html:4 +msgid "Administration" +msgstr "Administravimas" + +#: bookwyrm/templates/settings/layout.html:29 +msgid "Manage Users" +msgstr "Tvarkyti naudotojus" + +#: bookwyrm/templates/settings/layout.html:51 +msgid "Moderation" +msgstr "Moderavimas" + +#: bookwyrm/templates/settings/layout.html:55 +#: bookwyrm/templates/settings/reports/reports.html:8 +#: bookwyrm/templates/settings/reports/reports.html:17 +msgid "Reports" +msgstr "Pranešimai" + +#: bookwyrm/templates/settings/layout.html:68 +msgid "Instance Settings" +msgstr "Serverio nustatymai" + +#: bookwyrm/templates/settings/layout.html:76 +#: bookwyrm/templates/settings/site.html:4 +#: bookwyrm/templates/settings/site.html:6 +msgid "Site Settings" +msgstr "Puslapio nustatymai" + +#: bookwyrm/templates/settings/reports/report.html:5 +#: bookwyrm/templates/settings/reports/report.html:8 +#: bookwyrm/templates/settings/reports/report_preview.html:6 +#, python-format +msgid "Report #%(report_id)s: %(username)s" +msgstr "Pranešti apie #%(report_id)s: %(username)s" + +#: bookwyrm/templates/settings/reports/report.html:9 +msgid "Back to reports" +msgstr "Atgal į pranešimus" + +#: bookwyrm/templates/settings/reports/report.html:23 +msgid "Moderator Comments" +msgstr "Moderatoriaus komentarai" + +#: bookwyrm/templates/settings/reports/report.html:41 +#: bookwyrm/templates/snippets/create_status.html:28 +msgid "Comment" +msgstr "Komentuoti" + +#: bookwyrm/templates/settings/reports/report.html:46 +msgid "Reported statuses" +msgstr "Praneštos būsenos" + +#: bookwyrm/templates/settings/reports/report.html:48 +msgid "No statuses reported" +msgstr "Nepranešta apie būsenas" + +#: bookwyrm/templates/settings/reports/report.html:54 +msgid "Status has been deleted" +msgstr "Būsena ištrinta" + +#: bookwyrm/templates/settings/reports/report_preview.html:13 +msgid "No notes provided" +msgstr "Užrašų nepateikta" + +#: bookwyrm/templates/settings/reports/report_preview.html:20 +#, python-format +msgid "Reported by %(username)s" +msgstr "Pranešė %(username)s" + +#: bookwyrm/templates/settings/reports/report_preview.html:30 +msgid "Re-open" +msgstr "Atidaryti pakartotinai" + +#: bookwyrm/templates/settings/reports/report_preview.html:32 +msgid "Resolve" +msgstr "Išspręsti" + +#: bookwyrm/templates/settings/reports/reports.html:6 +#, python-format +msgid "Reports: %(instance_name)s" +msgstr "Pranešimai: %(instance_name)s" + +#: bookwyrm/templates/settings/reports/reports.html:14 +#, python-format +msgid "Reports: %(instance_name)s" +msgstr "Pranešimai: %(instance_name)s" + +#: bookwyrm/templates/settings/reports/reports.html:28 +msgid "Resolved" +msgstr "Išspręsta" + +#: bookwyrm/templates/settings/reports/reports.html:37 +msgid "No reports found." +msgstr "Pranešimų nerasta." + +#: bookwyrm/templates/settings/site.html:10 +#: bookwyrm/templates/settings/site.html:21 +msgid "Instance Info" +msgstr "Serverio informacija" + +#: bookwyrm/templates/settings/site.html:11 +#: bookwyrm/templates/settings/site.html:54 +msgid "Images" +msgstr "Paveikslėliai" + +#: bookwyrm/templates/settings/site.html:12 +#: bookwyrm/templates/settings/site.html:74 +msgid "Footer Content" +msgstr "Poraštės turinys" + +#: bookwyrm/templates/settings/site.html:13 +#: bookwyrm/templates/settings/site.html:98 +msgid "Registration" +msgstr "Registracija" + +#: bookwyrm/templates/settings/site.html:24 +msgid "Instance Name:" +msgstr "Serverio pavadinimas:" + +#: bookwyrm/templates/settings/site.html:28 +msgid "Tagline:" +msgstr "Žymos linija:" + +#: bookwyrm/templates/settings/site.html:32 +msgid "Instance description:" +msgstr "Serverio aprašymas:" + +#: bookwyrm/templates/settings/site.html:36 +msgid "Short description:" +msgstr "Trumpas aprašymas:" + +#: bookwyrm/templates/settings/site.html:37 +msgid "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." +msgstr "Naudota, kai turinys buvo peržiūrimas per joinbookwyrm.com. Nepalaiko HTML arba „Markdown“." + +#: bookwyrm/templates/settings/site.html:41 +msgid "Code of conduct:" +msgstr "Elgesio kodeksas:" + +#: bookwyrm/templates/settings/site.html:45 +msgid "Privacy Policy:" +msgstr "Privatumo politika:" + +#: bookwyrm/templates/settings/site.html:57 +msgid "Logo:" +msgstr "Logotipas:" + +#: bookwyrm/templates/settings/site.html:61 +msgid "Logo small:" +msgstr "Mažas logotipas:" + +#: bookwyrm/templates/settings/site.html:65 +msgid "Favicon:" +msgstr "Puslapio ikonėlė:" + +#: bookwyrm/templates/settings/site.html:77 +msgid "Support link:" +msgstr "Paramos nuoroda:" + +#: bookwyrm/templates/settings/site.html:81 +msgid "Support title:" +msgstr "Paramos pavadinimas:" + +#: bookwyrm/templates/settings/site.html:85 +msgid "Admin email:" +msgstr "Administratoriaus el. paštas:" + +#: bookwyrm/templates/settings/site.html:89 +msgid "Additional info:" +msgstr "Papildoma informacija:" + +#: bookwyrm/templates/settings/site.html:103 +msgid "Allow registration" +msgstr "Leisti registruotis" + +#: bookwyrm/templates/settings/site.html:109 +msgid "Allow invite requests" +msgstr "Leisti prašyti kvietimų" + +#: bookwyrm/templates/settings/site.html:115 +msgid "Require users to confirm email address" +msgstr "Reikalauti el. pašto patvirtinimo" + +#: bookwyrm/templates/settings/site.html:117 +msgid "(Recommended if registration is open)" +msgstr "(Rekomenduojama, jei leidžiama registruotis)" + +#: bookwyrm/templates/settings/site.html:120 +msgid "Registration closed text:" +msgstr "Užrakintos registracijos tekstas:" + +#: bookwyrm/templates/settings/site.html:124 +msgid "Invite request text:" +msgstr "Kvietimo prašymo tekstas:" + +#: bookwyrm/templates/settings/users/delete_user_form.html:5 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:31 +msgid "Permanently delete user" +msgstr "Visam laikui ištrinti vartotoją" + +#: bookwyrm/templates/settings/users/delete_user_form.html:12 +#, python-format +msgid "Are you sure you want to delete %(username)s's account? This action cannot be undone. To proceed, please enter your password to confirm deletion." +msgstr "Ar tikrai norite ištrinti %(username)s paskyrą? To negalėsite atšaukti. Norėdami tęsti, įveskite savo slaptažodį, kad patvirtintumėte sprendimą trinti." + +#: bookwyrm/templates/settings/users/delete_user_form.html:17 +msgid "Your password:" +msgstr "Jūsų slaptažodis:" + +#: bookwyrm/templates/settings/users/user.html:7 +msgid "Back to users" +msgstr "Atgal į vartotojų sąrašą" + +#: bookwyrm/templates/settings/users/user_admin.html:7 +#, python-format +msgid "Users: %(instance_name)s" +msgstr "Vartotojai: %(instance_name)s" + +#: bookwyrm/templates/settings/users/user_admin.html:22 +#: bookwyrm/templates/settings/users/username_filter.html:5 +msgid "Username" +msgstr "Vartotojo vardas" + +#: bookwyrm/templates/settings/users/user_admin.html:26 +msgid "Date Added" +msgstr "Pridėjimo data" + +#: bookwyrm/templates/settings/users/user_admin.html:30 +msgid "Last Active" +msgstr "Paskutinį kartą aktyvus" + +#: bookwyrm/templates/settings/users/user_admin.html:38 +msgid "Remote instance" +msgstr "Nutolęs serveris" + +#: bookwyrm/templates/settings/users/user_admin.html:47 +#: bookwyrm/templates/settings/users/user_info.html:24 +msgid "Active" +msgstr "Aktyvus" + +#: bookwyrm/templates/settings/users/user_admin.html:47 +#: bookwyrm/templates/settings/users/user_info.html:28 +msgid "Inactive" +msgstr "Neaktyvus" + +#: bookwyrm/templates/settings/users/user_admin.html:52 +#: bookwyrm/templates/settings/users/user_info.html:120 +msgid "Not set" +msgstr "Nenustatytas" + +#: bookwyrm/templates/settings/users/user_info.html:16 +msgid "View user profile" +msgstr "Peržiūrėti vartotojo profilį" + +#: bookwyrm/templates/settings/users/user_info.html:36 +msgid "Local" +msgstr "Vietinis" + +#: bookwyrm/templates/settings/users/user_info.html:38 +msgid "Remote" +msgstr "Nutolęs" + +#: bookwyrm/templates/settings/users/user_info.html:47 +msgid "User details" +msgstr "Vartotojo duomenys" + +#: bookwyrm/templates/settings/users/user_info.html:51 +msgid "Email:" +msgstr "El. paštas:" + +#: bookwyrm/templates/settings/users/user_info.html:61 +msgid "(View reports)" +msgstr "(Peržiūrėti ataskaitas)" + +#: bookwyrm/templates/settings/users/user_info.html:67 +msgid "Blocked by count:" +msgstr "Užblokavę:" + +#: bookwyrm/templates/settings/users/user_info.html:70 +msgid "Last active date:" +msgstr "Paskutinį kartą aktyvus:" + +#: bookwyrm/templates/settings/users/user_info.html:73 +msgid "Manually approved followers:" +msgstr "Patvirtinti sekėjai:" + +#: bookwyrm/templates/settings/users/user_info.html:76 +msgid "Discoverable:" +msgstr "Aptinkama:" + +#: bookwyrm/templates/settings/users/user_info.html:80 +msgid "Deactivation reason:" +msgstr "Išjungimo priežastis:" + +#: bookwyrm/templates/settings/users/user_info.html:95 +msgid "Instance details" +msgstr "Serverio informacija" + +#: bookwyrm/templates/settings/users/user_info.html:117 +msgid "View instance" +msgstr "Peržiūrėti serverį" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:5 +msgid "Permanently deleted" +msgstr "Visam laikui ištrintas" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:13 +#: bookwyrm/templates/snippets/status/status_options.html:32 +#: bookwyrm/templates/snippets/user_options.html:13 +msgid "Send direct message" +msgstr "Siųsti asmeninę žinutę" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:20 +msgid "Suspend user" +msgstr "Laikinai išjungti vartotoją" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:25 +msgid "Un-suspend user" +msgstr "Atblokuoti narį" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:47 +msgid "Access level:" +msgstr "Priėjimo lygis:" + +#: bookwyrm/templates/shelf/create_shelf_form.html:5 +msgid "Create Shelf" +msgstr "Sukurti lentyną" + +#: bookwyrm/templates/shelf/edit_shelf_form.html:5 +msgid "Edit Shelf" +msgstr "Redaguoti lentyną" + +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 +msgid "All books" +msgstr "Visos knygos" + +#: bookwyrm/templates/shelf/shelf.html:69 +msgid "Create shelf" +msgstr "Sukurti lentyną" + +#: bookwyrm/templates/shelf/shelf.html:90 +#, python-format +msgid "%(formatted_count)s book" +msgid_plural "%(formatted_count)s books" +msgstr[0] "%(formatted_count)s knyga" +msgstr[1] "%(formatted_count)s knygos" +msgstr[2] "%(formatted_count)s knygų" +msgstr[3] "%(formatted_count)s knygos" + +#: bookwyrm/templates/shelf/shelf.html:97 +#, python-format +msgid "(showing %(start)s-%(end)s)" +msgstr "(rodoma %(start)s–%(end)s)" + +#: bookwyrm/templates/shelf/shelf.html:109 +msgid "Edit shelf" +msgstr "Redaguoti lentyną" + +#: bookwyrm/templates/shelf/shelf.html:117 +msgid "Delete shelf" +msgstr "Ištrinti lentyną" + +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 +msgid "Shelved" +msgstr "Sudėta į lentynas" + +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 +msgid "Started" +msgstr "Pradėta" + +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 +msgid "Finished" +msgstr "Baigta" + +#: bookwyrm/templates/shelf/shelf.html:203 +msgid "This shelf is empty." +msgstr "Ši lentyna tuščia." + +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "Pakviesti" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "Atšaukti kvietimą" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "Pašalinti @%(username)s" + +#: bookwyrm/templates/snippets/announcement.html:31 +#, python-format +msgid "Posted by %(username)s" +msgstr "Publikavo %(username)s" + +#: bookwyrm/templates/snippets/authors.html:22 +#, python-format +msgid "and %(remainder_count_display)s other" +msgid_plural "and %(remainder_count_display)s others" +msgstr[0] "ir %(remainder_count_display)s kitas" +msgstr[1] "ir %(remainder_count_display)s kiti" +msgstr[2] "ir %(remainder_count_display)s kitų" +msgstr[3] "ir %(remainder_count_display)s kitų" + +#: bookwyrm/templates/snippets/book_cover.html:61 +msgid "No cover" +msgstr "Nėra viršelio" + +#: bookwyrm/templates/snippets/book_titleby.html:6 +#, python-format +msgid "%(title)s by" +msgstr "%(title)s" + +#: bookwyrm/templates/snippets/boost_button.html:20 +#: bookwyrm/templates/snippets/boost_button.html:21 +msgid "Boost" +msgstr "Populiarinti" + +#: bookwyrm/templates/snippets/boost_button.html:33 +#: bookwyrm/templates/snippets/boost_button.html:34 +msgid "Un-boost" +msgstr "Nepopuliarinti" + +#: bookwyrm/templates/snippets/create_status.html:39 +msgid "Quote" +msgstr "Citata" + +#: bookwyrm/templates/snippets/create_status/comment.html:15 +msgid "Some thoughts on the book" +msgstr "Mintys apie knygą" + +#: bookwyrm/templates/snippets/create_status/comment.html:27 +#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:15 +msgid "Progress:" +msgstr "Progresas:" + +#: bookwyrm/templates/snippets/create_status/comment.html:53 +#: bookwyrm/templates/snippets/progress_field.html:18 +msgid "pages" +msgstr "puslapiai" + +#: bookwyrm/templates/snippets/create_status/comment.html:59 +#: bookwyrm/templates/snippets/progress_field.html:23 +msgid "percent" +msgstr "procentai" + +#: bookwyrm/templates/snippets/create_status/comment.html:66 +#, python-format +msgid "of %(pages)s pages" +msgstr "iš %(pages)s psl." + +#: bookwyrm/templates/snippets/create_status/content_field.html:17 +#: bookwyrm/templates/snippets/status/layout.html:34 +#: bookwyrm/templates/snippets/status/layout.html:52 +#: bookwyrm/templates/snippets/status/layout.html:53 +msgid "Reply" +msgstr "Atsakyti" + +#: bookwyrm/templates/snippets/create_status/content_field.html:17 +msgid "Content" +msgstr "Turinys" + +#: bookwyrm/templates/snippets/create_status/content_warning_field.html:10 +msgid "Content warning:" +msgstr "Įspėjimas dėl turinio:" + +#: bookwyrm/templates/snippets/create_status/content_warning_field.html:18 +msgid "Spoilers ahead!" +msgstr "Galimas turinio atskleidimas!" + +#: bookwyrm/templates/snippets/create_status/content_warning_toggle.html:13 +msgid "Include spoiler alert" +msgstr "Įdėti įspėjimą apie turinio atskleidimą" + +#: bookwyrm/templates/snippets/create_status/layout.html:48 +#: bookwyrm/templates/snippets/reading_modals/form.html:7 +msgid "Comment:" +msgstr "Komentuoti:" + +#: bookwyrm/templates/snippets/create_status/post_options_block.html:8 +#: bookwyrm/templates/snippets/privacy-icons.html:15 +#: bookwyrm/templates/snippets/privacy-icons.html:16 +#: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 +msgid "Private" +msgstr "Privatu" + +#: bookwyrm/templates/snippets/create_status/post_options_block.html:21 +msgid "Post" +msgstr "Publikuoti" + +#: bookwyrm/templates/snippets/create_status/quotation.html:17 +msgid "Quote:" +msgstr "Citata:" + +#: bookwyrm/templates/snippets/create_status/quotation.html:25 +#, python-format +msgid "An excerpt from '%(book_title)s'" +msgstr "Ištrauka iš „%(book_title)s“" + +#: bookwyrm/templates/snippets/create_status/quotation.html:32 +msgid "Position:" +msgstr "Pozicija:" + +#: bookwyrm/templates/snippets/create_status/quotation.html:45 +msgid "On page:" +msgstr "Puslapyje:" + +#: bookwyrm/templates/snippets/create_status/quotation.html:51 +msgid "At percent:" +msgstr "Proc.:" + +#: bookwyrm/templates/snippets/create_status/review.html:25 +#, python-format +msgid "Your review of '%(book_title)s'" +msgstr "Jūsų apžvalga apie „%(book_title)s“" + +#: bookwyrm/templates/snippets/create_status/review.html:40 +msgid "Review:" +msgstr "Atsiliepimas:" + +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:4 +msgid "Delete these read dates?" +msgstr "Ištrinti šias skaitymo datas?" + +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:7 +#, python-format +msgid "You are deleting this readthrough and its %(count)s associated progress updates." +msgstr "Trinate tai, kas perskaityta ir %(count)s susietų progreso naujinių." + +#: bookwyrm/templates/snippets/fav_button.html:16 +#: bookwyrm/templates/snippets/fav_button.html:17 +msgid "Like" +msgstr "Mėgti" + +#: bookwyrm/templates/snippets/fav_button.html:30 +#: bookwyrm/templates/snippets/fav_button.html:31 +msgid "Un-like" +msgstr "Nebemėgti" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:7 +msgid "Show filters" +msgstr "Rodyti filtrus" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:9 +msgid "Hide filters" +msgstr "Slėpti filtrus" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:22 +msgid "Apply filters" +msgstr "Taikyti filtrus" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:26 +msgid "Clear filters" +msgstr "Valyti filtrus" + +#: bookwyrm/templates/snippets/follow_button.html:14 +#, python-format +msgid "Follow @%(username)s" +msgstr "Sekti @%(username)s" + +#: bookwyrm/templates/snippets/follow_button.html:16 +msgid "Follow" +msgstr "Sekti" + +#: bookwyrm/templates/snippets/follow_button.html:25 +msgid "Undo follow request" +msgstr "Atšaukti prašymus sekti" + +#: bookwyrm/templates/snippets/follow_button.html:30 +#, python-format +msgid "Unfollow @%(username)s" +msgstr "Nebesekti @%(username)s" + +#: bookwyrm/templates/snippets/follow_button.html:32 +msgid "Unfollow" +msgstr "Nebesekti" + +#: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 +msgid "Accept" +msgstr "Sutikti" + +#: bookwyrm/templates/snippets/form_rate_stars.html:20 +#: bookwyrm/templates/snippets/stars.html:13 +msgid "No rating" +msgstr "Įvertinimų nėra" + +#: bookwyrm/templates/snippets/form_rate_stars.html:28 +#, python-format +msgid "%(half_rating)s star" +msgid_plural "%(half_rating)s stars" +msgstr[0] "%(half_rating)s žvaigždutė" +msgstr[1] "%(half_rating)s žvaigždutės" +msgstr[2] "%(half_rating)s žvaigždutės" +msgstr[3] "%(half_rating)s žvaigždučių" + +#: bookwyrm/templates/snippets/form_rate_stars.html:64 +#: bookwyrm/templates/snippets/stars.html:7 +#, python-format +msgid "%(rating)s star" +msgid_plural "%(rating)s stars" +msgstr[0] "%(rating)s žvaigždutė" +msgstr[1] "%(rating)s žvaigždutės" +msgstr[2] "%(rating)s žvaigždutės" +msgstr[3] "%(rating)s žvaigždučių" + +#: bookwyrm/templates/snippets/generated_status/goal.html:2 +#, python-format +msgid "set a goal to read %(counter)s book in %(year)s" +msgid_plural "set a goal to read %(counter)s books in %(year)s" +msgstr[0] "nustatė tikslą perskaityti %(counter)s knygą %(year)s m." +msgstr[1] "nustatė tikslą perskaityti %(counter)s knygas %(year)s m." +msgstr[2] "nustatė tikslą perskaityti %(counter)s knygų %(year)s m." +msgstr[3] "nustatė tikslą perskaityti %(counter)s knygas %(year)s m." + +#: bookwyrm/templates/snippets/generated_status/rating.html:3 +#, python-format +msgid "rated %(title)s: %(display_rating)s star" +msgid_plural "rated %(title)s: %(display_rating)s stars" +msgstr[0] "įvertinta %(title)s: %(display_rating)s žvaigždute" +msgstr[1] "įvertinta %(title)s: %(display_rating)s žvaigždutėmis" +msgstr[2] "įvertinta %(title)s: %(display_rating)s žvaigždutėmis" +msgstr[3] "įvertinta %(title)s: %(display_rating)s žvaigždutėmis" + +#: bookwyrm/templates/snippets/generated_status/review_pure_name.html:4 +#, python-format +msgid "Review of \"%(book_title)s\" (%(display_rating)s star): %(review_title)s" +msgid_plural "Review of \"%(book_title)s\" (%(display_rating)s stars): %(review_title)s" +msgstr[0] "Knygos „%(book_title)s“ (%(display_rating)s žvaigždutė) apžvalga: %(review_title)s" +msgstr[1] "Knygos „%(book_title)s“ (%(display_rating)s žvaigždutės) apžvalga: %(review_title)s" +msgstr[2] "Knygos „%(book_title)s“ (%(display_rating)s žvaigždutės) apžvalga: %(review_title)s" +msgstr[3] "Knygos „%(book_title)s“ (%(display_rating)s žvaigždutės) apžvalga: %(review_title)s" + +#: bookwyrm/templates/snippets/generated_status/review_pure_name.html:8 +#, python-format +msgid "Review of \"%(book_title)s\": %(review_title)s" +msgstr "Knygos „%(book_title)s“ apžvalga: %(review_title)s" + +#: bookwyrm/templates/snippets/goal_form.html:4 +#, python-format +msgid "Set a goal for how many books you'll finish reading in %(year)s, and track your progress throughout the year." +msgstr "Nusistatykite tikslą, kiek knygų perskaitysite %(year)s m. ir metų eigoje sekite savo progresą." + +#: bookwyrm/templates/snippets/goal_form.html:16 +msgid "Reading goal:" +msgstr "Skaitymo tikslai:" + +#: bookwyrm/templates/snippets/goal_form.html:21 +msgid "books" +msgstr "knygos" + +#: bookwyrm/templates/snippets/goal_form.html:26 +msgid "Goal privacy:" +msgstr "Tikslo privatumas:" + +#: bookwyrm/templates/snippets/goal_form.html:33 +#: bookwyrm/templates/snippets/reading_modals/layout.html:13 +msgid "Post to feed" +msgstr "Skelbti" + +#: bookwyrm/templates/snippets/goal_form.html:37 +msgid "Set goal" +msgstr "Nustatyti tikslą" + +#: bookwyrm/templates/snippets/goal_progress.html:9 +#, python-format +msgid "%(percent)s%% complete!" +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ų." + +#: bookwyrm/templates/snippets/goal_progress.html:14 +#, python-format +msgid "%(username)s has read %(read_count)s of %(goal_count)s books." +msgstr "%(username)s perskaitė %(read_count)s iš %(goal_count)s knygų." + +#: bookwyrm/templates/snippets/page_text.html:8 +#, python-format +msgid "page %(page)s of %(total_pages)s" +msgstr "%(page)s psl. iš %(total_pages)s" + +#: bookwyrm/templates/snippets/page_text.html:14 +#, python-format +msgid "page %(page)s" +msgstr "%(page)s psl." + +#: bookwyrm/templates/snippets/pagination.html:12 +msgid "Previous" +msgstr "Ankstesnis" + +#: bookwyrm/templates/snippets/pagination.html:23 +msgid "Next" +msgstr "Kitas" + +#: bookwyrm/templates/snippets/privacy-icons.html:3 +#: bookwyrm/templates/snippets/privacy-icons.html:4 +#: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 +msgid "Public" +msgstr "Viešas" + +#: bookwyrm/templates/snippets/privacy-icons.html:7 +#: bookwyrm/templates/snippets/privacy-icons.html:8 +#: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 +msgid "Unlisted" +msgstr "Nėra sąraše" + +#: bookwyrm/templates/snippets/privacy-icons.html:12 +msgid "Followers-only" +msgstr "Tik sekėjai" + +#: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 +msgid "Post privacy" +msgstr "Įrašo privatumas" + +#: bookwyrm/templates/snippets/privacy_select.html:17 +#: bookwyrm/templates/user/relationships/followers.html:6 +#: bookwyrm/templates/user/relationships/layout.html:11 +msgid "Followers" +msgstr "Sekėjai" + +#: bookwyrm/templates/snippets/rate_action.html:4 +msgid "Leave a rating" +msgstr "Palikti įvertinimą" + +#: bookwyrm/templates/snippets/rate_action.html:19 +msgid "Rate" +msgstr "Įvertinti" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:6 +#, python-format +msgid "Finish \"%(book_title)s\"" +msgstr "Užbaigti „%(book_title)s“" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:23 +#: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:20 +#: bookwyrm/templates/snippets/readthrough_form.html:7 +msgid "Started reading" +msgstr "Pradėta skaityti" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:31 +#: bookwyrm/templates/snippets/readthrough_form.html:20 +msgid "Finished reading" +msgstr "Baigta skaityti" + +#: bookwyrm/templates/snippets/reading_modals/form.html:9 +msgid "(Optional)" +msgstr "(Nebūtina)" + +#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 +msgid "Update progress" +msgstr "Atnaujinti progresą" + +#: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:6 +#, python-format +msgid "Start \"%(book_title)s\"" +msgstr "Pradėti „%(book_title)s“" + +#: bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html:6 +#, python-format +msgid "Want to Read \"%(book_title)s\"" +msgstr "Noriu perskaityti „%(book_title)s“" + +#: bookwyrm/templates/snippets/readthrough_form.html:14 +msgid "Progress" +msgstr "Progresas" + +#: bookwyrm/templates/snippets/register_form.html:32 +msgid "Sign Up" +msgstr "Registruotis" + +#: bookwyrm/templates/snippets/report_button.html:6 +msgid "Report" +msgstr "Pranešti" + +#: bookwyrm/templates/snippets/report_modal.html:6 +#, python-format +msgid "Report @%(username)s" +msgstr "Pranešti apie @%(username)s" + +#: bookwyrm/templates/snippets/report_modal.html:23 +#, python-format +msgid "This report will be sent to %(site_name)s's moderators for review." +msgstr "Šis pranešimas bus nusiųstas peržiūrėti %(site_name)s puslapio moderatoriams." + +#: bookwyrm/templates/snippets/report_modal.html:24 +msgid "More info about this report:" +msgstr "Daugiau informacijos apie šį pranešimą:" + +#: bookwyrm/templates/snippets/shelf_selector.html:4 +msgid "Move book" +msgstr "Perkelti knygą" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown.html:5 +msgid "More shelves" +msgstr "Daugiau lentynų" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:17 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:24 +msgid "Start reading" +msgstr "Pradėti skaityti" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:29 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:36 +msgid "Want to read" +msgstr "Noriu perskaityti" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:62 +#, python-format +msgid "Remove from %(name)s" +msgstr "Pašalinti iš %(name)s" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:30 +msgid "Finish reading" +msgstr "Baigti skaityti" + +#: bookwyrm/templates/snippets/status/content_status.html:72 +msgid "Content warning" +msgstr "Įspėjimas dėl turinio" + +#: bookwyrm/templates/snippets/status/content_status.html:79 +msgid "Show status" +msgstr "Rodyti būseną" + +#: bookwyrm/templates/snippets/status/content_status.html:101 +#, python-format +msgid "(Page %(page)s)" +msgstr "(Psl. %(page)s)" + +#: bookwyrm/templates/snippets/status/content_status.html:103 +#, python-format +msgid "(%(percent)s%%)" +msgstr "(%(percent)s%%)" + +#: bookwyrm/templates/snippets/status/content_status.html:125 +msgid "Open image in new window" +msgstr "Atidaryti paveikslėlį naujame lange" + +#: bookwyrm/templates/snippets/status/content_status.html:144 +msgid "Hide status" +msgstr "Slėpti būseną" + +#: bookwyrm/templates/snippets/status/header.html:45 +#, python-format +msgid "edited %(date)s" +msgstr "redaguota %(date)s" + +#: bookwyrm/templates/snippets/status/headers/comment.html:2 +#, python-format +msgid "commented on %(book)s" +msgstr "komentuota %(book)s" + +#: bookwyrm/templates/snippets/status/headers/note.html:8 +#, python-format +msgid "replied to %(username)s's status" +msgstr "atsakyta į %(username)s būseną" + +#: bookwyrm/templates/snippets/status/headers/quotation.html:2 +#, python-format +msgid "quoted %(book)s" +msgstr "pacitavo %(book)s" + +#: bookwyrm/templates/snippets/status/headers/rating.html:3 +#, python-format +msgid "rated %(book)s:" +msgstr "įvertinta %(book)s:" + +#: bookwyrm/templates/snippets/status/headers/read.html:7 +#, python-format +msgid "finished reading %(book)s" +msgstr "baigti skaityti %(book)s" + +#: bookwyrm/templates/snippets/status/headers/reading.html:7 +#, python-format +msgid "started reading %(book)s" +msgstr "pradėjo skaityti %(book)s" + +#: bookwyrm/templates/snippets/status/headers/review.html:3 +#, python-format +msgid "reviewed %(book)s" +msgstr "apžvelgė %(book)s" + +#: bookwyrm/templates/snippets/status/headers/to_read.html:7 +#, python-format +msgid "%(username)s wants to read %(book)s" +msgstr "%(username)s nori perskaityti %(book)s" + +#: bookwyrm/templates/snippets/status/layout.html:24 +#: bookwyrm/templates/snippets/status/status_options.html:17 +msgid "Delete status" +msgstr "Ištrinti įrašą" + +#: bookwyrm/templates/snippets/status/layout.html:56 +#: bookwyrm/templates/snippets/status/layout.html:57 +msgid "Boost status" +msgstr "Pagreitinti būseną" + +#: bookwyrm/templates/snippets/status/layout.html:60 +#: bookwyrm/templates/snippets/status/layout.html:61 +msgid "Like status" +msgstr "Mėgti būseną" + +#: bookwyrm/templates/snippets/status/status.html:10 +msgid "boosted" +msgstr "pagreitinta" + +#: bookwyrm/templates/snippets/status/status_options.html:7 +#: bookwyrm/templates/snippets/user_options.html:7 +msgid "More options" +msgstr "Daugiau parinkčių" + +#: bookwyrm/templates/snippets/switch_edition_button.html:5 +msgid "Switch to this edition" +msgstr "Perjungti į šį leidimą" + +#: bookwyrm/templates/snippets/table-sort-header.html:6 +msgid "Sorted ascending" +msgstr "Surūšiuota didėjimo tvarka" + +#: bookwyrm/templates/snippets/table-sort-header.html:10 +msgid "Sorted descending" +msgstr "Surūšiuota mažėjimo tvarka" + +#: bookwyrm/templates/snippets/trimmed_text.html:17 +msgid "Show more" +msgstr "Rodyti daugiau" + +#: bookwyrm/templates/snippets/trimmed_text.html:35 +msgid "Show less" +msgstr "Rodyti mažiau" + +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Jūsų knygos" + +#: bookwyrm/templates/user/books_header.html:15 +#, python-format +msgid "%(username)s's books" +msgstr "%(username)s – knygos" + +#: bookwyrm/templates/user/goal.html:8 +#, python-format +msgid "%(year)s Reading Progress" +msgstr "%(year)s m. skaitymo progresas" + +#: bookwyrm/templates/user/goal.html:12 +msgid "Edit Goal" +msgstr "Redaguoti tikslą" + +#: bookwyrm/templates/user/goal.html:28 +#, python-format +msgid "%(name)s hasn't set a reading goal for %(year)s." +msgstr "%(name)s nenustatė %(year)s m. skaitymo tikslo." + +#: bookwyrm/templates/user/goal.html:40 +#, python-format +msgid "Your %(year)s Books" +msgstr "Jūsų %(year)s m. knygos" + +#: bookwyrm/templates/user/goal.html:42 +#, python-format +msgid "%(username)s's %(year)s Books" +msgstr "%(username)s – %(year)s m. knygos" + +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "Jūsų grupės" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "Grupės: %(username)s" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "Sukurti grupę" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 +msgid "User Profile" +msgstr "Naudotojo paskyra" + +#: bookwyrm/templates/user/layout.html:45 +msgid "Follow Requests" +msgstr "Sekti prašymus" + +#: bookwyrm/templates/user/layout.html:70 +msgid "Reading Goal" +msgstr "Skaitymo tikslas" + +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "Grupės" + +#: bookwyrm/templates/user/lists.html:11 +#, python-format +msgid "Lists: %(username)s" +msgstr "Sąrašai: %(username)s" + +#: bookwyrm/templates/user/lists.html:17 bookwyrm/templates/user/lists.html:29 +msgid "Create list" +msgstr "Sukurti sąrašą" + +#: bookwyrm/templates/user/relationships/followers.html:12 +#, python-format +msgid "%(username)s has no followers" +msgstr "%(username)s neturi sekėjų" + +#: bookwyrm/templates/user/relationships/following.html:6 +#: bookwyrm/templates/user/relationships/layout.html:15 +msgid "Following" +msgstr "Sekama" + +#: bookwyrm/templates/user/relationships/following.html:12 +#, python-format +msgid "%(username)s isn't following any users" +msgstr "%(username)s nieko neseka" + +#: bookwyrm/templates/user/user.html:16 +msgid "Edit profile" +msgstr "Redaguoti paskyrą" + +#: bookwyrm/templates/user/user.html:33 +#, python-format +msgid "View all %(size)s" +msgstr "Žiūrėti visus %(size)s" + +#: bookwyrm/templates/user/user.html:46 +msgid "View all books" +msgstr "Žiūrėti visas knygas" + +#: bookwyrm/templates/user/user.html:59 +msgid "User Activity" +msgstr "Naudotojo aktyvumas" + +#: bookwyrm/templates/user/user.html:63 +msgid "RSS feed" +msgstr "RSS srautas" + +#: bookwyrm/templates/user/user.html:74 +msgid "No activities yet!" +msgstr "Įrašų dar nėra" + +#: bookwyrm/templates/user/user_preview.html:22 +#, python-format +msgid "Joined %(date)s" +msgstr "Joined %(date)s" + +#: bookwyrm/templates/user/user_preview.html:26 +#, python-format +msgid "%(counter)s follower" +msgid_plural "%(counter)s followers" +msgstr[0] "%(counter)s sekėjas" +msgstr[1] "%(counter)s sekėjai" +msgstr[2] "%(counter)s sekėjų" +msgstr[3] "%(counter)s sekėjai" + +#: bookwyrm/templates/user/user_preview.html:27 +#, python-format +msgid "%(counter)s following" +msgstr "%(counter)s seka" + +#: bookwyrm/templates/user/user_preview.html:34 +#, python-format +msgid "%(mutuals_display)s follower you follow" +msgid_plural "%(mutuals_display)s followers you follow" +msgstr[0] "%(mutuals_display)s sekėjas, kurį sekate jūs" +msgstr[1] "%(mutuals_display)s sekėjai, kuriuos sekate jūs" +msgstr[2] "%(mutuals_display)s sekėjai, kuriuos sekate jūs" +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" + +#: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28 +msgid "File exceeds maximum size: 10MB" +msgstr "Failas viršijo maksimalų dydį: 10 MB" + +#: bookwyrm/templatetags/utilities.py:31 +#, python-format +msgid "%(title)s: %(subtitle)s" +msgstr "%(title)s: %(subtitle)s" + +#: bookwyrm/views/imports/import_data.py:64 +msgid "Not a valid csv file" +msgstr "Netinkamas csv failas" + +#: bookwyrm/views/landing/login.py:69 +msgid "Username or password are incorrect" +msgstr "Naudotojo vardas arba slaptažodis neteisingi" + +#: bookwyrm/views/landing/password.py:32 +msgid "No user with that email address was found." +msgstr "Šiuo el. pašto adresu nerastas nei vienas narys." + +#: bookwyrm/views/landing/password.py:43 +#, python-brace-format +msgid "A password reset link was sent to {email}" +msgstr "Slaptažodžio atstatymo nuoroda išsiųsta į {email}" + +#: bookwyrm/views/rss_feed.py:35 +#, python-brace-format +msgid "Status updates from {obj.display_name}" +msgstr "Būsenos atnaujinimai iš {obj.display_name}" + From 7d66013b52ee206829ead146259b831687fd2d37 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 10:26:00 -0800 Subject: [PATCH 117/134] Adds Lithuanian to the user options --- .../0117_alter_user_preferred_language.py | 32 +++++++++++++++++++ bookwyrm/settings.py | 1 + 2 files changed, 33 insertions(+) create mode 100644 bookwyrm/migrations/0117_alter_user_preferred_language.py diff --git a/bookwyrm/migrations/0117_alter_user_preferred_language.py b/bookwyrm/migrations/0117_alter_user_preferred_language.py new file mode 100644 index 000000000..c892b0516 --- /dev/null +++ b/bookwyrm/migrations/0117_alter_user_preferred_language.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.5 on 2021-11-15 18:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0116_auto_20211114_1734"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="preferred_language", + field=models.CharField( + blank=True, + choices=[ + ("en-us", "English"), + ("de-de", "Deutsch (German)"), + ("es-es", "Español (Spanish)"), + ("fr-fr", "Français (French)"), + ("lt-lt", "lietuvių (Lithuanian)"), + ("pt-br", "Português - Brasil (Brazilian Portuguese)"), + ("zh-hans", "简体中文 (Simplified Chinese)"), + ("zh-hant", "繁體中文 (Traditional Chinese)"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index 44d65cca0..d469e6fe7 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -166,6 +166,7 @@ LANGUAGES = [ ("de-de", _("Deutsch (German)")), ("es-es", _("Español (Spanish)")), ("fr-fr", _("Français (French)")), + ("lt-lt", _("lietuvių (Lithuanian)")), ("pt-br", _("Português - Brasil (Brazilian Portuguese)")), ("zh-hans", _("简体中文 (Simplified Chinese)")), ("zh-hant", _("繁體中文 (Traditional Chinese)")), From bcfe13bb4ef7f9710003d1394571b65c36016158 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 11:27:27 -0800 Subject: [PATCH 118/134] Sort followers/following lists by if you follow the user --- bookwyrm/views/user.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/bookwyrm/views/user.py b/bookwyrm/views/user.py index b7ab1d3cf..082408f97 100644 --- a/bookwyrm/views/user.py +++ b/bookwyrm/views/user.py @@ -1,6 +1,7 @@ """ non-interactive pages """ from django.contrib.auth.decorators import login_required from django.core.paginator import Paginator +from django.db.models import Q, Count from django.http import Http404 from django.shortcuts import redirect from django.template.response import TemplateResponse @@ -105,9 +106,8 @@ class Followers(View): if is_api_request(request): return ActivitypubResponse(user.to_followers_activity(**request.GET)) - paginated = Paginator( - user.followers.order_by("-created_date").all(), PAGE_LENGTH - ) + followers = annotate_if_follows(request.user, user.followers) + paginated = Paginator(followers.all(), PAGE_LENGTH) data = { "user": user, "is_self": request.user.id == user.id, @@ -126,9 +126,8 @@ class Following(View): if is_api_request(request): return ActivitypubResponse(user.to_following_activity(**request.GET)) - paginated = Paginator( - user.following.order_by("-created_date").all(), PAGE_LENGTH - ) + following = annotate_if_follows(request.user, user.following) + paginated = Paginator(following.all(), PAGE_LENGTH) data = { "user": user, "is_self": request.user.id == user.id, @@ -137,6 +136,16 @@ class Following(View): return TemplateResponse(request, "user/relationships/following.html", data) +def annotate_if_follows(user, queryset): + """Sort a list of users by if you follow them""" + if not user.is_authenticated: + return queryset.order_by("-created_date") + + return queryset.annotate( + request_user_follows=Count("followers", filter=Q(followers=user)) + ).order_by("-request_user_follows", "-created_date") + + class Groups(View): """list of user's groups view""" From 5e5cb262907f0f8a3f3a6364ce17e32ce9877fbd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 11:41:29 -0800 Subject: [PATCH 119/134] Preserve spaces between links --- bookwyrm/templates/import/manual_review.html | 6 ++++-- bookwyrm/templates/snippets/book_titleby.html | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/bookwyrm/templates/import/manual_review.html b/bookwyrm/templates/import/manual_review.html index b6c2b6b26..7e429a0fa 100644 --- a/bookwyrm/templates/import/manual_review.html +++ b/bookwyrm/templates/import/manual_review.html @@ -46,8 +46,10 @@ {% include 'snippets/book_cover.html' with book=guess cover_class='is-h-s' size='small' %} -
    - {% include 'snippets/book_titleby.html' with book=guess %} +
    +

    + {% include 'snippets/book_titleby.html' with book=guess %} +

    {% csrf_token %} diff --git a/bookwyrm/templates/snippets/book_titleby.html b/bookwyrm/templates/snippets/book_titleby.html index 1c2bb176d..6dbaeb265 100644 --- a/bookwyrm/templates/snippets/book_titleby.html +++ b/bookwyrm/templates/snippets/book_titleby.html @@ -5,11 +5,9 @@ {% if book.authors.exists %} {% blocktrans trimmed with path=book.local_path title=book|book_title %} {{ title }} by -{% endblocktrans %} -{% include 'snippets/authors.html' with book=book limit=3 %} +{% endblocktrans %} {% include 'snippets/authors.html' with book=book limit=3 %} {% else %} {{ book|book_title }} {% endif %} - {% endspaceless %} From f22ae235748c6ec12c3f08af823df720890cbd30 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 15 Nov 2021 13:30:11 -0800 Subject: [PATCH 120/134] Safer call to get preview image or books --- bookwyrm/models/status.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bookwyrm/models/status.py b/bookwyrm/models/status.py index a52af123c..c7c0a4253 100644 --- a/bookwyrm/models/status.py +++ b/bookwyrm/models/status.py @@ -189,8 +189,10 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel): if hasattr(activity, "name"): activity.name = self.pure_name activity.type = self.pure_type - books = [getattr(self, "book", None)] + list(self.mention_books.all()) - if len(books) == 1 and books[0].preview_image: + book = getattr(self, "book", None) + books = [book] if book else [] + books += list(self.mention_books.all()) + if len(books) == 1 and getattr(books[0], "preview_image", None): covers = [ activitypub.Document( url=fields.get_absolute_url(books[0].preview_image), From 77f29a621f80e5ce1a80bf166e57528309333e7d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Nov 2021 09:29:58 -0800 Subject: [PATCH 121/134] Adds command to pull locale updates --- bw-dev | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/bw-dev b/bw-dev index 35f3694ee..f50800cf0 100755 --- a/bw-dev +++ b/bw-dev @@ -108,6 +108,17 @@ case "$CMD" in compilemessages) runweb django-admin compilemessages --ignore venv $@ ;; + update_locales) + git fetch origin l10n_main:l10n_main + git checkout l10n_main locale/de_DE + git checkout l10n_main locale/es_ES + git checkout l10n_main locale/fr_FR + git checkout l10n_main locale/lt_LT + git checkout l10n_main locale/pt_BR + git checkout l10n_main locale/zh_Hans + git checkout l10n_main locale/zh_Hant + runweb django-admin compilemessages --ignore venv + ;; build) docker-compose build ;; From a1830ac70165c90036bf97ef3d4f0d9fc25eac7b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Nov 2021 09:30:11 -0800 Subject: [PATCH 122/134] Adds updates locales --- locale/de_DE/LC_MESSAGES/django.mo | Bin 61566 -> 60544 bytes locale/de_DE/LC_MESSAGES/django.po | 258 +++++--- locale/es_ES/LC_MESSAGES/django.mo | Bin 61028 -> 60011 bytes locale/es_ES/LC_MESSAGES/django.po | 258 +++++--- locale/fr_FR/LC_MESSAGES/django.mo | Bin 62690 -> 62284 bytes locale/fr_FR/LC_MESSAGES/django.po | 260 +++++--- locale/lt_LT/LC_MESSAGES/django.mo | Bin 61077 -> 61085 bytes locale/lt_LT/LC_MESSAGES/django.po | 8 +- locale/pt_BR/LC_MESSAGES/django.mo | Bin 56435 -> 62235 bytes locale/pt_BR/LC_MESSAGES/django.po | 849 +++++++++++++++++---------- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 56859 -> 56164 bytes locale/zh_Hans/LC_MESSAGES/django.po | 286 +++++---- locale/zh_Hant/LC_MESSAGES/django.mo | Bin 38249 -> 37625 bytes locale/zh_Hant/LC_MESSAGES/django.po | 252 +++++--- 14 files changed, 1399 insertions(+), 772 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.mo b/locale/de_DE/LC_MESSAGES/django.mo index 19aa94f8fc132c768e7691d5fc774579469219ee..f49377602bd22295101586a22cb0e70402ea5905 100644 GIT binary patch delta 17240 zcmezOfVtr&bNxLbmZ=O33=A^N3=A?13=DrH7#LJp7#QvtfU+u<~T7hI599VY;s~?uwh_e`0B*KpvS<#VC2leAkDzQkm$_7V8p<{Q0olQx51f# zL5zWc;kGjag98Ht!zX73h5!Zz24fcn1_K6$dWIGk1_pTs28OLJ3=I4X3=CIY7#PGE z7#NjfV_;BZU|{HQgLq_>8v}zRLp=k-0XK-nx7-*QOc)p# zUb!(aa4|42$h$+twcHsPR2di;tlSwG_!t-%65Js^&39*DP-b9Y=yr$rc)dFVLp}oo z!y_mi{3?beO3{?ya3~AmB43P{B3=h2_L1^s*3DO!L1_o0G28PK# z3=EnK3=Ais^k*MPNXYs!Ft9Q(Fu3?KFbFd+FnIYgFt9N&FvR&XFmQlE#Fv4go|l1v zAI%x z85kI@`$9tSp)VxlK0?JA{2=mNehl^Cpce6i7$EP*z#zcDz@Xy?(O~Pxz`)JGz~JM@ zzyL~*5q=OKbV1ck^n*BjksrjTtDxp=fa>4t2l43{KZrxGLM^@tr62p%LtOY4s_`$> zA})VOoZ9$95=*{61A`DK?))K%a)v*|!8`pK7(gL-%pc<5EB+9R9{V#eWHT@@Jokqr zy5Inad8Gjm^(z7(4&PQEz`(GGfq`LP03=8f10g=n4utT_10g_7$v z2~f}nLJYbFrSAnYFtC6US0KdUuLB_tWekF-=L>>(SUm{hkb3hVhz8dnh{aw(kf00; zf*2eFRhSY4NdrYe5TCX{^-T_fMA?iWNUm8K1WBx0pz8R785kxoFfhmlL(E+l4AH+O z7;IiW!(phz)nJHAZ$tSnf+0S57YqpjmJo=`xkDf>mkxob*9?IeY!(7hX9HE|90GAz za0tXBDIt)wkP`w4*;250Jp)612-qbI?NEbfLh0pD@vR{Y3{ngX497ztQSb;#e+3)B zz`zj-ahO0T#6pEoh((5>kb=!B6ym_BP>2H)LLu2PJ(Pig2bBM-Lm@uu2!%w!G>`-X z1H+yc4Q^YB(h7 z7KcN8yc4SL0Mz{RQ1y4h8S24h`U|MUU#J0G5s)%oA_9_X4I&^x?->Dcc}xVP2+oUO zU`S!~?%0AU@@YghYuzBqRzHBOy_x9?8I9!N9;^4k~{^Ay5zrNfcF) z5REO7kT~p#goMCUsK&)m{^m$X93F)7uR`S?M?!r3ITGTKUr_VdqabOBKME3ZT2YV? z(yxz#_{cR15`^JV5RJ)E5C;`N>8dD*4_l!8eyF;cQ1N9@dLvYPPZY$bC!yjuq2@n< zI^;tXBn0ZYqai`#5)IMd6%C2wsAx#gWky4MR22;gk;Z6#4&2+^;is(f#5RV*&ntLe*;-T9ykf479)>qHKz!VE{IcF>+1mt2NQKARs zJH$d96c7tBFbc}gjD`5H7%E;L3o*D4s&7dwB!sraLPBUyEX0H7V<8^95zD~91pLbmAEpJV0%}c!&e4;~_!c z1m(|y(hK7uLB1j$V)4#+h{uk_LqhmUJVQOWet#AZ3Hnb^io^cO;=6;)Baji*6-Ag7Q@YB<}tv zK&o5zLc1|KB>Xs)$Jg^z6 z?r41?1E@8`a5WKp1FkHxhbW~U}Ar`u3 zLLB6m32}HRl#b72s0VjEGBY7AEzE>ell7U9pq!NnNxhpgAwhWz%D(|M@J%MD568gp zITPYA-YiInsbxVd3e18yJUR;!0trw$Hw#jNR%O*gf^cmX#0Q76ATB-yr7uIp?_@#J zz>_S9&p&5D`h?8c5Ph0Z+AtfU-!dEGV5e+|Lqf74ArO}hiR#pBNE#`u&t_myVPIfr z$%e%7%4~=QN3$WR{%STP3LZcWcm}oLZ8pSb-=N~Zp$=fmfjE>a2O=+-1M#_B4kU!N zp?piIx_Y-9h=rk0iPRiOkQPBT^g!uZIS?PLfT~{)^ugBK2UQzkAXo4)KAZc zD2#*BY59<#%*%%)#^QX4&)V}L7WU?Y3}RrInGXrc1^EyUZODgY=R;8b<9tX|e9ec1 z08;@212-uDix)t$jdB4*L3jbg2Pp-RI4drISlkHGz`(#TwE*Ivg$0mAxD2ZPOaa8< zx1r`dE`W4KKNK*4Vu9gH0mSD?g%CQskb$8d)bB4TgrvrrLP&n@FN8Q`K_Mil*Fx#- zg^-{;SP1d?<3dQ3yf1_}gtZ9b0PP}(!;Om|9&s#!SQtG;F(k^?7DN00TZ$nC&XHnBqPhdsz+3`xId=)fLJ=rmr37MtZVALkCQxy^ z5=aQSmq0=$vjmce>q{UGm{kIC&?2b54Il~7sMoF%NRXd`8g#t`(v5xq)nHW$2}+Mr zh`R7nh|g0>Ar7oAg_L|PrI5;LeJKNj7Xt&sT_~+l1}V~u%OGvTMP&>OE({C|^#{rz zK4&e5q)ORxNLnx|2iMOGuH}&Nz9gvp(sD=;?<$Anf}`b-kT_iq@!=(?_^onC6g()0 zB-S_O5Qlz*(!a{VAy?19TmjL@3#COXAVDo#0ZH|`6%dV%6%ZeLLHUUlU;`Mkp!^c3 zzFH{17i!+L3P_O8t6*R_%D}*|rUK%DqDs(cTRj6qZ6!p(%}PknK8Mm@Dj^}lSOu|2 ztP0`~g(^rQ)r5-sR6#-_tO^nmF;$SZVlq^HH&!I7F-(5+d5wkf61%h8XBw4RKg(H6(7+sv(KEr5fU))zuIO?x==@ z^uB6H_B&S1z)%kw(|u6Qz|haY!0@da;()dqh>xe#K%!z^4a9(TH4ynNHIOmfLp6{A zNa0#Y;`6L!VA#OGz)(^P8M0NaV_=A5U|=Y!gEU+&)4|NO-K@1EG%JmHO;IZGb zddNuUw0cN6AlLvN9A>a>fP_q51H>UM4UmFnN(00JyBZ*=oVyVcGGUF7B0Q@R;`8Z^ zkhosb2nn(EQ2y>l28JRA28Lse^`Jz+z+l+~Q8={;;==_^kT_b`1kt#+3F45GO^|}- zeiOuk|4op=XP#zA+$T0e49;kVguv})NXTfkKteFM1ri03Ees64pwaUB7D)SlJyhUd z3nYkqS{WFaK>4#3GV;=h(KLC1A`-Iw7MN)AWH`WgEs>M18)Z;1R^^iK1zks zo1pUlJ0MZz-3cjBYC0hyau7<3bwNhIv%4V8`~6)IkNoHYhjcvycQ>S(lw8=gG@5|U3QFfiCLFfeFLgp{D^6G0X+FtkjBB+i`^AqCm9i3|*3p#1-LA_GGj zXuN+C1A`d@1HbjO6o`v>ra}}bPlY5do2d*8_MqYSsgT^! zGZo^X=~E#-S}_$;Fx{OBY1@683Te!WO@kz2>uC%OHK6&0X$%bI3=9mfr!g?pF)%PB zPluEXkES!!GbDp%KxQy7#DnVp8IU+)oyowE1e*Dn2^qmWITKQin$BWi=wM)A2$;pd zkPhmC&4Pr4<7`OwoH85Y;8n9BmDa1-kRaEc14*1wb0BGK{v1fiEuB*jiR+znAU-@a z2a@m4&Vl&!&KyW0dOHWA?hDj_zjGj|n0YQlUTiKzzwBH{Zqb+v2}zT=5OaLzLM)7f ziWkj=gm`y7RASLwh!3{Sg&2GWDt>=1ByK-L<+O#` z>Yh3e;*q)YAaT70%D+4hV*Vqjy85s4ATItp4^nV&&WBVYV)G#`H<=Gfl& z7;5H264{RVki>OmJ|ylx&WGq1T>!CIX#qsP;R1;HP74?qS{WD^{1!k;&?^hT=G8NN zSpZ3F1`8ny9TqY$90w&jC|_g|#2|%5kSH*O(pHNgLF~K;lIUULkx;p45<}U7DFt~gVODb zAqFm33~A|XS`5h*+o9^uEM{QHU|?XlwiptX_Ddi$BH>FI7}!Di|HTqWoP1aU(a5|M zlBgt>LL4B!6ykH;rI18pwiMzJ-=&a{3114)m$4L*$ZD5D663_B5Rc4R3JKvAQ1v^O zLZa&AQU->4&`jqwsK7(0hIdc{e=UUs8UHef1GSbx5})ldNE`-3#fz6gLauEY#NkVp zLDInLWe|&ZErW#Msb!F&`O-3o2N;$!)PpAqxt2qGCbAsjBkko7pV%yi7!UxZ6QJ@1 z%OMsvLizKd@*AM^0jT(e<&a70hszce-eauQo+~=)?q>bX0kf85b2{C`hN=T8uXeA^n z&#Z)0N>}Tl2EAVi39|nyA*q;e6@;&~3SzP4Du}_Js~{SaRzVz6vkDR=lUG4PWaTOb zhGx)Y)hdWbyjMfgP}pin6r@1uoYfHd`jXWUAJngg6etr{LtK6uN?%_Maq;8T5TCq( ziho-TNpwtWAR#2a2Etca15t0e2I6q1HIR@DS_AP=GPgP7O5 z4wA@Lt%G>v(mF^8JX;3|v9BN+l>eF5Ls~%m>me2ytcN5fhxHH(T-QV5%5Oa+t|Qk& z(n3B|UB`Mzb=$ihV!?s+kT^fT9#Ze$T@Pu5{$CGqpw?60UIF(MQ?-{Pz>eQZiM)F>PCo*S8s$kaOXyd0}pJ31m)F@3=CnQr58{O zEH^>)Ic|cO7rqISwh}i%>i@<~5Odl$)kEUAZxe)Gun7{>n>Ilb)!t1Ihn?F534v#u zAW`xOO84(Vw;%k{t^-LoDjw4ADPrGbGzC+6)Pqo%Nd`J~#`NxV0H# z@yE>&2Qh7d7$~v@5_IxgAmxMl7Kp=~w?NcIZ-InJ?iPr7O;CP6lwPt05(PWAK+Hd} z1>%wVn@|fLK^44(O8nUZNi3{eA&FCBE5rwuTOk7pu28xJD!+IuB&d&Uh3GrC6_S`A zZiP7X<5q};oZBGkgtmdBw4Om`8^mQ=+aL-pw?X=Lf!iRdchNS8#v|JxEheSLFUvmFcfZwG?BWtLlVbE zr~%uzLxTG3c8CLBZiiGRpP+pG9T1;b>;U_O!D$CXf4~k%9Ea_IjDqLx09nMquxQF4(!}?jkh*|r7eu|x zE(qUf7sLTRyCD6AKxpGGNL+2-1qq_#yC5akIjDi( zc0qg~up5%9HFrZSaNiB-lEv+Y3}ANch6MG#-H-z3>~2VR{l{*Iez`pm+I$ZrWCHdu z)PvW2P22+sl7)L9KG?YjV$kJ1ki_?1O}$z&=QtkcILM_SHjz(smytdwJ}G1aZJVhas9e{*D*8xasUwHtM@An>nB+~N-AP#$d021UM4nRUu>>#8GXK)Z= zzV|^$$b=q*4WND235BXtgfDcVf$f-4-OuNB#s-0 zAwGN!rGFlVq;B>jkT|wJ0`Zae5r{*=k3c+-a0Fs;(GiF_HAf&8_aA|nzZ@#R?+C=< zCyp>MsDSeS`6H0H_;Li2$T*Ke;?C+Q#K4fFkTel@6jDuR9))DPwxbYzo1p5BAB9B0 z#iNkgj^h}_AsWXZ4zPyOLB}AC(adAe@&C!kAVE9(7{sE*#~2uvFfcHzI|eZ@_&6la zx{gCaX8Li6!Ze2H zmqO(aoPv1d!YKv@chKtCQxJ=7PeVe+>og?S#GQsXxTO9xBq(c7Lo8}P4H>svbQ)4w zoIVXn6O3mdsoCfZ#37DnAU+H{12H)548#LfXCMVq#~B9jYS?9GAW?eu48)^1&Oki& zKW9}L406*4&oyBa}Wmvo`V>Wat;#YW#=GcL+$4v zK7DZx5+dKuK}tr}^Nw>O8e0=^2 zMEu1SNR<4#0ts^7tB{b9fzmoxA*tTxDkQ2BuR_!nLFF5-f`XcXVd7Oth#Z2dJAIX* z9=tgG&Q*xdKVOBojPn|#1eCi5G0@@~MBein#K-Ya`En?K;x&kaR$haI(9Ua+5V~>= zQqtYK25Bd7T!)x%eH{`-0oS4RfB1DsP$xkZG+bw3I0Tw%y$*3e#0`jnnKvLlE4~4V z>!uqJi#u*WM$2d1U|_IiU|@K117e}lO$LT73=9mRHyIehK}$1lL56yhZb72>Wc@7$ z@bdYmw;;pjBDW#+edcWjhF%5+hThu{dFeZlMCx@1lG^L;KrEhn2O_`r4rKB9ojZ_3 z>~j~AIOpGml!)8zLPGG#T}Ybv1*Pjb?mlwHnf*A}#4;dIj85kI(9x^Zlf|koXWMGH@O-MY1OdLo*g3M-zJc0~9M?8X9(EA7y zmy;hs95Cw<#Nq26K`O63k04R^`4MDT{_i752-!Ral?U|<4E>KGW%WI<00V>C6NpPo zpFn0jjy{1p@F@dBEXaXRAr@3Tg-kfKJ%u>@;Zw*me)DILT5ifSh&dOZK}Ne3pF{eH z4bK@E5*Zj6?mTB;Z~)c+b}t}7S^okO#8X~C3ZTU=AU-?x0+MaczJNI7+6#z}?!ABn z<%<`P#3uQYfng^6YX5pNh67#SEC6hSjp3=9nIj1Y&lF)}br zW@2DyWn^G5Wdv>Vfb1pF1Sw`_U;u4631MPjn83&&#&Cy;fuR;^07zK{BLhRy|-hgsC0|NsqGXuj#s2s>}0VW29HUIy3?HBpAcdAp3=B6IA;paiRQxw+(v^{c zp$*Chse8i+Nq#dy>KPaqjxaDVoMnP6(lcRXV3-A(M}a!V6ErCU(gYG?U|^7BW? zN}3?Ca3%(Z$Dr9^5C=3R$;80G$IQTB1J&HY$iQ$N%HG4kz%UW2&J9X~mLY6pWMGho zIu5iM2P6gRS1pH%f%vx>85ovZ!085ou`FfdGDVqoZCVqkayRig`)2XSYB(hg%i z149oZ19+K05R#-K)I!i^I(tS2hHeH1hEhfbhJ}m_3>r)f48NHe7|IwK7;Z2zFcdQ| zFqAPdFla&bG%_(TYz0l?F)}ceF)%Pxfy`%OV7SG^z#tAP4MDauK;~kZ>lqms)-y6N zurV_*m@_dj{9<5WV1zov2ukNOF)*YuGB8Mk)G;zJ1T#TK3!51k7)qdOW4Rw(WBLl-{s03(x zp*S-G!*M8o7Stk8gKZ8dM3@*D9x*X6Y=_E&jA(|c0kJ_i2$V$`85rJyNC$DnHU)EGchnc0A*iL zAp@F{WMp7)1%(0w1H*ep28NFekha$vCI*HDpxQbJ>=FisCPoH^B}@zq){G1cyO|gm z_Cv)hL2FnTCx0{-29*}vjF7fr0V4y$GX@4wcOSfSY8@j3!+iz@1~sS?KSP}cGGrc9 z%m9>GLCydb_Dl>6Cm10US)c_GS3so+6J(VIXeJdjX9?1Kor!@#4{BEC8c;33$iQ$D zB*Oq{BZ8RvObiTvK}nYp(tHE0AK1qPY4SyYEQ2~gn3;hgmWhFZpOJyVnhDajWMN_e zZ{d_?W?)zZRhJL)?Ia79Nfs>ipg|JQ-qW2-khbSDs2b3UK9JoY9K*=KaFUUMVG9!j zgCvLz5@cXtaAss+NMT}NSj_}!=e}lSV6cLE2C9TX802;)28O*%kR~KZd>W{=!oa|= z0F**O0z06Z9x^d7>|tbJI1hEiTm}XPQE1H~02KqZ#7&qWU4hpO3=Ha^LV^*}>;#zw z!ko+u3|UMJ3>Tn!c7X&zyE&os3r0vM3}!!A*beH5M~n;%GE9)p4OoJKf#C(HnZwM$ z@PmngVJ#yA!y~9f9Vk07GBD&o`AJX<6&M*9HZU?U>}O~6$(Lm)e69YpCR9+WKA7f%*cm>)x4O&po#K2&|$iQF@s%{Zx)-!wt zX=Y$xm=4N4P>m8$`ZB0wfhzvT$iVQ4k%57cnStRY69af?=o1qILl4L`pcXuo22r3M z!A($3hU$I5$iQF>%F$5%Hzo##pG*u4S)dxqf{B441>_r$P6h^s2vD4Yq5#SVQ7aiC zdt4WRDiKBohI3E{g5+Sh6KXhUUveiS1H)#hgfvv#7fFv469dCcP>Z#m2{Jyxha?Hr z$FQ6cvOEmN7hz^#-~_eVpaz2Ww5Nf5#=yXEg@J+LEh7U%AQJv)&b%aK^21*IT?fUGy?-e6B7f&Qc$43x9m>3w`U@g?m zjF1(YF-!~$rx+O+4uCp&3=9lwK#HM;X@ZJoCI$v2Mh1p2pjHM01A_!J1H(=R28NBG z`We(50$IYuz#zrUz_65of#D3OW68(>8kYr|(g`LR7#@SNEfWL7CQ$jC#>Bu73$oOx$iUzSvJ@K3AaQw6@PXRmAPxfq!(338iIIW9o{52B1E@92z`(GU0Wx$1 z8l!+JW0=ke*%@?a8!0-pukAf!5YYdQ4Sdh9&jF9Dj zAU0_2Ifw?~Mo_bek%1u!)I9YO&oEE6Nz~yeE=epZNlmfZJSTA?1~ z0|NuID+7ZA0|SGUD+5CS0|P^}D+7Z814BK-8dnAec?JfCyRHlj{0s~Xe_a_E#2FYE zc-9xQ+}s!#L>L$tCc8o8SGX}S$TBc69B^Y`2w`AgxaY>epvJ(! zVC)VNk8+2ouW)BzP-0+U=yhjcP-I|W*x(NF$R&3M21$l`28I{z5Q~{S7#K_#7#M^+ zAQrfLFfed2Ffhb>K;*ML7#LI;7#ONN7#R2%7#J3KKzzL3gMmSrfq~()2gK*^Js24B z85kIpJR$TXPX>lO1_lNuF9wES1_p*gF9wDL1_p+sUJMLT^$ZLQYTgVCkqitBjou6l zF$@e0x4jt{q8S(%EPNOk1Q{3@ruZ;0R536xEc1b=Q}l%dWwkFPX!rOsFqkqhFkJR! zV9;b>VBqwF(8hj{5Q+6;U|?lnU}*7UU=U_tVCeE=U|?flV3_B}z);V@z`(H7kAZ=g zfq`M29|HqB0|UbzsDdL<{%I)xvLD1jx1i#0{1_NO`oH)wFffCn&X0kChk=2C(H|nt z=g+{v$-uxM?hgq;MSn=h8A8P!{2A)O3cUOwK^@``F(BTbfkA+QfguN~q1K;)ft!JW zp~s(r!H|K0VTM1%2dALwF8V_p{>UHV(^pV)K0x*Vg*u2Q0OC;50EojR1L`3R`%?K@fAqf+4hAFarY%C~XBpJfo77hhNe0&9}?{P3B>RtpxqV#7lB+;^jK-9&BFfdGDU|`4% z0h?RT@DD1%5(+U;I20_wpc)EssWy~v5eo5vT__|ZLP8-viw=c2JR7RM5~{ups;&pB zZgMEZVT(f{A+#kFlt}9t81{rhg7_#@;ylzL*P#Z#gwo%k;;dl|3{s#}9R`UCBPi_} z1~E7y4C1haFo=Z(VIYeb7#hPM1zlGd#DlBC7#P?<`F}$gBwub1gZTJ#7{o_6!XQ!b z3@ZL93=)L@!yqBW7Y;4hz6ZVhyfOn5Q}{yAr?kOLW<;!NJy$}h=c_F%t(mC z*F-{!;(d_}45^^XDH7rVhbV|S-cit~iGoB)LKGwl3PI&BKLZ0pc@zVK1p@;^dlV!D z4nXNsP>oljAaQsn3gV!rQII(P4COONLxNl|8X~V64UspFhWOYy8sZSIXoy3?qakT1 zzCIcfbXC!iAOi70W&YG?NQf+lYTO(Rbr_UB6%Fy>6)68cRNYIc_%|rc7z44GCkEmm z$ry+}%@~OJ^(HY8mpH^gLLfQ@5;Rkw8fL{n;%Ze4Bez z3F0E1B!~lSlORFn4W&bqAR6P7AU?}Wf;hM|2@*1`Nsu_5l?17l7bP(;sDoO|Q294W zkPu}|hM3Qm3~{(feKN!#*XAP%%nfvERNfv68lfmoaY70*q9Wb;a>c>Sgnh(+6>1{_L(xbR{MBu?+AKoaHC z6o^lMra+q0e5nw5!&Hcc=BW?|IHy8FC@7VIL5_ieAu<&bG8Itu4N&!M5Pm(wq*RE( zGg28C%o!LM)}}%d+Jl$8z%+KO~Y zoY$s995_E6V$sHQNb~$iIwWLnr$a*IRXPKME~uHF!N9-)%KzpWkRWx)fMl2C42S{M z84v^eG8h>2K^=|^h(j(w#cx6BHyMy9_?H1G;kYtEK4W0e&V+Qq95NvxmYoT4Kzk;{ zoMo8|4E3Nc)rL$+939Ps`0#8dBn~fULVS8F6A~gXG9f|z6{`Lp)F8Gjh`2x&149-A z1A}B1BkPmUW zSw5tjZ3~r8%!lNPvV2HLEz5^^U`Ia0hX?W@Y2jo(q&NH|A5zrw6+l8%r2y1Bu4iD- zD}cm(XaOW>^9mp#Pz9ws3n2M>MghcvT?G&e4nftQE`T`jdI1ANA7~(=fPp~=)Wa!+ zsGkL;7ZpN+d{rSNQLZm!U|3B&YYm=4)ZOohXiq4DI~}XN+D%-Ln)+Mon8tFy6vS92OcVg zIOH7Ez&lWVPf8(C_XW!TT?#3HxXVC^jDbP94B`NgO$oSRh^wi8}Rih{Y!5knXr`IYfQ^ z^m0g$E`=)GQVt1$gXIt(-+*d-QVuB@-T3V6i-7H@Kr&AT)7I8|MjXMA!AYn2|{bA zxN{Z6fu2>6#2Z=#@nIB{POgH4WDZnc8I-Q8f`m+46(|?fGcZhpYFJeT@%d&b{}j}K z%TWGZsK#ed{x_(B|EnND$zILCaFl_8L9`m;f!o!PCf&1Yh`dt`Bq{=+bZiX+g9s@9 zXVpMlT3-Y4L1zsl)lPznZ>@oZ#QqvcNF1$!r1CRR^OrGfIkk|usjmeE2?N8FT1e2YfGXTl3vt-7T1ecUuZ5)Qx3v%- ziPS+Hs8|PyBK0~*cGRzfSnOHHz|apGNv(r8;C&s$!++}->cL~a?DY@>#OomnWa}Y= z#MC03H+WYhYlA1C5wAKw36djSS$y=g39|h9J;*VIw3P z-*1GBp#E=!lnYf&;K65xWlhlb|MezFqIlZ`DR}-iK^&mm3`ylB&5)4U-wY|+FE>Mc z&d>shYu*+}h)F>CDlH5QMGOoK`Yn(&um~#tuLa^k&Q?eiiPyJ6G^({ig372B;$n|h zhy@v~kkReZR!H2RYK0hlu@w>mE^UyInb-yi!98t|C^*!{z~IZkz;LP!(oc|Rhw#(e zAtAK2oq>Ugfq|j^MLT4q^L0BUU&?ks3^M3|gos%OB<|fhAW`Ap0dZJs2Lpo!0|UdP z4u}Q2J0Ky&)ycr%%)r19+6l36CY1lYlYzmJfq_B03u0bw7XyPgX#Bsd3lai{x*$F} z2c@OE!3r2Mx*>73r5jS9Jne>rh*l4TuJ2(053674fwccMdLbT3?1cn%NiU@KZ0d!0 zY;iBd0V{h!Ayv=7un8)$s~3_u4nXNQy$lSK7#J8N`XCxs_c1U;ftp%)82A}Ig&On~I~brTpE zJ}@#cT$})D*&Lb#$)}$tLAuo}lOaLtJDGvO4%E$_3@$<$E=-14^mZ~NaVkxL6lDHW z7#PAB7#Px~FfgPsFfi<$!oXn0z`&p~71AP#p31;b4;p4~oeF6IO`8gF$oi>}>~m=< zB-N`wCse^gD7}3F z1A`?41H;(`knF_15MqGnLP#ptUI_7t@j^(PJ3;xG3n3O%K-G0GggAKeLP+^Be<8Ro zsb^TT5E25X7D7_z?S%{s)}U#)MUceiw+NERvKB$&zI_qIfYpm27VlUD(SLjq#DW`( z7#La^7#N-`f|R6Liy`K9ErukzV~Zi`t}SL@I1ZZsdju6&wFF|&wk43bIu4~TEP({^ z%_WdT_h|{lVd6_61{p7fgoHhmc3%n!N&lsgw3NOSl8u{|LiA5r3NdfzQU(T4MaOUn zYS4$JkRbj8HHd2&q?#032GJk`rA?PX4D?$DY5629gXE4>sQRj93=A2d`MzZkhrC?| znQ~!W4sqzT<&dbEw;bC4-?$u-_>L`yINcR7RbD##USOE#Ly(=Itys-k3 z*j}%I#3kcOh`8cPaN=PwSqX7?&`L;Jh+GM=IAbNmrxhz9MRmhUhzHg|=^ZN}9y_$M z9^%5ADJLB;Dk>8&Cz$p$314Y7|%t zafsGhNR&9Pg@j1>S_Xz@1_p-GwGfZ|TnkAmdeih0;gYLtK7!JtR#$Uk^!)KcIZ> z4G?)5D6O{vVvfTGi26{dc-jU?fmX4Bfx!|~|4-cjaq)Smf@>Qf7QcWR@M8nS2fQ00 zAtSmG5;AfdAr8>k2rCy6C|-2ZGx!t-UO+B12#b{YTg8i`$?N1?STcGAdS;Q zn;;H-3zcWs3~?aeW`=t3q7$XfkPxun3~`y;W{5%2n;~f<6H1qEhFH|N84_g^HbX*Y z#b!u|Y=G+D1-0NjRQ+S9x=))S9{9Bx;xXYZ^$>&Pwm=Lp+XCS`Y=QVVVhh9}d0QY3 ztl0u_VDlD8kj~fwX<{wi0&&P6s6Ljh5c8zAf)W`6gUVJ&b?&kiVvg5VNLmT3hcc44 zLR?h36_QvQwn7{-aVsPQR&Iqv$yO-64{G4?t&pbJS*U)^ZIEnfvJGNU&^Czv$Ze49 zo4O4W^flWcQBpr)8^kAzp$ax^gE-*$Hb@BE*amUwJE%s6?GT5GY=`(*emkW6P~Q%5 zu=93^`snSDkjmW-F~14Q?}yS$wu7Uxo?+*9h=nJ%LwtA>YQZCj0*1Fx@ju%kE@s^U zY0pdSfcVUE2V~&E6-t*t0QwIzlXaZ7Jb7E0u^Wf zhfLoMseBed`FD3iJoIcg#6usT`v2{Qqy?5e3=H+4HCfVoAQr{!f%Nf8_dtBS8Y+Hx z52WdJ2TC*Sg*ZTEFQn^bwHM;!zP%6&XYYlik)?YfmCgpJ`cqK;gS`+3{MyS<4_=!k zxDVn&lYNjlb=n6BQonsrAMb<2UFtqa2$k-Glyo)wAQmjy2l2qZeUQ|DeILYvulpcf zI-dQIkx`5NkdV&V4=I?c_t!)E`^)x23^)U&pYDfDK>XVevDp3qBt-lVKrBo@05PcX z03`8EH~<-d*na@hFSvIA;y}5BkP_1EAVhuTL5Mva2O%C@Sbq@W<4p%4LAdWAB(0C?v=< zk3v$n6I8tZD8vU-jzaX!JqmH~@}rQnwEif>fqRca(!%AVkp9K1qmVSDcnn0>Gcafz zgZNPY7{p@hW00uufr>{SgZL!%7{s9RV~{xSI|k`3?>z=_;Dcij2mCw+aTw!qkOd43 zT*o1NK`1SC9O7W*;|vUZp!#3;I3!MNjzbIxfhvrFDoi~Nu{i%YByF@Ehxl+NlwN)u zlDfAZhs5#A;}8%1gqp*80^$L_6A+6PPC(4jI>EqD4_azzdjeuXC{#ht35d(fPC$Ar zwI?7^vFHROk!?Q#jyr}IQ1whFA!&l=B%~oCeiD-HOin`dC7gs7CH@yI?vOP z5DGgDu{h;4B#q^rhJ;M#X-FcSdKxWxIAs56NMgHo8WL2(XCNBY&Ok!M z=nTYR;b$O0AAbfC#FNiJ^e;UF(YNOe#N6{x@%v{W9{6?!k|x;e&q7+I0%svXWp@@5 z^ucE#K8ZRDu{ixKWCXJq%71qj;=^BOAr^6*gE&C?9K@%(=O7k)oP$^xaSozB6DnU0 zm9L+44&tLl=NK5=85kIjpMzM;e;yJtO5E>s>IE)Ad?IrR;xL0t5QkV@f|%ob2@>@2mmq^p z1((1+X1I6>5;FHMF)+x1^8dR_kf7wf3<)BQ%McgZUWOEvE|(#dQPyS1Q0wZ;kV@v) zWk^t4U4bOR>?@F>eEtQ3H-q>WoQAwK_j6XG!TTaXe`<`%>}vs(~(_gj!e8Vi*#t%nNq--0+~ z`7KBgZNCKxqD!|RCE=Z0kcI@?ZHNVyw;@sFcN-D~p|>GHodA`uyUoCG2(()MHpBs8 zcOd4a-+_3n@D3!Z>l^MsEN;648E&6;hk?PCfq~)C9f*YrcNrMAFfcF#-(_G3XJBC9 zxCa?bPPhk&hS>5PN;bRwzr;P z_5+B5)ej)c@s(NX18xq1-u- zAnG_CLqb68F~sNUk0I*K9)m)%o`J#nF{CjV@feZ|njb@k&!#_y1QEj%28IR(1_rh# z3=ICD<#taXY2o@4NMhu83ZVs_GBAXK<_n%OFa$C%FyuXDV2A*1Px1nLQ7B z1{u^2dj_5V?|ue}%Zbk*4w&%_;_@}mAhp`AXOOu2_zW`c|N9vvgsh%J%7fnLkfQqz zl&|sv;?Uw3kQtT3FQ5*5$-oc`a^Opd`DHH|80tYY8Z9p&F2Da0vH`*L6{Pl?^a^6o z`B#u(botki&Su?f2G9~dhFh;81(VGiP*5^3)V_fP@uWA90%+kIh{uk+f#jOgZy*l2 z@&@9eJ8u~3L7PArp1px2Hu1L%3@aHJ7`)y>G<z)%1hK6?vEJbCXR1}=IB$FFrcOWAU3G{-^K{ZS}IJC(#jjE0px?5P_{7> zBvJB!_E|76Ff0MN8nl;#iGg7QR1IiT$!P{iXA@-hDMkhcZ>YNaP#Uy48YBnWUvh|% zfua5w69dCDMo88HNnB=ttYT?rWMKHu#K15Es__RS1H*Dg28I<-{#ix_hGHfLhM7=) zDOg*|JUb&K2Zb^*)H7^lWMB|uVqn zFlaL}Ffc(4(_~~|$Y*3=Sk1t|pbT|b6%zx)bg29dMh1o{ObiU-j0_BRP_Z?jGy?VQ zbw&n;N+t$|I7SABS5SFIMh1pjMh1owQ2ak+VqmZXB|1h1hV@Jg4DT2i7}}tk*D^3L zm@_djTm`udlmMaPcR_tVCI$u;Mo1e$5~PNafkBUnfuV$nfgy~EfuWg^fgzKDfuW9x zf#C)N1A{LU0|OTmr0oDQZW$A3{uRUm&DSzOX1t7`7J!67bA!tm85j;TGB7AIGcf2g zF)+MjVqloe$iQ$Dv>=g@fk6lAqi{w@sTah^z);A9}@#Z3Y5Kyk%8d>l)Vv3!~M_7$iR@u#K2&}$iVQ4fq|i#0aEFhGBPkU zfPBfoz;JM>9eJc*HkffK|B#XndNBLhPRNC32jj)8&U7$cQ4)`Ch*P(p(0;b3H7xC*uS%H)TZ z!jnH(veeIJWMJrJVqhp{U|_IkVqjR!#K0g0)d8{vhS``H7#2gtk3$6&m?6{N`xzM+ zltFnDP-&ItHW;G;R8yX3# z8Z$C5v_NGRgK{S`WZPc?BLjmO69dCFP;vmN1O*5P*C&B08Ab*Mcc`x2p!^DocTiwK z&9-M`U}yw+nt_4AiHU*X9wP&T6x6NvnHU&;L)ATJVqoxsngbHL0V?$vAWbw-4JywJ zS+WP(2MF3txfxXSf)rk4Vqkc}$iVOoYA8qygguxTK*RJ5`A~5$CI*HMCPOlhp#6nR3=9fP^$ZMr zj0_Ar85kIJ7#SFrGBGfm18uEiU|{$FDylqmsK7vXuMh1qN z3=9mePz|8%bfE2&;!Kcs;YmgYhDQtx3=fzX7}P-#$;7~*%f!I&6r=}K5kW&JhY7M? zvZS zX@V(2Jq41IW@2Di1#%b@1H%_k{Lh9O0NOsw$i%?#7*xbU%m>3wAGeO3B z<)Py7OpqqpW>C$@$iOfM)T&{IG)T{YYy<6hWn^FgZ7zNc>IX0~fEOe|r63isC=&z2 zR3-)n15kwlN;C|Rmh5dt28J)7#s<`~Hqd$iW(Ed5sBacAGBE6BU|>iAB_yaAA2S2P zCq@Q_07eFeQ%npD>p3vNFflN!f$H&r%7ZlTV_;z526+RtLz@}WkphWBu@yr(BV>dOByfO{f#C%x z*MX7_X!}2?D*#HnP=l>NIS|w_Vq##hfK~IJ2cgypGD1d}%AkCZiR(e}&j=a*hyWG6 zphEzlrh$?HXj5=C69a=eBLjmgI6%4>7#O&i85k}zF)(}vc^tHIi;02Z5U4l6#K0f` z)qNe*uwZ0hcmhgwNH%@|mH5zr3Wusa11gfBYTkpEFN5033=9k_Ku%;}V8~!%VED_x zz;FVTH$f9CP;mx-r~wj83=B&_-3mqqhCQI_i;;ohG$W*Y3R7zVYKnr?Gcz#AK^*{+ zYXNzP5i(vng^_`whLM3`G04jd3=AKc7#Q3@iWnFe{6Km^c@xCH!UP!~0j*!-VPs$s zVq##>fcik3nStRksQ!cUL5Db0fC_O?PZAU}ObiUOm>3u&K_w9r1H(g*flv%O%t4+J zGP<-Kl=m4K7~G)dfRspp>PJ&128LIlpa<1~APjaH1H(R0mxY0W!34_R52X(>FfhCY z>4xIBPy;_OF))aNdJRxMRGQ&60|Uc0P|E<+cmfsLP;)dvElQB0ub_GlDp<&=W!%z7nKxmeibOr zwfR%@ZD#g>qWtut)Z)oU;!U}d^K%PwQcF@(tR{bq7Z+A2F3HTvQOL|wD1ay`*4xaO zFp)9Zt2DO&WO7MHszOqJNlAXLLVlV8h?kRDTmq6QPR&V8E&&UvYNRD*=A@>?C+C;u zm1q_#WR|4n7AurzWF}`QK%_uAGQlp>n>;b`i%F`2szzpBN@|5>v6X^NaY<2rUb>yC zMoDH#PO4_HjXqRFA*oV9RU@&qBqP5_b8|zIEDvW%Q6jsK~p=ZewP&ib~DQ0a-&#?3Cr_A)=>vv-tKNem>Wt zywuVXg|gJ5;?m@d%?pmjGO;`6\n" "Language-Team: German\n" "Language: de\n" @@ -72,15 +72,16 @@ msgstr "Aufsteigend" msgid "Descending" msgstr "Absteigend" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "Fehler beim Laden des Buches" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "Keine Übereinstimmung für das Buch gefunden" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "Ausstehend" @@ -100,23 +101,23 @@ msgstr "Moderator*in löschen" msgid "Domain block" msgstr "Domainsperrung" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "Hörbuch" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "E-Book" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "Graphic Novel" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "Hardcover" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "Taschenbuch" @@ -133,21 +134,21 @@ msgstr "Föderiert" msgid "Blocked" msgstr "Blockiert" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s ist keine gültige remote_id" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s ist kein gültiger Benutzer*inname" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "Benutzer*inname" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "Dieser Benutzer*inname ist bereits vergeben." @@ -892,22 +893,37 @@ msgstr "Bookwyrm-Benutzer*innen" msgid "All known users" msgstr "Alle bekannten Benutzer*innen" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 #, python-format msgid "%(username)s rated %(book_title)s" msgstr "%(username)s hat %(book_title)s bewertet" -#: bookwyrm/templates/discover/card-header.html:13 +#: bookwyrm/templates/discover/card-header.html:27 #, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "%(username)s hat %(book_title)s besprochen" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "%(username)s hat %(book_title)s kommentiert" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "%(username)s hat %(book_title)s zitiert" @@ -1058,9 +1074,8 @@ msgstr "Du kannst dein Leseziel jederzeit auf deiner Profil msgid "Updates" msgstr "Updates" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "Deine Bücher" #: bookwyrm/templates/feed/layout.html:14 @@ -1069,11 +1084,13 @@ msgstr "Hier sind noch keine Bücher! Versuche, nach Büchern zu suchen, um losz #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "Zu lesen" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "Lese ich gerade" @@ -1081,6 +1098,7 @@ msgstr "Lese ich gerade" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "Gelesen" @@ -1366,88 +1384,161 @@ msgid "No recent imports" msgstr "Keine aktuellen Importe" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "Importstatus" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" -msgstr "Zurück zu den Importen" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "Import gestartet:" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "Import abgeschlossen:" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "IMPORTSCHRITT-FEHLER" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "Import läuft noch." - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(Zur Aktualisierung „Neu laden” wählen)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "Laden fehlgeschlagen" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "Zum Ende der Liste springen, um die %(failed_count)s Einträge, die nicht importiert werden konnten, auszuwählen." +msgid "Refresh" +msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "Zeile %(index)s: %(title)s von %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "Alle(s) auswählen" +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "Erneut versuchen" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "Erfolgreich importiert" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "Import-Fortschritt" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "Buch" - -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titel" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor*in" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "Besprechen" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Buch" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Status" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "Importiert" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Bestätigen" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Du kannst deine Goodreads-Daten von der Import/Export-Seite deines Goodreads-Kontos downloaden." +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1579,10 +1670,6 @@ msgstr "Navigations-Hauptmenü" msgid "Feed" msgstr "Feed" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "Deine Bücher" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "Einstellungen" @@ -1682,10 +1769,6 @@ msgstr "Du bist soweit!" msgid "Suggested by" msgstr "Vorgeschlagen von" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "Bestätigen" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "Ablehnen" @@ -2238,15 +2321,6 @@ msgstr "Startdatum" msgid "End date" msgstr "Enddatum" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "Status" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "aktiv" @@ -3095,10 +3169,6 @@ msgstr "Teilen" msgid "Un-boost" msgstr "Teilen zurücknehmen" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "Besprechen" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "Zitieren" @@ -3525,7 +3595,7 @@ msgstr "%(date)s bearbeitet" msgid "commented on %(book)s" msgstr "hat %(book)s kommentiert" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "hat auf die Statusmeldung von %(username)s geantwortet" @@ -3604,7 +3674,11 @@ msgstr "Mehr anzeigen" msgid "Show less" msgstr "Weniger anzeigen" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Deine Bücher" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "Bücher von %(username)s" @@ -3748,7 +3822,7 @@ msgstr "Datei überschreitet die maximale Größe von 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s: %(subtitle)s" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "Keine gültige CSV-Datei" diff --git a/locale/es_ES/LC_MESSAGES/django.mo b/locale/es_ES/LC_MESSAGES/django.mo index c844411e582bf1629c5192f308b505dea717d723..9614a669c3aa133bb13af01293952c2b0790dfc1 100644 GIT binary patch delta 17240 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 S>Zsu6=;L#E^5&Q4nxp|d?Ow|O diff --git a/locale/es_ES/LC_MESSAGES/django.po b/locale/es_ES/LC_MESSAGES/django.po index d776e11dd..b5fc1ce34 100644 --- a/locale/es_ES/LC_MESSAGES/django.po +++ b/locale/es_ES/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-24 14:09+0000\n" -"PO-Revision-Date: 2021-10-26 20:55\n" +"POT-Creation-Date: 2021-11-14 15:08+0000\n" +"PO-Revision-Date: 2021-11-15 18:03\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Spanish\n" "Language: es\n" @@ -72,15 +72,16 @@ msgstr "Ascendente" msgid "Descending" msgstr "Descendente" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "Error en cargar libro" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "No se pudo encontrar el libro" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "Pendiente" @@ -100,23 +101,23 @@ msgstr "Eliminación de moderador" msgid "Domain block" msgstr "Bloqueo de dominio" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "Audio libro" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "Libro electrónico" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "Novela gráfica" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "Tapa dura" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "Tapa blanda" @@ -133,21 +134,21 @@ msgstr "Federalizado" msgid "Blocked" msgstr "Bloqueado" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s no es un remote_id válido" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s no es un usuario válido" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "nombre de usuario" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "Ya existe un usuario con ese nombre." @@ -892,22 +893,37 @@ msgstr "Usuarios de BookWyrm" msgid "All known users" msgstr "Todos los usuarios conocidos" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 #, python-format msgid "%(username)s rated %(book_title)s" msgstr "%(username)s calificó %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:13 +#: bookwyrm/templates/discover/card-header.html:27 #, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "%(username)s reseñó %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "%(username)s comentó en %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "%(username)s citó %(book_title)s" @@ -1058,9 +1074,8 @@ msgstr "Puedes establecer o cambiar tu objetivo de lectura en cualquier momento msgid "Updates" msgstr "Actualizaciones" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "Tus libros" #: bookwyrm/templates/feed/layout.html:14 @@ -1069,11 +1084,13 @@ msgstr "¡No hay ningún libro aquí ahorita! Busca a un libro para empezar" #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "Para leer" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "Leyendo actualmente" @@ -1081,6 +1098,7 @@ msgstr "Leyendo actualmente" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "Leído" @@ -1366,88 +1384,161 @@ msgid "No recent imports" msgstr "No hay ninguna importación reciente" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "Importar estado" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" -msgstr "Volver a las importaciones" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "Importación ha empezado:" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "Importación ha terminado:" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "TAREA FALLÓ" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "Importación todavia en progreso." - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(¡Refresca para actualizar!)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "No se pudo cargar" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "Saltar al final de la lista para seleccionar los %(failed_count)s artículos que no se pudieron importar." +msgid "Refresh" +msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "Renglón %(index)s: %(title)s por %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "Seleccionar todo" +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "Reintentar ítems" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "Importado exitosamente" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "Progreso de importación" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "Libro" - -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor/Autora" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "Reseña" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Libro" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Estado" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "Importado" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Aprobar" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Puede descargar sus datos de Goodreads desde la página de Importación/Exportación de su cuenta de Goodreads." +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1579,10 +1670,6 @@ msgstr "Menú de navigación central" msgid "Feed" msgstr "Actividad" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "Tus libros" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "Configuración" @@ -1682,10 +1769,6 @@ msgstr "¡Está todo listo!" msgid "Suggested by" msgstr "Sugerido por" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "Aprobar" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "Desechar" @@ -2238,15 +2321,6 @@ msgstr "Fecha de inicio" msgid "End date" msgstr "Fecha final" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "Estado" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "activo" @@ -3095,10 +3169,6 @@ msgstr "Impulsar" msgid "Un-boost" msgstr "Des-impulsar" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "Reseña" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "Cita" @@ -3525,7 +3595,7 @@ msgstr "editado %(date)s" msgid "commented on %(book)s" msgstr "comentó en \"%(book)s\"" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "respondió al estado de %(username)s" @@ -3604,7 +3674,11 @@ msgstr "Mostrar más" msgid "Show less" msgstr "Mostrar menos" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Tus libros" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "Los libros de %(username)s" @@ -3748,7 +3822,7 @@ msgstr "Archivo excede el tamaño máximo: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s: %(subtitle)s" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "No un archivo csv válido" diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo index 0bc2fb3dad8abed5091b5b7d7746a492e681d9cc..1e81ac6e6aa1e751a387956c9466e48433254d03 100644 GIT binary patch delta 16872 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 S;g!i5`K5\n" "Language-Team: French\n" "Language: fr\n" @@ -72,15 +72,16 @@ msgstr "Ordre croissant" msgid "Descending" msgstr "Ordre décroissant" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "Erreur lors du chargement du livre" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "Impossible de trouver une correspondance pour le livre" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "En attente" @@ -100,23 +101,23 @@ msgstr "Suppression du modérateur" msgid "Domain block" msgstr "Bloc de domaine" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "Livre audio" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "eBook" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "Roman Graphique" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "Couverture rigide" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "Couverture souple" @@ -133,21 +134,21 @@ msgstr "Fédéré" msgid "Blocked" msgstr "Bloqué" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s n’est pas une remote_id valide." -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s n’est pas un nom de compte valide." -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "nom du compte :" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "Ce nom est déjà associé à un compte." @@ -892,22 +893,37 @@ msgstr "Comptes BookWyrm" msgid "All known users" msgstr "Tous les comptes connus" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "%(username)s veut lire %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "%(username)s a terminé %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "%(username)s a commencé %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:23 #, python-format msgid "%(username)s rated %(book_title)s" msgstr "%(username)s a noté %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:13 +#: bookwyrm/templates/discover/card-header.html:27 #, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "%(username)s a critiqué %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "%(username)s a commenté %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "%(username)s a cité un passage de %(book_title)s" @@ -1058,10 +1074,9 @@ msgstr "Vous pouvez définir ou changer votre défi lecture à n’importe quel msgid "Updates" msgstr "Mises à jour" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" -msgstr "Vos livres" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" +msgstr "Vos Livres" #: bookwyrm/templates/feed/layout.html:14 msgid "There are no books here right now! Try searching for a book to get started" @@ -1069,11 +1084,13 @@ msgstr "Aucun livre ici pour l’instant ! Cherchez un livre pour commencer" #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "À lire" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "Lectures en cours" @@ -1081,6 +1098,7 @@ msgstr "Lectures en cours" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "Lu" @@ -1366,88 +1384,161 @@ msgid "No recent imports" msgstr "Aucune importation récente" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "Statut de l’importation" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" -msgstr "Retourner à l’importation" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "Début de l’importation :" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "Fin de l’importation :" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "la tâche a échoué" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "L’importation est toujours en cours" - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(Rechargez la page pour la mettre à jour !)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "Éléments non importés" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "Sauter en bas de liste pour sélectionner les %(failed_count)s items n’ayant pu être importés." +msgid "Refresh" +msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "Ligne %(index)s : %(title)s de %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "Tout sélectionner" +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "Réessayer l’importation de ces éléments" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "Importation réussie" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "Importation en cours" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "Livre" - -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titre" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Auteur/autrice" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "Critique" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Livre" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Statut" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "Importé" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Approuver" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Vous pouvez télécharger vos données GoodReads depuis la page Import/Export de votre compte GoodReads." +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1579,10 +1670,6 @@ msgstr "Menu de navigation principal " msgid "Feed" msgstr "Fil d’actualité" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "Vos Livres" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "Paramètres" @@ -1682,10 +1769,6 @@ msgstr "Aucun livre en attente de validation !" msgid "Suggested by" msgstr "Suggéré par" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "Approuver" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "Rejeter" @@ -2238,15 +2321,6 @@ msgstr "Date de début" msgid "End date" msgstr "Date de fin" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "Statut" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "active" @@ -3095,10 +3169,6 @@ msgstr "Partager" msgid "Un-boost" msgstr "Annuler le partage" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "Critique" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "Citation" @@ -3525,7 +3595,7 @@ msgstr "modifié le %(date)s" msgid "commented on %(book)s" msgstr "a commenté %(book)s" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "a répondu au statut de %(username)s" @@ -3604,7 +3674,11 @@ msgstr "Déplier" msgid "Show less" msgstr "Replier" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Vos livres" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "Livres de %(username)s" @@ -3748,7 +3822,7 @@ msgstr "Ce fichier dépasse la taille limite : 10 Mo" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s (%(subtitle)s)" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "Fichier CSV non valide" diff --git a/locale/lt_LT/LC_MESSAGES/django.mo b/locale/lt_LT/LC_MESSAGES/django.mo index 9d11576fd32656bb9d97df42d532f370e888691f..ea2d76b14c61ccef786c478e234431b32a354d4c 100644 GIT binary patch delta 4425 zcmbPwmwE18<_$cG^#TkG4BZZ(?AO06An6#D|YJL45dc69a=70|NucW(Eds z1_lQC%@BubZ)RW+WME+M+6>Vjvl$YS`I{LSKq1?{8RGC6n;{OIzZnuDn>RBsm@qIf zoT%RnapB+1kRW2+0`Zyj76t|-1_lPxEfD#LEf9kewm?E4eG9~b@+}Ytb!>q+WXcvu z6fT2`AK3!&-~}jsa| z7#J7|wn8kJxE11)#Zd9>Q1KgEAtCn)s*iaa#9Y2@kdTwu#=xMH3=A3!3=H@7 zKthOpFC-+C_Cm}t-3v+7o_iS>^cWZzBA|5p-g=0^+x9Xrm@zOg9D{23yB88fg8LvA zDeq%ouwr0fu-FGNxOgAL!EI3a#rq)U?AQlM4OlTUpokK(C32?iy03=$_cJR3=HxN3=Gohae$4^AOnK^$e>IL0q&6s_@1kNE-NX2;v}_!w`$r4nu<8@GvCkTnc%~1XO4nrJr@h~VV>KPcGLJbr?0`ZCT5s1YqM;I8S85kJ! zjzApXbp&E@=n;qou}2^VWgcN*P-b9Ys67Hn-3yOEe7Fm$@5~XfPZ_R5_1}Z)e+H5V z<^NAdAaVcq2qar@9fbs?;!%jW(@{ti_#cHBoNyH4)1sr0)ZPGB>fm9Y6_1*(!ktfpde&m z*ag-9;us`k{v3lioZ~p8mJ~e>QD<@-;(?^&kPt07&QK4oG>Hk9vh zsvaWXeG1~!gj0}2mU#-2pKDG*3YH$I_|{X9kU9YszXMgrdK%(G(bEtgI-iD^6AGm> zPD7%q`ZPrUw9^oWt*So_iR-PWA#r@|G$fHdKMirf`_qu1|9_f+A(?@Jf%6Q+g4{C@ z1M1H}4D5o^^Ugp*Zqpe^t~d#$Z$RniXCU@{I|DJlUi>U1&ehLC+GGxAA#s;+7GiKI zRK63+Uvw4{V%yF_e0cgSB){J~3kj)zXCdW@`Z&Q28QeBA&KSwc}PBed!B(olYxQZ%XvsHkh=hJx!DDX141r992R>4 z5(T*zAU>_Q0EwzjsQBay3=A<03=H$2^1m-Y9KdrCVxHnf1_mim{7a_IP){BtJ=gCD#NhyB`k{etvF)(;CFfgQFf<(c_OOPnLcnK0>PcK1&`uimY zhF}H;2C>VKGC%7w#J+~h3=H+$3=9nYmmzUJ`!XbZt+)*F>6Xh71NUBr2H9nZkFP@w zcyt*Oav!1M|DpQ1u0TRW>gCwdO*C2`L!8J%o@Lq?g6T1%ak;Zk1Pn@np92|8W z5(W9!A=$70IwZd@yAG*C4qk^iBtPokfLI)G1Ck3OZZI(DgX-@a z5R2E}fCS;e8<3DX4b^w+1|$l8-(X;91Cp9R`Lv1_p*TcOVYez6(jb(RU#Z=(-Duf<<>B@|*55Fr+as)H6J~%fR5v zz`)>n4-&M~??E(fya#dVgL@DkzK8Pv-h;#;&wU1lVg?2V+4~F(QJ}uveTcd@_aPSj zx({&}*8_+-@(&=D`5d%XgsCWDblHWZaL$d3##|#XN3=9kpA47cn_%TGE z@DoVllm*eC{BQ6CVzBcQNT<*XBms*1ClHO3oAM^ssaFgP1`G@g9uG~Rv9z!1&A!0`Mv#OKa$AR3F`K;p3G z4Fkh_(0~P0y!tJ~K`n0?7#bNE7Fm;>!g9V8A8y delta 4417 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 R@ki~9OeL9{1D^PD0RYJTAmac4 diff --git a/locale/lt_LT/LC_MESSAGES/django.po b/locale/lt_LT/LC_MESSAGES/django.po index e17f1a056..82d7cbbe2 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-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-15 18:03\n" +"PO-Revision-Date: 2021-11-15 19:25\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Lithuanian\n" "Language: lt\n" @@ -172,7 +172,7 @@ msgstr "Knygos" #: bookwyrm/settings.py:165 msgid "English" -msgstr "Anglų" +msgstr "English (Anglų)" #: bookwyrm/settings.py:166 msgid "Deutsch (German)" @@ -3647,7 +3647,7 @@ msgstr "įvertinta %(book)s:" #: bookwyrm/templates/snippets/status/headers/read.html:7 #, python-format msgid "finished reading %(book)s" -msgstr "baigti skaityti %(book)s" +msgstr "baigė skaityti %(book)s" #: bookwyrm/templates/snippets/status/headers/reading.html:7 #, python-format @@ -3681,7 +3681,7 @@ msgstr "Mėgti būseną" #: bookwyrm/templates/snippets/status/status.html:10 msgid "boosted" -msgstr "pagreitinta" +msgstr "iškėlė" #: bookwyrm/templates/snippets/status/status_options.html:7 #: bookwyrm/templates/snippets/user_options.html:7 diff --git a/locale/pt_BR/LC_MESSAGES/django.mo b/locale/pt_BR/LC_MESSAGES/django.mo index 1ebe5280048618f0a5075466d95c52dd815070ec..dd430b3ae3e17cf023d1419fd26eefc3f9d498bd 100644 GIT binary patch delta 23083 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 VN>rj?IJ_&TBr`X0^OvjjYyf=@Yuo?; delta 18160 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 NNoHC8<|%L5*#IE;ABX?| diff --git a/locale/pt_BR/LC_MESSAGES/django.po b/locale/pt_BR/LC_MESSAGES/django.po index 2e729a2f2..a7ea1a86a 100644 --- a/locale/pt_BR/LC_MESSAGES/django.po +++ b/locale/pt_BR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-15 22:03+0000\n" -"PO-Revision-Date: 2021-10-22 13:31\n" +"POT-Creation-Date: 2021-11-14 15:08+0000\n" +"PO-Revision-Date: 2021-11-16 00:36\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt\n" @@ -46,41 +46,42 @@ msgstr "{i} usos" msgid "Unlimited" msgstr "Ilimitado" -#: bookwyrm/forms.py:326 +#: bookwyrm/forms.py:332 msgid "List Order" msgstr "Ordem de inserção" -#: bookwyrm/forms.py:327 +#: bookwyrm/forms.py:333 msgid "Book Title" msgstr "Título do livro" -#: bookwyrm/forms.py:328 bookwyrm/templates/shelf/shelf.html:136 -#: bookwyrm/templates/shelf/shelf.html:168 +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Avaliação" -#: bookwyrm/forms.py:330 bookwyrm/templates/lists/list.html:109 +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Organizar por" -#: bookwyrm/forms.py:334 +#: bookwyrm/forms.py:340 msgid "Ascending" msgstr "Crescente" -#: bookwyrm/forms.py:335 +#: bookwyrm/forms.py:341 msgid "Descending" msgstr "Decrescente" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "Erro ao carregar livro" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "Não foi possível encontrar o livro" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "Pendente" @@ -100,23 +101,23 @@ msgstr "Exclusão de moderador" msgid "Domain block" msgstr "Bloqueio de domínio" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "Audiolivro" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "e-book" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "Graphic novel" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "Capa dura" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "Capa mole" @@ -133,21 +134,21 @@ msgstr "Federado" msgid "Blocked" msgstr "Bloqueado" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s não é um remote_id válido" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s não é um nome de usuário válido" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "nome de usuário" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "Já existe um usuário com este nome." @@ -165,7 +166,7 @@ msgstr "Linha do tempo dos livros" #: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 #: bookwyrm/templates/search/layout.html:42 -#: bookwyrm/templates/user/layout.html:81 +#: bookwyrm/templates/user/layout.html:88 msgid "Books" msgstr "Livros" @@ -223,7 +224,7 @@ msgid "Edit Author" msgstr "Editar autor" #: bookwyrm/templates/author/author.html:34 -#: bookwyrm/templates/author/edit_author.html:41 +#: bookwyrm/templates/author/edit_author.html:43 msgid "Aliases:" msgstr "Pseudônimos:" @@ -276,71 +277,72 @@ msgstr "Adicionado:" msgid "Updated:" msgstr "Atualizado:" -#: bookwyrm/templates/author/edit_author.html:15 +#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/book/edit/edit_book.html:25 msgid "Last edited by:" msgstr "Editado pela última vez por:" -#: bookwyrm/templates/author/edit_author.html:31 +#: bookwyrm/templates/author/edit_author.html:33 #: bookwyrm/templates/book/edit/edit_book_form.html:15 msgid "Metadata" msgstr "Metadados" -#: bookwyrm/templates/author/edit_author.html:33 -#: bookwyrm/templates/lists/form.html:8 bookwyrm/templates/shelf/form.html:9 +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 msgid "Name:" msgstr "Nome:" -#: bookwyrm/templates/author/edit_author.html:43 +#: bookwyrm/templates/author/edit_author.html:45 #: bookwyrm/templates/book/edit/edit_book_form.html:65 #: bookwyrm/templates/book/edit/edit_book_form.html:79 #: bookwyrm/templates/book/edit/edit_book_form.html:124 msgid "Separate multiple values with commas." msgstr "Separe com vírgulas." -#: bookwyrm/templates/author/edit_author.html:50 +#: bookwyrm/templates/author/edit_author.html:52 msgid "Bio:" msgstr "Sobre mim:" -#: bookwyrm/templates/author/edit_author.html:57 +#: bookwyrm/templates/author/edit_author.html:59 msgid "Wikipedia link:" msgstr "Link da Wikipédia:" -#: bookwyrm/templates/author/edit_author.html:63 +#: bookwyrm/templates/author/edit_author.html:65 msgid "Birth date:" msgstr "Data de nascimento:" -#: bookwyrm/templates/author/edit_author.html:71 +#: bookwyrm/templates/author/edit_author.html:73 msgid "Death date:" msgstr "Data da morte:" -#: bookwyrm/templates/author/edit_author.html:79 +#: bookwyrm/templates/author/edit_author.html:81 msgid "Author Identifiers" msgstr "Identificadores do autor" -#: bookwyrm/templates/author/edit_author.html:81 +#: bookwyrm/templates/author/edit_author.html:83 msgid "Openlibrary key:" msgstr "Chave Openlibrary:" -#: bookwyrm/templates/author/edit_author.html:89 +#: bookwyrm/templates/author/edit_author.html:91 #: bookwyrm/templates/book/edit/edit_book_form.html:224 msgid "Inventaire ID:" msgstr "ID Inventaire:" -#: bookwyrm/templates/author/edit_author.html:97 +#: bookwyrm/templates/author/edit_author.html:99 msgid "Librarything key:" msgstr "Chave Librarything:" -#: bookwyrm/templates/author/edit_author.html:105 +#: bookwyrm/templates/author/edit_author.html:107 msgid "Goodreads key:" msgstr "Chave Goodreads:" -#: bookwyrm/templates/author/edit_author.html:116 +#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:44 +#: bookwyrm/templates/lists/form.html:75 #: bookwyrm/templates/preferences/edit_user.html:124 #: bookwyrm/templates/settings/announcements/announcement_form.html:69 #: bookwyrm/templates/settings/federation/edit_instance.html:74 @@ -352,11 +354,13 @@ msgstr "Chave Goodreads:" msgid "Save" msgstr "Salvar" -#: bookwyrm/templates/author/edit_author.html:117 +#: 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:111 +#: bookwyrm/templates/book/edit/edit_book.html:112 +#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/settings/federation/instance.html:88 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -397,7 +401,7 @@ msgstr "Adicionar descrição" #: bookwyrm/templates/book/book.html:136 #: bookwyrm/templates/book/edit/edit_book_form.html:34 -#: bookwyrm/templates/lists/form.html:12 bookwyrm/templates/shelf/form.html:17 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 msgid "Description:" msgstr "Descrição:" @@ -430,7 +434,7 @@ msgstr "Criar" #: bookwyrm/templates/book/book.html:197 msgid "You don't have any reading activity for this book." -msgstr "Você não tem nenhuma atividade de leitura para este livro." +msgstr "Você ainda não registrou seu progresso para este livro." #: bookwyrm/templates/book/book.html:218 msgid "Reviews" @@ -460,7 +464,7 @@ msgstr "Lugares" #: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 #: bookwyrm/templates/search/layout.html:25 #: bookwyrm/templates/search/layout.html:50 -#: bookwyrm/templates/user/layout.html:75 +#: bookwyrm/templates/user/layout.html:82 msgid "Lists" msgstr "Listas" @@ -470,7 +474,7 @@ msgstr "Adicionar à lista" #: bookwyrm/templates/book/book.html:315 #: bookwyrm/templates/book/cover_modal.html:31 -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 #: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 #: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 msgid "Add" @@ -543,7 +547,9 @@ msgid "This is a new work" msgstr "É uma nova obra" #: bookwyrm/templates/book/edit/edit_book.html:97 -#: bookwyrm/templates/password_reset.html:30 +#: 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 "Confirmar" @@ -612,7 +618,7 @@ msgid "John Doe, Jane Smith" msgstr "Fulano da Silva, Sicrano de Oliveira" #: bookwyrm/templates/book/edit/edit_book_form.html:132 -#: bookwyrm/templates/shelf/shelf.html:127 +#: bookwyrm/templates/shelf/shelf.html:140 msgid "Cover" msgstr "Capa" @@ -686,7 +692,7 @@ msgstr "%(pages)s páginas" #: bookwyrm/templates/book/publisher_info.html:38 #, python-format msgid "%(languages)s language" -msgstr "%(languages)s idioma" +msgstr "Língua: %(languages)s" #: bookwyrm/templates/book/publisher_info.html:65 #, python-format @@ -793,7 +799,7 @@ msgstr "Reenviar link de confirmação" #: bookwyrm/templates/confirm_email/resend_form.html:11 #: bookwyrm/templates/landing/layout.html:67 -#: bookwyrm/templates/password_reset_request.html:18 +#: bookwyrm/templates/landing/password_reset_request.html:18 #: bookwyrm/templates/preferences/edit_user.html:56 #: bookwyrm/templates/snippets/register_form.html:13 msgid "Email address:" @@ -828,7 +834,7 @@ msgstr "Listar seu perfil no diretório para que outros usuários da BookWyrm te #: bookwyrm/templates/directory/directory.html:24 #, python-format msgid "You can opt-out at any time in your profile settings." -msgstr "Você pode cancelar isto a qualquer momento em suas configurações de perfil." +msgstr "Você pode desabilitar esta opção a qualquer momento em suas configurações de perfil." #: bookwyrm/templates/directory/directory.html:29 #: bookwyrm/templates/feed/goal_card.html:17 @@ -887,22 +893,37 @@ msgstr "Usuários da BookWyrm" msgid "All known users" msgstr "Todos os usuários conhecidos" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "%(username)s quer ler %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "%(username)s terminou de ler %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "%(username)s começou a ler %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:23 #, python-format msgid "%(username)s rated %(book_title)s" msgstr "%(username)s avaliou %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:13 +#: bookwyrm/templates/discover/card-header.html:27 #, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "%(username)s resenhou %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" -msgstr "%(username)s comentou sobre %(book_title)s" +msgstr "%(username)s comentou %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "%(username)s citou %(book_title)s" @@ -993,10 +1014,10 @@ msgid "You requested to reset your %(site_name)s password. Click the link below msgstr "Você solicitou a redefinição de sua senha no %(site_name)s. Clique no link abaixo para definir uma nova senha e entrar no site." #: bookwyrm/templates/email/password_reset/html_content.html:9 -#: bookwyrm/templates/password_reset.html:4 -#: bookwyrm/templates/password_reset.html:10 -#: bookwyrm/templates/password_reset_request.html:4 -#: bookwyrm/templates/password_reset_request.html:10 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 msgid "Reset Password" msgstr "Redefinir senha" @@ -1042,7 +1063,7 @@ msgstr "Não há nenhuma atividade! Tente seguir um usuário para começar" #: bookwyrm/templates/user/goal_form.html:6 #, python-format msgid "%(year)s Reading Goal" -msgstr "Meta de leitura de %(year)s" +msgstr "Meta de leitura para %(year)s" #: bookwyrm/templates/feed/goal_card.html:18 #, python-format @@ -1053,9 +1074,8 @@ msgstr "Você pode definir ou alterar sua meta de leitura a qualquer momento em msgid "Updates" msgstr "Atualizações" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "Seus livros" #: bookwyrm/templates/feed/layout.html:14 @@ -1064,11 +1084,13 @@ msgstr "Não há nenhum livro aqui! Tente pesquisar livros para começar" #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "Quero ler" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "Lendo atualmente" @@ -1076,6 +1098,7 @@ msgstr "Lendo atualmente" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "Lido" @@ -1102,7 +1125,7 @@ msgid "What are you reading?" msgstr "O que você está lendo?" #: bookwyrm/templates/get_started/books.html:9 -#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:137 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 msgid "Search for a book" msgstr "Pesquisar livro" @@ -1120,8 +1143,9 @@ msgstr "Você pode adicionar livros quando começar a usar o %(site_name)s." #: bookwyrm/templates/get_started/books.html:17 #: bookwyrm/templates/get_started/users.html:18 #: bookwyrm/templates/get_started/users.html:19 -#: bookwyrm/templates/layout.html:51 bookwyrm/templates/layout.html:52 -#: bookwyrm/templates/lists/list.html:141 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 #: bookwyrm/templates/search/layout.html:4 #: bookwyrm/templates/search/layout.html:9 msgid "Search" @@ -1137,7 +1161,7 @@ msgid "Popular on %(site_name)s" msgstr "Popular em %(site_name)s" #: bookwyrm/templates/get_started/books.html:58 -#: bookwyrm/templates/lists/list.html:154 +#: bookwyrm/templates/lists/list.html:155 msgid "No books found" msgstr "Nenhum livro encontrado" @@ -1212,7 +1236,7 @@ msgstr "Mostrar conta nas sugestões de usuários:" #: bookwyrm/templates/get_started/profile.html:52 msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." -msgstr "Sua conta aparecerá no diretório e pode ser recomendada para outros usuários da BookWyrm." +msgstr "Sua conta aparecerá no diretório e poderá ser recomendada para outros usuários da BookWyrm." #: bookwyrm/templates/get_started/users.html:11 msgid "Search for a user" @@ -1223,9 +1247,110 @@ msgstr "Procurar usuário" msgid "No users found for \"%(query)s\"" msgstr "Nenhum usuário encontrado para \"%(query)s\"" +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Criar grupo" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Gerenciado por %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "Deletar grupo?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Esta ação não pode ser desfeita" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Excluir" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Editar grupo" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "Adicione novos membros!" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Nome do grupo:" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Descrição do grupo:" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Excluir grupo" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Pesquisar usuário para adicionar" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Este grupo não tem listas" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Editar grupo" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Membros podem adicionar ou remover livros nas listas de seu grupo" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Sair do grupo" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Segue você" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s seguidor que você segue" +msgstr[1] "%(mutuals)s seguidores que você segue" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s livro em sua estante" +msgstr[1] "%(shared_books)s livros em suas estantes" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "Nenhum membro em potencial encontrado para \"%(user_query)s\"" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Gerente" + #: bookwyrm/templates/import/import.html:5 #: bookwyrm/templates/import/import.html:9 -#: bookwyrm/templates/shelf/shelf.html:57 +#: bookwyrm/templates/shelf/shelf.html:61 msgid "Import Books" msgstr "Importar livros" @@ -1259,100 +1384,160 @@ msgid "No recent imports" msgstr "Nenhuma importação recente" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "Status da importação" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" -msgstr "Voltar às importações" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "Status da nova tentativa" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "Importações" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "Importação iniciada:" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "Importação concluída:" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "FALHA NA EXECUÇÃO" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "Importação em andamento." - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(Recarregue para atualizar!)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "Falha ao carregar" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "Em curso" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "Vá ao fim da lista para selecionar os %(failed_count)s itens que não foram importados." +msgid "Refresh" +msgstr "Atualizar" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "Linha %(index)s: %(title)s de %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "%(display_counter)s item precisa de aprovação manual." +msgstr[1] "%(display_counter)s itens precisam de aprovação manual." -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "Selecionar todos" +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "Revisar itens" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "Tentar novamente" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "Falha ao importar %(display_counter)s item." +msgstr[1] "Falha ao importar %(display_counter)s itens." -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "Importado com sucesso" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "Ver e solucionar importações fracassadas" -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "Progresso da importação" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "Linha" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "Livro" - -#: bookwyrm/templates/import/import_status.html:122 -#: bookwyrm/templates/shelf/shelf.html:128 -#: bookwyrm/templates/shelf/shelf.html:150 +#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" -#: bookwyrm/templates/import/import_status.html:125 -#: bookwyrm/templates/shelf/shelf.html:129 -#: bookwyrm/templates/shelf/shelf.html:153 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "ISBN" + +#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "Estante" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "Resenhar" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Livro" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Publicação" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "Visualizar resenha importada" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "Importado" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "Precisa de resenha manual" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +msgstr "Solução de problemas de importação" + +#: 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 "Aprovar uma sugestão adicionará permanentemente o livro sugerido às suas estantes e associará suas datas de leitura, resenhas e avaliações aos do livro." + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Aprovar" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "Rejeitar" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "Você pode baixar seus dados do Goodreads na página de Importar/Exportar da sua conta." -#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:8 -#: bookwyrm/templates/login.html:49 -msgid "Create an Account" -msgstr "Criar conta" +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "Itens cuja importação falhou" -#: bookwyrm/templates/invite.html:21 -msgid "Permission Denied" -msgstr "Permissão negada" +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "Solução de problemas" -#: bookwyrm/templates/invite.html:22 -msgid "Sorry! This invite code is no longer valid." -msgstr "Desculpe! Este convite não é mais válido." +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "Tentar uma importação novamente pode corrigir itens faltantes como:" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "O livro foi adicionado à sua instância desde esta importação" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "Um erro temporário ou timeout fez com que a fonte de dados externa ficasse inacessível." + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "Desde a importação a BookWyrm foi atualizada com uma correção de bugs" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "Fale com a administração ou crie um problema se você perceber itens com erros inesperados." #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format @@ -1369,6 +1554,20 @@ msgstr "Código de conduta" msgid "Privacy Policy" msgstr "Política de privacidade" +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Criar conta" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Permissão negada" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "Desculpe! Este convite não é mais válido." + #: bookwyrm/templates/landing/landing.html:6 msgid "Recent Books" msgstr "Livros recentes" @@ -1407,6 +1606,53 @@ msgstr "Obrigado! Sua solicitação foi recebida." msgid "Your Account" msgstr "Sua conta" +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Entrar" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Entrar" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "Endereço de e-mail confirmado com sucesso." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Usuário:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Senha:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "Esqueceu sua senha?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "Mais sobre este site" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Confirmar senha:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Um link para redefinir sua senha será enviada para seu e-mail" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Redefinir senha" + #: bookwyrm/templates/layout.html:13 #, python-format msgid "%(site_name)s search" @@ -1424,10 +1670,6 @@ msgstr "Menu de navegação principal" msgid "Feed" msgstr "Novidades" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "Seus livros" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "Configurações" @@ -1454,25 +1696,10 @@ msgstr "Sair" msgid "Notifications" msgstr "Notificações" -#: bookwyrm/templates/layout.html:170 bookwyrm/templates/layout.html:174 -#: bookwyrm/templates/login.html:21 -#: bookwyrm/templates/snippets/register_form.html:4 -msgid "Username:" -msgstr "Usuário:" - #: bookwyrm/templates/layout.html:175 msgid "password" msgstr "senha" -#: bookwyrm/templates/layout.html:176 bookwyrm/templates/login.html:40 -msgid "Forgot your password?" -msgstr "Esqueceu sua senha?" - -#: bookwyrm/templates/layout.html:179 bookwyrm/templates/login.html:7 -#: bookwyrm/templates/login.html:37 -msgid "Log in" -msgstr "Entrar" - #: bookwyrm/templates/layout.html:187 msgid "Join" msgstr "Registrar" @@ -1487,7 +1714,7 @@ msgstr "Erro ao publicar" #: bookwyrm/templates/layout.html:234 msgid "Contact site admin" -msgstr "Contatar administração" +msgstr "Falar com a administração" #: bookwyrm/templates/layout.html:238 msgid "Documentation" @@ -1513,11 +1740,16 @@ msgstr "Criar lista" #: bookwyrm/templates/lists/created_text.html:5 #, python-format -msgid "Created and curated by %(username)s" -msgstr "Criada e curada por %(username)s" +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Criada por %(username)s e gerenciada por %(groupname)s" #: bookwyrm/templates/lists/created_text.html:7 #, python-format +msgid "Created and curated by %(username)s" +msgstr "Criada e organizada por %(username)s" + +#: bookwyrm/templates/lists/created_text.html:9 +#, python-format msgid "Created by %(username)s" msgstr "Criada por %(username)s" @@ -1537,10 +1769,6 @@ msgstr "Tudo pronto!" msgid "Suggested by" msgstr "Sugerido por" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "Aprovar" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "Descartar" @@ -1549,118 +1777,130 @@ msgstr "Descartar" msgid "Delete this list?" msgstr "Deletar esta lista?" -#: bookwyrm/templates/lists/delete_list_modal.html:7 -msgid "This action cannot be un-done" -msgstr "Esta ação não pode ser desfeita" - -#: bookwyrm/templates/lists/delete_list_modal.html:15 -#: bookwyrm/templates/settings/announcements/announcement.html:20 -#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 -#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Excluir" - #: bookwyrm/templates/lists/edit_form.html:5 #: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Editar lista" -#: bookwyrm/templates/lists/form.html:18 +#: bookwyrm/templates/lists/form.html:19 msgid "List curation:" -msgstr "Curadoria da lista:" +msgstr "Configuração da lista:" -#: bookwyrm/templates/lists/form.html:21 +#: bookwyrm/templates/lists/form.html:22 msgid "Closed" msgstr "Fechada" -#: bookwyrm/templates/lists/form.html:22 +#: bookwyrm/templates/lists/form.html:23 msgid "Only you can add and remove books to this list" -msgstr "Só você pode adicionar ou remover livros nesta lista" - -#: bookwyrm/templates/lists/form.html:26 -msgid "Curated" -msgstr "Curado" +msgstr "Só você pode adicionar ou remover livros" #: bookwyrm/templates/lists/form.html:27 +msgid "Curated" +msgstr "Moderada" + +#: bookwyrm/templates/lists/form.html:28 msgid "Anyone can suggest books, subject to your approval" msgstr "Qualquer pessoa pode sugerir livros para sua aprovação" -#: bookwyrm/templates/lists/form.html:31 +#: bookwyrm/templates/lists/form.html:32 msgctxt "curation type" msgid "Open" msgstr "Aberta" -#: bookwyrm/templates/lists/form.html:32 +#: bookwyrm/templates/lists/form.html:33 msgid "Anyone can add books to this list" msgstr "Qualquer pessoa pode adicionar livros à lista" -#: bookwyrm/templates/lists/form.html:50 +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Grupo" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "Membros do grupo podem adicionar e remover itens da lista" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Selecionar grupo" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Selecione um grupo" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "Você ainda não tem nenhum Grupo!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Criar grupo" + +#: bookwyrm/templates/lists/form.html:81 msgid "Delete list" msgstr "Excluir lista" -#: bookwyrm/templates/lists/list.html:20 +#: bookwyrm/templates/lists/list.html:21 msgid "You successfully suggested a book for this list!" msgstr "Você sugeriu um livro para esta lista com sucesso!" -#: bookwyrm/templates/lists/list.html:22 +#: bookwyrm/templates/lists/list.html:23 msgid "You successfully added a book to this list!" msgstr "Você adicionou um livro a esta lista com sucesso!" -#: bookwyrm/templates/lists/list.html:28 +#: bookwyrm/templates/lists/list.html:29 msgid "This list is currently empty" msgstr "Esta lista está vazia" -#: bookwyrm/templates/lists/list.html:66 +#: bookwyrm/templates/lists/list.html:67 #, python-format msgid "Added by %(username)s" msgstr "Adicionado por %(username)s" -#: bookwyrm/templates/lists/list.html:75 +#: bookwyrm/templates/lists/list.html:76 msgid "List position" msgstr "Posição na lista" -#: bookwyrm/templates/lists/list.html:81 +#: bookwyrm/templates/lists/list.html:82 msgid "Set" msgstr "Definir" -#: bookwyrm/templates/lists/list.html:91 +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 #: bookwyrm/templates/snippets/shelf_selector.html:26 msgid "Remove" msgstr "Remover" -#: bookwyrm/templates/lists/list.html:105 -#: bookwyrm/templates/lists/list.html:122 +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 msgid "Sort List" msgstr "Ordenar lista" -#: bookwyrm/templates/lists/list.html:115 +#: bookwyrm/templates/lists/list.html:116 msgid "Direction" -msgstr "Direção" +msgstr "Sentido" -#: bookwyrm/templates/lists/list.html:129 +#: bookwyrm/templates/lists/list.html:130 msgid "Add Books" msgstr "Adicionar livros" -#: bookwyrm/templates/lists/list.html:131 +#: bookwyrm/templates/lists/list.html:132 msgid "Suggest Books" msgstr "Sugerir livros" -#: bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/lists/list.html:143 msgid "search" msgstr "pesquisar" -#: bookwyrm/templates/lists/list.html:148 +#: bookwyrm/templates/lists/list.html:149 msgid "Clear search" msgstr "Limpar pesquisa" -#: bookwyrm/templates/lists/list.html:153 +#: bookwyrm/templates/lists/list.html:154 #, python-format msgid "No books found matching the query \"%(query)s\"" msgstr "Nenhum livro encontrado para \"%(query)s\"" -#: bookwyrm/templates/lists/list.html:181 +#: bookwyrm/templates/lists/list.html:182 msgid "Suggest" msgstr "Sugerir" @@ -1672,30 +1912,18 @@ msgstr "Salvo" msgid "Your Lists" msgstr "Suas listas" -#: bookwyrm/templates/lists/lists.html:35 +#: bookwyrm/templates/lists/lists.html:36 msgid "All Lists" msgstr "Todas as listas" -#: bookwyrm/templates/lists/lists.html:39 +#: bookwyrm/templates/lists/lists.html:40 msgid "Saved Lists" msgstr "Listas salvas" -#: bookwyrm/templates/login.html:4 -msgid "Login" -msgstr "Entrar" - -#: bookwyrm/templates/login.html:15 -msgid "Success! Email address confirmed." -msgstr "Endereço de e-mail confirmado com sucesso." - -#: bookwyrm/templates/login.html:27 bookwyrm/templates/password_reset.html:17 -#: bookwyrm/templates/snippets/register_form.html:22 -msgid "Password:" -msgstr "Senha:" - -#: bookwyrm/templates/login.html:62 -msgid "More about this site" -msgstr "Mais sobre este site" +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "aceitou seu convite para participar do grupo \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format @@ -1734,7 +1962,7 @@ msgstr "curtiu sua resenha de %(book_title)scomment on%(book_title)s" +msgid "liked your comment on %(book_title)s" msgstr "curtiu seu comentário sobre %(book_title)s" #: bookwyrm/templates/notifications/items/fav.html:31 @@ -1760,6 +1988,21 @@ msgstr "pediu para te seguir" msgid "Your import completed." msgstr "Sua importação foi concluída." +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "te convidou para participar do grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "entrou em seu grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "saiu de seu grupo \"%(group_name)s\"" + #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format msgid "mentioned you in a review of %(book_title)s" @@ -1780,6 +2023,16 @@ msgstr "te mencionou em uma citação de %(book msgid "mentioned you in a status" msgstr "te mencionou em uma publicação" +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "foi excluído(a) de seu grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "Você foi excluído(a) do grupo \"%(group_name)s\"" + #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" @@ -1805,9 +2058,24 @@ msgstr "respondeu à sua report needs moderation." msgstr "Uma nova denúncia para moderação." +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "mudou o nível de privacidade de %(group_name)s" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "mudou o nome de %(group_name)s" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "mudou a descrição de %(group_name)s" + #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" -msgstr "Excluir notificações" +msgstr "Limpar notificações" #: bookwyrm/templates/notifications/notifications_page.html:29 msgid "All" @@ -1819,21 +2087,7 @@ msgstr "Menções" #: bookwyrm/templates/notifications/notifications_page.html:45 msgid "You're all caught up!" -msgstr "Você se atualizou!" - -#: bookwyrm/templates/password_reset.html:23 -#: bookwyrm/templates/preferences/change_password.html:18 -#: bookwyrm/templates/preferences/delete_user.html:20 -msgid "Confirm password:" -msgstr "Confirmar senha:" - -#: bookwyrm/templates/password_reset_request.html:14 -msgid "A link to reset your password will be sent to your email address" -msgstr "Um link para redefinir sua senha será enviada para seu e-mail" - -#: bookwyrm/templates/password_reset_request.html:28 -msgid "Reset password" -msgstr "Redefinir senha" +msgstr "Nenhuma notificação nova!" #: bookwyrm/templates/preferences/blocks.html:4 #: bookwyrm/templates/preferences/blocks.html:7 @@ -1887,7 +2141,7 @@ msgstr "Perfil" #: bookwyrm/templates/preferences/edit_user.html:13 #: bookwyrm/templates/preferences/edit_user.html:68 msgid "Display preferences" -msgstr "Preferências visuais" +msgstr "Preferências da interface" #: bookwyrm/templates/preferences/edit_user.html:14 #: bookwyrm/templates/preferences/edit_user.html:106 @@ -1905,7 +2159,7 @@ msgstr "Mostrar sugestões de usuários:" #: bookwyrm/templates/preferences/edit_user.html:85 #, python-format msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." -msgstr "Sua conta aparecerá no diretório e pode ser recomendada para outros usuários da BookWyrm." +msgstr "Sua conta aparecerá no diretório e poderá ser recomendada para outros usuários da BookWyrm." #: bookwyrm/templates/preferences/edit_user.html:89 msgid "Preferred Timezone: " @@ -2067,15 +2321,6 @@ msgstr "Data de início" msgid "End date" msgstr "Data final" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "Publicação" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "ativo" @@ -2257,7 +2502,7 @@ msgid "Details" msgstr "Detalhes" #: bookwyrm/templates/settings/federation/instance.html:35 -#: bookwyrm/templates/user/layout.html:63 +#: bookwyrm/templates/user/layout.html:64 msgid "Activity" msgstr "Atividade" @@ -2833,53 +3078,66 @@ msgstr "Criar estante" msgid "Edit Shelf" msgstr "Editar estante" -#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf.py:55 +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" msgstr "Todos os livros" -#: bookwyrm/templates/shelf/shelf.html:55 +#: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" msgstr "Criar estante" -#: bookwyrm/templates/shelf/shelf.html:77 +#: bookwyrm/templates/shelf/shelf.html:90 #, python-format msgid "%(formatted_count)s book" msgid_plural "%(formatted_count)s books" msgstr[0] "%(formatted_count)s livro" msgstr[1] "%(formatted_count)s livros" -#: bookwyrm/templates/shelf/shelf.html:84 +#: bookwyrm/templates/shelf/shelf.html:97 #, python-format msgid "(showing %(start)s-%(end)s)" msgstr "(mostrando %(start)s-%(end)s)" -#: bookwyrm/templates/shelf/shelf.html:96 +#: bookwyrm/templates/shelf/shelf.html:109 msgid "Edit shelf" msgstr "Editar estante" -#: bookwyrm/templates/shelf/shelf.html:104 +#: bookwyrm/templates/shelf/shelf.html:117 msgid "Delete shelf" msgstr "Excluir estante" -#: bookwyrm/templates/shelf/shelf.html:132 -#: bookwyrm/templates/shelf/shelf.html:158 +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 msgid "Shelved" msgstr "Adicionado" -#: bookwyrm/templates/shelf/shelf.html:133 -#: bookwyrm/templates/shelf/shelf.html:161 +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 msgid "Started" msgstr "Iniciado" -#: bookwyrm/templates/shelf/shelf.html:134 -#: bookwyrm/templates/shelf/shelf.html:164 +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 msgid "Finished" msgstr "Terminado" -#: bookwyrm/templates/shelf/shelf.html:190 +#: bookwyrm/templates/shelf/shelf.html:203 msgid "This shelf is empty." msgstr "Esta estante está vazia." +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "Convidar" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "Desconvidar" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "Excluir @%(username)s" + #: bookwyrm/templates/snippets/announcement.html:31 #, python-format msgid "Posted by %(username)s" @@ -2911,10 +3169,6 @@ msgstr "Compartilhar" msgid "Un-boost" msgstr "Descompartilhar" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "Resenhar" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "Citar" @@ -2975,6 +3229,7 @@ msgstr "Comentário:" #: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:16 #: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 msgid "Private" msgstr "Particular" @@ -3070,6 +3325,7 @@ msgid "Unfollow" msgstr "Deixar de seguir" #: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 msgid "Accept" msgstr "Aceitar" @@ -3181,12 +3437,14 @@ msgstr "Próxima" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" msgstr "Público" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" msgstr "Não listado" @@ -3195,6 +3453,7 @@ msgid "Followers-only" msgstr "Apenas seguidores" #: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" msgstr "Privacidade da publicação" @@ -3329,14 +3588,14 @@ msgstr "Esconder publicação" #: bookwyrm/templates/snippets/status/header.html:45 #, python-format msgid "edited %(date)s" -msgstr "editado em %(date)s" +msgstr "editado %(date)s" #: bookwyrm/templates/snippets/status/headers/comment.html:2 #, python-format msgid "commented on %(book)s" -msgstr "comentou sobre %(book)s" +msgstr "comentou %(book)s" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "respondeu à publicação de %(username)s" @@ -3388,32 +3647,13 @@ msgstr "Curtir publicação" #: bookwyrm/templates/snippets/status/status.html:10 msgid "boosted" -msgstr "compartilhado" +msgstr "compartilhou" #: bookwyrm/templates/snippets/status/status_options.html:7 #: bookwyrm/templates/snippets/user_options.html:7 msgid "More options" msgstr "Mais opções" -#: bookwyrm/templates/snippets/suggested_users.html:16 -#, python-format -msgid "%(mutuals)s follower you follow" -msgid_plural "%(mutuals)s followers you follow" -msgstr[0] "%(mutuals)s seguidor você segue" -msgstr[1] "%(mutuals)s seguidores você segue" - -#: bookwyrm/templates/snippets/suggested_users.html:23 -#, python-format -msgid "%(shared_books)s book on your shelves" -msgid_plural "%(shared_books)s books on your shelves" -msgstr[0] "%(shared_books)s livro em sua estante" -msgstr[1] "%(shared_books)s livros em suas estantes" - -#: bookwyrm/templates/snippets/suggested_users.html:31 -#: bookwyrm/templates/user/user_preview.html:36 -msgid "Follows you" -msgstr "Segue você" - #: bookwyrm/templates/snippets/switch_edition_button.html:5 msgid "Switch to this edition" msgstr "Trocar para esta edição" @@ -3434,7 +3674,11 @@ msgstr "Mostrar mais" msgid "Show less" msgstr "Mostrar menos" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Seus livros" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "livros de %(username)s" @@ -3463,18 +3707,35 @@ msgstr "Seus livros de %(year)s" msgid "%(username)s's %(year)s Books" msgstr "Livros de %(username)s de %(year)s" -#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10 +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "Seus grupos" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "Grupos: %(username)s" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "Criar grupo" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 msgid "User Profile" msgstr "Perfil do usuário" -#: bookwyrm/templates/user/layout.html:44 +#: bookwyrm/templates/user/layout.html:45 msgid "Follow Requests" msgstr "Solicitações para seguir" -#: bookwyrm/templates/user/layout.html:69 +#: bookwyrm/templates/user/layout.html:70 msgid "Reading Goal" msgstr "Meta de leitura" +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "Grupos" + #: bookwyrm/templates/user/lists.html:11 #, python-format msgid "Lists: %(username)s" @@ -3527,7 +3788,7 @@ msgstr "Nenhuma atividade ainda!" #: bookwyrm/templates/user/user_preview.html:22 #, python-format msgid "Joined %(date)s" -msgstr "Membro desde %(date)s" +msgstr "Entrou %(date)s" #: bookwyrm/templates/user/user_preview.html:26 #, python-format @@ -3561,19 +3822,19 @@ msgstr "Arquivo excede o tamanho máximo: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s: %(subtitle)s" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "Não é um arquivo csv válido" -#: bookwyrm/views/login.py:69 +#: bookwyrm/views/landing/login.py:69 msgid "Username or password are incorrect" msgstr "Nome de usuário ou senha incorretos" -#: bookwyrm/views/password.py:32 +#: bookwyrm/views/landing/password.py:32 msgid "No user with that email address was found." msgstr "Não há nenhum usuário com este e-mail." -#: bookwyrm/views/password.py:41 +#: bookwyrm/views/landing/password.py:43 #, python-brace-format msgid "A password reset link was sent to {email}" msgstr "Um link para redefinição da senha foi enviado para {email}" diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index fbb1986cf8b43b014b8909367d9d5bc656e798f6..5034e6daf6eb4eede9107ade7dc1a3146f0de539 100644 GIT binary patch delta 17515 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 aC%f7vzq<0B`RV$dll!k)Z\n" "Language-Team: Chinese Simplified\n" "Language: zh\n" @@ -72,15 +72,16 @@ msgstr "升序" msgid "Descending" msgstr "降序" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "加载书籍时出错" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "找不到匹配的书" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "待处理" @@ -100,23 +101,23 @@ msgstr "仲裁员删除" msgid "Domain block" msgstr "域名屏蔽" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "有声书籍" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "电子书" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "图像小说" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "精装" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "平装" @@ -133,21 +134,21 @@ msgstr "跨站" msgid "Blocked" msgstr "已屏蔽" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s 不是有效的 remote_id" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s 不是有效的用户名" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "用户名" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "已经存在使用该用户名的用户。" @@ -757,7 +758,7 @@ msgstr "帮助" #: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8 msgid "Edit status" -msgstr "设置状态" +msgstr "编辑状态" #: bookwyrm/templates/confirm_email/confirm_email.html:4 msgid "Confirm email" @@ -889,22 +890,37 @@ msgstr "BookWyrm 用户" msgid "All known users" msgstr "所有已知用户" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "%(username)s 想要阅读 %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 #, python-format msgid "%(username)s rated %(book_title)s" msgstr "%(username)s%(book_title)s 留下了评分" -#: bookwyrm/templates/discover/card-header.html:13 +#: bookwyrm/templates/discover/card-header.html:27 #, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "%(username)s 已评价 %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "%(username)s 评论了 %(book_title)s" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "%(username)s 引用了 %(book_title)s" @@ -1055,9 +1071,8 @@ msgstr "你可以在任何时候从你的个人资料页面 msgid "Updates" msgstr "更新" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "你的书目" #: bookwyrm/templates/feed/layout.html:14 @@ -1066,11 +1081,13 @@ msgstr "现在这里还没有任何书目!尝试着从搜索某本书开始吧 #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "想读" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "在读" @@ -1078,6 +1095,7 @@ msgstr "在读" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "读过" @@ -1233,11 +1251,11 @@ msgstr "创建群组" #: bookwyrm/templates/groups/created_text.html:4 #, python-format msgid "Managed by %(username)s" -msgstr "由 %(username)s 创建并策展" +msgstr "由 %(username)s 管理" #: bookwyrm/templates/groups/delete_group_modal.html:4 msgid "Delete this group?" -msgstr "删除该群组" +msgstr "删除该群组?" #: bookwyrm/templates/groups/delete_group_modal.html:7 #: bookwyrm/templates/lists/delete_list_modal.html:7 @@ -1261,11 +1279,11 @@ msgstr "编辑群组" #: bookwyrm/templates/groups/find_users.html:6 msgid "Add new members!" -msgstr "添加新成员" +msgstr "添加新成员!" #: bookwyrm/templates/groups/form.html:8 msgid "Group Name:" -msgstr "群组名称" +msgstr "群组名称:" #: bookwyrm/templates/groups/form.html:12 msgid "Group Description:" @@ -1289,7 +1307,7 @@ msgstr "编辑群组" #: bookwyrm/templates/groups/members.html:8 msgid "Members can add and remove books on a group's book lists" -msgstr "会员可以在群组的书籍列表中添加和删除书" +msgstr "成员可以在群组的书籍列表中添加和删除书籍" #: bookwyrm/templates/groups/members.html:19 msgid "Leave group" @@ -1361,88 +1379,159 @@ msgid "No recent imports" msgstr "无最近的导入" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "导入状态" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" -msgstr "回到导入" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "导入开始:" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "导入完成:" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "任务失败" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "还在导入中。" - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(按下重新加载来更新!)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "加载失败" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "跳转至列表底部来选取 %(failed_count)s 个导入失败的项目。" +msgid "Refresh" +msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" -msgstr "第 %(index)s 行: %(author)s 所著的 %(title)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "全选" +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "重试项目" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "成功导入了" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" -msgstr "导入进度" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "书目" - -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "标题" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "书评" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "书目" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "状态" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "已导入" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "批准" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "您可以从 导入/导出页面 下载或导出您的 Goodread 数据。" +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1574,10 +1663,6 @@ msgstr "主导航菜单" msgid "Feed" msgstr "动态" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "你的书目" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "设置" @@ -1677,10 +1762,6 @@ msgstr "都弄好了!" msgid "Suggested by" msgstr "推荐来自" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "批准" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "削除" @@ -1737,7 +1818,7 @@ msgstr "选择群组" #: bookwyrm/templates/lists/form.html:45 msgid "Select a group" -msgstr "选择一个组" +msgstr "选择一个群组" #: bookwyrm/templates/lists/form.html:56 msgid "You don't have any Groups yet!" @@ -1835,7 +1916,7 @@ msgstr "保存的列表" #: bookwyrm/templates/notifications/items/accept.html:16 #, python-format msgid "accepted your invitation to join group \"%(group_name)s\"" -msgstr "接受了您的邀请,加入 \"%(group_name)s\" 群组" +msgstr "接受了您的邀请,加入了 \"%(group_name)s\" 群组" #: bookwyrm/templates/notifications/items/add.html:24 #, python-format @@ -1880,7 +1961,7 @@ msgstr "喜欢了你的 %(book_title)s #: bookwyrm/templates/notifications/items/fav.html:31 #, python-format msgid "liked your quote from %(book_title)s" -msgstr "喜欢了你对 %(book_title)s 的引用" +msgstr "喜欢了你的 %(book_title)s 的引用" #: bookwyrm/templates/notifications/items/fav.html:37 #, python-format @@ -1908,12 +1989,12 @@ msgstr "邀请您加入群组 \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/join.html:16 #, python-format msgid "has joined your group \"%(group_name)s\"" -msgstr "已加入您的群組 \"%(group_name)s\"" +msgstr "已加入您的群组 \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/leave.html:16 #, python-format msgid "has left your group \"%(group_name)s\"" -msgstr "退出了了您的群组 \"%(group_name)s\"" +msgstr "退出了您的群组 \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/mention.html:20 #, python-format @@ -1938,7 +2019,7 @@ msgstr "在 状态 中提到了你" #: bookwyrm/templates/notifications/items/remove.html:17 #, python-format msgid "has been removed from your group \"%(group_name)s\"" -msgstr "已经从您的群组中将 \"%(group_name)s\" 移除" +msgstr "已被从您的 \"%(group_name)s\" 群组中移出" #: bookwyrm/templates/notifications/items/remove.html:23 #, python-format @@ -1973,17 +2054,17 @@ msgstr "有新的 报告 需要仲裁。" #: bookwyrm/templates/notifications/items/update.html:16 #, python-format msgid "has changed the privacy level for %(group_name)s" -msgstr "更改了 %(group_name)s的隐私级别" +msgstr "更改了 %(group_name)s 的隐私级别" #: bookwyrm/templates/notifications/items/update.html:20 #, python-format msgid "has changed the name of %(group_name)s" -msgstr "更改了 %(group_name)s的名称" +msgstr "更改了 %(group_name)s 的名称" #: bookwyrm/templates/notifications/items/update.html:24 #, python-format msgid "has changed the description of %(group_name)s" -msgstr "更改了 %(group_name)s的描述" +msgstr "更改了 %(group_name)s 的描述" #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" @@ -2233,15 +2314,6 @@ msgstr "开始日期" msgid "End date" msgstr "结束日期" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "状态" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "活跃" @@ -3085,10 +3157,6 @@ msgstr "转发" msgid "Un-boost" msgstr "取消转发" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "书评" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "引用" @@ -3510,7 +3578,7 @@ msgstr "在 %(date)s 已编辑" msgid "commented on %(book)s" msgstr "评论了 %(book)s" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "回复了 %(username)s状态" @@ -3589,7 +3657,11 @@ msgstr "显示更多" msgid "Show less" msgstr "显示更少" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "你的书目" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "%(username)s 的书目" @@ -3731,7 +3803,7 @@ msgstr "文件超过了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "%(title)s:%(subtitle)s" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "不是有效的 csv 文件" diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo index 1f615988e85b86ceed992fb8f9eeca9fa4068e0d..baefb103cead9162e9927bcfbee60ac4ab807d82 100644 GIT binary patch delta 12711 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 delta 13329 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 Q`)T(~h*6tAws7zP0Exf0_W%F@ diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index cdaa1f81a..9b6e27b8c 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-10-24 14:09+0000\n" -"PO-Revision-Date: 2021-10-24 18:36\n" +"POT-Creation-Date: 2021-11-14 15:08+0000\n" +"PO-Revision-Date: 2021-11-15 18:02\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Chinese Traditional\n" "Language: zh\n" @@ -72,15 +72,16 @@ msgstr "升序" msgid "Descending" msgstr "降序" -#: bookwyrm/importers/importer.py:75 +#: bookwyrm/importers/importer.py:127 msgid "Error loading book" msgstr "" -#: bookwyrm/importers/importer.py:88 +#: bookwyrm/importers/importer.py:135 msgid "Could not find a match for book" msgstr "" #: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 msgid "Pending" msgstr "" @@ -100,23 +101,23 @@ msgstr "" msgid "Domain block" msgstr "" -#: bookwyrm/models/book.py:232 +#: bookwyrm/models/book.py:233 msgid "Audiobook" msgstr "" -#: bookwyrm/models/book.py:233 +#: bookwyrm/models/book.py:234 msgid "eBook" msgstr "" -#: bookwyrm/models/book.py:234 +#: bookwyrm/models/book.py:235 msgid "Graphic novel" msgstr "" -#: bookwyrm/models/book.py:235 +#: bookwyrm/models/book.py:236 msgid "Hardcover" msgstr "" -#: bookwyrm/models/book.py:236 +#: bookwyrm/models/book.py:237 msgid "Paperback" msgstr "" @@ -133,21 +134,21 @@ msgstr "跨站" msgid "Blocked" msgstr "已封鎖" -#: bookwyrm/models/fields.py:27 +#: bookwyrm/models/fields.py:29 #, python-format msgid "%(value)s is not a valid remote_id" msgstr "%(value)s 不是有效的 remote_id" -#: bookwyrm/models/fields.py:36 bookwyrm/models/fields.py:45 +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 #, python-format msgid "%(value)s is not a valid username" msgstr "%(value)s 不是有效的使用者名稱" -#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:171 +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 msgid "username" msgstr "使用者名稱" -#: bookwyrm/models/fields.py:186 +#: bookwyrm/models/fields.py:188 msgid "A user with that username already exists." msgstr "已經存在使用該名稱的使用者。" @@ -889,22 +890,37 @@ msgstr "BookWyrm 使用者" msgid "All known users" msgstr "所有已知使用者" -#: bookwyrm/templates/discover/card-header.html:9 +#: bookwyrm/templates/discover/card-header.html:8 #, python-format -msgid "%(username)s rated %(book_title)s" +msgid "%(username)s wants to read %(book_title)s" msgstr "" #: bookwyrm/templates/discover/card-header.html:13 #, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 +#, python-format +msgid "%(username)s rated %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:27 +#, python-format msgid "%(username)s reviewed %(book_title)s" msgstr "" -#: bookwyrm/templates/discover/card-header.html:17 +#: bookwyrm/templates/discover/card-header.html:31 #, python-format msgid "%(username)s commented on %(book_title)s" msgstr "" -#: bookwyrm/templates/discover/card-header.html:21 +#: bookwyrm/templates/discover/card-header.html:35 #, python-format msgid "%(username)s quoted %(book_title)s" msgstr "" @@ -1055,9 +1071,8 @@ msgstr "你可以在任何時候從你的使用者資料頁 msgid "Updates" msgstr "更新" -#: bookwyrm/templates/feed/layout.html:12 -#: bookwyrm/templates/user/books_header.html:3 -msgid "Your books" +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" msgstr "你的書目" #: bookwyrm/templates/feed/layout.html:14 @@ -1066,11 +1081,13 @@ msgstr "現在這裡還沒有任何書目!嘗試著從搜尋某本書開始吧 #: bookwyrm/templates/feed/layout.html:25 #: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 msgid "To Read" msgstr "想讀" #: bookwyrm/templates/feed/layout.html:26 #: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 msgid "Currently Reading" msgstr "在讀" @@ -1078,6 +1095,7 @@ msgstr "在讀" #: bookwyrm/templates/shelf/shelf.html:42 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 msgid "Read" msgstr "讀過" @@ -1361,88 +1379,159 @@ msgid "No recent imports" msgstr "無最近的匯入" #: bookwyrm/templates/import/import_status.html:6 -#: bookwyrm/templates/import/import_status.html:10 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 msgid "Import Status" msgstr "匯入狀態" -#: bookwyrm/templates/import/import_status.html:11 -msgid "Back to imports" +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" msgstr "" -#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" msgstr "匯入開始:" -#: bookwyrm/templates/import/import_status.html:20 -msgid "Import completed:" -msgstr "匯入完成:" - -#: bookwyrm/templates/import/import_status.html:24 -msgid "TASK FAILED" -msgstr "任務失敗" - -#: bookwyrm/templates/import/import_status.html:32 -msgid "Import still in progress." -msgstr "還在匯入中。" - -#: bookwyrm/templates/import/import_status.html:34 -msgid "(Hit reload to update!)" -msgstr "(按下重新載入來更新!)" - -#: bookwyrm/templates/import/import_status.html:41 -msgid "Failed to load" -msgstr "載入失敗" +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" #: bookwyrm/templates/import/import_status.html:50 -#, python-format -msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import." -msgstr "跳轉至列表底部來選取 %(failed_count)s 個匯入失敗的項目。" +msgid "Refresh" +msgstr "" #: bookwyrm/templates/import/import_status.html:62 #, python-format -msgid "Line %(index)s: %(title)s by %(author)s" +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" + +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:82 -msgid "Select all" -msgstr "全選" +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" -#: bookwyrm/templates/import/import_status.html:85 -msgid "Retry items" -msgstr "重試項目" - -#: bookwyrm/templates/import/import_status.html:112 -msgid "Successfully imported" -msgstr "成功匯入了" - -#: bookwyrm/templates/import/import_status.html:114 -msgid "Import Progress" +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:119 -msgid "Book" -msgstr "書目" +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" -#: bookwyrm/templates/import/import_status.html:122 +#: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "標題" -#: bookwyrm/templates/import/import_status.html:125 +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" -#: bookwyrm/templates/import/import_status.html:148 +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "書評" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "書目" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "狀態" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 msgid "Imported" msgstr "已匯入" +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "批准" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." msgstr "" +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format msgid "About %(site_name)s" @@ -1574,10 +1663,6 @@ msgstr "主導航選單" msgid "Feed" msgstr "動態" -#: bookwyrm/templates/layout.html:106 -msgid "Your Books" -msgstr "你的書目" - #: bookwyrm/templates/layout.html:116 msgid "Settings" msgstr "設定" @@ -1677,10 +1762,6 @@ msgstr "都弄好了!" msgid "Suggested by" msgstr "推薦來自" -#: bookwyrm/templates/lists/curate.html:57 -msgid "Approve" -msgstr "批准" - #: bookwyrm/templates/lists/curate.html:63 msgid "Discard" msgstr "放棄" @@ -2233,15 +2314,6 @@ msgstr "開始日期" msgid "End date" msgstr "結束日期" -#: bookwyrm/templates/settings/announcements/announcements.html:38 -#: bookwyrm/templates/settings/federation/instance_list.html:46 -#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 -#: bookwyrm/templates/settings/invites/status_filter.html:5 -#: bookwyrm/templates/settings/users/user_admin.html:34 -#: bookwyrm/templates/settings/users/user_info.html:20 -msgid "Status" -msgstr "狀態" - #: bookwyrm/templates/settings/announcements/announcements.html:48 msgid "active" msgstr "啟用" @@ -3085,10 +3157,6 @@ msgstr "轉發" msgid "Un-boost" msgstr "取消轉發" -#: bookwyrm/templates/snippets/create_status.html:17 -msgid "Review" -msgstr "書評" - #: bookwyrm/templates/snippets/create_status.html:39 msgid "Quote" msgstr "引用" @@ -3510,7 +3578,7 @@ msgstr "" msgid "commented on %(book)s" msgstr "" -#: bookwyrm/templates/snippets/status/headers/note.html:15 +#: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" msgstr "回覆了 %(username)s狀態" @@ -3589,7 +3657,11 @@ msgstr "顯示更多" msgid "Show less" msgstr "顯示更少" -#: bookwyrm/templates/user/books_header.html:5 +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "你的書目" + +#: bookwyrm/templates/user/books_header.html:15 #, python-format msgid "%(username)s's books" msgstr "%(username)s 的書目" @@ -3731,7 +3803,7 @@ msgstr "檔案超過了最大大小: 10MB" msgid "%(title)s: %(subtitle)s" msgstr "" -#: bookwyrm/views/import_data.py:67 +#: bookwyrm/views/imports/import_data.py:64 msgid "Not a valid csv file" msgstr "不是有效的 csv 檔案" From a26302683f335d9f6f76fed9c1f1d79b4a793e85 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Nov 2021 09:31:57 -0800 Subject: [PATCH 123/134] List command in echo --- bw-dev | 1 + 1 file changed, 1 insertion(+) diff --git a/bw-dev b/bw-dev index f50800cf0..5da971705 100755 --- a/bw-dev +++ b/bw-dev @@ -173,6 +173,7 @@ case "$CMD" in echo " collectstatic" echo " makemessages" echo " compilemessages [locale]" + echo " update_locales" echo " build" echo " clean" echo " black" From 6dd7eebd98573c5d7618385ec75b5143cd2ec714 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Nov 2021 10:16:28 -0800 Subject: [PATCH 124/134] Fixes tests --- bookwyrm/connectors/inventaire.py | 2 +- bookwyrm/tests/connectors/test_inventaire_connector.py | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index e180dc62f..e9f538569 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -67,7 +67,7 @@ class Connector(AbstractConnector): extracted = list(data.get("entities").values()) try: data = extracted[0] - except KeyError: + except (KeyError, IndexError): raise ConnectorException("Invalid book data") # flatten the data so that images, uri, and claims are on the same level return { diff --git a/bookwyrm/tests/connectors/test_inventaire_connector.py b/bookwyrm/tests/connectors/test_inventaire_connector.py index 6536bae71..65325d02f 100644 --- a/bookwyrm/tests/connectors/test_inventaire_connector.py +++ b/bookwyrm/tests/connectors/test_inventaire_connector.py @@ -269,10 +269,14 @@ class Inventaire(TestCase): responses.GET, "https://inventaire.io/?action=by-uris&uris=hello", ) - data = {"wdt:P629": "hello"} - self.connector.get_work_from_edition_data(data) + data = {"wdt:P629": ["hello"]} + with patch("bookwyrm.connectors.inventaire.Connector.get_book_data") as mock: + self.connector.get_work_from_edition_data(data) + self.assertEqual(mock.call_count, 1) + args = mock.call_args[0] + self.assertEqual(args[0], "https://inventaire.io?action=by-uris&uris=hello") - data = {"wdt:P629": None} + data = {"wdt:P629": [None]} with self.assertRaises(ConnectorException): self.connector.get_work_from_edition_data(data) From e3fec5885ad58661c7c5328d6ac408e0b22bf53f Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 16 Nov 2021 16:17:38 -0800 Subject: [PATCH 125/134] Fixes logic on nodeinfo page --- bookwyrm/views/wellknown.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bookwyrm/views/wellknown.py b/bookwyrm/views/wellknown.py index de4f7e62e..a9b35b637 100644 --- a/bookwyrm/views/wellknown.py +++ b/bookwyrm/views/wellknown.py @@ -108,7 +108,8 @@ def instance_info(_): "thumbnail": logo, "languages": ["en"], "registrations": site.allow_registration, - "approval_required": site.allow_registration and site.allow_invite_requests, + "approval_required": not site.allow_registration + and site.allow_invite_requests, "email": site.admin_email, } ) From 058184a81b6eef1e76b837e942b69f5aa7f2da47 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 17 Nov 2021 09:49:59 -0800 Subject: [PATCH 126/134] Adds translations for french and lithuanian lcoales --- locale/de_DE/LC_MESSAGES/django.mo | Bin 60544 -> 30883 bytes locale/fr_FR/LC_MESSAGES/django.mo | Bin 62284 -> 65002 bytes locale/fr_FR/LC_MESSAGES/django.po | 52 +++++++++++++-------------- locale/lt_LT/LC_MESSAGES/django.mo | Bin 61085 -> 61847 bytes locale/lt_LT/LC_MESSAGES/django.po | 14 ++++---- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 56164 -> 44096 bytes locale/zh_Hant/LC_MESSAGES/django.mo | Bin 37625 -> 38839 bytes 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.mo b/locale/de_DE/LC_MESSAGES/django.mo index f49377602bd22295101586a22cb0e70402ea5905..4ce83f72b3f3850c58528f13afcd23442a75a515 100644 GIT binary patch delta 14999 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 Bt}57^E2(7!sWs7>pPg7;2p%`ZhQ-Fo-cQFx+-# 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 C^@Xkg diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo index 1e81ac6e6aa1e751a387956c9466e48433254d03..8696fb99d4fe41e6b3d7f2248ee170dcab6da7be 100644 GIT binary patch delta 20089 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 delta 17436 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 J`#zs51_0v~p}hbA diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index ee9850e2d..23661a28c 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-15 22:27\n" +"PO-Revision-Date: 2021-11-16 23:06\n" "Last-Translator: Mouse Reeve \n" "Language-Team: French\n" "Language: fr\n" @@ -1392,11 +1392,11 @@ msgstr "Statut de l’importation" #: bookwyrm/templates/import/import_status.html:13 #: bookwyrm/templates/import/import_status.html:27 msgid "Retry Status" -msgstr "" +msgstr "Statut de la nouvelle tentative" #: bookwyrm/templates/import/import_status.html:22 msgid "Imports" -msgstr "" +msgstr "Importations" #: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" @@ -1404,38 +1404,38 @@ msgstr "Début de l’importation :" #: bookwyrm/templates/import/import_status.html:48 msgid "In progress" -msgstr "" +msgstr "En cours de traitement" #: bookwyrm/templates/import/import_status.html:50 msgid "Refresh" -msgstr "" +msgstr "Actualiser" #: bookwyrm/templates/import/import_status.html:62 #, python-format msgid "%(display_counter)s item needs manual approval." msgid_plural "%(display_counter)s items need manual approval." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(display_counter)s élément a besoin d'être approuvé manuellement." +msgstr[1] "%(display_counter)s éléments ont besoin d'être approuvés manuellement." #: bookwyrm/templates/import/import_status.html:67 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" -msgstr "" +msgstr "Vérifier les éléments" #: bookwyrm/templates/import/import_status.html:73 #, python-format msgid "%(display_counter)s item failed to import." msgid_plural "%(display_counter)s items failed to import." -msgstr[0] "" -msgstr[1] "" +msgstr[0] "%(display_counter)s élément n'a pas pu être importé." +msgstr[1] "%(display_counter)s éléments n'ont pas pu être importés." #: bookwyrm/templates/import/import_status.html:79 msgid "View and troubleshoot failed items" -msgstr "" +msgstr "Afficher et corriger les importations ayant échoué" #: bookwyrm/templates/import/import_status.html:91 msgid "Row" -msgstr "" +msgstr "Ligne" #: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 @@ -1445,7 +1445,7 @@ msgstr "Titre" #: bookwyrm/templates/import/import_status.html:97 msgid "ISBN" -msgstr "" +msgstr "ISBN" #: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 @@ -1455,7 +1455,7 @@ msgstr "Auteur/autrice" #: bookwyrm/templates/import/import_status.html:103 msgid "Shelf" -msgstr "" +msgstr "Étagère" #: bookwyrm/templates/import/import_status.html:106 #: bookwyrm/templates/import/manual_review.html:13 @@ -1479,7 +1479,7 @@ msgstr "Statut" #: bookwyrm/templates/import/import_status.html:144 msgid "View imported review" -msgstr "" +msgstr "Afficher la critique importée" #: bookwyrm/templates/import/import_status.html:158 msgid "Imported" @@ -1487,16 +1487,16 @@ msgstr "Importé" #: bookwyrm/templates/import/import_status.html:164 msgid "Needs manual review" -msgstr "" +msgstr "Nécessite une vérification manuelle" #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" -msgstr "" +msgstr "Résolution des problèmes d'importation" #: 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 "Approuver une suggestion ajoutera définitivement le livre suggéré à vos étagères et associera vos dates, critiques et notes de lecture à ce livre." #: bookwyrm/templates/import/manual_review.html:56 #: bookwyrm/templates/lists/curate.html:57 @@ -1505,7 +1505,7 @@ msgstr "Approuver" #: bookwyrm/templates/import/manual_review.html:64 msgid "Reject" -msgstr "" +msgstr "Rejeter" #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." @@ -1513,31 +1513,31 @@ msgstr "Vous pouvez télécharger vos données GoodReads depuis la page open an issue if you are seeing unexpected failed items." -msgstr "" +msgstr "Contactez votre administrateur·ice ou signalez un problème si vous voyez des éléments inattendus qui ont échoué." #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format diff --git a/locale/lt_LT/LC_MESSAGES/django.mo b/locale/lt_LT/LC_MESSAGES/django.mo index ea2d76b14c61ccef786c478e234431b32a354d4c..0b31ed928845cf4b7a4076a3d165b541be594590 100644 GIT binary patch delta 17417 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 mf;#W!|8u1oCpXMD-z>9WuK4DC+r\n" "Language-Team: Lithuanian\n" "Language: lt\n" @@ -902,17 +902,17 @@ msgstr "Visi žinomi nariai" #: bookwyrm/templates/discover/card-header.html:8 #, python-format msgid "%(username)s wants to read %(book_title)s" -msgstr "" +msgstr "%(username)s nori perskaityti %(book_title)s" #: bookwyrm/templates/discover/card-header.html:13 #, python-format msgid "%(username)s finished reading %(book_title)s" -msgstr "" +msgstr "%(username)s perskaitė %(book_title)s" #: bookwyrm/templates/discover/card-header.html:18 #, python-format msgid "%(username)s started reading %(book_title)s" -msgstr "" +msgstr "%(username)s pradėjo skaityti %(book_title)s" #: bookwyrm/templates/discover/card-header.html:23 #, python-format @@ -1449,7 +1449,7 @@ msgstr "" #: bookwyrm/templates/import/import_status.html:91 msgid "Row" -msgstr "" +msgstr "Eilutė" #: bookwyrm/templates/import/import_status.html:94 #: bookwyrm/templates/shelf/shelf.html:141 @@ -1459,7 +1459,7 @@ msgstr "Pavadinimas" #: bookwyrm/templates/import/import_status.html:97 msgid "ISBN" -msgstr "" +msgstr "ISBN" #: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/shelf/shelf.html:142 @@ -1519,7 +1519,7 @@ msgstr "Patvirtinti" #: bookwyrm/templates/import/manual_review.html:64 msgid "Reject" -msgstr "" +msgstr "Atmesti" #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 5034e6daf6eb4eede9107ade7dc1a3146f0de539..1d1227f8092b70c68bb692fb532759090142aa83 100644 GIT binary patch delta 16563 zcmaE|jrqV0ruutAEK?a67#JopF)+w5Ffc3;VPME*W?<0K1c@>*JTPNm&|+X3~CGv3@(-s@oY;51`!4ZhE7Wc1|1A{8aVO9(b$_xw)ZB`5nMhpxLtE?Cp@)_zG818}@3=F>33=DY; z3=Dg%85n{Y7#MVH7#N}%7#JFC7#OM;7#Qx@Ffc?iFffGMLVUW>7UJ_ywhRoW3=9mM zb_@)lK(mL^nRXBlOtxcSU}a!n*k#ASAk4tPZ~#hQv14Fht7l+fcwxuDzyb2H9RmX| z0|UbkI|c@J1_lN;djC!tOzjyMco-NMETQ6V z_6!W13=9nZ_K+xugz__?bg?}HLp?}Ctvv$+9|HqJmpuamHv1e5QhjlKpZ0F0I^uk0b;R+1H@q#4iIx)9UxIq?!ZtF zPE@NL7#M^=LE`{P9G9UQzBoWagwYY=Kz>Jv1#*s%xL0z7806vzQCIE=38_{`hy!{Z zAt5;35n}#4sJ@Mk3=9$s3=EeY>meH6KsA1GWME)nU|{&;2yr>16C`m7IzfD(?gY_j z;slZRb%IzN>jcr4?F0$I0w+jF)i^=SZ-T1pa)Nkd22}m>dM8NGu5p57tG!N;M0NtI zP|2BrVFCjKgP}9Tz(dXu15P+IFbFa*FkFXqCKpHuNVq^8Ebjtw zu)YgKeZ8#<#9%L|!T_kka2JTf(p?}vsBnSAaf1saXgggX4w(#mF1=IBm60Q&nv|S+%F?NNx*wPh}T^w8?E)H>p1Z|Ql#N~Oe z5DTlJ;=NGunNWSpTp1XwK-tcffkBUff#Itw1A{yR1A~ei#6A}{kp6lG1|K&_(8sw! z49vzoz)eD?SQI`)@U*Q39K!*ndLp`X#nFf_u;sHs;TRb2>+UWrbA_j)@ z9uOZt^nm!_E!2WvP@2UPVlkg5L|(!Z;&4?c-@p^%P+O?DuO}oeM0hgPgI!+i3GvYy zPe>4N@`NP5gPstVUxHe2+Y{oWr%?JWRQ*>^ND#AlLF6U9Am%B0LG-J8K^$n{1xZs@ zP}6;=n6VgCBcA9Qwu!5@LU$`h>k9 z4wCYQ_*~x`5|Z{%exNtRL5cO=5CgNJ0#)9Spl*SRPw<8qJl`AQv#s6`AMN#q_~e*3 zB&ctBL*n!)RNrTBNUh1_1F=ZK2jVd;ABcy|eIV-VZG0dGdO_)6A4t%}_%JYdFfcGA z`9MNqwGSjDHbMEPp!7u_NC@13TJX{b;^S{n3)p-iJ{R$YcuWn-H}VCmt7mZWh1A<2 zz7U7xLFsac0)_@(NC-^ug}8W`FC@gaKn*$!mA~o>amZ_^x<9@UpL6*^)Qk9mEo4yk zgM_59AE*wgXJD}QV_;BcU|@*#gTz^@A0&uo`9Un4?+0<%TBrfr{2=XuV}1||l>8x4 zpyLnmp}9ZAB4>XF20sP{hG2h4+FIlfamXQmNQhkYXJB9f<^RV}jW7Hm`S=S+0@Sn$ zfEa8P0MTe00CA8{03?c{0w8H1Apqj=k^o4{s1qu`CII4~O;G*&0w7U&Hh_Uaj)8&U zN&o{xJ*c7a8LHtoR0Crm!~)(xh{3{v3=HNB3=A59kVKRa2=PH~Af&*m4}^r!Y$&}1 zO0NwBm+=hSpyr$mgtRg5LCyIc$WRY%v2X-If>JaHVzGP>#HXr34B+b6I0#~)MG(Y5 zuOLW>#0Eipk`u(hpv%C(&>aME$j%^0Vm$=acPj{D{u?O&8>dnh^~MB4eApfgv1oBH#Gpe^b!UPhiRoc5#NjW4Awm2;7~+9%!H^JR34y2+41wsE z41qXQxjuw}Aq&*l41v^A(?cKz9SdOq`}|A@q;9wv0!dV_LLjO9R|o@xF#`hwcPOMW zY99(Qupt!UfX+~eMH50H4w)4SDRNhYLek9PP)LZ@Uxy03glha73dxQvVGxVu!XOSY z4} zMZDnoI6M=|FNlDIP(uX7fm5OKvm+Q7ltKA_5mdpk2nGgy1_p-P5s;AJj)b^WHWK0! z)ksJj>P1328lI7mlCd}v5@MZ^&<;l=B zX~$?thy_PO%uk4hB;K58hI(*kaskwU)ldcdp$4Chh9sH`(GVYei-tIWH3niJZw#bA zAQi*FkjucpAQuDiNDq{r8Us;3F9wopmO=GxkAZ~Pk(hc2<6I2Hq8m^R|6(9<$`%W; zSR@u=uyQO!y-qA7?#*H$bw@xf1A{gL14BhDqzGOT3$ge(RQ>r_hy!lMLPF+MEF>-c zsgH$pB6;EbDez~BNZ z851Gdr!Wyx4zwjgDv_Cq3=B>T3=G?#@;?(HA;*^l$!3yCkPwnjf_O|V36fa#k{}*1 z2GjKn3^qv+pSnU7`X@nr9G(P8)#+e`3=Gvt5FfQb)z5~CFNLaK2j%aBnsYn}5|ZbW zAP&0=<-bURgyc664a)z_$q)w!Btu*#l?+Kl%208)WQdOfk|90{ONJ!6Sg86|DBYI~ zNnF#DAyKh184|}kk|7Q`2bI5*3<=41$qWqjpdl5;6o^m7QXp}ql>#xyECu2qj}%B_ zGB5>Fz~rYud@wBq610m`Ah}_63dF*rDG&>9r$9XRG6fQ%pHm=XL(Hj=5tEQqhI-H- z5JOig14A6BH=7EnRLs&Kxgj$RGW61!2FYG5=?vgOC4+Q`MTzMUgUiz)*|$9%V!_&U zNSgYW4)K_02BZLs&44((D+3ZG(=+NJj71p?3`GnK3~MtWZ99cbh3us`m-ShPs)Z2nat0I`0Qdf1A{+k_$>!A%2kvDiK68>kRaWV1JU;^ zhk-$Zfq~&OR9+?*;sMoMNUk!>g^aS*mq8h)b0MQ%3VD!5Xh|LhoQ^B@*~&4c*tA5@$z9}*Hg`H(0R&WEVChw@$X85kykLLeWkzn+1mfPo>3fq{Xy z04%_eQ2;I&7zzs@2F)*kB(7xz3=9dNF`@#9g^Goc5YQ}y=!+|4U@&K7U`Q{7)PD1e zAo_L`L89^!lz+DfQl5M-0_CE51_qvDNVRKH3^6dJ7~I5)sX5pyc*(xjB1F3@~i710_D{Z2h>$V z4DN>V=T$=roYmC~3}&D)V5q!s4Me?K4J59OYar%?L+Q90h{dT;etr!kQJ2*~9J-_i z5~4Tip$c9=>Gx3jTMfj;e`_H1HD4_x?hI-n7J1e}d=LQTN7ONwP(tF;i9->HST@L4US2>k|?=cbQ)0c<~jz3 zS_TG&$xwO0dWd?7dPu6*fQGmoDCdF3|6QR&utD_@A4WkH6hjm+R6z}Bhw`UG<(EL4 zZmXf7E-i=gy+D7^40n!38X@nFQ z$&C;T+n{uBBgBDIp!6ary`d4}fqhW^X(<0Dl>ZFM|I!GFQpP3*hI-HhgJ=`PXEIF? z1B{@wJ(Tu=(veLNho&__3aEOhzIjcM0%%JU#G#zcki;p_4B<;a`SMV{dNag>dd&>= z3?K)@LM2k5bT*VOYKAzdvKivzHmLX%sQ7Fse?>E-XS5zFehNxohw6I*<$r?G|DiNb z3pf!lFi5sQEYfKKB?<-xODOFF6_0O$)CD;$3=Fmm3=ADD5T6}ufjI0eRNZYT{Q@ff z6{?Q86%ry`tq^;JS|Rqx*SA7SETdLPPsX+tQkyxpLM-rtY6yhVaZvH>R!F%}1QnkG z6<^p235gZ0kb>zjRQ@@X{?ZD`j*M*(ht~_XK`fGQgOv4ZZ4eh)w?Pt#2b7L!gOm#e zQ28n--QEWA$rLDmIh4Pp4dUbDQ1j12#jioty@WWRp5a>?q#AF56CnmEPXudV zFox0&6CoD*PJ~omArm1!%z}!yLe=#^ZQ1PrukZe~t3DTTzodg-8Sp`*pXc8o?TmY#D z<^S7I10F%?S0D+{(g`U26KXNTWJt*HPKG#0VKT%)>XRW3Hi7b;CPPBZAIgu1s?V7W zaab{w-#(dvp&qn0qYo-D52|q~RN+>r_(>>zVKSsrxek^8JsDDu^G|^|%x((AVS!U1 zArdhK(t=8u0_luaO@TOg@f1iR+%Scq9y}AVYYHS4--H_U3968FDnx_OR7gkS^VhsSt;}fXaV>(%+{-LgL?4X#N+P2C+yIN~=L>V<_z~ z4N~O#PJ>uf4Ha*K(*4sQ4x2L#k`0$lgG9->X%Gk8nFfiHCs6%grZF%CF)%Rvu7?`n zHyvVd^mK?rlBPp~G=DloV-r+-5|o}l9a2QEf$F;i6~75p{|qYrZ92pOf2Tuo3F{1q z1EryKy)%@NJp*F#WGKA=O0R{|yJkQfa(o6Pn_Zs)NeiE#@?tX~K31LyF~<-}+s%aN z^PUOy;7o|el4gP(R?kohm8gZ%Ei)n6qkASKNTix^~QF)+k1Ffgdjf;hAZOxH6oOn@q!Hw)sj)lmMvSr8YWo(1UxUYZ37 zI_BAsnNjW8klL?gHY9CqpAG45Kb;Lp%-VAx<%i202tQ#Cq#Is22ND%K=P)qvgYy6R zIS`BP&w;q~8I=ES4x~-^bq>TQKcO_+TnJwnN-NBTI9wM>J3z&Q=R%??VJ;*jtD$r& zRK9;M14BJ%E!Uj65C<%u3kjNaP- zARe-r2g&~~P=4+_hzCmNG1PXy!jIBe5=$bja~`OseJ_4yD7yoD-cSO6&? zco#rM#S|AXFjz7$FqAHU)PCz1FfimZFfec|gv5QtLWl#FErf{gUkGWc=`VuNQHvn* zt&1SJVcsH0?pasA2vQwhS_Bz*lwAz*S><9#qMNW7;=_Yb`W%$Ly_kU^1GIK*F#|&= z0|P_g5{SCxPiS1(!hv9MhIT44ShHqJHr*NS&~D8ARWmWef~~pao3JA?ll#L)7hD4j$O7XE?kZ z;_|P{A#u;N0%D-V3W&J;3do41&I(A-7eeV%P+EBSW^R9w8Km^RMXJC+n3aGAvxLhB~k6Q(4Fl4NP47tvMioaO}iK=g_AaNPAngP6s zC22Lpg4wGfxna?21_o;e28MmBAr}5x4fZhu%NhvZYz+egBPjnHGeKM~!N|aHgMoqJ z1|tI;fY$HjfChva7#PYJ7#O4(85njkFfed2GBC(O#X*X{g9s$7%gDemkr6UZ2wJ=t z&cwiA#l*lck%57s88ke@$iSe)1R8&VY67j@1Wm*Ifb!d*j=0arz|aa6Th9m?>j809 z7#SG0FhWMbofsJyI2jojnwS_EnxXnSp|mw4Bsx+V85rCd7#M7s7#LnNGB6lGv(u!0;So3j+g#2qOc-1SZJn^-l%{h9E`;h89K!hO3~lUPcCn zS0D#6GB8Yms$as$z;F~K$H2fK!^FVg&&a?~$Hc(!nUR5kl@U^O=P@xbWP#XBpzvp4 zU^v9Uz#z`Zz_5^!fnf&3Wei^!85p>kAo)Lxk%3_p%n3P<`j24zXoqV5nzeUp3=9cS z-$V6*sq2gk3@aHK7@jgRFmyoWRT&u=n3xzC)-Xa6Rti)cG@$_21SQTv=_!m13@f0H z0xjo+3WFEBq(H^N{!e3KVCZFHV3^Oyz+eMfNXo>(@D8fln-S8{0C8Oy85k}yGBD^f zGB9{UEx!lqFET;ec^eoQ7z&se7*0VA2kC*~Sy0A9D4oc}z_1;Z{y-ztATd)$1_no{ z#&jk~=?4-A;nj=`3?CR77~+^17(zh~f~o__U0{Ti6D*)a#l*m{nSp^pn~8xzhzT+u z08#_P$)FVzj0_Cl7#J94F)}bPg7TjaXp)hMfgzTWfnfn71A_w-14Aj21%(Wddiya0 z1A_v{5sVBB%NZCL&VtelXqhe}q%HRz)Q@CfU^vadz_6Q(_BC@8Hk zFfimm`5?6{ObiT}Opwkjh!4WjObiSaj0_AvKnWDIrdyPWfgy>JfuW3%fq{dOf#DxW z6$1mqH%11AQc%b+F)&0jGB9W|GBEr`GW-c61H)`a28LgZ3=HK=3=CzUAcs135d#AQ zXkqyo1_p*0sMr$*1_nV!28L~n3=BIU=G23iMprUH+U+l(7GH(ZAnFbS1H)a=YDf@= z0kRtQ76SuA1gKnKWMBwqWMKFMl>^Oqfta8{3=j>%b3i2}h`|7va_a;|5hG+k;}0nQ zqnH>Ncp2`F}DWMD91gbdMuglZTd4cRVeXdGr_V5kP=e`}}!ND&OTGcqtpGBGd&GC^iW zLE@gEl+MJ!&;@nKVbE%LCI$vRCI*IA3=9kzObiUS85kHE85tNvm>3x3k<7it$iQ#` zw1fjx3NkS;@I&S5PckqtfE)p8L==Jw7X}6fF{mWSQbs1oKmv%}2o>K7;(%H|piU~( zF};io4B|`-4Dk#M4A(&Q0#qEdGQNh1fngs51A`eO14AVv1A`GL)EF5UZZd+_--Fg+ zGcqtNgBltEDu|%$El_$7BLjmPBLl-u1_lN<(1H{u28Jd^28QX33=Bz7M?sY`d;)oZ zfq~&XBLhP;69a=5BLjmT69a=0nmSPPtq7F=-hifCnHU(3flPoZx(M1Zz{tR$#l*m1 z$jHEO4OE#hFfgnG84C584^%BkTP9RYk%@sJh>3wA1yn9DK^CQe79oSwBr-5C{0A|h z7+my%7Mu4?zGx#n`GE~f{dYzNh6*MI26aXT1|dcUhIWt^sL{t585s6K*-lIh4B3nf z3}&Dj9qJ6w8s}6f`w$}o13y$P$hOZQ0ts(mWMB|xWMDYOz`)SX#K7Rr#K4fx#8A($ zl!1Za8EDS~0|UcJMg|6D5N2Xva0ZDnGB9{CLfX3?P{XSj85o+G7#M1q7#PwR85m|V zFfe>%WMBwkWMH@lieV&6YZw_AWEdG3vXR8TfSNQ63=B+Q^XeHGtU$Fn69a<-BLhPl zl0wjs6NoFo#K6!9YKVhMc}50?9wtb``T=M?BO?RD0R{$!rHl*=T?`Bixr_`9-Js?M zXtxL00tNovwgD69gL!pHMgC(ei2NDIX=mI%}k%8eZl0gBW zA_TNFnE|q*ry5j%Gcho@FflN2FflOLF)=V~gz5*atpsg50&Pjk1BEJRkq4;W1hopG zW-3AHzo7U(1LYJmGBD&aF)$Q@T6$2ir=US}Mh1qDP{WNG85r^z85j~785lM)GBBtx zF)*x!ss$-o0V1F{nUR6Pj*)?35mbIU0|Ub&(3)Ck2-|?-AEY)5RN;d5FM)RQFfcGI z1~o}R5}+0Wln!HHV9;b@V7LTYUd+V6Py(uW85kHsm>3vrm>3uYnHU&$F)}bbWMp8l zU}RwU%K+)J6f-d}=z>}UpsI<9fguCx7!6Qa0&0u}GeY_>^PmzIplkt36Htp`)H_B7 zhV7t)1XTwTuVrLlc!0zQiGeU^z6?Z5L4B&o$iVOx)TRP8O&Ay$=70uem_VyV>KPcs zpa#qY1t&-sC=@^i5GeRS2@f<0&&a^Aih+S)HB`Qwk%1wUiGe`?suv{ujFEw152&_) zi7_%TG%ztRL@`1-b09Tppo$%|KZ=Qg;R8qj)=2hbVqoZCWMDYQ$iPs*z`&3OGKh(R zp@oTop%T=d0VxLK$!$(<9BKJQxrrs3#ghvricju$=9v7|`PSt3F4H#8a*bx3%<66| z>XBKZP?VaJpO~UhlCMx&kdj!EsyI2oU1RfNcV(u@mfpsjA9(*{6iUi3Em0`R$ShXK z%quQQ%u7z4eBIZ1vW}m#Oj3S+b}@rvN{T{qepzY}m<3m~%`aoJn!n-ZM1N++$rl1L zIf|20^HMVN(kK54EMdzn$S*1>o}3aic{6A5Cq|y!g8brCh2oOLlG5VIKSHKVz80!B znKMj-Gf%-WIXS;HuVivq*xbqS;pUSUgnLb9iLjMWQz%N+O({xDD`9X+%}Fgug{qvK z5RpImOT_fab0W(oD@4gm4v3PSyd)}qGGDaPWb0`4$$8N+lW#>!bLXWffIQ9MnwK&; zEJk&6PRtHQMytslac+~P;^imX#fwi)j2E7KZjJclHSx3A1B&v~i&Bdx+a;KqBc$>$T&Wy(_XN)j`RQWZR1tQb7= z$}&q*6@pR=OH+$WiYHejPKov^%`E^$N=ZhlLQ;N7Nq(+EewqS^my=ms0+K0C%}GrL zMN6uJszzF3W=?8KJUEmzixo0UQge$H$}=*PGZY|FARU=tXX;JnPEw!jlH~4)5~DWy ziFSGnKBo;fimXY#Lt|C4!&Og6U^ZDgG6 zS|ZM9HF<7HCI=)KQ&T1jmp#`?_Njg`*{a53GE=SEWSiRl$;<1uPp+-k-2AiNlxeb6 z)91-H%|0w8nPsVyt6J1HSGDvpPX66$%$Al|mS2=P`F@Ma24QQ_E5nY2XsQ|0 z-RiuT{`*t{O--g3qCONJe#!PY1_=_UE7{D zG)_)h)HzvYvBKoQ#p-NNcT9NNzkTw&#j__bUSc@;-jblnPD^d2cW#3?_QlriFM2x} zo^~vFIdch2?b5W#TFa^@?_3r&S#G(E(6shv3l}py+py!wj^3wBHa?r$F}Ztr_GIQ2 zx|3~J=uR$Qkuv$+3W>>lE2Sq-S}Df5WaEo1OE)iAxss9n*@8V!_w-v$E?Mn5*>R2X z4Qwy=&wjdV+2qo-rt0f@o^?#HVt5Mn z=F>e5PnUOFF}&D6r(u>~Pj;+=So0L@o9DAy zUM}4EeD*q!mD=l7CMU0V4th4H^J(j5coaUL)$(Nj!e@=^K?T|4h9-t5yV_nXU;J$L zmZwW*;ZkeG@OX>(!l}uUVs@ssSy~6kaUsu|gDE#R|_l8(vJD z{(M#oo|0~}%myFE$qP4XPky{nSiXP4)BY}or>)J;rfzuFyN==c?1@j;&wn~`#*6hW zFV^jvT)C-Xve;(z$-bNOC*R&IE4XRlvpJp5`X@ZuH~ZPd886mt*zCN;nQ?O8*3XkW zw#{c--}Zb#qt#@)?dp>&wkJ*I-ciQ(bYH{M&fdw>b`)&p-6_V%_Ox~L^Ub>_oA1)t zT(WC1qsYtl-WThqLIRNC$dnIHR}u-9leMmCus@r-^hNtBg~=C-#V0?w$TC^}+LXz9m*a&R z=RBXXg5lYmhNlzyoHpt delta 27210 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 HP@e|?%*Yh9 diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo index baefb103cead9162e9927bcfbee60ac4ab807d82..f9ca27be9b891b3b13c30e68d084e0cd54184a43 100644 GIT binary patch delta 14268 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 delta 13392 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 F0RYvT_t^jd From 9961a08c936592c4f48b47c01053fabf4c3e6725 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 17 Nov 2021 10:02:39 -0800 Subject: [PATCH 127/134] Adds Galician locale --- .../0118_alter_user_preferred_language.py | 33 + bookwyrm/settings.py | 3 +- bw-dev | 1 + locale/fr_FR/LC_MESSAGES/django.mo | Bin 65002 -> 44850 bytes locale/gl_ES/LC_MESSAGES/django.mo | Bin 0 -> 43625 bytes locale/gl_ES/LC_MESSAGES/django.po | 3846 +++++++++++++++++ 6 files changed, 3882 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0118_alter_user_preferred_language.py create mode 100644 locale/gl_ES/LC_MESSAGES/django.mo create mode 100644 locale/gl_ES/LC_MESSAGES/django.po diff --git a/bookwyrm/migrations/0118_alter_user_preferred_language.py b/bookwyrm/migrations/0118_alter_user_preferred_language.py new file mode 100644 index 000000000..2019bb369 --- /dev/null +++ b/bookwyrm/migrations/0118_alter_user_preferred_language.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.5 on 2021-11-17 18:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0117_alter_user_preferred_language"), + ] + + operations = [ + migrations.AlterField( + model_name="user", + name="preferred_language", + field=models.CharField( + blank=True, + choices=[ + ("en-us", "English"), + ("de-de", "Deutsch (German)"), + ("es-es", "Español (Spanish)"), + ("gl-es", "Galego (Galician)"), + ("fr-fr", "Français (French)"), + ("lt-lt", "Lietuvių (Lithuanian)"), + ("pt-br", "Português - Brasil (Brazilian Portuguese)"), + ("zh-hans", "简体中文 (Simplified Chinese)"), + ("zh-hant", "繁體中文 (Traditional Chinese)"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/settings.py b/bookwyrm/settings.py index d469e6fe7..d6c0b5d5e 100644 --- a/bookwyrm/settings.py +++ b/bookwyrm/settings.py @@ -165,8 +165,9 @@ LANGUAGES = [ ("en-us", _("English")), ("de-de", _("Deutsch (German)")), ("es-es", _("Español (Spanish)")), + ("gl-es", _("Galego (Galician)")), ("fr-fr", _("Français (French)")), - ("lt-lt", _("lietuvių (Lithuanian)")), + ("lt-lt", _("Lietuvių (Lithuanian)")), ("pt-br", _("Português - Brasil (Brazilian Portuguese)")), ("zh-hans", _("简体中文 (Simplified Chinese)")), ("zh-hant", _("繁體中文 (Traditional Chinese)")), diff --git a/bw-dev b/bw-dev index 5da971705..75c69662b 100755 --- a/bw-dev +++ b/bw-dev @@ -113,6 +113,7 @@ case "$CMD" in git checkout l10n_main locale/de_DE git checkout l10n_main locale/es_ES git checkout l10n_main locale/fr_FR + git checkout l10n_main locale/gl_ES git checkout l10n_main locale/lt_LT git checkout l10n_main locale/pt_BR git checkout l10n_main locale/zh_Hans diff --git a/locale/fr_FR/LC_MESSAGES/django.mo b/locale/fr_FR/LC_MESSAGES/django.mo index 8696fb99d4fe41e6b3d7f2248ee170dcab6da7be..4cdcbf8ea2a3ffdeed740317a055f435e5954b7c 100644 GIT binary patch delta 16292 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 bJG>HPr$T97D%^5~l+?+gf2L1f^j8P~Hun!& literal 65002 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 UY0tE$Yo~)Z0E1e@SdM@N0I-w}dH?_b diff --git a/locale/gl_ES/LC_MESSAGES/django.mo b/locale/gl_ES/LC_MESSAGES/django.mo new file mode 100644 index 0000000000000000000000000000000000000000..149986eb7ed6ecd85ba1544e12c1b5bf7d5ac480 GIT binary patch literal 43625 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 IF-MaD05;pA@c;k- literal 0 HcmV?d00001 diff --git a/locale/gl_ES/LC_MESSAGES/django.po b/locale/gl_ES/LC_MESSAGES/django.po new file mode 100644 index 000000000..c1aee0316 --- /dev/null +++ b/locale/gl_ES/LC_MESSAGES/django.po @@ -0,0 +1,3846 @@ +msgid "" +msgstr "" +"Project-Id-Version: bookwyrm\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2021-11-14 15:08+0000\n" +"PO-Revision-Date: 2021-11-15 18:03\n" +"Last-Translator: Mouse Reeve \n" +"Language-Team: Galician\n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Crowdin-Project: bookwyrm\n" +"X-Crowdin-Project-ID: 479239\n" +"X-Crowdin-Language: gl\n" +"X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" +"X-Crowdin-File-ID: 1553\n" + +#: bookwyrm/forms.py:242 +msgid "A user with this email already exists." +msgstr "Xa existe unha unsuaria con este email." + +#: bookwyrm/forms.py:256 +msgid "One Day" +msgstr "Un día" + +#: bookwyrm/forms.py:257 +msgid "One Week" +msgstr "Unha semana" + +#: bookwyrm/forms.py:258 +msgid "One Month" +msgstr "Un mes" + +#: bookwyrm/forms.py:259 +msgid "Does Not Expire" +msgstr "Non caduca" + +#: bookwyrm/forms.py:263 +#, python-brace-format +msgid "{i} uses" +msgstr "{i} usos" + +#: bookwyrm/forms.py:264 +msgid "Unlimited" +msgstr "Sen límite" + +#: bookwyrm/forms.py:332 +msgid "List Order" +msgstr "Orde da listaxe" + +#: bookwyrm/forms.py:333 +msgid "Book Title" +msgstr "Título do libro" + +#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/templates/shelf/shelf.html:181 +#: bookwyrm/templates/snippets/create_status/review.html:33 +msgid "Rating" +msgstr "Puntuación" + +#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +msgid "Sort By" +msgstr "Ordenar por" + +#: bookwyrm/forms.py:340 +msgid "Ascending" +msgstr "Ascendente" + +#: bookwyrm/forms.py:341 +msgid "Descending" +msgstr "Descendente" + +#: bookwyrm/importers/importer.py:127 +msgid "Error loading book" +msgstr "Erro ao cargar o libro" + +#: bookwyrm/importers/importer.py:135 +msgid "Could not find a match for book" +msgstr "Non se atopan coincidencias para o libro" + +#: bookwyrm/models/base_model.py:17 +#: bookwyrm/templates/import/import_status.html:171 +msgid "Pending" +msgstr "Pendente" + +#: bookwyrm/models/base_model.py:18 +msgid "Self deletion" +msgstr "Auto eliminación" + +#: bookwyrm/models/base_model.py:19 +msgid "Moderator suspension" +msgstr "Suspendido pola moderación" + +#: bookwyrm/models/base_model.py:20 +msgid "Moderator deletion" +msgstr "Eliminado pola moderación" + +#: bookwyrm/models/base_model.py:21 +msgid "Domain block" +msgstr "Bloqueo de dominio" + +#: bookwyrm/models/book.py:233 +msgid "Audiobook" +msgstr "Audiolibro" + +#: bookwyrm/models/book.py:234 +msgid "eBook" +msgstr "eBook" + +#: bookwyrm/models/book.py:235 +msgid "Graphic novel" +msgstr "Novela gráfica" + +#: bookwyrm/models/book.py:236 +msgid "Hardcover" +msgstr "Portada dura" + +#: bookwyrm/models/book.py:237 +msgid "Paperback" +msgstr "En rústica" + +#: bookwyrm/models/federated_server.py:11 +#: bookwyrm/templates/settings/federation/edit_instance.html:42 +#: bookwyrm/templates/settings/federation/instance_list.html:19 +msgid "Federated" +msgstr "Federado" + +#: bookwyrm/models/federated_server.py:12 +#: bookwyrm/templates/settings/federation/edit_instance.html:43 +#: bookwyrm/templates/settings/federation/instance.html:10 +#: bookwyrm/templates/settings/federation/instance_list.html:23 +msgid "Blocked" +msgstr "Bloqueado" + +#: bookwyrm/models/fields.py:29 +#, python-format +msgid "%(value)s is not a valid remote_id" +msgstr "%(value)s non é un remote_id válido" + +#: bookwyrm/models/fields.py:38 bookwyrm/models/fields.py:47 +#, python-format +msgid "%(value)s is not a valid username" +msgstr "%(value)s non é un nome de usuaria válido" + +#: bookwyrm/models/fields.py:183 bookwyrm/templates/layout.html:171 +msgid "username" +msgstr "nome de usuaria" + +#: bookwyrm/models/fields.py:188 +msgid "A user with that username already exists." +msgstr "Xa existe unha usuaria con ese nome." + +#: bookwyrm/settings.py:118 +msgid "Home Timeline" +msgstr "Cronoloxía de Inicio" + +#: bookwyrm/settings.py:118 +msgid "Home" +msgstr "Inicio" + +#: bookwyrm/settings.py:119 +msgid "Books Timeline" +msgstr "Cronoloxía de libros" + +#: bookwyrm/settings.py:119 bookwyrm/templates/search/layout.html:21 +#: bookwyrm/templates/search/layout.html:42 +#: bookwyrm/templates/user/layout.html:88 +msgid "Books" +msgstr "Libros" + +#: bookwyrm/settings.py:165 +msgid "English" +msgstr "Inglés" + +#: bookwyrm/settings.py:166 +msgid "Deutsch (German)" +msgstr "Alemán (Alemaña)" + +#: bookwyrm/settings.py:167 +msgid "Español (Spanish)" +msgstr "Español (España)" + +#: bookwyrm/settings.py:168 +msgid "Français (French)" +msgstr "Francés (Francia)" + +#: bookwyrm/settings.py:169 +msgid "Português - Brasil (Brazilian Portuguese)" +msgstr "Portugués - Brasil (portugués brasileiro)" + +#: bookwyrm/settings.py:170 +msgid "简体中文 (Simplified Chinese)" +msgstr "简体中文 (Chinés simplificado)" + +#: bookwyrm/settings.py:171 +msgid "繁體中文 (Traditional Chinese)" +msgstr "繁體中文 (Chinés tradicional)" + +#: bookwyrm/templates/404.html:4 bookwyrm/templates/404.html:8 +msgid "Not Found" +msgstr "Non se atopa" + +#: bookwyrm/templates/404.html:9 +msgid "The page you requested doesn't seem to exist!" +msgstr "Parece que non existe a páxina solicitada!" + +#: bookwyrm/templates/500.html:4 +msgid "Oops!" +msgstr "Vaite!" + +#: bookwyrm/templates/500.html:8 +msgid "Server Error" +msgstr "Erro do servidor" + +#: bookwyrm/templates/500.html:9 +msgid "Something went wrong! Sorry about that." +msgstr "Algo fallou! Lamentámolo." + +#: bookwyrm/templates/author/author.html:17 +#: bookwyrm/templates/author/author.html:18 +msgid "Edit Author" +msgstr "Editar Autora" + +#: bookwyrm/templates/author/author.html:34 +#: bookwyrm/templates/author/edit_author.html:43 +msgid "Aliases:" +msgstr "Alias:" + +#: bookwyrm/templates/author/author.html:45 +msgid "Born:" +msgstr "Nacemento:" + +#: bookwyrm/templates/author/author.html:52 +msgid "Died:" +msgstr "Morte:" + +#: bookwyrm/templates/author/author.html:61 +msgid "Wikipedia" +msgstr "Wikipedia" + +#: bookwyrm/templates/author/author.html:69 +#: bookwyrm/templates/book/book.html:94 +msgid "View on OpenLibrary" +msgstr "Ver en OpenLibrary" + +#: bookwyrm/templates/author/author.html:77 +#: bookwyrm/templates/book/book.html:97 +msgid "View on Inventaire" +msgstr "Ver en Inventaire" + +#: bookwyrm/templates/author/author.html:85 +msgid "View on LibraryThing" +msgstr "Ver en LibraryThing" + +#: bookwyrm/templates/author/author.html:93 +msgid "View on Goodreads" +msgstr "Ver en Goodreads" + +#: bookwyrm/templates/author/author.html:108 +#, python-format +msgid "Books by %(name)s" +msgstr "Libros de %(name)s" + +#: bookwyrm/templates/author/edit_author.html:5 +msgid "Edit Author:" +msgstr "Editar autora:" + +#: bookwyrm/templates/author/edit_author.html:13 +#: bookwyrm/templates/book/edit/edit_book.html:18 +msgid "Added:" +msgstr "Engadida:" + +#: bookwyrm/templates/author/edit_author.html:14 +#: bookwyrm/templates/book/edit/edit_book.html:21 +msgid "Updated:" +msgstr "Actualizada:" + +#: bookwyrm/templates/author/edit_author.html:16 +#: bookwyrm/templates/book/edit/edit_book.html:25 +msgid "Last edited by:" +msgstr "Última edición por:" + +#: bookwyrm/templates/author/edit_author.html:33 +#: bookwyrm/templates/book/edit/edit_book_form.html:15 +msgid "Metadata" +msgstr "Metadatos" + +#: bookwyrm/templates/author/edit_author.html:35 +#: bookwyrm/templates/lists/form.html:9 bookwyrm/templates/shelf/form.html:9 +msgid "Name:" +msgstr "Nome:" + +#: bookwyrm/templates/author/edit_author.html:45 +#: bookwyrm/templates/book/edit/edit_book_form.html:65 +#: bookwyrm/templates/book/edit/edit_book_form.html:79 +#: bookwyrm/templates/book/edit/edit_book_form.html:124 +msgid "Separate multiple values with commas." +msgstr "Separa múltiples valores con vírgulas." + +#: bookwyrm/templates/author/edit_author.html:52 +msgid "Bio:" +msgstr "Bio:" + +#: bookwyrm/templates/author/edit_author.html:59 +msgid "Wikipedia link:" +msgstr "Ligazón a Wikipedia:" + +#: bookwyrm/templates/author/edit_author.html:65 +msgid "Birth date:" +msgstr "Data de nacemento:" + +#: bookwyrm/templates/author/edit_author.html:73 +msgid "Death date:" +msgstr "Data do falecemento:" + +#: bookwyrm/templates/author/edit_author.html:81 +msgid "Author Identifiers" +msgstr "Identificadores da autora" + +#: bookwyrm/templates/author/edit_author.html:83 +msgid "Openlibrary key:" +msgstr "Chave en Openlibrary:" + +#: bookwyrm/templates/author/edit_author.html:91 +#: bookwyrm/templates/book/edit/edit_book_form.html:224 +msgid "Inventaire ID:" +msgstr "ID en Inventaire:" + +#: bookwyrm/templates/author/edit_author.html:99 +msgid "Librarything key:" +msgstr "Chave en Librarything:" + +#: bookwyrm/templates/author/edit_author.html:107 +msgid "Goodreads key:" +msgstr "Chave en Goodreads:" + +#: bookwyrm/templates/author/edit_author.html:118 +#: bookwyrm/templates/book/book.html:140 +#: bookwyrm/templates/book/edit/edit_book.html:110 +#: bookwyrm/templates/book/readthrough.html:76 +#: bookwyrm/templates/groups/form.html:24 +#: bookwyrm/templates/lists/bookmark_button.html:15 +#: bookwyrm/templates/lists/form.html:75 +#: bookwyrm/templates/preferences/edit_user.html:124 +#: bookwyrm/templates/settings/announcements/announcement_form.html:69 +#: bookwyrm/templates/settings/federation/edit_instance.html:74 +#: bookwyrm/templates/settings/federation/instance.html:87 +#: bookwyrm/templates/settings/site.html:134 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:64 +#: bookwyrm/templates/shelf/form.html:25 +#: bookwyrm/templates/snippets/reading_modals/layout.html:18 +msgid "Save" +msgstr "Gardar" + +#: 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/readthrough.html:77 +#: bookwyrm/templates/groups/delete_group_modal.html:17 +#: bookwyrm/templates/lists/delete_list_modal.html:17 +#: bookwyrm/templates/settings/federation/instance.html:88 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 +#: bookwyrm/templates/snippets/report_modal.html:34 +msgid "Cancel" +msgstr "Cancelar" + +#: bookwyrm/templates/book/book.html:47 +#: bookwyrm/templates/discover/large-book.html:22 +#: bookwyrm/templates/landing/large-book.html:25 +#: bookwyrm/templates/landing/small-book.html:18 +msgid "by" +msgstr "por" + +#: bookwyrm/templates/book/book.html:55 bookwyrm/templates/book/book.html:56 +msgid "Edit Book" +msgstr "Editar libro" + +#: bookwyrm/templates/book/book.html:73 +#: bookwyrm/templates/book/cover_modal.html:5 +msgid "Add cover" +msgstr "Engadir portada" + +#: bookwyrm/templates/book/book.html:77 +msgid "Failed to load cover" +msgstr "Fallou a carga da portada" + +#: bookwyrm/templates/book/book.html:117 +#, python-format +msgid "(%(review_count)s review)" +msgid_plural "(%(review_count)s reviews)" +msgstr[0] "(%(review_count)s recensión)" +msgstr[1] "(%(review_count)s recensións)" + +#: bookwyrm/templates/book/book.html:129 +msgid "Add Description" +msgstr "Engadir descrición" + +#: bookwyrm/templates/book/book.html:136 +#: bookwyrm/templates/book/edit/edit_book_form.html:34 +#: bookwyrm/templates/lists/form.html:13 bookwyrm/templates/shelf/form.html:17 +msgid "Description:" +msgstr "Descrición:" + +#: bookwyrm/templates/book/book.html:150 +#, python-format +msgid "%(count)s editions" +msgstr "%(count)s edicións" + +#: bookwyrm/templates/book/book.html:158 +#, python-format +msgid "This edition is on your %(shelf_name)s shelf." +msgstr "Esta edición está no teu estante %(shelf_name)s." + +#: bookwyrm/templates/book/book.html:164 +#, python-format +msgid "A different edition of this book is on your %(shelf_name)s shelf." +msgstr "Hai unha edición diferente deste libro no teu estante %(shelf_name)s." + +#: bookwyrm/templates/book/book.html:175 +msgid "Your reading activity" +msgstr "Actividade lectora" + +#: bookwyrm/templates/book/book.html:178 +msgid "Add read dates" +msgstr "Engadir datas de lectura" + +#: bookwyrm/templates/book/book.html:187 +msgid "Create" +msgstr "Crear" + +#: bookwyrm/templates/book/book.html:197 +msgid "You don't have any reading activity for this book." +msgstr "Non tes actividade lectora neste libro." + +#: bookwyrm/templates/book/book.html:218 +msgid "Reviews" +msgstr "Recensións" + +#: bookwyrm/templates/book/book.html:223 +msgid "Your reviews" +msgstr "As túas recensións" + +#: bookwyrm/templates/book/book.html:229 +msgid "Your comments" +msgstr "Os teus comentarios" + +#: bookwyrm/templates/book/book.html:235 +msgid "Your quotes" +msgstr "As túas citas" + +#: bookwyrm/templates/book/book.html:271 +msgid "Subjects" +msgstr "Temas" + +#: bookwyrm/templates/book/book.html:283 +msgid "Places" +msgstr "Lugares" + +#: bookwyrm/templates/book/book.html:294 bookwyrm/templates/layout.html:75 +#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12 +#: bookwyrm/templates/search/layout.html:25 +#: bookwyrm/templates/search/layout.html:50 +#: bookwyrm/templates/user/layout.html:82 +msgid "Lists" +msgstr "Listaxes" + +#: bookwyrm/templates/book/book.html:305 +msgid "Add to list" +msgstr "Engadir a listaxe" + +#: bookwyrm/templates/book/book.html:315 +#: bookwyrm/templates/book/cover_modal.html:31 +#: bookwyrm/templates/lists/list.html:182 +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:26 +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:32 +msgid "Add" +msgstr "Engadir" + +#: bookwyrm/templates/book/book_identifiers.html:8 +msgid "ISBN:" +msgstr "ISBN:" + +#: bookwyrm/templates/book/book_identifiers.html:15 +#: bookwyrm/templates/book/edit/edit_book_form.html:232 +msgid "OCLC Number:" +msgstr "Número OCLC:" + +#: bookwyrm/templates/book/book_identifiers.html:22 +#: bookwyrm/templates/book/edit/edit_book_form.html:240 +msgid "ASIN:" +msgstr "ASIN:" + +#: bookwyrm/templates/book/cover_modal.html:17 +#: bookwyrm/templates/book/edit/edit_book_form.html:143 +msgid "Upload cover:" +msgstr "Subir portada:" + +#: bookwyrm/templates/book/cover_modal.html:23 +#: bookwyrm/templates/book/edit/edit_book_form.html:148 +msgid "Load cover from url:" +msgstr "Cargar portada desde url:" + +#: bookwyrm/templates/book/edit/edit_book.html:5 +#: bookwyrm/templates/book/edit/edit_book.html:11 +#, python-format +msgid "Edit \"%(book_title)s\"" +msgstr "Editar \"%(book_title)s\"" + +#: bookwyrm/templates/book/edit/edit_book.html:5 +#: bookwyrm/templates/book/edit/edit_book.html:13 +msgid "Add Book" +msgstr "Engadir libro" + +#: bookwyrm/templates/book/edit/edit_book.html:47 +msgid "Confirm Book Info" +msgstr "Confirma info do libro" + +#: bookwyrm/templates/book/edit/edit_book.html:55 +#, python-format +msgid "Is \"%(name)s\" an existing author?" +msgstr "É \"%(name)s\" unha autora existente?" + +#: bookwyrm/templates/book/edit/edit_book.html:64 +#, python-format +msgid "Author of %(book_title)s" +msgstr "Autora de %(book_title)s" + +#: bookwyrm/templates/book/edit/edit_book.html:68 +msgid "This is a new author" +msgstr "Esta é unha nova autora" + +#: bookwyrm/templates/book/edit/edit_book.html:75 +#, python-format +msgid "Creating a new author: %(name)s" +msgstr "Creando nova autora: %(name)s" + +#: bookwyrm/templates/book/edit/edit_book.html:82 +msgid "Is this an edition of an existing work?" +msgstr "É esta a edición dun traballo existente?" + +#: bookwyrm/templates/book/edit/edit_book.html:90 +msgid "This is a new work" +msgstr "Este é un novo traballo" + +#: bookwyrm/templates/book/edit/edit_book.html:97 +#: 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 "Confirmar" + +#: bookwyrm/templates/book/edit/edit_book.html:99 +#: bookwyrm/templates/feed/status.html:9 +msgid "Back" +msgstr "Atrás" + +#: bookwyrm/templates/book/edit/edit_book_form.html:18 +#: bookwyrm/templates/snippets/create_status/review.html:16 +msgid "Title:" +msgstr "Título:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:26 +msgid "Subtitle:" +msgstr "Subtítulo:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:44 +msgid "Series:" +msgstr "Serie:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:53 +msgid "Series number:" +msgstr "Número da serie:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:63 +msgid "Languages:" +msgstr "Idiomas:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:74 +msgid "Publication" +msgstr "Publicación" + +#: bookwyrm/templates/book/edit/edit_book_form.html:77 +msgid "Publisher:" +msgstr "Editorial:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:86 +msgid "First published date:" +msgstr "Data da primeira edición:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:94 +msgid "Published date:" +msgstr "Data de publicación:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:104 +msgid "Authors" +msgstr "Autoras" + +#: bookwyrm/templates/book/edit/edit_book_form.html:112 +#, python-format +msgid "Remove %(name)s" +msgstr "Eliminar %(name)s" + +#: bookwyrm/templates/book/edit/edit_book_form.html:115 +#, python-format +msgid "Author page for %(name)s" +msgstr "Páxina de autora para %(name)s" + +#: bookwyrm/templates/book/edit/edit_book_form.html:122 +msgid "Add Authors:" +msgstr "Engadir autoras:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:123 +msgid "John Doe, Jane Smith" +msgstr "Xoán Díaz, Noela Rubio" + +#: bookwyrm/templates/book/edit/edit_book_form.html:132 +#: bookwyrm/templates/shelf/shelf.html:140 +msgid "Cover" +msgstr "Portada" + +#: bookwyrm/templates/book/edit/edit_book_form.html:161 +msgid "Physical Properties" +msgstr "Propiedades físicas" + +#: bookwyrm/templates/book/edit/edit_book_form.html:166 +#: bookwyrm/templates/book/editions/format_filter.html:5 +msgid "Format:" +msgstr "Formato:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:177 +msgid "Format details:" +msgstr "Detalles do formato:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:187 +msgid "Pages:" +msgstr "Páxinas:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:197 +msgid "Book Identifiers" +msgstr "Identificadores do libro" + +#: bookwyrm/templates/book/edit/edit_book_form.html:200 +msgid "ISBN 13:" +msgstr "ISBN 13:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:208 +msgid "ISBN 10:" +msgstr "ISBN 10:" + +#: bookwyrm/templates/book/edit/edit_book_form.html:216 +msgid "Openlibrary ID:" +msgstr "ID en Openlibrary:" + +#: bookwyrm/templates/book/editions/editions.html:4 +#, python-format +msgid "Editions of %(book_title)s" +msgstr "Edicións de %(book_title)s" + +#: bookwyrm/templates/book/editions/editions.html:8 +#, python-format +msgid "Editions of \"%(work_title)s\"" +msgstr "Edicións de %(work_title)s" + +#: bookwyrm/templates/book/editions/format_filter.html:8 +#: bookwyrm/templates/book/editions/language_filter.html:8 +msgid "Any" +msgstr "Calquera" + +#: bookwyrm/templates/book/editions/language_filter.html:5 +#: bookwyrm/templates/preferences/edit_user.html:95 +msgid "Language:" +msgstr "Idioma:" + +#: bookwyrm/templates/book/editions/search_filter.html:5 +msgid "Search editions" +msgstr "Buscar edicións" + +#: bookwyrm/templates/book/publisher_info.html:23 +#, python-format +msgid "%(format)s, %(pages)s pages" +msgstr "%(format)s, %(pages)s páxinas" + +#: bookwyrm/templates/book/publisher_info.html:25 +#, python-format +msgid "%(pages)s pages" +msgstr "%(pages)s páxinas" + +#: bookwyrm/templates/book/publisher_info.html:38 +#, python-format +msgid "%(languages)s language" +msgstr "idioma %(languages)s" + +#: bookwyrm/templates/book/publisher_info.html:65 +#, python-format +msgid "Published %(date)s by %(publisher)s." +msgstr "Publicado en %(date)s por %(publisher)s." + +#: bookwyrm/templates/book/publisher_info.html:67 +#, python-format +msgid "Published %(date)s" +msgstr "Publicado en %(date)s" + +#: bookwyrm/templates/book/publisher_info.html:69 +#, python-format +msgid "Published by %(publisher)s." +msgstr "Publicado por %(publisher)s." + +#: bookwyrm/templates/book/rating.html:13 +msgid "rated it" +msgstr "valorouno" + +#: bookwyrm/templates/book/readthrough.html:8 +msgid "Progress Updates:" +msgstr "Actualizacións da lectura:" + +#: bookwyrm/templates/book/readthrough.html:13 +msgid "finished" +msgstr "rematado" + +#: bookwyrm/templates/book/readthrough.html:24 +msgid "Show all updates" +msgstr "Mostrar tódalas actualizacións" + +#: bookwyrm/templates/book/readthrough.html:40 +msgid "Delete this progress update" +msgstr "Eliminar esta actualización da lectura" + +#: bookwyrm/templates/book/readthrough.html:51 +msgid "started" +msgstr "iniciado" + +#: bookwyrm/templates/book/readthrough.html:58 +#: bookwyrm/templates/book/readthrough.html:72 +msgid "Edit read dates" +msgstr "Editar datas da lectura" + +#: bookwyrm/templates/book/readthrough.html:62 +msgid "Delete these read dates" +msgstr "Eliminar estas datas da lectura" + +#: bookwyrm/templates/components/inline_form.html:8 +#: bookwyrm/templates/components/modal.html:11 +#: bookwyrm/templates/components/tooltip.html:7 +#: bookwyrm/templates/feed/layout.html:71 +#: bookwyrm/templates/get_started/layout.html:20 +#: bookwyrm/templates/get_started/layout.html:53 +#: bookwyrm/templates/search/book.html:49 +#: bookwyrm/templates/snippets/announcement.html:18 +msgid "Close" +msgstr "Pechar" + +#: bookwyrm/templates/components/tooltip.html:3 +msgid "Help" +msgstr "Axuda" + +#: bookwyrm/templates/compose.html:5 bookwyrm/templates/compose.html:8 +msgid "Edit status" +msgstr "Editar estado" + +#: bookwyrm/templates/confirm_email/confirm_email.html:4 +msgid "Confirm email" +msgstr "Confirmar email" + +#: bookwyrm/templates/confirm_email/confirm_email.html:7 +msgid "Confirm your email address" +msgstr "Confirma o enderezo do teu email" + +#: bookwyrm/templates/confirm_email/confirm_email.html:13 +msgid "A confirmation code has been sent to the email address you used to register your account." +msgstr "Enviámosche un código de confirmación ao enderezo de email que usaches ao rexistrar a túa conta." + +#: bookwyrm/templates/confirm_email/confirm_email.html:15 +msgid "Sorry! We couldn't find that code." +msgstr "Lamentámolo! Non puidemos atopar ese código." + +#: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/settings/users/user_info.html:85 +msgid "Confirmation code:" +msgstr "Código de confirmación:" + +#: bookwyrm/templates/confirm_email/confirm_email.html:25 +#: bookwyrm/templates/landing/layout.html:73 +#: bookwyrm/templates/settings/dashboard/dashboard.html:93 +#: bookwyrm/templates/snippets/report_modal.html:33 +msgid "Submit" +msgstr "Enviar" + +#: bookwyrm/templates/confirm_email/confirm_email.html:32 +msgid "Can't find your code?" +msgstr "Non atopas o código?" + +#: bookwyrm/templates/confirm_email/resend_form.html:4 +msgid "Resend confirmation link" +msgstr "Reenviar ligazón de confirmación" + +#: bookwyrm/templates/confirm_email/resend_form.html:11 +#: bookwyrm/templates/landing/layout.html:67 +#: bookwyrm/templates/landing/password_reset_request.html:18 +#: bookwyrm/templates/preferences/edit_user.html:56 +#: bookwyrm/templates/snippets/register_form.html:13 +msgid "Email address:" +msgstr "Enderezo de email:" + +#: bookwyrm/templates/confirm_email/resend_form.html:17 +msgid "Resend link" +msgstr "Reenviar ligazón" + +#: bookwyrm/templates/directory/community_filter.html:5 +msgid "Community" +msgstr "Comunidade" + +#: bookwyrm/templates/directory/community_filter.html:8 +msgid "Local users" +msgstr "Usuarias locais" + +#: bookwyrm/templates/directory/community_filter.html:12 +msgid "Federated community" +msgstr "Comunidade federada" + +#: bookwyrm/templates/directory/directory.html:4 +#: bookwyrm/templates/directory/directory.html:9 +#: bookwyrm/templates/layout.html:101 +msgid "Directory" +msgstr "Directorio" + +#: bookwyrm/templates/directory/directory.html:17 +msgid "Make your profile discoverable to other BookWyrm users." +msgstr "Permite que outras usuarias de BookWyrm poidan descubrir o teu perfil." + +#: bookwyrm/templates/directory/directory.html:24 +#, python-format +msgid "You can opt-out at any time in your profile settings." +msgstr "Podes retirar o permiso en calquera momento nos axustes do perfil." + +#: bookwyrm/templates/directory/directory.html:29 +#: bookwyrm/templates/feed/goal_card.html:17 +#: bookwyrm/templates/snippets/announcement.html:34 +msgid "Dismiss message" +msgstr "Desbotar mensaxe" + +#: bookwyrm/templates/directory/sort_filter.html:5 +msgid "Order by" +msgstr "Orde por" + +#: bookwyrm/templates/directory/sort_filter.html:8 +msgid "Recently active" +msgstr "Actividade recente" + +#: bookwyrm/templates/directory/sort_filter.html:9 +msgid "Suggested" +msgstr "Suxerido" + +#: bookwyrm/templates/directory/user_card.html:17 +#: bookwyrm/templates/directory/user_card.html:18 +#: bookwyrm/templates/user/user_preview.html:16 +#: bookwyrm/templates/user/user_preview.html:17 +msgid "Locked account" +msgstr "Conta bloqueada" + +#: bookwyrm/templates/directory/user_card.html:40 +msgid "follower you follow" +msgid_plural "followers you follow" +msgstr[0] "seguidora que segues" +msgstr[1] "seguidoras que segues" + +#: bookwyrm/templates/directory/user_card.html:47 +msgid "book on your shelves" +msgid_plural "books on your shelves" +msgstr[0] "libro nos teus estantes" +msgstr[1] "libros nos teus estantes" + +#: bookwyrm/templates/directory/user_card.html:55 +msgid "posts" +msgstr "publicacións" + +#: bookwyrm/templates/directory/user_card.html:61 +msgid "last active" +msgstr "último activo" + +#: bookwyrm/templates/directory/user_type_filter.html:5 +msgid "User type" +msgstr "Tipo de usuaria" + +#: bookwyrm/templates/directory/user_type_filter.html:8 +msgid "BookWyrm users" +msgstr "Usuarias BookWyrm" + +#: bookwyrm/templates/directory/user_type_filter.html:12 +msgid "All known users" +msgstr "Tódalas usuarias coñecidas" + +#: bookwyrm/templates/discover/card-header.html:8 +#, python-format +msgid "%(username)s wants to read %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:13 +#, python-format +msgid "%(username)s finished reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:18 +#, python-format +msgid "%(username)s started reading %(book_title)s" +msgstr "" + +#: bookwyrm/templates/discover/card-header.html:23 +#, python-format +msgid "%(username)s rated %(book_title)s" +msgstr "%(username)s valorou %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:27 +#, python-format +msgid "%(username)s reviewed %(book_title)s" +msgstr "%(username)s fixo a recensión de %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:31 +#, python-format +msgid "%(username)s commented on %(book_title)s" +msgstr "%(username)s comentou %(book_title)s" + +#: bookwyrm/templates/discover/card-header.html:35 +#, python-format +msgid "%(username)s quoted %(book_title)s" +msgstr "%(username)s citou %(book_title)s" + +#: bookwyrm/templates/discover/discover.html:4 +#: bookwyrm/templates/discover/discover.html:10 +#: bookwyrm/templates/layout.html:78 +msgid "Discover" +msgstr "Descubrir" + +#: bookwyrm/templates/discover/discover.html:12 +#, python-format +msgid "See what's new in the local %(site_name)s community" +msgstr "Olla as novidades na comunidade local de %(site_name)s" + +#: bookwyrm/templates/discover/large-book.html:52 +#: bookwyrm/templates/discover/small-book.html:36 +msgid "View status" +msgstr "Ver estado" + +#: bookwyrm/templates/email/confirm/html_content.html:6 +#: bookwyrm/templates/email/confirm/text_content.html:4 +#, python-format +msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:" +msgstr "Un último chanzo antes de unirte a %(site_name)s! Confirma o teu enderezo de email premendo na ligazón inferior:" + +#: bookwyrm/templates/email/confirm/html_content.html:11 +msgid "Confirm Email" +msgstr "Confirmar email" + +#: bookwyrm/templates/email/confirm/html_content.html:15 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "Ou escribe o código \"%(confirmation_code)s\" na páxina de conexión." + +#: bookwyrm/templates/email/confirm/subject.html:2 +msgid "Please confirm your email" +msgstr "Por favor confirma o teu email" + +#: bookwyrm/templates/email/confirm/text_content.html:10 +#, python-format +msgid "Or enter the code \"%(confirmation_code)s\" at login." +msgstr "Ou escribe o código \"%(confirmation_code)s\" na páxina de conexión." + +#: bookwyrm/templates/email/html_layout.html:15 +#: bookwyrm/templates/email/text_layout.html:2 +msgid "Hi there," +msgstr "Ola," + +#: bookwyrm/templates/email/html_layout.html:21 +#, python-format +msgid "BookWyrm hosted on %(site_name)s" +msgstr "BookWyrm hospedado en %(site_name)s" + +#: bookwyrm/templates/email/html_layout.html:23 +msgid "Email preference" +msgstr "Preferencia do email" + +#: bookwyrm/templates/email/invite/html_content.html:6 +#: bookwyrm/templates/email/invite/subject.html:2 +#, python-format +msgid "You're invited to join %(site_name)s!" +msgstr "Foches convidada a %(site_name)s!" + +#: bookwyrm/templates/email/invite/html_content.html:9 +msgid "Join Now" +msgstr "Únete agora" + +#: bookwyrm/templates/email/invite/html_content.html:15 +#, python-format +msgid "Learn more about %(site_name)s." +msgstr "Coñece máis acerca de %(site_name)s." + +#: bookwyrm/templates/email/invite/text_content.html:4 +#, python-format +msgid "You're invited to join %(site_name)s! Click the link below to create an account." +msgstr "Foches convidada a unirte a %(site_name)s! Preme na ligazón para crear unha conta." + +#: bookwyrm/templates/email/invite/text_content.html:8 +#, python-format +msgid "Learn more about %(site_name)s:" +msgstr "Coñece máis acerca de %(site_name)s:" + +#: bookwyrm/templates/email/password_reset/html_content.html:6 +#: bookwyrm/templates/email/password_reset/text_content.html:4 +#, python-format +msgid "You requested to reset your %(site_name)s password. Click the link below to set a new password and log in to your account." +msgstr "Solicitaches restablecer o contrasinal en %(site_name)s. Preme na ligazón para establecer un novo contrasinal e conectarte á túa conta." + +#: bookwyrm/templates/email/password_reset/html_content.html:9 +#: bookwyrm/templates/landing/password_reset.html:4 +#: bookwyrm/templates/landing/password_reset.html:10 +#: bookwyrm/templates/landing/password_reset_request.html:4 +#: bookwyrm/templates/landing/password_reset_request.html:10 +msgid "Reset Password" +msgstr "Restablecer contrasinal" + +#: bookwyrm/templates/email/password_reset/html_content.html:13 +#: bookwyrm/templates/email/password_reset/text_content.html:8 +msgid "If you didn't request to reset your password, you can ignore this email." +msgstr "Se non solicitaches cambiar o contrasinal podes ignorar este email." + +#: bookwyrm/templates/email/password_reset/subject.html:2 +#, python-format +msgid "Reset your %(site_name)s password" +msgstr "Restablece o contrasinal en %(site_name)s" + +#: bookwyrm/templates/feed/direct_messages.html:8 +#, python-format +msgid "Direct Messages with %(username)s" +msgstr "Mensaxes Directas con %(username)s" + +#: bookwyrm/templates/feed/direct_messages.html:10 +#: bookwyrm/templates/layout.html:111 +msgid "Direct Messages" +msgstr "Mensaxes Directas" + +#: bookwyrm/templates/feed/direct_messages.html:13 +msgid "All messages" +msgstr "Tódalas mensaxes" + +#: bookwyrm/templates/feed/direct_messages.html:22 +msgid "You have no messages right now." +msgstr "Non tes mensaxes por agora." + +#: bookwyrm/templates/feed/feed.html:22 +#, python-format +msgid "load 0 unread status(es)" +msgstr "cargar 0 estado(s) non lidos" + +#: bookwyrm/templates/feed/feed.html:38 +msgid "There aren't any activities right now! Try following a user to get started" +msgstr "Non hai actividade por agora! Proba a seguir algunha persoa para comezar" + +#: bookwyrm/templates/feed/goal_card.html:6 +#: bookwyrm/templates/feed/layout.html:90 +#: bookwyrm/templates/user/goal_form.html:6 +#, python-format +msgid "%(year)s Reading Goal" +msgstr "%(year)s Obxectivo de lectura" + +#: bookwyrm/templates/feed/goal_card.html:18 +#, python-format +msgid "You can set or change your reading goal any time from your profile page" +msgstr "Podes establecer ou cambiar un obxectivo de lectura en calquera momento desde a túa páxina de perfil" + +#: bookwyrm/templates/feed/layout.html:5 +msgid "Updates" +msgstr "Actualizacións" + +#: bookwyrm/templates/feed/layout.html:12 bookwyrm/templates/layout.html:106 +msgid "Your Books" +msgstr "Os teus libros" + +#: bookwyrm/templates/feed/layout.html:14 +msgid "There are no books here right now! Try searching for a book to get started" +msgstr "Aínda non tes libros! Busca algún co que comezar" + +#: bookwyrm/templates/feed/layout.html:25 +#: bookwyrm/templates/shelf/shelf.html:38 +#: bookwyrm/templates/user/books_header.html:4 +msgid "To Read" +msgstr "Pendentes" + +#: bookwyrm/templates/feed/layout.html:26 +#: bookwyrm/templates/shelf/shelf.html:40 +#: bookwyrm/templates/user/books_header.html:6 +msgid "Currently Reading" +msgstr "Lectura actual" + +#: bookwyrm/templates/feed/layout.html:27 +#: bookwyrm/templates/shelf/shelf.html:42 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:23 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 +#: bookwyrm/templates/user/books_header.html:8 +msgid "Read" +msgstr "Lido" + +#: bookwyrm/templates/feed/suggested_users.html:5 +#: bookwyrm/templates/get_started/users.html:6 +msgid "Who to follow" +msgstr "A quen seguir" + +#: bookwyrm/templates/feed/suggested_users.html:9 +msgid "Don't show suggested users" +msgstr "Non mostrar suxestións" + +#: bookwyrm/templates/feed/suggested_users.html:14 +msgid "View directory" +msgstr "Ver directorio" + +#: bookwyrm/templates/get_started/book_preview.html:6 +#, python-format +msgid "Have you read %(book_title)s?" +msgstr "Liches %(book_title)s?" + +#: bookwyrm/templates/get_started/books.html:6 +msgid "What are you reading?" +msgstr "Que estás a ler?" + +#: bookwyrm/templates/get_started/books.html:9 +#: bookwyrm/templates/layout.html:45 bookwyrm/templates/lists/list.html:138 +msgid "Search for a book" +msgstr "Buscar un libro" + +#: bookwyrm/templates/get_started/books.html:11 +#, python-format +msgid "No books found for \"%(query)s\"" +msgstr "Non se atopan libros con \"%(query)s\"" + +#: bookwyrm/templates/get_started/books.html:11 +#, python-format +msgid "You can add books when you start using %(site_name)s." +msgstr "Podes engadir libros cando comeces a usar %(site_name)s." + +#: bookwyrm/templates/get_started/books.html:16 +#: bookwyrm/templates/get_started/books.html:17 +#: bookwyrm/templates/get_started/users.html:18 +#: bookwyrm/templates/get_started/users.html:19 +#: bookwyrm/templates/groups/group.html:19 +#: bookwyrm/templates/groups/group.html:20 bookwyrm/templates/layout.html:51 +#: bookwyrm/templates/layout.html:52 bookwyrm/templates/lists/list.html:142 +#: bookwyrm/templates/search/layout.html:4 +#: bookwyrm/templates/search/layout.html:9 +msgid "Search" +msgstr "Buscar" + +#: bookwyrm/templates/get_started/books.html:27 +msgid "Suggested Books" +msgstr "Libros suxeridos" + +#: bookwyrm/templates/get_started/books.html:46 +#, python-format +msgid "Popular on %(site_name)s" +msgstr "Populares en %(site_name)s" + +#: bookwyrm/templates/get_started/books.html:58 +#: bookwyrm/templates/lists/list.html:155 +msgid "No books found" +msgstr "Non se atopan libros" + +#: bookwyrm/templates/get_started/books.html:63 +#: bookwyrm/templates/get_started/profile.html:54 +msgid "Save & continue" +msgstr "Gardar & continuar" + +#: bookwyrm/templates/get_started/layout.html:5 +#: bookwyrm/templates/landing/layout.html:5 +msgid "Welcome" +msgstr "Benvida" + +#: bookwyrm/templates/get_started/layout.html:15 +#, python-format +msgid "Welcome to %(site_name)s!" +msgstr "Sexas ben vida a %(site_name)s!" + +#: bookwyrm/templates/get_started/layout.html:17 +msgid "These are some first steps to get you started." +msgstr "Aquí tes unhas endereitas para ir aprendendo." + +#: bookwyrm/templates/get_started/layout.html:31 +#: bookwyrm/templates/get_started/profile.html:6 +msgid "Create your profile" +msgstr "Crea o teu perfil" + +#: bookwyrm/templates/get_started/layout.html:35 +msgid "Add books" +msgstr "Engade libros" + +#: bookwyrm/templates/get_started/layout.html:39 +msgid "Find friends" +msgstr "Atopa amizades" + +#: bookwyrm/templates/get_started/layout.html:45 +msgid "Skip this step" +msgstr "Omitir este paso" + +#: bookwyrm/templates/get_started/layout.html:49 +msgid "Finish" +msgstr "Rematar" + +#: bookwyrm/templates/get_started/profile.html:15 +#: bookwyrm/templates/preferences/edit_user.html:42 +msgid "Display name:" +msgstr "Nome público:" + +#: bookwyrm/templates/get_started/profile.html:22 +#: bookwyrm/templates/preferences/edit_user.html:49 +msgid "Summary:" +msgstr "Resumo:" + +#: bookwyrm/templates/get_started/profile.html:23 +msgid "A little bit about you" +msgstr "Algo acerca de ti" + +#: bookwyrm/templates/get_started/profile.html:32 +#: bookwyrm/templates/preferences/edit_user.html:27 +msgid "Avatar:" +msgstr "Avatar:" + +#: bookwyrm/templates/get_started/profile.html:42 +#: bookwyrm/templates/preferences/edit_user.html:110 +msgid "Manually approve followers:" +msgstr "Aprobar seguimentos manualmente:" + +#: bookwyrm/templates/get_started/profile.html:48 +#: bookwyrm/templates/preferences/edit_user.html:80 +msgid "Show this account in suggested users:" +msgstr "Mostar esta conta en usuarias suxeridas:" + +#: bookwyrm/templates/get_started/profile.html:52 +msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." +msgstr "A túa conta aparecerá no directorio e pode ser recomendada a outras usuarias de BookWyrm." + +#: bookwyrm/templates/get_started/users.html:11 +msgid "Search for a user" +msgstr "Buscar usuarias" + +#: bookwyrm/templates/get_started/users.html:13 +#, python-format +msgid "No users found for \"%(query)s\"" +msgstr "Non se atopan usuarias para \"%(query)s\"" + +#: bookwyrm/templates/groups/create_form.html:5 +msgid "Create Group" +msgstr "Crear grupo" + +#: bookwyrm/templates/groups/created_text.html:4 +#, python-format +msgid "Managed by %(username)s" +msgstr "Xestionado por %(username)s" + +#: bookwyrm/templates/groups/delete_group_modal.html:4 +msgid "Delete this group?" +msgstr "Eliminar este grupo?" + +#: bookwyrm/templates/groups/delete_group_modal.html:7 +#: bookwyrm/templates/lists/delete_list_modal.html:7 +msgid "This action cannot be un-done" +msgstr "Esta acción non ten volta atrás" + +#: bookwyrm/templates/groups/delete_group_modal.html:15 +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcements/announcement.html:20 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:49 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:36 +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 +#: bookwyrm/templates/snippets/follow_request_buttons.html:12 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:13 +msgid "Delete" +msgstr "Eliminar" + +#: bookwyrm/templates/groups/edit_form.html:5 +msgid "Edit Group" +msgstr "Editar grupo" + +#: bookwyrm/templates/groups/find_users.html:6 +msgid "Add new members!" +msgstr "Engadir novos membros!" + +#: bookwyrm/templates/groups/form.html:8 +msgid "Group Name:" +msgstr "Nome do grupo:" + +#: bookwyrm/templates/groups/form.html:12 +msgid "Group Description:" +msgstr "Descrición do grupo:" + +#: bookwyrm/templates/groups/form.html:30 +msgid "Delete group" +msgstr "Eliminar grupo" + +#: bookwyrm/templates/groups/group.html:15 +msgid "Search to add a user" +msgstr "Buscar para engadir usuaria" + +#: bookwyrm/templates/groups/group.html:36 +msgid "This group has no lists" +msgstr "Este grupo non ten listaxes" + +#: bookwyrm/templates/groups/layout.html:16 +msgid "Edit group" +msgstr "Editar grupo" + +#: bookwyrm/templates/groups/members.html:8 +msgid "Members can add and remove books on a group's book lists" +msgstr "Os membros poden engadir e eliminar libros nas listaxes do grupo" + +#: bookwyrm/templates/groups/members.html:19 +msgid "Leave group" +msgstr "Saír do grupo" + +#: bookwyrm/templates/groups/members.html:41 +#: bookwyrm/templates/groups/suggested_users.html:32 +#: bookwyrm/templates/snippets/suggested_users.html:31 +#: bookwyrm/templates/user/user_preview.html:36 +msgid "Follows you" +msgstr "Séguete" + +#: bookwyrm/templates/groups/suggested_users.html:17 +#: bookwyrm/templates/snippets/suggested_users.html:16 +#, python-format +msgid "%(mutuals)s follower you follow" +msgid_plural "%(mutuals)s followers you follow" +msgstr[0] "%(mutuals)s seguidora que segues" +msgstr[1] "%(mutuals)s seguidoras que segues" + +#: bookwyrm/templates/groups/suggested_users.html:24 +#: bookwyrm/templates/snippets/suggested_users.html:23 +#, python-format +msgid "%(shared_books)s book on your shelves" +msgid_plural "%(shared_books)s books on your shelves" +msgstr[0] "%(shared_books)s libro nos teus estantes" +msgstr[1] "%(shared_books)s libros nos teus estantes" + +#: bookwyrm/templates/groups/suggested_users.html:40 +#, python-format +msgid "No potential members found for \"%(user_query)s\"" +msgstr "Non se atopan potenciais membros para \"%(user_query)s\"" + +#: bookwyrm/templates/groups/user_groups.html:15 +msgid "Manager" +msgstr "Xestora" + +#: bookwyrm/templates/import/import.html:5 +#: bookwyrm/templates/import/import.html:9 +#: bookwyrm/templates/shelf/shelf.html:61 +msgid "Import Books" +msgstr "Importar libros" + +#: bookwyrm/templates/import/import.html:18 +msgid "Data source:" +msgstr "Fonte de datos:" + +#: bookwyrm/templates/import/import.html:37 +msgid "Data file:" +msgstr "Ficheiro de datos:" + +#: bookwyrm/templates/import/import.html:45 +msgid "Include reviews" +msgstr "Incluir recensións" + +#: bookwyrm/templates/import/import.html:50 +msgid "Privacy setting for imported reviews:" +msgstr "Axuste de privacidade para recensións importadas:" + +#: bookwyrm/templates/import/import.html:56 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:64 +msgid "Import" +msgstr "Importar" + +#: bookwyrm/templates/import/import.html:61 +msgid "Recent Imports" +msgstr "Importacións recentes" + +#: bookwyrm/templates/import/import.html:63 +msgid "No recent imports" +msgstr "Sen importacións recentes" + +#: bookwyrm/templates/import/import_status.html:6 +#: bookwyrm/templates/import/import_status.html:15 +#: bookwyrm/templates/import/import_status.html:29 +msgid "Import Status" +msgstr "Estado da importación" + +#: bookwyrm/templates/import/import_status.html:13 +#: bookwyrm/templates/import/import_status.html:27 +msgid "Retry Status" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:22 +msgid "Imports" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:39 +msgid "Import started:" +msgstr "Importación iniciada:" + +#: bookwyrm/templates/import/import_status.html:48 +msgid "In progress" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:50 +msgid "Refresh" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:62 +#, python-format +msgid "%(display_counter)s item needs manual approval." +msgid_plural "%(display_counter)s items need manual approval." +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/manual_review.html:8 +msgid "Review items" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:73 +#, python-format +msgid "%(display_counter)s item failed to import." +msgid_plural "%(display_counter)s items failed to import." +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/import/import_status.html:79 +msgid "View and troubleshoot failed items" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:91 +msgid "Row" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/shelf/shelf.html:141 +#: bookwyrm/templates/shelf/shelf.html:163 +msgid "Title" +msgstr "Título" + +#: bookwyrm/templates/import/import_status.html:97 +msgid "ISBN" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/shelf/shelf.html:142 +#: bookwyrm/templates/shelf/shelf.html:166 +msgid "Author" +msgstr "Autor" + +#: bookwyrm/templates/import/import_status.html:103 +msgid "Shelf" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/manual_review.html:13 +#: bookwyrm/templates/snippets/create_status.html:17 +msgid "Review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:110 +msgid "Book" +msgstr "Libro" + +#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/settings/announcements/announcements.html:38 +#: bookwyrm/templates/settings/federation/instance_list.html:46 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 +#: bookwyrm/templates/settings/invites/status_filter.html:5 +#: bookwyrm/templates/settings/users/user_admin.html:34 +#: bookwyrm/templates/settings/users/user_info.html:20 +msgid "Status" +msgstr "Estado" + +#: bookwyrm/templates/import/import_status.html:144 +msgid "View imported review" +msgstr "" + +#: bookwyrm/templates/import/import_status.html:158 +msgid "Imported" +msgstr "Importado" + +#: bookwyrm/templates/import/import_status.html:164 +msgid "Needs manual review" +msgstr "" + +#: bookwyrm/templates/import/manual_review.html:5 +#: bookwyrm/templates/import/troubleshoot.html:4 +msgid "Import Troubleshooting" +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 "" + +#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/lists/curate.html:57 +msgid "Approve" +msgstr "Admitir" + +#: bookwyrm/templates/import/manual_review.html:64 +msgid "Reject" +msgstr "" + +#: bookwyrm/templates/import/tooltip.html:6 +msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." +msgstr "Podes descargar os teus datos en Goodreads desde a páxina de Importación/Exportación na túa conta Goodreads." + +#: bookwyrm/templates/import/troubleshoot.html:7 +msgid "Failed items" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:12 +msgid "Troubleshooting" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:20 +msgid "Re-trying an import can fix missing items in cases such as:" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:23 +msgid "The book has been added to the instance since this import" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:24 +msgid "A transient error or timeout caused the external data source to be unavailable." +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:25 +msgid "BookWyrm has been updated since this import with a bug fix" +msgstr "" + +#: bookwyrm/templates/import/troubleshoot.html:28 +msgid "Contact your admin or open an issue if you are seeing unexpected failed items." +msgstr "" + +#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 +#, python-format +msgid "About %(site_name)s" +msgstr "Acerca de %(site_name)s" + +#: bookwyrm/templates/landing/about.html:10 +#: bookwyrm/templates/landing/about.html:20 +msgid "Code of Conduct" +msgstr "Código de Conduta" + +#: bookwyrm/templates/landing/about.html:13 +#: bookwyrm/templates/landing/about.html:29 +msgid "Privacy Policy" +msgstr "Política de Privacidade" + +#: bookwyrm/templates/landing/invite.html:4 +#: bookwyrm/templates/landing/invite.html:8 +#: bookwyrm/templates/landing/login.html:49 +msgid "Create an Account" +msgstr "Crear unha Conta" + +#: bookwyrm/templates/landing/invite.html:21 +msgid "Permission Denied" +msgstr "Permiso denegado" + +#: bookwyrm/templates/landing/invite.html:22 +msgid "Sorry! This invite code is no longer valid." +msgstr "Lamentámolo! Este convite xa non é válido." + +#: bookwyrm/templates/landing/landing.html:6 +msgid "Recent Books" +msgstr "Libros recentes" + +#: bookwyrm/templates/landing/layout.html:17 +msgid "Decentralized" +msgstr "Descentralizado" + +#: bookwyrm/templates/landing/layout.html:23 +msgid "Friendly" +msgstr "Amigable" + +#: bookwyrm/templates/landing/layout.html:29 +msgid "Anti-Corporate" +msgstr "Anti-corporacións" + +#: bookwyrm/templates/landing/layout.html:45 +#, python-format +msgid "Join %(name)s" +msgstr "Únete a %(name)s" + +#: bookwyrm/templates/landing/layout.html:47 +msgid "Request an Invitation" +msgstr "Solicita un convite" + +#: bookwyrm/templates/landing/layout.html:49 +#, python-format +msgid "%(name)s registration is closed" +msgstr "%(name)s ten o rexistro pechado" + +#: bookwyrm/templates/landing/layout.html:60 +msgid "Thank you! Your request has been received." +msgstr "Grazas! A solicitude foi recibida." + +#: bookwyrm/templates/landing/layout.html:82 +msgid "Your Account" +msgstr "A túa Conta" + +#: bookwyrm/templates/landing/login.html:4 +msgid "Login" +msgstr "Conectar" + +#: bookwyrm/templates/landing/login.html:7 +#: bookwyrm/templates/landing/login.html:37 bookwyrm/templates/layout.html:179 +msgid "Log in" +msgstr "Conecta" + +#: bookwyrm/templates/landing/login.html:15 +msgid "Success! Email address confirmed." +msgstr "Correcto! Enderezo de email confirmado." + +#: bookwyrm/templates/landing/login.html:21 bookwyrm/templates/layout.html:170 +#: bookwyrm/templates/snippets/register_form.html:4 +msgid "Username:" +msgstr "Nome de usuaria:" + +#: bookwyrm/templates/landing/login.html:27 +#: bookwyrm/templates/landing/password_reset.html:17 +#: bookwyrm/templates/layout.html:174 +#: bookwyrm/templates/snippets/register_form.html:22 +msgid "Password:" +msgstr "Contrasinal:" + +#: bookwyrm/templates/landing/login.html:40 bookwyrm/templates/layout.html:176 +msgid "Forgot your password?" +msgstr "Esqueceches o contrasinal?" + +#: bookwyrm/templates/landing/login.html:62 +msgid "More about this site" +msgstr "Máis acerca deste sitio" + +#: bookwyrm/templates/landing/password_reset.html:23 +#: bookwyrm/templates/preferences/change_password.html:18 +#: bookwyrm/templates/preferences/delete_user.html:20 +msgid "Confirm password:" +msgstr "Confirma o contrasinal:" + +#: bookwyrm/templates/landing/password_reset_request.html:14 +msgid "A link to reset your password will be sent to your email address" +msgstr "Enviaremos unha ligazón ao teu email para restablecer o contrasinal" + +#: bookwyrm/templates/landing/password_reset_request.html:28 +msgid "Reset password" +msgstr "Restablecer contrasinal" + +#: bookwyrm/templates/layout.html:13 +#, python-format +msgid "%(site_name)s search" +msgstr "Busca en %(site_name)s" + +#: bookwyrm/templates/layout.html:43 +msgid "Search for a book, user, or list" +msgstr "Busca un libro, usuaria ou lista" + +#: bookwyrm/templates/layout.html:61 bookwyrm/templates/layout.html:62 +msgid "Main navigation menu" +msgstr "Menú principal de navegación" + +#: bookwyrm/templates/layout.html:72 +msgid "Feed" +msgstr "Fonte" + +#: bookwyrm/templates/layout.html:116 +msgid "Settings" +msgstr "Axustes" + +#: bookwyrm/templates/layout.html:125 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:15 +#: bookwyrm/templates/settings/invites/manage_invites.html:3 +#: bookwyrm/templates/settings/invites/manage_invites.html:15 +#: bookwyrm/templates/settings/layout.html:40 +msgid "Invites" +msgstr "Convites" + +#: bookwyrm/templates/layout.html:132 +msgid "Admin" +msgstr "Admin" + +#: bookwyrm/templates/layout.html:139 +msgid "Log out" +msgstr "Desconectar" + +#: bookwyrm/templates/layout.html:147 bookwyrm/templates/layout.html:148 +#: bookwyrm/templates/notifications/notifications_page.html:5 +#: bookwyrm/templates/notifications/notifications_page.html:10 +msgid "Notifications" +msgstr "Notificacións" + +#: bookwyrm/templates/layout.html:175 +msgid "password" +msgstr "contrasinal" + +#: bookwyrm/templates/layout.html:187 +msgid "Join" +msgstr "Únete" + +#: bookwyrm/templates/layout.html:221 +msgid "Successfully posted status" +msgstr "Publicación correcta" + +#: bookwyrm/templates/layout.html:222 +msgid "Error posting status" +msgstr "Erro ao publicar" + +#: bookwyrm/templates/layout.html:234 +msgid "Contact site admin" +msgstr "Contacta coa administración" + +#: bookwyrm/templates/layout.html:238 +msgid "Documentation" +msgstr "Documentación" + +#: bookwyrm/templates/layout.html:245 +#, python-format +msgid "Support %(site_name)s on %(support_title)s" +msgstr "Axuda a %(site_name)s en %(support_title)s" + +#: bookwyrm/templates/layout.html:249 +msgid "BookWyrm's source code is freely available. You can contribute or report issues on GitHub." +msgstr "O código fonte de BookWyrm é público. Podes colaborar ou informar de problemas en GitHub." + +#: bookwyrm/templates/lists/bookmark_button.html:30 +msgid "Un-save" +msgstr "Reverter" + +#: bookwyrm/templates/lists/create_form.html:5 +#: bookwyrm/templates/lists/lists.html:20 +msgid "Create List" +msgstr "Crear lista" + +#: bookwyrm/templates/lists/created_text.html:5 +#, python-format +msgid "Created by %(username)s and managed by %(groupname)s" +msgstr "Creada por %(username)s e xestionada por %(groupname)s" + +#: bookwyrm/templates/lists/created_text.html:7 +#, python-format +msgid "Created and curated by %(username)s" +msgstr "Creada e mantida por %(username)s" + +#: bookwyrm/templates/lists/created_text.html:9 +#, python-format +msgid "Created by %(username)s" +msgstr "Creada por %(username)s" + +#: bookwyrm/templates/lists/curate.html:8 +msgid "Pending Books" +msgstr "Libros pendentes" + +#: bookwyrm/templates/lists/curate.html:11 +msgid "Go to list" +msgstr "Ir á lista" + +#: bookwyrm/templates/lists/curate.html:15 +msgid "You're all set!" +msgstr "Remataches!" + +#: bookwyrm/templates/lists/curate.html:45 +msgid "Suggested by" +msgstr "Suxerido por" + +#: bookwyrm/templates/lists/curate.html:63 +msgid "Discard" +msgstr "Descartar" + +#: bookwyrm/templates/lists/delete_list_modal.html:4 +msgid "Delete this list?" +msgstr "Eliminar esta lista?" + +#: bookwyrm/templates/lists/edit_form.html:5 +#: bookwyrm/templates/lists/layout.html:16 +msgid "Edit List" +msgstr "Editar lista" + +#: bookwyrm/templates/lists/form.html:19 +msgid "List curation:" +msgstr "Mantemento da lista:" + +#: bookwyrm/templates/lists/form.html:22 +msgid "Closed" +msgstr "Pechada" + +#: bookwyrm/templates/lists/form.html:23 +msgid "Only you can add and remove books to this list" +msgstr "Só ti podes engadir e eliminar libros desta lista" + +#: bookwyrm/templates/lists/form.html:27 +msgid "Curated" +msgstr "Xestionada" + +#: bookwyrm/templates/lists/form.html:28 +msgid "Anyone can suggest books, subject to your approval" +msgstr "Calquera pode suxerir libros, suxeita á túa aprobación" + +#: bookwyrm/templates/lists/form.html:32 +msgctxt "curation type" +msgid "Open" +msgstr "Aberta" + +#: bookwyrm/templates/lists/form.html:33 +msgid "Anyone can add books to this list" +msgstr "Calquera pode engadir libros á lista" + +#: bookwyrm/templates/lists/form.html:37 +msgid "Group" +msgstr "Grupo" + +#: bookwyrm/templates/lists/form.html:38 +msgid "Group members can add to and remove from this list" +msgstr "As persoas do grupo poden engadir e eliminar libros desta lista" + +#: bookwyrm/templates/lists/form.html:41 +msgid "Select Group" +msgstr "Elexir grupo" + +#: bookwyrm/templates/lists/form.html:45 +msgid "Select a group" +msgstr "Elexir un grupo" + +#: bookwyrm/templates/lists/form.html:56 +msgid "You don't have any Groups yet!" +msgstr "Aínda non tes Grupos!" + +#: bookwyrm/templates/lists/form.html:58 +msgid "Create a Group" +msgstr "Crea un Grupo" + +#: bookwyrm/templates/lists/form.html:81 +msgid "Delete list" +msgstr "Eliminar lista" + +#: bookwyrm/templates/lists/list.html:21 +msgid "You successfully suggested a book for this list!" +msgstr "Suxeriches correctamente un libro para esta lista!" + +#: bookwyrm/templates/lists/list.html:23 +msgid "You successfully added a book to this list!" +msgstr "Engadiches correctamente un libro a esta lista!" + +#: bookwyrm/templates/lists/list.html:29 +msgid "This list is currently empty" +msgstr "A lista está baleira neste intre" + +#: bookwyrm/templates/lists/list.html:67 +#, python-format +msgid "Added by %(username)s" +msgstr "Engadido por %(username)s" + +#: bookwyrm/templates/lists/list.html:76 +msgid "List position" +msgstr "Posición da lista" + +#: bookwyrm/templates/lists/list.html:82 +msgid "Set" +msgstr "Establecer" + +#: bookwyrm/templates/lists/list.html:92 +#: bookwyrm/templates/snippets/remove_from_group_button.html:19 +#: bookwyrm/templates/snippets/shelf_selector.html:26 +msgid "Remove" +msgstr "Eliminar" + +#: bookwyrm/templates/lists/list.html:106 +#: bookwyrm/templates/lists/list.html:123 +msgid "Sort List" +msgstr "Ordenar lista" + +#: bookwyrm/templates/lists/list.html:116 +msgid "Direction" +msgstr "Dirección" + +#: bookwyrm/templates/lists/list.html:130 +msgid "Add Books" +msgstr "Engadir Libros" + +#: bookwyrm/templates/lists/list.html:132 +msgid "Suggest Books" +msgstr "Suxerir Libros" + +#: bookwyrm/templates/lists/list.html:143 +msgid "search" +msgstr "buscar" + +#: bookwyrm/templates/lists/list.html:149 +msgid "Clear search" +msgstr "Limpar busca" + +#: bookwyrm/templates/lists/list.html:154 +#, python-format +msgid "No books found matching the query \"%(query)s\"" +msgstr "Non se atopan libros coa consulta \"%(query)s\"" + +#: bookwyrm/templates/lists/list.html:182 +msgid "Suggest" +msgstr "Suxire" + +#: bookwyrm/templates/lists/list_items.html:15 +msgid "Saved" +msgstr "Gardado" + +#: bookwyrm/templates/lists/lists.html:14 bookwyrm/templates/user/lists.html:9 +msgid "Your Lists" +msgstr "A túas listas" + +#: bookwyrm/templates/lists/lists.html:36 +msgid "All Lists" +msgstr "Tódalas listas" + +#: bookwyrm/templates/lists/lists.html:40 +msgid "Saved Lists" +msgstr "Listas gardadas" + +#: bookwyrm/templates/notifications/items/accept.html:16 +#, python-format +msgid "accepted your invitation to join group \"%(group_name)s\"" +msgstr "aceptou o teu convite para unirse ao grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/add.html:24 +#, python-format +msgid "added %(book_title)s to your list \"%(list_name)s\"" +msgstr "engadiu %(book_title)s á túa lista \"%(list_name)s\"" + +#: bookwyrm/templates/notifications/items/add.html:31 +#, python-format +msgid "suggested adding %(book_title)s to your list \"%(list_name)s\"" +msgstr "suxeriu engadir %(book_title)s á túa lista \"%(list_name)s\"" + +#: bookwyrm/templates/notifications/items/boost.html:19 +#, python-format +msgid "boosted your review of %(book_title)s" +msgstr "promoveu a túa recensión de %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:25 +#, python-format +msgid "boosted your comment on%(book_title)s" +msgstr "promoveu o teu comentario acerca de %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:31 +#, python-format +msgid "boosted your quote from %(book_title)s" +msgstr "promoveu a túa cita acerca de %(book_title)s" + +#: bookwyrm/templates/notifications/items/boost.html:37 +#, python-format +msgid "boosted your status" +msgstr "promoveu a túa publicación" + +#: bookwyrm/templates/notifications/items/fav.html:19 +#, python-format +msgid "liked your review of %(book_title)s" +msgstr "gustoulle a túa recensión de %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:25 +#, python-format +msgid "liked your comment on %(book_title)s" +msgstr "gustoulle o teu comentario para %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:31 +#, python-format +msgid "liked your quote from %(book_title)s" +msgstr "gustoulle a túa cita de %(book_title)s" + +#: bookwyrm/templates/notifications/items/fav.html:37 +#, python-format +msgid "liked your status" +msgstr "gustoulle a túa publicación" + +#: bookwyrm/templates/notifications/items/follow.html:15 +msgid "followed you" +msgstr "séguete" + +#: bookwyrm/templates/notifications/items/follow_request.html:11 +msgid "sent you a follow request" +msgstr "enviouche unha solicitude de seguimento" + +#: bookwyrm/templates/notifications/items/import.html:14 +#, python-format +msgid "Your import completed." +msgstr "A importación completouse." + +#: bookwyrm/templates/notifications/items/invite.html:15 +#, python-format +msgid "invited you to join the group \"%(group_name)s\"" +msgstr "convidoute a unirte ao grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/join.html:16 +#, python-format +msgid "has joined your group \"%(group_name)s\"" +msgstr "uniuse ao teu grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/leave.html:16 +#, python-format +msgid "has left your group \"%(group_name)s\"" +msgstr "deixou o teu grupo \"%(group_name)s\"" + +#: bookwyrm/templates/notifications/items/mention.html:20 +#, python-format +msgid "mentioned you in a review of %(book_title)s" +msgstr "mencionoute nunha recensión sobre %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:26 +#, python-format +msgid "mentioned you in a comment on %(book_title)s" +msgstr "mencionoute nun comentario para %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:32 +#, python-format +msgid "mentioned you in a quote from %(book_title)s" +msgstr "mencionoute nunha cita en %(book_title)s" + +#: bookwyrm/templates/notifications/items/mention.html:38 +#, python-format +msgid "mentioned you in a status" +msgstr "mencionoute nun estado" + +#: bookwyrm/templates/notifications/items/remove.html:17 +#, python-format +msgid "has been removed from your group \"%(group_name)s\"" +msgstr "" + +#: bookwyrm/templates/notifications/items/remove.html:23 +#, python-format +msgid "You have been removed from the \"%(group_name)s\" group" +msgstr "" + +#: bookwyrm/templates/notifications/items/reply.html:21 +#, python-format +msgid "replied to your review of %(book_title)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/reply.html:27 +#, python-format +msgid "replied to your comment on %(book_title)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/reply.html:33 +#, python-format +msgid "replied to your quote from %(book_title)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/reply.html:39 +#, python-format +msgid "replied to your status" +msgstr "" + +#: bookwyrm/templates/notifications/items/report.html:15 +#, python-format +msgid "A new report needs moderation." +msgstr "" + +#: bookwyrm/templates/notifications/items/update.html:16 +#, python-format +msgid "has changed the privacy level for %(group_name)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/update.html:20 +#, python-format +msgid "has changed the name of %(group_name)s" +msgstr "" + +#: bookwyrm/templates/notifications/items/update.html:24 +#, python-format +msgid "has changed the description of %(group_name)s" +msgstr "" + +#: bookwyrm/templates/notifications/notifications_page.html:18 +msgid "Delete notifications" +msgstr "Eliminar notificacións" + +#: bookwyrm/templates/notifications/notifications_page.html:29 +msgid "All" +msgstr "Todas" + +#: bookwyrm/templates/notifications/notifications_page.html:33 +msgid "Mentions" +msgstr "Mencións" + +#: bookwyrm/templates/notifications/notifications_page.html:45 +msgid "You're all caught up!" +msgstr "Estás ao día!" + +#: bookwyrm/templates/preferences/blocks.html:4 +#: bookwyrm/templates/preferences/blocks.html:7 +#: bookwyrm/templates/preferences/layout.html:31 +msgid "Blocked Users" +msgstr "Usuarias bloqueadas" + +#: bookwyrm/templates/preferences/blocks.html:12 +msgid "No users currently blocked." +msgstr "Non tes usuarias bloqueadas." + +#: bookwyrm/templates/preferences/change_password.html:4 +#: bookwyrm/templates/preferences/change_password.html:7 +#: bookwyrm/templates/preferences/change_password.html:21 +#: bookwyrm/templates/preferences/layout.html:20 +msgid "Change Password" +msgstr "Cambiar contrasinal" + +#: bookwyrm/templates/preferences/change_password.html:14 +msgid "New password:" +msgstr "Novo contrasinal:" + +#: bookwyrm/templates/preferences/delete_user.html:4 +#: bookwyrm/templates/preferences/delete_user.html:7 +#: bookwyrm/templates/preferences/delete_user.html:26 +#: bookwyrm/templates/preferences/layout.html:24 +#: bookwyrm/templates/settings/users/delete_user_form.html:23 +msgid "Delete Account" +msgstr "Eliminar conta" + +#: bookwyrm/templates/preferences/delete_user.html:12 +msgid "Permanently delete account" +msgstr "Eliminar a conta de xeito definitivo" + +#: bookwyrm/templates/preferences/delete_user.html:14 +msgid "Deleting your account cannot be undone. The username will not be available to register in the future." +msgstr "Se eliminas a conta non haberá volta atrás. O nome de usuaria non estará dispoñible para rexistro no futuro." + +#: bookwyrm/templates/preferences/edit_user.html:4 +#: bookwyrm/templates/preferences/edit_user.html:7 +#: bookwyrm/templates/preferences/layout.html:15 +msgid "Edit Profile" +msgstr "Editar perfil" + +#: bookwyrm/templates/preferences/edit_user.html:12 +#: bookwyrm/templates/preferences/edit_user.html:25 +#: bookwyrm/templates/settings/users/user_info.html:7 +msgid "Profile" +msgstr "Perfil" + +#: bookwyrm/templates/preferences/edit_user.html:13 +#: bookwyrm/templates/preferences/edit_user.html:68 +msgid "Display preferences" +msgstr "Preferencias da interface" + +#: bookwyrm/templates/preferences/edit_user.html:14 +#: bookwyrm/templates/preferences/edit_user.html:106 +msgid "Privacy" +msgstr "Privacidade" + +#: bookwyrm/templates/preferences/edit_user.html:72 +msgid "Show reading goal prompt in feed:" +msgstr "Mostrar obxectivo de lectura na fonte:" + +#: bookwyrm/templates/preferences/edit_user.html:76 +msgid "Show suggested users:" +msgstr "Mostrar en usuarias suxeridas:" + +#: bookwyrm/templates/preferences/edit_user.html:85 +#, python-format +msgid "Your account will show up in the directory, and may be recommended to other BookWyrm users." +msgstr "A túa conta aparecerá no directorio, e podería ser recomendada a outras usuarias de BookWyrm." + +#: bookwyrm/templates/preferences/edit_user.html:89 +msgid "Preferred Timezone: " +msgstr "Zona horaria preferida: " + +#: bookwyrm/templates/preferences/edit_user.html:116 +msgid "Default post privacy:" +msgstr "Privacidade por defecto:" + +#: bookwyrm/templates/preferences/layout.html:11 +msgid "Account" +msgstr "Conta" + +#: bookwyrm/templates/preferences/layout.html:27 +msgid "Relationships" +msgstr "Relacións" + +#: bookwyrm/templates/reading_progress/finish.html:5 +#, python-format +msgid "Finish \"%(book_title)s\"" +msgstr "Acabei \"%(book_title)s\"" + +#: bookwyrm/templates/reading_progress/start.html:5 +#, python-format +msgid "Start \"%(book_title)s\"" +msgstr "Comecei \"%(book_title)s\"" + +#: bookwyrm/templates/reading_progress/want.html:5 +#, python-format +msgid "Want to Read \"%(book_title)s\"" +msgstr "Quero ler \"%(book_title)s\"" + +#: bookwyrm/templates/search/book.html:47 +#: bookwyrm/templates/settings/reports/reports.html:25 +#: bookwyrm/templates/snippets/announcement.html:16 +msgid "Open" +msgstr "Abrir" + +#: bookwyrm/templates/search/book.html:85 +msgid "Import book" +msgstr "Importar libro" + +#: bookwyrm/templates/search/book.html:107 +msgid "Load results from other catalogues" +msgstr "Cargar resultados desde outros catálogos" + +#: bookwyrm/templates/search/book.html:111 +msgid "Manually add book" +msgstr "Engadir un libro manualmente" + +#: bookwyrm/templates/search/book.html:116 +msgid "Log in to import or add books." +msgstr "Conéctate para importar ou engadir libros." + +#: bookwyrm/templates/search/layout.html:16 +msgid "Search query" +msgstr "Termos a buscar" + +#: bookwyrm/templates/search/layout.html:19 +msgid "Search type" +msgstr "Tipo de busca" + +#: bookwyrm/templates/search/layout.html:23 +#: bookwyrm/templates/search/layout.html:46 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:27 +#: bookwyrm/templates/settings/federation/instance_list.html:44 +#: bookwyrm/templates/settings/layout.html:34 +#: bookwyrm/templates/settings/users/user_admin.html:3 +#: bookwyrm/templates/settings/users/user_admin.html:10 +msgid "Users" +msgstr "Usuarias" + +#: bookwyrm/templates/search/layout.html:58 +#, python-format +msgid "No results found for \"%(query)s\"" +msgstr "Sen resultados para \"%(query)s\"" + +#: bookwyrm/templates/settings/announcements/announcement.html:3 +#: bookwyrm/templates/settings/announcements/announcement.html:6 +msgid "Announcement" +msgstr "Anuncio" + +#: bookwyrm/templates/settings/announcements/announcement.html:7 +#: bookwyrm/templates/settings/federation/instance.html:13 +msgid "Back to list" +msgstr "Volver á lista" + +#: bookwyrm/templates/settings/announcements/announcement.html:11 +#: bookwyrm/templates/settings/announcements/announcement_form.html:6 +msgid "Edit Announcement" +msgstr "Editar anuncio" + +#: bookwyrm/templates/settings/announcements/announcement.html:35 +msgid "Visible:" +msgstr "Visible:" + +#: bookwyrm/templates/settings/announcements/announcement.html:38 +msgid "True" +msgstr "Certo" + +#: bookwyrm/templates/settings/announcements/announcement.html:40 +msgid "False" +msgstr "Falso" + +#: bookwyrm/templates/settings/announcements/announcement.html:47 +#: bookwyrm/templates/settings/announcements/announcement_form.html:40 +#: bookwyrm/templates/settings/dashboard/dashboard.html:71 +msgid "Start date:" +msgstr "Data de inicio:" + +#: bookwyrm/templates/settings/announcements/announcement.html:54 +#: bookwyrm/templates/settings/announcements/announcement_form.html:49 +#: bookwyrm/templates/settings/dashboard/dashboard.html:77 +msgid "End date:" +msgstr "Data de fin:" + +#: bookwyrm/templates/settings/announcements/announcement.html:60 +#: bookwyrm/templates/settings/announcements/announcement_form.html:58 +msgid "Active:" +msgstr "Activo:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:8 +#: bookwyrm/templates/settings/announcements/announcements.html:8 +msgid "Create Announcement" +msgstr "Crear Anuncio" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:16 +msgid "Preview:" +msgstr "Vista previa:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:23 +msgid "Content:" +msgstr "Contido:" + +#: bookwyrm/templates/settings/announcements/announcement_form.html:30 +msgid "Event date:" +msgstr "Data do evento:" + +#: bookwyrm/templates/settings/announcements/announcements.html:3 +#: bookwyrm/templates/settings/announcements/announcements.html:5 +#: bookwyrm/templates/settings/layout.html:72 +msgid "Announcements" +msgstr "Anuncios" + +#: bookwyrm/templates/settings/announcements/announcements.html:22 +#: bookwyrm/templates/settings/federation/instance_list.html:36 +msgid "Date added" +msgstr "Data engadida" + +#: bookwyrm/templates/settings/announcements/announcements.html:26 +msgid "Preview" +msgstr "Vista previa" + +#: bookwyrm/templates/settings/announcements/announcements.html:30 +msgid "Start date" +msgstr "Data de inicio" + +#: bookwyrm/templates/settings/announcements/announcements.html:34 +msgid "End date" +msgstr "Data de fin" + +#: bookwyrm/templates/settings/announcements/announcements.html:48 +msgid "active" +msgstr "activo" + +#: bookwyrm/templates/settings/announcements/announcements.html:48 +msgid "inactive" +msgstr "inactivo" + +#: bookwyrm/templates/settings/announcements/announcements.html:52 +msgid "No announcements found" +msgstr "Non hai anuncios" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:6 +#: bookwyrm/templates/settings/dashboard/dashboard.html:8 +#: bookwyrm/templates/settings/layout.html:26 +msgid "Dashboard" +msgstr "Taboleiro" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:15 +#: bookwyrm/templates/settings/dashboard/dashboard.html:100 +msgid "Total users" +msgstr "Total de usuarias" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:21 +#: bookwyrm/templates/settings/dashboard/user_chart.html:16 +msgid "Active this month" +msgstr "Activas este mes" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:27 +msgid "Statuses" +msgstr "Estados" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:33 +#: bookwyrm/templates/settings/dashboard/works_chart.html:11 +msgid "Works" +msgstr "Traballos" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:43 +#, python-format +msgid "%(display_count)s open report" +msgid_plural "%(display_count)s open reports" +msgstr[0] "%(display_count)s denuncia aberta" +msgstr[1] "%(display_count)s denuncias abertas" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:54 +#, python-format +msgid "%(display_count)s invite request" +msgid_plural "%(display_count)s invite requests" +msgstr[0] "%(display_count)s solicitude de convite" +msgstr[1] "%(display_count)s solicitudes de convite" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:65 +msgid "Instance Activity" +msgstr "Actividade na instancia" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:83 +msgid "Interval:" +msgstr "Intervalo:" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:87 +msgid "Days" +msgstr "Días" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:88 +msgid "Weeks" +msgstr "Semanas" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:106 +msgid "User signup activity" +msgstr "Rexistros de usuarias" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:112 +msgid "Status activity" +msgstr "Actividade do estado" + +#: bookwyrm/templates/settings/dashboard/dashboard.html:118 +msgid "Works created" +msgstr "Traballos creados" + +#: bookwyrm/templates/settings/dashboard/registration_chart.html:10 +msgid "Registrations" +msgstr "Rexistros" + +#: bookwyrm/templates/settings/dashboard/status_chart.html:11 +msgid "Statuses posted" +msgstr "Estados publicados" + +#: bookwyrm/templates/settings/dashboard/user_chart.html:11 +msgid "Total" +msgstr "Total" + +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:5 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:10 +msgid "Add domain" +msgstr "Engadir dominio" + +#: bookwyrm/templates/settings/email_blocklist/domain_form.html:11 +msgid "Domain:" +msgstr "Dominio:" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:5 +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:7 +#: bookwyrm/templates/settings/layout.html:59 +msgid "Email Blocklist" +msgstr "Lista de bloqueo de email" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:18 +msgid "When someone tries to register with an email from this domain, no account will be created. The registration process will appear to have worked." +msgstr "Non se creará a conta cando alguén se intente rexistrar usando un email deste dominio. O proceso de rexistro aparentará terse completado." + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:25 +msgid "Domain" +msgstr "Dominio" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:29 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:27 +msgid "Options" +msgstr "Opcións" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:38 +#, python-format +msgid "%(display_count)s user" +msgid_plural "%(display_count)s users" +msgstr[0] "%(display_count)s usuaria" +msgstr[1] "%(display_count)s usuarias" + +#: bookwyrm/templates/settings/email_blocklist/email_blocklist.html:59 +msgid "No email domains currently blocked" +msgstr "Non tes dominios de email bloqueados" + +#: bookwyrm/templates/settings/federation/edit_instance.html:3 +#: bookwyrm/templates/settings/federation/edit_instance.html:6 +#: bookwyrm/templates/settings/federation/edit_instance.html:20 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:3 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:20 +#: bookwyrm/templates/settings/federation/instance_list.html:9 +#: bookwyrm/templates/settings/federation/instance_list.html:10 +msgid "Add instance" +msgstr "Engadir instancia" + +#: bookwyrm/templates/settings/federation/edit_instance.html:7 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:7 +msgid "Back to instance list" +msgstr "Volver á lista de instancias" + +#: bookwyrm/templates/settings/federation/edit_instance.html:16 +#: bookwyrm/templates/settings/federation/instance_blocklist.html:16 +msgid "Import block list" +msgstr "Importar lista de bloqueo" + +#: bookwyrm/templates/settings/federation/edit_instance.html:30 +msgid "Instance:" +msgstr "Instancia:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:39 +#: bookwyrm/templates/settings/federation/instance.html:28 +#: bookwyrm/templates/settings/users/user_info.html:106 +msgid "Status:" +msgstr "Estado:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:52 +#: bookwyrm/templates/settings/federation/instance.html:22 +#: bookwyrm/templates/settings/users/user_info.html:100 +msgid "Software:" +msgstr "Software:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:61 +#: bookwyrm/templates/settings/federation/instance.html:25 +#: bookwyrm/templates/settings/users/user_info.html:103 +msgid "Version:" +msgstr "Versión:" + +#: bookwyrm/templates/settings/federation/edit_instance.html:70 +msgid "Notes:" +msgstr "Notas:" + +#: bookwyrm/templates/settings/federation/instance.html:19 +msgid "Details" +msgstr "Detalles" + +#: bookwyrm/templates/settings/federation/instance.html:35 +#: bookwyrm/templates/user/layout.html:64 +msgid "Activity" +msgstr "Actividade" + +#: bookwyrm/templates/settings/federation/instance.html:38 +msgid "Users:" +msgstr "Usuarias:" + +#: bookwyrm/templates/settings/federation/instance.html:41 +#: bookwyrm/templates/settings/federation/instance.html:47 +msgid "View all" +msgstr "Ver todo" + +#: bookwyrm/templates/settings/federation/instance.html:44 +#: bookwyrm/templates/settings/users/user_info.html:56 +msgid "Reports:" +msgstr "Denuncias:" + +#: bookwyrm/templates/settings/federation/instance.html:50 +msgid "Followed by us:" +msgstr "Seguidas por nós:" + +#: bookwyrm/templates/settings/federation/instance.html:55 +msgid "Followed by them:" +msgstr "Somos seguidas por:" + +#: bookwyrm/templates/settings/federation/instance.html:60 +msgid "Blocked by us:" +msgstr "Temos bloquedas:" + +#: bookwyrm/templates/settings/federation/instance.html:72 +#: bookwyrm/templates/settings/users/user_info.html:110 +msgid "Notes" +msgstr "Notas" + +#: bookwyrm/templates/settings/federation/instance.html:75 +#: bookwyrm/templates/snippets/status/status_options.html:24 +msgid "Edit" +msgstr "Editar" + +#: bookwyrm/templates/settings/federation/instance.html:79 +msgid "No notes" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance.html:94 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:8 +msgid "Actions" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance.html:98 +#: bookwyrm/templates/snippets/block_button.html:5 +msgid "Block" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance.html:99 +msgid "All users from this instance will be deactivated." +msgstr "" + +#: bookwyrm/templates/settings/federation/instance.html:104 +#: bookwyrm/templates/snippets/block_button.html:10 +msgid "Un-block" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance.html:105 +msgid "All users from this instance will be re-activated." +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:6 +msgid "Import Blocklist" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:26 +#: bookwyrm/templates/snippets/goal_progress.html:7 +msgid "Success!" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:30 +msgid "Successfully blocked:" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_blocklist.html:32 +msgid "Failed:" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_list.html:3 +#: bookwyrm/templates/settings/federation/instance_list.html:5 +#: bookwyrm/templates/settings/layout.html:45 +msgid "Federated Instances" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_list.html:32 +#: bookwyrm/templates/settings/users/server_filter.html:5 +msgid "Instance name" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_list.html:40 +msgid "Software" +msgstr "" + +#: bookwyrm/templates/settings/federation/instance_list.html:63 +msgid "No instances found" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:4 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:11 +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:25 +#: bookwyrm/templates/settings/invites/manage_invites.html:11 +msgid "Invite Requests" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:23 +msgid "Ignored Invite Requests" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:35 +msgid "Date requested" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:39 +msgid "Date accepted" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:42 +msgid "Email" +msgstr "" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:47 +msgid "Action" +msgstr "Acción" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:50 +msgid "No requests" +msgstr "Sen solicitudes" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:59 +#: bookwyrm/templates/settings/invites/status_filter.html:16 +msgid "Accepted" +msgstr "Aceptadas" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:61 +#: bookwyrm/templates/settings/invites/status_filter.html:12 +msgid "Sent" +msgstr "Enviadas" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:63 +#: bookwyrm/templates/settings/invites/status_filter.html:8 +msgid "Requested" +msgstr "Solicitadas" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:73 +msgid "Send invite" +msgstr "Enviar convite" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:75 +msgid "Re-send invite" +msgstr "Volver a enviar" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:95 +msgid "Ignore" +msgstr "Ignorar" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:97 +msgid "Un-ignore" +msgstr "Non ignorar" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:108 +msgid "Back to pending requests" +msgstr "Volver a solicitudes pendentes" + +#: bookwyrm/templates/settings/invites/manage_invite_requests.html:110 +msgid "View ignored requests" +msgstr "Ver solicitudes ignoradas" + +#: bookwyrm/templates/settings/invites/manage_invites.html:21 +msgid "Generate New Invite" +msgstr "Crear Novo convite" + +#: bookwyrm/templates/settings/invites/manage_invites.html:27 +msgid "Expiry:" +msgstr "Caducidade:" + +#: bookwyrm/templates/settings/invites/manage_invites.html:33 +msgid "Use limit:" +msgstr "Límite de uso:" + +#: bookwyrm/templates/settings/invites/manage_invites.html:40 +msgid "Create Invite" +msgstr "Crear convite" + +#: bookwyrm/templates/settings/invites/manage_invites.html:47 +msgid "Link" +msgstr "Ligazón" + +#: bookwyrm/templates/settings/invites/manage_invites.html:48 +msgid "Expires" +msgstr "Caduca" + +#: bookwyrm/templates/settings/invites/manage_invites.html:49 +msgid "Max uses" +msgstr "Máx. de usos" + +#: bookwyrm/templates/settings/invites/manage_invites.html:50 +msgid "Times used" +msgstr "Veces utilizado" + +#: bookwyrm/templates/settings/invites/manage_invites.html:53 +msgid "No active invites" +msgstr "Sen convites activos" + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:5 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:10 +msgid "Add IP address" +msgstr "Engade enderezo IP" + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:11 +msgid "Use IP address blocks with caution, and consider using blocks only temporarily, as IP addresses are often shared or change hands. If you block your own IP, you will not be able to access this page." +msgstr "Usa os bloqueos por IP con tino, e considera outros bloqueos ou só temporalmente, xa que os enderezos IP son habitualmente compartidos ou cambian con frecuencia. Se bloqueas o teu propio IP non poderás acceder a esta páxina." + +#: bookwyrm/templates/settings/ip_blocklist/ip_address_form.html:18 +msgid "IP Address:" +msgstr "Enderezo IP:" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:5 +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:7 +#: bookwyrm/templates/settings/layout.html:63 +msgid "IP Address Blocklist" +msgstr "Lista de enderezos IP bloqueados" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:18 +msgid "Any traffic from this IP address will get a 404 response when trying to access any part of the application." +msgstr "Calquera tráfico desde estos enderezos IP obterá resposta 404 ao intentar acceder a calquera parte da aplicación." + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:24 +msgid "Address" +msgstr "Enderezo" + +#: bookwyrm/templates/settings/ip_blocklist/ip_blocklist.html:46 +msgid "No IP addresses currently blocked" +msgstr "Actualmente non tes IP bloqueados" + +#: bookwyrm/templates/settings/ip_blocklist/ip_tooltip.html:6 +msgid "You can block IP ranges using CIDR syntax." +msgstr "Podes bloquear rangos de IP utilizando sintaxe CIDR." + +#: bookwyrm/templates/settings/layout.html:4 +msgid "Administration" +msgstr "Administración" + +#: bookwyrm/templates/settings/layout.html:29 +msgid "Manage Users" +msgstr "" + +#: bookwyrm/templates/settings/layout.html:51 +msgid "Moderation" +msgstr "" + +#: bookwyrm/templates/settings/layout.html:55 +#: bookwyrm/templates/settings/reports/reports.html:8 +#: bookwyrm/templates/settings/reports/reports.html:17 +msgid "Reports" +msgstr "" + +#: bookwyrm/templates/settings/layout.html:68 +msgid "Instance Settings" +msgstr "" + +#: bookwyrm/templates/settings/layout.html:76 +#: bookwyrm/templates/settings/site.html:4 +#: bookwyrm/templates/settings/site.html:6 +msgid "Site Settings" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:5 +#: bookwyrm/templates/settings/reports/report.html:8 +#: bookwyrm/templates/settings/reports/report_preview.html:6 +#, python-format +msgid "Report #%(report_id)s: %(username)s" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:9 +msgid "Back to reports" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:23 +msgid "Moderator Comments" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:41 +#: bookwyrm/templates/snippets/create_status.html:28 +msgid "Comment" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:46 +msgid "Reported statuses" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:48 +msgid "No statuses reported" +msgstr "" + +#: bookwyrm/templates/settings/reports/report.html:54 +msgid "Status has been deleted" +msgstr "" + +#: bookwyrm/templates/settings/reports/report_preview.html:13 +msgid "No notes provided" +msgstr "" + +#: bookwyrm/templates/settings/reports/report_preview.html:20 +#, python-format +msgid "Reported by %(username)s" +msgstr "" + +#: bookwyrm/templates/settings/reports/report_preview.html:30 +msgid "Re-open" +msgstr "" + +#: bookwyrm/templates/settings/reports/report_preview.html:32 +msgid "Resolve" +msgstr "" + +#: bookwyrm/templates/settings/reports/reports.html:6 +#, python-format +msgid "Reports: %(instance_name)s" +msgstr "" + +#: bookwyrm/templates/settings/reports/reports.html:14 +#, python-format +msgid "Reports: %(instance_name)s" +msgstr "" + +#: bookwyrm/templates/settings/reports/reports.html:28 +msgid "Resolved" +msgstr "" + +#: bookwyrm/templates/settings/reports/reports.html:37 +msgid "No reports found." +msgstr "" + +#: bookwyrm/templates/settings/site.html:10 +#: bookwyrm/templates/settings/site.html:21 +msgid "Instance Info" +msgstr "" + +#: bookwyrm/templates/settings/site.html:11 +#: bookwyrm/templates/settings/site.html:54 +msgid "Images" +msgstr "Imaxes" + +#: bookwyrm/templates/settings/site.html:12 +#: bookwyrm/templates/settings/site.html:74 +msgid "Footer Content" +msgstr "Contido web do pé" + +#: bookwyrm/templates/settings/site.html:13 +#: bookwyrm/templates/settings/site.html:98 +msgid "Registration" +msgstr "Rexistro" + +#: bookwyrm/templates/settings/site.html:24 +msgid "Instance Name:" +msgstr "Nome da instancia:" + +#: bookwyrm/templates/settings/site.html:28 +msgid "Tagline:" +msgstr "Lema:" + +#: bookwyrm/templates/settings/site.html:32 +msgid "Instance description:" +msgstr "Descrición da instancia:" + +#: bookwyrm/templates/settings/site.html:36 +msgid "Short description:" +msgstr "Descrición curta:" + +#: bookwyrm/templates/settings/site.html:37 +msgid "Used when the instance is previewed on joinbookwyrm.com. Does not support HTML or Markdown." +msgstr "Utilizado na vista previa da instancia en joinbookwyrm.com. Non admite HTML ou Markdown." + +#: bookwyrm/templates/settings/site.html:41 +msgid "Code of conduct:" +msgstr "Código de conduta:" + +#: bookwyrm/templates/settings/site.html:45 +msgid "Privacy Policy:" +msgstr "Política de privacidade:" + +#: bookwyrm/templates/settings/site.html:57 +msgid "Logo:" +msgstr "Logo:" + +#: bookwyrm/templates/settings/site.html:61 +msgid "Logo small:" +msgstr "Logo pequeno:" + +#: bookwyrm/templates/settings/site.html:65 +msgid "Favicon:" +msgstr "Favicon:" + +#: bookwyrm/templates/settings/site.html:77 +msgid "Support link:" +msgstr "Ligazón de axuda:" + +#: bookwyrm/templates/settings/site.html:81 +msgid "Support title:" +msgstr "Título de axuda:" + +#: bookwyrm/templates/settings/site.html:85 +msgid "Admin email:" +msgstr "Email de Admin:" + +#: bookwyrm/templates/settings/site.html:89 +msgid "Additional info:" +msgstr "Info adicional:" + +#: bookwyrm/templates/settings/site.html:103 +msgid "Allow registration" +msgstr "Abrir rexistro" + +#: bookwyrm/templates/settings/site.html:109 +msgid "Allow invite requests" +msgstr "Permitir solicitudes de convite" + +#: bookwyrm/templates/settings/site.html:115 +msgid "Require users to confirm email address" +msgstr "Requerir que a usuaria confirme o enderezo de email" + +#: bookwyrm/templates/settings/site.html:117 +msgid "(Recommended if registration is open)" +msgstr "(Recomendable se o rexistro está aberto)" + +#: bookwyrm/templates/settings/site.html:120 +msgid "Registration closed text:" +msgstr "Texto se o rexistro está pechado:" + +#: bookwyrm/templates/settings/site.html:124 +msgid "Invite request text:" +msgstr "Texto para a solicitude do convite:" + +#: bookwyrm/templates/settings/users/delete_user_form.html:5 +#: bookwyrm/templates/settings/users/user_moderation_actions.html:31 +msgid "Permanently delete user" +msgstr "Eliminar definitivamente a usuaria" + +#: bookwyrm/templates/settings/users/delete_user_form.html:12 +#, python-format +msgid "Are you sure you want to delete %(username)s's account? This action cannot be undone. To proceed, please enter your password to confirm deletion." +msgstr "Tes a certeza de querer eliminar a conta de %(username)s? Esta acción non ten volta atrás. Para facelo, escribe o teu contrasinal e confirma a eliminación." + +#: bookwyrm/templates/settings/users/delete_user_form.html:17 +msgid "Your password:" +msgstr "Contrasinal:" + +#: bookwyrm/templates/settings/users/user.html:7 +msgid "Back to users" +msgstr "Volver a usuarias" + +#: bookwyrm/templates/settings/users/user_admin.html:7 +#, python-format +msgid "Users: %(instance_name)s" +msgstr "Usuarias: %(instance_name)s" + +#: bookwyrm/templates/settings/users/user_admin.html:22 +#: bookwyrm/templates/settings/users/username_filter.html:5 +msgid "Username" +msgstr "Nome de usuaria" + +#: bookwyrm/templates/settings/users/user_admin.html:26 +msgid "Date Added" +msgstr "Data de alta" + +#: bookwyrm/templates/settings/users/user_admin.html:30 +msgid "Last Active" +msgstr "Última vez activa" + +#: bookwyrm/templates/settings/users/user_admin.html:38 +msgid "Remote instance" +msgstr "Instancia remota" + +#: bookwyrm/templates/settings/users/user_admin.html:47 +#: bookwyrm/templates/settings/users/user_info.html:24 +msgid "Active" +msgstr "Activa" + +#: bookwyrm/templates/settings/users/user_admin.html:47 +#: bookwyrm/templates/settings/users/user_info.html:28 +msgid "Inactive" +msgstr "Inactiva" + +#: bookwyrm/templates/settings/users/user_admin.html:52 +#: bookwyrm/templates/settings/users/user_info.html:120 +msgid "Not set" +msgstr "Non establecido" + +#: bookwyrm/templates/settings/users/user_info.html:16 +msgid "View user profile" +msgstr "Ver perfil da usuaria" + +#: bookwyrm/templates/settings/users/user_info.html:36 +msgid "Local" +msgstr "Local" + +#: bookwyrm/templates/settings/users/user_info.html:38 +msgid "Remote" +msgstr "Remota" + +#: bookwyrm/templates/settings/users/user_info.html:47 +msgid "User details" +msgstr "Detalles da usuaria" + +#: bookwyrm/templates/settings/users/user_info.html:51 +msgid "Email:" +msgstr "Email:" + +#: bookwyrm/templates/settings/users/user_info.html:61 +msgid "(View reports)" +msgstr "(Ver denuncias)" + +#: bookwyrm/templates/settings/users/user_info.html:67 +msgid "Blocked by count:" +msgstr "Bloqueada pola conta:" + +#: bookwyrm/templates/settings/users/user_info.html:70 +msgid "Last active date:" +msgstr "Data da última actividade:" + +#: bookwyrm/templates/settings/users/user_info.html:73 +msgid "Manually approved followers:" +msgstr "Seguidoras aprobadas manualmente:" + +#: bookwyrm/templates/settings/users/user_info.html:76 +msgid "Discoverable:" +msgstr "Atopable:" + +#: bookwyrm/templates/settings/users/user_info.html:80 +msgid "Deactivation reason:" +msgstr "Razón da desactivación:" + +#: bookwyrm/templates/settings/users/user_info.html:95 +msgid "Instance details" +msgstr "Detalles da instancia" + +#: bookwyrm/templates/settings/users/user_info.html:117 +msgid "View instance" +msgstr "Ver instancia" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:5 +msgid "Permanently deleted" +msgstr "Eliminada definitivamente" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:13 +#: bookwyrm/templates/snippets/status/status_options.html:32 +#: bookwyrm/templates/snippets/user_options.html:13 +msgid "Send direct message" +msgstr "Enviar mensaxe directa" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:20 +msgid "Suspend user" +msgstr "" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:25 +msgid "Un-suspend user" +msgstr "" + +#: bookwyrm/templates/settings/users/user_moderation_actions.html:47 +msgid "Access level:" +msgstr "" + +#: bookwyrm/templates/shelf/create_shelf_form.html:5 +msgid "Create Shelf" +msgstr "" + +#: bookwyrm/templates/shelf/edit_shelf_form.html:5 +msgid "Edit Shelf" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 +msgid "All books" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:69 +msgid "Create shelf" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:90 +#, python-format +msgid "%(formatted_count)s book" +msgid_plural "%(formatted_count)s books" +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/shelf/shelf.html:97 +#, python-format +msgid "(showing %(start)s-%(end)s)" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:109 +msgid "Edit shelf" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:117 +msgid "Delete shelf" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:145 +#: bookwyrm/templates/shelf/shelf.html:171 +msgid "Shelved" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:146 +#: bookwyrm/templates/shelf/shelf.html:174 +msgid "Started" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:147 +#: bookwyrm/templates/shelf/shelf.html:177 +msgid "Finished" +msgstr "" + +#: bookwyrm/templates/shelf/shelf.html:203 +msgid "This shelf is empty." +msgstr "" + +#: bookwyrm/templates/snippets/add_to_group_button.html:15 +msgid "Invite" +msgstr "" + +#: bookwyrm/templates/snippets/add_to_group_button.html:24 +msgid "Uninvite" +msgstr "" + +#: bookwyrm/templates/snippets/add_to_group_button.html:28 +#, python-format +msgid "Remove @%(username)s" +msgstr "" + +#: bookwyrm/templates/snippets/announcement.html:31 +#, python-format +msgid "Posted by %(username)s" +msgstr "" + +#: bookwyrm/templates/snippets/authors.html:22 +#, python-format +msgid "and %(remainder_count_display)s other" +msgid_plural "and %(remainder_count_display)s others" +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/snippets/book_cover.html:61 +msgid "No cover" +msgstr "" + +#: bookwyrm/templates/snippets/book_titleby.html:6 +#, python-format +msgid "%(title)s by" +msgstr "" + +#: bookwyrm/templates/snippets/boost_button.html:20 +#: bookwyrm/templates/snippets/boost_button.html:21 +msgid "Boost" +msgstr "" + +#: bookwyrm/templates/snippets/boost_button.html:33 +#: bookwyrm/templates/snippets/boost_button.html:34 +msgid "Un-boost" +msgstr "" + +#: bookwyrm/templates/snippets/create_status.html:39 +msgid "Quote" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/comment.html:15 +msgid "Some thoughts on the book" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/comment.html:27 +#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:15 +msgid "Progress:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/comment.html:53 +#: bookwyrm/templates/snippets/progress_field.html:18 +msgid "pages" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/comment.html:59 +#: bookwyrm/templates/snippets/progress_field.html:23 +msgid "percent" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/comment.html:66 +#, python-format +msgid "of %(pages)s pages" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/content_field.html:17 +#: bookwyrm/templates/snippets/status/layout.html:34 +#: bookwyrm/templates/snippets/status/layout.html:52 +#: bookwyrm/templates/snippets/status/layout.html:53 +msgid "Reply" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/content_field.html:17 +msgid "Content" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/content_warning_field.html:10 +msgid "Content warning:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/content_warning_field.html:18 +msgid "Spoilers ahead!" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/content_warning_toggle.html:13 +msgid "Include spoiler alert" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/layout.html:48 +#: bookwyrm/templates/snippets/reading_modals/form.html:7 +msgid "Comment:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/post_options_block.html:8 +#: bookwyrm/templates/snippets/privacy-icons.html:15 +#: bookwyrm/templates/snippets/privacy-icons.html:16 +#: bookwyrm/templates/snippets/privacy_select.html:20 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 +msgid "Private" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/post_options_block.html:21 +msgid "Post" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/quotation.html:17 +msgid "Quote:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/quotation.html:25 +#, python-format +msgid "An excerpt from '%(book_title)s'" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/quotation.html:32 +msgid "Position:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/quotation.html:45 +msgid "On page:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/quotation.html:51 +msgid "At percent:" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/review.html:25 +#, python-format +msgid "Your review of '%(book_title)s'" +msgstr "" + +#: bookwyrm/templates/snippets/create_status/review.html:40 +msgid "Review:" +msgstr "" + +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:4 +msgid "Delete these read dates?" +msgstr "" + +#: bookwyrm/templates/snippets/delete_readthrough_modal.html:7 +#, python-format +msgid "You are deleting this readthrough and its %(count)s associated progress updates." +msgstr "" + +#: bookwyrm/templates/snippets/fav_button.html:16 +#: bookwyrm/templates/snippets/fav_button.html:17 +msgid "Like" +msgstr "" + +#: bookwyrm/templates/snippets/fav_button.html:30 +#: bookwyrm/templates/snippets/fav_button.html:31 +msgid "Un-like" +msgstr "" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:7 +msgid "Show filters" +msgstr "Mostrar filtros" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:9 +msgid "Hide filters" +msgstr "Agochar filtros" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:22 +msgid "Apply filters" +msgstr "Aplicar filtros" + +#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:26 +msgid "Clear filters" +msgstr "Limpar filtros" + +#: bookwyrm/templates/snippets/follow_button.html:14 +#, python-format +msgid "Follow @%(username)s" +msgstr "Seguir a @%(username)s" + +#: bookwyrm/templates/snippets/follow_button.html:16 +msgid "Follow" +msgstr "Seguir" + +#: bookwyrm/templates/snippets/follow_button.html:25 +msgid "Undo follow request" +msgstr "Retirar solicitude de seguimento" + +#: bookwyrm/templates/snippets/follow_button.html:30 +#, python-format +msgid "Unfollow @%(username)s" +msgstr "Deixar de seguir a @%(username)s" + +#: bookwyrm/templates/snippets/follow_button.html:32 +msgid "Unfollow" +msgstr "Non seguir" + +#: bookwyrm/templates/snippets/follow_request_buttons.html:7 +#: bookwyrm/templates/snippets/join_invitation_buttons.html:8 +msgid "Accept" +msgstr "Aceptar" + +#: bookwyrm/templates/snippets/form_rate_stars.html:20 +#: bookwyrm/templates/snippets/stars.html:13 +msgid "No rating" +msgstr "Sen avaliar" + +#: bookwyrm/templates/snippets/form_rate_stars.html:28 +#, python-format +msgid "%(half_rating)s star" +msgid_plural "%(half_rating)s stars" +msgstr[0] "%(half_rating)s estrela" +msgstr[1] "%(half_rating)s estrelas" + +#: bookwyrm/templates/snippets/form_rate_stars.html:64 +#: bookwyrm/templates/snippets/stars.html:7 +#, python-format +msgid "%(rating)s star" +msgid_plural "%(rating)s stars" +msgstr[0] "%(rating)s estrela" +msgstr[1] "%(rating)s estrelas" + +#: bookwyrm/templates/snippets/generated_status/goal.html:2 +#, python-format +msgid "set a goal to read %(counter)s book in %(year)s" +msgid_plural "set a goal to read %(counter)s books in %(year)s" +msgstr[0] "establecer obxectivo de %(counter)s libro ao %(year)s" +msgstr[1] "establecer obxectivo de ler %(counter)s libros ao %(year)s" + +#: bookwyrm/templates/snippets/generated_status/rating.html:3 +#, python-format +msgid "rated %(title)s: %(display_rating)s star" +msgid_plural "rated %(title)s: %(display_rating)s stars" +msgstr[0] "valorado %(title)s: %(display_rating)s estrela" +msgstr[1] "valorado %(title)s: %(display_rating)s estrelas" + +#: bookwyrm/templates/snippets/generated_status/review_pure_name.html:4 +#, python-format +msgid "Review of \"%(book_title)s\" (%(display_rating)s star): %(review_title)s" +msgid_plural "Review of \"%(book_title)s\" (%(display_rating)s stars): %(review_title)s" +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/snippets/generated_status/review_pure_name.html:8 +#, python-format +msgid "Review of \"%(book_title)s\": %(review_title)s" +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:4 +#, python-format +msgid "Set a goal for how many books you'll finish reading in %(year)s, and track your progress throughout the year." +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:16 +msgid "Reading goal:" +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:21 +msgid "books" +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:26 +msgid "Goal privacy:" +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:33 +#: bookwyrm/templates/snippets/reading_modals/layout.html:13 +msgid "Post to feed" +msgstr "" + +#: bookwyrm/templates/snippets/goal_form.html:37 +msgid "Set goal" +msgstr "" + +#: bookwyrm/templates/snippets/goal_progress.html:9 +#, python-format +msgid "%(percent)s%% complete!" +msgstr "" + +#: bookwyrm/templates/snippets/goal_progress.html:12 +#, python-format +msgid "You've read %(read_count)s of %(goal_count)s books." +msgstr "" + +#: bookwyrm/templates/snippets/goal_progress.html:14 +#, python-format +msgid "%(username)s has read %(read_count)s of %(goal_count)s books." +msgstr "" + +#: bookwyrm/templates/snippets/page_text.html:8 +#, python-format +msgid "page %(page)s of %(total_pages)s" +msgstr "" + +#: bookwyrm/templates/snippets/page_text.html:14 +#, python-format +msgid "page %(page)s" +msgstr "" + +#: bookwyrm/templates/snippets/pagination.html:12 +msgid "Previous" +msgstr "" + +#: bookwyrm/templates/snippets/pagination.html:23 +msgid "Next" +msgstr "" + +#: bookwyrm/templates/snippets/privacy-icons.html:3 +#: bookwyrm/templates/snippets/privacy-icons.html:4 +#: bookwyrm/templates/snippets/privacy_select.html:11 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 +msgid "Public" +msgstr "" + +#: bookwyrm/templates/snippets/privacy-icons.html:7 +#: bookwyrm/templates/snippets/privacy-icons.html:8 +#: bookwyrm/templates/snippets/privacy_select.html:14 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 +msgid "Unlisted" +msgstr "" + +#: bookwyrm/templates/snippets/privacy-icons.html:12 +msgid "Followers-only" +msgstr "" + +#: bookwyrm/templates/snippets/privacy_select.html:6 +#: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 +msgid "Post privacy" +msgstr "" + +#: bookwyrm/templates/snippets/privacy_select.html:17 +#: bookwyrm/templates/user/relationships/followers.html:6 +#: bookwyrm/templates/user/relationships/layout.html:11 +msgid "Followers" +msgstr "" + +#: bookwyrm/templates/snippets/rate_action.html:4 +msgid "Leave a rating" +msgstr "" + +#: bookwyrm/templates/snippets/rate_action.html:19 +msgid "Rate" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:6 +#, python-format +msgid "Finish \"%(book_title)s\"" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:23 +#: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:20 +#: bookwyrm/templates/snippets/readthrough_form.html:7 +msgid "Started reading" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:31 +#: bookwyrm/templates/snippets/readthrough_form.html:20 +msgid "Finished reading" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/form.html:9 +msgid "(Optional)" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 +msgid "Update progress" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:6 +#, python-format +msgid "Start \"%(book_title)s\"" +msgstr "" + +#: bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html:6 +#, python-format +msgid "Want to Read \"%(book_title)s\"" +msgstr "" + +#: bookwyrm/templates/snippets/readthrough_form.html:14 +msgid "Progress" +msgstr "" + +#: bookwyrm/templates/snippets/register_form.html:32 +msgid "Sign Up" +msgstr "" + +#: bookwyrm/templates/snippets/report_button.html:6 +msgid "Report" +msgstr "" + +#: bookwyrm/templates/snippets/report_modal.html:6 +#, python-format +msgid "Report @%(username)s" +msgstr "" + +#: bookwyrm/templates/snippets/report_modal.html:23 +#, python-format +msgid "This report will be sent to %(site_name)s's moderators for review." +msgstr "" + +#: bookwyrm/templates/snippets/report_modal.html:24 +msgid "More info about this report:" +msgstr "" + +#: bookwyrm/templates/snippets/shelf_selector.html:4 +msgid "Move book" +msgstr "" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown.html:5 +msgid "More shelves" +msgstr "" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:17 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:24 +msgid "Start reading" +msgstr "" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:29 +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:36 +msgid "Want to read" +msgstr "" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:62 +#, python-format +msgid "Remove from %(name)s" +msgstr "" + +#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:30 +msgid "Finish reading" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:72 +msgid "Content warning" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:79 +msgid "Show status" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:101 +#, python-format +msgid "(Page %(page)s)" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:103 +#, python-format +msgid "(%(percent)s%%)" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:125 +msgid "Open image in new window" +msgstr "" + +#: bookwyrm/templates/snippets/status/content_status.html:144 +msgid "Hide status" +msgstr "" + +#: bookwyrm/templates/snippets/status/header.html:45 +#, python-format +msgid "edited %(date)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/comment.html:2 +#, python-format +msgid "commented on %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/note.html:8 +#, python-format +msgid "replied to %(username)s's status" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/quotation.html:2 +#, python-format +msgid "quoted %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/rating.html:3 +#, python-format +msgid "rated %(book)s:" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/read.html:7 +#, python-format +msgid "finished reading %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/reading.html:7 +#, python-format +msgid "started reading %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/review.html:3 +#, python-format +msgid "reviewed %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/headers/to_read.html:7 +#, python-format +msgid "%(username)s wants to read %(book)s" +msgstr "" + +#: bookwyrm/templates/snippets/status/layout.html:24 +#: bookwyrm/templates/snippets/status/status_options.html:17 +msgid "Delete status" +msgstr "" + +#: bookwyrm/templates/snippets/status/layout.html:56 +#: bookwyrm/templates/snippets/status/layout.html:57 +msgid "Boost status" +msgstr "" + +#: bookwyrm/templates/snippets/status/layout.html:60 +#: bookwyrm/templates/snippets/status/layout.html:61 +msgid "Like status" +msgstr "" + +#: bookwyrm/templates/snippets/status/status.html:10 +msgid "boosted" +msgstr "" + +#: bookwyrm/templates/snippets/status/status_options.html:7 +#: bookwyrm/templates/snippets/user_options.html:7 +msgid "More options" +msgstr "" + +#: bookwyrm/templates/snippets/switch_edition_button.html:5 +msgid "Switch to this edition" +msgstr "" + +#: bookwyrm/templates/snippets/table-sort-header.html:6 +msgid "Sorted ascending" +msgstr "" + +#: bookwyrm/templates/snippets/table-sort-header.html:10 +msgid "Sorted descending" +msgstr "" + +#: bookwyrm/templates/snippets/trimmed_text.html:17 +msgid "Show more" +msgstr "" + +#: bookwyrm/templates/snippets/trimmed_text.html:35 +msgid "Show less" +msgstr "" + +#: bookwyrm/templates/user/books_header.html:10 +msgid "Your books" +msgstr "Os teus libros" + +#: bookwyrm/templates/user/books_header.html:15 +#, python-format +msgid "%(username)s's books" +msgstr "" + +#: bookwyrm/templates/user/goal.html:8 +#, python-format +msgid "%(year)s Reading Progress" +msgstr "" + +#: bookwyrm/templates/user/goal.html:12 +msgid "Edit Goal" +msgstr "" + +#: bookwyrm/templates/user/goal.html:28 +#, python-format +msgid "%(name)s hasn't set a reading goal for %(year)s." +msgstr "" + +#: bookwyrm/templates/user/goal.html:40 +#, python-format +msgid "Your %(year)s Books" +msgstr "" + +#: bookwyrm/templates/user/goal.html:42 +#, python-format +msgid "%(username)s's %(year)s Books" +msgstr "" + +#: bookwyrm/templates/user/groups.html:9 +msgid "Your Groups" +msgstr "" + +#: bookwyrm/templates/user/groups.html:11 +#, python-format +msgid "Groups: %(username)s" +msgstr "" + +#: bookwyrm/templates/user/groups.html:17 +msgid "Create group" +msgstr "" + +#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 +msgid "User Profile" +msgstr "" + +#: bookwyrm/templates/user/layout.html:45 +msgid "Follow Requests" +msgstr "" + +#: bookwyrm/templates/user/layout.html:70 +msgid "Reading Goal" +msgstr "" + +#: bookwyrm/templates/user/layout.html:76 +msgid "Groups" +msgstr "" + +#: bookwyrm/templates/user/lists.html:11 +#, python-format +msgid "Lists: %(username)s" +msgstr "" + +#: bookwyrm/templates/user/lists.html:17 bookwyrm/templates/user/lists.html:29 +msgid "Create list" +msgstr "" + +#: bookwyrm/templates/user/relationships/followers.html:12 +#, python-format +msgid "%(username)s has no followers" +msgstr "" + +#: bookwyrm/templates/user/relationships/following.html:6 +#: bookwyrm/templates/user/relationships/layout.html:15 +msgid "Following" +msgstr "" + +#: bookwyrm/templates/user/relationships/following.html:12 +#, python-format +msgid "%(username)s isn't following any users" +msgstr "" + +#: bookwyrm/templates/user/user.html:16 +msgid "Edit profile" +msgstr "" + +#: bookwyrm/templates/user/user.html:33 +#, python-format +msgid "View all %(size)s" +msgstr "" + +#: bookwyrm/templates/user/user.html:46 +msgid "View all books" +msgstr "" + +#: bookwyrm/templates/user/user.html:59 +msgid "User Activity" +msgstr "" + +#: bookwyrm/templates/user/user.html:63 +msgid "RSS feed" +msgstr "" + +#: bookwyrm/templates/user/user.html:74 +msgid "No activities yet!" +msgstr "" + +#: bookwyrm/templates/user/user_preview.html:22 +#, python-format +msgid "Joined %(date)s" +msgstr "" + +#: bookwyrm/templates/user/user_preview.html:26 +#, python-format +msgid "%(counter)s follower" +msgid_plural "%(counter)s followers" +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/user/user_preview.html:27 +#, python-format +msgid "%(counter)s following" +msgstr "" + +#: bookwyrm/templates/user/user_preview.html:34 +#, python-format +msgid "%(mutuals_display)s follower you follow" +msgid_plural "%(mutuals_display)s followers you follow" +msgstr[0] "" +msgstr[1] "" + +#: bookwyrm/templates/user/user_preview.html:38 +msgid "No followers you follow" +msgstr "" + +#: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28 +msgid "File exceeds maximum size: 10MB" +msgstr "" + +#: bookwyrm/templatetags/utilities.py:31 +#, python-format +msgid "%(title)s: %(subtitle)s" +msgstr "" + +#: bookwyrm/views/imports/import_data.py:64 +msgid "Not a valid csv file" +msgstr "" + +#: bookwyrm/views/landing/login.py:69 +msgid "Username or password are incorrect" +msgstr "" + +#: bookwyrm/views/landing/password.py:32 +msgid "No user with that email address was found." +msgstr "" + +#: bookwyrm/views/landing/password.py:43 +#, python-brace-format +msgid "A password reset link was sent to {email}" +msgstr "" + +#: bookwyrm/views/rss_feed.py:35 +#, python-brace-format +msgid "Status updates from {obj.display_name}" +msgstr "" + From 9662143518a8e6c7358514814cfd642221611b47 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 17 Nov 2021 10:03:48 -0800 Subject: [PATCH 128/134] Updates english locale file --- locale/en_US/LC_MESSAGES/django.po | 98 +++++++++++++++++++----------- 1 file changed, 61 insertions(+), 37 deletions(-) diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index 14bbb1b96..f5df1265d 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-14 15:08+0000\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -18,71 +18,71 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "" -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 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:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "" @@ -184,18 +184,26 @@ msgid "Español (Spanish)" msgstr "" #: bookwyrm/settings.py:168 -msgid "Français (French)" +msgid "Galego (Galician)" msgstr "" #: bookwyrm/settings.py:169 -msgid "Português - Brasil (Brazilian Portuguese)" +msgid "Français (French)" msgstr "" #: bookwyrm/settings.py:170 -msgid "简体中文 (Simplified Chinese)" +msgid "Lietuvių (Lithuanian)" msgstr "" #: bookwyrm/settings.py:171 +msgid "Português - Brasil (Brazilian Portuguese)" +msgstr "" + +#: bookwyrm/settings.py:172 +msgid "简体中文 (Simplified Chinese)" +msgstr "" + +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "" @@ -1411,64 +1419,64 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1478,18 +1486,34 @@ msgstr "" msgid "Status" msgstr "" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1499,12 +1523,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "" From 41dd915d7f1e62086fda14bafde0ddd2db84acb9 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 17 Nov 2021 20:22:00 -0800 Subject: [PATCH 129/134] Email templates --- bookwyrm/emailing.py | 19 +++++++++++++------ bookwyrm/models/site.py | 11 ++++++++++- bookwyrm/templates/email/html_layout.html | 2 +- .../email/moderation_report/html_content.html | 11 +++++++++++ .../email/moderation_report/subject.html | 2 ++ .../email/moderation_report/text_content.html | 9 +++++++++ bookwyrm/templates/email/preview.html | 2 +- bookwyrm/views/admin/reports.py | 5 +++-- bookwyrm/views/admin/site.py | 3 +++ 9 files changed, 53 insertions(+), 11 deletions(-) create mode 100644 bookwyrm/templates/email/moderation_report/html_content.html create mode 100644 bookwyrm/templates/email/moderation_report/subject.html create mode 100644 bookwyrm/templates/email/moderation_report/text_content.html diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index c6a197f29..dbf2369e9 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -10,14 +10,9 @@ from bookwyrm.settings import DOMAIN def email_data(): """fields every email needs""" site = models.SiteSettings.objects.get() - if site.logo_small: - logo_path = f"/images/{site.logo_small.url}" - else: - logo_path = "/static/images/logo-small.png" - return { "site_name": site.name, - "logo": logo_path, + "logo": site.logo_small_url, "domain": DOMAIN, "user": None, } @@ -46,6 +41,18 @@ def password_reset_email(reset_code): send_email.delay(reset_code.user.email, *format_email("password_reset", data)) +def moderation_report_email(report): + """a report was created""" + data = email_data() + data["reporter"] = report.reporter.localname or report.reporter.username + data["reportee"] = report.user.localname or report.user.username + data["report_link"] = report.remote_id + + for admin in models.User.objects.filter(permissions="moderate_user"): + data["user"] = admin.display_name + send_email.delay(admin.email, *format_email("moderation_report", data)) + + def format_email(email_name, data): """render the email templates""" subject = get_template(f"email/{email_name}/subject.html").render(data).strip() diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index 8338fff88..a5d2df4e3 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -1,5 +1,6 @@ """ the particulars for this instance of BookWyrm """ import datetime +from urllib.parse import urljoin from django.db import models, IntegrityError from django.dispatch import receiver @@ -7,9 +8,10 @@ from django.utils import timezone from model_utils import FieldTracker from bookwyrm.preview_images import generate_site_preview_image_task -from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES +from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, STATIC_FULL_URL from .base_model import BookWyrmModel, new_access_code from .user import User +from .fields import get_absolute_url class SiteSettings(models.Model): @@ -66,6 +68,13 @@ class SiteSettings(models.Model): default_settings.save() return default_settings + @property + def logo_small_url(self): + """ helper to build the lgoo url """ + if self.logo_small: + return get_absolute_url(self.logo_small) + return urljoin(STATIC_FULL_URL, "images/logo-small.png") + class SiteInvite(models.Model): """gives someone access to create an account on the instance""" diff --git a/bookwyrm/templates/email/html_layout.html b/bookwyrm/templates/email/html_layout.html index 02527ff52..01e2f35c6 100644 --- a/bookwyrm/templates/email/html_layout.html +++ b/bookwyrm/templates/email/html_layout.html @@ -2,7 +2,7 @@

    - logo + logo
    {{ site_name }}
    diff --git a/bookwyrm/templates/email/moderation_report/html_content.html b/bookwyrm/templates/email/moderation_report/html_content.html new file mode 100644 index 000000000..10df380f2 --- /dev/null +++ b/bookwyrm/templates/email/moderation_report/html_content.html @@ -0,0 +1,11 @@ +{% extends 'email/html_layout.html' %} +{% load i18n %} + +{% block content %} +

    +{% blocktrans %}@{{ reporter }} has flagged behavior by @{{ reportee }} for moderation. {% endblocktrans %} +

    + +{% trans "View report" as text %} +{% include 'email/snippets/action.html' with path=report_link text=text %} +{% endblock %} diff --git a/bookwyrm/templates/email/moderation_report/subject.html b/bookwyrm/templates/email/moderation_report/subject.html new file mode 100644 index 000000000..c268f1aa8 --- /dev/null +++ b/bookwyrm/templates/email/moderation_report/subject.html @@ -0,0 +1,2 @@ +{% load i18n %} +{% blocktrans %}New report for {{ site_name }}{% endblocktrans %} diff --git a/bookwyrm/templates/email/moderation_report/text_content.html b/bookwyrm/templates/email/moderation_report/text_content.html new file mode 100644 index 000000000..57d37d446 --- /dev/null +++ b/bookwyrm/templates/email/moderation_report/text_content.html @@ -0,0 +1,9 @@ +{% extends 'email/text_layout.html' %} +{% load i18n %} +{% block content %} + +{% blocktrans %}@{{ reporter}} has flagged behavior by @{{ reportee }} for moderation. {% endblocktrans %} + +{% trans "View report" %} +{{ report_link }} +{% endblock %} diff --git a/bookwyrm/templates/email/preview.html b/bookwyrm/templates/email/preview.html index ab4323054..66d856c08 100644 --- a/bookwyrm/templates/email/preview.html +++ b/bookwyrm/templates/email/preview.html @@ -1,4 +1,4 @@ - +
    Subject: {% include subject_path %} diff --git a/bookwyrm/views/admin/reports.py b/bookwyrm/views/admin/reports.py index f72d7970b..a32e955dc 100644 --- a/bookwyrm/views/admin/reports.py +++ b/bookwyrm/views/admin/reports.py @@ -7,7 +7,7 @@ from django.utils.decorators import method_decorator from django.views import View from django.views.decorators.http import require_POST -from bookwyrm import forms, models +from bookwyrm import emailing, forms, models # pylint: disable=no-self-use @@ -142,5 +142,6 @@ def make_report(request): if not form.is_valid(): raise ValueError(form.errors) - form.save() + report = form.save() + emailing.moderation_report_email(report) return redirect(request.headers.get("Referer", "/")) diff --git a/bookwyrm/views/admin/site.py b/bookwyrm/views/admin/site.py index b66fdb9f4..4dc14be16 100644 --- a/bookwyrm/views/admin/site.py +++ b/bookwyrm/views/admin/site.py @@ -48,4 +48,7 @@ def email_preview(request): data["invite_link"] = "https://example.com/link" data["confirmation_link"] = "https://example.com/link" data["confirmation_code"] = "AKJHKDGKJSDFG" + data["reporter"] = "ConcernedUser" + data["reportee"] = "UserName" + data["report_link"] = "https://example.com/link" return TemplateResponse(request, "email/preview.html", data) From 235167f06c0c4a664148611f5a267bb6fb6decf1 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 18 Nov 2021 14:03:19 -0800 Subject: [PATCH 130/134] Updates locales --- locale/de_DE/LC_MESSAGES/django.po | 100 ++++++++++------ locale/es_ES/LC_MESSAGES/django.mo | Bin 60011 -> 60011 bytes locale/es_ES/LC_MESSAGES/django.po | 100 ++++++++++------ locale/fr_FR/LC_MESSAGES/django.po | 100 ++++++++++------ locale/gl_ES/LC_MESSAGES/django.mo | Bin 43625 -> 48434 bytes locale/gl_ES/LC_MESSAGES/django.po | 170 +++++++++++++++------------ locale/lt_LT/LC_MESSAGES/django.mo | Bin 61847 -> 61847 bytes locale/lt_LT/LC_MESSAGES/django.po | 104 +++++++++------- locale/pt_BR/LC_MESSAGES/django.mo | Bin 62235 -> 62977 bytes locale/pt_BR/LC_MESSAGES/django.po | 100 ++++++++++------ locale/zh_Hans/LC_MESSAGES/django.po | 100 ++++++++++------ locale/zh_Hant/LC_MESSAGES/django.po | 100 ++++++++++------ 12 files changed, 533 insertions(+), 341 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index 6ebce09ac..429881200 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-15 18:03\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 18:42\n" "Last-Translator: Mouse Reeve \n" "Language-Team: German\n" "Language: de\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Es existiert bereits ein Benutzer*inkonto mit dieser E-Mail-Adresse." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Ein Tag" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Eine Woche" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Ein Monat" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "Läuft nicht ab" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i}-mal verwendbar" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Unbegrenzt" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Reihenfolge der Liste" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Buchtitel" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Bewertung" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Sortieren nach" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Aufsteigend" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Absteigend" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Fehler beim Laden des Buches" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "Keine Übereinstimmung für das Buch gefunden" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "Ausstehend" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español (Spanisch)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français (Französisch)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Português (Portugiesisch)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文 (vereinfachtes Chinesisch)" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文 (Chinesisch, traditionell)" @@ -1410,64 +1418,64 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titel" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor*in" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "Besprechen" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Buch" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1477,18 +1485,34 @@ msgstr "Buch" msgid "Status" msgstr "Status" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importiert" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1498,12 +1522,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Bestätigen" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "" diff --git a/locale/es_ES/LC_MESSAGES/django.mo b/locale/es_ES/LC_MESSAGES/django.mo index 9614a669c3aa133bb13af01293952c2b0790dfc1..fb8399c4153f43e570a4c2a071f4a95bb8a76f88 100644 GIT binary patch delta 22 ecmaETh57Xr<_+8X*v%CTEv!t8Ht*|O8w~(@U\n" "Language-Team: Spanish\n" "Language: es\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Ya existe un usuario con ese correo electrónico." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Un día" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Una semana" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Un mes" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "No expira" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} usos" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Sin límite" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Orden de la lista" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Título" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Calificación" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Ordenar por" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Ascendente" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Descendente" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Error en cargar libro" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "No se pudo encontrar el libro" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "Pendiente" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français (Francés)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Português - Brasil (Portugués Brasileño)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文 (Chino simplificado)" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文 (Chino tradicional)" @@ -1410,64 +1418,64 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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[1] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor/Autora" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "Reseña" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Libro" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1477,18 +1485,34 @@ msgstr "Libro" msgid "Status" msgstr "Estado" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importado" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1498,12 +1522,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Aprobar" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "" diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index 23661a28c..25db17d99 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-16 23:06\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 18:41\n" "Last-Translator: Mouse Reeve \n" "Language-Team: French\n" "Language: fr\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Cet email est déjà associé à un compte." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Un jour" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Une semaine" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Un mois" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "Sans expiration" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} utilisations" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Sans limite" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Ordre de la liste" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Titre du livre" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Note" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Trier par" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Ordre croissant" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Ordre décroissant" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Erreur lors du chargement du livre" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "Impossible de trouver une correspondance pour le livre" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "En attente" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Português - Brasil (Portugais brésilien)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简化字" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "Infos supplémentaires :" @@ -1410,64 +1418,64 @@ msgstr "En cours de traitement" msgid "Refresh" msgstr "Actualiser" -#: bookwyrm/templates/import/import_status.html:62 +#: 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] "%(display_counter)s élément a besoin d'être approuvé manuellement." msgstr[1] "%(display_counter)s éléments ont besoin d'être approuvés manuellement." -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "Vérifier les éléments" -#: bookwyrm/templates/import/import_status.html:73 +#: 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] "%(display_counter)s élément n'a pas pu être importé." msgstr[1] "%(display_counter)s éléments n'ont pas pu être importés." -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "Afficher et corriger les importations ayant échoué" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "Ligne" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Titre" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "ISBN" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Auteur/autrice" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "Étagère" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "Critique" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Livre" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1477,18 +1485,34 @@ msgstr "Livre" msgid "Status" msgstr "Statut" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "Afficher la critique importée" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importé" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "Nécessite une vérification manuelle" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1498,12 +1522,12 @@ msgstr "Résolution des problèmes d'importation" 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 "Approuver une suggestion ajoutera définitivement le livre suggéré à vos étagères et associera vos dates, critiques et notes de lecture à ce livre." -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Approuver" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "Rejeter" diff --git a/locale/gl_ES/LC_MESSAGES/django.mo b/locale/gl_ES/LC_MESSAGES/django.mo index 149986eb7ed6ecd85ba1544e12c1b5bf7d5ac480..0381a352ab63a4fbcaa81df21704f212e27db786 100644 GIT binary patch delta 16907 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 Rad4qNSz)Q^=DH=XSpf-{anS$( delta 13148 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\n" "Language-Team: Galician\n" "Language: gl\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Xa existe unha unsuaria con este email." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Un día" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Unha semana" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Un mes" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "Non caduca" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} usos" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Sen límite" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Orde da listaxe" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Título do libro" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Puntuación" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Ordenar por" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Ascendente" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Descendente" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Erro ao cargar o libro" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "Non se atopan coincidencias para o libro" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "Pendente" @@ -172,7 +172,7 @@ msgstr "Libros" #: bookwyrm/settings.py:165 msgid "English" -msgstr "Inglés" +msgstr "English (Inglés)" #: bookwyrm/settings.py:166 msgid "Deutsch (German)" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español (España)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "Galego (Galician)" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Francés (Francia)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "Lietuvių (Lithuanian)" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Portugués - Brasil (portugués brasileiro)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文 (Chinés simplificado)" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文 (Chinés tradicional)" @@ -896,17 +904,17 @@ msgstr "Tódalas usuarias coñecidas" #: bookwyrm/templates/discover/card-header.html:8 #, python-format msgid "%(username)s wants to read %(book_title)s" -msgstr "" +msgstr "%(username)s quere ler %(book_title)s" #: bookwyrm/templates/discover/card-header.html:13 #, python-format msgid "%(username)s finished reading %(book_title)s" -msgstr "" +msgstr "%(username)s rematou de ler %(book_title)s" #: bookwyrm/templates/discover/card-header.html:18 #, python-format msgid "%(username)s started reading %(book_title)s" -msgstr "" +msgstr "%(username)s comezou a ler %(book_title)s" #: bookwyrm/templates/discover/card-header.html:23 #, python-format @@ -1392,11 +1400,11 @@ msgstr "Estado da importación" #: bookwyrm/templates/import/import_status.html:13 #: bookwyrm/templates/import/import_status.html:27 msgid "Retry Status" -msgstr "" +msgstr "Intenta outra vez" #: bookwyrm/templates/import/import_status.html:22 msgid "Imports" -msgstr "" +msgstr "Importacións" #: bookwyrm/templates/import/import_status.html:39 msgid "Import started:" @@ -1404,70 +1412,70 @@ msgstr "Importación iniciada:" #: bookwyrm/templates/import/import_status.html:48 msgid "In progress" -msgstr "" +msgstr "En progreso" #: bookwyrm/templates/import/import_status.html:50 msgid "Refresh" -msgstr "" +msgstr "Actualizar" -#: bookwyrm/templates/import/import_status.html:62 +#: 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[1] "" +msgstr[0] "%(display_counter)s elemento precisa aprobación manual." +msgstr[1] "%(display_counter)s elementos precisan aprobación manual." -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" -msgstr "" +msgstr "Revisar elementos" -#: bookwyrm/templates/import/import_status.html:73 +#: 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[1] "" +msgstr[0] "fallou a importación de %(display_counter)s elemento." +msgstr[1] "fallou a importación de %(display_counter)s elementos." -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" -msgstr "" +msgstr "Ver e arranxar os problemas" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" -msgstr "" +msgstr "Fila" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" -msgstr "" +msgstr "ISBN" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" -msgstr "" +msgstr "Estante" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" -msgstr "" +msgstr "Revisar" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Libro" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1477,35 +1485,51 @@ msgstr "Libro" msgid "Status" msgstr "Estado" -#: bookwyrm/templates/import/import_status.html:144 -msgid "View imported review" -msgstr "" +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "Non dispoñible vista previa da importación." -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:162 +msgid "View imported review" +msgstr "Ver revisión importada" + +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importado" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" -msgstr "" +msgstr "Precisa revisión manual" + +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +msgstr "Volver a intentar" + +#: 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 "Esta importación ten un formato antigo xa non soportado. Se queres intentar recuperar os elementos que faltan nesta importación preme no botón inferior para actualizar o formato de importación." + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "Actualizar importación" #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" -msgstr "" +msgstr "Arranxar importación" #: 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 "Ao aceptar unha suxestión engadirá permanentemente o libro suxerido aos teus estantes e asociará as túas datas de lectura, revisións e valoracións a ese libro." -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Admitir" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" -msgstr "" +msgstr "Rexeitar" #: bookwyrm/templates/import/tooltip.html:6 msgid "You can download your Goodreads data from the Import/Export page of your Goodreads account." @@ -1513,31 +1537,31 @@ msgstr "Podes descargar os teus datos en Goodreads desde a open an issue if you are seeing unexpected failed items." -msgstr "" +msgstr "Contacta coa administración ou abre unha incidencia se atopas fallos non agardados." #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #, python-format @@ -2026,22 +2050,22 @@ msgstr "mencionoute nun estado" #: bookwyrm/templates/notifications/items/remove.html:17 #, python-format msgid "has been removed from your group \"%(group_name)s\"" -msgstr "" +msgstr "foi retirada do teu grupo \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/remove.html:23 #, python-format msgid "You have been removed from the \"%(group_name)s\" group" -msgstr "" +msgstr "Foches eliminada do grupo \"%(group_name)s\"" #: bookwyrm/templates/notifications/items/reply.html:21 #, python-format msgid "replied to your review of %(book_title)s" -msgstr "" +msgstr "respondeu á túa revisión de %(book_title)s" #: bookwyrm/templates/notifications/items/reply.html:27 #, python-format msgid "replied to your comment on %(book_title)s" -msgstr "" +msgstr "respondeu ao teu comentario en %(book_title)s" #: bookwyrm/templates/notifications/items/reply.html:33 #, python-format diff --git a/locale/lt_LT/LC_MESSAGES/django.mo b/locale/lt_LT/LC_MESSAGES/django.mo index 0b31ed928845cf4b7a4076a3d165b541be594590..6a72ab36cef1f22fa4663fd9dadbbda3c88c5083 100644 GIT binary patch delta 5434 zcmbRKn0fkR<_&M8>-iZN7~U>sV31>AVEDV3fdRyqS;D};!@$6xvxI?xg@J*=atQ+i z9|Hq}9aP+R2?K*L0|P_U5{UY|B@7H&3=9l)OBfh*85kH=E@5DhWME*p4psMY2?K)? z0|Nu=QU(TY1_lNVC~dNop&o3o!%_wYb_NCp|D_BJ$qWn(;Y%49)EF2Tb}waMuw`Ii zc(fE^k-{>F0S3z$7&bF7FxV`EIOM}J1_m|;1_qYp3=CWh3=G`M85lSi7#PHsGcZUo zFfhn3XJAlZU|_IX&cGnez`zgZyb9u@d8;4}SOw*8Uj+%N!>b@Zc?_k0uY$zA@M=hq>#l}4z;87~JZUw= zp*5=+7$g`N>KR&~5_4BWf^hq41_l`h28IKxAwIaf8WLpBp$5HO4e<%%8i>IHYak9* zSp)Ha*&2wvJCqKC(y35&B~W#3Yd|4a&%iK!4FiKY0|UdFH4F?o3=9lU)-W(6fr5T5 zB<@SrLL4%EEyTiwYat=CbuGlg15ojcYavndbS=aIU!i=Kbqox=3=9k+>mX67vmWfIzYbzy{W^$+o$DYL&4u#Ut%IbIL+c=k^ahlEy$+I%|3S@> zT@SIyc0DBML)Sx6fBt#~hC~JihVJzY4E3N?{dPShj+r(#8zDX{*$4@N$r~Xdw{jySgmyydQyU=` z-G=htZiIO3-$qD?32lPVs+;N|8ZDp#o}0j_k|74lFNM+_n;;g?-o(IQ%D}*|YZD~I zK0w9)Y=T%Iy&2*#{mqb&aor5@Y0zd!2qbKV*q6T<5;YC=n;|}&u^Hl`ZBPv-p&G73 z#h-14lw?0QLqbAi3nawkwm>Xa+X4x4t1XbIbKL@QNEB3E!4?Jvbp{58iY*WaE!YBy z+WK`{AU@j)Rd8hsBuM{274U3@@P)TR5|Q#&NOrW{3bEK3DjyCNPu~i0SngIx6qas< zghbs|h=tuy@kv|39$XCCczi3whmW>G(!!gqkf3JX25~6=Hb~s+Z37#? z;IIu6l)>8|L7Tk|Vo}XDhy$CqK|*BuHUUXEFmQtMzr+qmiKny!l1S`#K;qJG2c!s%+ySwuY6rweJy7ulQ1OF1AR%}e zs_)GXNCiP*`&P!FnXa(6-uZiY%shtg}H^ue7F1F!9b z`1}D>{0&r`aTg>ixOYLKP;M7Qo#ieD25klg2G?DX>b!6l#NruH`L(+k>cRE%&Rr0f zUD*W*>SwzkLH}(RBr5*yfmxWX&E(++N-T zNfUSWKtkZ{9!P3u*vr6R!@$76yB89bUV9-S61o>+ej-%7xPC7r@zm{QV6bCgV3@NP z;*i^WAx*0Hdm%2B+6QsD(mqH?80`b4UIqrAeGmsE?PFkYVPIe=-Uo5Oj(w1Pesmwi z;>-IWY2^MsNSgQorR(|kLxNImKP0Z4_d^_zzaL_7^L~iMQ}#m~vSdFbh}Z0gq~?SB z85lGe7#NQ4hlJ3F{g9C0J^(RC?f@iF8y#R^&;wO=P`cm%*xY)C`3D#n%orFL)7euwr0fP&^1RIOZV4!TARv@;wK^1~Du=2ubA|4?;rd{y_!?BL)VB zp9djPsB;J+?{Wy@k)lJO5Ugils5%4*vI&PEaX$ADB+ix}f&|^BLy(}{2Ngea2;%eW zhaidS?jcB8cyfq=p$gQRKE%La&%nTtahQRDnSp^}#bJoKYYsya>9)fliy0X19A;pU z1m*uvPz5|kAR5JvFfjNqFffE2fkeULBM=8|IRf$d{v!|v-8llW_|*|eIq~@jr2Qar zlz~B!fq}u~D8%PsMcN7w`O-CUPpK_Fep&pcNWF{l%50Czx)`)A-j%2qT<{!hI(+j|Iaaq zPgssaEap89X{m@Ghd99aIK*PR;}8qnjzbIzI?lkL%)r2qb{vwryN*MAxEQK$>v4!r z4?y)Fhw48MmA`$w9uoJ@jzhA==i`u|0*ez6gFR0`d>VZMlG-z&@-0yH zQ%^wZkVQ~+M^8W;e)$B%gSVmd6R3G_>rX&@`2PgNM_eZ%K9M^Ki97R?5RLvPAt4iS z5)ws8Cn0H}?<6EBSD%FFzj+c8LT^t(Jn-`*q}F6R1yQGZ3gVIAQxJRWQ%^x$TyP3v z@Z?hv4f{_)LgXHl{(1_MsCZ68EYO3}R;M8bxt(TU$YW$+2s{mGO&>S|38^1vAo6Ty zAt51n7Q&Z23(mgv3@T6oONao2%UOtzBhNw-UD8=d{w_TWDQH@u;_J>re0&fpeif?j z-&u%H`OZOnYI6=^jvtgxJO_!ol5-&a^$ZOC=O8Xxd=3)#>&`*q{QNnHiyxeWIN-%O zNEG}y2kE3TorhSEb{?X?;ylPe28L!RJ^ef+1XrJjB`XZEmaGrrd0hIsWpNCi= zZ~+qc3Kt-4HOmW-I83|%F*pw@-vs5)z5otFhV>U9K0I;(lK-z?fP~cd3y_jf;UdIC zRu>`ay)Q!QoP>)E4E3OXe;rg{E|lJV5mL+Dya;hQ!zG9V`7c3yEPn|SMTStm)g?$s z`9Rf$K*duoL3&hWQ1y$U^qNZ$hitvXP!H~QpMn~2;Swa#+_(hEx6dvyFld5`)Ju@u zAbuI*a{bE?2l!rwI4tZkBnr|lLws6z84^`ZQ1PD23=A<03=Gqu@?S1P9Kd>|9%7)> z6-c76xB~HU@D)hGl5_V1_wb!~Ukjm)p6-ZewaTSs)?5;8}crq|BBwU3=!K$l} zC_8l(5@PqRLUPrIs|*am3=9nX*C2I3a{V=kg_YMJ*{b6jB+jQm`3tW>e7g1;#K3LW zAeGOlYY-n_fae8v2DA~z;Ky?f#D>SKlcWtQ@P;=#5|#!5TC2vgs8W;2?=TM zn~*5Wya{$#JwxS9NPg{tYS?iT68EQWLK4-*n~+3w^CrZBY_}i=^WTE_NbwfLC)T$h z4i3HriGqwSZ$avmUAG_(xpoUwg4Q!Ie1R$yyba0!8n+=9d)|iRg23Ah z4Emt1(`|^wD{e!AaMx`}NF9OdyL=lG1z&D6Ftjl+FfiSLsOyB%lkY$rI`MhBO8S zhT9Jq7t2G1R2EYdIVAT z^by3O&yOGuV}1-VN8&LgYSbSy)Pn~O?H)sdHuEvWht-cEQSjg~149D?1H+5Q3=ESP z7#K32FfcSTFfjai0tv!~r;s3Se+sd9;!_5OPzDBuH%}q?-RT)5yUu^cz`)4Bz;Nps z1A_qr1H+wX5PiJQHy<+C5YKL|U}RurV6?e%LY**6S!QnH=0A%cIjfAX7~U>sV31>AVEDI~fq|cafkAc&0|O5O1B31o1_l-e1_rAo z3=Dh>3=H;Aala)D48jZy4ADy<>hqT{FlaF_Fw`$$V9;e?U|6+;fkBdif#C*J-KQlC z3`z_P3~Wmo7`Pc27&M`@=~9Mzu)&T?85r0Z7#ISUGB6}FFfc?cWnfTaU|`s@l!3vP zfq~)iQiw&0%OD0AE@NQW%)r24yA0xxkINVs*cccXSeG*}a4|42@GNIw;9y{25MR!~ zAjQDIps<{QL4kpR!Fo9ZgERvJLkv{DVtG9S11AFmL*sG=237_JhVJDI4Dt*N3=@|# zFbFX)Fl<~7aru$u3=AR+3=GegGcd?9FfjaC4snRo3P?z)t$R{F)%PJT*1H~3bJ4Y1H&=~1_q&(5TET_ z39;zFN{GQ{q5QimAr5=B5)y*{p?vmL5Rb{Mf`pLTDo7MsLHV9g`TAHWBYhPE11K#N zu7WtIX%!?Wr>uhbX#OgQ16D)%J61tL>c}dHPo6;OKdT^dFR~gEzX zacJ#o1_lWRhI)opsKmV0kRaT#nt?%vfq~)RYKRZ+t%d~I3#dWwRzrNkv<70Z;2Ma7 zRo6f~V7>+-?*XO5p>!HlT`5#u`x;Ql)iW^6Si`_z&cML1b`1lA4g&+j(=`kXNuZ!# z3yJ&EwGfBQSPQXm(OO8zY+DPl@E}zD(ppH=JX;HKz&9wLbsYl(F9QRE=sHMLDzAft zm=;L9o`HeEX&ppkz&c2fCai;4*su;_Vb?l{Mf0Hi_3I#MidVg!XMXtN5(0^vA@&t)hD1$c{bq;{XKseLXggHHDX4}U zQ1R!RAtl+b&5)1~-2w?Q`7IEO)we)`+fE+K91;yxSGa|NL7jntp>hkvK?}D) zqPBkh7KqQbK^0ux0twQ;PzAhOA$*aokVK@i6_Oq8wn8j+fyzff#WS`-9G15g5`|@3 zAt6z}6=GozRDAMQu!rjz=4^!o`TDI8AD-9>@!{jGkhJi2D!uniKo`rE(; zFgR|51ZBuJNYLhNgIH9%4dTF-ZIBR|v5kSj1eDFUK^*vK8z_Y885mw|gZPYLJ0!nL zZHFkZ-3~Fxbvq;ke6~X@h}jNtQ0{h!Ln^mJqOcn(zH&RH*4(-s5(2xR^x^H0kUO)T zfx(S|f#K421_n-0{+HYVDe;tdKoW_=4oF=3?|>AcQ9B?ORqufKs23`}5GsCX2P6cq zK=r-d0SUn$J0Ky*v=dS-OYVf2c*V&L_i z5T8GUiob=5Gwp&z16w2>{sI%I|z@W{*z~HtEQk@s=f>=BgD!*u+XJD!_COpGw+G_mf<2JLRka6V@uWQvpRC;jiQ6lC zAZg<69!Lnh+XG4MjC&avY#10A`1V4g(t9r?M8ft$%uj-fm(=ftBpwiL$H2facQ3>t zclJV>R3G+2Tq?Z};&SDEkdQFm2THvR48Hpy4oKd|z~I8bz)-Re;((p|Ao={*K8VFv z_CeCfgME-R@e@kd3+#skrTTtIT)FIrIG|uZ#Nd|w5R0eohd5;Een=3n-4994hxRit zXfQA^oY)Tup^y6^A;EJ1VvhU)NTN1Az`&pfs_dY2;Q_F@^$ZIRFff=gFfeR@YIuGC z5=6fbKrG@t$iQI5z`&q%5MprbL5PD34npL64}uM1SacAQ$~PT^gwTV73=BpL3=F>x zLZVRj5JcYf5X2+Jhd?1%&%jW92ohuy4?*I5-XTbwtvCb;y3L0mLAf6)e)bT==Qj>P z64kv!khJjh5CcOM0|UdmLktY|3=9mJhZz`{85kH=9)_5^_An%oZa)mNn1SK$VFm_C zQ2zf6Rls`$qEY+^1A`9(14H-`NE9qN0&&pRBM_e-I0A9d-6If-Umt;#6JL%%+7F^f z85k597#K{CLVO;66cQErMOt9N4piZxqmVRk>nOyA6t-D~>@Nvile$D$XBcs0X+E{~m+* zg!MSYV!q>$mWsr2hyzTHLoBvG4za-fIK-gf;|vVS3=9nE$04b^`#8jhOQ8C;9f$bz zAXNVesQwF3`8&t!A#wlwI3!zqISvU*?h_DkofD8Kusi`V*y{wur!glWsXYrS-wIVf z?F6I_SqxQo>;%N&S581Ycn3;9g_`%S{shE_3@0Hz;ywxSiTp`O+*zE2XbdG#o!TjgM?y|P?5$5b1#xlVDTu*S zPC+yrI0Xrj`%wDZDM+H?Jq@uyA4*%Fh8X02nt>sYk%1xTG^90s@C+oRex8BIv!8{8 zgwR@1|9X@iQdKMM)5Ls0Q+P<8*$ zLVU`94&qbWa}aa

    )zYNYs^{1L?14V3=?Y;-V$zAaTF`93;*!oP)Ud;W>x{UY>(Q z!OwG$PAcn!Z~@}OqZc6g|HcJKNd33~DG3!XLOf)B z5u)DbBBahqyvV>%59;^VLj~qR={*-2z}@d#7a=ZZyaaKez$J)}6)r)d$Oy`}z61#= zU#PlJsCeonNRO%cQRa(@+C0UVS0FwPxdJIzlCMCbqWub__F8`hQW@R50x8QSuR?N#{Z$4APX-2t#H)}fSbY@| zWv8z~LhSxkNUr*Lm4P9cfq_Bb8l(iF3DJ7j>kxxuuR|;R$YfAw(Zv$7%np~Fr0$&=iPvGDmUJMm?wM_;&b(z5cQTfAtCK^ z6B1=vH^C08XQ;Xf$*!-+KqrAvkjfGTJ447t+ZLyvx9Fi-Ccm{VpVNCEa6SNMT@LSaT1Ocm(f5$_w@T z3=9Db3=9tUAt5mFJ_AD?0|Udd`w)k#K7b_N&<79)v^;=B!JG#S4D}$Nt$Dz}kjB8k zaOVL7gD(REgY!d3&`x{^(YX2{#HY6&LVWlV%K!cl9ES{Sj~Ez=LBnm2AcI)lk09!v zJ%U*D+AVJvp6cWT8Pazghddk2M3L4OS3d!%z&mh@#!7~O1Mg|6k+s_~& za`zcTAMf+chYU8vvzsXxnp+tgZ?2qBC(K%sUzAz8`S;?7PF&gfxv6<2rTHa^lQ*`j KZRUO6#RUMx1+$C* diff --git a/locale/lt_LT/LC_MESSAGES/django.po b/locale/lt_LT/LC_MESSAGES/django.po index 494c2e6c8..9928785a6 100644 --- a/locale/lt_LT/LC_MESSAGES/django.po +++ b/locale/lt_LT/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-16 17:33\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 20:02\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Lithuanian\n" "Language: lt\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Vartotojas su šiuo el. pašto adresu jau yra." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Diena" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Savaitė" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Mėnuo" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "Galiojimas nesibaigia" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} naudoja" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Neribota" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Sąrašo užsakymas" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Knygos antraštė" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Įvertinimas" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Rūšiuoti pagal" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Didėjančia tvarka" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Mažėjančia tvarka" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Klaida įkeliant knygą" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "Nepavyko rasti tokios knygos" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "Laukiama" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español (Ispanų)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français (Prancūzų)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Português - Brasil (Portugalų–brazilų)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文 (Supaprastinta kinų)" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文 (Tradicinė kinų)" @@ -1420,7 +1428,7 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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." @@ -1429,12 +1437,12 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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." @@ -1443,45 +1451,45 @@ msgstr[1] "" msgstr[2] "" msgstr[3] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "Eilutė" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Pavadinimas" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "ISBN" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autorius" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "Peržiūra" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Knyga" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1491,18 +1499,34 @@ msgstr "Knyga" msgid "Status" msgstr "Būsena" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importuota" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1512,12 +1536,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Patvirtinti" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "Atmesti" @@ -1698,7 +1722,7 @@ msgstr "Pakvietimai" #: bookwyrm/templates/layout.html:132 msgid "Admin" -msgstr "Administratorius" +msgstr "Administravimas" #: bookwyrm/templates/layout.html:139 msgid "Log out" @@ -3627,7 +3651,7 @@ msgstr "redaguota %(date)s" #: bookwyrm/templates/snippets/status/headers/comment.html:2 #, python-format msgid "commented on %(book)s" -msgstr "komentuota %(book)s" +msgstr "pakomentavo %(book)s" #: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format diff --git a/locale/pt_BR/LC_MESSAGES/django.mo b/locale/pt_BR/LC_MESSAGES/django.mo index dd430b3ae3e17cf023d1419fd26eefc3f9d498bd..ea48a5e7afd1558dd11af9e0f9a39a6d8a0abbd2 100644 GIT binary patch delta 18492 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

    Hx^y|jA(NLwELyf4 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 diff --git a/locale/pt_BR/LC_MESSAGES/django.po b/locale/pt_BR/LC_MESSAGES/django.po index a7ea1a86a..ad50793ec 100644 --- a/locale/pt_BR/LC_MESSAGES/django.po +++ b/locale/pt_BR/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-16 00:36\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 23:52\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Portuguese, Brazilian\n" "Language: pt\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "Já existe um usuário com este endereço de e-mail." -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "Um dia" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "Uma semana" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "Um mês" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "Não expira" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} usos" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "Ilimitado" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "Ordem de inserção" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "Título do livro" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 bookwyrm/templates/shelf/shelf.html:149 #: bookwyrm/templates/shelf/shelf.html:181 #: bookwyrm/templates/snippets/create_status/review.html:33 msgid "Rating" msgstr "Avaliação" -#: bookwyrm/forms.py:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "Organizar por" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "Crescente" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "Decrescente" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "Erro ao carregar livro" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "Não foi possível encontrar o livro" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "Pendente" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español (Espanhol)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "Galego (Galego)" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français (Francês)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "Lietuvių (Lituano)" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "Português - Brasil (Brazilian Portuguese)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文 (Chinês simplificado)" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文 (Chinês tradicional)" @@ -1410,64 +1418,64 @@ msgstr "Em curso" msgid "Refresh" msgstr "Atualizar" -#: bookwyrm/templates/import/import_status.html:62 +#: 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] "%(display_counter)s item precisa de aprovação manual." msgstr[1] "%(display_counter)s itens precisam de aprovação manual." -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "Revisar itens" -#: bookwyrm/templates/import/import_status.html:73 +#: 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] "Falha ao importar %(display_counter)s item." msgstr[1] "Falha ao importar %(display_counter)s itens." -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "Ver e solucionar importações fracassadas" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "Linha" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "Título" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "ISBN" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "Autor" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "Estante" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "Resenhar" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "Livro" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1477,18 +1485,34 @@ msgstr "Livro" msgid "Status" msgstr "Publicação" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "Pré-visualização de importação indisponível." + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "Visualizar resenha importada" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "Importado" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "Precisa de resenha manual" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +msgstr "Tentar novamente" + +#: 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 "Esta importação está em um formato antigo que não é mais compatível. Se quiser resolver alguns itens faltantes dessa importação, clique no botão abaixo para atualizar o formato da importação." + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "Atualizar importação" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1498,12 +1522,12 @@ msgstr "Solução de problemas de importação" 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 "Aprovar uma sugestão adicionará permanentemente o livro sugerido às suas estantes e associará suas datas de leitura, resenhas e avaliações aos do livro." -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "Aprovar" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "Rejeitar" diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index bb04744d8..1b86621df 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-15 20:22\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 18:42\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Chinese Simplified\n" "Language: zh\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "已经存在使用该邮箱的用户。" -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "一周" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "一个月" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "{i} 次使用" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "列表顺序" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "书名" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 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:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "降序" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "加载书籍时出错" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "找不到匹配的书" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "待处理" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español(西班牙语)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français(法语)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "葡萄牙语-巴西(巴西的葡语)" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "简体中文" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文(繁体中文)" @@ -1405,62 +1413,62 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "标题" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "书评" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "书目" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1470,18 +1478,34 @@ msgstr "书目" msgid "Status" msgstr "状态" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "已导入" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1491,12 +1515,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "批准" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 9b6e27b8c..4ca2a071a 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/LC_MESSAGES/django.po @@ -2,8 +2,8 @@ msgid "" msgstr "" "Project-Id-Version: bookwyrm\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-11-14 15:08+0000\n" -"PO-Revision-Date: 2021-11-15 18:02\n" +"POT-Creation-Date: 2021-11-17 18:03+0000\n" +"PO-Revision-Date: 2021-11-17 18:41\n" "Last-Translator: Mouse Reeve \n" "Language-Team: Chinese Traditional\n" "Language: zh\n" @@ -17,71 +17,71 @@ msgstr "" "X-Crowdin-File: /[bookwyrm-social.bookwyrm] main/locale/en_US/LC_MESSAGES/django.po\n" "X-Crowdin-File-ID: 1553\n" -#: bookwyrm/forms.py:242 +#: bookwyrm/forms.py:248 msgid "A user with this email already exists." msgstr "已經存在使用該郵箱的使用者。" -#: bookwyrm/forms.py:256 +#: bookwyrm/forms.py:262 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:263 msgid "One Week" msgstr "一週" -#: bookwyrm/forms.py:258 +#: bookwyrm/forms.py:264 msgid "One Month" msgstr "一個月" -#: bookwyrm/forms.py:259 +#: bookwyrm/forms.py:265 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:269 #, python-brace-format msgid "{i} uses" msgstr "" -#: bookwyrm/forms.py:264 +#: bookwyrm/forms.py:270 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:332 +#: bookwyrm/forms.py:338 msgid "List Order" msgstr "列表順序" -#: bookwyrm/forms.py:333 +#: bookwyrm/forms.py:339 msgid "Book Title" msgstr "書名" -#: bookwyrm/forms.py:334 bookwyrm/templates/shelf/shelf.html:149 +#: bookwyrm/forms.py:340 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:336 bookwyrm/templates/lists/list.html:110 +#: bookwyrm/forms.py:342 bookwyrm/templates/lists/list.html:110 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:340 +#: bookwyrm/forms.py:346 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:341 +#: bookwyrm/forms.py:347 msgid "Descending" msgstr "降序" -#: bookwyrm/importers/importer.py:127 +#: bookwyrm/importers/importer.py:141 bookwyrm/importers/importer.py:163 msgid "Error loading book" msgstr "" -#: bookwyrm/importers/importer.py:135 +#: bookwyrm/importers/importer.py:150 msgid "Could not find a match for book" msgstr "" #: bookwyrm/models/base_model.py:17 -#: bookwyrm/templates/import/import_status.html:171 +#: bookwyrm/templates/import/import_status.html:190 msgid "Pending" msgstr "" @@ -183,18 +183,26 @@ msgid "Español (Spanish)" msgstr "Español(西班牙語)" #: bookwyrm/settings.py:168 +msgid "Galego (Galician)" +msgstr "" + +#: bookwyrm/settings.py:169 msgid "Français (French)" msgstr "Français(法語)" -#: bookwyrm/settings.py:169 +#: bookwyrm/settings.py:170 +msgid "Lietuvių (Lithuanian)" +msgstr "" + +#: bookwyrm/settings.py:171 msgid "Português - Brasil (Brazilian Portuguese)" msgstr "" -#: bookwyrm/settings.py:170 +#: bookwyrm/settings.py:172 msgid "简体中文 (Simplified Chinese)" msgstr "簡體中文" -#: bookwyrm/settings.py:171 +#: bookwyrm/settings.py:173 msgid "繁體中文 (Traditional Chinese)" msgstr "繁體中文" @@ -1405,62 +1413,62 @@ msgstr "" msgid "Refresh" msgstr "" -#: bookwyrm/templates/import/import_status.html:62 +#: 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] "" -#: bookwyrm/templates/import/import_status.html:67 +#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/manual_review.html:8 msgid "Review items" msgstr "" -#: bookwyrm/templates/import/import_status.html:73 +#: 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] "" -#: bookwyrm/templates/import/import_status.html:79 +#: bookwyrm/templates/import/import_status.html:88 msgid "View and troubleshoot failed items" msgstr "" -#: bookwyrm/templates/import/import_status.html:91 +#: bookwyrm/templates/import/import_status.html:100 msgid "Row" msgstr "" -#: bookwyrm/templates/import/import_status.html:94 +#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:163 msgid "Title" msgstr "標題" -#: bookwyrm/templates/import/import_status.html:97 +#: bookwyrm/templates/import/import_status.html:106 msgid "ISBN" msgstr "" -#: bookwyrm/templates/import/import_status.html:100 +#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:166 msgid "Author" msgstr "作者" -#: bookwyrm/templates/import/import_status.html:103 +#: bookwyrm/templates/import/import_status.html:112 msgid "Shelf" msgstr "" -#: bookwyrm/templates/import/import_status.html:106 +#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/snippets/create_status.html:17 msgid "Review" msgstr "書評" -#: bookwyrm/templates/import/import_status.html:110 +#: bookwyrm/templates/import/import_status.html:119 msgid "Book" msgstr "書目" -#: bookwyrm/templates/import/import_status.html:113 +#: bookwyrm/templates/import/import_status.html:122 #: bookwyrm/templates/settings/announcements/announcements.html:38 #: bookwyrm/templates/settings/federation/instance_list.html:46 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:44 @@ -1470,18 +1478,34 @@ msgstr "書目" msgid "Status" msgstr "狀態" -#: bookwyrm/templates/import/import_status.html:144 +#: bookwyrm/templates/import/import_status.html:130 +msgid "Import preview unavailable." +msgstr "" + +#: bookwyrm/templates/import/import_status.html:162 msgid "View imported review" msgstr "" -#: bookwyrm/templates/import/import_status.html:158 +#: bookwyrm/templates/import/import_status.html:176 msgid "Imported" msgstr "已匯入" -#: bookwyrm/templates/import/import_status.html:164 +#: bookwyrm/templates/import/import_status.html:182 msgid "Needs manual review" msgstr "" +#: bookwyrm/templates/import/import_status.html:195 +msgid "Retry" +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 "" + +#: bookwyrm/templates/import/import_status.html:215 +msgid "Update import" +msgstr "" + #: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/troubleshoot.html:4 msgid "Import Troubleshooting" @@ -1491,12 +1515,12 @@ msgstr "" 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 "" -#: bookwyrm/templates/import/manual_review.html:56 +#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/lists/curate.html:57 msgid "Approve" msgstr "批准" -#: bookwyrm/templates/import/manual_review.html:64 +#: bookwyrm/templates/import/manual_review.html:66 msgid "Reject" msgstr "" From 3787a31c67385cfdf2b9c9944a1d86649be9007c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 18 Nov 2021 14:39:22 -0800 Subject: [PATCH 131/134] Updates image helpers on site --- bookwyrm/models/site.py | 23 +++++++++++++++++++---- bookwyrm/templates/email/preview.html | 2 +- bookwyrm/views/wellknown.py | 13 +++---------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/bookwyrm/models/site.py b/bookwyrm/models/site.py index a5d2df4e3..5d91553e3 100644 --- a/bookwyrm/models/site.py +++ b/bookwyrm/models/site.py @@ -68,12 +68,27 @@ class SiteSettings(models.Model): default_settings.save() return default_settings + @property + def logo_url(self): + """helper to build the logo url""" + return self.get_url("logo", "images/logo.png") + @property def logo_small_url(self): - """ helper to build the lgoo url """ - if self.logo_small: - return get_absolute_url(self.logo_small) - return urljoin(STATIC_FULL_URL, "images/logo-small.png") + """helper to build the logo url""" + return self.get_url("logo_small", "images/logo-small.png") + + @property + def favicon_url(self): + """helper to build the logo url""" + return self.get_url("favicon", "images/favicon.png") + + def get_url(self, field, default_path): + """get a media url or a default static path""" + uploaded = getattr(self, field, None) + if uploaded: + return get_absolute_url(uploaded) + return urljoin(STATIC_FULL_URL, default_path) class SiteInvite(models.Model): diff --git a/bookwyrm/templates/email/preview.html b/bookwyrm/templates/email/preview.html index 66d856c08..42f8707a3 100644 --- a/bookwyrm/templates/email/preview.html +++ b/bookwyrm/templates/email/preview.html @@ -1,4 +1,4 @@ - +

    Subject: {% include subject_path %} diff --git a/bookwyrm/views/wellknown.py b/bookwyrm/views/wellknown.py index a9b35b637..04aa88bf2 100644 --- a/bookwyrm/views/wellknown.py +++ b/bookwyrm/views/wellknown.py @@ -9,7 +9,7 @@ from django.utils import timezone from django.views.decorators.http import require_GET from bookwyrm import models -from bookwyrm.settings import DOMAIN, VERSION, MEDIA_FULL_URL, STATIC_FULL_URL +from bookwyrm.settings import DOMAIN, VERSION @require_GET @@ -93,7 +93,7 @@ def instance_info(_): status_count = models.Status.objects.filter(user__local=True, deleted=False).count() site = models.SiteSettings.get() - logo = get_image_url(site.logo, "logo.png") + logo = site.logo_url return JsonResponse( { "uri": DOMAIN, @@ -134,14 +134,7 @@ def host_meta(request): def opensearch(request): """Open Search xml spec""" site = models.SiteSettings.get() - image = get_image_url(site.favicon, "favicon.png") + image = site.favicon_url return TemplateResponse( request, "opensearch.xml", {"image": image, "DOMAIN": DOMAIN} ) - - -def get_image_url(obj, fallback): - """helper for loading the full path to an image""" - if obj: - return f"{MEDIA_FULL_URL}{obj}" - return f"{STATIC_FULL_URL}images/{fallback}" From 21c90ac99ee848c25bcc62eac3beb3f2cf691d93 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 18 Nov 2021 14:51:00 -0800 Subject: [PATCH 132/134] Use groups not permissions --- bookwyrm/emailing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index dbf2369e9..fab1a2d54 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -48,7 +48,7 @@ def moderation_report_email(report): data["reportee"] = report.user.localname or report.user.username data["report_link"] = report.remote_id - for admin in models.User.objects.filter(permissions="moderate_user"): + for admin in models.User.objects.filter(groups__name="moderator"): data["user"] = admin.display_name send_email.delay(admin.email, *format_email("moderation_report", data)) From 417f09690f4c3017c729324279a86e36d0e9c229 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 18 Nov 2021 15:08:00 -0800 Subject: [PATCH 133/134] Include admin and moderator in reporting email --- bookwyrm/emailing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/emailing.py b/bookwyrm/emailing.py index fab1a2d54..08fd9ef85 100644 --- a/bookwyrm/emailing.py +++ b/bookwyrm/emailing.py @@ -48,7 +48,7 @@ def moderation_report_email(report): data["reportee"] = report.user.localname or report.user.username data["report_link"] = report.remote_id - for admin in models.User.objects.filter(groups__name="moderator"): + for admin in models.User.objects.filter(groups__name__in=["admin", "moderator"]): data["user"] = admin.display_name send_email.delay(admin.email, *format_email("moderation_report", data)) From 7ac3d5da7c2758de905b855905c40da670dd9b43 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 19 Nov 2021 09:33:51 -0800 Subject: [PATCH 134/134] Full coverage in Galician locale! --- locale/de_DE/LC_MESSAGES/django.mo | Bin 30883 -> 60544 bytes locale/fr_FR/LC_MESSAGES/django.mo | Bin 44850 -> 65002 bytes locale/gl_ES/LC_MESSAGES/django.mo | Bin 48434 -> 55932 bytes locale/gl_ES/LC_MESSAGES/django.po | 208 +++++++++++++-------------- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 44096 -> 56164 bytes locale/zh_Hant/LC_MESSAGES/django.mo | Bin 38839 -> 37625 bytes 6 files changed, 104 insertions(+), 104 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.mo b/locale/de_DE/LC_MESSAGES/django.mo index 4ce83f72b3f3850c58528f13afcd23442a75a515..fe402ad72b85652f0f99396feb4ce8486ff03152 100644 GIT binary patch literal 60544 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 B1_ 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 UY0tE$Yo~)Z0E1e@SdM@N08wWSegFUf delta 16292 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 bJG>HPr$T97D%^5~l+?+gf2L1f^j8P~Hun!& diff --git a/locale/gl_ES/LC_MESSAGES/django.mo b/locale/gl_ES/LC_MESSAGES/django.mo index 0381a352ab63a4fbcaa81df21704f212e27db786..ad56b337193c5e6c8d5aab3c5f952421a6aa57a8 100644 GIT binary patch delta 20338 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 delta 14553 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\n" "Language-Team: Galician\n" "Language: gl\n" @@ -2070,32 +2070,32 @@ msgstr "respondeu ao teu replied to your quote from %(book_title)s" -msgstr "" +msgstr "respondeu á túa cita de %(book_title)s" #: bookwyrm/templates/notifications/items/reply.html:39 #, python-format msgid "replied to your status" -msgstr "" +msgstr "respondeu ao teu estado" #: bookwyrm/templates/notifications/items/report.html:15 #, python-format msgid "A new report needs moderation." -msgstr "" +msgstr "Hai unha nova denuncia para moderar." #: bookwyrm/templates/notifications/items/update.html:16 #, python-format msgid "has changed the privacy level for %(group_name)s" -msgstr "" +msgstr "cambiou o nivel de privacidade de %(group_name)s" #: bookwyrm/templates/notifications/items/update.html:20 #, python-format msgid "has changed the name of %(group_name)s" -msgstr "" +msgstr "cambiou o nome a %(group_name)s" #: bookwyrm/templates/notifications/items/update.html:24 #, python-format msgid "has changed the description of %(group_name)s" -msgstr "" +msgstr "cambiou a descrición de %(group_name)s" #: bookwyrm/templates/notifications/notifications_page.html:18 msgid "Delete notifications" @@ -2568,89 +2568,89 @@ msgstr "Editar" #: bookwyrm/templates/settings/federation/instance.html:79 msgid "No notes" -msgstr "" +msgstr "Sen notas" #: bookwyrm/templates/settings/federation/instance.html:94 #: bookwyrm/templates/settings/users/user_moderation_actions.html:8 msgid "Actions" -msgstr "" +msgstr "Accións" #: bookwyrm/templates/settings/federation/instance.html:98 #: bookwyrm/templates/snippets/block_button.html:5 msgid "Block" -msgstr "" +msgstr "Bloquear" #: bookwyrm/templates/settings/federation/instance.html:99 msgid "All users from this instance will be deactivated." -msgstr "" +msgstr "Tódalas usuarias desta instancia serán desactivadas." #: bookwyrm/templates/settings/federation/instance.html:104 #: bookwyrm/templates/snippets/block_button.html:10 msgid "Un-block" -msgstr "" +msgstr "Desbloquear" #: bookwyrm/templates/settings/federation/instance.html:105 msgid "All users from this instance will be re-activated." -msgstr "" +msgstr "Tódalas usuarias desta instancia volverán a estar activas." #: bookwyrm/templates/settings/federation/instance_blocklist.html:6 msgid "Import Blocklist" -msgstr "" +msgstr "Importar Lista de Bloqueo" #: bookwyrm/templates/settings/federation/instance_blocklist.html:26 #: bookwyrm/templates/snippets/goal_progress.html:7 msgid "Success!" -msgstr "" +msgstr "Feito!" #: bookwyrm/templates/settings/federation/instance_blocklist.html:30 msgid "Successfully blocked:" -msgstr "" +msgstr "Bloqueaches a:" #: bookwyrm/templates/settings/federation/instance_blocklist.html:32 msgid "Failed:" -msgstr "" +msgstr "Fallou:" #: bookwyrm/templates/settings/federation/instance_list.html:3 #: bookwyrm/templates/settings/federation/instance_list.html:5 #: bookwyrm/templates/settings/layout.html:45 msgid "Federated Instances" -msgstr "" +msgstr "Instancias federadas" #: bookwyrm/templates/settings/federation/instance_list.html:32 #: bookwyrm/templates/settings/users/server_filter.html:5 msgid "Instance name" -msgstr "" +msgstr "Nome da instancia" #: bookwyrm/templates/settings/federation/instance_list.html:40 msgid "Software" -msgstr "" +msgstr "Software" #: bookwyrm/templates/settings/federation/instance_list.html:63 msgid "No instances found" -msgstr "" +msgstr "Non hai instancias" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:4 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:11 #: bookwyrm/templates/settings/invites/manage_invite_requests.html:25 #: bookwyrm/templates/settings/invites/manage_invites.html:11 msgid "Invite Requests" -msgstr "" +msgstr "Solicitudes de convite" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:23 msgid "Ignored Invite Requests" -msgstr "" +msgstr "Solicitudes de convite ignoradas" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:35 msgid "Date requested" -msgstr "" +msgstr "Data da solicitude" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:39 msgid "Date accepted" -msgstr "" +msgstr "Data de aceptación" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:42 msgid "Email" -msgstr "" +msgstr "Email" #: bookwyrm/templates/settings/invites/manage_invite_requests.html:47 msgid "Action" @@ -2776,99 +2776,99 @@ msgstr "Administración" #: bookwyrm/templates/settings/layout.html:29 msgid "Manage Users" -msgstr "" +msgstr "Xestionar usuarias" #: bookwyrm/templates/settings/layout.html:51 msgid "Moderation" -msgstr "" +msgstr "Moderación" #: bookwyrm/templates/settings/layout.html:55 #: bookwyrm/templates/settings/reports/reports.html:8 #: bookwyrm/templates/settings/reports/reports.html:17 msgid "Reports" -msgstr "" +msgstr "Denuncias" #: bookwyrm/templates/settings/layout.html:68 msgid "Instance Settings" -msgstr "" +msgstr "Axustes da instancia" #: bookwyrm/templates/settings/layout.html:76 #: bookwyrm/templates/settings/site.html:4 #: bookwyrm/templates/settings/site.html:6 msgid "Site Settings" -msgstr "" +msgstr "Axustes da web" #: bookwyrm/templates/settings/reports/report.html:5 #: bookwyrm/templates/settings/reports/report.html:8 #: bookwyrm/templates/settings/reports/report_preview.html:6 #, python-format msgid "Report #%(report_id)s: %(username)s" -msgstr "" +msgstr "Denuncia #%(report_id)s: %(username)s" #: bookwyrm/templates/settings/reports/report.html:9 msgid "Back to reports" -msgstr "" +msgstr "Volver a denuncias" #: bookwyrm/templates/settings/reports/report.html:23 msgid "Moderator Comments" -msgstr "" +msgstr "Comentarios da moderación" #: bookwyrm/templates/settings/reports/report.html:41 #: bookwyrm/templates/snippets/create_status.html:28 msgid "Comment" -msgstr "" +msgstr "Comentario" #: bookwyrm/templates/settings/reports/report.html:46 msgid "Reported statuses" -msgstr "" +msgstr "Estados dununciados" #: bookwyrm/templates/settings/reports/report.html:48 msgid "No statuses reported" -msgstr "" +msgstr "Sen denuncias sobre estados" #: bookwyrm/templates/settings/reports/report.html:54 msgid "Status has been deleted" -msgstr "" +msgstr "O estado foi eliminado" #: bookwyrm/templates/settings/reports/report_preview.html:13 msgid "No notes provided" -msgstr "" +msgstr "Non hai notas" #: bookwyrm/templates/settings/reports/report_preview.html:20 #, python-format msgid "Reported by %(username)s" -msgstr "" +msgstr "Denunciado por %(username)s" #: bookwyrm/templates/settings/reports/report_preview.html:30 msgid "Re-open" -msgstr "" +msgstr "Volver a abrir" #: bookwyrm/templates/settings/reports/report_preview.html:32 msgid "Resolve" -msgstr "" +msgstr "Resolver" #: bookwyrm/templates/settings/reports/reports.html:6 #, python-format msgid "Reports: %(instance_name)s" -msgstr "" +msgstr "Denuncias: %(instance_name)s" #: bookwyrm/templates/settings/reports/reports.html:14 #, python-format msgid "Reports: %(instance_name)s" -msgstr "" +msgstr "Denuncias: %(instance_name)s" #: bookwyrm/templates/settings/reports/reports.html:28 msgid "Resolved" -msgstr "" +msgstr "Resoltas" #: bookwyrm/templates/settings/reports/reports.html:37 msgid "No reports found." -msgstr "" +msgstr "Non hai denuncias." #: bookwyrm/templates/settings/site.html:10 #: bookwyrm/templates/settings/site.html:21 msgid "Instance Info" -msgstr "" +msgstr "Info da instancia" #: bookwyrm/templates/settings/site.html:11 #: bookwyrm/templates/settings/site.html:54 @@ -3084,31 +3084,31 @@ msgstr "Enviar mensaxe directa" #: bookwyrm/templates/settings/users/user_moderation_actions.html:20 msgid "Suspend user" -msgstr "" +msgstr "Usuaria suspendida" #: bookwyrm/templates/settings/users/user_moderation_actions.html:25 msgid "Un-suspend user" -msgstr "" +msgstr "Usuaria reactivada" #: bookwyrm/templates/settings/users/user_moderation_actions.html:47 msgid "Access level:" -msgstr "" +msgstr "Nivel de acceso:" #: bookwyrm/templates/shelf/create_shelf_form.html:5 msgid "Create Shelf" -msgstr "" +msgstr "Crear Estante" #: bookwyrm/templates/shelf/edit_shelf_form.html:5 msgid "Edit Shelf" -msgstr "" +msgstr "Editar estante" #: bookwyrm/templates/shelf/shelf.html:28 bookwyrm/views/shelf/shelf.py:53 msgid "All books" -msgstr "" +msgstr "Tódolos libros" #: bookwyrm/templates/shelf/shelf.html:69 msgid "Create shelf" -msgstr "" +msgstr "Crear estante" #: bookwyrm/templates/shelf/shelf.html:90 #, python-format @@ -3414,240 +3414,240 @@ msgstr "" #: bookwyrm/templates/snippets/goal_form.html:26 msgid "Goal privacy:" -msgstr "" +msgstr "Obxectivo de privacidade:" #: bookwyrm/templates/snippets/goal_form.html:33 #: bookwyrm/templates/snippets/reading_modals/layout.html:13 msgid "Post to feed" -msgstr "" +msgstr "Publicar na cronoloxía" #: bookwyrm/templates/snippets/goal_form.html:37 msgid "Set goal" -msgstr "" +msgstr "Establecer obxectivo" #: bookwyrm/templates/snippets/goal_progress.html:9 #, python-format msgid "%(percent)s%% complete!" -msgstr "" +msgstr "%(percent)s%% completo!" #: bookwyrm/templates/snippets/goal_progress.html:12 #, python-format msgid "You've read %(read_count)s of %(goal_count)s books." -msgstr "" +msgstr "Liches %(read_count)s de %(goal_count)s libros." #: bookwyrm/templates/snippets/goal_progress.html:14 #, python-format msgid "%(username)s has read %(read_count)s of %(goal_count)s books." -msgstr "" +msgstr "%(username)s leu %(read_count)s de %(goal_count)s libros." #: bookwyrm/templates/snippets/page_text.html:8 #, python-format msgid "page %(page)s of %(total_pages)s" -msgstr "" +msgstr "páxina %(page)s de %(total_pages)s" #: bookwyrm/templates/snippets/page_text.html:14 #, python-format msgid "page %(page)s" -msgstr "" +msgstr "páxina %(page)s" #: bookwyrm/templates/snippets/pagination.html:12 msgid "Previous" -msgstr "" +msgstr "Anterior" #: bookwyrm/templates/snippets/pagination.html:23 msgid "Next" -msgstr "" +msgstr "Seguinte" #: bookwyrm/templates/snippets/privacy-icons.html:3 #: bookwyrm/templates/snippets/privacy-icons.html:4 #: bookwyrm/templates/snippets/privacy_select.html:11 #: bookwyrm/templates/snippets/privacy_select_no_followers.html:11 msgid "Public" -msgstr "" +msgstr "Público" #: bookwyrm/templates/snippets/privacy-icons.html:7 #: bookwyrm/templates/snippets/privacy-icons.html:8 #: bookwyrm/templates/snippets/privacy_select.html:14 #: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 msgid "Unlisted" -msgstr "" +msgstr "Non listado" #: bookwyrm/templates/snippets/privacy-icons.html:12 msgid "Followers-only" -msgstr "" +msgstr "Só seguidoras" #: bookwyrm/templates/snippets/privacy_select.html:6 #: bookwyrm/templates/snippets/privacy_select_no_followers.html:6 msgid "Post privacy" -msgstr "" +msgstr "Privacidade da publicación" #: bookwyrm/templates/snippets/privacy_select.html:17 #: bookwyrm/templates/user/relationships/followers.html:6 #: bookwyrm/templates/user/relationships/layout.html:11 msgid "Followers" -msgstr "" +msgstr "Seguidoras" #: bookwyrm/templates/snippets/rate_action.html:4 msgid "Leave a rating" -msgstr "" +msgstr "Fai unha valoración" #: bookwyrm/templates/snippets/rate_action.html:19 msgid "Rate" -msgstr "" +msgstr "Valorar" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:6 #, python-format msgid "Finish \"%(book_title)s\"" -msgstr "" +msgstr "Rematei \"%(book_title)s\"" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:23 #: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:20 #: bookwyrm/templates/snippets/readthrough_form.html:7 msgid "Started reading" -msgstr "" +msgstr "Comecei a ler" #: bookwyrm/templates/snippets/reading_modals/finish_reading_modal.html:31 #: bookwyrm/templates/snippets/readthrough_form.html:20 msgid "Finished reading" -msgstr "" +msgstr "Rematei de ler" #: bookwyrm/templates/snippets/reading_modals/form.html:9 msgid "(Optional)" -msgstr "" +msgstr "(Optativo)" #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:5 #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:50 msgid "Update progress" -msgstr "" +msgstr "Actualización do progreso" #: bookwyrm/templates/snippets/reading_modals/start_reading_modal.html:6 #, python-format msgid "Start \"%(book_title)s\"" -msgstr "" +msgstr "Comecei a ler \"%(book_title)s\"" #: bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html:6 #, python-format msgid "Want to Read \"%(book_title)s\"" -msgstr "" +msgstr "Quero ler \"%(book_title)s\"" #: bookwyrm/templates/snippets/readthrough_form.html:14 msgid "Progress" -msgstr "" +msgstr "Progreso" #: bookwyrm/templates/snippets/register_form.html:32 msgid "Sign Up" -msgstr "" +msgstr "Inscribirse" #: bookwyrm/templates/snippets/report_button.html:6 msgid "Report" -msgstr "" +msgstr "Denunciar" #: bookwyrm/templates/snippets/report_modal.html:6 #, python-format msgid "Report @%(username)s" -msgstr "" +msgstr "Denunciar a @%(username)s" #: bookwyrm/templates/snippets/report_modal.html:23 #, python-format msgid "This report will be sent to %(site_name)s's moderators for review." -msgstr "" +msgstr "Esta denuncia vaise enviar á moderación en %(site_name)s para o seu análise." #: bookwyrm/templates/snippets/report_modal.html:24 msgid "More info about this report:" -msgstr "" +msgstr "Máis info acerca desta denuncia:" #: bookwyrm/templates/snippets/shelf_selector.html:4 msgid "Move book" -msgstr "" +msgstr "Mover libro" #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown.html:5 msgid "More shelves" -msgstr "" +msgstr "Máis estantes" #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:17 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:24 msgid "Start reading" -msgstr "" +msgstr "Comezar a ler" #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:29 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:36 msgid "Want to read" -msgstr "" +msgstr "Quero ler" #: bookwyrm/templates/snippets/shelve_button/shelve_button_dropdown_options.html:62 #, python-format msgid "Remove from %(name)s" -msgstr "" +msgstr "Eliminar de %(name)s" #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:30 msgid "Finish reading" -msgstr "" +msgstr "Rematar a lectura" #: bookwyrm/templates/snippets/status/content_status.html:72 msgid "Content warning" -msgstr "" +msgstr "Aviso sobre o contido" #: bookwyrm/templates/snippets/status/content_status.html:79 msgid "Show status" -msgstr "" +msgstr "Mostrar estado" #: bookwyrm/templates/snippets/status/content_status.html:101 #, python-format msgid "(Page %(page)s)" -msgstr "" +msgstr "(Páxina %(page)s)" #: bookwyrm/templates/snippets/status/content_status.html:103 #, python-format msgid "(%(percent)s%%)" -msgstr "" +msgstr "(%(percent)s%%)" #: bookwyrm/templates/snippets/status/content_status.html:125 msgid "Open image in new window" -msgstr "" +msgstr "Abrir imaxe en nova ventá" #: bookwyrm/templates/snippets/status/content_status.html:144 msgid "Hide status" -msgstr "" +msgstr "Agochar estado" #: bookwyrm/templates/snippets/status/header.html:45 #, python-format msgid "edited %(date)s" -msgstr "" +msgstr "editado %(date)s" #: bookwyrm/templates/snippets/status/headers/comment.html:2 #, python-format msgid "commented on %(book)s" -msgstr "" +msgstr "comentou en %(book)s" #: bookwyrm/templates/snippets/status/headers/note.html:8 #, python-format msgid "replied to %(username)s's status" -msgstr "" +msgstr "respondeu ao estado de %(username)s" #: bookwyrm/templates/snippets/status/headers/quotation.html:2 #, python-format msgid "quoted %(book)s" -msgstr "" +msgstr "citou a %(book)s" #: bookwyrm/templates/snippets/status/headers/rating.html:3 #, python-format msgid "rated %(book)s:" -msgstr "" +msgstr "valorou %(book)s:" #: bookwyrm/templates/snippets/status/headers/read.html:7 #, python-format msgid "finished reading %(book)s" -msgstr "" +msgstr "rematou de ler %(book)s" #: bookwyrm/templates/snippets/status/headers/reading.html:7 #, python-format msgid "started reading %(book)s" -msgstr "" +msgstr "comezou a ler %(book)s" #: bookwyrm/templates/snippets/status/headers/review.html:3 #, python-format msgid "reviewed %(book)s" -msgstr "" +msgstr "recensionou %(book)s" #: bookwyrm/templates/snippets/status/headers/to_read.html:7 #, python-format diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 1d1227f8092b70c68bb692fb532759090142aa83..da41e106d8f6fb8769409570da5a1bc960a3ddee 100644 GIT binary patch delta 27210 zcmX?bgXzgO=K6a=EK?a67#L)k85m?37#LV285q=A7#Q9dfU+uwm2~`I599VoN{7duwh_e;B{tT&|_d=@N#BgkY-?DsB~svFk)a}nCcACcfy&0 zL5zWc;j=RXg98Ht1D6W}LjVH6WJ;NLq1_pTs28OdP3=I4X3=D5w7#PGE z7#RM#Ffb@EFffR^GBEfsFff?8GBAiRFfcT`LgZ(-GBC(8FfeRzWnc(lU|=}s%D|w; zz`&sF1`+pigQ(ANV_;BXU|^_qV_;BZU|?9_2Jy%tHwFethI$5u8*UJbKe;h5m@qIf zFu5}@a4|42n7c#7o!l81R2di;g4`Jx_!t-%D%>GHZFgs2P-b9YSnLk*@o{$shI|GF zhF?%R%Y%U-kAZ>VmInhvFaraFrzZnL0s{lXTu%muC%7zDf-7!ny67;?NB7z9B+^JZYEVqjo+;LX4g$-ux6?E?wQtv-;T{pQ2K zUVj8&ttRD4*32qJh^B;vf+}h&nYt1_qFRJwFBpW>ARvF);8j zFfdp{#XbBO7&sXi7y|tuAsOul3Bhcrc$FVRJy=1DA0){8pa#tJV_*BGYz78~!~jU*I~xEo?>$t#QhgxAc5J(8!3xTACXCa`Fu4iC)50&@{bqHf9#9(14tr!Y%pnfO=gA@Y;gJUQp z3SyviekjD?rcj8(xUEcau_6k7lbh|STQg#w1h#5=KW!iMEEWY;*h9t zh=Z%b85rt81x!;oC@2^hri4S{ZeBRV;+0VTws1&@9E9@EheI56D;$!@UWP-8+IQg) zhcib&)bmF`qE0pf;$!0oh(42? zAR)J;J_-^aS(Il;vgZU7Y7L;vp9%D zJmaAGKPV0ocWH5uL{=CFadADA-xmi7nK@7c7R5m<+!_a|Ob*6DJn$tB;(_0B5QhrH zLs~*o@sJR+h=+*V#zR8PJ)VJ~9#pM{Koum!LmZGA4>71X9%4~PJjBIQp!D2$h=Z2J zGcb5CFfgo%hdAJCJS6DNJ)gmU1cJqx@}BkU{D9O`JnQr6CpwS0BXV0M2N#bL(TaEwTLGP z62)Rk5RWP*K|G*ap9HbcK8bls>8ARUi| zDUhJsmjWq}jzjsNf*sVz8hy%Ky^z>9n+%HLm zgvh#7PzcpCFlFnTIN)MB#GnsQb-&UfLCl{4@u7GIBno9SKt5$)P|1LVh*1W_ z!S)#p4E3P)zDEYcpa7^uR0ab>76SuAat0*s&Or_Qn*j+a=1fR+%#jI6yo#BS{B4*C zaez}M1A{TBPnZemsMKXbEZm<7anOlOh<)cXq3!>hP>qi>AufHL38|faWX*iWkC!~%L4V~7#MQ1AP#HKf`r(DEQm#?vmg$?ngt1gTTuFWRz0K${gMR< zYV~Z04{Wj_E_Q*^zEJV7Y)Bf2%ZB(oHyhG7tcA)ihSIB{`Zi}n9K0tR;*fLM5C`AL zhD7!K`fNxdd7aI`paSX?W<%mwIR|2aeGVkm`{zL7G%5#TKtc}0f$2FApA|sGOLHI| zsL6piv;`_ZIS1nN899&;UJB*cZ-y#70JZQuRN{UPBuL*tHL&GEG>YUx9H5j7aiAuY zZwci)ohyaA;jA$tMD9N_{;$Ve4H zJfu|s$<8)Very3GD)I{$7(_t%zXoc+!~#gRnG02Lu>j(Odj*i7e_H^t_%~ENe<8#{ z(uI&js89$|?^XzLcxWNSqS!)6XEdvjfgzWHfg!ID_0cFJyhcy&Kf_7ptB&Zh`LyG9l z#gN+bR52viyeft`@M|%|A&eyu^Y}|3`ov4>A#tV-70@ez6gYMzkVF**)lgdkad|6L zT_2P`uLPohc?raU>!9L0N+2P0umln^k4qql_$Smnky40*Wa>*H8nsFxE;1>F1i4Eo z#KOQ*NH;nPs$okhBq$F-)mU{ z19%&f9jLr~1tf?~Dj>PQz5)^w zt`(3V_JN9rR6wF2ssfT&(<&ey%ZAYP3?&ti5U7P}Y=_eQ6_5~_UI9t<%OM&Vc2_`r zd<4qB4b}ey%6|vd_Z`Y-uY@>Apb`?~5|s=LM;RCx)G9$9sAph!QwbS%`wmqQTm^}O zL@1qC1qqSrDu_cTR6%?&s|u1x7emF5RY5}HLKP$=u2n%2^Ebi41m&QUBW>-U^qP801kO|e05LsFc3EG`dbw{BVT(5@2?SpDa zBK}tm@sMf_#DPXNkPxw`VPL2SWj}`+h{aJg3=I7Y3=9P|5C<^SLVV0u3yBJeT8IG} zwGer|TF6+gO)X>qvbPqJ_zu@HFl=C8V0c#x8M>Wc$G{NBz`*dP4$^S(hSs`S^$hh4 zL7*YgdPu(gP|pA!=@e*ylmp!j;6Y-B?F|qIzG#3r^@=crS85oKf7#JLyAZcJTRD!=5;zOxsNOsd`hG;Zz zhB(Bz8RFo`W{3rq&5%Lpwq{7&-)@GO`=}Wb0--ICkXh6M3Bj{1kSMrZ-@?G)%fP^J zy9Ltz*KCFGD_S89lVhz63``6R3_n{T1CoDQA!$Lc4PuaE8ze;B+aQT6ybTf+32hLE zO>1Ld&;T{x+aTtjX@i86bUOosGXn!deOf!j!c|a#AMFebjtmS8HXRTH>pB=1ycrl6 z+B+a2aJd8Gqx(==rxPMy*$IiNqn(iQ4rF9S2rZ64nxIHcSF*~MJWBZn}J~x0|SF*4@CW*9?0~Sf#Fdfq``4}0>t1i6CmpNCPJEW1`{DoxzLFa`ND~iY}q{#l1Nuhgx3FiCqfE} zOA{e2p#M& zozB3J4$2i!zVi%7oGzRJiMu~DAP$Y4$-q#-z`#&ElYzk%RKUz+V6bOkU@)2m3Av(K zkj`lLEJ#UscorlZzM2Jbpy=#+NMf^{4GBW$*^tB%F&k3y#m|NWeI``A97@+g=~gJ+ zGaHiKCeH>XDh7rHQ1KN|dOg&fZBTVbp!CIhDC6F2NXzCml>Y}xbIySnEC!{O=Rktm z07^U0f#m(eCZsBhc?fFcxcxgh&@N3;`LYOKwNwWD)0nq(Q7FE z18NcLT!=#?=0fth>Rbi}GX@5Ru(=Qi^+M$r%!MSfwR0gBUxd;(=0Y5BAIg6@mw^E^ z{><=UE+n6N%!Bx#Y#zi%tL8xr*fkH*EI$b42h4}~Fnm75K}qu=>hkA9d{#Cek`3GE zL(;%XsQjV%5RaaO@-NN@IUF?q2Q}z5RKpJ_UvL4$0=WecjoJ$!L2A4JVxi*#h>tuL zKpY&j0OEk81&~}*3{}?-mG6V{=PiIF=A|HUQ2o!a5K{06EQA=`w-93B)P;~#z7#6H zdm+R@hZaH{bbcYkhu5Ltcp_ z@T4;DVu%Zsp|sXwh|3M3v>lZ8hSCvGI(0F`VMS1WE0mrDrRPKGHH#r3wR16~Jh-$N z(hBBUQqRDU$-uy1xdc)IE?xq0$T28=b_pcNt}KE0^d6Lc1Eqg0fjE?7DMVg$DTJ@Q z6w>7~fQp+yX(yv9J&-Q30h}q4XpuJs(Q1fzmsdLVR>=DWnL#zZ4P@ z|Dd$sGDsAtEQ3_PR?8sv^e=-%@iZvEe%>;OOO`?P^$S(if$ z5|!K9^e#2?=c|-x8|M4a)b0@}nU9dWOX15Etbwhq$;5s-R~%q{}oJqL5)7 zl->=s-~^O^4N5%)SSX#f0#ePEuV7%X zWnf^KyaM9Wi(m~53^!IleE1rw{^tsa2iR6ZEaF=Uk(XWx30cjR5RchH>EM+Rk7a_? zf%1RLN{9uMRzeJ#xf0^Sg)1RJyJaOLG3{RoseTVb)t`Y{co|ARfQr9e2`K@;K*hyY zLCjZP1+iFb6{LuEUB$pq51OyfTm^A?*(ylE)4U4egUL{h3s*sE#}!a@dsjhxb_z=0 zTLsA_pP=%8pfu-dh)2X$L(JEN^37I5%=cW)P!C>k5WX4`MDeR3E-i&BtbuCmhiaI! z8q)Gv1r^^3KcgoR%;;H-Ej@H|DUo3;==4TkPxVV z@;jg!rb5N%tbsUm%^FD599jd3lCx0y+8RiE;{F;)Z}}-yzs6cfcGX`CaexPu_OD+H z38JvI5C>#J=`yHzGn7AVEhNYmuZ0BlMyLV1q4I~I>d!;@kD&B>DE$XYbFPD!Beo7= zU%d*HVYm*G`0Svx+d4>4`>lhxI2NidWgR5$3!&nz>mW_4o^_BQ-wxIH6e|B^9VA45 zL-lj7hv=7B54NwKK?lNMFj)_AkquOV=XywW8oM6S$IDv}X+H0Vs=EuNU#*99r@ya< zIFxe(#2kSQ5WXywud)H+b3-U?50?Ag$WW4Uqib09L@jFb8VD;tdd= zY=DX%*Z|39$D#a}Q2GPZg6|u^K4f6s2+_y85mKJWZiF~6dLsja9w`53Y=p$=^o@|T zuy7;9AzPsIX{h+4jgTc*UpGR0X0!>S&vFxl@4N|Okr$MXg3?)=Aaz6)l%BZ>;(#5S zp!xqORN&Gkh>P!Uf~4-}P=h~hg0%mCZh|;aY%_$`+zheM2Fmx@49QmUn<3rrrp*wG z)^CP5V9#bq$liwP`@Wf>9=x1}eG6o4S85AHgUc3(1%XgH1u9;?1!8c^7D#s5xCPRV zKeYuC6`!_193Zk45;EpnAtjz8lpnJd5>jbfAs)@$3eEqePz5zmi8iRhKB)LqD1ZJ| z28IaG!lbQ`#_E5lyzw@O!M58VK6Kdz37Ld#kVISnm2cbzNdq0*Al>j|_1hpm7TgYT zk=%BOL26LG?skYzOt(Wq#2!iqLFv@(5Q{3dL(J)b(o>=4EZPn!uvTt|gv9>skS^LS zsQLBGJ0KQv?|>K}v;(3+eh0*draK@$$b_n^+5vHBBb46>r6)l3Pu~H_W=nQJLShqC z{v1^PDwO{SqOP9dCDg$0P>KIgnr$bfpy1sJ=}s%|gbYx+?Sxnmw-b^`b9O>JP`(r5 zusSH+1{Lpv(o=UrJUC}3BqUdY#p@Xu_CO^LLk+$F<=@*03EJ0C{%^1b1_q8@5Qp*a zf>^8!rL~~6;Vy_i3nR!Orc1 zxcDzroxpC0PsMjbn%(ldA#rNC8{)&H-Hd zg7_X(Bl8}J0la%4J`~>r8RL=L0~v70+5>UGEU5ecFo}K8{I9W(0Xz_?zYpSorhO2f_e1&9_CX9-ybogWMyLTt zpz>Fs^uv9SsCWnEi|>boh{}G*5RAosh`Dk5A@-!!?}xag2rALEAL7E!{g4otxF6z! zQDiK>h&4ARQ=e38mc*K+Fw30Lk~s2Ow#y4l2Ls0K`M}>!AXBq4X)J#_I zLy&=sd50h&dj1e-@k%`d!}mjwwwl9XNFr-K49PAV4?_l(P9271BY`6jas4BZlFb9k zPdNe^bgDf9@yOmIkdU~11Y+^yBao1K1?7K&(m#(dFz|r#KWI7vw0xHLD8%K0P+AU3 zYeQ)ZDD8R_;puapc*P0G81se`koLyK6QKED1_p-TCm>xcj*}3V@|=V;Hib_@EHFID zz|h6Oz~Fuo5(1Y_LLBn+BqV=-g6d;C1&Mp!Q;^Ya*;5P*mJAFGg{L3`535fxFwA3M zV0e5A(vE1VKMh$le)}|}2=+b$NrVMwAPt0hXCOX!c?P16=`5tVT?D1)o`uMtI191( z;aNyN|9BRnU-TSgVk6-kBxLrSgXDtC=O7-aXE_gH2tsK&D6M^-fguAlDRrKKA(VlE zVIfrfJCtU*07)}~7a;oOFF-;@=K{n5_E7QU3k(clpgE-rkdQro0W#Qi?gBUp>KS}4 zLNu0Lged5|2uVZ}E<#2wWx(0D@%{9o($fj$Mxc?5KLHR%6Iz(XQbx2}ix&cYuHa8$m zufQANpkhe60kOCTN>9E4@#!omf5{C3v# zGBPl5F)}dhV_;x-#>BuN&&0s6gOPz@Ark|`awY}_S0)CAlZ*@u+ZY)bPBAbr*fB9M z)H5iGe|k ziGkq&69dC~2FOg;83qQ1UM25L2v?o12}wu}r6_Dqmsa}N^( zgWP0AL-BeaMo24Q0uuwnB?bnDbxaHl|3FEN8KjqiVJp-L`Am?R9~~wJh7?8yhR0AF zxaBCHL_6l6h;Py?Mw^|L5vIxuNXn40Ruw=BLjmT z69a=F69a<;69a<@)Diob7#Nl^GBCu0QYten))*KV_A@asyn!m>VrF3IXJlYl0E&62 zm^u>!LpR7)DEEWoBS_!wA`g^^lQ)K^SUD8EBCg0|Ub)s3SpUn=>*n zFoRsrz`*d4fq`KwNRR=2foq>U&kFlPC;Sd7@!*!_O5(Y@?;1>e}!%nD1 z&>puQP)*MODN98dA=6k#pzu_dxUuMh1rSpwa|M?kW=lLo!H`fq~&E0|P@G69dCE zMh1p!P%+SUIMCKL(8j+yMh1oqCI*JDObqo5M?nff`<|E>7)lrz7^Xs9c#H`$AUhMZ z1euY6;V0A}5G4dvlg7xva0Tj!*Nl*5N#e|q$~%COfnhHL1H&9p!enA#m;y>qj0_CQ zObiSHj0_BO85kInV6{dY0|P@T$YjtiKPCo-=S&O?i$SggtsZ1zV3-8jO~}l^Ulhgr?$t9f zFf=eRFsx)`V3-fe9#EfwmMucnf+;qr#T=ko0#qh|LI-N`Bd`hx0or+13EJcd;eyxX zL7Cu+AH)Xj$pq2D%nS_mHJ~a96da5U47p4U3=XOIpkz7O4H z+6{FSXyyU5Z4oNXu$Pg6;U#Dx2dEMUEzn|MU}%6!o@9b-VcNjNz~Bk0riGXp7?wdT z>1JYJ&KUAv z7#L1N6@j)~K7i>26)B)%iiv??Iw`W*kUl1;dJx-$k%3_~BLhPYX!9Zy1H%)joFFp;LnA2PffRwptU#+bp>m*o#DX9; z$bJDP28J)7RuvNi!#hR>1`9?81`SYA0@Zkfk%8eq0|P@D)N#uh85qtmGB7YPF)-X< zf~-FWDRlyEda-5NY;T5RjWn^GTW@2E70XKT8L8*#?fkBax zfuRUg5P>Q#kn@-r7+!(4(SrQWz`(%H#K5qNiGiUM)K&mB9vK)Ic0uJprh|5{@-s6q zTw`QlkOvir3=9l^Ks%nHE?UIIz_1ClFBs$lsJ$S^T5TtPBi6{^+-R97)EFjz1#Ff=kUFr0;oUtnNh z&;hlrK?Z}@!!bbm(OgWB&f_dbNYCXeBLl-GsKL(}85mxGN>L^ThRI9}3_c*knHd;1 zfr@qp1_nPS28JG}T1h4bhK)>+rM4hD3PGbFphN+c2Z@1FHHcqpg<$I$7!7^qPU(g5lrF)=X6FfuS~0A&eA28MGC3=D^$dZ0=ePBAht6o48% zpgop{nHU(F85kH|gM7}&z>olhdqmV*SL zxEQK#3#hFMYGX1nFnj>DQ zJ0utx7;b|4Vo-;%GBPj-LD|KiZUCshVPs&aV`5-f0MY;|J{cGolo%NpDxvDMEEpIV zQb0>186jJlwV@K{p_VFw`cq5{49rZE6%EDeLCZP=p-Kcm%?41Dgo%N{n-Mau0J4S` zR8%l9Fla!HFkoU}Xk&s51)T(?aj5tX(6)c5S!ST72r~mi6exXz#Gz_H=7F#ZBLl-H zP#b9>R6{Eh1H*nO8>9fV;01Kj0*HMa)C~tEd^AHofMNjD4hF>-RIeW+1H)$~28NkX zzBnUfkZdDpuQ8~?V`5;4U}9kS!w6cx2&y?47#Lz085lZ1E&{a_KsG{g71Tn|*%6jZ z3=B&^Z6gK-hA#{Z3`>|GgIpa<3=CbMb~C6hVPs%f1GV@vBLhP!69dB$P`U)ID`c8{ z&&;hpC9}97C$TazNJsA^!B068!tF()m) zD6u3nFI}@(p|~UwWC5n&WOws>vU!QQshY(KMXBkT#U&s;`FRSN#R|ze`NgRzla(xH z3KeITq{c&)6{jW^C1-5jVG+m3Q;=GeoC*prl)EaPmZ(F(AEgcOf83oR*$PYZOHxxNAIOnM7G^C< z#3DMmus|J2Rnp`Jn@|O)VZ}E3iFOP&skwH3`3iaYC8@Xsl~+%jwvY$pg4iBlJm<_i@;(j`MHUi zd0=K{UU5lcUUDj!lb2eqkeiyDlv-4*IJwh4gB5JdU%9XJ>>6iSK` z)6z1N71E0Gb0M}P>{KYv%*jzmPc2bMR4_3xQ7B3+F38U-PE{z+NX=6yDXIhoX-U39 zVsdh7aj`;TUZp}oVo`}gewso_Myf($K|xMtav~_2^d>7h=GGUbDpcl|DioJO8Rdz2 zB?=|^3Mr{MsU@ijHpL}H`FZJfsv4kV2}uh!`cOgjVvseU>}0PH0t%$WWRSrM$%%P+ z`6UWTsS2feDfxM+dI}-=3I#>^$*HL+Itm3jsfop@3aNP|sYMD-mHDMb3I&P9#pU@$ zDIklJ^YhX&i*g|j$jr~vV{j}^PR&cn%u8o*EKz`_Ju3#s(v-}6P~cCV=2$XW%BhnL zoUyGoPj~vqIC+W7MEAUs)Vvaf^2DM%kY49}6uuP$Q~<;%%}D_z0EM*7ycC5*h1|rF z}tTK0AW_SO0lMc1$$iQPX6U8$N~zW$rEfO^%C<^ z6mk>u64O&t6p|_xY!VeRic-^Tl~gsr8VV9iGBk^o?4aDql5Xzo#TiNYiA5=sW8Hiu z5-W=tTv9!#%YqH!)9hGP6eo7dWvdCgr4BO)mFP5Q3DA3I#=}X{kl2 zdC958lc##fo4G&|GK5k{%E?d8W`J<47+mu6)JqgVxmcmNG(A1FxFj`20Tc+ulQ(-L zKtqhzQv(`I`kuP%pc1L1w0Ls3XCkK)$S|-IH+m|u<|bz5SWUj@De9h=o|9Re!Qfg{ zlwYKflb;BRcyK&Gg$nYELB$)?CM63S&dFG$`GJiUv?B2Bm?b)ZF~CRHR%C@-0Mr zF_f}WKx8Z)&0+?R#G({%%uHtVQD9EZDVQwpBWahJk_z*#M}BT91Bg%v$;?g7$;?Y- z@C;CJgp@}L@GwOZw3_Vcvt=@`uMP*em`zQwnw;zF#Nn7+l3A8nQaO34Z=q93YEfBY zjunGv9w_J%GmBCcJYB%t%#u`)D5#e~nFg~>6R47TUD6yJsQhsR(s0u(-HC7<`vQ&jc1yH4w zmk#BE6Zqr{{_2|z0vs5b64NI?jL>5D1?RJ($vJ_B{CTB`IXRV}BCaUEEH!0vf1o%k zxU8K#KSZiNKTjc10c?nRF*rRbfTE+A!8bJzRA_-1C5b7CC5a5a`6;O&tMl_<%={t+ z=ltB<)Vz{nBq4ASnTevRxU{$+HLn;V2=^W+H%`70m@J1V##4(Gl1qz`K2ZLk+VRcP0L?446v|0m| zy=9pxsVN|lf_zZ1n3K5-Dl;cDF;5{NA1s|(oT|wXkYAh$iU_O8W?`iwspVD-0Y#~0nfax~3;{)% zWr@j^lh=i{vq9>v&HCYTj0%W`OEE)GY7V%xEY8R*0P%A3OHwCCMCh|SK>W11GGZs= zWV@)>>WO8kDGb3NQUP4)G6aL0Hc(0-H3jU9;>mi^3c{fJMF;E|9R*Nv1S(M-qBVH( z!TCH9EHgPi+CvFaS_G%&q$Y!EW^g)V2u{sOgV$q|S4IElFDg+;K`KioFO9LVD@uiw zaq0PqIiQ%zEhtgQ%u`59O--?42+qhahvj_;yA-9Uwc30=W;-JXIM;!4b6cFeqe5u` zDEk#dN}lTcq%1vH(-u^L*D?f`B$kvGTS4j6VmLzqRJf+5OkNh3$qQjZ?Vc%OF`*EM*&o(CgLVj9FYMw%IMq*KF3Me*{ zGZORCQx!52^HPfS6g=zGz%3!Lkswx)LVkIkf@gpZhy!VMLA?yBHo=8Fq>Tm2-rzi< z#}Hbas*sbJn^|H7Vx~YFWf`dou&fDcVHbeXb!s`t5qSz(`I&j3R90T8Rg|ljoS&w1u{^K(=4^HLQ`iZWA+L2idM`%{Y`VVsz!04ZP) zO-@KrqXUY`#AI;O3K9lMsS3$Osi3yDohM?pNZgzqjsfh&zsfk4jC4Bh` z8Hr`73g!7l*{LadlW(PH3Ww(xWfwDmNtkhynNlazLqgv(K%oc}H^tCscJ_1$QYfy> zD@m--V~ETz1tmWPP)LB<2cYOFQgF}DPXXnmVo=qS2ub>&1~0tzl~GbsP;8~IUtV6W zmkv`53UGZ$bm(X17UTyPl_)8cBo?Kome?xAC*>sOWh*HZrRLZw<>iCAbE!p2cAlVQ zR-*4(0gf9`*$ArDKn-kgTNdFEXs}K0NIl36E+2{&DpN}oC!40(dM2fUdyb$6LJGpM zN^sXg8;9{|jYVj03}m4aq%zx_k!H^XZEP*b_{9lpN?T2yk{OheoLT^Cm4O`w&S~H> z5)}WSbO$j(fh1cQ!09cOAu%N-HAMl`d76AMN6rhmO9k#lf$RWV3#w&NtN;lh`3uYi zl}no7{+QBafh@Jn0$F{GlUHY}X(X3IYGQ?w%7RoD|AN#!hEyj|FBnuzr=}>VYJiG5 z&Em<+a?0vK1rKJxf?WYAnMm^~$T&zDkpk{JA(h;q*v5#fdfbu4fNmDZ!&nU=!Hfb( zwWyGjT9%rlkd|LxgwfYP3TJQ#Af+F$lR&8;H3gD`zzR@e3M_)h2qmx?IjLzSU=!-e zN>7=2&=dtupAg4@5)a5};9v*4f*5y6fd@3ed4nM*vA6_MG^R4-WM)rJ%vPSPX06T) zWB<-Zu>JDXpyGO)4RaqdPCk&MHrYO(b@G86)y?_&jEs{j3!aK1`Z$Rx;64c~?blN; z?K6P7PoSj1P@P!|sw;~bp08_ovUl>69c!OWYgf<+&de>y$xO>kO;K>p$jk#boa~?P zY<#(T3QS2zQ6i)TlbC~06Ht_&m6}|l>zSe(mRbaApIU+2z~z-ixsw|T_3I4{bq&oG z3@xlojJSLfi%WDviW2jRa}rDPi>wrU^Gl0U6@pSz%Tg6=azUIT5Zj?BvpBW1Krb(~ z#E#1+F)zI|F+Ei`BsDSD3TCqc!ohGARti-aT)v*Zt_Y_XPS!8VuaD4mF3K-Y$;{J* zIv3$aE(|$cPZui%6LU)=V@o7Sm@7bb=sNo$$+%_aq*^KHM?>n`qFmkL{N&8U96cC6 zR>2-LW}}~zpPZPJs-Kz{9~!Lh;~ekn8XWBC?i#G0l9ia3p08Jsk7g*?A%>==#*^n3 znJ2&+THp#(vsmHT+=VZj8eXj5{$l<1XB(Ta4EH^oyYT70)~8Eao=<3d*0uEM#4ap~ zo=)g}K4rzTj_s506v^sij{iNIv*yXpWzRSEGN@{x4);BqF@N&6qNQS>R0VR+<`qxd zdY*3I^t5&J%js(;&nV788RmO7Vb1d{i#9Ws6fz3G-_xP00UdAAELK&0zo&C@VX2&q z#?$`wFB>{F8Q$;dc)n&0e3Vb&<-)C#HcbGjk^dB3L3q7R{n_RfHu|Z#n=LDzGfp#!i5nP~V<^mWhHE_u3Z%JV5JK(bpK zU$*zZY~K5HL)()*vz|@a1`0mVINU%2k+x>+xl zH9qZF@N(u7{DXN4&u6tf-7(>5|MsU7roZ1a|Jm9l&nEXi**oXSj@}o|dtWSC{cO^b zms1)ZH#C8g^S;SXTbF|DnAP%hecST|jn5aZd$Dc_#HMGHd-Xs%cQ1Xud-?O-Yacf> zF+A;Uf4Zxm;rYycPdnP4t)F7W0P^SJ4Ulv@`D;z#V#?lUYZgA6 zy1{Dm*V>PalRwvYn76e)UAOba+GU^|@)U_<#Q@=1F+A(s_hd)!(~b>Kdv?BT?R`G0 z<;l)vlPepP*q-lO@_cv8Q>(BGWZdulo{p#cw!c`v7Lo!_3Jl{R}+1&ZhrZ0UqXFdwYioq2!O89j%J9B2vOLmA;^HG`=9r(ecm|}YRnVXUENQ1Z=3wPMQ*cN>q18D7mHh8 ztXuSaciW4uCM$+#3-&zS(~mTU2rBG0Plafne6G#4{^{&}Pn-LnZs>opehb6%-7W9; zbbwp`pkfdbVbA*eU+mw&0O35H(EEJ(1}i8JQf55uU;kwHQfR5NbK8^MeURXJvSaP@ z<-1?bTmn@MrI1GvH93kIo^RUsVsYzap>~z}r#sd??OMt3WbcBfOZPsV*zkT&55vn@ z6JAX3f3d&)+3qDzXRd(qAwk6OWXJB83%5e4XVbU6oWAAxuKl3#L`VUK99sxcD+bSC zCqD&40~o^?!kFC9K6A2KhaTIWhNsKBttMA@Sg<|YvioV*ipgs_BJ7^_?0U9tD|nzW zHLnCd?g*(d86Xt2;zZ_vQt6yER+HsBS56k`QsRBKW%rBi&5(p*HCeyQE8uDC<|n)Q zK(!2FToIK27+&n3{bWbOv$ab>RmJkfs45sBwFsorV0hWk@U(pwB$6hd?o!`u+U?Ca znSY9g03;JLK&Yn^XH2f|(V0A@N2?xO;6ozs>6{f1t&mda`Nm#&6hh;5QV%3cLsBfm zv;GNB`@0yPwl+VTy5U*xI)*2^H@#Tg$nbpj#HZ`$Kb<(^#rl>P>vlnfpH7?s(T&7! zWC0Z)lkfI4$UL9D?rCQ)v_bMhj3)bp}w z9VmZ7@;}6|Cwmu6RxB3wc?LHCTIqr7&S(7-p6r|bY~qX;>ozbTl=QEE(YzN_dx678 z0b`U=vCo;2?d8I)&lfaKPU`>4_OhY#<-(nl!zL^c-?{n4;#LMo4P(UsZzxUvGeKPt zR7&k^g#-h*UW3F8Xp&%Zue5APX9vcJ_jD#Pj8ilNl!!uz`|5XUFD(N#cwm&%li*hNrEYpKspH z@M8a*=d0IG?wzc`2g#HQu%X6vlUFfLPMx|o^6BXRnIymLc(lv$2i4>goF!nYva?j+-g&h&cucYHdI? zKbyVf*|ZG|5RMg;h85ehS|H++Yi7psK}vGC(8HN`H=mv*%P0?NraYUz;MwM>@Ma3b zv$abg;X1jnLUgiiGuLF^If~Nosvnx1ckh0(cPcbYwdR}=YS{g3>IMc#fIb6rCV!b@ z&jyLU$vSiWc_48ODUK#r&2_2=wT3pVc-GqYWbgjxQ&u1{8l9Faxb@}SMWE&w z#1SuNPI%g}&5GgaoE1nTk&uB%g(o|@Ao&8)uzfat8${FNh9*$GKV|*1o<;=^VbI{@ zvyN#Bu+d3S1N7uv6COxzftL2)=I&<$6)=0JZeBN!g^~H`#1)e_&bO`KJNen1&L_Ke zy;wi>>Fj+F^Fgf`aG3*Y(@xp?bnOI4K?F5$`ZiEl?U?YaV>_r7yrcKYo>`zk0ypK} z@9BB6w+*85#s2o^E4rW0>3*?w`?I-ApX{0Sw7LJ;jP;;8wrl>AU2V^2akV^Ku>I-U z2_QGWnQtyK=jr4|SUYf5%agqz{$zy(GwLBOQveS{zF5EZ+2*Ow<}Q7)fA))oJ)j7C zwr(ptCPASK3Vd)K{$zI_qWMVF5G2+SNH5eO$fxV~JZ)X752D(4LE;otyD2=`(fwlY zUQj|=zvpTDu4hf4J_CGcQ~_MEOkTC%oC-(=Ttz(HFbh;pcP|A+12{84$_`MkrF@~j z7sw;qH$C6o|6(0BIaRdu2~{wZX?M1Ccv`p#Gkn z!qbio&@K(Qlva4uFb8Rr4?I$dXxf9hh^GCchPj(1mQG=uylt7f+Mb4IQ}!`D2PfVq zJC}j;7i_3f;pz5GkaqCo9m^Bzw{L<3EyUMk`4JMvPuq7ffC|$oJHft0TXleI7_VMG z(GFA?Luvpr41nr~G-FBEUk^^W&u6u~oHgP3^2X=8mOt%S%>Wvp07p9{R3K4FTG&9_ zZ}9Yl!;Ja@Tp^>MXr~12l0loIpv(Yv6%MoT8})2X!_x_U(B$}Z+MH)=7CqV3HhD|A z(Byf`1tw2ep*gu}xz6MXE957uEuXSkcLgKUWQ$d5lap3!O`f#sz~rRWS45uf-t}VL zI*^~hBM$JijAaax!nCaLWXD=)JqQ}%0F6gJTeA>S45AE5GJu93rD5Zbpdq21jqnjm HP@e|?taKE= delta 16563 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 diff --git a/locale/zh_Hant/LC_MESSAGES/django.mo b/locale/zh_Hant/LC_MESSAGES/django.mo index f9ca27be9b891b3b13c30e68d084e0cd54184a43..f46e61fc0013b7807b09af06f48c5b61e1d46597 100644 GIT binary patch delta 13392 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 F0RZ4j_uc>i delta 14268 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