Merge branch 'main' into 1203-better-ui-for-adding-authors
This commit is contained in:
commit
e59a480065
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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">
|
||||||
|
|
|
@ -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 %}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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()
|
|
@ -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
|
||||||
|
@ -48,6 +56,8 @@ class EditBook(View):
|
||||||
if add_author:
|
if add_author:
|
||||||
data["add_author"] = add_author
|
data["add_author"] = add_author
|
||||||
data["author_matches"] = []
|
data["author_matches"] = []
|
||||||
|
data["isni_matches"] = []
|
||||||
|
|
||||||
for author in add_author:
|
for author in add_author:
|
||||||
if not author:
|
if not author:
|
||||||
continue
|
continue
|
||||||
|
@ -56,15 +66,35 @@ class EditBook(View):
|
||||||
"aliases", weight="B"
|
"aliases", weight="B"
|
||||||
)
|
)
|
||||||
|
|
||||||
data["author_matches"].append(
|
author_matches = (
|
||||||
{
|
|
||||||
"name": author.strip(),
|
|
||||||
"matches": (
|
|
||||||
models.Author.objects.annotate(search=vector)
|
models.Author.objects.annotate(search=vector)
|
||||||
.annotate(rank=SearchRank(vector, author))
|
.annotate(rank=SearchRank(vector, author))
|
||||||
.filter(rank__gt=0.4)
|
.filter(rank__gt=0.4)
|
||||||
.order_by("-rank")[:5]
|
.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(
|
||||||
|
{
|
||||||
|
"name": author.strip(),
|
||||||
|
"matches": matches,
|
||||||
|
"existing_isnis": exists,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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,8 +179,24 @@ 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
|
||||||
|
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)
|
author = models.Author.objects.create(name=match)
|
||||||
book.authors.add(author)
|
book.authors.add(author)
|
||||||
|
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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.
|
@ -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.
|
@ -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.
|
@ -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-22 08:50\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)"
|
||||||
|
@ -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,7 +1477,7 @@ 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
|
||||||
|
@ -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 "Reikalingas manualus atsiliepimas"
|
||||||
|
|
||||||
#: 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
|
||||||
|
@ -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
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue