From 6b3447761f2f27c1c2d09a545fff1edbb6421ec4 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 20 May 2021 18:16:35 -0700 Subject: [PATCH 01/87] Adds book format field with choices --- ...l_format_edition_physical_format_detail.py | 35 +++++++++++++++++++ bookwyrm/models/book.py | 12 ++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py diff --git a/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py new file mode 100644 index 000000000..05ad1a2ba --- /dev/null +++ b/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py @@ -0,0 +1,35 @@ +# Generated by Django 3.2 on 2021-05-21 00:17 + +from django.db import migrations +import bookwyrm + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0075_announcement"), + ] + + operations = [ + migrations.RenameField( + model_name="edition", + old_name="physical_format", + new_name="physical_format_detail", + ), + migrations.AddField( + model_name="edition", + name="physical_format", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("AudiobookFormat", "Audiobookformat"), + ("EBook", "Ebook"), + ("GraphicNovel", "Graphicnovel"), + ("Hardcover", "Hardcover"), + ("Paperback", "Paperback"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index 869ff04d2..ae79223d3 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -169,6 +169,13 @@ class Work(OrderedCollectionPageMixin, Book): deserialize_reverse_fields = [("editions", "editions")] +# https://schema.org/BookFormatType +FormatChoices = models.TextChoices( + "FormatChoices", + "AudiobookFormat EBook GraphicNovel Hardcover Paperback", +) + + class Edition(Book): """an edition of a book""" @@ -186,7 +193,10 @@ class Edition(Book): max_length=255, blank=True, null=True, deduplication_field=True ) pages = fields.IntegerField(blank=True, null=True) - physical_format = fields.CharField(max_length=255, blank=True, null=True) + physical_format = fields.CharField( + max_length=255, choices=FormatChoices.choices, null=True, blank=True + ) + physical_format_detail = fields.CharField(max_length=255, blank=True, null=True) publishers = fields.ArrayField( models.CharField(max_length=255), blank=True, default=list ) From e99e4831f13cf01cec8b418473da1c3d7ee7d695 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 19 Jun 2021 08:17:27 -0700 Subject: [PATCH 02/87] Updates migration --- ...l_format_edition_physical_format_detail.py | 35 ------ ...l_format_edition_physical_format_detail.py | 100 ++++++++++++++++++ 2 files changed, 100 insertions(+), 35 deletions(-) delete mode 100644 bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py create mode 100644 bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py diff --git a/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py deleted file mode 100644 index 05ad1a2ba..000000000 --- a/bookwyrm/migrations/0076_rename_physical_format_edition_physical_format_detail.py +++ /dev/null @@ -1,35 +0,0 @@ -# Generated by Django 3.2 on 2021-05-21 00:17 - -from django.db import migrations -import bookwyrm - - -class Migration(migrations.Migration): - - dependencies = [ - ("bookwyrm", "0075_announcement"), - ] - - operations = [ - migrations.RenameField( - model_name="edition", - old_name="physical_format", - new_name="physical_format_detail", - ), - migrations.AddField( - model_name="edition", - name="physical_format", - field=bookwyrm.models.fields.CharField( - blank=True, - choices=[ - ("AudiobookFormat", "Audiobookformat"), - ("EBook", "Ebook"), - ("GraphicNovel", "Graphicnovel"), - ("Hardcover", "Hardcover"), - ("Paperback", "Paperback"), - ], - max_length=255, - null=True, - ), - ), - ] diff --git a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py new file mode 100644 index 000000000..ab152252f --- /dev/null +++ b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py @@ -0,0 +1,100 @@ +# Generated by Django 3.2 on 2021-05-21 00:17 + +from django.db import migrations +import bookwyrm + + +def infer_format(app_registry, schema_editor): + """set the new phsyical format field based on existing format data""" + db_alias = schema_editor.connection.alias + + editions = ( + app_registry.get_model("bookwyrm", "Edition") + .objects.using(db_alias) + .filter(physical_format__isnull=False) + ) + mappings = { + "paperback": "Paperback", + "soft": "Paperback", + "pamphlet": "Paperback", + "peperback": "Paperback", + "tapa blanda": "Paperback", + "turtleback": "Paperback", + "pocket": "Paperback", + "spiral": "Paperback", + "ring": "Paperback", + "平装": "Paperback", + "简装": "Paperback", + "hardcover": "Hardcover", + "hardcocer": "Hardcover", + "hardover": "Hardcover", + "hardback": "Hardcover", + "library": "Hardcover", + "tapa dura": "Hardcover", + "leather": "Hardcover", + "clothbound": "Hardcover", + "精装": "Hardcover", + "ebook": "EBook", + "e-book": "EBook", + "digital": "EBook", + "computer file": "EBook", + "epub": "EBook", + "online": "EBook", + "pdf": "EBook", + "elektronische": "EBook", + "electronic": "EBook", + "audiobook": "AudiobookFormat", + "audio": "AudiobookFormat", + "cd": "AudiobookFormat", + "dvd": "AudiobookFormat", + "mp3": "AudiobookFormat", + "cassette": "AudiobookFormat", + "kindle": "AudiobookFormat", + "talking": "AudiobookFormat", + "sound": "AudiobookFormat", + "comic": "GraphicNovel", + "graphic": "GraphicNovel", + } + for edition in editions: + free_format = editions.physical_format_detail.lower() + if free_format in mappings: + edition.physical_format = mappings[free_format] + edition.save(broadcast=False) + else: + matches = [v for k, v in mappings if k in free_format] + if not matches: + continue + edition.physical_format = matches[0] + edition.save(broadcast=False) + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0076_preview_images"), + ] + + operations = [ + migrations.RenameField( + model_name="edition", + old_name="physical_format", + new_name="physical_format_detail", + ), + migrations.AddField( + model_name="edition", + name="physical_format", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("AudiobookFormat", "Audiobookformat"), + ("EBook", "Ebook"), + ("GraphicNovel", "Graphicnovel"), + ("Hardcover", "Hardcover"), + ("Paperback", "Paperback"), + ], + max_length=255, + null=True, + ), + ), + migrations.RunPython(infer_format), + ] From cb811c92a668e2e6766542edebf4565dd084c952 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 19 Jun 2021 08:36:12 -0700 Subject: [PATCH 03/87] Adds reverse migration stub --- ...ename_physical_format_edition_physical_format_detail.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py index ab152252f..eec94d626 100644 --- a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py +++ b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py @@ -57,16 +57,21 @@ def infer_format(app_registry, schema_editor): } for edition in editions: free_format = editions.physical_format_detail.lower() + print(free_format) if free_format in mappings: + print("hi") edition.physical_format = mappings[free_format] edition.save(broadcast=False) else: matches = [v for k, v in mappings if k in free_format] + print(matches) if not matches: continue edition.physical_format = matches[0] edition.save(broadcast=False) +def reverse(app_registry, schema_editor): + """doesn't need to do anything""" class Migration(migrations.Migration): @@ -96,5 +101,5 @@ class Migration(migrations.Migration): null=True, ), ), - migrations.RunPython(infer_format), + migrations.RunPython(infer_format, reverse), ] From f82161d648cb06f57cabc57f45f13ac99f4f43fd Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Sat, 19 Jun 2021 08:37:53 -0700 Subject: [PATCH 04/87] Fixes migration query --- ...hysical_format_edition_physical_format_detail.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py index eec94d626..020cc49ab 100644 --- a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py +++ b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py @@ -11,7 +11,7 @@ def infer_format(app_registry, schema_editor): editions = ( app_registry.get_model("bookwyrm", "Edition") .objects.using(db_alias) - .filter(physical_format__isnull=False) + .filter(physical_format_detail__isnull=False) ) mappings = { "paperback": "Paperback", @@ -56,19 +56,16 @@ def infer_format(app_registry, schema_editor): "graphic": "GraphicNovel", } for edition in editions: - free_format = editions.physical_format_detail.lower() - print(free_format) + free_format = edition.physical_format_detail.lower() if free_format in mappings: - print("hi") edition.physical_format = mappings[free_format] - edition.save(broadcast=False) + edition.save() else: - matches = [v for k, v in mappings if k in free_format] - print(matches) + matches = [v for k, v in mappings.items() if k in free_format] if not matches: continue edition.physical_format = matches[0] - edition.save(broadcast=False) + edition.save() def reverse(app_registry, schema_editor): """doesn't need to do anything""" From 48fcdcbe93a6171ef249e22726ad4ae0e56ea80c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 4 Aug 2021 14:12:37 -0700 Subject: [PATCH 05/87] Python formatting --- ...077_rename_physical_format_edition_physical_format_detail.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py index 020cc49ab..fcff93523 100644 --- a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py +++ b/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py @@ -67,9 +67,11 @@ def infer_format(app_registry, schema_editor): edition.physical_format = matches[0] edition.save() + def reverse(app_registry, schema_editor): """doesn't need to do anything""" + class Migration(migrations.Migration): dependencies = [ From 2c08be79f86f11f103d09645eebe02b8d10c6111 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 4 Aug 2021 14:19:17 -0700 Subject: [PATCH 06/87] Merge migration --- bookwyrm/migrations/0080_merge_20210804_2114.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 bookwyrm/migrations/0080_merge_20210804_2114.py diff --git a/bookwyrm/migrations/0080_merge_20210804_2114.py b/bookwyrm/migrations/0080_merge_20210804_2114.py new file mode 100644 index 000000000..d8365eaf4 --- /dev/null +++ b/bookwyrm/migrations/0080_merge_20210804_2114.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.4 on 2021-08-04 21:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0077_rename_physical_format_edition_physical_format_detail"), + ("bookwyrm", "0079_merge_20210804_1746"), + ] + + operations = [] From f80503d9471c1b22db8027c4feea329b9511797d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Mon, 6 Sep 2021 22:15:13 -0700 Subject: [PATCH 07/87] Merge migration --- bookwyrm/migrations/0089_merge_20210907_0514.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 bookwyrm/migrations/0089_merge_20210907_0514.py diff --git a/bookwyrm/migrations/0089_merge_20210907_0514.py b/bookwyrm/migrations/0089_merge_20210907_0514.py new file mode 100644 index 000000000..86d29599a --- /dev/null +++ b/bookwyrm/migrations/0089_merge_20210907_0514.py @@ -0,0 +1,13 @@ +# Generated by Django 3.2.4 on 2021-09-07 05:14 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0080_merge_20210804_2114"), + ("bookwyrm", "0088_auto_20210905_2233"), + ] + + operations = [] From 8a748fa67582fba91d2dd2efad366592a145cc77 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 09:22:15 -0700 Subject: [PATCH 08/87] Adds format fields to edit book view --- .../0090_alter_edition_physical_format.py | 30 +++ bookwyrm/models/book.py | 14 +- bookwyrm/templates/book/edit_book.html | 27 ++- locale/de_DE/LC_MESSAGES/django.po | 209 ++++++++++++----- locale/en_US/LC_MESSAGES/django.po | 172 ++++++++++---- locale/es/LC_MESSAGES/django.po | 211 ++++++++++++----- locale/fr_FR/LC_MESSAGES/django.po | 213 +++++++++++++----- locale/zh_Hans/LC_MESSAGES/django.po | 201 +++++++++++++---- locale/zh_Hant/LC_MESSAGES/django.po | 201 +++++++++++++---- 9 files changed, 954 insertions(+), 324 deletions(-) create mode 100644 bookwyrm/migrations/0090_alter_edition_physical_format.py diff --git a/bookwyrm/migrations/0090_alter_edition_physical_format.py b/bookwyrm/migrations/0090_alter_edition_physical_format.py new file mode 100644 index 000000000..b37a75a66 --- /dev/null +++ b/bookwyrm/migrations/0090_alter_edition_physical_format.py @@ -0,0 +1,30 @@ +# Generated by Django 3.2.4 on 2021-09-07 19:46 + +import bookwyrm.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0089_merge_20210907_0514"), + ] + + operations = [ + migrations.AlterField( + model_name="edition", + name="physical_format", + field=bookwyrm.models.fields.CharField( + blank=True, + choices=[ + ("AudiobookFormat", "Audiobook"), + ("EBook", "eBook"), + ("GraphicNovel", "Graphic novel"), + ("Hardcover", "Hardcover"), + ("Paperback", "Paperback"), + ], + max_length=255, + null=True, + ), + ), + ] diff --git a/bookwyrm/models/book.py b/bookwyrm/models/book.py index e21d61e20..5888ea07a 100644 --- a/bookwyrm/models/book.py +++ b/bookwyrm/models/book.py @@ -5,6 +5,7 @@ from django.contrib.postgres.search import SearchVectorField from django.contrib.postgres.indexes import GinIndex from django.db import models from django.dispatch import receiver +from django.utils.translation import gettext_lazy as _ from model_utils import FieldTracker from model_utils.managers import InheritanceManager from imagekit.models import ImageSpecField @@ -225,10 +226,13 @@ class Work(OrderedCollectionPageMixin, Book): # https://schema.org/BookFormatType -FormatChoices = models.TextChoices( - "FormatChoices", - "AudiobookFormat EBook GraphicNovel Hardcover Paperback", -) +FormatChoices = [ + ("AudiobookFormat", _("Audiobook")), + ("EBook", _("eBook")), + ("GraphicNovel", _("Graphic novel")), + ("Hardcover", _("Hardcover")), + ("Paperback", _("Paperback")), +] class Edition(Book): @@ -249,7 +253,7 @@ class Edition(Book): ) pages = fields.IntegerField(blank=True, null=True) physical_format = fields.CharField( - max_length=255, choices=FormatChoices.choices, null=True, blank=True + max_length=255, choices=FormatChoices, null=True, blank=True ) physical_format_detail = fields.CharField(max_length=255, blank=True, null=True) publishers = fields.ArrayField( diff --git a/bookwyrm/templates/book/edit_book.html b/bookwyrm/templates/book/edit_book.html index 2f6ca3242..ebfeccf50 100644 --- a/bookwyrm/templates/book/edit_book.html +++ b/bookwyrm/templates/book/edit_book.html @@ -253,12 +253,27 @@

{% trans "Physical Properties" %}

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

{{ error | escape }}

- {% endfor %} +
+
+
+ +
+ {{ form.physical_format }} +
+ {% for error in form.physical_format.errors %} +

{{ error | escape }}

+ {% endfor %} +
+
+
+
+ + {{ form.physical_format_detail }} + {% for error in form.physical_format_detail.errors %} +

{{ error | escape }}

+ {% endfor %} +
+
diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index b3623765d..49b1b4b22 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/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-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-03-02 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -18,67 +18,93 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +#, fuzzy +#| msgid "Add Books" +msgid "Audiobook" +msgstr "Bücher hinzufügen" + +#: bookwyrm/forms.py:196 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Buch" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Cover hinzufügen" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 #, fuzzy #| msgid "A user with that username already exists." msgid "A user with this email already exists." msgstr "Dieser Benutzename ist bereits vergeben." -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "Ein Tag" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "Eine Woche" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "Ein Monat" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "Läuft nicht aus" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "%(count)d Benutzungen" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 #, fuzzy #| msgid "Unlisted" msgid "Unlimited" msgstr "Ungelistet" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 #, fuzzy #| msgid "Title" msgid "Book Title" msgstr "Titel" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 #, fuzzy #| msgid "Started reading" msgid "Ascending" msgstr "Zu lesen angefangen" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 #, fuzzy #| msgid "Started reading" msgid "Descending" @@ -284,7 +310,7 @@ msgid "Openlibrary key:" msgstr "" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 #, fuzzy #| msgid "View on OpenLibrary" msgid "Inventaire ID:" @@ -300,10 +326,10 @@ msgstr "" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -318,8 +344,9 @@ msgstr "Speichern" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -458,12 +485,12 @@ msgid "ISBN:" msgstr "" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "OCLC Nummer:" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "" @@ -609,28 +636,32 @@ msgstr "" msgid "Physical Properties" msgstr "Physikalische Eigenschaften" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +msgid "Format details:" +msgstr "" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "Seiten:" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "Buchidentifikatoren" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "" @@ -766,6 +797,7 @@ msgid "Sorry! We couldn't find that code." msgstr "" #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 #, fuzzy #| msgid "Confirm password:" msgid "Confirmation code:" @@ -1605,8 +1637,27 @@ msgstr "Bestätigen" msgid "Discard" msgstr "Ablehnen" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +#, fuzzy +#| msgid "Delete this progress update" +msgid "Delete this list?" +msgstr "Dieses Fortschrittsupdate löschen" + +#: bookwyrm/templates/lists/delete_list_modal.html:7 +#, fuzzy +#| msgid "This shelf is empty." +msgid "This action cannot be un-done" +msgstr "Dieses Regal ist leer." + +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Liste bearbeiten" @@ -1641,6 +1692,12 @@ msgstr "Offen" msgid "Anyone can add books to this list" msgstr "Alle können Bücher hinzufügen" +#: bookwyrm/templates/lists/form.html:49 +#, fuzzy +#| msgid "Delete status" +msgid "Delete list" +msgstr "Post löschen" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "" @@ -2070,6 +2127,7 @@ msgid "Account" msgstr "" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "Profil" @@ -2208,12 +2266,6 @@ msgstr "Zurück zu den Meldungen" msgid "Edit Announcement" msgstr "Ankündigungen" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Löschen" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "" @@ -2280,6 +2332,7 @@ msgstr "Lesedaten bearbeiten" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "" @@ -2329,7 +2382,7 @@ msgstr "Instanzname" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 #, fuzzy #| msgid "Import Status" msgid "Status:" @@ -2348,13 +2401,13 @@ msgstr "Blockierte Nutzer*innen" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 #, fuzzy #| msgid "Description:" msgid "Version:" @@ -2383,6 +2436,7 @@ msgid "View all" msgstr "" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 #, fuzzy #| msgid "Recent Imports" msgid "Reports:" @@ -2407,7 +2461,7 @@ msgid "Blocked by us:" msgstr "Blockierte Nutzer*innen" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "" @@ -3428,7 +3482,7 @@ msgstr[1] "folgt dir" msgid "No followers you follow" msgstr "folgt dir" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 #, fuzzy #| msgid "Back to reports" msgid "Back to users" @@ -3464,37 +3518,89 @@ msgid "Remote instance" msgstr "Instanzname" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 #, fuzzy #| msgid "Activity" msgid "Active" msgstr "Aktivität" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 #, fuzzy #| msgid "User Profile" msgid "View user profile" msgstr "Benutzerprofil" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "Lokal" + +#: bookwyrm/templates/user_admin/user_info.html:38 +#, fuzzy +#| msgid "Remove" +msgid "Remote" +msgstr "Entfernen" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:52 +#, fuzzy +#| msgid "Email address:" +msgid "Email:" +msgstr "E-Mail Adresse" + +#: bookwyrm/templates/user_admin/user_info.html:64 +msgid "(View reports)" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:72 +#, fuzzy +#| msgid "Blocked Users" +msgid "Blocked by count:" +msgstr "Blockierte Nutzer*innen" + +#: bookwyrm/templates/user_admin/user_info.html:77 +#, fuzzy +#| msgid "Birth date:" +msgid "Last active date:" +msgstr "Geburtsdatum:" + +#: bookwyrm/templates/user_admin/user_info.html:82 +#, fuzzy +#| msgid "Manually approve followers:" +msgid "Manually approved followers:" +msgstr "Folgende manuell bestätigen" + +#: bookwyrm/templates/user_admin/user_info.html:87 +#, fuzzy +#| msgid "Discard" +msgid "Discoverable:" +msgstr "Ablehnen" + +#: bookwyrm/templates/user_admin/user_info.html:93 +#, fuzzy +#| msgid "Deactivate user" +msgid "Deactivation reason:" +msgstr "Nutzer:in deaktivieren" + +#: bookwyrm/templates/user_admin/user_info.html:111 #, fuzzy #| msgid "Instance Settings" msgid "Instance details" msgstr "Instanzeinstellungen" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "" @@ -3560,9 +3666,6 @@ msgstr "" #~ msgid "Federated Timeline" #~ msgstr "Föderierende Server" -#~ msgid "Local" -#~ msgstr "Lokal" - #, fuzzy #~| msgid "Lists: %(username)s" #~ msgid "Reports: %(server_name)s" @@ -3639,11 +3742,6 @@ msgstr "" #~ msgid "Value %(value)r is not a valid choice." #~ msgstr "%(value)s ist keine gültige remote_id" -#, fuzzy -#~| msgid "This shelf is empty." -#~ msgid "This field cannot be null." -#~ msgstr "Dieses Regal ist leer." - #, fuzzy #~| msgid "A user with that username already exists." #~ msgid "%(model_name)s with this %(field_label)s already exists." @@ -3873,9 +3971,6 @@ msgstr "" #~ msgid "by %(author)s" #~ msgstr "von %(author)s" -#~ msgid "Deactivate user" -#~ msgstr "Nutzer:in deaktivieren" - #~ msgid "Reactivate user" #~ msgstr "Nutzer:in reaktivieren" diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index 5fb906116..637853e28 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-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -18,59 +18,79 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +msgid "Audiobook" +msgstr "" + +#: bookwyrm/forms.py:196 +msgid "eBook" +msgstr "" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +msgid "Hardcover" +msgstr "" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 msgid "A user with this email already exists." msgstr "" -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 msgid "Unlimited" msgstr "" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 msgid "Book Title" msgstr "" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 msgid "Ascending" msgstr "" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 msgid "Descending" msgstr "" @@ -262,7 +282,7 @@ msgid "Openlibrary key:" msgstr "" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 msgid "Inventaire ID:" msgstr "" @@ -276,10 +296,10 @@ msgstr "" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -294,8 +314,9 @@ msgstr "" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -419,12 +440,12 @@ msgid "ISBN:" msgstr "" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "" @@ -554,28 +575,32 @@ msgstr "" msgid "Physical Properties" msgstr "" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +msgid "Format details:" +msgstr "" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "" @@ -701,6 +726,7 @@ msgid "Sorry! We couldn't find that code." msgstr "" #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 msgid "Confirmation code:" msgstr "" @@ -1476,8 +1502,23 @@ msgstr "" msgid "Discard" msgstr "" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +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/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "" @@ -1512,6 +1553,10 @@ msgstr "" msgid "Anyone can add books to this list" msgstr "" +#: bookwyrm/templates/lists/form.html:49 +msgid "Delete list" +msgstr "" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "" @@ -1901,6 +1946,7 @@ msgid "Account" msgstr "" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "" @@ -2021,12 +2067,6 @@ msgstr "" msgid "Edit Announcement" msgstr "" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "" @@ -2077,6 +2117,7 @@ msgstr "" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "" @@ -2114,7 +2155,7 @@ msgstr "" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 msgid "Status:" msgstr "" @@ -2129,13 +2170,13 @@ msgstr "" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 msgid "Version:" msgstr "" @@ -2162,6 +2203,7 @@ msgid "View all" msgstr "" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 msgid "Reports:" msgstr "" @@ -2178,7 +2220,7 @@ msgid "Blocked by us:" msgstr "" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "" @@ -3100,7 +3142,7 @@ msgstr[1] "" msgid "No followers you follow" msgstr "" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 msgid "Back to users" msgstr "" @@ -3127,31 +3169,69 @@ msgid "Remote instance" msgstr "" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 msgid "Active" msgstr "" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 msgid "View user profile" msgstr "" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:38 +msgid "Remote" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:52 +msgid "Email:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:64 +msgid "(View reports)" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:72 +msgid "Blocked by count:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:77 +msgid "Last active date:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:82 +msgid "Manually approved followers:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:87 +msgid "Discoverable:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:93 +msgid "Deactivation reason:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:111 msgid "Instance details" msgstr "" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "" diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index 48e8e8cef..12c4fb35d 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/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-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n" "Last-Translator: Reese Porter \n" "Language-Team: LANGUAGE \n" @@ -18,59 +18,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "Agregar libros" + +#: bookwyrm/forms.py:196 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Libro" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Agregar portada" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 msgid "A user with this email already exists." msgstr "Ya existe un usuario con ese correo electrónico." -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "Un día" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "Una semana" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "Un mes" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "Nunca se vence" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "%(count)d usos" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 msgid "Unlimited" msgstr "Sin límite" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "Orden de la lista" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 msgid "Book Title" msgstr "Título" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "Calificación" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "Ordenar por" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 msgid "Ascending" msgstr "Ascendente" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 msgid "Descending" msgstr "Descendente" @@ -262,7 +288,7 @@ msgid "Openlibrary key:" msgstr "Clave OpenLibrary:" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 msgid "Inventaire ID:" msgstr "ID Inventaire:" @@ -276,10 +302,10 @@ msgstr "Clave Goodreads:" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -294,8 +320,9 @@ msgstr "Guardar" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -419,12 +446,12 @@ msgid "ISBN:" msgstr "ISBN:" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "Número OCLC:" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "ASIN:" @@ -554,28 +581,34 @@ msgstr "Portada:" msgid "Physical Properties" msgstr "Propiedades físicas:" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "Formato:" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +#, fuzzy +#| msgid "User details" +msgid "Format details:" +msgstr "Detalles" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "Páginas:" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "Identificadores de libro" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "ISBN 13:" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "ISBN 10:" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "ID OpenLibrary:" @@ -701,6 +734,7 @@ msgid "Sorry! We couldn't find that code." msgstr "Sentimos que no pudimos encontrar ese código" #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 msgid "Confirmation code:" msgstr "Código de confirmación:" @@ -1476,8 +1510,27 @@ msgstr "Aprobar" msgid "Discard" msgstr "Desechar" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +#, fuzzy +#| msgid "Delete this progress update" +msgid "Delete this list?" +msgstr "Eliminar esta actualización de progreso" + +#: bookwyrm/templates/lists/delete_list_modal.html:7 +#, fuzzy +#| msgid "This field cannot be null." +msgid "This action cannot be un-done" +msgstr "Este campo no puede ser nulo." + +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Editar lista" @@ -1512,6 +1565,12 @@ msgstr "Abierto" msgid "Anyone can add books to this list" msgstr "Cualquer usuario puede agregar libros a esta lista" +#: bookwyrm/templates/lists/form.html:49 +#, fuzzy +#| msgid "Delete status" +msgid "Delete list" +msgstr "Eliminar status" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "¡Has sugerido un libro para esta lista exitosamente!" @@ -1901,6 +1960,7 @@ msgid "Account" msgstr "Cuenta" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "Perfil" @@ -2021,12 +2081,6 @@ msgstr "Volver a la lista de servidores" msgid "Edit Announcement" msgstr "Editar anuncio" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Eliminar" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "Visible:" @@ -2077,6 +2131,7 @@ msgstr "Fecha final" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "Status" @@ -2114,7 +2169,7 @@ msgstr "Instancia:" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 msgid "Status:" msgstr "Status:" @@ -2129,13 +2184,13 @@ msgstr "Bloqueado" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "Software:" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 msgid "Version:" msgstr "Versión:" @@ -2162,6 +2217,7 @@ msgid "View all" msgstr "Ver todos" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 msgid "Reports:" msgstr "Informes:" @@ -2178,7 +2234,7 @@ msgid "Blocked by us:" msgstr "Bloqueado por nosotros:" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "Notas" @@ -3108,7 +3164,7 @@ msgstr[1] "%(mutuals_display)s seguidores que sigues" msgid "No followers you follow" msgstr "Ningún seguidor que tu sigues" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 msgid "Back to users" msgstr "Volver a usuarios" @@ -3135,31 +3191,85 @@ msgid "Remote instance" msgstr "Instancia remota" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 msgid "Active" msgstr "Activ@" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "Inactiv@" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "No establecido" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "Detalles" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 msgid "View user profile" msgstr "Ver perfil de usuario" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "Local" + +#: bookwyrm/templates/user_admin/user_info.html:38 +#, fuzzy +#| msgid "Remove" +msgid "Remote" +msgstr "Quitar" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "Detalles" + +#: bookwyrm/templates/user_admin/user_info.html:52 +#, fuzzy +#| msgid "Email" +msgid "Email:" +msgstr "Correo electronico" + +#: bookwyrm/templates/user_admin/user_info.html:64 +#, fuzzy +#| msgid "View directory" +msgid "(View reports)" +msgstr "Ver directorio" + +#: bookwyrm/templates/user_admin/user_info.html:72 +#, fuzzy +#| msgid "Blocked by us:" +msgid "Blocked by count:" +msgstr "Bloqueado por nosotros:" + +#: bookwyrm/templates/user_admin/user_info.html:77 +#, fuzzy +#| msgid "last active" +msgid "Last active date:" +msgstr "actividad reciente" + +#: bookwyrm/templates/user_admin/user_info.html:82 +#, fuzzy +#| msgid "Manually approve followers:" +msgid "Manually approved followers:" +msgstr "Aprobar seguidores a mano:" + +#: bookwyrm/templates/user_admin/user_info.html:87 +#, fuzzy +#| msgid "Discover" +msgid "Discoverable:" +msgstr "Descubrir" + +#: bookwyrm/templates/user_admin/user_info.html:93 +#, fuzzy +#| msgid "Deactivate user" +msgid "Deactivation reason:" +msgstr "Desactivar usuario" + +#: bookwyrm/templates/user_admin/user_info.html:111 msgid "Instance details" msgstr "Detalles de instancia" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "Ver instancia" @@ -3222,9 +3332,6 @@ msgstr "Actualizaciones de status de {obj.display_name}" #~ msgid "Federated Timeline" #~ msgstr "Línea temporal federalizado" -#~ msgid "Local" -#~ msgstr "Local" - #~ msgid "Federated Servers" #~ msgstr "Servidores federalizados" @@ -3348,9 +3455,6 @@ msgstr "Actualizaciones de status de {obj.display_name}" #~ msgid "Value %(value)r is not a valid choice." #~ msgstr "El valor %(value)s no es una opción válida." -#~ msgid "This field cannot be null." -#~ msgstr "Este campo no puede ser nulo." - #~ msgid "This field cannot be blank." #~ msgstr "Este campo no puede ser vacio." @@ -4128,9 +4232,6 @@ msgstr "Actualizaciones de status de {obj.display_name}" #~ msgid "Books tagged \"%(tag.name)s\"" #~ msgstr "Libros etiquetados con \"%(tag.name)s\"" -#~ msgid "Deactivate user" -#~ msgstr "Desactivar usuario" - #~ msgid "Reactivate user" #~ msgstr "Reactivar usuario" diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index 647d18ece..58ae1aa18 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-04-05 12:44+0100\n" "Last-Translator: Fabien Basmaison \n" "Language-Team: Mouse Reeve \n" @@ -18,59 +18,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "Ajoutez des livres" + +#: bookwyrm/forms.py:196 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Livre" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Ajouter une couverture" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 msgid "A user with this email already exists." msgstr "Cet email est déjà associé à un compte." -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "Un jour" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "Une semaine" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "Un mois" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "Sans expiration" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "%(count)d utilisations" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 msgid "Unlimited" msgstr "Sans limite" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "Ordre de la liste" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 msgid "Book Title" msgstr "Titre du livre" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "Note" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "Trier par" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 msgid "Ascending" msgstr "Ordre croissant" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 msgid "Descending" msgstr "Ordre décroissant" @@ -266,7 +292,7 @@ msgid "Openlibrary key:" msgstr "Clé Openlibrary :" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 msgid "Inventaire ID:" msgstr "Identifiant Inventaire :" @@ -280,10 +306,10 @@ msgstr "Clé Goodreads :" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -298,8 +324,9 @@ msgstr "Enregistrer" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -423,12 +450,12 @@ msgid "ISBN:" msgstr "ISBN :" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "Numéro OCLC :" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "ASIN :" @@ -558,28 +585,34 @@ msgstr "Couverture" msgid "Physical Properties" msgstr "Propriétés physiques" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "Format :" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +#, fuzzy +#| msgid "User details" +msgid "Format details:" +msgstr "Détails du compte" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "Pages :" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "Identifiants du livre" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "ISBN 13 :" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "ISBN 10 :" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "Identifiant Openlibrary :" @@ -707,6 +740,7 @@ msgid "Sorry! We couldn't find that code." msgstr "Pardon ! Nous ne reconnaissons pas ce code." #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 msgid "Confirmation code:" msgstr "Code de confirmation :" @@ -1495,8 +1529,27 @@ msgstr "Approuver" msgid "Discard" msgstr "Rejeter" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +#, fuzzy +#| msgid "Delete this progress update" +msgid "Delete this list?" +msgstr "Supprimer cette mise à jour" + +#: bookwyrm/templates/lists/delete_list_modal.html:7 +#, fuzzy +#| msgid "This shelf is empty." +msgid "This action cannot be un-done" +msgstr "Cette étagère est vide" + +#: bookwyrm/templates/lists/delete_list_modal.html:15 +#: bookwyrm/templates/settings/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "Modifier la liste" @@ -1531,6 +1584,12 @@ msgstr "Ouverte" msgid "Anyone can add books to this list" msgstr "N’importe qui peut suggérer des livres" +#: bookwyrm/templates/lists/form.html:49 +#, fuzzy +#| msgid "Delete status" +msgid "Delete list" +msgstr "Supprimer le statut" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "Vous avez suggéré un livre à cette liste !" @@ -1930,6 +1989,7 @@ msgid "Account" msgstr "Compte" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "Profil" @@ -2053,12 +2113,6 @@ msgstr "Retour à la liste" msgid "Edit Announcement" msgstr "Modifier l’annonce" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "Supprimer" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "Visible :" @@ -2109,6 +2163,7 @@ msgstr "Date de fin" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "Statut" @@ -2146,7 +2201,7 @@ msgstr "Instance :" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 msgid "Status:" msgstr "Statut :" @@ -2161,13 +2216,13 @@ msgstr "Bloqué" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "Logiciel :" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 msgid "Version:" msgstr "Description :" @@ -2194,6 +2249,7 @@ msgid "View all" msgstr "Voir tous" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 msgid "Reports:" msgstr "Signalements :" @@ -2210,7 +2266,7 @@ msgid "Blocked by us:" msgstr "Bloqués par nous :" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "Remarques" @@ -3159,7 +3215,7 @@ msgstr[1] "%(mutuals_display)s abonné(e)s que vous suivez" msgid "No followers you follow" msgstr "compte que vous suivez" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 msgid "Back to users" msgstr "Retour aux comptes" @@ -3186,31 +3242,85 @@ msgid "Remote instance" msgstr "Instance distante" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 msgid "Active" msgstr "Actif" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "Inactif" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "Non défini" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "Détails du compte" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 msgid "View user profile" msgstr "Voir le profil" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "Local" + +#: bookwyrm/templates/user_admin/user_info.html:38 +#, fuzzy +#| msgid "Remove" +msgid "Remote" +msgstr "Retirer" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "Détails du compte" + +#: bookwyrm/templates/user_admin/user_info.html:52 +#, fuzzy +#| msgid "Email" +msgid "Email:" +msgstr "Email" + +#: bookwyrm/templates/user_admin/user_info.html:64 +#, fuzzy +#| msgid "Directory" +msgid "(View reports)" +msgstr "Répertoire" + +#: bookwyrm/templates/user_admin/user_info.html:72 +#, fuzzy +#| msgid "Blocked by us:" +msgid "Blocked by count:" +msgstr "Bloqués par nous :" + +#: bookwyrm/templates/user_admin/user_info.html:77 +#, fuzzy +#| msgid "last active" +msgid "Last active date:" +msgstr "dernière activité" + +#: bookwyrm/templates/user_admin/user_info.html:82 +#, fuzzy +#| msgid "Manually approve followers:" +msgid "Manually approved followers:" +msgstr "Autoriser les abonnements manuellement :" + +#: bookwyrm/templates/user_admin/user_info.html:87 +#, fuzzy +#| msgid "Discard" +msgid "Discoverable:" +msgstr "Rejeter" + +#: bookwyrm/templates/user_admin/user_info.html:93 +#, fuzzy +#| msgid "Deactivate user" +msgid "Deactivation reason:" +msgstr "Désactiver le compte" + +#: bookwyrm/templates/user_admin/user_info.html:111 msgid "Instance details" msgstr "Détails de l’instance" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "Voir l’instance" @@ -3273,9 +3383,6 @@ msgstr "" #~ msgid "Federated Timeline" #~ msgstr "Fil d’actualité des instances fédérées" -#~ msgid "Local" -#~ msgstr "Local" - #, fuzzy #~| msgid "BookWyrm users" #~ msgid "BookWyrm\\" @@ -3331,11 +3438,6 @@ msgstr "" #~ msgid "Value %(value)r is not a valid choice." #~ msgstr "%(value)s n’est pas une remote_id valide." -#, fuzzy -#~| msgid "This shelf is empty." -#~ msgid "This field cannot be null." -#~ msgstr "Cette étagère est vide" - #, fuzzy #~| msgid "A user with this email already exists." #~ msgid "%(model_name)s with this %(field_label)s already exists." @@ -3555,9 +3657,6 @@ msgstr "" #~ msgid "by %(author)s" #~ msgstr "par %(author)s" -#~ msgid "Deactivate user" -#~ msgstr "Désactiver le compte" - #~ msgid "Reactivate user" #~ msgstr "Réactiver le compte" diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index 3adb5aef5..41188afe9 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-03-20 00:56+0000\n" "Last-Translator: Kana \n" "Language-Team: Mouse Reeve \n" @@ -18,59 +18,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "添加书目" + +#: bookwyrm/forms.py:196 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "书目" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "添加封面" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 msgid "A user with this email already exists." msgstr "已经存在使用该邮箱的用户。" -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "一周" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "一个月" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "%(count)d 次使用" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "列表顺序" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 msgid "Book Title" msgstr "书名" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "评价" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 msgid "Descending" msgstr "降序" @@ -262,7 +288,7 @@ msgid "Openlibrary key:" msgstr "Openlibrary key:" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 msgid "Inventaire ID:" msgstr "Inventaire ID:" @@ -276,10 +302,10 @@ msgstr "Goodreads key:" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -294,8 +320,9 @@ msgstr "保存" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -418,12 +445,12 @@ msgid "ISBN:" msgstr "ISBN:" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "OCLC 号:" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "ASIN:" @@ -553,28 +580,34 @@ msgstr "封面" msgid "Physical Properties" msgstr "实体性质" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "格式:" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +#, fuzzy +#| msgid "User details" +msgid "Format details:" +msgstr "用户详情" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "页数:" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "书目标识号" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "ISBN 13:" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "ISBN 10:" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "Openlibrary ID:" @@ -702,6 +735,7 @@ msgid "Sorry! We couldn't find that code." msgstr "抱歉!我们无法找到该代码。" #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 msgid "Confirmation code:" msgstr "确认代码:" @@ -1477,8 +1511,25 @@ msgstr "批准" msgid "Discard" msgstr "削除" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +#, fuzzy +#| msgid "Delete this progress update" +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/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "编辑列表" @@ -1513,6 +1564,12 @@ msgstr "开放" msgid "Anyone can add books to this list" msgstr "任何人都可以向此列表中添加书目" +#: bookwyrm/templates/lists/form.html:49 +#, fuzzy +#| msgid "Delete status" +msgid "Delete list" +msgstr "删除发文" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "你成功向该列表推荐了一本书!" @@ -1909,6 +1966,7 @@ msgid "Account" msgstr "帐号" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "个人资料" @@ -2029,12 +2087,6 @@ msgstr "回到列表" msgid "Edit Announcement" msgstr "编辑公告" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "删除" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "可见:" @@ -2085,6 +2137,7 @@ msgstr "结束日期" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "状态" @@ -2122,7 +2175,7 @@ msgstr "实例:" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 msgid "Status:" msgstr "状态:" @@ -2137,13 +2190,13 @@ msgstr "已屏蔽" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "软件:" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 msgid "Version:" msgstr "版本:" @@ -2170,6 +2223,7 @@ msgid "View all" msgstr "查看全部" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 msgid "Reports:" msgstr "报告:" @@ -2186,7 +2240,7 @@ msgid "Blocked by us:" msgstr "我们所屏蔽的:" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "备注" @@ -3106,7 +3160,7 @@ msgstr[0] "%(mutuals_display)s 个你也关注的关注者" msgid "No followers you follow" msgstr "没有你关注的关注者" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 msgid "Back to users" msgstr "回到用户" @@ -3133,31 +3187,83 @@ msgid "Remote instance" msgstr "移除服务器" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 msgid "Active" msgstr "活跃" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "停用" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "未设置" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "用户详情" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 msgid "View user profile" msgstr "查看用户个人资料" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "本站" + +#: bookwyrm/templates/user_admin/user_info.html:38 +#, fuzzy +#| msgid "Remove" +msgid "Remote" +msgstr "移除" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "用户详情" + +#: bookwyrm/templates/user_admin/user_info.html:52 +#, fuzzy +#| msgid "Email" +msgid "Email:" +msgstr "邮箱" + +#: bookwyrm/templates/user_admin/user_info.html:64 +#, fuzzy +#| msgid "Directory" +msgid "(View reports)" +msgstr "目录" + +#: bookwyrm/templates/user_admin/user_info.html:72 +#, fuzzy +#| msgid "Blocked by us:" +msgid "Blocked by count:" +msgstr "我们所屏蔽的:" + +#: bookwyrm/templates/user_admin/user_info.html:77 +#, fuzzy +#| msgid "last active" +msgid "Last active date:" +msgstr "最后活跃" + +#: bookwyrm/templates/user_admin/user_info.html:82 +#, fuzzy +#| msgid "Manually approve followers:" +msgid "Manually approved followers:" +msgstr "手动批准关注者:" + +#: bookwyrm/templates/user_admin/user_info.html:87 +#, fuzzy +#| msgid "Discover" +msgid "Discoverable:" +msgstr "发现" + +#: bookwyrm/templates/user_admin/user_info.html:93 +msgid "Deactivation reason:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:111 msgid "Instance details" msgstr "实例详情" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "查看实例" @@ -3219,6 +3325,3 @@ msgstr "" #~ msgid "Federated Timeline" #~ msgstr "跨站时间线" - -#~ msgid "Local" -#~ msgstr "本站" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 2149c9131..317cf052a 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/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-09-05 23:09+0000\n" +"POT-Creation-Date: 2021-09-07 16:12+0000\n" "PO-Revision-Date: 2021-06-30 10:36+0000\n" "Last-Translator: Grace Cheng \n" "Language-Team: LANGUAGE \n" @@ -18,59 +18,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: bookwyrm/forms.py:235 +#: bookwyrm/forms.py:195 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "新增書目" + +#: bookwyrm/forms.py:196 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "書目" + +#: bookwyrm/forms.py:197 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/forms.py:198 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "新增封面" + +#: bookwyrm/forms.py:199 +msgid "Paperback" +msgstr "" + +#: bookwyrm/forms.py:246 msgid "A user with this email already exists." msgstr "已經存在使用該郵箱的使用者。" -#: bookwyrm/forms.py:249 +#: bookwyrm/forms.py:260 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:250 +#: bookwyrm/forms.py:261 msgid "One Week" msgstr "一週" -#: bookwyrm/forms.py:251 +#: bookwyrm/forms.py:262 msgid "One Month" msgstr "一個月" -#: bookwyrm/forms.py:252 +#: bookwyrm/forms.py:263 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:257 +#: bookwyrm/forms.py:268 #, python-format msgid "%(count)d uses" msgstr "%(count)d 次使用" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:271 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:310 +#: bookwyrm/forms.py:321 msgid "List Order" msgstr "列表順序" -#: bookwyrm/forms.py:311 +#: bookwyrm/forms.py:322 msgid "Book Title" msgstr "書名" -#: bookwyrm/forms.py:312 +#: bookwyrm/forms.py:323 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "評價" -#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:318 +#: bookwyrm/forms.py:329 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:319 +#: bookwyrm/forms.py:330 msgid "Descending" msgstr "降序" @@ -268,7 +294,7 @@ msgid "Openlibrary key:" msgstr "Openlibrary key:" #: bookwyrm/templates/author/edit_author.html:89 -#: bookwyrm/templates/book/edit_book.html:300 +#: bookwyrm/templates/book/edit_book.html:315 msgid "Inventaire ID:" msgstr "Inventaire ID:" @@ -282,10 +308,10 @@ msgstr "Goodreads key:" #: bookwyrm/templates/author/edit_author.html:116 #: bookwyrm/templates/book/book.html:140 -#: bookwyrm/templates/book/edit_book.html:328 +#: bookwyrm/templates/book/edit_book.html:343 #: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/lists/bookmark_button.html:15 -#: bookwyrm/templates/lists/form.html:42 +#: bookwyrm/templates/lists/form.html:44 #: bookwyrm/templates/preferences/edit_user.html:78 #: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/edit_server.html:68 @@ -300,8 +326,9 @@ msgstr "儲存" #: bookwyrm/templates/author/edit_author.html:117 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/cover_modal.html:32 -#: bookwyrm/templates/book/edit_book.html:329 +#: bookwyrm/templates/book/edit_book.html:344 #: bookwyrm/templates/book/readthrough.html:77 +#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/moderation/report_modal.html:34 #: bookwyrm/templates/settings/federated_server.html:99 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:17 @@ -424,12 +451,12 @@ msgid "ISBN:" msgstr "ISBN:" #: bookwyrm/templates/book/book_identifiers.html:14 -#: bookwyrm/templates/book/edit_book.html:308 +#: bookwyrm/templates/book/edit_book.html:323 msgid "OCLC Number:" msgstr "OCLC 號:" #: bookwyrm/templates/book/book_identifiers.html:21 -#: bookwyrm/templates/book/edit_book.html:316 +#: bookwyrm/templates/book/edit_book.html:331 msgid "ASIN:" msgstr "ASIN:" @@ -561,28 +588,34 @@ msgstr "封面" msgid "Physical Properties" msgstr "實體性質" -#: bookwyrm/templates/book/edit_book.html:257 +#: bookwyrm/templates/book/edit_book.html:259 #: bookwyrm/templates/book/format_filter.html:5 msgid "Format:" msgstr "格式:" -#: bookwyrm/templates/book/edit_book.html:265 +#: bookwyrm/templates/book/edit_book.html:270 +#, fuzzy +#| msgid "User details" +msgid "Format details:" +msgstr "使用者詳情" + +#: bookwyrm/templates/book/edit_book.html:280 msgid "Pages:" msgstr "頁數:" -#: bookwyrm/templates/book/edit_book.html:274 +#: bookwyrm/templates/book/edit_book.html:289 msgid "Book Identifiers" msgstr "書目標識號" -#: bookwyrm/templates/book/edit_book.html:276 +#: bookwyrm/templates/book/edit_book.html:291 msgid "ISBN 13:" msgstr "ISBN 13:" -#: bookwyrm/templates/book/edit_book.html:284 +#: bookwyrm/templates/book/edit_book.html:299 msgid "ISBN 10:" msgstr "ISBN 10:" -#: bookwyrm/templates/book/edit_book.html:292 +#: bookwyrm/templates/book/edit_book.html:307 msgid "Openlibrary ID:" msgstr "Openlibrary ID:" @@ -714,6 +747,7 @@ msgid "Sorry! We couldn't find that code." msgstr "" #: bookwyrm/templates/confirm_email/confirm_email.html:19 +#: bookwyrm/templates/user_admin/user_info.html:100 #, fuzzy #| msgid "Confirm password:" msgid "Confirmation code:" @@ -1506,8 +1540,25 @@ msgstr "批准" msgid "Discard" msgstr "放棄" +#: bookwyrm/templates/lists/delete_list_modal.html:4 +#, fuzzy +#| msgid "Delete this progress update" +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/announcement.html:20 +#: 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/list_layout.html:16 +#: bookwyrm/templates/lists/layout.html:16 msgid "Edit List" msgstr "編輯列表" @@ -1542,6 +1593,12 @@ msgstr "開放" msgid "Anyone can add books to this list" msgstr "任何人都可以向此列表新增書目" +#: bookwyrm/templates/lists/form.html:49 +#, fuzzy +#| msgid "Delete status" +msgid "Delete list" +msgstr "刪除狀態" + #: bookwyrm/templates/lists/list.html:20 msgid "You successfully suggested a book for this list!" msgstr "你成功!向該列表推薦了一本書" @@ -1941,6 +1998,7 @@ msgid "Account" msgstr "帳號" #: bookwyrm/templates/preferences/layout.html:15 +#: bookwyrm/templates/user_admin/user_info.html:7 msgid "Profile" msgstr "使用者資料" @@ -2064,12 +2122,6 @@ msgstr "回到列表" msgid "Edit Announcement" msgstr "編輯公告" -#: bookwyrm/templates/settings/announcement.html:20 -#: bookwyrm/templates/snippets/delete_readthrough_modal.html:15 -#: bookwyrm/templates/snippets/follow_request_buttons.html:12 -msgid "Delete" -msgstr "刪除" - #: bookwyrm/templates/settings/announcement.html:35 msgid "Visible:" msgstr "可見:" @@ -2120,6 +2172,7 @@ msgstr "結束日期" #: bookwyrm/templates/settings/manage_invite_requests.html:44 #: bookwyrm/templates/settings/status_filter.html:5 #: bookwyrm/templates/user_admin/user_admin.html:34 +#: bookwyrm/templates/user_admin/user_info.html:20 msgid "Status" msgstr "狀態" @@ -2157,7 +2210,7 @@ msgstr "實例:" #: bookwyrm/templates/settings/edit_server.html:37 #: bookwyrm/templates/settings/federated_server.html:31 -#: bookwyrm/templates/user_admin/user_info.html:34 +#: bookwyrm/templates/user_admin/user_info.html:125 msgid "Status:" msgstr "狀態:" @@ -2172,13 +2225,13 @@ msgstr "已封鎖" #: bookwyrm/templates/settings/edit_server.html:48 #: bookwyrm/templates/settings/federated_server.html:23 -#: bookwyrm/templates/user_admin/user_info.html:26 +#: bookwyrm/templates/user_admin/user_info.html:117 msgid "Software:" msgstr "軟件:" #: bookwyrm/templates/settings/edit_server.html:55 #: bookwyrm/templates/settings/federated_server.html:27 -#: bookwyrm/templates/user_admin/user_info.html:30 +#: bookwyrm/templates/user_admin/user_info.html:121 msgid "Version:" msgstr "版本:" @@ -2205,6 +2258,7 @@ msgid "View all" msgstr "檢視全部" #: bookwyrm/templates/settings/federated_server.html:50 +#: bookwyrm/templates/user_admin/user_info.html:59 msgid "Reports:" msgstr "舉報:" @@ -2221,7 +2275,7 @@ msgid "Blocked by us:" msgstr "我們所封鎖的:" #: bookwyrm/templates/settings/federated_server.html:82 -#: bookwyrm/templates/user_admin/user_info.html:39 +#: bookwyrm/templates/user_admin/user_info.html:130 msgid "Notes" msgstr "備註" @@ -3164,7 +3218,7 @@ msgstr[0] "%(mutuals_display)s 個你也關注的關注者" msgid "No followers you follow" msgstr "你關注的關注者" -#: bookwyrm/templates/user_admin/user.html:9 +#: bookwyrm/templates/user_admin/user.html:8 msgid "Back to users" msgstr "回到使用者" @@ -3191,31 +3245,83 @@ msgid "Remote instance" msgstr "移除伺服器" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:24 msgid "Active" msgstr "活躍" #: bookwyrm/templates/user_admin/user_admin.html:47 +#: bookwyrm/templates/user_admin/user_info.html:28 msgid "Inactive" msgstr "停用" #: bookwyrm/templates/user_admin/user_admin.html:52 -#: bookwyrm/templates/user_admin/user_info.html:49 +#: bookwyrm/templates/user_admin/user_info.html:140 msgid "Not set" msgstr "未設定" -#: bookwyrm/templates/user_admin/user_info.html:5 -msgid "User details" -msgstr "使用者詳情" - -#: bookwyrm/templates/user_admin/user_info.html:14 +#: bookwyrm/templates/user_admin/user_info.html:16 msgid "View user profile" msgstr "檢視使用者資料" -#: bookwyrm/templates/user_admin/user_info.html:20 +#: bookwyrm/templates/user_admin/user_info.html:36 +msgid "Local" +msgstr "本站" + +#: bookwyrm/templates/user_admin/user_info.html:38 +#, fuzzy +#| msgid "Remove" +msgid "Remote" +msgstr "移除" + +#: bookwyrm/templates/user_admin/user_info.html:47 +msgid "User details" +msgstr "使用者詳情" + +#: bookwyrm/templates/user_admin/user_info.html:52 +#, fuzzy +#| msgid "Email" +msgid "Email:" +msgstr "郵箱" + +#: bookwyrm/templates/user_admin/user_info.html:64 +#, fuzzy +#| msgid "Directory" +msgid "(View reports)" +msgstr "目錄" + +#: bookwyrm/templates/user_admin/user_info.html:72 +#, fuzzy +#| msgid "Blocked by us:" +msgid "Blocked by count:" +msgstr "我們所封鎖的:" + +#: bookwyrm/templates/user_admin/user_info.html:77 +#, fuzzy +#| msgid "last active" +msgid "Last active date:" +msgstr "最後活躍" + +#: bookwyrm/templates/user_admin/user_info.html:82 +#, fuzzy +#| msgid "Manually approve followers:" +msgid "Manually approved followers:" +msgstr "手動批准關注者:" + +#: bookwyrm/templates/user_admin/user_info.html:87 +#, fuzzy +#| msgid "Discard" +msgid "Discoverable:" +msgstr "放棄" + +#: bookwyrm/templates/user_admin/user_info.html:93 +msgid "Deactivation reason:" +msgstr "" + +#: bookwyrm/templates/user_admin/user_info.html:111 msgid "Instance details" msgstr "實例詳情" -#: bookwyrm/templates/user_admin/user_info.html:46 +#: bookwyrm/templates/user_admin/user_info.html:137 msgid "View instance" msgstr "檢視實例" @@ -3277,6 +3383,3 @@ msgstr "" #~ msgid "Federated Timeline" #~ msgstr "跨站時間線" - -#~ msgid "Local" -#~ msgstr "本站" From 8420d0a173e00df640f71459f38c14a66ce81772 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 12:50:24 -0700 Subject: [PATCH 09/87] Adds format translations --- locale/de_DE/LC_MESSAGES/django.po | 80 ++++++++++++++-------------- locale/en_US/LC_MESSAGES/django.po | 68 +++++++++++------------ locale/es/LC_MESSAGES/django.po | 80 ++++++++++++++-------------- locale/fr_FR/LC_MESSAGES/django.po | 80 ++++++++++++++-------------- locale/zh_Hans/LC_MESSAGES/django.po | 80 ++++++++++++++-------------- locale/zh_Hant/LC_MESSAGES/django.po | 80 ++++++++++++++-------------- 6 files changed, 234 insertions(+), 234 deletions(-) diff --git a/locale/de_DE/LC_MESSAGES/django.po b/locale/de_DE/LC_MESSAGES/django.po index 49b1b4b22..73f729d5b 100644 --- a/locale/de_DE/LC_MESSAGES/django.po +++ b/locale/de_DE/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-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-03-02 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -18,98 +18,98 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:195 -#, fuzzy -#| msgid "Add Books" -msgid "Audiobook" -msgstr "Bücher hinzufügen" - -#: bookwyrm/forms.py:196 -#, fuzzy -#| msgid "Book" -msgid "eBook" -msgstr "Buch" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -#, fuzzy -#| msgid "Add cover" -msgid "Hardcover" -msgstr "Cover hinzufügen" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 #, fuzzy #| msgid "A user with that username already exists." msgid "A user with this email already exists." msgstr "Dieser Benutzename ist bereits vergeben." -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "Ein Tag" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "Eine Woche" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "Ein Monat" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "Läuft nicht aus" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "%(count)d Benutzungen" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 #, fuzzy #| msgid "Unlisted" msgid "Unlimited" msgstr "Ungelistet" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 #, fuzzy #| msgid "Title" msgid "Book Title" msgstr "Titel" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 #, fuzzy #| msgid "Started reading" msgid "Ascending" msgstr "Zu lesen angefangen" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 #, fuzzy #| msgid "Started reading" msgid "Descending" msgstr "Zu lesen angefangen" +#: bookwyrm/models/book.py:230 +#, fuzzy +#| msgid "Add Books" +msgid "Audiobook" +msgstr "Bücher hinzufügen" + +#: bookwyrm/models/book.py:231 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Buch" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Cover hinzufügen" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" diff --git a/locale/en_US/LC_MESSAGES/django.po b/locale/en_US/LC_MESSAGES/django.po index 637853e28..41b988359 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-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n" "Last-Translator: Mouse Reeve \n" "Language-Team: English \n" @@ -18,82 +18,82 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:195 -msgid "Audiobook" -msgstr "" - -#: bookwyrm/forms.py:196 -msgid "eBook" -msgstr "" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -msgid "Hardcover" -msgstr "" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 msgid "A user with this email already exists." msgstr "" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 msgid "Unlimited" msgstr "" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 msgid "Book Title" msgstr "" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 msgid "Ascending" msgstr "" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 msgid "Descending" msgstr "" +#: bookwyrm/models/book.py:230 +msgid "Audiobook" +msgstr "" + +#: bookwyrm/models/book.py:231 +msgid "eBook" +msgstr "" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +msgid "Hardcover" +msgstr "" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" diff --git a/locale/es/LC_MESSAGES/django.po b/locale/es/LC_MESSAGES/django.po index 12c4fb35d..904a07ca4 100644 --- a/locale/es/LC_MESSAGES/django.po +++ b/locale/es/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-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n" "Last-Translator: Reese Porter \n" "Language-Team: LANGUAGE \n" @@ -18,88 +18,88 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:195 -#, fuzzy -#| msgid "Add books" -msgid "Audiobook" -msgstr "Agregar libros" - -#: bookwyrm/forms.py:196 -#, fuzzy -#| msgid "Book" -msgid "eBook" -msgstr "Libro" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -#, fuzzy -#| msgid "Add cover" -msgid "Hardcover" -msgstr "Agregar portada" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 msgid "A user with this email already exists." msgstr "Ya existe un usuario con ese correo electrónico." -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "Un día" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "Una semana" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "Un mes" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "Nunca se vence" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "%(count)d usos" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 msgid "Unlimited" msgstr "Sin límite" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "Orden de la lista" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 msgid "Book Title" msgstr "Título" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "Calificación" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "Ordenar por" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 msgid "Ascending" msgstr "Ascendente" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 msgid "Descending" msgstr "Descendente" +#: bookwyrm/models/book.py:230 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "Agregar libros" + +#: bookwyrm/models/book.py:231 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Libro" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Agregar portada" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" diff --git a/locale/fr_FR/LC_MESSAGES/django.po b/locale/fr_FR/LC_MESSAGES/django.po index 58ae1aa18..2312e30b2 100644 --- a/locale/fr_FR/LC_MESSAGES/django.po +++ b/locale/fr_FR/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-04-05 12:44+0100\n" "Last-Translator: Fabien Basmaison \n" "Language-Team: Mouse Reeve \n" @@ -18,88 +18,88 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: bookwyrm/forms.py:195 -#, fuzzy -#| msgid "Add books" -msgid "Audiobook" -msgstr "Ajoutez des livres" - -#: bookwyrm/forms.py:196 -#, fuzzy -#| msgid "Book" -msgid "eBook" -msgstr "Livre" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -#, fuzzy -#| msgid "Add cover" -msgid "Hardcover" -msgstr "Ajouter une couverture" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 msgid "A user with this email already exists." msgstr "Cet email est déjà associé à un compte." -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "Un jour" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "Une semaine" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "Un mois" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "Sans expiration" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "%(count)d utilisations" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 msgid "Unlimited" msgstr "Sans limite" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "Ordre de la liste" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 msgid "Book Title" msgstr "Titre du livre" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "Note" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "Trier par" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 msgid "Ascending" msgstr "Ordre croissant" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 msgid "Descending" msgstr "Ordre décroissant" +#: bookwyrm/models/book.py:230 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "Ajoutez des livres" + +#: bookwyrm/models/book.py:231 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "Livre" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "Ajouter une couverture" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" diff --git a/locale/zh_Hans/LC_MESSAGES/django.po b/locale/zh_Hans/LC_MESSAGES/django.po index 41188afe9..a8212af85 100644 --- a/locale/zh_Hans/LC_MESSAGES/django.po +++ b/locale/zh_Hans/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 0.1.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-03-20 00:56+0000\n" "Last-Translator: Kana \n" "Language-Team: Mouse Reeve \n" @@ -18,88 +18,88 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: bookwyrm/forms.py:195 -#, fuzzy -#| msgid "Add books" -msgid "Audiobook" -msgstr "添加书目" - -#: bookwyrm/forms.py:196 -#, fuzzy -#| msgid "Book" -msgid "eBook" -msgstr "书目" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -#, fuzzy -#| msgid "Add cover" -msgid "Hardcover" -msgstr "添加封面" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 msgid "A user with this email already exists." msgstr "已经存在使用该邮箱的用户。" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "一周" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "一个月" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "%(count)d 次使用" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "列表顺序" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 msgid "Book Title" msgstr "书名" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "评价" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 msgid "Descending" msgstr "降序" +#: bookwyrm/models/book.py:230 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "添加书目" + +#: bookwyrm/models/book.py:231 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "书目" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "添加封面" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" diff --git a/locale/zh_Hant/LC_MESSAGES/django.po b/locale/zh_Hant/LC_MESSAGES/django.po index 317cf052a..a5d7ea94e 100644 --- a/locale/zh_Hant/LC_MESSAGES/django.po +++ b/locale/zh_Hant/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-09-07 16:12+0000\n" +"POT-Creation-Date: 2021-09-07 19:50+0000\n" "PO-Revision-Date: 2021-06-30 10:36+0000\n" "Last-Translator: Grace Cheng \n" "Language-Team: LANGUAGE \n" @@ -18,88 +18,88 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: bookwyrm/forms.py:195 -#, fuzzy -#| msgid "Add books" -msgid "Audiobook" -msgstr "新增書目" - -#: bookwyrm/forms.py:196 -#, fuzzy -#| msgid "Book" -msgid "eBook" -msgstr "書目" - -#: bookwyrm/forms.py:197 -msgid "Graphic novel" -msgstr "" - -#: bookwyrm/forms.py:198 -#, fuzzy -#| msgid "Add cover" -msgid "Hardcover" -msgstr "新增封面" - -#: bookwyrm/forms.py:199 -msgid "Paperback" -msgstr "" - -#: bookwyrm/forms.py:246 +#: bookwyrm/forms.py:235 msgid "A user with this email already exists." msgstr "已經存在使用該郵箱的使用者。" -#: bookwyrm/forms.py:260 +#: bookwyrm/forms.py:249 msgid "One Day" msgstr "一天" -#: bookwyrm/forms.py:261 +#: bookwyrm/forms.py:250 msgid "One Week" msgstr "一週" -#: bookwyrm/forms.py:262 +#: bookwyrm/forms.py:251 msgid "One Month" msgstr "一個月" -#: bookwyrm/forms.py:263 +#: bookwyrm/forms.py:252 msgid "Does Not Expire" msgstr "永不失效" -#: bookwyrm/forms.py:268 +#: bookwyrm/forms.py:257 #, python-format msgid "%(count)d uses" msgstr "%(count)d 次使用" -#: bookwyrm/forms.py:271 +#: bookwyrm/forms.py:260 msgid "Unlimited" msgstr "不受限" -#: bookwyrm/forms.py:321 +#: bookwyrm/forms.py:310 msgid "List Order" msgstr "列表順序" -#: bookwyrm/forms.py:322 +#: bookwyrm/forms.py:311 msgid "Book Title" msgstr "書名" -#: bookwyrm/forms.py:323 +#: bookwyrm/forms.py:312 #: bookwyrm/templates/snippets/create_status/review.html:23 #: bookwyrm/templates/user/shelf/shelf.html:117 #: bookwyrm/templates/user/shelf/shelf.html:148 msgid "Rating" msgstr "評價" -#: bookwyrm/forms.py:325 bookwyrm/templates/lists/list.html:107 +#: bookwyrm/forms.py:314 bookwyrm/templates/lists/list.html:107 msgid "Sort By" msgstr "排序方式" -#: bookwyrm/forms.py:329 +#: bookwyrm/forms.py:318 msgid "Ascending" msgstr "升序" -#: bookwyrm/forms.py:330 +#: bookwyrm/forms.py:319 msgid "Descending" msgstr "降序" +#: bookwyrm/models/book.py:230 +#, fuzzy +#| msgid "Add books" +msgid "Audiobook" +msgstr "新增書目" + +#: bookwyrm/models/book.py:231 +#, fuzzy +#| msgid "Book" +msgid "eBook" +msgstr "書目" + +#: bookwyrm/models/book.py:232 +msgid "Graphic novel" +msgstr "" + +#: bookwyrm/models/book.py:233 +#, fuzzy +#| msgid "Add cover" +msgid "Hardcover" +msgstr "新增封面" + +#: bookwyrm/models/book.py:234 +msgid "Paperback" +msgstr "" + #: bookwyrm/models/fields.py:27 #, python-format msgid "%(value)s is not a valid remote_id" From 6db0bf4b6aa13bd783e9d61cf7698d76550e6a9d Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 7 Sep 2021 12:51:07 -0700 Subject: [PATCH 10/87] Adds AP field --- bookwyrm/activitypub/book.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bookwyrm/activitypub/book.py b/bookwyrm/activitypub/book.py index bd27c4e60..d8599c4b3 100644 --- a/bookwyrm/activitypub/book.py +++ b/bookwyrm/activitypub/book.py @@ -54,6 +54,7 @@ class Edition(Book): asin: str = "" pages: int = None physicalFormat: str = "" + physicalFormatDetail: str = "" publishers: List[str] = field(default_factory=lambda: []) editionRank: int = 0 From 1f06d1a1d8386fcf6aa09441d09b6f2d0dd4941b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Tue, 14 Sep 2021 15:26:18 -0700 Subject: [PATCH 11/87] Removes local connector --- bookwyrm/connectors/__init__.py | 2 +- bookwyrm/connectors/abstract_connector.py | 1 - bookwyrm/connectors/connector_manager.py | 16 +- bookwyrm/connectors/self_connector.py | 164 ------------------ bookwyrm/management/commands/initdb.py | 13 -- .../migrations/0097_remove_connector_local.py | 17 ++ bookwyrm/models/connector.py | 1 - bookwyrm/templates/search/book.html | 19 +- .../snippets/search_result_text.html | 22 +-- bookwyrm/views/search.py | 19 +- 10 files changed, 55 insertions(+), 219 deletions(-) delete mode 100644 bookwyrm/connectors/self_connector.py create mode 100644 bookwyrm/migrations/0097_remove_connector_local.py diff --git a/bookwyrm/connectors/__init__.py b/bookwyrm/connectors/__init__.py index 689f27018..efbdb1666 100644 --- a/bookwyrm/connectors/__init__.py +++ b/bookwyrm/connectors/__init__.py @@ -3,4 +3,4 @@ from .settings import CONNECTORS from .abstract_connector import ConnectorException from .abstract_connector import get_data, get_image -from .connector_manager import search, local_search, first_search_result +from .connector_manager import search, first_search_result diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index ffacffdf0..9f20a6c35 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -31,7 +31,6 @@ class AbstractMinimalConnector(ABC): "isbn_search_url", "name", "identifier", - "local", ] for field in self_fields: setattr(self, field, getattr(info, field)) diff --git a/bookwyrm/connectors/connector_manager.py b/bookwyrm/connectors/connector_manager.py index 1d9588d6b..6f62b59a3 100644 --- a/bookwyrm/connectors/connector_manager.py +++ b/bookwyrm/connectors/connector_manager.py @@ -55,7 +55,7 @@ def search(query, min_confidence=0.1, return_first=False): # if we found anything, return it return result_set[0] - if result_set or connector.local: + if result_set: results.append( { "connector": connector, @@ -71,20 +71,6 @@ def search(query, min_confidence=0.1, return_first=False): return results -def local_search(query, min_confidence=0.1, raw=False, filters=None): - """only look at local search results""" - connector = load_connector(models.Connector.objects.get(local=True)) - return connector.search( - query, min_confidence=min_confidence, raw=raw, filters=filters - ) - - -def isbn_local_search(query, raw=False): - """only look at local search results""" - connector = load_connector(models.Connector.objects.get(local=True)) - return connector.isbn_search(query, raw=raw) - - def first_search_result(query, min_confidence=0.1): """search until you find a result that fits""" return search(query, min_confidence=min_confidence, return_first=True) or None diff --git a/bookwyrm/connectors/self_connector.py b/bookwyrm/connectors/self_connector.py deleted file mode 100644 index 8d5a7614e..000000000 --- a/bookwyrm/connectors/self_connector.py +++ /dev/null @@ -1,164 +0,0 @@ -""" using a bookwyrm instance as a source of book data """ -from functools import reduce -import operator - -from django.contrib.postgres.search import SearchRank, SearchQuery -from django.db.models import OuterRef, Subquery, F, Q - -from bookwyrm import models -from .abstract_connector import AbstractConnector, SearchResult - - -class Connector(AbstractConnector): - """instantiate a connector""" - - # pylint: disable=arguments-differ - def search(self, query, min_confidence=0, raw=False, filters=None): - """search your local database""" - filters = filters or [] - if not query: - return [] - # first, try searching unqiue identifiers - results = search_identifiers(query, *filters) - if not results: - # then try searching title/author - results = search_title_author(query, min_confidence, *filters) - search_results = [] - for result in results: - if raw: - search_results.append(result) - else: - search_results.append(self.format_search_result(result)) - if len(search_results) >= 10: - break - if not raw: - search_results.sort(key=lambda r: r.confidence, reverse=True) - return search_results - - def isbn_search(self, query, raw=False): - """search your local database""" - if not query: - return [] - - filters = [{f: query} for f in ["isbn_10", "isbn_13"]] - results = models.Edition.objects.filter( - reduce(operator.or_, (Q(**f) for f in filters)) - ).distinct() - - # when there are multiple editions of the same work, pick the default. - # it would be odd for this to happen. - - default_editions = models.Edition.objects.filter( - parent_work=OuterRef("parent_work") - ).order_by("-edition_rank") - results = ( - results.annotate( - default_id=Subquery(default_editions.values("id")[:1]) - ).filter(default_id=F("id")) - or results - ) - - search_results = [] - for result in results: - if raw: - search_results.append(result) - else: - search_results.append(self.format_search_result(result)) - if len(search_results) >= 10: - break - return search_results - - def format_search_result(self, search_result): - cover = None - if search_result.cover: - cover = "%s%s" % (self.covers_url, search_result.cover) - - return SearchResult( - title=search_result.title, - key=search_result.remote_id, - author=search_result.author_text, - year=search_result.published_date.year - if search_result.published_date - else None, - connector=self, - cover=cover, - confidence=search_result.rank if hasattr(search_result, "rank") else 1, - ) - - def format_isbn_search_result(self, search_result): - return self.format_search_result(search_result) - - def is_work_data(self, data): - pass - - def get_edition_from_work_data(self, data): - pass - - def get_work_from_edition_data(self, data): - pass - - def get_authors_from_data(self, data): - return None - - def parse_isbn_search_data(self, data): - """it's already in the right format, don't even worry about it""" - return data - - def parse_search_data(self, data): - """it's already in the right format, don't even worry about it""" - return data - - def expand_book_data(self, book): - pass - - -def search_identifiers(query, *filters): - """tries remote_id, isbn; defined as dedupe fields on the model""" - # pylint: disable=W0212 - or_filters = [ - {f.name: query} - for f in models.Edition._meta.get_fields() - if hasattr(f, "deduplication_field") and f.deduplication_field - ] - results = models.Edition.objects.filter( - *filters, reduce(operator.or_, (Q(**f) for f in or_filters)) - ).distinct() - if results.count() <= 1: - return results - - # when there are multiple editions of the same work, pick the default. - # it would be odd for this to happen. - default_editions = models.Edition.objects.filter( - parent_work=OuterRef("parent_work") - ).order_by("-edition_rank") - return ( - results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter( - default_id=F("id") - ) - or results - ) - - -def search_title_author(query, min_confidence, *filters): - """searches for title and author""" - query = SearchQuery(query, config="simple") | SearchQuery(query, config="english") - results = ( - models.Edition.objects.filter(*filters, search_vector=query) - .annotate(rank=SearchRank(F("search_vector"), query)) - .filter(rank__gt=min_confidence) - .order_by("-rank") - ) - - # when there are multiple editions of the same work, pick the closest - editions_of_work = results.values("parent_work__id").values_list("parent_work__id") - - # filter out multiple editions of the same work - for work_id in set(editions_of_work): - editions = results.filter(parent_work=work_id) - default = editions.order_by("-edition_rank").first() - default_rank = default.rank if default else 0 - # if mutliple books have the top rank, pick the default edition - if default_rank == editions.first().rank: - yield default - else: - yield editions.first() diff --git a/bookwyrm/management/commands/initdb.py b/bookwyrm/management/commands/initdb.py index 71ac511a0..9f2f29cda 100644 --- a/bookwyrm/management/commands/initdb.py +++ b/bookwyrm/management/commands/initdb.py @@ -73,19 +73,6 @@ def init_permissions(): def init_connectors(): """access book data sources""" - Connector.objects.create( - identifier=DOMAIN, - name="Local", - local=True, - connector_file="self_connector", - base_url="https://%s" % DOMAIN, - books_url="https://%s/book" % DOMAIN, - covers_url="https://%s/images/" % DOMAIN, - search_url="https://%s/search?q=" % DOMAIN, - isbn_search_url="https://%s/isbn/" % DOMAIN, - priority=1, - ) - Connector.objects.create( identifier="bookwyrm.social", name="BookWyrm dot Social", diff --git a/bookwyrm/migrations/0097_remove_connector_local.py b/bookwyrm/migrations/0097_remove_connector_local.py new file mode 100644 index 000000000..fc04bccec --- /dev/null +++ b/bookwyrm/migrations/0097_remove_connector_local.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.4 on 2021-09-14 22:10 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("bookwyrm", "0096_merge_20210912_0044"), + ] + + operations = [ + migrations.RemoveField( + model_name="connector", + name="local", + ), + ] diff --git a/bookwyrm/models/connector.py b/bookwyrm/models/connector.py index 17ba31489..b982c0ff6 100644 --- a/bookwyrm/models/connector.py +++ b/bookwyrm/models/connector.py @@ -14,7 +14,6 @@ class Connector(BookWyrmModel): identifier = models.CharField(max_length=255, unique=True) priority = models.IntegerField(default=2) name = models.CharField(max_length=255, null=True, blank=True) - local = models.BooleanField(default=False) connector_file = models.CharField(max_length=255, choices=ConnectorFiles.choices) api_key = models.CharField(max_length=255, null=True, blank=True) active = models.BooleanField(default=True) diff --git a/bookwyrm/templates/search/book.html b/bookwyrm/templates/search/book.html index 39f837328..12164bb3f 100644 --- a/bookwyrm/templates/search/book.html +++ b/bookwyrm/templates/search/book.html @@ -8,7 +8,24 @@
    {% for result in local_results.results %}
  • - {% include 'snippets/search_result_text.html' with result=result %} +
    +
    + {% include 'snippets/book_cover.html' with book=result cover_class='is-w-xs is-h-xs' %} +
    + +
    +

    + + {% include "snippets/book_titleby.html" with book=result %} + +

    +

    + {% if result.first_published_date or result.published_date %} + ({% firstof result.first_published_date.year result.published_date.year %}) + {% endif %} +

    +
    +
  • {% endfor %}
diff --git a/bookwyrm/templates/snippets/search_result_text.html b/bookwyrm/templates/snippets/search_result_text.html index 40fa5a3d5..973f1f5bc 100644 --- a/bookwyrm/templates/snippets/search_result_text.html +++ b/bookwyrm/templates/snippets/search_result_text.html @@ -9,10 +9,8 @@ {{ result.title }}

@@ -26,16 +24,14 @@ {% endif %}

- {% if remote_result %} -
- {% csrf_token %} + + {% csrf_token %} - + - -
- {% endif %} + +
diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index cdea86631..6c9593a1d 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -10,6 +10,7 @@ from django.views import View from bookwyrm import models from bookwyrm.connectors import connector_manager +from bookwyrm.book_search import search from bookwyrm.settings import PAGE_LENGTH from bookwyrm.utils import regex from .helpers import is_api_request, privacy_filter @@ -31,9 +32,7 @@ class Search(View): if is_api_request(request): # only return local book results via json so we don't cascade - book_results = connector_manager.local_search( - query, min_confidence=min_confidence - ) + book_results = search(query, min_confidence=min_confidence) return JsonResponse([r.json() for r in book_results], safe=False) if query and not search_type: @@ -69,13 +68,13 @@ class Search(View): def book_search(query, _, min_confidence, search_remote=False): """the real business is elsewhere""" # try a local-only search - if not search_remote: - results = connector_manager.local_search(query, min_confidence=min_confidence) - if results: - # gret, we found something - return [{"results": results}], False - # if there weere no local results, or the request was for remote, search all sources - return connector_manager.search(query, min_confidence=min_confidence), True + results = [{"results": search(query, min_confidence=min_confidence)}] + if results and not search_remote: + return results, False + + # if there were no local results, or the request was for remote, search all sources + results += connector_manager.search(query, min_confidence=min_confidence) + return results, True def user_search(query, viewer, *_): From 98325818b2295ca4786a8f51c055cea13b28cbfe Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 10:44:33 -0700 Subject: [PATCH 12/87] Display search results in api mode and regular --- bookwyrm/book_search.py | 120 ++++++++++++++++++ bookwyrm/templates/search/book.html | 28 +++- .../snippets/search_result_text.html | 37 ------ bookwyrm/urls.py | 1 + bookwyrm/views/helpers.py | 4 +- bookwyrm/views/search.py | 6 +- 6 files changed, 155 insertions(+), 41 deletions(-) create mode 100644 bookwyrm/book_search.py delete mode 100644 bookwyrm/templates/snippets/search_result_text.html diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py new file mode 100644 index 000000000..8682b83e1 --- /dev/null +++ b/bookwyrm/book_search.py @@ -0,0 +1,120 @@ +""" using a bookwyrm instance as a source of book data """ +from functools import reduce +import operator + +from django.contrib.postgres.search import SearchRank, SearchQuery +from django.db.models import OuterRef, Subquery, F, Q + +from bookwyrm import models +from bookwyrm.connectors.abstract_connector import SearchResult +from bookwyrm.settings import MEDIA_FULL_URL + + +# pylint: disable=arguments-differ +def search(query, min_confidence=0, filters=None): + """search your local database""" + filters = filters or [] + if not query: + return [] + # first, try searching unqiue identifiers + results = search_identifiers(query, *filters) + if not results: + # then try searching title/author + results = search_title_author(query, min_confidence, *filters) + return results + + +def isbn_search(query): + """search your local database""" + if not query: + return [] + + filters = [{f: query} for f in ["isbn_10", "isbn_13"]] + results = models.Edition.objects.filter( + reduce(operator.or_, (Q(**f) for f in filters)) + ).distinct() + + # when there are multiple editions of the same work, pick the default. + # it would be odd for this to happen. + + default_editions = models.Edition.objects.filter( + parent_work=OuterRef("parent_work") + ).order_by("-edition_rank") + results = ( + results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter( + default_id=F("id") + ) + or results + ) + return results + + +def format_search_result(search_result): + """convert a book object into a search result object""" + cover = None + if search_result.cover: + cover = f"{MEDIA_FULL_URL}{search_result.cover}" + + return SearchResult( + title=search_result.title, + key=search_result.remote_id, + author=search_result.author_text, + year=search_result.published_date.year + if search_result.published_date + else None, + cover=cover, + confidence=search_result.rank if hasattr(search_result, "rank") else 1, + connector="", + ).json() + + +def search_identifiers(query, *filters): + """tries remote_id, isbn; defined as dedupe fields on the model""" + # pylint: disable=W0212 + or_filters = [ + {f.name: query} + for f in models.Edition._meta.get_fields() + if hasattr(f, "deduplication_field") and f.deduplication_field + ] + results = models.Edition.objects.filter( + *filters, reduce(operator.or_, (Q(**f) for f in or_filters)) + ).distinct() + if results.count() <= 1: + return results + + # when there are multiple editions of the same work, pick the default. + # it would be odd for this to happen. + default_editions = models.Edition.objects.filter( + parent_work=OuterRef("parent_work") + ).order_by("-edition_rank") + return ( + results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter( + default_id=F("id") + ) + or results + ) + + +def search_title_author(query, min_confidence, *filters): + """searches for title and author""" + query = SearchQuery(query, config="simple") | SearchQuery(query, config="english") + results = ( + models.Edition.objects.filter(*filters, search_vector=query) + .annotate(rank=SearchRank(F("search_vector"), query)) + .filter(rank__gt=min_confidence) + .order_by("-rank") + ) + + # when there are multiple editions of the same work, pick the closest + editions_of_work = results.values("parent_work__id").values_list("parent_work__id") + + # filter out multiple editions of the same work + for work_id in set(editions_of_work): + editions = results.filter(parent_work=work_id) + default = editions.order_by("-edition_rank").first() + default_rank = default.rank if default else 0 + # if mutliple books have the top rank, pick the default edition + if default_rank == editions.first().rank: + yield default + else: + yield editions.first() diff --git a/bookwyrm/templates/search/book.html b/bookwyrm/templates/search/book.html index 12164bb3f..98590f202 100644 --- a/bookwyrm/templates/search/book.html +++ b/bookwyrm/templates/search/book.html @@ -60,7 +60,33 @@
    {% for result in result_set.results %}
  • - {% include 'snippets/search_result_text.html' with result=result remote_result=True %} +
    +
    + {% include 'snippets/book_cover.html' with book=result cover_class='is-w-xs is-h-xs' external_path=True %} +
    +
    +

    + + {{ result.title }} + +

    +

    + {{ result.author }} + {% if result.year %}({{ result.year }}){% endif %} +

    +
    + {% csrf_token %} + + +
    +
    +
  • {% endfor %}
