Merge branch 'main' into add-feed-filters

This commit is contained in:
Mouse Reeve 2021-12-02 12:14:54 -08:00 committed by GitHub
commit ed28d5f945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
38 changed files with 886 additions and 316 deletions

View File

@ -27,7 +27,7 @@ class Author(BookDataModel):
# idk probably other keys would be useful here? # idk probably other keys would be useful here?
born = fields.DateTimeField(blank=True, null=True) born = fields.DateTimeField(blank=True, null=True)
died = fields.DateTimeField(blank=True, null=True) died = fields.DateTimeField(blank=True, null=True)
name = fields.CharField(max_length=255, deduplication_field=True) name = fields.CharField(max_length=255)
aliases = fields.ArrayField( aliases = fields.ArrayField(
models.CharField(max_length=255), blank=True, default=list models.CharField(max_length=255), blank=True, default=list
) )

View File

@ -296,7 +296,7 @@ class ManyToManyField(ActivitypubFieldMixin, models.ManyToManyField):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
def set_field_from_activity(self, instance, data, overwrite=True): def set_field_from_activity(self, instance, data, overwrite=True):
"""helper function for assinging a value to the field""" """helper function for assigning a value to the field"""
if not overwrite and getattr(instance, self.name).exists(): if not overwrite and getattr(instance, self.name).exists():
return False return False
@ -398,7 +398,11 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
if formatted is None or formatted is MISSING: if formatted is None or formatted is MISSING:
return False return False
if not overwrite and hasattr(instance, self.name): if (
not overwrite
and hasattr(instance, self.name)
and getattr(instance, self.name)
):
return False return False
getattr(instance, self.name).save(*formatted, save=save) getattr(instance, self.name).save(*formatted, save=save)

View File

@ -317,15 +317,21 @@ def save_and_cleanup(image, instance=None):
"""Save and close the file""" """Save and close the file"""
if not isinstance(instance, (models.Book, models.User, models.SiteSettings)): if not isinstance(instance, (models.Book, models.User, models.SiteSettings)):
return False return False
uuid = uuid4()
file_name = f"{instance.id}-{uuid}.jpg"
image_buffer = BytesIO() image_buffer = BytesIO()
try: try:
try: try:
old_path = instance.preview_image.name file_name = instance.preview_image.name
except ValueError: except ValueError:
old_path = None file_name = None
if not file_name or file_name == "":
uuid = uuid4()
file_name = f"{instance.id}-{uuid}.jpg"
# Clean up old file before saving
if file_name and default_storage.exists(file_name):
default_storage.delete(file_name)
# Save # Save
image.save(image_buffer, format="jpeg", quality=75) image.save(image_buffer, format="jpeg", quality=75)
@ -345,10 +351,6 @@ def save_and_cleanup(image, instance=None):
else: else:
instance.save(update_fields=["preview_image"]) instance.save(update_fields=["preview_image"])
# Clean up old file after saving
if old_path and default_storage.exists(old_path):
default_storage.delete(old_path)
finally: finally:
image_buffer.close() image_buffer.close()
return True return True

View File

@ -45,6 +45,13 @@ let BookWyrm = new class {
'change', 'change',
this.disableIfTooLarge.bind(this) this.disableIfTooLarge.bind(this)
)); ));
document.querySelectorAll('[data-duplicate]')
.forEach(node => node.addEventListener(
'click',
this.duplicateInput.bind(this)
))
} }
/** /**
@ -403,4 +410,24 @@ let BookWyrm = new class {
); );
} }
} }
duplicateInput (event ) {
const trigger = event.currentTarget;
const input_id = trigger.dataset['duplicate']
const orig = document.getElementById(input_id);
const parent = orig.parentNode;
const new_count = parent.querySelectorAll("input").length + 1
let input = orig.cloneNode();
input.id += ("-" + (new_count))
input.value = ""
let label = parent.querySelector("label").cloneNode();
label.setAttribute("for", input.id)
parent.appendChild(label)
parent.appendChild(input)
}
}(); }();

View File

@ -187,6 +187,7 @@ let StatusCache = new class {
.forEach(item => BookWyrm.addRemoveClass(item, "is-hidden", false)); .forEach(item => BookWyrm.addRemoveClass(item, "is-hidden", false));
// Remove existing disabled states // Remove existing disabled states
button.querySelectorAll("[data-shelf-dropdown-identifier] button") button.querySelectorAll("[data-shelf-dropdown-identifier] button")
.forEach(item => item.disabled = false); .forEach(item => item.disabled = false);

View File

@ -2,6 +2,7 @@
{% load i18n %} {% load i18n %}
{% load markdown %} {% load markdown %}
{% load humanize %} {% load humanize %}
{% load utilities %}
{% block title %}{{ author.name }}{% endblock %} {% block title %}{{ author.name }}{% endblock %}
@ -25,7 +26,7 @@
<div class="block columns content" itemscope itemtype="https://schema.org/Person"> <div class="block columns content" itemscope itemtype="https://schema.org/Person">
<meta itemprop="name" content="{{ author.name }}"> <meta itemprop="name" content="{{ author.name }}">
{% if author.aliases or author.born or author.died or author.wikipedia_link or author.openlibrary_key or author.inventaire_id %} {% if author.aliases or author.born or author.died or author.wikipedia_link or author.openlibrary_key or author.inventaire_id or author.isni %}
<div class="column is-two-fifths"> <div class="column is-two-fifths">
<div class="box py-2"> <div class="box py-2">
<dl> <dl>
@ -63,6 +64,14 @@
</p> </p>
{% endif %} {% endif %}
{% if author.isni %}
<p class="my-1">
<a itemprop="sameAs" href="https://isni.org/isni/{{ author.isni|remove_spaces }}" rel="noopener" target="_blank">
{% trans "View ISNI record" %}
</a>
</p>
{% endif %}
{% if author.openlibrary_key %} {% if author.openlibrary_key %}
<p class="my-1"> <p class="my-1">
<a itemprop="sameAs" href="https://openlibrary.org/authors/{{ author.openlibrary_key }}" target="_blank" rel="noopener"> <a itemprop="sameAs" href="https://openlibrary.org/authors/{{ author.openlibrary_key }}" target="_blank" rel="noopener">

View File

@ -153,12 +153,21 @@
{# user's relationship to the book #} {# user's relationship to the book #}
<div class="block"> <div class="block">
{% if user_shelfbooks.count > 0 %}
<h2 class="title is-5">
{% trans "You have shelved this edition in:" %}
</h2>
<ul>
{% for shelf in user_shelfbooks %} {% for shelf in user_shelfbooks %}
<p> <li class="box">
{% blocktrans with path=shelf.shelf.local_path shelf_name=shelf.shelf.name %}This edition is on your <a href="{{ path }}">{{ shelf_name }}</a> shelf.{% endblocktrans %} {% blocktrans with path=shelf.shelf.local_path shelf_name=shelf.shelf.name %}<a href="{{ path }}">{{ shelf_name }}</a>{% endblocktrans %}
{% include 'snippets/shelf_selector.html' with current=shelf.shelf %} <div class="mb-3">
</p> {% include 'snippets/shelf_selector.html' with shelf=shelf.shelf class="is-small" readthrough=readthrough %}
</div>
</li>
{% endfor %} {% endfor %}
</ul>
{% endif %}
{% for shelf in other_edition_shelves %} {% for shelf in other_edition_shelves %}
<p> <p>
{% blocktrans with book_path=shelf.book.local_path shelf_path=shelf.shelf.local_path shelf_name=shelf.shelf.name %}A <a href="{{ book_path }}">different edition</a> of this book is on your <a href="{{ shelf_path }}">{{ shelf_name }}</a> shelf.{% endblocktrans %} {% blocktrans with book_path=shelf.book.local_path shelf_path=shelf.shelf.local_path shelf_name=shelf.shelf.name %}A <a href="{{ book_path }}">different edition</a> of this book is on your <a href="{{ shelf_path }}">{{ shelf_name }}</a> shelf.{% endblocktrans %}

View File

@ -1,6 +1,7 @@
{% extends 'layout.html' %} {% extends 'layout.html' %}
{% load i18n %} {% load i18n %}
{% load humanize %} {% load humanize %}
{% load utilities %}
{% block title %}{% if book %}{% blocktrans with book_title=book.title %}Edit "{{ book_title }}"{% endblocktrans %}{% else %}{% trans "Add Book" %}{% endif %}{% endblock %} {% block title %}{% if book %}{% blocktrans with book_title=book.title %}Edit "{{ book_title }}"{% endblocktrans %}{% else %}{% trans "Add Book" %}{% endif %}{% endblock %}
@ -52,19 +53,29 @@
{% for author in author_matches %} {% for author in author_matches %}
<fieldset> <fieldset>
<legend class="title is-5 mb-1"> <legend class="title is-5 mb-1">
{% blocktrans with name=author.name %}Is "{{ name }}" an existing author?{% endblocktrans %} {% blocktrans with name=author.name %}Is "{{ name }}" one of these authors?{% endblocktrans %}
</legend> </legend>
{% with forloop.counter0 as counter %} {% with forloop.counter0 as counter %}
{% for match in author.matches %} {% for match in author.matches %}
<label class="label mb-2"> <label class="label">
<input type="radio" name="author_match-{{ counter }}" value="{{ match.id }}" required> <input type="radio" name="author_match-{{ counter }}" value="{{ match.id }}" required>
{{ match.name }} {{ match.name }}
</label> </label>
<p class="help"> <p class="help ml-5 mb-2">
<a href="{{ match.local_path }}" target="_blank">{% blocktrans with book_title=match.book_set.first.title %}Author of <em>{{ book_title }}</em>{% endblocktrans %}</a> {% with book_title=match.book_set.first.title alt_title=match.bio %}
{% if book_title %}
<a href="{{ match.local_path }}" target="_blank">{% trans "Author of " %}<em>{{ book_title }}</em></a>
{% else %}
<a href="{{ match.id }}" target="_blank">{% if alt_title %}{% trans "Author of " %}<em>{{ alt_title }}</em>{% else %} {% trans "Find more information at isni.org" %}{% endif %}</a>
{% endif %}
{% endwith %}
</p> </p>
<p class="help ml-5">
{{ author.existing_isnis|get_isni_bio:match }}
</p>
{{ author.existing_isnis|get_isni:match }}
{% endfor %} {% endfor %}
<label class="label"> <label class="label mt-2">
<input type="radio" name="author_match-{{ counter }}" value="{{ author.name }}" required> {% trans "This is a new author" %} <input type="radio" name="author_match-{{ counter }}" value="{{ author.name }}" required> {% trans "This is a new author" %}
</label> </label>
{% endwith %} {% endwith %}

View File

@ -119,10 +119,16 @@
</fieldset> </fieldset>
{% endif %} {% endif %}
<div class="field"> <div class="field">
<label class="label" for="id_add_author">{% trans "Add Authors:" %}</label> <label class="label">{% trans "Add Authors:" %}</label>
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'John Doe, Jane Smith' %}" value="{{ add_author }}" {% if confirm_mode %}readonly{% endif %}> {% for author in add_author %}
<span class="help">{% trans "Separate multiple values with commas." %}</span> <label class="label is-sr-only" for="id_add_author{% if not forloop.first %}-{{forloop.counter}}{% endif %}">{% trans "Add Author" %}</label>
<input class="input" type="text" name="add_author" id="id_add_author{% if not forloop.first %}-{{forloop.counter}}{% endif %}" placeholder="{% trans 'Jane Doe' %}" value="{{ author }}" {% if confirm_mode %}readonly{% endif %}>
{% empty %}
<label class="label is-sr-only" for="id_add_author">{% trans "Add Author" %}</label>
<input class="input" type="text" name="add_author" id="id_add_author" placeholder="{% trans 'Jane Doe' %}" value="{{ author }}" {% if confirm_mode %}readonly{% endif %}>
{% endfor %}
</div> </div>
<span class="help"><button class="button is-small" type="button" data-duplicate="id_add_author" id="another_author_field">{% trans "Add Another Author" %}</button></span>
</div> </div>
</section> </section>
</div> </div>

View File

@ -9,10 +9,11 @@ Finish "<em>{{ book_title }}</em>"
{% endblock %} {% endblock %}
{% block modal-form-open %} {% block modal-form-open %}
<form name="finish-reading" action="{% url 'reading-status' 'finish' book.id %}" method="post" class="submit-status"> <form name="finish-reading" action="{% url 'reading-status' 'finish' book.id %}" method="post" {% if not refresh %}class="submit-status"{% endif %}>
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="id" value="{{ readthrough.id }}"> <input type="hidden" name="id" value="{{ readthrough.id }}">
<input type="hidden" name="reading_status" value="read"> <input type="hidden" name="reading_status" value="read">
<input type="hidden" name="shelf" value="{{ move_from }}">
{% endblock %} {% endblock %}
{% block reading-dates %} {% block reading-dates %}

View File

@ -9,8 +9,9 @@ Start "<em>{{ book_title }}</em>"
{% endblock %} {% endblock %}
{% block modal-form-open %} {% block modal-form-open %}
<form name="start-reading" action="{% url 'reading-status' 'start' book.id %}" method="post" class="submit-status"> <form name="start-reading" action="{% url 'reading-status' 'start' book.id %}" method="post" {% if not refresh %}class="submit-status"{% endif %}>
<input type="hidden" name="reading_status" value="reading"> <input type="hidden" name="reading_status" value="reading">
<input type="hidden" name="shelf" value="{{ move_from }}">
{% csrf_token %} {% csrf_token %}
{% endblock %} {% endblock %}

View File

@ -9,8 +9,9 @@ Want to Read "<em>{{ book_title }}</em>"
{% endblock %} {% endblock %}
{% block modal-form-open %} {% block modal-form-open %}
<form name="shelve" action="{% url 'reading-status' 'want' book.id %}" method="post" class="submit-status"> <form name="shelve" action="{% url 'reading-status' 'want' book.id %}" method="post" {% if not refresh %}class="submit-status"{% endif %}>
<input type="hidden" name="reading_status" value="to-read"> <input type="hidden" name="reading_status" value="to-read">
<input type="hidden" name="shelf" value="{{ move_from }}">
{% csrf_token %} {% csrf_token %}
{% endblock %} {% endblock %}

View File

@ -1,29 +1,88 @@
{% extends 'components/dropdown.html' %} {% extends 'components/dropdown.html' %}
{% load i18n %} {% load i18n %}
{% load bookwyrm_tags %}
{% load utilities %}
{% block dropdown-trigger %} {% block dropdown-trigger %}
<span>{% trans "Move book" %}</span> <span>{% trans "Move book" %}</span>
<span class="icon icon-arrow-down" aria-hidden="true"></span> <span class="icon icon-arrow-down" aria-hidden="true"></span>
{% endblock %} {% endblock %}
{% block dropdown-list %} {% block dropdown-list %}
{% with book.id|uuid as uuid %}
{% active_shelf book as active_shelf %}
{% latest_read_through book request.user as readthrough %}
{% for shelf in user_shelves %} {% for shelf in user_shelves %}
{% if shelf.editable %}
<li role="menuitem" class="dropdown-item p-0"> <li role="menuitem" class="dropdown-item p-0">
<form name="shelve" action="/shelve/" method="post"> <form name="shelve" action="/shelve/" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="book" value="{{ book.id }}"> <input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="change-shelf-from" value="{{ current.identifier }}"> <input type="hidden" name="change-shelf-from" value="{{ current.identifier }}">
<input type="hidden" name="shelf" value="{{ shelf.identifier }}"> <input type="hidden" name="shelf" value="{{ shelf.identifier }}">
<button class="button is-fullwidth is-small shelf-option is-radiusless is-white" type="submit" {% if shelf.identifier == current.identifier %}disabled{% endif %}><span>{{ shelf.name }}</span></button> <button class="button is-fullwidth is-small shelf-option is-radiusless is-white" type="submit" {% if shelf in book.shelf_set.all %} disabled {% endif %}><span>{{ shelf.name }}</span></button>
</form> </form>
</li> </li>
{% else%}
{% comparison_bool shelf.identifier active_shelf.shelf.identifier as is_current %}
{% with button_class="is-fullwidth is-small shelf-option is-radiusless is-white" %}
<li role="menuitem" class="dropdown-item p-0">
{% if shelf.identifier == 'reading' %}
{% trans "Start reading" as button_text %}
{% url 'reading-status' 'start' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=button_class text=button_text controls_text="start_reading" controls_uid=uuid focus="modal_title_start_reading" disabled=is_current fallback_url=fallback_url %}
{% elif shelf.identifier == 'read' %}
{% trans "Read" as button_text %}
{% url 'reading-status' 'finish' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=button_class text=button_text controls_text="finish_reading" controls_uid=uuid focus="modal_title_finish_reading" disabled=is_current fallback_url=fallback_url %}
{% elif shelf.identifier == 'to-read' %}
{% trans "Want to read" as button_text %}
{% url 'reading-status' 'want' book.id as fallback_url %}
{% include 'snippets/toggle/toggle_button.html' with class=button_class text=button_text controls_text="want_to_read" controls_uid=uuid focus="modal_title_want_to_read" disabled=is_current fallback_url=fallback_url %}
{% endif %}
</li>
{% endwith %}
{% endif %}
{% endfor %} {% endfor %}
<li class="navbar-divider" role="separator"></li>
{% if shelf.identifier == 'all' %}
{% for shelved_in in book.shelves.all %}
<li class="navbar-divider m-0" role="separator" ></li>
<li role="menuitem" class="dropdown-item p-0"> <li role="menuitem" class="dropdown-item p-0">
<form name="shelve" action="/unshelve/" method="post"> <form name="shelve" action="/unshelve/" method="post">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="book" value="{{ book.id }}"> <input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="shelf" value="{{ current.id }}"> <input type="hidden" name="shelf" value="{{ shelved_in.id }}">
<button class="button is-fullwidth is-small is-radiusless is-danger is-light" type="submit">{% trans "Remove" %}</button> <button class="button is-fullwidth is-small is-radiusless is-danger is-light" type="submit">{% trans "Remove from" %} {{ shelved_in.name }}</button>
</form> </form>
</li> </li>
{% endfor %}
{% else %}
<li class="navbar-divider" role="separator" ></li>
<li role="menuitem" class="dropdown-item p-0">
<form name="shelve" action="/unshelve/" method="post">
{% csrf_token %}
<input type="hidden" name="book" value="{{ book.id }}">
<input type="hidden" name="shelf" value="{{ shelf.id }}">
<button class="button is-fullwidth is-small is-radiusless is-danger is-light" type="submit">{% trans "Remove from" %} {{ shelf.name }}</button>
</form>
</li>
{% endif %}
{% include 'snippets/reading_modals/want_to_read_modal.html' with book=active_shelf.book controls_text="want_to_read" controls_uid=uuid move_from=current.id refresh=True %}
{% include 'snippets/reading_modals/start_reading_modal.html' with book=active_shelf.book controls_text="start_reading" controls_uid=uuid move_from=current.id refresh=True %}
{% include 'snippets/reading_modals/finish_reading_modal.html' with book=active_shelf.book controls_text="finish_reading" controls_uid=uuid move_from=current.id readthrough=readthrough refresh=True %}
{% endwith %}
{% endblock %} {% endblock %}

View File

@ -32,7 +32,7 @@
{% elif shelf.editable %} {% elif shelf.editable %}
<form name="shelve" action="/shelve/" method="post"> <form name="shelve" action="/shelve/" method="post" autocomplete="off">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="book" value="{{ active_shelf.book.id }}"> <input type="hidden" name="book" value="{{ active_shelf.book.id }}">
<button class="button {{ class }}" name="shelf" type="submit" value="{{ shelf.identifier }}" {% if shelf in book.shelf_set.all %} disabled {% endif %}> <button class="button {{ class }}" name="shelf" type="submit" value="{{ shelf.identifier }}" {% if shelf in book.shelf_set.all %} disabled {% endif %}>

View File

@ -1,6 +1,6 @@
{% load utilities %} {% load utilities %}
{% if fallback_url %} {% if fallback_url %}
<form name="fallback_form_{{ 0|uuid }}" method="GET" action="{{ fallback_url }}"> <form name="fallback_form_{{ 0|uuid }}" method="GET" action="{{ fallback_url }}" autocomplete="off">
{% endif %} {% endif %}
<button <button
{% if not fallback_url %} {% if not fallback_url %}

View File

@ -77,7 +77,12 @@ def related_status(notification):
def active_shelf(context, book): def active_shelf(context, book):
"""check what shelf a user has a book on, if any""" """check what shelf a user has a book on, if any"""
if hasattr(book, "current_shelves"): if hasattr(book, "current_shelves"):
return book.current_shelves[0] if len(book.current_shelves) else {"book": book} read_shelves = [
s
for s in book.current_shelves
if s.shelf.identifier in models.Shelf.READ_STATUS_IDENTIFIERS
]
return read_shelves[0] if len(read_shelves) else {"book": book}
shelf = ( shelf = (
models.ShelfBook.objects.filter( models.ShelfBook.objects.filter(

View File

@ -1,8 +1,11 @@
""" template filters for really common utilities """ """ template filters for really common utilities """
import os import os
import re
from uuid import uuid4 from uuid import uuid4
from django import template from django import template
from django.utils.safestring import mark_safe
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.template.defaultfilters import stringfilter
from django.templatetags.static import static from django.templatetags.static import static
@ -66,3 +69,39 @@ def get_book_cover_thumbnail(book, size="medium", ext="jpg"):
return cover_thumbnail.url return cover_thumbnail.url
except OSError: except OSError:
return static("images/no_cover.jpg") return static("images/no_cover.jpg")
@register.filter(name="get_isni_bio")
def get_isni_bio(existing, author):
"""Returns the isni bio string if an existing author has an isni listed"""
auth_isni = re.sub(r"\D", "", str(author.isni))
if len(existing) == 0:
return ""
for value in existing:
if hasattr(value, "bio") and auth_isni == re.sub(r"\D", "", str(value.isni)):
return mark_safe(f"Author of <em>{value.bio}</em>")
return ""
# pylint: disable=unused-argument
@register.filter(name="get_isni", needs_autoescape=True)
def get_isni(existing, author, autoescape=True):
"""Returns the isni ID if an existing author has an ISNI listing"""
auth_isni = re.sub(r"\D", "", str(author.isni))
if len(existing) == 0:
return ""
for value in existing:
if hasattr(value, "isni") and auth_isni == re.sub(r"\D", "", str(value.isni)):
isni = value.isni
return mark_safe(
f'<input type="text" name="isni-for-{author.id}" value="{isni}" hidden>'
)
return ""
@register.filter(name="remove_spaces")
@stringfilter
def remove_spaces(arg):
"""Removes spaces from argument passed in"""
return re.sub(r"\s", "", str(arg))

View File

@ -19,7 +19,7 @@ from django.utils import timezone
from bookwyrm import activitypub from bookwyrm import activitypub
from bookwyrm.activitypub.base_activity import ActivityObject from bookwyrm.activitypub.base_activity import ActivityObject
from bookwyrm.models import fields, User, Status from bookwyrm.models import fields, User, Status, Edition
from bookwyrm.models.base_model import BookWyrmModel from bookwyrm.models.base_model import BookWyrmModel
from bookwyrm.models.activitypub_mixin import ActivitypubMixin from bookwyrm.models.activitypub_mixin import ActivitypubMixin
from bookwyrm.settings import DOMAIN from bookwyrm.settings import DOMAIN
@ -215,7 +215,7 @@ class ModelFields(TestCase):
"rat", "rat@rat.rat", "ratword", local=True, localname="rat" "rat", "rat@rat.rat", "ratword", local=True, localname="rat"
) )
public = "https://www.w3.org/ns/activitystreams#Public" public = "https://www.w3.org/ns/activitystreams#Public"
followers = "%s/followers" % user.remote_id followers = f"{user.remote_id}/followers"
instance = fields.PrivacyField() instance = fields.PrivacyField()
instance.name = "privacy_field" instance.name = "privacy_field"
@ -409,11 +409,10 @@ class ModelFields(TestCase):
"""loadin' a list of items from Links""" """loadin' a list of items from Links"""
# TODO # TODO
@responses.activate
@patch("bookwyrm.models.activitypub_mixin.ObjectMixin.broadcast") @patch("bookwyrm.models.activitypub_mixin.ObjectMixin.broadcast")
@patch("bookwyrm.suggested_users.remove_user_task.delay") @patch("bookwyrm.suggested_users.remove_user_task.delay")
def test_image_field(self, *_): def test_image_field_to_activity(self, *_):
"""storing images""" """serialize an image field to activitypub"""
user = User.objects.create_user( user = User.objects.create_user(
"mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse" "mouse", "mouse@mouse.mouse", "mouseword", local=True, localname="mouse"
) )
@ -437,16 +436,155 @@ class ModelFields(TestCase):
self.assertEqual(output.name, "") self.assertEqual(output.name, "")
self.assertEqual(output.type, "Document") self.assertEqual(output.type, "Document")
@responses.activate
def test_image_field_from_activity(self, *_):
"""load an image from activitypub"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField()
responses.add( responses.add(
responses.GET, responses.GET,
"http://www.example.com/image.jpg", "http://www.example.com/image.jpg",
body=user.avatar.file.read(), body=image.tobytes(),
status=200, status=200,
) )
loaded_image = instance.field_from_activity("http://www.example.com/image.jpg") loaded_image = instance.field_from_activity("http://www.example.com/image.jpg")
self.assertIsInstance(loaded_image, list) self.assertIsInstance(loaded_image, list)
self.assertIsInstance(loaded_image[1], ContentFile) self.assertIsInstance(loaded_image[1], ContentFile)
@responses.activate
def test_image_field_set_field_from_activity(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity)
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 43200)
@responses.activate
def test_image_field_set_field_from_activity_no_overwrite_no_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=False)
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 43200)
@responses.activate
def test_image_field_set_field_from_activity_no_overwrite_with_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
another_image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/logo.png"
)
another_image = Image.open(another_image_file)
another_output = BytesIO()
another_image.save(another_output, format=another_image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=another_image.tobytes(),
status=200,
)
book = Edition.objects.create(title="hello")
book.cover.save("test.jpg", ContentFile(output.getvalue()))
self.assertEqual(book.cover.size, 2136)
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=False)
# same cover as before
self.assertEqual(book.cover.size, 2136)
@responses.activate
def test_image_field_set_field_from_activity_with_overwrite_with_cover(self, *_):
"""update a model instance from an activitypub object"""
image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/default_avi.jpg"
)
image = Image.open(image_file)
output = BytesIO()
image.save(output, format=image.format)
book = Edition.objects.create(title="hello")
book.cover.save("test.jpg", ContentFile(output.getvalue()))
self.assertEqual(book.cover.size, 2136)
another_image_file = pathlib.Path(__file__).parent.joinpath(
"../../static/images/logo.png"
)
another_image = Image.open(another_image_file)
another_output = BytesIO()
another_image.save(another_output, format=another_image.format)
instance = fields.ImageField(activitypub_field="cover", name="cover")
responses.add(
responses.GET,
"http://www.example.com/image.jpg",
body=another_image.tobytes(),
status=200,
)
MockActivity = namedtuple("MockActivity", ("cover"))
mock_activity = MockActivity("http://www.example.com/image.jpg")
instance.set_field_from_activity(book, mock_activity, overwrite=True)
# new cover
self.assertIsNotNone(book.cover.name)
self.assertEqual(book.cover.size, 376800)
def test_datetime_field(self, *_): def test_datetime_field(self, *_):
"""this one is pretty simple, it just has to use isoformat""" """this one is pretty simple, it just has to use isoformat"""
instance = fields.DateTimeField() instance = fields.DateTimeField()

183
bookwyrm/utils/isni.py Normal file
View File

@ -0,0 +1,183 @@
"""ISNI author checking utilities"""
import xml.etree.ElementTree as ET
import requests
from bookwyrm import activitypub, models
def request_isni_data(search_index, search_term, max_records=5):
"""Request data from the ISNI API"""
search_string = f'{search_index}="{search_term}"'
query_params = {
"query": search_string,
"version": "1.1",
"operation": "searchRetrieve",
"recordSchema": "isni-b",
"maximumRecords": max_records,
"startRecord": "1",
"recordPacking": "xml",
"sortKeys": "RLV,pica,0,,",
}
result = requests.get("http://isni.oclc.org/sru/", params=query_params, timeout=10)
# the OCLC ISNI server asserts the payload is encoded
# in latin1, but we know better
result.encoding = "utf-8"
return result.text
def make_name_string(element):
"""create a string of form 'personal_name surname'"""
# NOTE: this will often be incorrect, many naming systems
# list "surname" before personal name
forename = element.find(".//forename")
surname = element.find(".//surname")
if forename is not None:
return "".join([forename.text, " ", surname.text])
return surname.text
def get_other_identifier(element, code):
"""Get other identifiers associated with an author from their ISNI record"""
identifiers = element.findall(".//otherIdentifierOfIdentity")
for section_head in identifiers:
if (
section_head.find(".//type") is not None
and section_head.find(".//type").text == code
and section_head.find(".//identifier") is not None
):
return section_head.find(".//identifier").text
# if we can't find it in otherIdentifierOfIdentity,
# try sources
for source in element.findall(".//sources"):
code_of_source = source.find(".//codeOfSource")
if code_of_source is not None and code_of_source.text.lower() == code.lower():
return source.find(".//sourceIdentifier").text
return ""
def get_external_information_uri(element, match_string):
"""Get URLs associated with an author from their ISNI record"""
sources = element.findall(".//externalInformation")
for source in sources:
information = source.find(".//information")
uri = source.find(".//URI")
if (
uri is not None
and information is not None
and information.text.lower() == match_string.lower()
):
return uri.text
return ""
def find_authors_by_name(name_string, description=False):
"""Query the ISNI database for possible author matches by name"""
payload = request_isni_data("pica.na", name_string)
# parse xml
root = ET.fromstring(payload)
# build list of possible authors
possible_authors = []
for element in root.iter("responseRecord"):
personal_name = element.find(".//forename/..")
if not personal_name:
continue
author = get_author_from_isni(element.find(".//isniUnformatted").text)
if bool(description):
titles = []
# prefer title records from LoC+ coop, Australia, Ireland, or Singapore
# in that order
for source in ["LCNACO", "NLA", "N6I", "NLB"]:
for parent in element.findall(f'.//titleOfWork/[@source="{source}"]'):
titles.append(parent.find(".//title"))
for parent in element.findall(f'.//titleOfWork[@subsource="{source}"]'):
titles.append(parent.find(".//title"))
# otherwise just grab the first title listing
titles.append(element.find(".//title"))
if titles is not None:
# some of the "titles" in ISNI are a little ...iffy
# '@' is used by ISNI/OCLC to index the starting point ignoring stop words
# (e.g. "The @Government of no one")
title_elements = [
e for e in titles if not e.text.replace("@", "").isnumeric()
]
if len(title_elements):
author.bio = title_elements[0].text.replace("@", "")
else:
author.bio = None
possible_authors.append(author)
return possible_authors
def get_author_from_isni(isni):
"""Find data to populate a new author record from their ISNI"""
payload = request_isni_data("pica.isn", isni)
# parse xml
root = ET.fromstring(payload)
# there should only be a single responseRecord
# but let's use the first one just in case
element = root.find(".//responseRecord")
name = make_name_string(element.find(".//forename/.."))
viaf = get_other_identifier(element, "viaf")
# use a set to dedupe aliases in ISNI
aliases = set()
aliases_element = element.findall(".//personalNameVariant")
for entry in aliases_element:
aliases.add(make_name_string(entry))
# aliases needs to be list not set
aliases = list(aliases)
bio = element.find(".//nameTitle")
bio = bio.text if bio is not None else ""
wikipedia = get_external_information_uri(element, "Wikipedia")
author = activitypub.Author(
id=element.find(".//isniURI").text,
name=name,
isni=isni,
viafId=viaf,
aliases=aliases,
bio=bio,
wikipediaLink=wikipedia,
)
return author
def build_author_from_isni(match_value):
"""Build basic author class object from ISNI URL"""
# if it is an isni value get the data
if match_value.startswith("https://isni.org/isni/"):
isni = match_value.replace("https://isni.org/isni/", "")
return {"author": get_author_from_isni(isni)}
# otherwise it's a name string
return {}
def augment_author_metadata(author, isni):
"""Update any missing author fields from ISNI data"""
isni_author = get_author_from_isni(isni)
isni_author.to_model(model=models.Author, instance=author, overwrite=False)
# we DO want to overwrite aliases because we're adding them to the
# existing aliases and ISNI will usually have more.
# We need to dedupe because ISNI records often have lots of dupe aliases
aliases = set(isni_author.aliases)
for alias in author.aliases:
aliases.add(alias)
author.aliases = list(aliases)
author.save()

View File

@ -1,4 +1,5 @@
""" the good stuff! the books! """ """ the good stuff! the books! """
from re import sub
from dateutil.parser import parse as dateparse from dateutil.parser import parse as dateparse
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.postgres.search import SearchRank, SearchVector from django.contrib.postgres.search import SearchRank, SearchVector
@ -11,10 +12,16 @@ from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from bookwyrm import book_search, forms, models from bookwyrm import book_search, forms, models
# from bookwyrm.activitypub.base_activity import ActivityObject
from bookwyrm.utils.isni import (
find_authors_by_name,
build_author_from_isni,
augment_author_metadata,
)
from bookwyrm.views.helpers import get_edition from bookwyrm.views.helpers import get_edition
from .books import set_cover_from_url from .books import set_cover_from_url
# pylint: disable=no-self-use # pylint: disable=no-self-use
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")
@method_decorator( @method_decorator(
@ -33,6 +40,7 @@ class EditBook(View):
data = {"book": book, "form": forms.EditionForm(instance=book)} data = {"book": book, "form": forms.EditionForm(instance=book)}
return TemplateResponse(request, "book/edit/edit_book.html", data) return TemplateResponse(request, "book/edit/edit_book.html", data)
# pylint: disable=too-many-locals
def post(self, request, book_id=None): def post(self, request, book_id=None):
"""edit a book cool""" """edit a book cool"""
# returns None if no match is found # returns None if no match is found
@ -43,12 +51,14 @@ class EditBook(View):
if not form.is_valid(): if not form.is_valid():
return TemplateResponse(request, "book/edit/edit_book.html", data) return TemplateResponse(request, "book/edit/edit_book.html", data)
add_author = request.POST.get("add_author") # filter out empty author fields
# we're adding an author through a free text field add_author = [author for author in request.POST.getlist("add_author") if author]
if add_author: if add_author:
data["add_author"] = add_author data["add_author"] = add_author
data["author_matches"] = [] data["author_matches"] = []
for author in add_author.split(","): data["isni_matches"] = []
for author in add_author:
if not author: if not author:
continue continue
# check for existing authors # check for existing authors
@ -56,15 +66,35 @@ class EditBook(View):
"aliases", weight="B" "aliases", weight="B"
) )
author_matches = (
models.Author.objects.annotate(search=vector)
.annotate(rank=SearchRank(vector, author))
.filter(rank__gt=0.4)
.order_by("-rank")[:5]
)
isni_authors = find_authors_by_name(
author, description=True
) # find matches from ISNI API
# dedupe isni authors we already have in the DB
exists = [
i
for i in isni_authors
for a in author_matches
if sub(r"\D", "", str(i.isni)) == sub(r"\D", "", str(a.isni))
]
# pylint: disable=cell-var-from-loop
matches = list(filter(lambda x: x not in exists, isni_authors))
# combine existing and isni authors
matches.extend(author_matches)
data["author_matches"].append( data["author_matches"].append(
{ {
"name": author.strip(), "name": author.strip(),
"matches": ( "matches": matches,
models.Author.objects.annotate(search=vector) "existing_isnis": exists,
.annotate(rank=SearchRank(vector, author))
.filter(rank__gt=0.4)
.order_by("-rank")[:5]
),
} }
) )
@ -122,6 +152,8 @@ class EditBook(View):
class ConfirmEditBook(View): class ConfirmEditBook(View):
"""confirm edits to a book""" """confirm edits to a book"""
# pylint: disable=too-many-locals
# pylint: disable=too-many-branches
def post(self, request, book_id=None): def post(self, request, book_id=None):
"""edit a book cool""" """edit a book cool"""
# returns None if no match is found # returns None if no match is found
@ -147,9 +179,25 @@ class ConfirmEditBook(View):
author = get_object_or_404( author = get_object_or_404(
models.Author, id=request.POST[f"author_match-{i}"] models.Author, id=request.POST[f"author_match-{i}"]
) )
# update author metadata if the ISNI record is more complete
isni = request.POST.get(f"isni-for-{match}", None)
if isni is not None:
augment_author_metadata(author, isni)
except ValueError: except ValueError:
# otherwise it's a name # otherwise it's a new author
author = models.Author.objects.create(name=match) isni_match = request.POST.get(f"author_match-{i}")
author_object = build_author_from_isni(isni_match)
# with author data class from isni id
if "author" in author_object:
skeleton = models.Author.objects.create(
name=author_object["author"].name
)
author = author_object["author"].to_model(
model=models.Author, overwrite=True, instance=skeleton
)
else:
# or it's just a name
author = models.Author.objects.create(name=match)
book.authors.add(author) book.authors.add(author)
# create work, if needed # create work, if needed

View File

@ -9,6 +9,7 @@ from django.views import View
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from bookwyrm import models from bookwyrm import models
from bookwyrm.views.shelf.shelf_actions import unshelve
from .status import CreateStatus from .status import CreateStatus
from .helpers import get_edition, handle_reading_status, is_api_request from .helpers import get_edition, handle_reading_status, is_api_request
from .helpers import load_date_in_user_tz_as_utc from .helpers import load_date_in_user_tz_as_utc
@ -16,6 +17,7 @@ from .helpers import load_date_in_user_tz_as_utc
@method_decorator(login_required, name="dispatch") @method_decorator(login_required, name="dispatch")
# pylint: disable=no-self-use # pylint: disable=no-self-use
# pylint: disable=too-many-return-statements
class ReadingStatus(View): class ReadingStatus(View):
"""consider reading a book""" """consider reading a book"""
@ -89,8 +91,21 @@ class ReadingStatus(View):
privacy = request.POST.get("privacy") privacy = request.POST.get("privacy")
handle_reading_status(request.user, desired_shelf, book, privacy) handle_reading_status(request.user, desired_shelf, book, privacy)
# if the request includes a "shelf" value we are using the 'move' button
if bool(request.POST.get("shelf")):
# unshelve the existing shelf
this_shelf = request.POST.get("shelf")
if (
bool(current_status_shelfbook)
and int(this_shelf) != int(current_status_shelfbook.shelf.id)
and current_status_shelfbook.shelf.identifier
!= desired_shelf.identifier
):
return unshelve(request, book_id=book_id)
if is_api_request(request): if is_api_request(request):
return HttpResponse() return HttpResponse()
return redirect(referer) return redirect(referer)

View File

@ -91,13 +91,13 @@ def shelve(request):
@login_required @login_required
@require_POST @require_POST
def unshelve(request): def unshelve(request, book_id=False):
"""remove a book from a user's shelf""" """remove a book from a user's shelf"""
book = get_object_or_404(models.Edition, id=request.POST.get("book")) identity = book_id if book_id else request.POST.get("book")
book = get_object_or_404(models.Edition, id=identity)
shelf_book = get_object_or_404( shelf_book = get_object_or_404(
models.ShelfBook, book=book, shelf__id=request.POST["shelf"] models.ShelfBook, book=book, shelf__id=request.POST["shelf"]
) )
shelf_book.raise_not_deletable(request.user) shelf_book.raise_not_deletable(request.user)
shelf_book.delete() shelf_book.delete()
return redirect(request.headers.get("Referer", "/")) return redirect(request.headers.get("Referer", "/"))

View File

@ -54,6 +54,7 @@ class CreateStatus(View):
data = {"book": book} data = {"book": book}
return TemplateResponse(request, "compose.html", data) return TemplateResponse(request, "compose.html", data)
# pylint: disable=too-many-branches
def post(self, request, status_type, existing_status_id=None): def post(self, request, status_type, existing_status_id=None):
"""create status of whatever type""" """create status of whatever type"""
created = not existing_status_id created = not existing_status_id
@ -117,11 +118,12 @@ class CreateStatus(View):
status.save(created=created) status.save(created=created)
# update a readthorugh, if needed # update a readthrough, if needed
try: if bool(request.POST.get("id")):
edit_readthrough(request) try:
except Http404: edit_readthrough(request)
pass except Http404:
pass
if is_api_request(request): if is_api_request(request):
return HttpResponse() return HttpResponse()

1
bw-dev
View File

@ -118,6 +118,7 @@ case "$CMD" in
git checkout l10n_main locale/pt_BR git checkout l10n_main locale/pt_BR
git checkout l10n_main locale/zh_Hans git checkout l10n_main locale/zh_Hans
git checkout l10n_main locale/zh_Hant git checkout l10n_main locale/zh_Hant
runweb django-admin makemessages --no-wrap --ignore=venv -l en_US $@
runweb django-admin compilemessages --ignore venv runweb django-admin compilemessages --ignore venv
;; ;;
build) build)

Binary file not shown.

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-24 10:57+0000\n" "POT-Creation-Date: 2021-12-02 18:24+0000\n"
"PO-Revision-Date: 2021-02-28 17:19-0800\n" "PO-Revision-Date: 2021-02-28 17:19-0800\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: English <LL@li.org>\n" "Language-Team: English <LL@li.org>\n"
@ -243,47 +243,51 @@ msgstr ""
msgid "Something went wrong! Sorry about that." msgid "Something went wrong! Sorry about that."
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:17
#: bookwyrm/templates/author/author.html:18 #: bookwyrm/templates/author/author.html:18
#: bookwyrm/templates/author/author.html:19
msgid "Edit Author" msgid "Edit Author"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:34 #: bookwyrm/templates/author/author.html:35
#: bookwyrm/templates/author/edit_author.html:43 #: bookwyrm/templates/author/edit_author.html:43
msgid "Aliases:" msgid "Aliases:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:45 #: bookwyrm/templates/author/author.html:46
msgid "Born:" msgid "Born:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:52 #: bookwyrm/templates/author/author.html:53
msgid "Died:" msgid "Died:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:61 #: bookwyrm/templates/author/author.html:62
msgid "Wikipedia" msgid "Wikipedia"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:69 #: bookwyrm/templates/author/author.html:70
msgid "View ISNI record"
msgstr ""
#: bookwyrm/templates/author/author.html:78
#: bookwyrm/templates/book/book.html:94 #: bookwyrm/templates/book/book.html:94
msgid "View on OpenLibrary" msgid "View on OpenLibrary"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:77 #: bookwyrm/templates/author/author.html:86
#: bookwyrm/templates/book/book.html:97 #: bookwyrm/templates/book/book.html:97
msgid "View on Inventaire" msgid "View on Inventaire"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:85 #: bookwyrm/templates/author/author.html:94
msgid "View on LibraryThing" msgid "View on LibraryThing"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:93 #: bookwyrm/templates/author/author.html:102
msgid "View on Goodreads" msgid "View on Goodreads"
msgstr "" msgstr ""
#: bookwyrm/templates/author/author.html:108 #: bookwyrm/templates/author/author.html:117
#, python-format #, python-format
msgid "Books by %(name)s" msgid "Books by %(name)s"
msgstr "" msgstr ""
@ -293,17 +297,17 @@ msgid "Edit Author:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/edit_author.html:13 #: bookwyrm/templates/author/edit_author.html:13
#: bookwyrm/templates/book/edit/edit_book.html:18 #: bookwyrm/templates/book/edit/edit_book.html:19
msgid "Added:" msgid "Added:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/edit_author.html:14 #: bookwyrm/templates/author/edit_author.html:14
#: bookwyrm/templates/book/edit/edit_book.html:21 #: bookwyrm/templates/book/edit/edit_book.html:22
msgid "Updated:" msgid "Updated:"
msgstr "" msgstr ""
#: bookwyrm/templates/author/edit_author.html:16 #: bookwyrm/templates/author/edit_author.html:16
#: bookwyrm/templates/book/edit/edit_book.html:25 #: bookwyrm/templates/book/edit/edit_book.html:26
msgid "Last edited by:" msgid "Last edited by:"
msgstr "" msgstr ""
@ -363,7 +367,7 @@ msgstr ""
#: bookwyrm/templates/author/edit_author.html:118 #: bookwyrm/templates/author/edit_author.html:118
#: bookwyrm/templates/book/book.html:140 #: bookwyrm/templates/book/book.html:140
#: bookwyrm/templates/book/edit/edit_book.html:110 #: bookwyrm/templates/book/edit/edit_book.html:121
#: bookwyrm/templates/book/readthrough.html:76 #: bookwyrm/templates/book/readthrough.html:76
#: bookwyrm/templates/groups/form.html:24 #: bookwyrm/templates/groups/form.html:24
#: bookwyrm/templates/lists/bookmark_button.html:15 #: bookwyrm/templates/lists/bookmark_button.html:15
@ -382,8 +386,8 @@ msgstr ""
#: bookwyrm/templates/author/edit_author.html:119 #: bookwyrm/templates/author/edit_author.html:119
#: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190 #: bookwyrm/templates/book/book.html:141 bookwyrm/templates/book/book.html:190
#: bookwyrm/templates/book/cover_modal.html:32 #: bookwyrm/templates/book/cover_modal.html:32
#: bookwyrm/templates/book/edit/edit_book.html:112 #: bookwyrm/templates/book/edit/edit_book.html:123
#: bookwyrm/templates/book/edit/edit_book.html:115 #: bookwyrm/templates/book/edit/edit_book.html:126
#: bookwyrm/templates/book/readthrough.html:77 #: bookwyrm/templates/book/readthrough.html:77
#: bookwyrm/templates/groups/delete_group_modal.html:17 #: bookwyrm/templates/groups/delete_group_modal.html:17
#: bookwyrm/templates/lists/delete_list_modal.html:17 #: bookwyrm/templates/lists/delete_list_modal.html:17
@ -525,56 +529,60 @@ msgstr ""
msgid "Load cover from url:" msgid "Load cover from url:"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:5 #: bookwyrm/templates/book/edit/edit_book.html:6
#: bookwyrm/templates/book/edit/edit_book.html:11 #: bookwyrm/templates/book/edit/edit_book.html:12
#, python-format #, python-format
msgid "Edit \"%(book_title)s\"" msgid "Edit \"%(book_title)s\""
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:5 #: bookwyrm/templates/book/edit/edit_book.html:6
#: bookwyrm/templates/book/edit/edit_book.html:13 #: bookwyrm/templates/book/edit/edit_book.html:14
msgid "Add Book" msgid "Add Book"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:47 #: bookwyrm/templates/book/edit/edit_book.html:48
msgid "Confirm Book Info" msgid "Confirm Book Info"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:55 #: bookwyrm/templates/book/edit/edit_book.html:56
#, python-format #, python-format
msgid "Is \"%(name)s\" an existing author?" msgid "Is \"%(name)s\" one of these authors?"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:64 #: bookwyrm/templates/book/edit/edit_book.html:67
#, python-format #: bookwyrm/templates/book/edit/edit_book.html:69
msgid "Author of <em>%(book_title)s</em>" msgid "Author of "
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:68 #: bookwyrm/templates/book/edit/edit_book.html:69
msgid "Find more information at isni.org"
msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:79
msgid "This is a new author" msgid "This is a new author"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:75 #: bookwyrm/templates/book/edit/edit_book.html:86
#, python-format #, python-format
msgid "Creating a new author: %(name)s" msgid "Creating a new author: %(name)s"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:82 #: bookwyrm/templates/book/edit/edit_book.html:93
msgid "Is this an edition of an existing work?" msgid "Is this an edition of an existing work?"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:90 #: bookwyrm/templates/book/edit/edit_book.html:101
msgid "This is a new work" msgid "This is a new work"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:97 #: bookwyrm/templates/book/edit/edit_book.html:108
#: bookwyrm/templates/groups/members.html:16 #: bookwyrm/templates/groups/members.html:16
#: bookwyrm/templates/landing/password_reset.html:30 #: bookwyrm/templates/landing/password_reset.html:30
#: bookwyrm/templates/snippets/remove_from_group_button.html:16 #: bookwyrm/templates/snippets/remove_from_group_button.html:16
msgid "Confirm" msgid "Confirm"
msgstr "" msgstr ""
#: bookwyrm/templates/book/edit/edit_book.html:99 #: bookwyrm/templates/book/edit/edit_book.html:110
#: bookwyrm/templates/feed/status.html:9 #: bookwyrm/templates/feed/status.html:9
msgid "Back" msgid "Back"
msgstr "" msgstr ""
@ -3886,7 +3894,7 @@ msgstr ""
msgid "File exceeds maximum size: 10MB" msgid "File exceeds maximum size: 10MB"
msgstr "" msgstr ""
#: bookwyrm/templatetags/utilities.py:31 #: bookwyrm/templatetags/utilities.py:34
#, python-format #, python-format
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr ""

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n" "Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n" "POT-Creation-Date: 2021-11-17 18:03+0000\n"
"PO-Revision-Date: 2021-11-17 18:42\n" "PO-Revision-Date: 2021-11-19 18:53\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: Spanish\n" "Language-Team: Spanish\n"
"Language: es\n" "Language: es\n"
@ -184,7 +184,7 @@ msgstr "Español"
#: bookwyrm/settings.py:168 #: bookwyrm/settings.py:168
msgid "Galego (Galician)" msgid "Galego (Galician)"
msgstr "" msgstr "Gallego (Galicia)"
#: bookwyrm/settings.py:169 #: bookwyrm/settings.py:169
msgid "Français (French)" msgid "Français (French)"
@ -192,7 +192,7 @@ msgstr "Français (Francés)"
#: bookwyrm/settings.py:170 #: bookwyrm/settings.py:170
msgid "Lietuvių (Lithuanian)" msgid "Lietuvių (Lithuanian)"
msgstr "" msgstr "Lituano (Lituania)"
#: bookwyrm/settings.py:171 #: bookwyrm/settings.py:171
msgid "Português - Brasil (Brazilian Portuguese)" msgid "Português - Brasil (Brazilian Portuguese)"
@ -904,17 +904,17 @@ msgstr "Todos los usuarios conocidos"
#: bookwyrm/templates/discover/card-header.html:8 #: bookwyrm/templates/discover/card-header.html:8
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> wants to read <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> wants to read <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> quiere leer <a href=\"%(book_path)s\">%(book_title)s</a>"
#: bookwyrm/templates/discover/card-header.html:13 #: bookwyrm/templates/discover/card-header.html:13
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> finished reading <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> finished reading <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> ha terminado de leer <a href=\"%(book_path)s\">%(book_title)s</a>"
#: bookwyrm/templates/discover/card-header.html:18 #: bookwyrm/templates/discover/card-header.html:18
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> started reading <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> started reading <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> ha empezado a leer <a href=\"%(book_path)s\">%(book_title)s</a>"
#: bookwyrm/templates/discover/card-header.html:23 #: bookwyrm/templates/discover/card-header.html:23
#, python-format #, python-format
@ -1400,11 +1400,11 @@ msgstr "Importar estado"
#: bookwyrm/templates/import/import_status.html:13 #: bookwyrm/templates/import/import_status.html:13
#: bookwyrm/templates/import/import_status.html:27 #: bookwyrm/templates/import/import_status.html:27
msgid "Retry Status" msgid "Retry Status"
msgstr "" msgstr "Estado del Reintento"
#: bookwyrm/templates/import/import_status.html:22 #: bookwyrm/templates/import/import_status.html:22
msgid "Imports" msgid "Imports"
msgstr "" msgstr "Importaciones"
#: bookwyrm/templates/import/import_status.html:39 #: bookwyrm/templates/import/import_status.html:39
msgid "Import started:" msgid "Import started:"
@ -1412,38 +1412,38 @@ msgstr "Importación ha empezado:"
#: bookwyrm/templates/import/import_status.html:48 #: bookwyrm/templates/import/import_status.html:48
msgid "In progress" msgid "In progress"
msgstr "" msgstr "En progreso"
#: bookwyrm/templates/import/import_status.html:50 #: bookwyrm/templates/import/import_status.html:50
msgid "Refresh" msgid "Refresh"
msgstr "" msgstr "Refrescar"
#: bookwyrm/templates/import/import_status.html:71 #: bookwyrm/templates/import/import_status.html:71
#, python-format #, python-format
msgid "%(display_counter)s item needs manual approval." msgid "%(display_counter)s item needs manual approval."
msgid_plural "%(display_counter)s items need manual approval." msgid_plural "%(display_counter)s items need manual approval."
msgstr[0] "" msgstr[0] "%(display_counter)s elemento necesita aprobación manual."
msgstr[1] "" msgstr[1] "%(display_counter)s elementos necesitan aprobación manual."
#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/import_status.html:76
#: bookwyrm/templates/import/manual_review.html:8 #: bookwyrm/templates/import/manual_review.html:8
msgid "Review items" msgid "Review items"
msgstr "" msgstr "Revisar elementos"
#: bookwyrm/templates/import/import_status.html:82 #: bookwyrm/templates/import/import_status.html:82
#, python-format #, python-format
msgid "%(display_counter)s item failed to import." msgid "%(display_counter)s item failed to import."
msgid_plural "%(display_counter)s items failed to import." msgid_plural "%(display_counter)s items failed to import."
msgstr[0] "" msgstr[0] "%(display_counter)s elemento no se pudo importar."
msgstr[1] "" msgstr[1] "%(display_counter)s elementos no se pudieron importar."
#: bookwyrm/templates/import/import_status.html:88 #: bookwyrm/templates/import/import_status.html:88
msgid "View and troubleshoot failed items" msgid "View and troubleshoot failed items"
msgstr "" msgstr "Ver y solucionar los elementos fallidos"
#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/import/import_status.html:100
msgid "Row" msgid "Row"
msgstr "" msgstr "Fila"
#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/import/import_status.html:103
#: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:141
@ -1453,7 +1453,7 @@ msgstr "Título"
#: bookwyrm/templates/import/import_status.html:106 #: bookwyrm/templates/import/import_status.html:106
msgid "ISBN" msgid "ISBN"
msgstr "" msgstr "ISBN"
#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/import/import_status.html:109
#: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:142
@ -1463,7 +1463,7 @@ msgstr "Autor/Autora"
#: bookwyrm/templates/import/import_status.html:112 #: bookwyrm/templates/import/import_status.html:112
msgid "Shelf" msgid "Shelf"
msgstr "" msgstr "Estantería"
#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/import_status.html:115
#: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/import/manual_review.html:13
@ -1487,11 +1487,11 @@ msgstr "Estado"
#: bookwyrm/templates/import/import_status.html:130 #: bookwyrm/templates/import/import_status.html:130
msgid "Import preview unavailable." msgid "Import preview unavailable."
msgstr "" msgstr "Previsualización de la importación no disponible."
#: bookwyrm/templates/import/import_status.html:162 #: bookwyrm/templates/import/import_status.html:162
msgid "View imported review" msgid "View imported review"
msgstr "" msgstr "Ver reseña importada"
#: bookwyrm/templates/import/import_status.html:176 #: bookwyrm/templates/import/import_status.html:176
msgid "Imported" msgid "Imported"
@ -1499,28 +1499,28 @@ msgstr "Importado"
#: bookwyrm/templates/import/import_status.html:182 #: bookwyrm/templates/import/import_status.html:182
msgid "Needs manual review" msgid "Needs manual review"
msgstr "" msgstr "Necesita revisión manual"
#: bookwyrm/templates/import/import_status.html:195 #: bookwyrm/templates/import/import_status.html:195
msgid "Retry" msgid "Retry"
msgstr "" msgstr "Reintentar"
#: bookwyrm/templates/import/import_status.html:213 #: bookwyrm/templates/import/import_status.html:213
msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format." msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format."
msgstr "" msgstr "Esta importación está en un formato antiguo que ya no es compatible. Si desea solucionar los elementos que faltan en esta importación, haga clic en el botón de abajo para actualizar el formato de importación."
#: bookwyrm/templates/import/import_status.html:215 #: bookwyrm/templates/import/import_status.html:215
msgid "Update import" msgid "Update import"
msgstr "" msgstr "Actualizar importación"
#: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/manual_review.html:5
#: bookwyrm/templates/import/troubleshoot.html:4 #: bookwyrm/templates/import/troubleshoot.html:4
msgid "Import Troubleshooting" msgid "Import Troubleshooting"
msgstr "" msgstr "Solucionar Importación"
#: bookwyrm/templates/import/manual_review.html:21 #: bookwyrm/templates/import/manual_review.html:21
msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book." msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book."
msgstr "" msgstr "La aprobación de una sugerencia añadirá permanentemente el libro sugerido a tus estanterías y asociará tus fechas de lectura, tus reseñas y tus valoraciones a ese libro."
#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/import/manual_review.html:58
#: bookwyrm/templates/lists/curate.html:57 #: bookwyrm/templates/lists/curate.html:57
@ -1529,7 +1529,7 @@ msgstr "Aprobar"
#: bookwyrm/templates/import/manual_review.html:66 #: bookwyrm/templates/import/manual_review.html:66
msgid "Reject" msgid "Reject"
msgstr "" msgstr "Rechazar"
#: bookwyrm/templates/import/tooltip.html:6 #: bookwyrm/templates/import/tooltip.html:6
msgid "You can download your Goodreads data from the <a href=\"https://www.goodreads.com/review/import\" target=\"_blank\" rel=\"noopener\">Import/Export page</a> of your Goodreads account." msgid "You can download your Goodreads data from the <a href=\"https://www.goodreads.com/review/import\" target=\"_blank\" rel=\"noopener\">Import/Export page</a> of your Goodreads account."
@ -1537,31 +1537,31 @@ msgstr "Puede descargar sus datos de Goodreads desde la <a href=\"https://www.go
#: bookwyrm/templates/import/troubleshoot.html:7 #: bookwyrm/templates/import/troubleshoot.html:7
msgid "Failed items" msgid "Failed items"
msgstr "" msgstr "Elementos fallidos"
#: bookwyrm/templates/import/troubleshoot.html:12 #: bookwyrm/templates/import/troubleshoot.html:12
msgid "Troubleshooting" msgid "Troubleshooting"
msgstr "" msgstr "Solución de problemas"
#: bookwyrm/templates/import/troubleshoot.html:20 #: bookwyrm/templates/import/troubleshoot.html:20
msgid "Re-trying an import can fix missing items in cases such as:" msgid "Re-trying an import can fix missing items in cases such as:"
msgstr "" msgstr "Reintentar una importación puede reparar elementos ausentes en casos como:"
#: bookwyrm/templates/import/troubleshoot.html:23 #: bookwyrm/templates/import/troubleshoot.html:23
msgid "The book has been added to the instance since this import" msgid "The book has been added to the instance since this import"
msgstr "" msgstr "El libro ha sido añadido al nodo a partir de esta importación"
#: bookwyrm/templates/import/troubleshoot.html:24 #: bookwyrm/templates/import/troubleshoot.html:24
msgid "A transient error or timeout caused the external data source to be unavailable." msgid "A transient error or timeout caused the external data source to be unavailable."
msgstr "" msgstr "Un error transitorio o un tiempo de espera rebasado causó que la fuente de datos externa no estuviera disponible."
#: bookwyrm/templates/import/troubleshoot.html:25 #: bookwyrm/templates/import/troubleshoot.html:25
msgid "BookWyrm has been updated since this import with a bug fix" msgid "BookWyrm has been updated since this import with a bug fix"
msgstr "" msgstr "BookWyrm ha sido actualizado con posterioridad a esta importación con una corrección de errores"
#: bookwyrm/templates/import/troubleshoot.html:28 #: bookwyrm/templates/import/troubleshoot.html:28
msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items." msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items."
msgstr "" msgstr "Póngase en contacto con su administrador o <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>cree una propuesta</a> si está viendo elementos fallidos inesperados."
#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230
#, python-format #, python-format

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n" "Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n" "POT-Creation-Date: 2021-11-17 18:03+0000\n"
"PO-Revision-Date: 2021-11-17 18:41\n" "PO-Revision-Date: 2021-11-22 19:37\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: French\n" "Language-Team: French\n"
"Language: fr\n" "Language: fr\n"
@ -99,7 +99,7 @@ msgstr "Suppression du modérateur"
#: bookwyrm/models/base_model.py:21 #: bookwyrm/models/base_model.py:21
msgid "Domain block" msgid "Domain block"
msgstr "Bloc de domaine" msgstr "Blocage de domaine"
#: bookwyrm/models/book.py:233 #: bookwyrm/models/book.py:233
msgid "Audiobook" msgid "Audiobook"
@ -184,7 +184,7 @@ msgstr "Español"
#: bookwyrm/settings.py:168 #: bookwyrm/settings.py:168
msgid "Galego (Galician)" msgid "Galego (Galician)"
msgstr "" msgstr "Galego (Galicien)"
#: bookwyrm/settings.py:169 #: bookwyrm/settings.py:169
msgid "Français (French)" msgid "Français (French)"
@ -192,7 +192,7 @@ msgstr "Français"
#: bookwyrm/settings.py:170 #: bookwyrm/settings.py:170
msgid "Lietuvių (Lithuanian)" msgid "Lietuvių (Lithuanian)"
msgstr "" msgstr "Lietuvių (Lituanien)"
#: bookwyrm/settings.py:171 #: bookwyrm/settings.py:171
msgid "Português - Brasil (Brazilian Portuguese)" msgid "Português - Brasil (Brazilian Portuguese)"
@ -1487,7 +1487,7 @@ msgstr "Statut"
#: bookwyrm/templates/import/import_status.html:130 #: bookwyrm/templates/import/import_status.html:130
msgid "Import preview unavailable." msgid "Import preview unavailable."
msgstr "" msgstr "Aperçu de l'importation indisponible."
#: bookwyrm/templates/import/import_status.html:162 #: bookwyrm/templates/import/import_status.html:162
msgid "View imported review" msgid "View imported review"
@ -1503,15 +1503,15 @@ msgstr "Nécessite une vérification manuelle"
#: bookwyrm/templates/import/import_status.html:195 #: bookwyrm/templates/import/import_status.html:195
msgid "Retry" msgid "Retry"
msgstr "" msgstr "Réessayer"
#: bookwyrm/templates/import/import_status.html:213 #: bookwyrm/templates/import/import_status.html:213
msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format." msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format."
msgstr "" msgstr "Cette importation est dans un ancien format qui n'est plus pris en charge. Si vous souhaitez corriger les éléments manquants de cette importation, cliquez sur le bouton ci-dessous pour mettre à jour le format d'importation."
#: bookwyrm/templates/import/import_status.html:215 #: bookwyrm/templates/import/import_status.html:215
msgid "Update import" msgid "Update import"
msgstr "" msgstr "Mettre à jour l'importation"
#: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/manual_review.html:5
#: bookwyrm/templates/import/troubleshoot.html:4 #: bookwyrm/templates/import/troubleshoot.html:4

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n" "Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n" "POT-Creation-Date: 2021-11-17 18:03+0000\n"
"PO-Revision-Date: 2021-11-19 16:48\n" "PO-Revision-Date: 2021-11-19 17:43\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: Galician\n" "Language-Team: Galician\n"
"Language: gl\n" "Language: gl\n"
@ -3114,140 +3114,140 @@ msgstr "Crear estante"
#, python-format #, python-format
msgid "%(formatted_count)s book" msgid "%(formatted_count)s book"
msgid_plural "%(formatted_count)s books" msgid_plural "%(formatted_count)s books"
msgstr[0] "" msgstr[0] "%(formatted_count)s libro"
msgstr[1] "" msgstr[1] "%(formatted_count)s libros"
#: bookwyrm/templates/shelf/shelf.html:97 #: bookwyrm/templates/shelf/shelf.html:97
#, python-format #, python-format
msgid "(showing %(start)s-%(end)s)" msgid "(showing %(start)s-%(end)s)"
msgstr "" msgstr "(mostrando %(start)s-%(end)s)"
#: bookwyrm/templates/shelf/shelf.html:109 #: bookwyrm/templates/shelf/shelf.html:109
msgid "Edit shelf" msgid "Edit shelf"
msgstr "" msgstr "Editar estante"
#: bookwyrm/templates/shelf/shelf.html:117 #: bookwyrm/templates/shelf/shelf.html:117
msgid "Delete shelf" msgid "Delete shelf"
msgstr "" msgstr "Eliminar estante"
#: bookwyrm/templates/shelf/shelf.html:145 #: bookwyrm/templates/shelf/shelf.html:145
#: bookwyrm/templates/shelf/shelf.html:171 #: bookwyrm/templates/shelf/shelf.html:171
msgid "Shelved" msgid "Shelved"
msgstr "" msgstr "No estante"
#: bookwyrm/templates/shelf/shelf.html:146 #: bookwyrm/templates/shelf/shelf.html:146
#: bookwyrm/templates/shelf/shelf.html:174 #: bookwyrm/templates/shelf/shelf.html:174
msgid "Started" msgid "Started"
msgstr "" msgstr "Comezado"
#: bookwyrm/templates/shelf/shelf.html:147 #: bookwyrm/templates/shelf/shelf.html:147
#: bookwyrm/templates/shelf/shelf.html:177 #: bookwyrm/templates/shelf/shelf.html:177
msgid "Finished" msgid "Finished"
msgstr "" msgstr "Rematado"
#: bookwyrm/templates/shelf/shelf.html:203 #: bookwyrm/templates/shelf/shelf.html:203
msgid "This shelf is empty." msgid "This shelf is empty."
msgstr "" msgstr "Este estante esta baleiro."
#: bookwyrm/templates/snippets/add_to_group_button.html:15 #: bookwyrm/templates/snippets/add_to_group_button.html:15
msgid "Invite" msgid "Invite"
msgstr "" msgstr "Convidar"
#: bookwyrm/templates/snippets/add_to_group_button.html:24 #: bookwyrm/templates/snippets/add_to_group_button.html:24
msgid "Uninvite" msgid "Uninvite"
msgstr "" msgstr "Retirar convite"
#: bookwyrm/templates/snippets/add_to_group_button.html:28 #: bookwyrm/templates/snippets/add_to_group_button.html:28
#, python-format #, python-format
msgid "Remove @%(username)s" msgid "Remove @%(username)s"
msgstr "" msgstr "Eliminar @%(username)s"
#: bookwyrm/templates/snippets/announcement.html:31 #: bookwyrm/templates/snippets/announcement.html:31
#, python-format #, python-format
msgid "Posted by <a href=\"%(user_path)s\">%(username)s</a>" msgid "Posted by <a href=\"%(user_path)s\">%(username)s</a>"
msgstr "" msgstr "Publicado por <a href=\"%(user_path)s\">%(username)s</a>"
#: bookwyrm/templates/snippets/authors.html:22 #: bookwyrm/templates/snippets/authors.html:22
#, python-format #, python-format
msgid "and %(remainder_count_display)s other" msgid "and %(remainder_count_display)s other"
msgid_plural "and %(remainder_count_display)s others" msgid_plural "and %(remainder_count_display)s others"
msgstr[0] "" msgstr[0] "e %(remainder_count_display)s outro"
msgstr[1] "" msgstr[1] "e %(remainder_count_display)s outros"
#: bookwyrm/templates/snippets/book_cover.html:61 #: bookwyrm/templates/snippets/book_cover.html:61
msgid "No cover" msgid "No cover"
msgstr "" msgstr "Sen portada"
#: bookwyrm/templates/snippets/book_titleby.html:6 #: bookwyrm/templates/snippets/book_titleby.html:6
#, python-format #, python-format
msgid "<a href=\"%(path)s\">%(title)s</a> by" msgid "<a href=\"%(path)s\">%(title)s</a> by"
msgstr "" msgstr "<a href=\"%(path)s\">%(title)s</a> por"
#: bookwyrm/templates/snippets/boost_button.html:20 #: bookwyrm/templates/snippets/boost_button.html:20
#: bookwyrm/templates/snippets/boost_button.html:21 #: bookwyrm/templates/snippets/boost_button.html:21
msgid "Boost" msgid "Boost"
msgstr "" msgstr "Promover"
#: bookwyrm/templates/snippets/boost_button.html:33 #: bookwyrm/templates/snippets/boost_button.html:33
#: bookwyrm/templates/snippets/boost_button.html:34 #: bookwyrm/templates/snippets/boost_button.html:34
msgid "Un-boost" msgid "Un-boost"
msgstr "" msgstr "Retirar promoción"
#: bookwyrm/templates/snippets/create_status.html:39 #: bookwyrm/templates/snippets/create_status.html:39
msgid "Quote" msgid "Quote"
msgstr "" msgstr "Cita"
#: bookwyrm/templates/snippets/create_status/comment.html:15 #: bookwyrm/templates/snippets/create_status/comment.html:15
msgid "Some thoughts on the book" msgid "Some thoughts on the book"
msgstr "" msgstr "Cousas interesantes no libro"
#: bookwyrm/templates/snippets/create_status/comment.html:27 #: bookwyrm/templates/snippets/create_status/comment.html:27
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:15 #: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:15
msgid "Progress:" msgid "Progress:"
msgstr "" msgstr "Progreso:"
#: bookwyrm/templates/snippets/create_status/comment.html:53 #: bookwyrm/templates/snippets/create_status/comment.html:53
#: bookwyrm/templates/snippets/progress_field.html:18 #: bookwyrm/templates/snippets/progress_field.html:18
msgid "pages" msgid "pages"
msgstr "" msgstr "páxinas"
#: bookwyrm/templates/snippets/create_status/comment.html:59 #: bookwyrm/templates/snippets/create_status/comment.html:59
#: bookwyrm/templates/snippets/progress_field.html:23 #: bookwyrm/templates/snippets/progress_field.html:23
msgid "percent" msgid "percent"
msgstr "" msgstr "porcentaxe"
#: bookwyrm/templates/snippets/create_status/comment.html:66 #: bookwyrm/templates/snippets/create_status/comment.html:66
#, python-format #, python-format
msgid "of %(pages)s pages" msgid "of %(pages)s pages"
msgstr "" msgstr "de %(pages)s páxinas"
#: bookwyrm/templates/snippets/create_status/content_field.html:17 #: bookwyrm/templates/snippets/create_status/content_field.html:17
#: bookwyrm/templates/snippets/status/layout.html:34 #: bookwyrm/templates/snippets/status/layout.html:34
#: bookwyrm/templates/snippets/status/layout.html:52 #: bookwyrm/templates/snippets/status/layout.html:52
#: bookwyrm/templates/snippets/status/layout.html:53 #: bookwyrm/templates/snippets/status/layout.html:53
msgid "Reply" msgid "Reply"
msgstr "" msgstr "Responder"
#: bookwyrm/templates/snippets/create_status/content_field.html:17 #: bookwyrm/templates/snippets/create_status/content_field.html:17
msgid "Content" msgid "Content"
msgstr "" msgstr "Contido"
#: bookwyrm/templates/snippets/create_status/content_warning_field.html:10 #: bookwyrm/templates/snippets/create_status/content_warning_field.html:10
msgid "Content warning:" msgid "Content warning:"
msgstr "" msgstr "Aviso sobre o contido:"
#: bookwyrm/templates/snippets/create_status/content_warning_field.html:18 #: bookwyrm/templates/snippets/create_status/content_warning_field.html:18
msgid "Spoilers ahead!" msgid "Spoilers ahead!"
msgstr "" msgstr "Contén Spoilers!"
#: bookwyrm/templates/snippets/create_status/content_warning_toggle.html:13 #: bookwyrm/templates/snippets/create_status/content_warning_toggle.html:13
msgid "Include spoiler alert" msgid "Include spoiler alert"
msgstr "" msgstr "Incluír alerta de spoiler"
#: bookwyrm/templates/snippets/create_status/layout.html:48 #: bookwyrm/templates/snippets/create_status/layout.html:48
#: bookwyrm/templates/snippets/reading_modals/form.html:7 #: bookwyrm/templates/snippets/reading_modals/form.html:7
msgid "Comment:" msgid "Comment:"
msgstr "" msgstr "Comentario:"
#: bookwyrm/templates/snippets/create_status/post_options_block.html:8 #: bookwyrm/templates/snippets/create_status/post_options_block.html:8
#: bookwyrm/templates/snippets/privacy-icons.html:15 #: bookwyrm/templates/snippets/privacy-icons.html:15
@ -3255,60 +3255,60 @@ msgstr ""
#: bookwyrm/templates/snippets/privacy_select.html:20 #: bookwyrm/templates/snippets/privacy_select.html:20
#: bookwyrm/templates/snippets/privacy_select_no_followers.html:17 #: bookwyrm/templates/snippets/privacy_select_no_followers.html:17
msgid "Private" msgid "Private"
msgstr "" msgstr "Privado"
#: bookwyrm/templates/snippets/create_status/post_options_block.html:21 #: bookwyrm/templates/snippets/create_status/post_options_block.html:21
msgid "Post" msgid "Post"
msgstr "" msgstr "Publicación"
#: bookwyrm/templates/snippets/create_status/quotation.html:17 #: bookwyrm/templates/snippets/create_status/quotation.html:17
msgid "Quote:" msgid "Quote:"
msgstr "" msgstr "Cita:"
#: bookwyrm/templates/snippets/create_status/quotation.html:25 #: bookwyrm/templates/snippets/create_status/quotation.html:25
#, python-format #, python-format
msgid "An excerpt from '%(book_title)s'" msgid "An excerpt from '%(book_title)s'"
msgstr "" msgstr "Un extracto de '%(book_title)s'"
#: bookwyrm/templates/snippets/create_status/quotation.html:32 #: bookwyrm/templates/snippets/create_status/quotation.html:32
msgid "Position:" msgid "Position:"
msgstr "" msgstr "Posición:"
#: bookwyrm/templates/snippets/create_status/quotation.html:45 #: bookwyrm/templates/snippets/create_status/quotation.html:45
msgid "On page:" msgid "On page:"
msgstr "" msgstr "Na páxina:"
#: bookwyrm/templates/snippets/create_status/quotation.html:51 #: bookwyrm/templates/snippets/create_status/quotation.html:51
msgid "At percent:" msgid "At percent:"
msgstr "" msgstr "Na porcentaxe:"
#: bookwyrm/templates/snippets/create_status/review.html:25 #: bookwyrm/templates/snippets/create_status/review.html:25
#, python-format #, python-format
msgid "Your review of '%(book_title)s'" msgid "Your review of '%(book_title)s'"
msgstr "" msgstr "A túa recensión de '%(book_title)s'"
#: bookwyrm/templates/snippets/create_status/review.html:40 #: bookwyrm/templates/snippets/create_status/review.html:40
msgid "Review:" msgid "Review:"
msgstr "" msgstr "Recensión:"
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:4 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:4
msgid "Delete these read dates?" msgid "Delete these read dates?"
msgstr "" msgstr "Eliminar estas datas de lectura?"
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:7 #: bookwyrm/templates/snippets/delete_readthrough_modal.html:7
#, python-format #, python-format
msgid "You are deleting this readthrough and its %(count)s associated progress updates." msgid "You are deleting this readthrough and its %(count)s associated progress updates."
msgstr "" msgstr "Vas eliminar o diario de lectura e as súas %(count)s actualizacións de progreso da lectura."
#: bookwyrm/templates/snippets/fav_button.html:16 #: bookwyrm/templates/snippets/fav_button.html:16
#: bookwyrm/templates/snippets/fav_button.html:17 #: bookwyrm/templates/snippets/fav_button.html:17
msgid "Like" msgid "Like"
msgstr "" msgstr "Gústame"
#: bookwyrm/templates/snippets/fav_button.html:30 #: bookwyrm/templates/snippets/fav_button.html:30
#: bookwyrm/templates/snippets/fav_button.html:31 #: bookwyrm/templates/snippets/fav_button.html:31
msgid "Un-like" msgid "Un-like"
msgstr "" msgstr "Retirar gústame"
#: bookwyrm/templates/snippets/filters_panel/filters_panel.html:7 #: bookwyrm/templates/snippets/filters_panel/filters_panel.html:7
msgid "Show filters" msgid "Show filters"
@ -3391,26 +3391,26 @@ msgstr[1] "valorado <em><a href=\"%(path)s\">%(title)s</a></em>: %(display_ratin
#, python-format #, python-format
msgid "Review of \"%(book_title)s\" (%(display_rating)s star): %(review_title)s" msgid "Review of \"%(book_title)s\" (%(display_rating)s star): %(review_title)s"
msgid_plural "Review of \"%(book_title)s\" (%(display_rating)s stars): %(review_title)s" msgid_plural "Review of \"%(book_title)s\" (%(display_rating)s stars): %(review_title)s"
msgstr[0] "" msgstr[0] "Recensión de \"%(book_title)s\" (%(display_rating)s estrela): %(review_title)s"
msgstr[1] "" msgstr[1] "Recensión de \"%(book_title)s\" (%(display_rating)s estrelas): %(review_title)s"
#: bookwyrm/templates/snippets/generated_status/review_pure_name.html:8 #: bookwyrm/templates/snippets/generated_status/review_pure_name.html:8
#, python-format #, python-format
msgid "Review of \"%(book_title)s\": %(review_title)s" msgid "Review of \"%(book_title)s\": %(review_title)s"
msgstr "" msgstr "Recensión de \"%(book_title)s\": %(review_title)s"
#: bookwyrm/templates/snippets/goal_form.html:4 #: bookwyrm/templates/snippets/goal_form.html:4
#, python-format #, python-format
msgid "Set a goal for how many books you'll finish reading in %(year)s, and track your progress throughout the year." msgid "Set a goal for how many books you'll finish reading in %(year)s, and track your progress throughout the year."
msgstr "" msgstr "Establece un obxectivo de cantos libros queres ler en %(year)s, e controla a túa progresión durante o ano."
#: bookwyrm/templates/snippets/goal_form.html:16 #: bookwyrm/templates/snippets/goal_form.html:16
msgid "Reading goal:" msgid "Reading goal:"
msgstr "" msgstr "Obxectivo de lectura:"
#: bookwyrm/templates/snippets/goal_form.html:21 #: bookwyrm/templates/snippets/goal_form.html:21
msgid "books" msgid "books"
msgstr "" msgstr "libros"
#: bookwyrm/templates/snippets/goal_form.html:26 #: bookwyrm/templates/snippets/goal_form.html:26
msgid "Goal privacy:" msgid "Goal privacy:"
@ -3652,51 +3652,51 @@ msgstr "recensionou <a href=\"%(book_path)s\">%(book)s</a>"
#: bookwyrm/templates/snippets/status/headers/to_read.html:7 #: bookwyrm/templates/snippets/status/headers/to_read.html:7
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> wants to read <a href=\"%(book_path)s\">%(book)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> wants to read <a href=\"%(book_path)s\">%(book)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> quere ler <a href=\"%(book_path)s\">%(book)s</a>"
#: bookwyrm/templates/snippets/status/layout.html:24 #: bookwyrm/templates/snippets/status/layout.html:24
#: bookwyrm/templates/snippets/status/status_options.html:17 #: bookwyrm/templates/snippets/status/status_options.html:17
msgid "Delete status" msgid "Delete status"
msgstr "" msgstr "Eliminar estado"
#: bookwyrm/templates/snippets/status/layout.html:56 #: bookwyrm/templates/snippets/status/layout.html:56
#: bookwyrm/templates/snippets/status/layout.html:57 #: bookwyrm/templates/snippets/status/layout.html:57
msgid "Boost status" msgid "Boost status"
msgstr "" msgstr "Promover estado"
#: bookwyrm/templates/snippets/status/layout.html:60 #: bookwyrm/templates/snippets/status/layout.html:60
#: bookwyrm/templates/snippets/status/layout.html:61 #: bookwyrm/templates/snippets/status/layout.html:61
msgid "Like status" msgid "Like status"
msgstr "" msgstr "Gustar estado"
#: bookwyrm/templates/snippets/status/status.html:10 #: bookwyrm/templates/snippets/status/status.html:10
msgid "boosted" msgid "boosted"
msgstr "" msgstr "promovido"
#: bookwyrm/templates/snippets/status/status_options.html:7 #: bookwyrm/templates/snippets/status/status_options.html:7
#: bookwyrm/templates/snippets/user_options.html:7 #: bookwyrm/templates/snippets/user_options.html:7
msgid "More options" msgid "More options"
msgstr "" msgstr "Máis opcións"
#: bookwyrm/templates/snippets/switch_edition_button.html:5 #: bookwyrm/templates/snippets/switch_edition_button.html:5
msgid "Switch to this edition" msgid "Switch to this edition"
msgstr "" msgstr "Cambiar a esta edición"
#: bookwyrm/templates/snippets/table-sort-header.html:6 #: bookwyrm/templates/snippets/table-sort-header.html:6
msgid "Sorted ascending" msgid "Sorted ascending"
msgstr "" msgstr "Orde ascendente"
#: bookwyrm/templates/snippets/table-sort-header.html:10 #: bookwyrm/templates/snippets/table-sort-header.html:10
msgid "Sorted descending" msgid "Sorted descending"
msgstr "" msgstr "Orde descendente"
#: bookwyrm/templates/snippets/trimmed_text.html:17 #: bookwyrm/templates/snippets/trimmed_text.html:17
msgid "Show more" msgid "Show more"
msgstr "" msgstr "Mostrar máis"
#: bookwyrm/templates/snippets/trimmed_text.html:35 #: bookwyrm/templates/snippets/trimmed_text.html:35
msgid "Show less" msgid "Show less"
msgstr "" msgstr "Mostrar menos"
#: bookwyrm/templates/user/books_header.html:10 #: bookwyrm/templates/user/books_header.html:10
msgid "Your books" msgid "Your books"
@ -3705,166 +3705,166 @@ msgstr "Os teus libros"
#: bookwyrm/templates/user/books_header.html:15 #: bookwyrm/templates/user/books_header.html:15
#, python-format #, python-format
msgid "%(username)s's books" msgid "%(username)s's books"
msgstr "" msgstr "Libros de %(username)s"
#: bookwyrm/templates/user/goal.html:8 #: bookwyrm/templates/user/goal.html:8
#, python-format #, python-format
msgid "%(year)s Reading Progress" msgid "%(year)s Reading Progress"
msgstr "" msgstr "Progresión da lectura en %(year)s"
#: bookwyrm/templates/user/goal.html:12 #: bookwyrm/templates/user/goal.html:12
msgid "Edit Goal" msgid "Edit Goal"
msgstr "" msgstr "Editar obxectivo"
#: bookwyrm/templates/user/goal.html:28 #: bookwyrm/templates/user/goal.html:28
#, python-format #, python-format
msgid "%(name)s hasn't set a reading goal for %(year)s." msgid "%(name)s hasn't set a reading goal for %(year)s."
msgstr "" msgstr "%(name)s non estableceu un obxectivo de lectura para %(year)s."
#: bookwyrm/templates/user/goal.html:40 #: bookwyrm/templates/user/goal.html:40
#, python-format #, python-format
msgid "Your %(year)s Books" msgid "Your %(year)s Books"
msgstr "" msgstr "O teus libros de %(year)s"
#: bookwyrm/templates/user/goal.html:42 #: bookwyrm/templates/user/goal.html:42
#, python-format #, python-format
msgid "%(username)s's %(year)s Books" msgid "%(username)s's %(year)s Books"
msgstr "" msgstr "Libros de %(username)s para %(year)s"
#: bookwyrm/templates/user/groups.html:9 #: bookwyrm/templates/user/groups.html:9
msgid "Your Groups" msgid "Your Groups"
msgstr "" msgstr "Os teus grupos"
#: bookwyrm/templates/user/groups.html:11 #: bookwyrm/templates/user/groups.html:11
#, python-format #, python-format
msgid "Groups: %(username)s" msgid "Groups: %(username)s"
msgstr "" msgstr "Grupos: %(username)s"
#: bookwyrm/templates/user/groups.html:17 #: bookwyrm/templates/user/groups.html:17
msgid "Create group" msgid "Create group"
msgstr "" msgstr "Crear grupo"
#: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10 #: bookwyrm/templates/user/layout.html:19 bookwyrm/templates/user/user.html:10
msgid "User Profile" msgid "User Profile"
msgstr "" msgstr "Perfil da usuaria"
#: bookwyrm/templates/user/layout.html:45 #: bookwyrm/templates/user/layout.html:45
msgid "Follow Requests" msgid "Follow Requests"
msgstr "" msgstr "Solicitudes de seguimento"
#: bookwyrm/templates/user/layout.html:70 #: bookwyrm/templates/user/layout.html:70
msgid "Reading Goal" msgid "Reading Goal"
msgstr "" msgstr "Obxectivo de lectura"
#: bookwyrm/templates/user/layout.html:76 #: bookwyrm/templates/user/layout.html:76
msgid "Groups" msgid "Groups"
msgstr "" msgstr "Grupos"
#: bookwyrm/templates/user/lists.html:11 #: bookwyrm/templates/user/lists.html:11
#, python-format #, python-format
msgid "Lists: %(username)s" msgid "Lists: %(username)s"
msgstr "" msgstr "Listas: %(username)s"
#: bookwyrm/templates/user/lists.html:17 bookwyrm/templates/user/lists.html:29 #: bookwyrm/templates/user/lists.html:17 bookwyrm/templates/user/lists.html:29
msgid "Create list" msgid "Create list"
msgstr "" msgstr "Crear lista"
#: bookwyrm/templates/user/relationships/followers.html:12 #: bookwyrm/templates/user/relationships/followers.html:12
#, python-format #, python-format
msgid "%(username)s has no followers" msgid "%(username)s has no followers"
msgstr "" msgstr "%(username)s non ten seguidoras"
#: bookwyrm/templates/user/relationships/following.html:6 #: bookwyrm/templates/user/relationships/following.html:6
#: bookwyrm/templates/user/relationships/layout.html:15 #: bookwyrm/templates/user/relationships/layout.html:15
msgid "Following" msgid "Following"
msgstr "" msgstr "Seguindo"
#: bookwyrm/templates/user/relationships/following.html:12 #: bookwyrm/templates/user/relationships/following.html:12
#, python-format #, python-format
msgid "%(username)s isn't following any users" msgid "%(username)s isn't following any users"
msgstr "" msgstr "%(username)s non segue a ninguén"
#: bookwyrm/templates/user/user.html:16 #: bookwyrm/templates/user/user.html:16
msgid "Edit profile" msgid "Edit profile"
msgstr "" msgstr "Editar perfil"
#: bookwyrm/templates/user/user.html:33 #: bookwyrm/templates/user/user.html:33
#, python-format #, python-format
msgid "View all %(size)s" msgid "View all %(size)s"
msgstr "" msgstr "Ver tódolos %(size)s"
#: bookwyrm/templates/user/user.html:46 #: bookwyrm/templates/user/user.html:46
msgid "View all books" msgid "View all books"
msgstr "" msgstr "Ver tódolos libros"
#: bookwyrm/templates/user/user.html:59 #: bookwyrm/templates/user/user.html:59
msgid "User Activity" msgid "User Activity"
msgstr "" msgstr "Actividade da usuaria"
#: bookwyrm/templates/user/user.html:63 #: bookwyrm/templates/user/user.html:63
msgid "RSS feed" msgid "RSS feed"
msgstr "" msgstr "Fonte RSS"
#: bookwyrm/templates/user/user.html:74 #: bookwyrm/templates/user/user.html:74
msgid "No activities yet!" msgid "No activities yet!"
msgstr "" msgstr "Sen actividade!"
#: bookwyrm/templates/user/user_preview.html:22 #: bookwyrm/templates/user/user_preview.html:22
#, python-format #, python-format
msgid "Joined %(date)s" msgid "Joined %(date)s"
msgstr "" msgstr "Uniuse en %(date)s"
#: bookwyrm/templates/user/user_preview.html:26 #: bookwyrm/templates/user/user_preview.html:26
#, python-format #, python-format
msgid "%(counter)s follower" msgid "%(counter)s follower"
msgid_plural "%(counter)s followers" msgid_plural "%(counter)s followers"
msgstr[0] "" msgstr[0] "%(counter)s seguidora"
msgstr[1] "" msgstr[1] "%(counter)s seguidoras"
#: bookwyrm/templates/user/user_preview.html:27 #: bookwyrm/templates/user/user_preview.html:27
#, python-format #, python-format
msgid "%(counter)s following" msgid "%(counter)s following"
msgstr "" msgstr "Seguindo a %(counter)s"
#: bookwyrm/templates/user/user_preview.html:34 #: bookwyrm/templates/user/user_preview.html:34
#, python-format #, python-format
msgid "%(mutuals_display)s follower you follow" msgid "%(mutuals_display)s follower you follow"
msgid_plural "%(mutuals_display)s followers you follow" msgid_plural "%(mutuals_display)s followers you follow"
msgstr[0] "" msgstr[0] "%(mutuals_display)s seguidora que segues"
msgstr[1] "" msgstr[1] "%(mutuals_display)s seguidoras que segues"
#: bookwyrm/templates/user/user_preview.html:38 #: bookwyrm/templates/user/user_preview.html:38
msgid "No followers you follow" msgid "No followers you follow"
msgstr "" msgstr "Sen seguidoras que ti segues"
#: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28 #: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28
msgid "File exceeds maximum size: 10MB" msgid "File exceeds maximum size: 10MB"
msgstr "" msgstr "O ficheiro supera o tamaño máximo: 10MB"
#: bookwyrm/templatetags/utilities.py:31 #: bookwyrm/templatetags/utilities.py:31
#, python-format #, python-format
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr "%(title)s: %(subtitle)s"
#: bookwyrm/views/imports/import_data.py:64 #: bookwyrm/views/imports/import_data.py:64
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "" msgstr "Non é un ficheiro csv válido"
#: bookwyrm/views/landing/login.py:69 #: bookwyrm/views/landing/login.py:69
msgid "Username or password are incorrect" msgid "Username or password are incorrect"
msgstr "" msgstr "O nome de usuaria ou contrasinal non son correctos"
#: bookwyrm/views/landing/password.py:32 #: bookwyrm/views/landing/password.py:32
msgid "No user with that email address was found." msgid "No user with that email address was found."
msgstr "" msgstr "Non atopamos unha usuaria con ese email."
#: bookwyrm/views/landing/password.py:43 #: bookwyrm/views/landing/password.py:43
#, python-brace-format #, python-brace-format
msgid "A password reset link was sent to {email}" msgid "A password reset link was sent to {email}"
msgstr "" msgstr "Enviamos unha ligazón de restablecemento a {email}"
#: bookwyrm/views/rss_feed.py:35 #: bookwyrm/views/rss_feed.py:35
#, python-brace-format #, python-brace-format
msgid "Status updates from {obj.display_name}" msgid "Status updates from {obj.display_name}"
msgstr "" msgstr "Actualizacións de estados desde {obj.display_name}"

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n" "Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n" "POT-Creation-Date: 2021-11-17 18:03+0000\n"
"PO-Revision-Date: 2021-11-17 20:02\n" "PO-Revision-Date: 2021-11-29 13:53\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: Lithuanian\n" "Language-Team: Lithuanian\n"
"Language: lt\n" "Language: lt\n"
@ -48,7 +48,7 @@ msgstr "Neribota"
#: bookwyrm/forms.py:338 #: bookwyrm/forms.py:338
msgid "List Order" msgid "List Order"
msgstr "Sąrašo užsakymas" msgstr "Kaip pridėta į sąrašą"
#: bookwyrm/forms.py:339 #: bookwyrm/forms.py:339
msgid "Book Title" msgid "Book Title"
@ -184,7 +184,7 @@ msgstr "Español (Ispanų)"
#: bookwyrm/settings.py:168 #: bookwyrm/settings.py:168
msgid "Galego (Galician)" msgid "Galego (Galician)"
msgstr "" msgstr "Galego (galisų)"
#: bookwyrm/settings.py:169 #: bookwyrm/settings.py:169
msgid "Français (French)" msgid "Français (French)"
@ -192,7 +192,7 @@ msgstr "Français (Prancūzų)"
#: bookwyrm/settings.py:170 #: bookwyrm/settings.py:170
msgid "Lietuvių (Lithuanian)" msgid "Lietuvių (Lithuanian)"
msgstr "" msgstr "Lietuvių"
#: bookwyrm/settings.py:171 #: bookwyrm/settings.py:171
msgid "Português - Brasil (Brazilian Portuguese)" msgid "Português - Brasil (Brazilian Portuguese)"
@ -591,7 +591,7 @@ msgstr "Kalbos:"
#: bookwyrm/templates/book/edit/edit_book_form.html:74 #: bookwyrm/templates/book/edit/edit_book_form.html:74
msgid "Publication" msgid "Publication"
msgstr "Paskelbimas" msgstr "Leidimas"
#: bookwyrm/templates/book/edit/edit_book_form.html:77 #: bookwyrm/templates/book/edit/edit_book_form.html:77
msgid "Publisher:" msgid "Publisher:"
@ -930,7 +930,7 @@ msgstr "<a href=\"%(user_path)s\">%(username)s</a> įvertino <a href=\"%(book_pa
#: bookwyrm/templates/discover/card-header.html:27 #: bookwyrm/templates/discover/card-header.html:27
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> reviewed <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> reviewed <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "<a href=\"%(user_path)s\">%(username)s</a> peržiūrėjo <a href=\"%(book_path)s\">%(book_title)s</a>" msgstr "<a href=\"%(user_path)s\">%(username)s</a> apžvelgė <a href=\"%(book_path)s\">%(book_title)s</a>"
#: bookwyrm/templates/discover/card-header.html:31 #: bookwyrm/templates/discover/card-header.html:31
#, python-format #, python-format
@ -1114,7 +1114,7 @@ msgstr "Šiuo metu skaitoma"
#: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12 #: bookwyrm/templates/snippets/shelve_button/shelve_button_options.html:12
#: bookwyrm/templates/user/books_header.html:8 #: bookwyrm/templates/user/books_header.html:8
msgid "Read" msgid "Read"
msgstr "Perskaičiau" msgstr "Perskaityta"
#: bookwyrm/templates/feed/suggested_users.html:5 #: bookwyrm/templates/feed/suggested_users.html:5
#: bookwyrm/templates/get_started/users.html:6 #: bookwyrm/templates/get_started/users.html:6
@ -1410,11 +1410,11 @@ msgstr "Importavimo būsena"
#: bookwyrm/templates/import/import_status.html:13 #: bookwyrm/templates/import/import_status.html:13
#: bookwyrm/templates/import/import_status.html:27 #: bookwyrm/templates/import/import_status.html:27
msgid "Retry Status" msgid "Retry Status"
msgstr "" msgstr "Pakartojimo būsena"
#: bookwyrm/templates/import/import_status.html:22 #: bookwyrm/templates/import/import_status.html:22
msgid "Imports" msgid "Imports"
msgstr "" msgstr "Importai"
#: bookwyrm/templates/import/import_status.html:39 #: bookwyrm/templates/import/import_status.html:39
msgid "Import started:" msgid "Import started:"
@ -1422,38 +1422,38 @@ msgstr "Importavimas prasidėjo:"
#: bookwyrm/templates/import/import_status.html:48 #: bookwyrm/templates/import/import_status.html:48
msgid "In progress" msgid "In progress"
msgstr "" msgstr "Vykdoma"
#: bookwyrm/templates/import/import_status.html:50 #: bookwyrm/templates/import/import_status.html:50
msgid "Refresh" msgid "Refresh"
msgstr "" msgstr "Atnaujinti"
#: bookwyrm/templates/import/import_status.html:71 #: bookwyrm/templates/import/import_status.html:71
#, python-format #, python-format
msgid "%(display_counter)s item needs manual approval." msgid "%(display_counter)s item needs manual approval."
msgid_plural "%(display_counter)s items need manual approval." msgid_plural "%(display_counter)s items need manual approval."
msgstr[0] "" msgstr[0] "%(display_counter)s reikia manualaus patvirtinimo."
msgstr[1] "" msgstr[1] "%(display_counter)s reikia manualaus patvirtinimo."
msgstr[2] "" msgstr[2] "%(display_counter)s reikia manualaus patvirtinimo."
msgstr[3] "" msgstr[3] "%(display_counter)s reikia manualaus patvirtinimo."
#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/import_status.html:76
#: bookwyrm/templates/import/manual_review.html:8 #: bookwyrm/templates/import/manual_review.html:8
msgid "Review items" msgid "Review items"
msgstr "" msgstr "Peržiūrėti elementus"
#: bookwyrm/templates/import/import_status.html:82 #: bookwyrm/templates/import/import_status.html:82
#, python-format #, python-format
msgid "%(display_counter)s item failed to import." msgid "%(display_counter)s item failed to import."
msgid_plural "%(display_counter)s items failed to import." msgid_plural "%(display_counter)s items failed to import."
msgstr[0] "" msgstr[0] "%(display_counter)s nepavyko importuoti."
msgstr[1] "" msgstr[1] "%(display_counter)s nepavyko importuoti."
msgstr[2] "" msgstr[2] "%(display_counter)s nepavyko importuoti."
msgstr[3] "" msgstr[3] "%(display_counter)s nepavyko importuoti."
#: bookwyrm/templates/import/import_status.html:88 #: bookwyrm/templates/import/import_status.html:88
msgid "View and troubleshoot failed items" msgid "View and troubleshoot failed items"
msgstr "" msgstr "Žiūrėkite ir taisykite nepavykusius elementus"
#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/import/import_status.html:100
msgid "Row" msgid "Row"
@ -1477,13 +1477,13 @@ msgstr "Autorius"
#: bookwyrm/templates/import/import_status.html:112 #: bookwyrm/templates/import/import_status.html:112
msgid "Shelf" msgid "Shelf"
msgstr "" msgstr "Lentyna"
#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/import_status.html:115
#: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/import/manual_review.html:13
#: bookwyrm/templates/snippets/create_status.html:17 #: bookwyrm/templates/snippets/create_status.html:17
msgid "Review" msgid "Review"
msgstr "Peržiūra" msgstr "Apžvalga"
#: bookwyrm/templates/import/import_status.html:119 #: bookwyrm/templates/import/import_status.html:119
msgid "Book" msgid "Book"
@ -1501,11 +1501,11 @@ msgstr "Būsena"
#: bookwyrm/templates/import/import_status.html:130 #: bookwyrm/templates/import/import_status.html:130
msgid "Import preview unavailable." msgid "Import preview unavailable."
msgstr "" msgstr "Nepavyko įkelti peržiūros."
#: bookwyrm/templates/import/import_status.html:162 #: bookwyrm/templates/import/import_status.html:162
msgid "View imported review" msgid "View imported review"
msgstr "" msgstr "Peržiūrėti įkeltą atsiliepimą"
#: bookwyrm/templates/import/import_status.html:176 #: bookwyrm/templates/import/import_status.html:176
msgid "Imported" msgid "Imported"
@ -1513,28 +1513,28 @@ msgstr "Importuota"
#: bookwyrm/templates/import/import_status.html:182 #: bookwyrm/templates/import/import_status.html:182
msgid "Needs manual review" msgid "Needs manual review"
msgstr "" msgstr "Reikalinga peržvelgti"
#: bookwyrm/templates/import/import_status.html:195 #: bookwyrm/templates/import/import_status.html:195
msgid "Retry" msgid "Retry"
msgstr "" msgstr "Bandyti dar kartą"
#: bookwyrm/templates/import/import_status.html:213 #: bookwyrm/templates/import/import_status.html:213
msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format." msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format."
msgstr "" msgstr "Tai seno formato importas, kuris nebepalaikomas. Jei norite matyti importo metu praleistus elementus, spustelėkite žemiau esantį mygtuką ir atnaujinkite importavimo formatą."
#: bookwyrm/templates/import/import_status.html:215 #: bookwyrm/templates/import/import_status.html:215
msgid "Update import" msgid "Update import"
msgstr "" msgstr "Atnaujinti importą"
#: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/manual_review.html:5
#: bookwyrm/templates/import/troubleshoot.html:4 #: bookwyrm/templates/import/troubleshoot.html:4
msgid "Import Troubleshooting" msgid "Import Troubleshooting"
msgstr "" msgstr "Importo problemų sprendimas"
#: bookwyrm/templates/import/manual_review.html:21 #: bookwyrm/templates/import/manual_review.html:21
msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book." msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book."
msgstr "" msgstr "Jei patvirtinsite siūlymą, siūloma knyga visam laikui bus įkelta į Jūsų lentyną, susieta su skaitymo datomis, atsiliepimais ir knygos reitingais."
#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/import/manual_review.html:58
#: bookwyrm/templates/lists/curate.html:57 #: bookwyrm/templates/lists/curate.html:57
@ -1551,31 +1551,31 @@ msgstr "Galite atsisiųsti savo „Goodreads“ duomenis iš <a href=\"https://w
#: bookwyrm/templates/import/troubleshoot.html:7 #: bookwyrm/templates/import/troubleshoot.html:7
msgid "Failed items" msgid "Failed items"
msgstr "" msgstr "Nepavykę elementai"
#: bookwyrm/templates/import/troubleshoot.html:12 #: bookwyrm/templates/import/troubleshoot.html:12
msgid "Troubleshooting" msgid "Troubleshooting"
msgstr "" msgstr "Problemų sprendimas"
#: bookwyrm/templates/import/troubleshoot.html:20 #: bookwyrm/templates/import/troubleshoot.html:20
msgid "Re-trying an import can fix missing items in cases such as:" msgid "Re-trying an import can fix missing items in cases such as:"
msgstr "" msgstr "Bandymas įkelti dar kartą gali sumaišyti trūkstamus elementus šiais atvejais:"
#: bookwyrm/templates/import/troubleshoot.html:23 #: bookwyrm/templates/import/troubleshoot.html:23
msgid "The book has been added to the instance since this import" msgid "The book has been added to the instance since this import"
msgstr "" msgstr "Importo metu knyga jau buvo pridėta"
#: bookwyrm/templates/import/troubleshoot.html:24 #: bookwyrm/templates/import/troubleshoot.html:24
msgid "A transient error or timeout caused the external data source to be unavailable." msgid "A transient error or timeout caused the external data source to be unavailable."
msgstr "" msgstr "Dėl klaidos arba pasibaigusio laiko išoriniai duomenų šaltiniai tapo nepasiekiami."
#: bookwyrm/templates/import/troubleshoot.html:25 #: bookwyrm/templates/import/troubleshoot.html:25
msgid "BookWyrm has been updated since this import with a bug fix" msgid "BookWyrm has been updated since this import with a bug fix"
msgstr "" msgstr "Nuo importo datos „BookWyrm“ atnaujinto programinę įrangą ir ištaisė klaidą"
#: bookwyrm/templates/import/troubleshoot.html:28 #: bookwyrm/templates/import/troubleshoot.html:28
msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items." msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items."
msgstr "" msgstr "Jei matote netikėtų nesklandumų, susisiekite su administratoriumi arba <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>registruokite problemą</a>."
#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230
#, python-format #, python-format
@ -2416,7 +2416,7 @@ msgstr[3] "%(display_count)s prašymai pakviesti"
#: bookwyrm/templates/settings/dashboard/dashboard.html:65 #: bookwyrm/templates/settings/dashboard/dashboard.html:65
msgid "Instance Activity" msgid "Instance Activity"
msgstr "Pavyzdinė veikla" msgstr "Serverio statistika"
#: bookwyrm/templates/settings/dashboard/dashboard.html:83 #: bookwyrm/templates/settings/dashboard/dashboard.html:83
msgid "Interval:" msgid "Interval:"
@ -2436,7 +2436,7 @@ msgstr "Naudotojo prisijungimo veikla"
#: bookwyrm/templates/settings/dashboard/dashboard.html:112 #: bookwyrm/templates/settings/dashboard/dashboard.html:112
msgid "Status activity" msgid "Status activity"
msgstr "Būsenos veikla" msgstr "Būsenos"
#: bookwyrm/templates/settings/dashboard/dashboard.html:118 #: bookwyrm/templates/settings/dashboard/dashboard.html:118
msgid "Works created" msgid "Works created"
@ -3467,7 +3467,7 @@ msgstr "%(percent)s%% baigta!"
#: bookwyrm/templates/snippets/goal_progress.html:12 #: bookwyrm/templates/snippets/goal_progress.html:12
#, python-format #, python-format
msgid "You've read <a href=\"%(path)s\">%(read_count)s of %(goal_count)s books</a>." msgid "You've read <a href=\"%(path)s\">%(read_count)s of %(goal_count)s books</a>."
msgstr "Perskaitėte <a href=\"%(path)s\">%(read_count)s iš %(goal_count)s knygų</a>." msgstr "Perskaityta <a href=\"%(path)s\">%(read_count)s iš %(goal_count)s knygų</a>."
#: bookwyrm/templates/snippets/goal_progress.html:14 #: bookwyrm/templates/snippets/goal_progress.html:14
#, python-format #, python-format
@ -3504,7 +3504,7 @@ msgstr "Viešas"
#: bookwyrm/templates/snippets/privacy_select.html:14 #: bookwyrm/templates/snippets/privacy_select.html:14
#: bookwyrm/templates/snippets/privacy_select_no_followers.html:14 #: bookwyrm/templates/snippets/privacy_select_no_followers.html:14
msgid "Unlisted" msgid "Unlisted"
msgstr "Nėra sąraše" msgstr "Slaptas"
#: bookwyrm/templates/snippets/privacy-icons.html:12 #: bookwyrm/templates/snippets/privacy-icons.html:12
msgid "Followers-only" msgid "Followers-only"
@ -3666,7 +3666,7 @@ msgstr "pacitavo <a href=\"%(book_path)s\">%(book)s</a>"
#: bookwyrm/templates/snippets/status/headers/rating.html:3 #: bookwyrm/templates/snippets/status/headers/rating.html:3
#, python-format #, python-format
msgid "rated <a href=\"%(book_path)s\">%(book)s</a>:" msgid "rated <a href=\"%(book_path)s\">%(book)s</a>:"
msgstr "įvertinta <a href=\"%(book_path)s\">%(book)s</a>:" msgstr "įvertino <a href=\"%(book_path)s\">%(book)s</a>:"
#: bookwyrm/templates/snippets/status/headers/read.html:7 #: bookwyrm/templates/snippets/status/headers/read.html:7
#, python-format #, python-format
@ -3846,7 +3846,7 @@ msgstr "Įrašų dar nėra"
#: bookwyrm/templates/user/user_preview.html:22 #: bookwyrm/templates/user/user_preview.html:22
#, python-format #, python-format
msgid "Joined %(date)s" msgid "Joined %(date)s"
msgstr "Joined %(date)s" msgstr "Prisijungė %(date)s"
#: bookwyrm/templates/user/user_preview.html:26 #: bookwyrm/templates/user/user_preview.html:26
#, python-format #, python-format
@ -3873,7 +3873,7 @@ msgstr[3] "%(mutuals_display)s sekėjai, kuriuos sekate jūs"
#: bookwyrm/templates/user/user_preview.html:38 #: bookwyrm/templates/user/user_preview.html:38
msgid "No followers you follow" msgid "No followers you follow"
msgstr "Jūs nieko nesekate" msgstr "Jūs kartu nieko nesekate"
#: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28 #: bookwyrm/templates/widgets/clearable_file_input_with_warning.html:28
msgid "File exceeds maximum size: 10MB" msgid "File exceeds maximum size: 10MB"

Binary file not shown.

View File

@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: bookwyrm\n" "Project-Id-Version: bookwyrm\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-11-17 18:03+0000\n" "POT-Creation-Date: 2021-11-17 18:03+0000\n"
"PO-Revision-Date: 2021-11-17 18:42\n" "PO-Revision-Date: 2021-11-29 09:31\n"
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n" "Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
"Language-Team: Chinese Simplified\n" "Language-Team: Chinese Simplified\n"
"Language: zh\n" "Language: zh\n"
@ -184,7 +184,7 @@ msgstr "Español西班牙语"
#: bookwyrm/settings.py:168 #: bookwyrm/settings.py:168
msgid "Galego (Galician)" msgid "Galego (Galician)"
msgstr "" msgstr "Galego加利西亚语"
#: bookwyrm/settings.py:169 #: bookwyrm/settings.py:169
msgid "Français (French)" msgid "Français (French)"
@ -192,11 +192,11 @@ msgstr "Français法语"
#: bookwyrm/settings.py:170 #: bookwyrm/settings.py:170
msgid "Lietuvių (Lithuanian)" msgid "Lietuvių (Lithuanian)"
msgstr "" msgstr "Lietuvių立陶宛语"
#: bookwyrm/settings.py:171 #: bookwyrm/settings.py:171
msgid "Português - Brasil (Brazilian Portuguese)" msgid "Português - Brasil (Brazilian Portuguese)"
msgstr "葡萄牙语-巴西(巴西的葡语)" msgstr "Português - Brasil巴西葡萄牙语)"
#: bookwyrm/settings.py:172 #: bookwyrm/settings.py:172
msgid "简体中文 (Simplified Chinese)" msgid "简体中文 (Simplified Chinese)"
@ -906,12 +906,12 @@ msgstr "<a href=\"%(user_path)s\">%(username)s</a> 想要阅读 <a href=\"%(book
#: bookwyrm/templates/discover/card-header.html:13 #: bookwyrm/templates/discover/card-header.html:13
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> finished reading <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> finished reading <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> 完成了 <a href=\"%(book_path)s\">%(book_title)s</a> 的阅读"
#: bookwyrm/templates/discover/card-header.html:18 #: bookwyrm/templates/discover/card-header.html:18
#, python-format #, python-format
msgid "<a href=\"%(user_path)s\">%(username)s</a> started reading <a href=\"%(book_path)s\">%(book_title)s</a>" msgid "<a href=\"%(user_path)s\">%(username)s</a> started reading <a href=\"%(book_path)s\">%(book_title)s</a>"
msgstr "" msgstr "<a href=\"%(user_path)s\">%(username)s</a> 开始阅读 <a href=\"%(book_path)s\">%(book_title)s</a>"
#: bookwyrm/templates/discover/card-header.html:23 #: bookwyrm/templates/discover/card-header.html:23
#, python-format #, python-format
@ -1395,11 +1395,11 @@ msgstr "导入状态"
#: bookwyrm/templates/import/import_status.html:13 #: bookwyrm/templates/import/import_status.html:13
#: bookwyrm/templates/import/import_status.html:27 #: bookwyrm/templates/import/import_status.html:27
msgid "Retry Status" msgid "Retry Status"
msgstr "" msgstr "重试状态"
#: bookwyrm/templates/import/import_status.html:22 #: bookwyrm/templates/import/import_status.html:22
msgid "Imports" msgid "Imports"
msgstr "" msgstr "导入"
#: bookwyrm/templates/import/import_status.html:39 #: bookwyrm/templates/import/import_status.html:39
msgid "Import started:" msgid "Import started:"
@ -1407,36 +1407,36 @@ msgstr "导入开始:"
#: bookwyrm/templates/import/import_status.html:48 #: bookwyrm/templates/import/import_status.html:48
msgid "In progress" msgid "In progress"
msgstr "" msgstr "正在进行"
#: bookwyrm/templates/import/import_status.html:50 #: bookwyrm/templates/import/import_status.html:50
msgid "Refresh" msgid "Refresh"
msgstr "" msgstr "刷新"
#: bookwyrm/templates/import/import_status.html:71 #: bookwyrm/templates/import/import_status.html:71
#, python-format #, python-format
msgid "%(display_counter)s item needs manual approval." msgid "%(display_counter)s item needs manual approval."
msgid_plural "%(display_counter)s items need manual approval." msgid_plural "%(display_counter)s items need manual approval."
msgstr[0] "" msgstr[0] "%(display_counter)s 项需要手动批准。"
#: bookwyrm/templates/import/import_status.html:76 #: bookwyrm/templates/import/import_status.html:76
#: bookwyrm/templates/import/manual_review.html:8 #: bookwyrm/templates/import/manual_review.html:8
msgid "Review items" msgid "Review items"
msgstr "" msgstr "审阅项目"
#: bookwyrm/templates/import/import_status.html:82 #: bookwyrm/templates/import/import_status.html:82
#, python-format #, python-format
msgid "%(display_counter)s item failed to import." msgid "%(display_counter)s item failed to import."
msgid_plural "%(display_counter)s items failed to import." msgid_plural "%(display_counter)s items failed to import."
msgstr[0] "" msgstr[0] "%(display_counter)s 项导入失败。"
#: bookwyrm/templates/import/import_status.html:88 #: bookwyrm/templates/import/import_status.html:88
msgid "View and troubleshoot failed items" msgid "View and troubleshoot failed items"
msgstr "" msgstr "查看并排查失败项目"
#: bookwyrm/templates/import/import_status.html:100 #: bookwyrm/templates/import/import_status.html:100
msgid "Row" msgid "Row"
msgstr "" msgstr ""
#: bookwyrm/templates/import/import_status.html:103 #: bookwyrm/templates/import/import_status.html:103
#: bookwyrm/templates/shelf/shelf.html:141 #: bookwyrm/templates/shelf/shelf.html:141
@ -1446,7 +1446,7 @@ msgstr "标题"
#: bookwyrm/templates/import/import_status.html:106 #: bookwyrm/templates/import/import_status.html:106
msgid "ISBN" msgid "ISBN"
msgstr "" msgstr "ISBN"
#: bookwyrm/templates/import/import_status.html:109 #: bookwyrm/templates/import/import_status.html:109
#: bookwyrm/templates/shelf/shelf.html:142 #: bookwyrm/templates/shelf/shelf.html:142
@ -1456,7 +1456,7 @@ msgstr "作者"
#: bookwyrm/templates/import/import_status.html:112 #: bookwyrm/templates/import/import_status.html:112
msgid "Shelf" msgid "Shelf"
msgstr "" msgstr "书架"
#: bookwyrm/templates/import/import_status.html:115 #: bookwyrm/templates/import/import_status.html:115
#: bookwyrm/templates/import/manual_review.html:13 #: bookwyrm/templates/import/manual_review.html:13
@ -1480,11 +1480,11 @@ msgstr "状态"
#: bookwyrm/templates/import/import_status.html:130 #: bookwyrm/templates/import/import_status.html:130
msgid "Import preview unavailable." msgid "Import preview unavailable."
msgstr "" msgstr "导入预览不可用。"
#: bookwyrm/templates/import/import_status.html:162 #: bookwyrm/templates/import/import_status.html:162
msgid "View imported review" msgid "View imported review"
msgstr "" msgstr "查看已导入的书评"
#: bookwyrm/templates/import/import_status.html:176 #: bookwyrm/templates/import/import_status.html:176
msgid "Imported" msgid "Imported"
@ -1492,28 +1492,28 @@ msgstr "已导入"
#: bookwyrm/templates/import/import_status.html:182 #: bookwyrm/templates/import/import_status.html:182
msgid "Needs manual review" msgid "Needs manual review"
msgstr "" msgstr "需要手动批准"
#: bookwyrm/templates/import/import_status.html:195 #: bookwyrm/templates/import/import_status.html:195
msgid "Retry" msgid "Retry"
msgstr "" msgstr "重试"
#: bookwyrm/templates/import/import_status.html:213 #: bookwyrm/templates/import/import_status.html:213
msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format." msgid "This import is in an old format that is no longer supported. If you would like to troubleshoot missing items from this import, click the button below to update the import format."
msgstr "" msgstr "此导入所用格式已不再受支持。 如果您想要在此次导入中排查缺失的项目,请点击下面的按钮来更新导入格式。"
#: bookwyrm/templates/import/import_status.html:215 #: bookwyrm/templates/import/import_status.html:215
msgid "Update import" msgid "Update import"
msgstr "" msgstr "更新导入"
#: bookwyrm/templates/import/manual_review.html:5 #: bookwyrm/templates/import/manual_review.html:5
#: bookwyrm/templates/import/troubleshoot.html:4 #: bookwyrm/templates/import/troubleshoot.html:4
msgid "Import Troubleshooting" msgid "Import Troubleshooting"
msgstr "" msgstr "导入排查"
#: bookwyrm/templates/import/manual_review.html:21 #: bookwyrm/templates/import/manual_review.html:21
msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book." msgid "Approving a suggestion will permanently add the suggested book to your shelves and associate your reading dates, reviews, and ratings with that book."
msgstr "" msgstr "批准建议后,被提议的书将会永久添加到您的书架上并与您的阅读日期、书评、评分联系起来。"
#: bookwyrm/templates/import/manual_review.html:58 #: bookwyrm/templates/import/manual_review.html:58
#: bookwyrm/templates/lists/curate.html:57 #: bookwyrm/templates/lists/curate.html:57
@ -1522,7 +1522,7 @@ msgstr "批准"
#: bookwyrm/templates/import/manual_review.html:66 #: bookwyrm/templates/import/manual_review.html:66
msgid "Reject" msgid "Reject"
msgstr "" msgstr "驳回"
#: bookwyrm/templates/import/tooltip.html:6 #: bookwyrm/templates/import/tooltip.html:6
msgid "You can download your Goodreads data from the <a href=\"https://www.goodreads.com/review/import\" target=\"_blank\" rel=\"noopener\">Import/Export page</a> of your Goodreads account." msgid "You can download your Goodreads data from the <a href=\"https://www.goodreads.com/review/import\" target=\"_blank\" rel=\"noopener\">Import/Export page</a> of your Goodreads account."
@ -1530,31 +1530,31 @@ msgstr "您可以从 <a href=\"https://www.goodreads.com/review/import\" target=
#: bookwyrm/templates/import/troubleshoot.html:7 #: bookwyrm/templates/import/troubleshoot.html:7
msgid "Failed items" msgid "Failed items"
msgstr "" msgstr "失败项目"
#: bookwyrm/templates/import/troubleshoot.html:12 #: bookwyrm/templates/import/troubleshoot.html:12
msgid "Troubleshooting" msgid "Troubleshooting"
msgstr "" msgstr "问题排查"
#: bookwyrm/templates/import/troubleshoot.html:20 #: bookwyrm/templates/import/troubleshoot.html:20
msgid "Re-trying an import can fix missing items in cases such as:" msgid "Re-trying an import can fix missing items in cases such as:"
msgstr "" msgstr "重试导入可以修复以下情况的缺失项目:"
#: bookwyrm/templates/import/troubleshoot.html:23 #: bookwyrm/templates/import/troubleshoot.html:23
msgid "The book has been added to the instance since this import" msgid "The book has been added to the instance since this import"
msgstr "" msgstr "在此次导入后该书已被添加到本实例"
#: bookwyrm/templates/import/troubleshoot.html:24 #: bookwyrm/templates/import/troubleshoot.html:24
msgid "A transient error or timeout caused the external data source to be unavailable." msgid "A transient error or timeout caused the external data source to be unavailable."
msgstr "" msgstr "暂时的错误或超时导致外部数据源不可用。"
#: bookwyrm/templates/import/troubleshoot.html:25 #: bookwyrm/templates/import/troubleshoot.html:25
msgid "BookWyrm has been updated since this import with a bug fix" msgid "BookWyrm has been updated since this import with a bug fix"
msgstr "" msgstr "在此次导入后BookWyrm 已经更新并修复了漏洞"
#: bookwyrm/templates/import/troubleshoot.html:28 #: bookwyrm/templates/import/troubleshoot.html:28
msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items." msgid "Contact your admin or <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>open an issue</a> if you are seeing unexpected failed items."
msgstr "" msgstr "如果您看到意外失败的项目,请联系您的管理员或 <a href='https://github.com/bookwyrm-social/bookwyrm/issues'>发起一个 issue</a>。"
#: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230 #: bookwyrm/templates/landing/about.html:7 bookwyrm/templates/layout.html:230
#, python-format #, python-format

Binary file not shown.

View File

@ -1,7 +1,7 @@
celery==4.4.2 celery==4.4.2
colorthief==0.2.1 colorthief==0.2.1
Django==3.2.5 Django==3.2.5
django-imagekit==4.0.2 django-imagekit==4.1.0
django-model-utils==4.0.0 django-model-utils==4.0.0
environs==9.3.4 environs==9.3.4
flower==0.9.4 flower==0.9.4