diff --git a/bookwyrm/templates/snippets/search_result_text.html b/bookwyrm/templates/snippets/search_result_text.html deleted file mode 100644 index 973f1f5bc..000000000 --- a/bookwyrm/templates/snippets/search_result_text.html +++ /dev/null @@ -1,37 +0,0 @@ -{% load i18n %} -
-
- {% include 'snippets/book_cover.html' with book=result cover_class='is-w-xs is-h-xs' external_path=True %} -
- -
-

- - {{ result.title }} - -

-

- {% if result.author %} - {{ result.author }} - {% endif %} - - {% if result.year %} - ({{ result.year }}) - {% endif %} -

- -
- {% csrf_token %} - - - - -
-
-
diff --git a/bookwyrm/urls.py b/bookwyrm/urls.py index 6acf75cb3..15086a666 100644 --- a/bookwyrm/urls.py +++ b/bookwyrm/urls.py @@ -221,6 +221,7 @@ urlpatterns = [ ), # search re_path(r"^search/?$", views.Search.as_view(), name="search"), + re_path(r"^search.json/?$", 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"), diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py index b1e5f68c7..aa26ae182 100644 --- a/bookwyrm/views/helpers.py +++ b/bookwyrm/views/helpers.py @@ -32,7 +32,9 @@ def get_user_from_username(viewer, username): def is_api_request(request): """check whether a request is asking for html or data""" - return "json" in request.headers.get("Accept", "") or request.path[-5:] == ".json" + return "json" in request.headers.get("Accept", "") or re.match( + r".*\.json/?$", request.path + ) def is_bookwyrm_request(request): diff --git a/bookwyrm/views/search.py b/bookwyrm/views/search.py index 6c9593a1d..60a1879aa 100644 --- a/bookwyrm/views/search.py +++ b/bookwyrm/views/search.py @@ -10,7 +10,7 @@ from django.views import View from bookwyrm import models from bookwyrm.connectors import connector_manager -from bookwyrm.book_search import search +from bookwyrm.book_search import search, format_search_result from bookwyrm.settings import PAGE_LENGTH from bookwyrm.utils import regex from .helpers import is_api_request, privacy_filter @@ -33,7 +33,9 @@ class Search(View): if is_api_request(request): # only return local book results via json so we don't cascade book_results = search(query, min_confidence=min_confidence) - return JsonResponse([r.json() for r in book_results], safe=False) + return JsonResponse( + [format_search_result(r) for r in book_results], safe=False + ) if query and not search_type: search_type = "user" if "@" in query else "book" From 0d5e05a3c2ca57922b45db4dfa5f47a842d66716 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 10:55:23 -0700 Subject: [PATCH 13/87] Updates other calls to the search endpoint --- bookwyrm/views/get_started.py | 5 ++--- bookwyrm/views/isbn.py | 4 ++-- bookwyrm/views/list.py | 6 ++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/bookwyrm/views/get_started.py b/bookwyrm/views/get_started.py index 3de88e104..981c62a21 100644 --- a/bookwyrm/views/get_started.py +++ b/bookwyrm/views/get_started.py @@ -11,8 +11,7 @@ from django.template.response import TemplateResponse from django.utils.decorators import method_decorator from django.views import View -from bookwyrm import forms, models -from bookwyrm.connectors import connector_manager +from bookwyrm import book_search, forms, models from bookwyrm.suggested_users import suggested_users from .edit_user import save_user_form @@ -55,7 +54,7 @@ class GetStartedBooks(View): query = request.GET.get("query") book_results = popular_books = [] if query: - book_results = connector_manager.local_search(query, raw=True)[:5] + book_results = book_search.search(query)[:5] if len(book_results) < 5: popular_books = ( models.Edition.objects.exclude( diff --git a/bookwyrm/views/isbn.py b/bookwyrm/views/isbn.py index 3055a3542..173a3adb9 100644 --- a/bookwyrm/views/isbn.py +++ b/bookwyrm/views/isbn.py @@ -4,7 +4,7 @@ from django.http import JsonResponse from django.template.response import TemplateResponse from django.views import View -from bookwyrm.connectors import connector_manager +from bookwyrm import book_search from bookwyrm.settings import PAGE_LENGTH from .helpers import is_api_request @@ -14,7 +14,7 @@ class Isbn(View): def get(self, request, isbn): """info about a book""" - book_results = connector_manager.isbn_local_search(isbn) + book_results = book_search.isbn_search(isbn) if is_api_request(request): return JsonResponse([r.json() for r in book_results], safe=False) diff --git a/bookwyrm/views/list.py b/bookwyrm/views/list.py index af99e9f55..e2eab7ef4 100644 --- a/bookwyrm/views/list.py +++ b/bookwyrm/views/list.py @@ -16,9 +16,8 @@ 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 book_search, forms, models from bookwyrm.activitypub import ActivitypubResponse -from bookwyrm.connectors import connector_manager from bookwyrm.settings import PAGE_LENGTH from .helpers import is_api_request, privacy_filter from .helpers import get_user_from_username @@ -150,9 +149,8 @@ class List(View): if query and request.user.is_authenticated: # search for books - suggestions = connector_manager.local_search( + suggestions = book_search.search( query, - raw=True, filters=[~Q(parent_work__editions__in=book_list.books.all())], ) elif request.user.is_authenticated: From 76ab5a763c081b08219d183229fc72c75d994527 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 10:56:28 -0700 Subject: [PATCH 14/87] Remove outdated test --- bookwyrm/tests/connectors/test_connector_manager.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/bookwyrm/tests/connectors/test_connector_manager.py b/bookwyrm/tests/connectors/test_connector_manager.py index 67b108dd1..32acba7a2 100644 --- a/bookwyrm/tests/connectors/test_connector_manager.py +++ b/bookwyrm/tests/connectors/test_connector_manager.py @@ -96,12 +96,6 @@ class ConnectorManager(TestCase): self.assertEqual(len(results[0]["results"]), 1) self.assertEqual(results[0]["results"][0].title, "Example Edition") - def test_local_search(self): - """search only the local database""" - results = connector_manager.local_search("Example") - self.assertEqual(len(results), 1) - self.assertEqual(results[0].title, "Example Edition") - def test_first_search_result(self): """only get one search result""" result = connector_manager.first_search_result("Example") From fbe05623ff3b994c6c91d9e36144fef33fa93138 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 11:07:36 -0700 Subject: [PATCH 15/87] Updates first_search_result functionality --- bookwyrm/book_search.py | 26 ++++++++++++++++-------- bookwyrm/connectors/connector_manager.py | 7 ++++++- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py index 8682b83e1..8693209cf 100644 --- a/bookwyrm/book_search.py +++ b/bookwyrm/book_search.py @@ -11,16 +11,18 @@ from bookwyrm.settings import MEDIA_FULL_URL # pylint: disable=arguments-differ -def search(query, min_confidence=0, filters=None): +def search(query, min_confidence=0, filters=None, return_first=False): """search your local database""" filters = filters or [] if not query: return [] # first, try searching unqiue identifiers - results = search_identifiers(query, *filters) + results = search_identifiers(query, *filters, return_first=return_first) if not results: # then try searching title/author - results = search_title_author(query, min_confidence, *filters) + results = search_title_author( + query, min_confidence, *filters, return_first=return_first + ) return results @@ -68,7 +70,7 @@ def format_search_result(search_result): ).json() -def search_identifiers(query, *filters): +def search_identifiers(query, *filters, return_first=False): """tries remote_id, isbn; defined as dedupe fields on the model""" # pylint: disable=W0212 or_filters = [ @@ -87,15 +89,18 @@ def search_identifiers(query, *filters): default_editions = models.Edition.objects.filter( parent_work=OuterRef("parent_work") ).order_by("-edition_rank") - return ( + results = ( results.annotate(default_id=Subquery(default_editions.values("id")[:1])).filter( default_id=F("id") ) or results ) + if return_first: + return results.first() + return results -def search_title_author(query, min_confidence, *filters): +def search_title_author(query, min_confidence, *filters, return_first=False): """searches for title and author""" query = SearchQuery(query, config="simple") | SearchQuery(query, config="english") results = ( @@ -109,12 +114,17 @@ def search_title_author(query, min_confidence, *filters): editions_of_work = results.values("parent_work__id").values_list("parent_work__id") # filter out multiple editions of the same work + results = [] for work_id in set(editions_of_work): editions = results.filter(parent_work=work_id) default = editions.order_by("-edition_rank").first() default_rank = default.rank if default else 0 # if mutliple books have the top rank, pick the default edition if default_rank == editions.first().rank: - yield default + result = default else: - yield editions.first() + result = editions.first() + if return_first: + return result + results.append(result) + return results diff --git a/bookwyrm/connectors/connector_manager.py b/bookwyrm/connectors/connector_manager.py index 6f62b59a3..d9c997e6e 100644 --- a/bookwyrm/connectors/connector_manager.py +++ b/bookwyrm/connectors/connector_manager.py @@ -10,7 +10,7 @@ from django.db.models import signals from requests import HTTPError -from bookwyrm import models +from bookwyrm import book_search, models from bookwyrm.tasks import app logger = logging.getLogger(__name__) @@ -73,6 +73,11 @@ def search(query, min_confidence=0.1, return_first=False): def first_search_result(query, min_confidence=0.1): """search until you find a result that fits""" + # try local search first + result = book_search.search(query, min_confidence=min_confidence, return_first=True) + if result: + return result + # otherwise, try remote endpoints return search(query, min_confidence=min_confidence, return_first=True) or None From 18591c7b561b1b2372f681f0fd4261d48b5bca01 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 11:30:04 -0700 Subject: [PATCH 16/87] Fixes circular import --- bookwyrm/book_search.py | 27 ++++++++++++++++++++++- bookwyrm/connectors/abstract_connector.py | 26 ---------------------- bookwyrm/connectors/bookwyrm_connector.py | 3 ++- bookwyrm/connectors/inventaire.py | 3 ++- bookwyrm/connectors/openlibrary.py | 3 ++- 5 files changed, 32 insertions(+), 30 deletions(-) diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py index 8693209cf..c4d03caf6 100644 --- a/bookwyrm/book_search.py +++ b/bookwyrm/book_search.py @@ -1,4 +1,5 @@ """ using a bookwyrm instance as a source of book data """ +from dataclasses import asdict, dataclass from functools import reduce import operator @@ -6,7 +7,6 @@ from django.contrib.postgres.search import SearchRank, SearchQuery from django.db.models import OuterRef, Subquery, F, Q from bookwyrm import models -from bookwyrm.connectors.abstract_connector import SearchResult from bookwyrm.settings import MEDIA_FULL_URL @@ -128,3 +128,28 @@ def search_title_author(query, min_confidence, *filters, return_first=False): return result results.append(result) return results + + +@dataclass +class SearchResult: + """standardized search result object""" + + title: str + key: str + connector: object + view_link: str = None + author: str = None + year: str = None + cover: str = None + confidence: int = 1 + + def __repr__(self): + return "".format( + self.key, self.title, self.author + ) + + def json(self): + """serialize a connector for json response""" + serialized = asdict(self) + del serialized["connector"] + return serialized diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 9f20a6c35..5c58f8f83 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -1,6 +1,5 @@ """ functionality outline for a book data connector """ from abc import ABC, abstractmethod -from dataclasses import asdict, dataclass import logging from django.db import transaction @@ -268,31 +267,6 @@ def get_image(url, timeout=10): return resp -@dataclass -class SearchResult: - """standardized search result object""" - - title: str - key: str - connector: object - view_link: str = None - author: str = None - year: str = None - cover: str = None - confidence: int = 1 - - def __repr__(self): - return "".format( - self.key, self.title, self.author - ) - - def json(self): - """serialize a connector for json response""" - serialized = asdict(self) - del serialized["connector"] - return serialized - - class Mapping: """associate a local database field with a field in an external dataset""" diff --git a/bookwyrm/connectors/bookwyrm_connector.py b/bookwyrm/connectors/bookwyrm_connector.py index 10a633b2d..6dcba7c31 100644 --- a/bookwyrm/connectors/bookwyrm_connector.py +++ b/bookwyrm/connectors/bookwyrm_connector.py @@ -1,6 +1,7 @@ """ using another bookwyrm instance as a source of book data """ from bookwyrm import activitypub, models -from .abstract_connector import AbstractMinimalConnector, SearchResult +from bookwyrm.book_search import SearchResult +from .abstract_connector import AbstractMinimalConnector class Connector(AbstractMinimalConnector): diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index d2a7b9faa..8b85dbd96 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -2,7 +2,8 @@ import re from bookwyrm import models -from .abstract_connector import AbstractConnector, SearchResult, Mapping +from bookwyrm.book_search import SearchResult +from .abstract_connector import AbstractConnector, Mapping from .abstract_connector import get_data from .connector_manager import ConnectorException diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index e58749c13..0bfc6ef1e 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -2,7 +2,8 @@ import re from bookwyrm import models -from .abstract_connector import AbstractConnector, SearchResult, Mapping +from bookwyrm.book_search import SearchResult +from .abstract_connector import AbstractConnector, Mapping from .abstract_connector import get_data from .connector_manager import ConnectorException from .openlibrary_languages import languages From beb482f1db43a6b9349373aab1ca6e494e9ce157 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 11:47:44 -0700 Subject: [PATCH 17/87] Linter fixes Temporarily disables C0209 because it's out of scope to fix here --- .github/workflows/pylint.yml | 2 +- bookwyrm/templates/search/book.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 1b14149f2..2a81eaa3e 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -24,5 +24,5 @@ jobs: pip install pylint - name: Analysing the code with pylint run: | - pylint bookwyrm/ --ignore=migrations,tests --disable=E1101,E1135,E1136,R0903,R0901,R0902,W0707,W0511,W0406,R0401,R0801 + pylint bookwyrm/ --ignore=migrations,tests --disable=E1101,E1135,E1136,R0903,R0901,R0902,W0707,W0511,W0406,R0401,R0801,C0209 diff --git a/bookwyrm/templates/search/book.html b/bookwyrm/templates/search/book.html index 98590f202..704f055bf 100644 --- a/bookwyrm/templates/search/book.html +++ b/bookwyrm/templates/search/book.html @@ -8,7 +8,7 @@
    {% for result in local_results.results %}
  • -
    +
    {% include 'snippets/book_cover.html' with book=result cover_class='is-w-xs is-h-xs' %}
    From 4cdf895d777d37066efb454f906bc90bc639ab3e Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 12:29:02 -0700 Subject: [PATCH 18/87] Removes references to local field in connector tests --- bookwyrm/tests/connectors/test_abstract_minimal_connector.py | 1 - bookwyrm/tests/connectors/test_connector_manager.py | 2 -- bookwyrm/tests/connectors/test_self_connector.py | 1 - bookwyrm/tests/importers/test_goodreads_import.py | 1 - bookwyrm/tests/importers/test_librarything_import.py | 1 - bookwyrm/tests/views/test_get_started.py | 2 +- bookwyrm/tests/views/test_search.py | 2 +- 7 files changed, 2 insertions(+), 8 deletions(-) diff --git a/bookwyrm/tests/connectors/test_abstract_minimal_connector.py b/bookwyrm/tests/connectors/test_abstract_minimal_connector.py index 846291399..30db40cd6 100644 --- a/bookwyrm/tests/connectors/test_abstract_minimal_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_minimal_connector.py @@ -53,7 +53,6 @@ class AbstractConnector(TestCase): self.assertEqual(connector.isbn_search_url, "https://example.com/isbn?q=") self.assertIsNone(connector.name) self.assertEqual(connector.identifier, "example.com") - self.assertFalse(connector.local) @responses.activate def test_search(self): diff --git a/bookwyrm/tests/connectors/test_connector_manager.py b/bookwyrm/tests/connectors/test_connector_manager.py index 32acba7a2..f87b9c438 100644 --- a/bookwyrm/tests/connectors/test_connector_manager.py +++ b/bookwyrm/tests/connectors/test_connector_manager.py @@ -25,7 +25,6 @@ class ConnectorManager(TestCase): self.connector = models.Connector.objects.create( identifier="test_connector", priority=1, - local=True, connector_file="self_connector", base_url="http://test.com/", books_url="http://test.com/", @@ -36,7 +35,6 @@ class ConnectorManager(TestCase): self.remote_connector = models.Connector.objects.create( identifier="test_connector_remote", priority=1, - local=False, connector_file="bookwyrm_connector", base_url="http://fake.ciom/", books_url="http://fake.ciom/", diff --git a/bookwyrm/tests/connectors/test_self_connector.py b/bookwyrm/tests/connectors/test_self_connector.py index 86aa7add4..a5eab8797 100644 --- a/bookwyrm/tests/connectors/test_self_connector.py +++ b/bookwyrm/tests/connectors/test_self_connector.py @@ -16,7 +16,6 @@ class SelfConnector(TestCase): models.Connector.objects.create( identifier=DOMAIN, name="Local", - local=True, connector_file="self_connector", base_url="https://%s" % DOMAIN, books_url="https://%s/book" % DOMAIN, diff --git a/bookwyrm/tests/importers/test_goodreads_import.py b/bookwyrm/tests/importers/test_goodreads_import.py index 387d9f4f2..c332bf693 100644 --- a/bookwyrm/tests/importers/test_goodreads_import.py +++ b/bookwyrm/tests/importers/test_goodreads_import.py @@ -42,7 +42,6 @@ class GoodreadsImport(TestCase): models.Connector.objects.create( identifier=DOMAIN, name="Local", - local=True, connector_file="self_connector", base_url="https://%s" % DOMAIN, books_url="https://%s/book" % DOMAIN, diff --git a/bookwyrm/tests/importers/test_librarything_import.py b/bookwyrm/tests/importers/test_librarything_import.py index dfdd515e1..7a1c5d510 100644 --- a/bookwyrm/tests/importers/test_librarything_import.py +++ b/bookwyrm/tests/importers/test_librarything_import.py @@ -43,7 +43,6 @@ class LibrarythingImport(TestCase): models.Connector.objects.create( identifier=DOMAIN, name="Local", - local=True, connector_file="self_connector", base_url="https://%s" % DOMAIN, books_url="https://%s/book" % DOMAIN, diff --git a/bookwyrm/tests/views/test_get_started.py b/bookwyrm/tests/views/test_get_started.py index 135896dc2..cc53986fa 100644 --- a/bookwyrm/tests/views/test_get_started.py +++ b/bookwyrm/tests/views/test_get_started.py @@ -30,7 +30,7 @@ class GetStartedViews(TestCase): remote_id="https://example.com/book/1", ) models.Connector.objects.create( - identifier="self", connector_file="self_connector", local=True + identifier="self", connector_file="self_connector" ) models.SiteSettings.objects.create() diff --git a/bookwyrm/tests/views/test_search.py b/bookwyrm/tests/views/test_search.py index dacbcbded..7eb75dab8 100644 --- a/bookwyrm/tests/views/test_search.py +++ b/bookwyrm/tests/views/test_search.py @@ -37,7 +37,7 @@ class Views(TestCase): parent_work=self.work, ) models.Connector.objects.create( - identifier="self", connector_file="self_connector", local=True + identifier="self", connector_file="self_connector" ) models.SiteSettings.objects.create() From 22af7ece7161ef450bd7c9b0071830fd57330822 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 12:41:30 -0700 Subject: [PATCH 19/87] Fixes SearchResult imports in tests --- .../connectors/test_abstract_connector.py | 2 +- .../test_abstract_minimal_connector.py | 3 +- .../connectors/test_bookwyrm_connector.py | 2 +- .../connectors/test_openlibrary_connector.py | 2 +- .../tests/connectors/test_self_connector.py | 106 ------------------ 5 files changed, 5 insertions(+), 110 deletions(-) delete mode 100644 bookwyrm/tests/connectors/test_self_connector.py diff --git a/bookwyrm/tests/connectors/test_abstract_connector.py b/bookwyrm/tests/connectors/test_abstract_connector.py index 8ce4c96bf..129b3f0c6 100644 --- a/bookwyrm/tests/connectors/test_abstract_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_connector.py @@ -119,7 +119,7 @@ class AbstractConnector(TestCase): @responses.activate def test_get_or_create_author(self): """load an author""" - self.connector.author_mappings = ( + self.connector.author_mappings = ( # pylint: disable=attribute-defined-outside-init [ # pylint: disable=attribute-defined-outside-init Mapping("id"), Mapping("name"), diff --git a/bookwyrm/tests/connectors/test_abstract_minimal_connector.py b/bookwyrm/tests/connectors/test_abstract_minimal_connector.py index 30db40cd6..589072123 100644 --- a/bookwyrm/tests/connectors/test_abstract_minimal_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_minimal_connector.py @@ -3,8 +3,9 @@ from django.test import TestCase import responses from bookwyrm import models +from bookwyrm.book_search import SearchResult from bookwyrm.connectors import abstract_connector -from bookwyrm.connectors.abstract_connector import Mapping, SearchResult +from bookwyrm.connectors.abstract_connector import Mapping class AbstractConnector(TestCase): diff --git a/bookwyrm/tests/connectors/test_bookwyrm_connector.py b/bookwyrm/tests/connectors/test_bookwyrm_connector.py index 46ea54a91..585080e66 100644 --- a/bookwyrm/tests/connectors/test_bookwyrm_connector.py +++ b/bookwyrm/tests/connectors/test_bookwyrm_connector.py @@ -4,8 +4,8 @@ import pathlib from django.test import TestCase from bookwyrm import models +from bookwyrm.book_search import SearchResult from bookwyrm.connectors.bookwyrm_connector import Connector -from bookwyrm.connectors.abstract_connector import SearchResult class BookWyrmConnector(TestCase): diff --git a/bookwyrm/tests/connectors/test_openlibrary_connector.py b/bookwyrm/tests/connectors/test_openlibrary_connector.py index 699b26ed4..75a273d63 100644 --- a/bookwyrm/tests/connectors/test_openlibrary_connector.py +++ b/bookwyrm/tests/connectors/test_openlibrary_connector.py @@ -7,11 +7,11 @@ from django.test import TestCase import responses from bookwyrm import models +from bookwyrm.book_search import SearchResult from bookwyrm.connectors.openlibrary import Connector from bookwyrm.connectors.openlibrary import ignore_edition from bookwyrm.connectors.openlibrary import get_languages, get_description from bookwyrm.connectors.openlibrary import pick_default_edition, get_openlibrary_key -from bookwyrm.connectors.abstract_connector import SearchResult from bookwyrm.connectors.connector_manager import ConnectorException diff --git a/bookwyrm/tests/connectors/test_self_connector.py b/bookwyrm/tests/connectors/test_self_connector.py deleted file mode 100644 index a5eab8797..000000000 --- a/bookwyrm/tests/connectors/test_self_connector.py +++ /dev/null @@ -1,106 +0,0 @@ -""" testing book data connectors """ -import datetime -from django.test import TestCase -from django.utils import timezone - -from bookwyrm import models -from bookwyrm.connectors.self_connector import Connector -from bookwyrm.settings import DOMAIN - - -class SelfConnector(TestCase): - """just uses local data""" - - def setUp(self): - """creating the connector""" - models.Connector.objects.create( - identifier=DOMAIN, - name="Local", - connector_file="self_connector", - base_url="https://%s" % DOMAIN, - books_url="https://%s/book" % DOMAIN, - covers_url="https://%s/images/covers" % DOMAIN, - search_url="https://%s/search?q=" % DOMAIN, - priority=1, - ) - self.connector = Connector(DOMAIN) - - def test_format_search_result(self): - """create a SearchResult""" - author = models.Author.objects.create(name="Anonymous") - edition = models.Edition.objects.create( - title="Edition of Example Work", - published_date=datetime.datetime(1980, 5, 10, tzinfo=timezone.utc), - ) - edition.authors.add(author) - result = self.connector.search("Edition of Example")[0] - self.assertEqual(result.title, "Edition of Example Work") - self.assertEqual(result.key, edition.remote_id) - self.assertEqual(result.author, "Anonymous") - self.assertEqual(result.year, 1980) - self.assertEqual(result.connector, self.connector) - - def test_search_rank(self): - """prioritize certain results""" - author = models.Author.objects.create(name="Anonymous") - edition = models.Edition.objects.create( - title="Edition of Example Work", - published_date=datetime.datetime(1980, 5, 10, tzinfo=timezone.utc), - parent_work=models.Work.objects.create(title=""), - ) - # author text is rank B - edition.authors.add(author) - - # series is rank D - models.Edition.objects.create( - title="Another Edition", - series="Anonymous", - parent_work=models.Work.objects.create(title=""), - ) - # subtitle is rank B - models.Edition.objects.create( - title="More Editions", - subtitle="The Anonymous Edition", - parent_work=models.Work.objects.create(title=""), - ) - # title is rank A - models.Edition.objects.create(title="Anonymous") - # doesn't rank in this search - models.Edition.objects.create( - title="An Edition", parent_work=models.Work.objects.create(title="") - ) - - results = self.connector.search("Anonymous") - self.assertEqual(len(results), 4) - self.assertEqual(results[0].title, "Anonymous") - self.assertEqual(results[1].title, "More Editions") - self.assertEqual(results[2].title, "Edition of Example Work") - self.assertEqual(results[3].title, "Another Edition") - - def test_search_multiple_editions(self): - """it should get rid of duplicate editions for the same work""" - work = models.Work.objects.create(title="Work Title") - edition_1 = models.Edition.objects.create( - title="Edition 1 Title", parent_work=work - ) - edition_2 = models.Edition.objects.create( - title="Edition 2 Title", - parent_work=work, - isbn_13="123456789", # this is now the defualt edition - ) - edition_3 = models.Edition.objects.create(title="Fish", parent_work=work) - - # pick the best edition - results = self.connector.search("Edition 1 Title") - self.assertEqual(len(results), 1) - self.assertEqual(results[0].key, edition_1.remote_id) - - # pick the default edition when no match is best - results = self.connector.search("Edition Title") - self.assertEqual(len(results), 1) - self.assertEqual(results[0].key, edition_2.remote_id) - - # only matches one edition, so no deduplication takes place - results = self.connector.search("Fish") - self.assertEqual(len(results), 1) - self.assertEqual(results[0].key, edition_3.remote_id) From 8c4cafed79a65354a0bfe4952074f17e87d9cead Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 12:52:10 -0700 Subject: [PATCH 20/87] Fixes formatting isbn endpoint results --- bookwyrm/book_search.py | 6 +++--- bookwyrm/tests/connectors/test_abstract_connector.py | 10 ++++------ bookwyrm/tests/views/test_isbn.py | 2 +- bookwyrm/views/isbn.py | 4 +++- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/bookwyrm/book_search.py b/bookwyrm/book_search.py index c4d03caf6..91a4e67a5 100644 --- a/bookwyrm/book_search.py +++ b/bookwyrm/book_search.py @@ -114,7 +114,7 @@ def search_title_author(query, min_confidence, *filters, return_first=False): editions_of_work = results.values("parent_work__id").values_list("parent_work__id") # filter out multiple editions of the same work - results = [] + list_results = [] for work_id in set(editions_of_work): editions = results.filter(parent_work=work_id) default = editions.order_by("-edition_rank").first() @@ -126,8 +126,8 @@ def search_title_author(query, min_confidence, *filters, return_first=False): result = editions.first() if return_first: return result - results.append(result) - return results + list_results.append(result) + return list_results @dataclass diff --git a/bookwyrm/tests/connectors/test_abstract_connector.py b/bookwyrm/tests/connectors/test_abstract_connector.py index 129b3f0c6..a453f6133 100644 --- a/bookwyrm/tests/connectors/test_abstract_connector.py +++ b/bookwyrm/tests/connectors/test_abstract_connector.py @@ -119,12 +119,10 @@ class AbstractConnector(TestCase): @responses.activate def test_get_or_create_author(self): """load an author""" - self.connector.author_mappings = ( # pylint: disable=attribute-defined-outside-init - [ # pylint: disable=attribute-defined-outside-init - Mapping("id"), - Mapping("name"), - ] - ) + self.connector.author_mappings = [ # pylint: disable=attribute-defined-outside-init # pylint: disable=attribute-defined-outside-init + Mapping("id"), + Mapping("name"), + ] responses.add( responses.GET, diff --git a/bookwyrm/tests/views/test_isbn.py b/bookwyrm/tests/views/test_isbn.py index a6a451748..05a109568 100644 --- a/bookwyrm/tests/views/test_isbn.py +++ b/bookwyrm/tests/views/test_isbn.py @@ -35,7 +35,7 @@ class IsbnViews(TestCase): parent_work=self.work, ) models.Connector.objects.create( - identifier="self", connector_file="self_connector", local=True + identifier="self", connector_file="self_connector" ) models.SiteSettings.objects.create() diff --git a/bookwyrm/views/isbn.py b/bookwyrm/views/isbn.py index 173a3adb9..e5343488d 100644 --- a/bookwyrm/views/isbn.py +++ b/bookwyrm/views/isbn.py @@ -17,7 +17,9 @@ class Isbn(View): book_results = book_search.isbn_search(isbn) if is_api_request(request): - return JsonResponse([r.json() for r in book_results], safe=False) + return JsonResponse( + [book_search.format_search_result(r) for r in book_results], safe=False + ) paginated = Paginator(book_results, PAGE_LENGTH).get_page( request.GET.get("page") From d9284ede9b3f367a9c343bc9e5f915a1f79b28e8 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 15:27:06 -0700 Subject: [PATCH 21/87] updates search tests --- bookwyrm/tests/views/test_search.py | 53 ++++++++++------------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/bookwyrm/tests/views/test_search.py b/bookwyrm/tests/views/test_search.py index 7eb75dab8..cd0273bf8 100644 --- a/bookwyrm/tests/views/test_search.py +++ b/bookwyrm/tests/views/test_search.py @@ -1,5 +1,6 @@ """ test for app action functionality """ import json +import pathlib from unittest.mock import patch from django.contrib.auth.models import AnonymousUser @@ -7,9 +8,9 @@ from django.http import JsonResponse from django.template.response import TemplateResponse from django.test import TestCase from django.test.client import RequestFactory +import responses from bookwyrm import models, views -from bookwyrm.connectors import abstract_connector from bookwyrm.settings import DOMAIN @@ -36,15 +37,11 @@ class Views(TestCase): remote_id="https://example.com/book/1", parent_work=self.work, ) - models.Connector.objects.create( - identifier="self", connector_file="self_connector" - ) models.SiteSettings.objects.create() def test_search_json_response(self): """searches local data only and returns book data in json format""" view = views.Search.as_view() - # we need a connector for this, sorry request = self.factory.get("", {"q": "Test Book"}) with patch("bookwyrm.views.search.is_api_request") as is_api: is_api.return_value = True @@ -67,28 +64,11 @@ class Views(TestCase): self.assertIsInstance(response, TemplateResponse) response.render() + @responses.activate def test_search_books(self): """searches remote connectors""" view = views.Search.as_view() - class TestConnector(abstract_connector.AbstractMinimalConnector): - """nothing added here""" - - def format_search_result(self, search_result): - pass - - def get_or_create_book(self, remote_id): - pass - - def parse_search_data(self, data): - pass - - def format_isbn_search_result(self, search_result): - return search_result - - def parse_isbn_search_data(self, data): - return data - models.Connector.objects.create( identifier="example.com", connector_file="openlibrary", @@ -97,26 +77,29 @@ class Views(TestCase): covers_url="https://example.com/covers", search_url="https://example.com/search?q=", ) - connector = TestConnector("example.com") - - search_result = abstract_connector.SearchResult( - key="http://www.example.com/book/1", - title="Gideon the Ninth", - author="Tamsyn Muir", - year="2019", - connector=connector, + datafile = pathlib.Path(__file__).parent.joinpath("../data/ol_search.json") + search_data = json.loads(datafile.read_bytes()) + responses.add( + responses.GET, + "https://example.com/search?q=Test%20Book", + json=search_data ) request = self.factory.get("", {"q": "Test Book", "remote": True}) request.user = self.local_user with patch("bookwyrm.views.search.is_api_request") as is_api: is_api.return_value = False - with patch("bookwyrm.connectors.connector_manager.search") as manager: - manager.return_value = [search_result] - response = view(request) + response = view(request) self.assertIsInstance(response, TemplateResponse) response.render() - self.assertEqual(response.context_data["results"][0].title, "Gideon the Ninth") + connector_results = response.context_data["results"] + self.assertEqual( + connector_results[0]["results"][0].title, "Test Book" + ) + self.assertEqual( + connector_results[1]["results"][0].title, + "This Is How You Lose the Time War" + ) def test_search_users(self): """searches remote connectors""" From 146538545209250a2117448746cf2b2dc95ec5ef Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Thu, 16 Sep 2021 15:29:06 -0700 Subject: [PATCH 22/87] Python formatting --- bookwyrm/tests/views/test_search.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/bookwyrm/tests/views/test_search.py b/bookwyrm/tests/views/test_search.py index cd0273bf8..da35f5571 100644 --- a/bookwyrm/tests/views/test_search.py +++ b/bookwyrm/tests/views/test_search.py @@ -80,9 +80,7 @@ class Views(TestCase): datafile = pathlib.Path(__file__).parent.joinpath("../data/ol_search.json") search_data = json.loads(datafile.read_bytes()) responses.add( - responses.GET, - "https://example.com/search?q=Test%20Book", - json=search_data + responses.GET, "https://example.com/search?q=Test%20Book", json=search_data ) request = self.factory.get("", {"q": "Test Book", "remote": True}) @@ -93,12 +91,10 @@ class Views(TestCase): self.assertIsInstance(response, TemplateResponse) response.render() connector_results = response.context_data["results"] - self.assertEqual( - connector_results[0]["results"][0].title, "Test Book" - ) + self.assertEqual(connector_results[0]["results"][0].title, "Test Book") self.assertEqual( connector_results[1]["results"][0].title, - "This Is How You Lose the Time War" + "This Is How You Lose the Time War", ) def test_search_users(self): From 967e26ce489a0570aaf881f12f6b192ce8afd907 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Fri, 17 Sep 2021 11:29:10 -0700 Subject: [PATCH 23/87] Updates connector manager tests --- .../connectors/test_connector_manager.py | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/bookwyrm/tests/connectors/test_connector_manager.py b/bookwyrm/tests/connectors/test_connector_manager.py index f87b9c438..186f918bf 100644 --- a/bookwyrm/tests/connectors/test_connector_manager.py +++ b/bookwyrm/tests/connectors/test_connector_manager.py @@ -5,7 +5,6 @@ import responses from bookwyrm import models from bookwyrm.connectors import connector_manager from bookwyrm.connectors.bookwyrm_connector import Connector as BookWyrmConnector -from bookwyrm.connectors.self_connector import Connector as SelfConnector class ConnectorManager(TestCase): @@ -22,16 +21,6 @@ class ConnectorManager(TestCase): title="Another Edition", parent_work=self.work, isbn_10="1111111111" ) - self.connector = models.Connector.objects.create( - identifier="test_connector", - priority=1, - connector_file="self_connector", - base_url="http://test.com/", - books_url="http://test.com/", - covers_url="http://test.com/", - isbn_search_url="http://test.com/isbn/", - ) - self.remote_connector = models.Connector.objects.create( identifier="test_connector_remote", priority=1, @@ -57,9 +46,8 @@ class ConnectorManager(TestCase): def test_get_connectors(self): """load all connectors""" connectors = list(connector_manager.get_connectors()) - self.assertEqual(len(connectors), 2) - self.assertIsInstance(connectors[0], SelfConnector) - self.assertIsInstance(connectors[1], BookWyrmConnector) + self.assertEqual(len(connectors), 1) + self.assertIsInstance(connectors[0], BookWyrmConnector) @responses.activate def test_search(self): @@ -71,7 +59,6 @@ class ConnectorManager(TestCase): ) results = connector_manager.search("Example") self.assertEqual(len(results), 1) - self.assertIsInstance(results[0]["connector"], SelfConnector) self.assertEqual(len(results[0]["results"]), 1) self.assertEqual(results[0]["results"][0].title, "Example Edition") @@ -90,7 +77,6 @@ class ConnectorManager(TestCase): ) results = connector_manager.search("0000000000") self.assertEqual(len(results), 1) - self.assertIsInstance(results[0]["connector"], SelfConnector) self.assertEqual(len(results[0]["results"]), 1) self.assertEqual(results[0]["results"][0].title, "Example Edition") @@ -117,6 +103,5 @@ class ConnectorManager(TestCase): def test_load_connector(self): """load a connector object from the database entry""" - connector = connector_manager.load_connector(self.connector) - self.assertIsInstance(connector, SelfConnector) - self.assertEqual(connector.identifier, "test_connector") + connector = connector_manager.load_connector(self.remote_connector) + self.assertEqual(connector.identifier, "test_connector_remote") From 4747bb215661e731d195ba2121d5cfcb98294d62 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 11:36:35 -0700 Subject: [PATCH 24/87] Hide cover preview column if cover is unset --- bookwyrm/templates/book/edit_book.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bookwyrm/templates/book/edit_book.html b/bookwyrm/templates/book/edit_book.html index 18cf66710..7b428449c 100644 --- a/bookwyrm/templates/book/edit_book.html +++ b/bookwyrm/templates/book/edit_book.html @@ -226,9 +226,11 @@

    {% trans "Cover" %}

    + {% if book.cover %}
    {% include 'snippets/book_cover.html' with book=book cover_class='is-h-xl-mobile is-w-auto-tablet' size_mobile='xlarge' size='large' %}
    + {% endif %}
    From 54a8815f4948861bc4a76dda1d9f0a686f9c1152 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 11:49:57 -0700 Subject: [PATCH 25/87] Updates migrations --- .../migrations/0080_merge_20210804_2114.py | 13 -------- .../migrations/0089_merge_20210907_0514.py | 13 -------- .../0090_alter_edition_physical_format.py | 30 ------------------- ...t_detail.py => 0101_auto_20210929_1847.py} | 8 ++--- 4 files changed, 4 insertions(+), 60 deletions(-) delete mode 100644 bookwyrm/migrations/0080_merge_20210804_2114.py delete mode 100644 bookwyrm/migrations/0089_merge_20210907_0514.py delete mode 100644 bookwyrm/migrations/0090_alter_edition_physical_format.py rename bookwyrm/migrations/{0077_rename_physical_format_edition_physical_format_detail.py => 0101_auto_20210929_1847.py} (93%) diff --git a/bookwyrm/migrations/0080_merge_20210804_2114.py b/bookwyrm/migrations/0080_merge_20210804_2114.py deleted file mode 100644 index d8365eaf4..000000000 --- a/bookwyrm/migrations/0080_merge_20210804_2114.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.4 on 2021-08-04 21:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("bookwyrm", "0077_rename_physical_format_edition_physical_format_detail"), - ("bookwyrm", "0079_merge_20210804_1746"), - ] - - operations = [] diff --git a/bookwyrm/migrations/0089_merge_20210907_0514.py b/bookwyrm/migrations/0089_merge_20210907_0514.py deleted file mode 100644 index 86d29599a..000000000 --- a/bookwyrm/migrations/0089_merge_20210907_0514.py +++ /dev/null @@ -1,13 +0,0 @@ -# Generated by Django 3.2.4 on 2021-09-07 05:14 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("bookwyrm", "0080_merge_20210804_2114"), - ("bookwyrm", "0088_auto_20210905_2233"), - ] - - operations = [] diff --git a/bookwyrm/migrations/0090_alter_edition_physical_format.py b/bookwyrm/migrations/0090_alter_edition_physical_format.py deleted file mode 100644 index b37a75a66..000000000 --- a/bookwyrm/migrations/0090_alter_edition_physical_format.py +++ /dev/null @@ -1,30 +0,0 @@ -# Generated by Django 3.2.4 on 2021-09-07 19:46 - -import bookwyrm.models.fields -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ("bookwyrm", "0089_merge_20210907_0514"), - ] - - operations = [ - migrations.AlterField( - model_name="edition", - name="physical_format", - field=bookwyrm.models.fields.CharField( - blank=True, - choices=[ - ("AudiobookFormat", "Audiobook"), - ("EBook", "eBook"), - ("GraphicNovel", "Graphic novel"), - ("Hardcover", "Hardcover"), - ("Paperback", "Paperback"), - ], - max_length=255, - null=True, - ), - ), - ] diff --git a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py b/bookwyrm/migrations/0101_auto_20210929_1847.py similarity index 93% rename from bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py rename to bookwyrm/migrations/0101_auto_20210929_1847.py index fcff93523..346dbf886 100644 --- a/bookwyrm/migrations/0077_rename_physical_format_edition_physical_format_detail.py +++ b/bookwyrm/migrations/0101_auto_20210929_1847.py @@ -75,7 +75,7 @@ def reverse(app_registry, schema_editor): class Migration(migrations.Migration): dependencies = [ - ("bookwyrm", "0076_preview_images"), + ('bookwyrm', '0100_shelf_description'), ] operations = [ @@ -90,9 +90,9 @@ class Migration(migrations.Migration): field=bookwyrm.models.fields.CharField( blank=True, choices=[ - ("AudiobookFormat", "Audiobookformat"), - ("EBook", "Ebook"), - ("GraphicNovel", "Graphicnovel"), + ("AudiobookFormat", "Audiobook"), + ("EBook", "eBook"), + ("GraphicNovel", "Graphic novel"), ("Hardcover", "Hardcover"), ("Paperback", "Paperback"), ], From 47706b5353be2b8927bda8fab7add0de8611f502 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 11:59:09 -0700 Subject: [PATCH 26/87] Use detail field on book paeg and meta --- bookwyrm/templates/book/publisher_info.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bookwyrm/templates/book/publisher_info.html b/bookwyrm/templates/book/publisher_info.html index b7975a623..42cb40986 100644 --- a/bookwyrm/templates/book/publisher_info.html +++ b/bookwyrm/templates/book/publisher_info.html @@ -4,13 +4,15 @@ {% load humanize %}

    - {% with format=book.physical_format pages=book.pages %} + {% firstof book.physical_format_detail book.physical_format as format %} + {% firstof book.physical_format book.physical_format_detail as format_property %} + {% with pages=book.pages %} {% if format %} {% comment %} @todo The bookFormat property is limited to a list of values whereas the book edition is free text. @see https://schema.org/bookFormat {% endcomment %} - + {% endif %} {% if pages %} From 123b23728f428dafe8677a03d3bc63959037c90c Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 12:21:19 -0700 Subject: [PATCH 27/87] Infer format in openlibrary import --- bookwyrm/connectors/abstract_connector.py | 14 +++++ bookwyrm/connectors/format_mappings.py | 43 +++++++++++++++ bookwyrm/connectors/openlibrary.py | 5 +- .../migrations/0101_auto_20210929_1847.py | 54 ++----------------- 4 files changed, 63 insertions(+), 53 deletions(-) create mode 100644 bookwyrm/connectors/format_mappings.py diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 455241cca..8d2e9f15f 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -9,6 +9,7 @@ from requests.exceptions import RequestException from bookwyrm import activitypub, models, settings from .connector_manager import load_more_data, ConnectorException +from .format_mappings import format_mappings logger = logging.getLogger(__name__) @@ -312,3 +313,16 @@ class Mapping: return self.formatter(value) except: # pylint: disable=bare-except return None + +def infer_physical_format(format_text): + """ try to figure out what the standardized format is from the free value """ + format_text = format_text.lower() + if format_text in format_mappings: + # try a direct match + return format_mappings[format_text] + else: + # failing that, try substring + matches = [v for k, v in format_mappings.items() if k in format_text] + if not matches: + return None + return matches[0] diff --git a/bookwyrm/connectors/format_mappings.py b/bookwyrm/connectors/format_mappings.py new file mode 100644 index 000000000..61f61efaa --- /dev/null +++ b/bookwyrm/connectors/format_mappings.py @@ -0,0 +1,43 @@ +""" comparing a free text format to the standardized one """ +format_mappings = { + "paperback": "Paperback", + "soft": "Paperback", + "pamphlet": "Paperback", + "peperback": "Paperback", + "tapa blanda": "Paperback", + "turtleback": "Paperback", + "pocket": "Paperback", + "spiral": "Paperback", + "ring": "Paperback", + "平装": "Paperback", + "简装": "Paperback", + "hardcover": "Hardcover", + "hardcocer": "Hardcover", + "hardover": "Hardcover", + "hardback": "Hardcover", + "library": "Hardcover", + "tapa dura": "Hardcover", + "leather": "Hardcover", + "clothbound": "Hardcover", + "精装": "Hardcover", + "ebook": "EBook", + "e-book": "EBook", + "digital": "EBook", + "computer file": "EBook", + "epub": "EBook", + "online": "EBook", + "pdf": "EBook", + "elektronische": "EBook", + "electronic": "EBook", + "audiobook": "AudiobookFormat", + "audio": "AudiobookFormat", + "cd": "AudiobookFormat", + "dvd": "AudiobookFormat", + "mp3": "AudiobookFormat", + "cassette": "AudiobookFormat", + "kindle": "AudiobookFormat", + "talking": "AudiobookFormat", + "sound": "AudiobookFormat", + "comic": "GraphicNovel", + "graphic": "GraphicNovel", +} diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index fca5d0f71..7f724d74d 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -3,7 +3,7 @@ import re from bookwyrm import models from .abstract_connector import AbstractConnector, SearchResult, Mapping -from .abstract_connector import get_data +from .abstract_connector import get_data, infer_physical_format from .connector_manager import ConnectorException from .openlibrary_languages import languages @@ -43,7 +43,8 @@ class Connector(AbstractConnector): ), Mapping("publishedDate", remote_field="publish_date"), Mapping("pages", remote_field="number_of_pages"), - Mapping("physicalFormat", remote_field="physical_format"), + Mapping("physicalFormat", remote_field="physical_format", formatter=infer_physical_format), + Mapping("physicalFormatDetail", remote_field="physical_format"), Mapping("publishers"), ] diff --git a/bookwyrm/migrations/0101_auto_20210929_1847.py b/bookwyrm/migrations/0101_auto_20210929_1847.py index 346dbf886..2acaa127e 100644 --- a/bookwyrm/migrations/0101_auto_20210929_1847.py +++ b/bookwyrm/migrations/0101_auto_20210929_1847.py @@ -2,6 +2,7 @@ from django.db import migrations import bookwyrm +from bookwyrm.connectors.abstract_connector import infer_physical_format def infer_format(app_registry, schema_editor): @@ -13,59 +14,10 @@ def infer_format(app_registry, schema_editor): .objects.using(db_alias) .filter(physical_format_detail__isnull=False) ) - mappings = { - "paperback": "Paperback", - "soft": "Paperback", - "pamphlet": "Paperback", - "peperback": "Paperback", - "tapa blanda": "Paperback", - "turtleback": "Paperback", - "pocket": "Paperback", - "spiral": "Paperback", - "ring": "Paperback", - "平装": "Paperback", - "简装": "Paperback", - "hardcover": "Hardcover", - "hardcocer": "Hardcover", - "hardover": "Hardcover", - "hardback": "Hardcover", - "library": "Hardcover", - "tapa dura": "Hardcover", - "leather": "Hardcover", - "clothbound": "Hardcover", - "精装": "Hardcover", - "ebook": "EBook", - "e-book": "EBook", - "digital": "EBook", - "computer file": "EBook", - "epub": "EBook", - "online": "EBook", - "pdf": "EBook", - "elektronische": "EBook", - "electronic": "EBook", - "audiobook": "AudiobookFormat", - "audio": "AudiobookFormat", - "cd": "AudiobookFormat", - "dvd": "AudiobookFormat", - "mp3": "AudiobookFormat", - "cassette": "AudiobookFormat", - "kindle": "AudiobookFormat", - "talking": "AudiobookFormat", - "sound": "AudiobookFormat", - "comic": "GraphicNovel", - "graphic": "GraphicNovel", - } for edition in editions: free_format = edition.physical_format_detail.lower() - if free_format in mappings: - edition.physical_format = mappings[free_format] - edition.save() - else: - matches = [v for k, v in mappings.items() if k in free_format] - if not matches: - continue - edition.physical_format = matches[0] - edition.save() + edition.physical_format = infer_physical_format(free_format) + edition.save() def reverse(app_registry, schema_editor): From 0aef011258bb2affe3764938c5287d4fde6f83a6 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 12:29:17 -0700 Subject: [PATCH 28/87] Don't use the format detail if it maps directly --- bookwyrm/connectors/abstract_connector.py | 8 ++++++++ bookwyrm/connectors/openlibrary.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 8d2e9f15f..175253490 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -326,3 +326,11 @@ def infer_physical_format(format_text): if not matches: return None return matches[0] + +def unique_physical_format(format_text): + """ only store the format if it isn't diretly in the format mappings""" + format_text = format_text.lower() + if format_text in format_mappings: + # try a direct match, so saving this would be redundant + return None + return format_text diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index 7f724d74d..5177f665f 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -3,7 +3,7 @@ import re from bookwyrm import models from .abstract_connector import AbstractConnector, SearchResult, Mapping -from .abstract_connector import get_data, infer_physical_format +from .abstract_connector import get_data, infer_physical_format, unique_physical_format from .connector_manager import ConnectorException from .openlibrary_languages import languages @@ -44,7 +44,7 @@ class Connector(AbstractConnector): Mapping("publishedDate", remote_field="publish_date"), Mapping("pages", remote_field="number_of_pages"), Mapping("physicalFormat", remote_field="physical_format", formatter=infer_physical_format), - Mapping("physicalFormatDetail", remote_field="physical_format"), + Mapping("physicalFormatDetail", remote_field="physical_format", formatter=unique_physical_format), Mapping("publishers"), ] From 32391dd64d129bac618d15a0ebdd3da8eae85d9b Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 12:38:31 -0700 Subject: [PATCH 29/87] Python formatting --- bookwyrm/connectors/abstract_connector.py | 6 ++++-- bookwyrm/connectors/inventaire.py | 2 +- bookwyrm/connectors/openlibrary.py | 12 ++++++++++-- bookwyrm/migrations/0101_auto_20210929_1847.py | 2 +- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 175253490..060b7182d 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -314,8 +314,9 @@ class Mapping: except: # pylint: disable=bare-except return None + def infer_physical_format(format_text): - """ try to figure out what the standardized format is from the free value """ + """try to figure out what the standardized format is from the free value""" format_text = format_text.lower() if format_text in format_mappings: # try a direct match @@ -327,8 +328,9 @@ def infer_physical_format(format_text): return None return matches[0] + def unique_physical_format(format_text): - """ only store the format if it isn't diretly in the format mappings""" + """only store the format if it isn't diretly in the format mappings""" format_text = format_text.lower() if format_text in format_mappings: # try a direct match, so saving this would be redundant diff --git a/bookwyrm/connectors/inventaire.py b/bookwyrm/connectors/inventaire.py index 704554880..1bfd2b500 100644 --- a/bookwyrm/connectors/inventaire.py +++ b/bookwyrm/connectors/inventaire.py @@ -8,7 +8,7 @@ from .connector_manager import ConnectorException class Connector(AbstractConnector): - """instantiate a connector for OL""" + """instantiate a connector for inventaire""" def __init__(self, identifier): super().__init__(identifier) diff --git a/bookwyrm/connectors/openlibrary.py b/bookwyrm/connectors/openlibrary.py index 5177f665f..ef8a7b3db 100644 --- a/bookwyrm/connectors/openlibrary.py +++ b/bookwyrm/connectors/openlibrary.py @@ -43,8 +43,16 @@ class Connector(AbstractConnector): ), Mapping("publishedDate", remote_field="publish_date"), Mapping("pages", remote_field="number_of_pages"), - Mapping("physicalFormat", remote_field="physical_format", formatter=infer_physical_format), - Mapping("physicalFormatDetail", remote_field="physical_format", formatter=unique_physical_format), + Mapping( + "physicalFormat", + remote_field="physical_format", + formatter=infer_physical_format, + ), + Mapping( + "physicalFormatDetail", + remote_field="physical_format", + formatter=unique_physical_format, + ), Mapping("publishers"), ] diff --git a/bookwyrm/migrations/0101_auto_20210929_1847.py b/bookwyrm/migrations/0101_auto_20210929_1847.py index 2acaa127e..3fca28eac 100644 --- a/bookwyrm/migrations/0101_auto_20210929_1847.py +++ b/bookwyrm/migrations/0101_auto_20210929_1847.py @@ -27,7 +27,7 @@ def reverse(app_registry, schema_editor): class Migration(migrations.Migration): dependencies = [ - ('bookwyrm', '0100_shelf_description'), + ("bookwyrm", "0100_shelf_description"), ] operations = [ From d36ef2bcf1c11595d261b33df26189b47bd88615 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 12:42:28 -0700 Subject: [PATCH 30/87] Pylint change --- bookwyrm/connectors/abstract_connector.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/bookwyrm/connectors/abstract_connector.py b/bookwyrm/connectors/abstract_connector.py index 060b7182d..2d10331b4 100644 --- a/bookwyrm/connectors/abstract_connector.py +++ b/bookwyrm/connectors/abstract_connector.py @@ -321,12 +321,11 @@ def infer_physical_format(format_text): if format_text in format_mappings: # try a direct match return format_mappings[format_text] - else: - # failing that, try substring - matches = [v for k, v in format_mappings.items() if k in format_text] - if not matches: - return None - return matches[0] + # failing that, try substring + matches = [v for k, v in format_mappings.items() if k in format_text] + if not matches: + return None + return matches[0] def unique_physical_format(format_text): From f0e31f730a69094860b1aae75886e68d6e3cc621 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 13:18:27 -0700 Subject: [PATCH 31/87] Moves form into snippet and adds boxes around sections --- bookwyrm/templates/book/edit_book.html | 331 +++----------------- bookwyrm/templates/book/edit_book_form.html | 249 +++++++++++++++ 2 files changed, 301 insertions(+), 279 deletions(-) create mode 100644 bookwyrm/templates/book/edit_book_form.html diff --git a/bookwyrm/templates/book/edit_book.html b/bookwyrm/templates/book/edit_book.html index eb4b1c531..e706dea8c 100644 --- a/bookwyrm/templates/book/edit_book.html +++ b/bookwyrm/templates/book/edit_book.html @@ -36,12 +36,6 @@ {% endif %} -{% if form.non_field_errors %} -

    -

    {{ form.non_field_errors }}

    -
    -{% endif %} -
    - - {% csrf_token %} {% if confirm_mode %} -
    -

    {% trans "Confirm Book Info" %}

    -
    - {% if author_matches %} - -
    - {% for author in author_matches %} -
    - - {% blocktrans with name=author.name %}Is "{{ name }}" an existing author?{% endblocktrans %} - - {% with forloop.counter0 as counter %} - {% for match in author.matches %} - -

    - {% blocktrans with book_title=match.book_set.first.title %}Author of {{ book_title }}{% endblocktrans %} -

    - {% endfor %} - - {% endwith %} -
    - {% endfor %} -
    - {% else %} -

    {% blocktrans with name=add_author %}Creating a new author: {{ name }}{% endblocktrans %}

    - {% endif %} - - {% if not book %} -
    -
    - - {% trans "Is this an edition of an existing work?" %} - - {% for match in book_matches %} - - {% endfor %} - -
    -
    - {% endif %} -
    - - - - {% trans "Back" %} - -
    - -
    - {% endif %} - - -
    -
    -
    -

    {% trans "Metadata" %}

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

    {{ error | escape }}

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

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.description }} - {% for error in form.description.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - - {% for error in form.series.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.series_number }} - {% for error in form.series_number.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.languages }} - {% trans "Separate multiple values with commas." %} - {% for error in form.languages.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.publishers }} - {% trans "Separate multiple values with commas." %} - {% for error in form.publishers.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - - {% for error in form.first_published_date.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - - {% for error in form.published_date.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    -
    - -
    -

    {% trans "Authors" %}

    - {% if book.authors.exists %} -
    - {% for author in book.authors.all %} -
    +
    +

    {% trans "Confirm Book Info" %}

    +
    + {% if author_matches %} + +
    + {% for author in author_matches %} +
    + + {% blocktrans with name=author.name %}Is "{{ name }}" an existing author?{% endblocktrans %} + + {% with forloop.counter0 as counter %} + {% for match in author.matches %}

    - {% blocktrans with name=author.name %}Author page for {{ name }}{% endblocktrans %} + {% blocktrans with book_title=match.book_set.first.title %}Author of {{ book_title }}{% endblocktrans %}

    -
    - {% endfor %} -
    - {% endif %} -
    - - - {% trans "Separate multiple values with commas." %} -
    -
    -
    - -
    -

    {% trans "Cover" %}

    -
    - {% if book.cover %} -
    - {% include 'snippets/book_cover.html' with book=book cover_class='is-h-xl-mobile is-w-auto-tablet' size_mobile='xlarge' size='large' %} -
    - {% endif %} - -
    -
    -
    - - {{ form.cover }} -
    -
    - - -
    - {% for error in form.cover.errors %} -

    {{ error | escape }}

    {% endfor %} -
    + + {% endwith %} + + {% endfor %}
    + {% else %} +

    {% blocktrans with name=add_author %}Creating a new author: {{ name }}{% endblocktrans %}

    + {% endif %} + + {% if not book %} +
    +
    + + {% trans "Is this an edition of an existing work?" %} + + {% for match in book_matches %} + + {% endfor %} + +
    +
    + {% endif %}
    -
    -

    {% trans "Physical Properties" %}

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

    {{ error | escape }}

    - {% endfor %} -
    -
    -
    -
    - - {{ form.physical_format_detail }} - {% for error in form.physical_format_detail.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    -
    -
    - -
    - - {{ form.pages }} - {% for error in form.pages.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    -
    - -
    -

    {% trans "Book Identifiers" %}

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

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.isbn_10 }} - {% for error in form.isbn_10.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.openlibrary_key }} - {% for error in form.openlibrary_key.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.inventaire_id }} - {% for error in form.inventaire_id.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.oclc_number }} - {% for error in form.oclc_number.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    - -
    - - {{ form.asin }} - {% for error in form.ASIN.errors %} -

    {{ error | escape }}

    - {% endfor %} -
    -
    + + + {% trans "Back" %} +
    -
    + +
    + {% endif %} + + {% include "book/edit_book_form.html" %} {% if not confirm_mode %}
    diff --git a/bookwyrm/templates/book/edit_book_form.html b/bookwyrm/templates/book/edit_book_form.html new file mode 100644 index 000000000..982bb56d2 --- /dev/null +++ b/bookwyrm/templates/book/edit_book_form.html @@ -0,0 +1,249 @@ +{% load i18n %} + +{% if form.non_field_errors %} +
    +

    {{ form.non_field_errors }}

    +
    +{% endif %} + +{% csrf_token %} + + +
    +
    +
    +

    {% trans "Metadata" %}

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

    {{ error | escape }}

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

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + {{ form.description }} + {% for error in form.description.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    + +
    +
    +
    + + + {% for error in form.series.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    +
    + + {{ form.series_number }} + {% for error in form.series_number.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    + +
    + + {{ form.languages }} + {% trans "Separate multiple values with commas." %} + {% for error in form.languages.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    + +
    +

    {% trans "Publication" %}

    +
    +
    + + {{ form.publishers }} + {% trans "Separate multiple values with commas." %} + {% for error in form.publishers.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + + {% for error in form.first_published_date.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + + {% for error in form.published_date.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    + +
    +

    {% trans "Authors" %}

    +
    + {% if book.authors.exists %} +
    + {% for author in book.authors.all %} +
    + +

    + {% blocktrans with name=author.name %}Author page for {{ name }}{% endblocktrans %} +

    +
    + {% endfor %} +
    + {% endif %} +
    + + + {% trans "Separate multiple values with commas." %} +
    +
    +
    +
    + +
    +
    +

    {% trans "Cover" %}

    +
    +
    + {% if book.cover %} +
    + {% include 'snippets/book_cover.html' with book=book cover_class='is-h-xl-mobile is-w-auto-tablet' size_mobile='xlarge' size='large' %} +
    + {% endif %} + +
    +
    + + {{ form.cover }} +
    +
    + + +
    + {% for error in form.cover.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    +
    + +
    +

    {% trans "Physical Properties" %}

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

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    +
    + + {{ form.physical_format_detail }} + {% for error in form.physical_format_detail.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    + +
    + + {{ form.pages }} + {% for error in form.pages.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    + +
    +

    {% trans "Book Identifiers" %}

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

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + {{ form.isbn_10 }} + {% for error in form.isbn_10.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + {{ form.openlibrary_key }} + {% for error in form.openlibrary_key.errors %} +

    {{ error | escape }}

    + {% endfor %} +
    + +
    + + {{ form.inventaire_id }} + {% for error in form.inventaire_id.errors %} +

    {{ error | escape }}

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

    {{ error | escape }}

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

    {{ error | escape }}

    + {% endfor %} +
    +
    +
    +
    +
    From 1e5a8dc3db38dfaecfa9faca1bfc793428bf80c2 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 13:21:11 -0700 Subject: [PATCH 32/87] Create subdirectories for book view templates --- bookwyrm/templates/book/{ => edit}/edit_book.html | 0 bookwyrm/templates/book/{ => edit}/edit_book_form.html | 0 bookwyrm/templates/book/{ => editions}/edition_filters.html | 0 bookwyrm/templates/book/{ => editions}/editions.html | 0 bookwyrm/templates/book/{ => editions}/format_filter.html | 0 bookwyrm/templates/book/{ => editions}/language_filter.html | 0 bookwyrm/templates/book/{ => editions}/search_filter.html | 0 7 files changed, 0 insertions(+), 0 deletions(-) rename bookwyrm/templates/book/{ => edit}/edit_book.html (100%) rename bookwyrm/templates/book/{ => edit}/edit_book_form.html (100%) rename bookwyrm/templates/book/{ => editions}/edition_filters.html (100%) rename bookwyrm/templates/book/{ => editions}/editions.html (100%) rename bookwyrm/templates/book/{ => editions}/format_filter.html (100%) rename bookwyrm/templates/book/{ => editions}/language_filter.html (100%) rename bookwyrm/templates/book/{ => editions}/search_filter.html (100%) diff --git a/bookwyrm/templates/book/edit_book.html b/bookwyrm/templates/book/edit/edit_book.html similarity index 100% rename from bookwyrm/templates/book/edit_book.html rename to bookwyrm/templates/book/edit/edit_book.html diff --git a/bookwyrm/templates/book/edit_book_form.html b/bookwyrm/templates/book/edit/edit_book_form.html similarity index 100% rename from bookwyrm/templates/book/edit_book_form.html rename to bookwyrm/templates/book/edit/edit_book_form.html diff --git a/bookwyrm/templates/book/edition_filters.html b/bookwyrm/templates/book/editions/edition_filters.html similarity index 100% rename from bookwyrm/templates/book/edition_filters.html rename to bookwyrm/templates/book/editions/edition_filters.html diff --git a/bookwyrm/templates/book/editions.html b/bookwyrm/templates/book/editions/editions.html similarity index 100% rename from bookwyrm/templates/book/editions.html rename to bookwyrm/templates/book/editions/editions.html diff --git a/bookwyrm/templates/book/format_filter.html b/bookwyrm/templates/book/editions/format_filter.html similarity index 100% rename from bookwyrm/templates/book/format_filter.html rename to bookwyrm/templates/book/editions/format_filter.html diff --git a/bookwyrm/templates/book/language_filter.html b/bookwyrm/templates/book/editions/language_filter.html similarity index 100% rename from bookwyrm/templates/book/language_filter.html rename to bookwyrm/templates/book/editions/language_filter.html diff --git a/bookwyrm/templates/book/search_filter.html b/bookwyrm/templates/book/editions/search_filter.html similarity index 100% rename from bookwyrm/templates/book/search_filter.html rename to bookwyrm/templates/book/editions/search_filter.html From 899e6b55a80f15c77b2a6770d5cb45150851cc25 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 13:23:52 -0700 Subject: [PATCH 33/87] Updates references to book templates --- bookwyrm/templates/book/edit/edit_book.html | 2 +- bookwyrm/templates/book/editions/edition_filters.html | 6 +++--- bookwyrm/templates/book/editions/editions.html | 2 +- bookwyrm/views/books.py | 8 ++++---- bookwyrm/views/editions.py | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bookwyrm/templates/book/edit/edit_book.html b/bookwyrm/templates/book/edit/edit_book.html index e706dea8c..e3e6f6f4d 100644 --- a/bookwyrm/templates/book/edit/edit_book.html +++ b/bookwyrm/templates/book/edit/edit_book.html @@ -109,7 +109,7 @@
    {% endif %} - {% include "book/edit_book_form.html" %} + {% include "book/edit/edit_book_form.html" %} {% if not confirm_mode %}
    diff --git a/bookwyrm/templates/book/editions/edition_filters.html b/bookwyrm/templates/book/editions/edition_filters.html index c41ab0c01..c6702a5cf 100644 --- a/bookwyrm/templates/book/editions/edition_filters.html +++ b/bookwyrm/templates/book/editions/edition_filters.html @@ -1,7 +1,7 @@ {% extends 'snippets/filters_panel/filters_panel.html' %} {% block filter_fields %} -{% include 'book/search_filter.html' %} -{% include 'book/language_filter.html' %} -{% include 'book/format_filter.html' %} +{% include 'book/editions/search_filter.html' %} +{% include 'book/editions/language_filter.html' %} +{% include 'book/editions/format_filter.html' %} {% endblock %} diff --git a/bookwyrm/templates/book/editions/editions.html b/bookwyrm/templates/book/editions/editions.html index 7a4338f12..a3ff08022 100644 --- a/bookwyrm/templates/book/editions/editions.html +++ b/bookwyrm/templates/book/editions/editions.html @@ -8,7 +8,7 @@

    {% blocktrans with work_path=work.local_path work_title=work|book_title %}Editions of "{{ work_title }}"{% endblocktrans %}

    -{% include 'book/edition_filters.html' %} +{% include 'book/editions/edition_filters.html' %}
    {% for book in editions %} diff --git a/bookwyrm/views/books.py b/bookwyrm/views/books.py index 71199e543..a31f39b17 100644 --- a/bookwyrm/views/books.py +++ b/bookwyrm/views/books.py @@ -138,7 +138,7 @@ class EditBook(View): if not book.description: book.description = book.parent_work.description data = {"book": book, "form": forms.EditionForm(instance=book)} - return TemplateResponse(request, "book/edit_book.html", data) + return TemplateResponse(request, "book/edit/edit_book.html", data) def post(self, request, book_id=None): """edit a book cool""" @@ -148,7 +148,7 @@ class EditBook(View): data = {"book": book, "form": form} if not form.is_valid(): - return TemplateResponse(request, "book/edit_book.html", data) + return TemplateResponse(request, "book/edit/edit_book.html", data) add_author = request.POST.get("add_author") # we're adding an author through a free text field @@ -207,7 +207,7 @@ class EditBook(View): except (MultiValueDictKeyError, ValueError): pass data["form"].data = formcopy - return TemplateResponse(request, "book/edit_book.html", data) + return TemplateResponse(request, "book/edit/edit_book.html", data) remove_authors = request.POST.getlist("remove_authors") for author_id in remove_authors: @@ -238,7 +238,7 @@ class ConfirmEditBook(View): data = {"book": book, "form": form} if not form.is_valid(): - return TemplateResponse(request, "book/edit_book.html", data) + return TemplateResponse(request, "book/edit/edit_book.html", data) with transaction.atomic(): # save book diff --git a/bookwyrm/views/editions.py b/bookwyrm/views/editions.py index d044f17cd..6cd54f768 100644 --- a/bookwyrm/views/editions.py +++ b/bookwyrm/views/editions.py @@ -66,7 +66,7 @@ class Editions(View): e.physical_format.lower() for e in editions if e.physical_format ), } - return TemplateResponse(request, "book/editions.html", data) + return TemplateResponse(request, "book/editions/editions.html", data) @login_required From 33b3b518e805a2c8e87949d330a9a3b072b02259 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 13:39:12 -0700 Subject: [PATCH 34/87] Move views into subdirectory --- bookwyrm/views/__init__.py | 8 +- bookwyrm/views/books.py | 350 ------------------------- bookwyrm/views/books/__init__.py | 0 bookwyrm/views/books/books.py | 182 +++++++++++++ bookwyrm/views/{ => books}/editions.py | 2 +- 5 files changed, 188 insertions(+), 354 deletions(-) delete mode 100644 bookwyrm/views/books.py create mode 100644 bookwyrm/views/books/__init__.py create mode 100644 bookwyrm/views/books/books.py rename bookwyrm/views/{ => books}/editions.py (98%) diff --git a/bookwyrm/views/__init__.py b/bookwyrm/views/__init__.py index be59d59c2..4209d4a90 100644 --- a/bookwyrm/views/__init__.py +++ b/bookwyrm/views/__init__.py @@ -27,13 +27,15 @@ from .preferences.edit_user import EditUser from .preferences.delete_user import DeleteUser from .preferences.block import Block, unblock +# books +from .books.books import Book, upload_cover, add_description, resolve_book +from .books.edit_book import EditBook, ConfirmEditBook +from .books.editions import Editions, switch_edition + # misc views from .author import Author, EditAuthor -from .books import Book, EditBook, ConfirmEditBook -from .books import upload_cover, add_description, resolve_book from .directory import Directory from .discover import Discover -from .editions import Editions, switch_edition from .feed import DirectMessage, Feed, Replies, Status from .follow import follow, unfollow from .follow import accept_follow_request, delete_follow_request diff --git a/bookwyrm/views/books.py b/bookwyrm/views/books.py deleted file mode 100644 index a31f39b17..000000000 --- a/bookwyrm/views/books.py +++ /dev/null @@ -1,350 +0,0 @@ -""" the good stuff! the books! """ -from uuid import uuid4 - -from dateutil.parser import parse as dateparse -from django.contrib.auth.decorators import login_required, permission_required -from django.contrib.postgres.search import SearchRank, SearchVector -from django.core.files.base import ContentFile -from django.core.paginator import Paginator -from django.db import transaction -from django.db.models import Avg, Q -from django.http import HttpResponseBadRequest, Http404 -from django.shortcuts import get_object_or_404, redirect -from django.template.response import TemplateResponse -from django.utils.datastructures import MultiValueDictKeyError -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.activitypub import ActivitypubResponse -from bookwyrm.connectors import connector_manager -from bookwyrm.connectors.abstract_connector import get_image -from bookwyrm.settings import PAGE_LENGTH -from .helpers import is_api_request, get_edition, privacy_filter - - -# pylint: disable=no-self-use -class Book(View): - """a book! this is the stuff""" - - def get(self, request, book_id, user_statuses=False): - """info about a book""" - if is_api_request(request): - book = get_object_or_404( - models.Book.objects.select_subclasses(), id=book_id - ) - return ActivitypubResponse(book.to_activity()) - - user_statuses = user_statuses if request.user.is_authenticated else False - - # it's safe to use this OR because edition and work and subclasses of the same - # table, so they never have clashing IDs - book = ( - models.Edition.viewer_aware_objects(request.user) - .filter(Q(id=book_id) | Q(parent_work__id=book_id)) - .order_by("-edition_rank") - .select_related("parent_work") - .prefetch_related("authors") - .first() - ) - - if not book or not book.parent_work: - raise Http404() - - # all reviews for all editions of the book - reviews = privacy_filter( - request.user, models.Review.objects.filter(book__parent_work__editions=book) - ) - - # the reviews to show - if user_statuses: - if user_statuses == "review": - queryset = book.review_set.select_subclasses() - elif user_statuses == "comment": - queryset = book.comment_set - else: - queryset = book.quotation_set - queryset = queryset.filter(user=request.user, deleted=False) - else: - queryset = reviews.exclude(Q(content__isnull=True) | Q(content="")) - queryset = queryset.select_related("user").order_by("-published_date") - paginated = Paginator(queryset, PAGE_LENGTH) - - lists = privacy_filter( - request.user, - models.List.objects.filter( - listitem__approved=True, - listitem__book__in=book.parent_work.editions.all(), - ), - ) - data = { - "book": book, - "statuses": paginated.get_page(request.GET.get("page")), - "review_count": reviews.count(), - "ratings": reviews.filter( - Q(content__isnull=True) | Q(content="") - ).select_related("user") - if not user_statuses - else None, - "rating": reviews.aggregate(Avg("rating"))["rating__avg"], - "lists": lists, - } - - if request.user.is_authenticated: - readthroughs = models.ReadThrough.objects.filter( - user=request.user, - book=book, - ).order_by("start_date") - - for readthrough in readthroughs: - readthrough.progress_updates = ( - readthrough.progressupdate_set.all().order_by("-updated_date") - ) - data["readthroughs"] = readthroughs - - data["user_shelfbooks"] = models.ShelfBook.objects.filter( - user=request.user, book=book - ).select_related("shelf") - - data["other_edition_shelves"] = models.ShelfBook.objects.filter( - ~Q(book=book), - user=request.user, - book__parent_work=book.parent_work, - ).select_related("shelf", "book") - - filters = {"user": request.user, "deleted": False} - data["user_statuses"] = { - "review_count": book.review_set.filter(**filters).count(), - "comment_count": book.comment_set.filter(**filters).count(), - "quotation_count": book.quotation_set.filter(**filters).count(), - } - - return TemplateResponse(request, "book/book.html", data) - - -@method_decorator(login_required, name="dispatch") -@method_decorator( - permission_required("bookwyrm.edit_book", raise_exception=True), name="dispatch" -) -class EditBook(View): - """edit a book""" - - def get(self, request, book_id=None): - """info about a book""" - book = None - if book_id: - book = get_edition(book_id) - if not book.description: - book.description = book.parent_work.description - data = {"book": book, "form": forms.EditionForm(instance=book)} - return TemplateResponse(request, "book/edit/edit_book.html", data) - - def post(self, request, book_id=None): - """edit a book cool""" - # returns None if no match is found - book = models.Edition.objects.filter(id=book_id).first() - form = forms.EditionForm(request.POST, request.FILES, instance=book) - - data = {"book": book, "form": form} - if not form.is_valid(): - return TemplateResponse(request, "book/edit/edit_book.html", data) - - add_author = request.POST.get("add_author") - # we're adding an author through a free text field - if add_author: - data["add_author"] = add_author - data["author_matches"] = [] - for author in add_author.split(","): - if not author: - continue - # check for existing authors - vector = SearchVector("name", weight="A") + SearchVector( - "aliases", weight="B" - ) - - data["author_matches"].append( - { - "name": author.strip(), - "matches": ( - models.Author.objects.annotate(search=vector) - .annotate(rank=SearchRank(vector, author)) - .filter(rank__gt=0.4) - .order_by("-rank")[:5] - ), - } - ) - - # we're creating a new book - if not book: - # check if this is an edition of an existing work - author_text = book.author_text if book else add_author - data["book_matches"] = connector_manager.local_search( - f'{form.cleaned_data.get("title")} {author_text}', - min_confidence=0.5, - raw=True, - )[:5] - - # either of the above cases requires additional confirmation - if add_author or not book: - # creting a book or adding an author to a book needs another step - data["confirm_mode"] = True - # this isn't preserved because it isn't part of the form obj - data["remove_authors"] = request.POST.getlist("remove_authors") - data["cover_url"] = request.POST.get("cover-url") - - # make sure the dates are passed in as datetime, they're currently a string - # QueryDicts are immutable, we need to copy - formcopy = data["form"].data.copy() - try: - formcopy["first_published_date"] = dateparse( - formcopy["first_published_date"] - ) - except (MultiValueDictKeyError, ValueError): - pass - try: - formcopy["published_date"] = dateparse(formcopy["published_date"]) - except (MultiValueDictKeyError, ValueError): - pass - data["form"].data = formcopy - return TemplateResponse(request, "book/edit/edit_book.html", data) - - remove_authors = request.POST.getlist("remove_authors") - for author_id in remove_authors: - book.authors.remove(author_id) - - book = form.save(commit=False) - url = request.POST.get("cover-url") - if url: - image = set_cover_from_url(url) - if image: - book.cover.save(*image, save=False) - book.save() - return redirect(f"/book/{book.id}") - - -@method_decorator(login_required, name="dispatch") -@method_decorator( - permission_required("bookwyrm.edit_book", raise_exception=True), name="dispatch" -) -class ConfirmEditBook(View): - """confirm edits to a book""" - - def post(self, request, book_id=None): - """edit a book cool""" - # returns None if no match is found - book = models.Edition.objects.filter(id=book_id).first() - form = forms.EditionForm(request.POST, request.FILES, instance=book) - - data = {"book": book, "form": form} - if not form.is_valid(): - return TemplateResponse(request, "book/edit/edit_book.html", data) - - with transaction.atomic(): - # save book - book = form.save() - - # get or create author as needed - for i in range(int(request.POST.get("author-match-count", 0))): - match = request.POST.get(f"author_match-{i}") - if not match: - return HttpResponseBadRequest() - try: - # if it's an int, it's an ID - match = int(match) - author = get_object_or_404( - models.Author, id=request.POST[f"author_match-{i}"] - ) - except ValueError: - # otherwise it's a name - author = models.Author.objects.create(name=match) - book.authors.add(author) - - # create work, if needed - if not book_id: - work_match = request.POST.get("parent_work") - if work_match and work_match != "0": - work = get_object_or_404(models.Work, id=work_match) - else: - work = models.Work.objects.create(title=form.cleaned_data["title"]) - work.authors.set(book.authors.all()) - book.parent_work = work - - for author_id in request.POST.getlist("remove_authors"): - book.authors.remove(author_id) - - # import cover, if requested - url = request.POST.get("cover-url") - if url: - image = set_cover_from_url(url) - if image: - book.cover.save(*image, save=False) - - # we don't tell the world when creating a book - book.save(broadcast=False) - - return redirect(f"/book/{book.id}") - - -@login_required -@require_POST -def upload_cover(request, book_id): - """upload a new cover""" - book = get_object_or_404(models.Edition, id=book_id) - book.last_edited_by = request.user - - url = request.POST.get("cover-url") - if url: - image = set_cover_from_url(url) - if image: - book.cover.save(*image) - - return redirect(f"{book.local_path}?cover_error=True") - - form = forms.CoverForm(request.POST, request.FILES, instance=book) - if not form.is_valid() or not form.files.get("cover"): - return redirect(book.local_path) - - book.cover = form.files["cover"] - book.save() - - return redirect(book.local_path) - - -def set_cover_from_url(url): - """load it from a url""" - try: - image_file = get_image(url) - except: # pylint: disable=bare-except - return None - if not image_file: - return None - image_name = str(uuid4()) + "." + url.split(".")[-1] - image_content = ContentFile(image_file.content) - return [image_name, image_content] - - -@login_required -@require_POST -@permission_required("bookwyrm.edit_book", raise_exception=True) -def add_description(request, book_id): - """upload a new cover""" - book = get_object_or_404(models.Edition, id=book_id) - - description = request.POST.get("description") - - book.description = description - book.last_edited_by = request.user - book.save(update_fields=["description", "last_edited_by"]) - - return redirect("book", book.id) - - -@require_POST -def resolve_book(request): - """figure out the local path to a book from a remote_id""" - remote_id = request.POST.get("remote_id") - connector = connector_manager.get_or_create_connector(remote_id) - book = connector.get_or_create_book(remote_id) - - return redirect("book", book.id) diff --git a/bookwyrm/views/books/__init__.py b/bookwyrm/views/books/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/bookwyrm/views/books/books.py b/bookwyrm/views/books/books.py new file mode 100644 index 000000000..9de647a24 --- /dev/null +++ b/bookwyrm/views/books/books.py @@ -0,0 +1,182 @@ +""" the good stuff! the books! """ +from uuid import uuid4 + +from django.contrib.auth.decorators import login_required, permission_required +from django.core.files.base import ContentFile +from django.core.paginator import Paginator +from django.db.models import Avg, Q +from django.http import Http404 +from django.shortcuts import get_object_or_404, redirect +from django.template.response import TemplateResponse +from django.views import View +from django.views.decorators.http import require_POST + +from bookwyrm import forms, models +from bookwyrm.activitypub import ActivitypubResponse +from bookwyrm.connectors import connector_manager +from bookwyrm.connectors.abstract_connector import get_image +from bookwyrm.settings import PAGE_LENGTH +from bookwyrm.views.helpers import is_api_request, privacy_filter + + +# pylint: disable=no-self-use +class Book(View): + """a book! this is the stuff""" + + def get(self, request, book_id, user_statuses=False): + """info about a book""" + if is_api_request(request): + book = get_object_or_404( + models.Book.objects.select_subclasses(), id=book_id + ) + return ActivitypubResponse(book.to_activity()) + + user_statuses = user_statuses if request.user.is_authenticated else False + + # it's safe to use this OR because edition and work and subclasses of the same + # table, so they never have clashing IDs + book = ( + models.Edition.viewer_aware_objects(request.user) + .filter(Q(id=book_id) | Q(parent_work__id=book_id)) + .order_by("-edition_rank") + .select_related("parent_work") + .prefetch_related("authors") + .first() + ) + + if not book or not book.parent_work: + raise Http404() + + # all reviews for all editions of the book + reviews = privacy_filter( + request.user, models.Review.objects.filter(book__parent_work__editions=book) + ) + + # the reviews to show + if user_statuses: + if user_statuses == "review": + queryset = book.review_set.select_subclasses() + elif user_statuses == "comment": + queryset = book.comment_set + else: + queryset = book.quotation_set + queryset = queryset.filter(user=request.user, deleted=False) + else: + queryset = reviews.exclude(Q(content__isnull=True) | Q(content="")) + queryset = queryset.select_related("user").order_by("-published_date") + paginated = Paginator(queryset, PAGE_LENGTH) + + lists = privacy_filter( + request.user, + models.List.objects.filter( + listitem__approved=True, + listitem__book__in=book.parent_work.editions.all(), + ), + ) + data = { + "book": book, + "statuses": paginated.get_page(request.GET.get("page")), + "review_count": reviews.count(), + "ratings": reviews.filter( + Q(content__isnull=True) | Q(content="") + ).select_related("user") + if not user_statuses + else None, + "rating": reviews.aggregate(Avg("rating"))["rating__avg"], + "lists": lists, + } + + if request.user.is_authenticated: + readthroughs = models.ReadThrough.objects.filter( + user=request.user, + book=book, + ).order_by("start_date") + + for readthrough in readthroughs: + readthrough.progress_updates = ( + readthrough.progressupdate_set.all().order_by("-updated_date") + ) + data["readthroughs"] = readthroughs + + data["user_shelfbooks"] = models.ShelfBook.objects.filter( + user=request.user, book=book + ).select_related("shelf") + + data["other_edition_shelves"] = models.ShelfBook.objects.filter( + ~Q(book=book), + user=request.user, + book__parent_work=book.parent_work, + ).select_related("shelf", "book") + + filters = {"user": request.user, "deleted": False} + data["user_statuses"] = { + "review_count": book.review_set.filter(**filters).count(), + "comment_count": book.comment_set.filter(**filters).count(), + "quotation_count": book.quotation_set.filter(**filters).count(), + } + + return TemplateResponse(request, "book/book.html", data) + + +@login_required +@require_POST +def upload_cover(request, book_id): + """upload a new cover""" + book = get_object_or_404(models.Edition, id=book_id) + book.last_edited_by = request.user + + url = request.POST.get("cover-url") + if url: + image = set_cover_from_url(url) + if image: + book.cover.save(*image) + + return redirect(f"{book.local_path}?cover_error=True") + + form = forms.CoverForm(request.POST, request.FILES, instance=book) + if not form.is_valid() or not form.files.get("cover"): + return redirect(book.local_path) + + book.cover = form.files["cover"] + book.save() + + return redirect(book.local_path) + + +def set_cover_from_url(url): + """load it from a url""" + try: + image_file = get_image(url) + except: # pylint: disable=bare-except + return None + if not image_file: + return None + image_name = str(uuid4()) + "." + url.split(".")[-1] + image_content = ContentFile(image_file.content) + return [image_name, image_content] + + +@login_required +@require_POST +@permission_required("bookwyrm.edit_book", raise_exception=True) +def add_description(request, book_id): + """upload a new cover""" + book = get_object_or_404(models.Edition, id=book_id) + + description = request.POST.get("description") + + book.description = description + book.last_edited_by = request.user + book.save(update_fields=["description", "last_edited_by"]) + + return redirect("book", book.id) + + +@require_POST +def resolve_book(request): + """figure out the local path to a book from a remote_id""" + remote_id = request.POST.get("remote_id") + connector = connector_manager.get_or_create_connector(remote_id) + book = connector.get_or_create_book(remote_id) + + return redirect("book", book.id) diff --git a/bookwyrm/views/editions.py b/bookwyrm/views/books/editions.py similarity index 98% rename from bookwyrm/views/editions.py rename to bookwyrm/views/books/editions.py index 6cd54f768..81d073224 100644 --- a/bookwyrm/views/editions.py +++ b/bookwyrm/views/books/editions.py @@ -14,7 +14,7 @@ from django.views.decorators.http import require_POST from bookwyrm import models from bookwyrm.activitypub import ActivitypubResponse from bookwyrm.settings import PAGE_LENGTH -from .helpers import is_api_request +from bookwyrm.views.helpers import is_api_request # pylint: disable=no-self-use From 47b08e7591aabd8c21f9d297c60726f7f9b3f009 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 14:21:57 -0700 Subject: [PATCH 35/87] Moves tests into dirs and updates render checks --- bookwyrm/tests/views/books/__init__.py | 1 + bookwyrm/tests/views/{ => books}/test_book.py | 97 ++++++++++++++++--- .../tests/views/{ => books}/test_editions.py | 56 ++++++++++- 3 files changed, 133 insertions(+), 21 deletions(-) create mode 100644 bookwyrm/tests/views/books/__init__.py rename bookwyrm/tests/views/{ => books}/test_book.py (83%) rename bookwyrm/tests/views/{ => books}/test_editions.py (78%) diff --git a/bookwyrm/tests/views/books/__init__.py b/bookwyrm/tests/views/books/__init__.py new file mode 100644 index 000000000..b6e690fd5 --- /dev/null +++ b/bookwyrm/tests/views/books/__init__.py @@ -0,0 +1 @@ +from . import * diff --git a/bookwyrm/tests/views/test_book.py b/bookwyrm/tests/views/books/test_book.py similarity index 83% rename from bookwyrm/tests/views/test_book.py rename to bookwyrm/tests/views/books/test_book.py index cf86a5969..5ddf00f5c 100644 --- a/bookwyrm/tests/views/test_book.py +++ b/bookwyrm/tests/views/books/test_book.py @@ -2,6 +2,7 @@ from io import BytesIO import pathlib from unittest.mock import patch +from tidylib import tidy_document from PIL import Image import responses @@ -63,14 +64,23 @@ class BookViews(TestCase): ) request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False result = view(request, self.book.id) self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = True result = view(request, self.book.id) self.assertIsInstance(result, ActivitypubResponse) @@ -103,27 +113,54 @@ class BookViews(TestCase): request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False result = view(request, self.book.id, user_statuses="review") self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(result.context_data["statuses"].object_list[0], review) - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False result = view(request, self.book.id, user_statuses="comment") self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + ptions={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(result.context_data["statuses"].object_list[0], comment) - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False result = view(request, self.book.id, user_statuses="quotation") self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(result.context_data["statuses"].object_list[0], quote) @@ -132,7 +169,7 @@ class BookViews(TestCase): view = views.Book.as_view() request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False with self.assertRaises(Http404): view(request, 0) @@ -142,10 +179,19 @@ class BookViews(TestCase): view = views.Book.as_view() request = self.factory.get("") request.user = self.local_user - with patch("bookwyrm.views.books.is_api_request") as is_api: + with patch("bookwyrm.views.books.books.is_api_request") as is_api: is_api.return_value = False result = view(request, self.work.id) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(result.context_data["book"], self.book) @@ -157,7 +203,16 @@ class BookViews(TestCase): request.user.is_superuser = True result = view(request, self.book.id) self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) def test_edit_book(self): @@ -188,7 +243,16 @@ class BookViews(TestCase): request.user = self.local_user result = view(request, self.book.id) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) # the changes haven't been saved yet self.book.refresh_from_db() @@ -283,7 +347,8 @@ class BookViews(TestCase): self.assertEqual(book.authors.first().name, "Sappho") self.assertEqual(book.authors.first(), book.parent_work.authors.first()) - def _setup_cover_url(self): + def _setup_cover_url(self): # pylint: disable=no-self-use + """creates cover url mock""" cover_url = "http://example.com" image_file = pathlib.Path(__file__).parent.joinpath( "../../static/images/default_avi.jpg" @@ -303,7 +368,6 @@ class BookViews(TestCase): def test_create_book_upload_cover_url(self): """create an entirely new book and work with cover url""" self.assertFalse(self.book.cover) - view = views.ConfirmEditBook.as_view() self.local_user.groups.add(self.group) cover_url = self._setup_cover_url() @@ -331,6 +395,7 @@ class BookViews(TestCase): ) form = forms.CoverForm(instance=self.book) + # pylint: disable=consider-using-with form.data["cover"] = SimpleUploadedFile( image_file, open(image_file, "rb").read(), content_type="image/jpeg" ) diff --git a/bookwyrm/tests/views/test_editions.py b/bookwyrm/tests/views/books/test_editions.py similarity index 78% rename from bookwyrm/tests/views/test_editions.py rename to bookwyrm/tests/views/books/test_editions.py index a138f3451..bbe29f522 100644 --- a/bookwyrm/tests/views/test_editions.py +++ b/bookwyrm/tests/views/books/test_editions.py @@ -1,5 +1,6 @@ """ test for app action functionality """ from unittest.mock import patch +from tidylib import tidy_document from django.template.response import TemplateResponse from django.test import TestCase @@ -44,7 +45,16 @@ class BookViews(TestCase): is_api.return_value = False result = view(request, self.work.id) self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertTrue("paperback" in result.context_data["formats"]) @@ -61,7 +71,16 @@ class BookViews(TestCase): is_api.return_value = False result = view(request, self.work.id) self.assertIsInstance(result, TemplateResponse) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(len(result.context_data["editions"].object_list), 2) self.assertEqual(len(result.context_data["formats"]), 2) @@ -72,7 +91,16 @@ class BookViews(TestCase): with patch("bookwyrm.views.editions.is_api_request") as is_api: is_api.return_value = False result = view(request, self.work.id) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(len(result.context_data["editions"].object_list), 1) @@ -80,7 +108,16 @@ class BookViews(TestCase): with patch("bookwyrm.views.editions.is_api_request") as is_api: is_api.return_value = False result = view(request, self.work.id) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(len(result.context_data["editions"].object_list), 1) @@ -88,7 +125,16 @@ class BookViews(TestCase): with patch("bookwyrm.views.editions.is_api_request") as is_api: is_api.return_value = False result = view(request, self.work.id) - result.render() + html = result.render() + _, errors = tidy_document( + html.content, + options={ + "drop-empty-elements": False, + "warn-proprietary-attributes": False, + }, + ) + if errors: + raise Exception(errors) self.assertEqual(result.status_code, 200) self.assertEqual(len(result.context_data["editions"].object_list), 1) From a8ed957e200285259d0eeebe5372bdd17584b393 Mon Sep 17 00:00:00 2001 From: Mouse Reeve Date: Wed, 29 Sep 2021 15:01:56 -0700 Subject: [PATCH 36/87] Fixes uuid reference in toggle button snippet --- bookwyrm/templates/snippets/toggle/toggle_button.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bookwyrm/templates/snippets/toggle/toggle_button.html b/bookwyrm/templates/snippets/toggle/toggle_button.html index 49740db13..56dda6f7a 100644 --- a/bookwyrm/templates/snippets/toggle/toggle_button.html +++ b/bookwyrm/templates/snippets/toggle/toggle_button.html @@ -1,5 +1,5 @@ {% if fallback_url %} - + {% endif %}
    {% endblock %} + +{% block form %} +{% include "snippets/reading_modals/form.html" with optional=True type="finish_modal" %} +{% endblock %} diff --git a/bookwyrm/templates/snippets/reading_modals/layout.html b/bookwyrm/templates/snippets/reading_modals/layout.html index 9b922aa60..89cc9a2e4 100644 --- a/bookwyrm/templates/snippets/reading_modals/layout.html +++ b/bookwyrm/templates/snippets/reading_modals/layout.html @@ -23,8 +23,7 @@
    - {% comparison_bool controls_text "progress_update" True as optional %} - {% include "snippets/reading_modals/form.html" with optional=optional %} + {% block form %}{% endblock %}
    {% endwith %} diff --git a/bookwyrm/templates/snippets/reading_modals/progress_update_modal.html b/bookwyrm/templates/snippets/reading_modals/progress_update_modal.html index 713dad8d4..df02d0b44 100644 --- a/bookwyrm/templates/snippets/reading_modals/progress_update_modal.html +++ b/bookwyrm/templates/snippets/reading_modals/progress_update_modal.html @@ -15,3 +15,7 @@ {% include "snippets/progress_field.html" with progress_required=True %} {% endblock %} + +{% block form %} +{% include "snippets/reading_modals/form.html" with optional=False type="update_modal" %} +{% endblock %} diff --git a/bookwyrm/templates/snippets/reading_modals/start_reading_modal.html b/bookwyrm/templates/snippets/reading_modals/start_reading_modal.html index 827c0a86d..cd0b64f3b 100644 --- a/bookwyrm/templates/snippets/reading_modals/start_reading_modal.html +++ b/bookwyrm/templates/snippets/reading_modals/start_reading_modal.html @@ -22,3 +22,7 @@ Start "{{ book_title }}"
    {% endblock %} + +{% block form %} +{% include "snippets/reading_modals/form.html" with optional=True type="start_modal" %} +{% endblock %} diff --git a/bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html b/bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html index 5dec637be..d1f06d8f1 100644 --- a/bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html +++ b/bookwyrm/templates/snippets/reading_modals/want_to_read_modal.html @@ -13,3 +13,7 @@ Want to Read "{{ book_title }}" {% csrf_token %} {% endblock %} + +{% block form %} +{% include "snippets/reading_modals/form.html" with optional=True type="want_modal" %} +{% endblock %} diff --git a/bookwyrm/templates/snippets/toggle/toggle_button.html b/bookwyrm/templates/snippets/toggle/toggle_button.html index 56dda6f7a..0f8e01655 100644 --- a/bookwyrm/templates/snippets/toggle/toggle_button.html +++ b/bookwyrm/templates/snippets/toggle/toggle_button.html @@ -1,5 +1,5 @@ {% if fallback_url %} -
    + {% endif %}
    {# Only show progress for editing existing readthroughs #} {% if readthrough.id and not readthrough.finish_date %} -