mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-12-04 15:26:48 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
c770b369d2
61 changed files with 2609 additions and 302 deletions
|
@ -31,7 +31,7 @@ Code contributions are gladly welcomed! If you're not sure where to start, take
|
|||
If you have questions about the project or contributing, you can set up a video call during BookWyrm ["office hours"](https://calendly.com/mouse-reeve/30min).
|
||||
|
||||
### Translation
|
||||
Do you speak a language besides English? BookWyrm needs localization! If you're comfortable using git and want to get into the code, there are [instructions](#workin-with-translations-and-locale-files) on how to create and edit localization files. If you feel more comfortable working in a regular text editor and would prefer not to run the application, get in touch directly and we can figure out a system, like emailing a text file, that works best.
|
||||
Do you speak a language besides English? BookWyrm needs localization! If you're comfortable using git and want to get into the code, there are [instructions](#working-with-translations-and-locale-files) on how to create and edit localization files. If you feel more comfortable working in a regular text editor and would prefer not to run the application, get in touch directly and we can figure out a system, like emailing a text file, that works best.
|
||||
|
||||
### Financial Support
|
||||
BookWyrm is an ad-free passion project with no intentions of seeking out venture funding or corporate financial relationships. If you want to help keep the project going, you can donate to the [Patreon](https://www.patreon.com/bookwyrm), or make a one time gift via [PayPal](https://paypal.me/oulipo).
|
||||
|
@ -118,7 +118,7 @@ If you edit the CSS or JavaScript, you will need to run Django's `collectstatic`
|
|||
./bw-dev collectstatic
|
||||
```
|
||||
|
||||
### Workin with translations and locale files
|
||||
### Working with translations and locale files
|
||||
Text in the html files are wrapped in translation tags (`{% trans %}` and `{% blocktrans %}`), and Django generates locale files for all the strings in which you can add translations for the text. You can find existing translations in the `locale/` directory.
|
||||
|
||||
The application's language is set by a request header sent by your browser to the application, so to change the language of the application, you can change the default language requested by your browser.
|
||||
|
@ -132,7 +132,10 @@ To start translation into a language which is currently supported, run the djang
|
|||
#### Editing a locale
|
||||
When you have a locale file, open the `django.po` in the directory for the language (for example, if you were adding German, `locale/de/LC_MESSAGES/django.po`. All the the text in the application will be shown in paired strings, with `msgid` as the original text, and `msgstr` as the translation (by default, this is set to an empty string, and will display the original text).
|
||||
|
||||
Add you translations to the `msgstr` strings, and when you're ready, compile the locale by running:
|
||||
Add your translations to the `msgstr` strings. As the messages in the application are updated, `gettext` will sometimes add best-guess fuzzy matched options for those translations. When a message is marked as fuzzy, it will not be used in the application, so be sure to remove it when you translate that line.
|
||||
|
||||
When you're done, compile the locale by running:
|
||||
|
||||
``` bash
|
||||
./bw-dev compilemessages
|
||||
```
|
||||
|
|
|
@ -26,7 +26,7 @@ class Book(ActivityObject):
|
|||
librarythingKey: str = ''
|
||||
goodreadsKey: str = ''
|
||||
|
||||
cover: Image = field(default_factory=lambda: {})
|
||||
cover: Image = None
|
||||
type: str = 'Book'
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ class AbstractMinimalConnector(ABC):
|
|||
'books_url',
|
||||
'covers_url',
|
||||
'search_url',
|
||||
'isbn_search_url',
|
||||
'max_query_count',
|
||||
'name',
|
||||
'identifier',
|
||||
|
@ -61,6 +62,30 @@ class AbstractMinimalConnector(ABC):
|
|||
results.append(self.format_search_result(doc))
|
||||
return results
|
||||
|
||||
def isbn_search(self, query):
|
||||
''' isbn search '''
|
||||
params = {}
|
||||
resp = requests.get(
|
||||
'%s%s' % (self.isbn_search_url, query),
|
||||
params=params,
|
||||
headers={
|
||||
'Accept': 'application/json; charset=utf-8',
|
||||
'User-Agent': settings.USER_AGENT,
|
||||
},
|
||||
)
|
||||
if not resp.ok:
|
||||
resp.raise_for_status()
|
||||
try:
|
||||
data = resp.json()
|
||||
except ValueError as e:
|
||||
logger.exception(e)
|
||||
raise ConnectorException('Unable to parse json response', e)
|
||||
results = []
|
||||
|
||||
for doc in self.parse_isbn_search_data(data):
|
||||
results.append(self.format_isbn_search_result(doc))
|
||||
return results
|
||||
|
||||
@abstractmethod
|
||||
def get_or_create_book(self, remote_id):
|
||||
''' pull up a book record by whatever means possible '''
|
||||
|
@ -73,6 +98,14 @@ class AbstractMinimalConnector(ABC):
|
|||
def format_search_result(self, search_result):
|
||||
''' create a SearchResult obj from json '''
|
||||
|
||||
@abstractmethod
|
||||
def parse_isbn_search_data(self, data):
|
||||
''' turn the result json from a search into a list '''
|
||||
|
||||
@abstractmethod
|
||||
def format_isbn_search_result(self, search_result):
|
||||
''' create a SearchResult obj from json '''
|
||||
|
||||
|
||||
class AbstractConnector(AbstractMinimalConnector):
|
||||
''' generic book data connector '''
|
||||
|
|
|
@ -19,3 +19,11 @@ class Connector(AbstractMinimalConnector):
|
|||
def format_search_result(self, search_result):
|
||||
search_result['connector'] = self
|
||||
return SearchResult(**search_result)
|
||||
|
||||
def parse_isbn_search_data(self, data):
|
||||
return data
|
||||
|
||||
def format_isbn_search_result(self, search_result):
|
||||
search_result['connector'] = self
|
||||
return SearchResult(**search_result)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
''' interface with whatever connectors the app has '''
|
||||
import importlib
|
||||
import re
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from requests import HTTPError
|
||||
|
@ -15,9 +16,27 @@ class ConnectorException(HTTPError):
|
|||
def search(query, min_confidence=0.1):
|
||||
''' find books based on arbitary keywords '''
|
||||
results = []
|
||||
|
||||
# Have we got a ISBN ?
|
||||
isbn = re.sub('[\W_]', '', query)
|
||||
maybe_isbn = len(isbn) in [10, 13] # ISBN10 or ISBN13
|
||||
|
||||
dedup_slug = lambda r: '%s/%s/%s' % (r.title, r.author, r.year)
|
||||
result_index = set()
|
||||
for connector in get_connectors():
|
||||
result_set = None
|
||||
if maybe_isbn:
|
||||
# Search on ISBN
|
||||
if not connector.isbn_search_url or connector.isbn_search_url == '':
|
||||
result_set = []
|
||||
else:
|
||||
try:
|
||||
result_set = connector.isbn_search(isbn)
|
||||
except (HTTPError, ConnectorException):
|
||||
pass
|
||||
|
||||
# if no isbn search or results, we fallback to generic search
|
||||
if result_set == None or result_set == []:
|
||||
try:
|
||||
result_set = connector.search(query, min_confidence=min_confidence)
|
||||
except (HTTPError, ConnectorException):
|
||||
|
@ -41,6 +60,12 @@ def local_search(query, min_confidence=0.1, raw=False):
|
|||
return connector.search(query, min_confidence=min_confidence, raw=raw)
|
||||
|
||||
|
||||
def isbn_local_search(query, raw=False):
|
||||
''' only look at local search results '''
|
||||
connector = load_connector(models.Connector.objects.get(local=True))
|
||||
return connector.isbn_search(query, raw=raw)
|
||||
|
||||
|
||||
def first_search_result(query, min_confidence=0.1):
|
||||
''' search until you find a result that fits '''
|
||||
for connector in get_connectors():
|
||||
|
|
|
@ -129,6 +129,22 @@ class Connector(AbstractConnector):
|
|||
)
|
||||
|
||||
|
||||
def parse_isbn_search_data(self, data):
|
||||
return list(data.values())
|
||||
|
||||
def format_isbn_search_result(self, search_result):
|
||||
# build the remote id from the openlibrary key
|
||||
key = self.books_url + search_result['key']
|
||||
authors = search_result.get('authors') or [{'name': 'Unknown'}]
|
||||
author_names = [ author.get('name') for author in authors]
|
||||
return SearchResult(
|
||||
title=search_result.get('title'),
|
||||
key=key,
|
||||
author=', '.join(author_names),
|
||||
connector=self,
|
||||
year=search_result.get('publish_date'),
|
||||
)
|
||||
|
||||
def load_edition_data(self, olkey):
|
||||
''' query openlibrary for editions of a work '''
|
||||
url = '%s/works/%s/editions' % (self.books_url, olkey)
|
||||
|
|
|
@ -33,6 +33,31 @@ class Connector(AbstractConnector):
|
|||
search_results.sort(key=lambda r: r.confidence, reverse=True)
|
||||
return search_results
|
||||
|
||||
def isbn_search(self, query, raw=False):
|
||||
''' search your local database '''
|
||||
if not query:
|
||||
return []
|
||||
|
||||
filters = [{f: query} for f in ['isbn_10', 'isbn_13']]
|
||||
results = models.Edition.objects.filter(
|
||||
reduce(operator.or_, (Q(**f) for f in filters))
|
||||
).distinct()
|
||||
|
||||
# when there are multiple editions of the same work, pick the default.
|
||||
# it would be odd for this to happen.
|
||||
results = results.filter(parent_work__default_edition__id=F('id')) \
|
||||
or results
|
||||
|
||||
search_results = []
|
||||
for result in results:
|
||||
if raw:
|
||||
search_results.append(result)
|
||||
else:
|
||||
search_results.append(self.format_search_result(result))
|
||||
if len(search_results) >= 10:
|
||||
break
|
||||
return search_results
|
||||
|
||||
|
||||
def format_search_result(self, search_result):
|
||||
return SearchResult(
|
||||
|
@ -47,6 +72,19 @@ class Connector(AbstractConnector):
|
|||
)
|
||||
|
||||
|
||||
def format_isbn_search_result(self, search_result):
|
||||
return SearchResult(
|
||||
title=search_result.title,
|
||||
key=search_result.remote_id,
|
||||
author=search_result.author_text,
|
||||
year=search_result.published_date.year if \
|
||||
search_result.published_date else None,
|
||||
connector=self,
|
||||
confidence=search_result.rank if \
|
||||
hasattr(search_result, 'rank') else 1,
|
||||
)
|
||||
|
||||
|
||||
def is_work_data(self, data):
|
||||
pass
|
||||
|
||||
|
@ -59,6 +97,10 @@ class Connector(AbstractConnector):
|
|||
def get_authors_from_data(self, data):
|
||||
return None
|
||||
|
||||
def parse_isbn_search_data(self, data):
|
||||
''' it's already in the right format, don't even worry about it '''
|
||||
return data
|
||||
|
||||
def parse_search_data(self, data):
|
||||
''' it's already in the right format, don't even worry about it '''
|
||||
return data
|
||||
|
|
|
@ -66,6 +66,7 @@ def init_connectors():
|
|||
books_url='https://%s/book' % DOMAIN,
|
||||
covers_url='https://%s/images/covers' % DOMAIN,
|
||||
search_url='https://%s/search?q=' % DOMAIN,
|
||||
isbn_search_url='https://%s/isbn/' % DOMAIN,
|
||||
priority=1,
|
||||
)
|
||||
|
||||
|
@ -77,6 +78,7 @@ def init_connectors():
|
|||
books_url='https://bookwyrm.social/book',
|
||||
covers_url='https://bookwyrm.social/images/covers',
|
||||
search_url='https://bookwyrm.social/search?q=',
|
||||
isbn_search_url='https://bookwyrm.social/isbn/',
|
||||
priority=2,
|
||||
)
|
||||
|
||||
|
@ -88,6 +90,7 @@ def init_connectors():
|
|||
books_url='https://openlibrary.org',
|
||||
covers_url='https://covers.openlibrary.org',
|
||||
search_url='https://openlibrary.org/search?q=',
|
||||
isbn_search_url='https://openlibrary.org/api/books?jscmd=data&format=json&bibkeys=ISBN:',
|
||||
priority=3,
|
||||
)
|
||||
|
||||
|
|
18
bookwyrm/migrations/0047_connector_isbn_search_url.py
Normal file
18
bookwyrm/migrations/0047_connector_isbn_search_url.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 3.0.7 on 2021-02-28 16:41
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('bookwyrm', '0046_sitesettings_privacy_policy'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='connector',
|
||||
name='isbn_search_url',
|
||||
field=models.CharField(blank=True, max_length=255, null=True),
|
||||
),
|
||||
]
|
|
@ -91,7 +91,7 @@ class Book(BookDataModel):
|
|||
@property
|
||||
def alt_text(self):
|
||||
''' image alt test '''
|
||||
text = '%s cover' % self.title
|
||||
text = '%s' % self.title
|
||||
if self.edition_info:
|
||||
text += ' (%s)' % self.edition_info
|
||||
return text
|
||||
|
|
|
@ -22,6 +22,7 @@ class Connector(BookWyrmModel):
|
|||
books_url = models.CharField(max_length=255)
|
||||
covers_url = models.CharField(max_length=255)
|
||||
search_url = models.CharField(max_length=255, null=True, blank=True)
|
||||
isbn_search_url = models.CharField(max_length=255, null=True, blank=True)
|
||||
|
||||
politeness_delay = models.IntegerField(null=True, blank=True) #seconds
|
||||
max_query_count = models.IntegerField(null=True, blank=True)
|
||||
|
|
|
@ -3,7 +3,7 @@ import re
|
|||
from urllib.parse import urlparse
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.auth.models import AbstractUser
|
||||
from django.contrib.auth.models import AbstractUser, Group
|
||||
from django.core.validators import MinValueValidator
|
||||
from django.db import models
|
||||
from django.utils import timezone
|
||||
|
@ -208,6 +208,13 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
|||
# an id needs to be set before we can proceed with related models
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# make users editors by default
|
||||
try:
|
||||
self.groups.add(Group.objects.get(name='editor'))
|
||||
except Group.DoesNotExist:
|
||||
# this should only happen in tests
|
||||
pass
|
||||
|
||||
# create keys and shelves for new local users
|
||||
self.key_pair = KeyPair.objects.create(
|
||||
remote_id='%s/#main-key' % self.remote_id)
|
||||
|
|
|
@ -141,6 +141,7 @@ LANGUAGE_CODE = 'en-us'
|
|||
LANGUAGES = [
|
||||
('en-us', _('English')),
|
||||
('de-de', _('German')),
|
||||
('es', _('Spanish')),
|
||||
('fr-fr', _('French')),
|
||||
('zh-cn', _('Simplified Chinese')),
|
||||
]
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
html {
|
||||
scroll-behavior: smooth;
|
||||
scroll-padding-top: 20%;
|
||||
}
|
||||
|
||||
/* --- --- */
|
||||
.image {
|
||||
overflow: hidden;
|
||||
|
|
|
@ -8,9 +8,12 @@ window.onload = function() {
|
|||
Array.from(document.getElementsByClassName('interaction'))
|
||||
.forEach(t => t.onsubmit = interact);
|
||||
|
||||
// select all
|
||||
Array.from(document.getElementsByClassName('select-all'))
|
||||
.forEach(t => t.onclick = selectAll);
|
||||
// Toggle all checkboxes.
|
||||
document
|
||||
.querySelectorAll('[data-action="toggle-all"]')
|
||||
.forEach(input => {
|
||||
input.addEventListener('change', toggleAllCheckboxes);
|
||||
});
|
||||
|
||||
// tab groups
|
||||
Array.from(document.getElementsByClassName('tab-group'))
|
||||
|
@ -136,9 +139,20 @@ function interact(e) {
|
|||
.forEach(t => addRemoveClass(t, 'hidden', t.className.indexOf('hidden') == -1));
|
||||
}
|
||||
|
||||
function selectAll(e) {
|
||||
e.target.parentElement.parentElement.querySelectorAll('[type="checkbox"]')
|
||||
.forEach(t => t.checked=true);
|
||||
/**
|
||||
* Toggle all descendant checkboxes of a target.
|
||||
*
|
||||
* Use `data-target="ID_OF_TARGET"` on the node being listened to.
|
||||
*
|
||||
* @param {Event} event - change Event
|
||||
* @return {undefined}
|
||||
*/
|
||||
function toggleAllCheckboxes(event) {
|
||||
const mainCheckbox = event.target;
|
||||
|
||||
document
|
||||
.querySelectorAll(`#${mainCheckbox.dataset.target} [type="checkbox"]`)
|
||||
.forEach(checkbox => {checkbox.checked = mainCheckbox.checked;});
|
||||
}
|
||||
|
||||
function toggleMenu(e) {
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
</div>
|
||||
|
||||
<div class="columns">
|
||||
<div class="column is-narrow">
|
||||
<div class="column is-one-fifth">
|
||||
{% include 'snippets/book_cover.html' with book=book size=large %}
|
||||
{% include 'snippets/rate_action.html' with user=request.user book=book %}
|
||||
{% include 'snippets/shelve_button/shelve_button.html' %}
|
||||
|
@ -93,7 +93,7 @@
|
|||
</section>
|
||||
</div>
|
||||
|
||||
<div class="column">
|
||||
<div class="column is-three-fifths">
|
||||
<div class="block">
|
||||
<h3 class="field is-grouped">
|
||||
{% include 'snippets/stars.html' with rating=rating %}
|
||||
|
@ -201,7 +201,7 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<div class="column is-one-fifth">
|
||||
{% if book.subjects %}
|
||||
<section class="content block">
|
||||
<h2 class="title is-5">{% trans "Subjects" %}</h2>
|
||||
|
@ -217,7 +217,7 @@
|
|||
<section class="content block">
|
||||
<h2 class="title is-5">{% trans "Places" %}</h2>
|
||||
<ul>
|
||||
{% for place in book.subject_placess %}
|
||||
{% for place in book.subject_places %}
|
||||
<li>{{ place }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
@ -254,8 +254,8 @@
|
|||
<div>
|
||||
{% include 'snippets/username.html' with user=rating.user %}
|
||||
</div>
|
||||
<div class="field is-grouped mb-0">
|
||||
<div>{% trans "rated it" %}</div>
|
||||
<div class="is-flex">
|
||||
<p class="mr-1">{% trans "rated it" %}</p>
|
||||
{% include 'snippets/stars.html' with rating=rating.rating %}
|
||||
</div>
|
||||
<div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
{% block dropdown-trigger %}{% endblock %}
|
||||
</button>
|
||||
<div class="dropdown-menu">
|
||||
<ul class="dropdown-content" role="menu" id="menu-options-{{ book.id }}">
|
||||
<ul class="dropdown-content" role="menu" id="menu-options-{{ uuid }}">
|
||||
{% block dropdown-list %}{% endblock %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
<div class="modal hidden" id="{{ controls_text }}-{{ controls_uid }}">
|
||||
<div
|
||||
role="dialog"
|
||||
class="modal hidden"
|
||||
id="{{ controls_text }}-{{ controls_uid }}"
|
||||
aria-labelledby="modal-card-title-{{ controls_text }}-{{ controls_uid }}"
|
||||
aria-modal="true"
|
||||
>
|
||||
{# @todo Implement focus traps to prevent tabbing out of the modal. #}
|
||||
<div class="modal-background"></div>
|
||||
<div class="modal-card">
|
||||
<header class="modal-card-head" tabindex="0" id="modal-title-{{ controls_text }}-{{ controls_uid }}">
|
||||
<h2 class="modal-card-title">
|
||||
<h2 class="modal-card-title" id="modal-card-title-{{ controls_text }}-{{ controls_uid }}">
|
||||
{% block modal-title %}{% endblock %}
|
||||
</h2>
|
||||
{% include 'snippets/toggle/toggle_button.html' with label="close" class="delete" nonbutton=True %}
|
||||
|
@ -18,7 +25,6 @@
|
|||
</footer>
|
||||
{% block modal-form-close %}{% endblock %}
|
||||
</div>
|
||||
<label class="modal-close is-large" for="{{ controls_text }}-{{ controls_uid }}" aria-label="close"></label>
|
||||
{% include 'snippets/toggle/toggle_button.html' with label="close" class="modal-close is-large" nonbutton=True %}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -54,11 +54,11 @@
|
|||
<div class="tile is-child box has-background-white-bis">
|
||||
<h2 class="title is-4">{% trans "Your Account" %}</h2>
|
||||
{% include 'user/user_preview.html' with user=request.user %}
|
||||
<div class="box content">
|
||||
{% if request.user.summary %}
|
||||
<div class="box content">
|
||||
{{ request.user.summary | to_markdown | safe }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load i18n %}
|
||||
{% if book %}
|
||||
<div class="columns">
|
||||
<div class="column is-narrow">
|
||||
|
@ -8,7 +9,7 @@
|
|||
<div class="column">
|
||||
<h3 class="title is-5"><a href="/book/{{ book.id }}">{{ book.title }}</a></h3>
|
||||
{% if book.authors %}
|
||||
<p class="subtitle is-5">by {% include 'snippets/authors.html' with book=book %}</p>
|
||||
<p class="subtitle is-5">{% trans "by" %} {% include 'snippets/authors.html' with book=book %}</p>
|
||||
{% endif %}
|
||||
{% if book|book_description %}
|
||||
<blockquote class="content">{{ book|book_description|to_markdown|safe|truncatewords_html:50 }}</blockquote>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load i18n %}
|
||||
{% if book %}
|
||||
<a href="{{ book.local_path }}">{% include 'snippets/book_cover.html' with book=book %}</a>
|
||||
{% include 'snippets/stars.html' with rating=book|rating:request.user %}
|
||||
|
||||
<h3 class="title is-6"><a href="/book/{{ book.id }}">{{ book.title }}</a></h3>
|
||||
{% if book.authors %}
|
||||
<p class="subtitle is-6">by {% include 'snippets/authors.html' with book=book %}</p>
|
||||
<p class="subtitle is-6">{% trans "by" %} {% include 'snippets/authors.html' with book=book %}</p>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<h1 class="title">{% blocktrans %}{{ tab_title }} Timeline{% endblocktrans %}</h1>
|
||||
<div class="tabs">
|
||||
<ul>
|
||||
<li class="{% if tab == 'home' %}is-active{% endif %}">
|
||||
<li class="{% if tab == 'home' %}is-active{% endif %}"{% if tab == 'home' %} aria-current="page"{% endif %}>
|
||||
<a href="/#feed">{% trans "Home" %}</a>
|
||||
</li>
|
||||
<li class="{% if tab == 'local' %}is-active{% endif %}">
|
||||
<li class="{% if tab == 'local' %}is-active{% endif %}"{% if tab == 'local' %} aria-current="page"{% endif %}>
|
||||
<a href="/local#feed">{% trans "Local" %}</a>
|
||||
</li>
|
||||
<li class="{% if tab == 'federated' %}is-active{% endif %}">
|
||||
<li class="{% if tab == 'federated' %}is-active{% endif %}"{% if tab == 'federated' %} aria-current="page"{% endif %}>
|
||||
<a href="/federated#feed">{% trans "Federated" %}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{% block panel %}
|
||||
<header class="block">
|
||||
<a href="/#feed" class="button" data-back>
|
||||
<span class="icon icon-arrow-left" aira-hidden="true"></span>
|
||||
<span class="icon icon-arrow-left" aria-hidden="true"></span>
|
||||
<span>{% trans "Back" %}</span>
|
||||
</a>
|
||||
</header>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
{% block title %}{% trans "Import Status" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% block content %}{% spaceless %}
|
||||
<div class="block">
|
||||
<h1 class="title">{% trans "Import Status" %}</h1>
|
||||
|
||||
|
@ -36,8 +36,19 @@
|
|||
{% if not job.retry %}
|
||||
<form name="retry" action="/import/{{ job.id }}" method="post">
|
||||
{% csrf_token %}
|
||||
|
||||
{% with failed_count=failed_items|length %}
|
||||
{% if failed_count > 10 %}
|
||||
<p class="block">
|
||||
<a href="#select-all-failed-imports">
|
||||
{% blocktrans %}Jump to the bottom of the list to select the {{ failed_count }} items which failed to import.{% endblocktrans %}
|
||||
</a>
|
||||
</p>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
<fieldset id="failed-imports">
|
||||
<ul>
|
||||
<fieldset>
|
||||
{% for item in failed_items %}
|
||||
<li class="pb-1">
|
||||
<input class="checkbox" type="checkbox" name="import_item" value="{{ item.id }}" id="import-item-{{ item.id }}">
|
||||
|
@ -51,15 +62,28 @@
|
|||
</p>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</fieldset>
|
||||
</ul>
|
||||
<div class="block pt-1 select-all">
|
||||
<label class="label">
|
||||
<input type="checkbox" class="checkbox">
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="mt-3">
|
||||
<a name="select-all-failed-imports"></a>
|
||||
|
||||
<label class="label is-inline">
|
||||
<input
|
||||
id="toggle-all-checkboxes-failed-imports"
|
||||
class="checkbox"
|
||||
type="checkbox"
|
||||
data-action="toggle-all"
|
||||
data-target="failed-imports"
|
||||
/>
|
||||
{% trans "Select all" %}
|
||||
</label>
|
||||
</div>
|
||||
<button class="button" type="submit">{% trans "Retry items" %}</button>
|
||||
|
||||
<button class="button is-block mt-3" type="submit">{% trans "Retry items" %}</button>
|
||||
</fieldset>
|
||||
|
||||
<hr>
|
||||
|
||||
{% else %}
|
||||
<ul>
|
||||
{% for item in failed_items %}
|
||||
|
@ -123,4 +147,4 @@
|
|||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endspaceless %}{% endblock %}
|
||||
|
|
33
bookwyrm/templates/isbn_search_results.html
Normal file
33
bookwyrm/templates/isbn_search_results.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
{% extends 'layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{% trans "Search Results" %}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% with book_results|first as local_results %}
|
||||
<div class="block">
|
||||
<h1 class="title">{% blocktrans %}Search Results for "{{ query }}"{% endblocktrans %}</h1>
|
||||
</div>
|
||||
|
||||
<div class="block columns">
|
||||
<div class="column">
|
||||
<h2 class="title">{% trans "Matching Books" %}</h2>
|
||||
<section class="block">
|
||||
{% if not results %}
|
||||
<p>{% blocktrans %}No books found for "{{ query }}"{% endblocktrans %}</p>
|
||||
{% else %}
|
||||
<ul>
|
||||
{% for result in results %}
|
||||
<li class="pd-4">
|
||||
<a href="{{ result.key }}">{% include 'snippets/search_result_text.html' with result=result link=True %}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</section>
|
||||
|
||||
<div class="column">
|
||||
</div>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endblock %}
|
|
@ -22,7 +22,7 @@
|
|||
<meta name="twitter:image:alt" content="BookWyrm Logo">
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar container" role="navigation" aria-label="main navigation">
|
||||
<nav class="navbar container" aria-label="main navigation">
|
||||
<div class="navbar-brand">
|
||||
<a class="navbar-item" href="/">
|
||||
<img class="image logo" src="{% if site.logo_small %}/images/{{ site.logo_small }}{% else %}/static/images/logo-small.png{% endif %}" alt="Home page">
|
||||
|
@ -69,10 +69,18 @@
|
|||
<div class="navbar-end">
|
||||
{% if request.user.is_authenticated %}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<div class="navbar-link pulldown-menu" role="button" aria-expanded="false" tabindex="0" aria-haspopup="true" aria-controls="navbar-dropdown"><p>
|
||||
<a
|
||||
href="{{ user.local_path }}"
|
||||
class="navbar-link pulldown-menu"
|
||||
role="button"
|
||||
aria-expanded="false"
|
||||
tabindex="0"
|
||||
aria-haspopup="true"
|
||||
aria-controls="navbar-dropdown"
|
||||
>
|
||||
{% include 'snippets/avatar.html' with user=request.user %}
|
||||
{% include 'snippets/username.html' with user=request.user %}
|
||||
</p></div>
|
||||
<span class="ml-2">{% include 'snippets/username.html' with user=request.user anchor=false %}</span>
|
||||
</a>
|
||||
<ul class="navbar-dropdown" id="navbar-dropdown">
|
||||
<li>
|
||||
<a href="/direct-messages" class="navbar-item">
|
||||
|
@ -95,7 +103,7 @@
|
|||
</a>
|
||||
</li>
|
||||
{% if perms.bookwyrm.create_invites or perms.bookwyrm.edit_instance_settings%}
|
||||
<hr class="navbar-divider">
|
||||
<li class="navbar-divider" role="presentation"></li>
|
||||
{% endif %}
|
||||
{% if perms.bookwyrm.create_invites %}
|
||||
<li>
|
||||
|
@ -111,7 +119,7 @@
|
|||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
<hr class="navbar-divider">
|
||||
<li class="navbar-divider" role="presentation"></li>
|
||||
<li>
|
||||
<a href="/logout" class="navbar-item">
|
||||
{% trans 'Log out' %}
|
||||
|
@ -141,12 +149,12 @@
|
|||
<div class="columns is-variable is-1">
|
||||
<div class="column">
|
||||
<label class="is-sr-only" for="id_localname">{% trans "Username:" %}</label>
|
||||
<input type="text" name="localname" maxlength="150" class="input" required="" id="id_localname" placeholder="username">
|
||||
<input type="text" name="localname" maxlength="150" class="input" required="" id="id_localname" placeholder="{% trans 'username' %}">
|
||||
</div>
|
||||
<div class="column">
|
||||
<label class="is-sr-only" for="id_password">{% trans "Username:" %}</label>
|
||||
<input type="password" name="password" maxlength="128" class="input" required="" id="id_password" placeholder="password">
|
||||
<p class="help"><a href="/password-reset">Forgot your password?</a></p>
|
||||
<input type="password" name="password" maxlength="128" class="input" required="" id="id_password" placeholder="{% trans 'password' %}">
|
||||
<p class="help"><a href="/password-reset">{% trans "Forgot your password?" %}</a></p>
|
||||
</div>
|
||||
<div class="column is-narrow">
|
||||
<button class="button is-primary" type="submit">{% trans "Log in" %}</button>
|
||||
|
@ -157,7 +165,7 @@
|
|||
{% if site.allow_registration and request.path != '' and request.path != '/' %}
|
||||
<div class="column is-narrow">
|
||||
<a href="/" class="button is-link">
|
||||
Join
|
||||
{% trans "Join" %}
|
||||
</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
@ -191,7 +199,7 @@
|
|||
{% if site.support_link %}
|
||||
<div class="column">
|
||||
<span class="icon icon-heart"></span>
|
||||
Support {{ site.name }} on <a href="{{ site.support_link }}" target="_blank">{{ site.support_title }}</a>
|
||||
{% blocktrans %}Support {{ site.name }} on <a href="{{ site.support_link }}" target="_blank">{{ site.support_title }}</a>{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="column">
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
{% block content %}
|
||||
<div class="block">
|
||||
<h1 class="title">{% trans "Not Found" %}</h1>
|
||||
<p>{% trans "The page your requested doesn't seem to exist!" %}</p>
|
||||
<p>{% trans "The page you requested doesn't seem to exist!" %}</p>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
|
|
@ -87,11 +87,11 @@
|
|||
</div>
|
||||
{% elif notification.notification_type == 'BOOST' %}
|
||||
{% if related_status.status_type == 'Review' %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">review of <em>{{ book.title }}</em></a>{% endblocktrans %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">review of <em>{{ book_title }}</em></a>{% endblocktrans %}
|
||||
{% elif related_status.status_type == 'Comment' %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">comment on<em>{{ book.title }}</em></a>{% endblocktrans %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">comment on<em>{{ book_title }}</em></a>{% endblocktrans %}
|
||||
{% elif related_status.status_type == 'Quotation' %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">quote from <em>{{ book.title }}</em></a>{% endblocktrans %}
|
||||
{% blocktrans with related_path=related_status.local_path book_title=related_status.book.title %}boosted your <a href="{{ related_path }}">quote from <em>{{ book_title }}</em></a>{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with related_path=related_status.local_path %}boosted your <a href="{{ related_path }}">status</a>{% endblocktrans %}
|
||||
{% endif %}
|
||||
|
@ -114,7 +114,9 @@
|
|||
<div class="columns">
|
||||
<div class="column">
|
||||
{% if related_status.content %}
|
||||
<a href="{{ related_status.local_path }}">{{ related_status.content | safe | truncatewords_html:10 }}</a>
|
||||
<a href="{{ related_status.local_path }}">
|
||||
{{ related_status.content | safe | truncatewords_html:10 }}{% if related_status.mention_books %} <em>{{ related_status.mention_books.first.title }}</em>{% endif %}
|
||||
</a>
|
||||
{% elif related_status.quote %}
|
||||
<a href="{{ related_status.local_path }}">{{ related_status.quote | safe | truncatewords_html:10 }}</a>
|
||||
{% elif related_status.rating %}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
{% load bookwyrm_tags %}
|
||||
<img class="avatar image {% if large %}is-96x96{% else %}is-32x32{% endif %}" src="{% if user.avatar %}/images/{{ user.avatar }}{% else %}/static/images/default_avi.jpg{% endif %}" alt="{{ user.alt_text }}">
|
||||
<img class="avatar image {% if large %}is-96x96{% else %}is-32x32{% endif %}" src="{% if user.avatar %}/images/{{ user.avatar }}{% else %}/static/images/default_avi.jpg{% endif %}" {% if ariaHide %}aria-hidden="true"{% endif %} alt="{{ user.alt_text }}">
|
||||
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
<div class="no-cover book-cover">
|
||||
<img class="book-cover" src="/static/images/no_cover.jpg" alt="No cover">
|
||||
<div>
|
||||
<p>{{ book.title }}</p>
|
||||
<p>({{ book.edition_info }})</p>
|
||||
<p>{{ book.alt_text }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% load i18n %}
|
||||
<nav class="pagination" role="navigation" aria-label="pagination">
|
||||
<nav class="pagination" aria-label="pagination">
|
||||
{% if page.has_previous %}
|
||||
<p class="pagination-previous">
|
||||
<a href="{{ path }}?page={{ page.previous_page_number }}{{ anchor }}">
|
||||
|
|
|
@ -67,4 +67,4 @@
|
|||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% include 'snippets/delete_readthrough_modal.html' with controls_text="delete-readthrough" controls_uid=readthrough.id %}
|
||||
{% include 'snippets/delete_readthrough_modal.html' with controls_text="delete-readthrough" controls_uid=readthrough.id no_body=True %}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
<hr class="navbar-divider">
|
||||
<li class="navbar-divider" role="presentation"></li>
|
||||
<li>
|
||||
<form class="dropdown-item pt-0 pb-0" name="shelve" action="/unshelve/" method="post">
|
||||
{% csrf_token %}
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
<div class="block">
|
||||
{% if status.status_type == 'Review' %}
|
||||
<div>
|
||||
<h3 class="title is-5 has-subtitle">
|
||||
{% if status.name %}<span dir="auto">{{ status.name }}</span><br>{% endif %}
|
||||
{% if status.name %}
|
||||
<h3 class="title is-5 has-subtitle" dir="auto">
|
||||
{{ status.name|escape }}
|
||||
</h3>
|
||||
<p class="subtitle">{% include 'snippets/stars.html' with rating=status.rating %}</p>
|
||||
{% endif %}
|
||||
{% include 'snippets/stars.html' with rating=status.rating %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
@ -35,7 +37,7 @@
|
|||
{% if status.content and status.status_type != 'GeneratedNote' and status.status_type != 'Announce' %}
|
||||
{% include 'snippets/trimmed_text.html' with full=status.content|safe %}
|
||||
{% endif %}
|
||||
{% if status.attachments %}
|
||||
{% if status.attachments.exists %}
|
||||
<div class="block">
|
||||
<div class="columns">
|
||||
{% for attachment in status.attachments.all %}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
{% load bookwyrm_tags %}
|
||||
{% load i18n %}
|
||||
{% include 'snippets/avatar.html' with user=status.user %}
|
||||
<a href="{{ status.user.local_path }}">
|
||||
{% include 'snippets/avatar.html' with user=status.user ariaHide="true" %}
|
||||
{% include 'snippets/username.html' with user=status.user %}
|
||||
</a>
|
||||
|
||||
{% if status.status_type == 'GeneratedNote' %}
|
||||
{{ status.content | safe }}
|
||||
|
|
|
@ -8,19 +8,29 @@
|
|||
{% with full|to_markdown|safe|truncatewords_html:60 as trimmed %}
|
||||
{% if trimmed != full %}
|
||||
<div id="hide-full-{{ uuid }}">
|
||||
<div class="content" id="trimmed-{{ uuid }}"><span dir="auto">{{ trimmed }}</span>
|
||||
<div class="content" id="trimmed-{{ uuid }}">
|
||||
<p dir="auto">{{ trimmed }}</p>
|
||||
|
||||
<div>
|
||||
{% trans "Show more" as button_text %}
|
||||
{% include 'snippets/toggle/open_button.html' with text=button_text controls_text="full" controls_uid=uuid class="is-small" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="full-{{ uuid }}" class="hidden">
|
||||
<div class="content"><span dir="auto">{{ full }}</span>
|
||||
<div class="content">
|
||||
<div dir="auto">{{ full }}</div>
|
||||
|
||||
<div>
|
||||
{% trans "Show less" as button_text %}
|
||||
{% include 'snippets/toggle/close_button.html' with text=button_text controls_text="full" controls_uid=uuid class="is-small" %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="content"><span dir="auto">{{ full }}</span></div>
|
||||
<div class="content">
|
||||
<div dir="auto">{{ full }}</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
|
|
|
@ -1,2 +1,13 @@
|
|||
{% spaceless %}
|
||||
{% load bookwyrm_tags %}
|
||||
<a href="{{ user.local_path }}" class="user">{% if user.name %}{{ user.name }}{% else %}{{ user | username }}{% endif %}</a>{% if possessive %}'s{% endif %}{% if show_full and user.name or show_full and user.localname %} ({{ user.username }}){% endif %}
|
||||
|
||||
<{% if anchor %}a href="{{ user.local_path }}"{% else %}span{% endif %}>
|
||||
{{ user.display_name }}
|
||||
</a>
|
||||
|
||||
{% if possessive %}'s{% endif %}
|
||||
|
||||
{% if show_full and user.name or show_full and user.localname %}
|
||||
({{ user.username }})
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{% extends 'user/user_layout.html' %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block title %}{{ user.name }}{% endblock %}
|
||||
{% block title %}{{ user.display_name }}{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
<div class="columns is-mobile">
|
||||
|
@ -67,7 +67,7 @@
|
|||
</div>
|
||||
</div>
|
||||
{% for activity in activities %}
|
||||
<div class="block" id="feed">
|
||||
<div class="block" id="feed-{{ activity.id }}">
|
||||
{% include 'snippets/status/status.html' with status=activity %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
|
|
@ -17,11 +17,11 @@
|
|||
{% include 'user/user_preview.html' with user=user %}
|
||||
</div>
|
||||
|
||||
<div class="column box has-background-white-bis content">
|
||||
{% if user.summary %}
|
||||
<div class="column box has-background-white-bis content">
|
||||
{{ user.summary | to_markdown | safe }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not is_self and request.user.is_authenticated %}
|
||||
{% include 'snippets/follow_button.html' with user=user %}
|
||||
|
@ -56,7 +56,7 @@
|
|||
<a href="{{ url }}">{% trans "Reading Goal" %}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if is_self or user.lists.exists %}
|
||||
{% if is_self or user.list_set.exists %}
|
||||
{% url 'user-lists' user|username as url %}
|
||||
<li{% if url in request.path %} class="is-active"{% endif %}>
|
||||
<a href="{{ url }}">{% trans "Lists" %}</a>
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
from . import *
|
|
@ -42,6 +42,10 @@ class AbstractConnector(TestCase):
|
|||
return search_result
|
||||
def parse_search_data(self, data):
|
||||
return data
|
||||
def format_isbn_search_result(self, search_result):
|
||||
return search_result
|
||||
def parse_isbn_search_data(self, data):
|
||||
return data
|
||||
def is_work_data(self, data):
|
||||
return data['type'] == 'work'
|
||||
def get_edition_from_work_data(self, data):
|
||||
|
|
|
@ -18,6 +18,7 @@ class AbstractConnector(TestCase):
|
|||
books_url='https://example.com/books',
|
||||
covers_url='https://example.com/covers',
|
||||
search_url='https://example.com/search?q=',
|
||||
isbn_search_url='https://example.com/isbn',
|
||||
)
|
||||
|
||||
class TestConnector(abstract_connector.AbstractMinimalConnector):
|
||||
|
@ -28,6 +29,10 @@ class AbstractConnector(TestCase):
|
|||
pass
|
||||
def parse_search_data(self, data):
|
||||
return data
|
||||
def format_isbn_search_result(self, search_result):
|
||||
return search_result
|
||||
def parse_isbn_search_data(self, data):
|
||||
return data
|
||||
self.test_connector = TestConnector('example.com')
|
||||
|
||||
|
||||
|
@ -39,6 +44,7 @@ class AbstractConnector(TestCase):
|
|||
self.assertEqual(connector.books_url, 'https://example.com/books')
|
||||
self.assertEqual(connector.covers_url, 'https://example.com/covers')
|
||||
self.assertEqual(connector.search_url, 'https://example.com/search?q=')
|
||||
self.assertEqual(connector.isbn_search_url, 'https://example.com/isbn')
|
||||
self.assertIsNone(connector.name)
|
||||
self.assertEqual(connector.identifier, 'example.com')
|
||||
self.assertIsNone(connector.max_query_count)
|
||||
|
|
|
@ -27,6 +27,7 @@ class Openlibrary(TestCase):
|
|||
books_url='https://openlibrary.org',
|
||||
covers_url='https://covers.openlibrary.org',
|
||||
search_url='https://openlibrary.org/search?q=',
|
||||
isbn_search_url='https://openlibrary.org/isbn',
|
||||
)
|
||||
self.connector = Connector('openlibrary.org')
|
||||
|
||||
|
@ -149,6 +150,34 @@ class Openlibrary(TestCase):
|
|||
self.assertEqual(result.connector, self.connector)
|
||||
|
||||
|
||||
def test_parse_isbn_search_result(self):
|
||||
''' extract the results from the search json response '''
|
||||
datafile = pathlib.Path(__file__).parent.joinpath(
|
||||
'../data/ol_isbn_search.json')
|
||||
search_data = json.loads(datafile.read_bytes())
|
||||
result = self.connector.parse_isbn_search_data(search_data)
|
||||
self.assertIsInstance(result, list)
|
||||
self.assertEqual(len(result), 1)
|
||||
|
||||
|
||||
def test_format_isbn_search_result(self):
|
||||
''' translate json from openlibrary into SearchResult '''
|
||||
datafile = pathlib.Path(__file__).parent.joinpath(
|
||||
'../data/ol_isbn_search.json')
|
||||
search_data = json.loads(datafile.read_bytes())
|
||||
results = self.connector.parse_isbn_search_data(search_data)
|
||||
self.assertIsInstance(results, list)
|
||||
|
||||
result = self.connector.format_isbn_search_result(results[0])
|
||||
self.assertIsInstance(result, SearchResult)
|
||||
self.assertEqual(result.title, 'Les ombres errantes')
|
||||
self.assertEqual(
|
||||
result.key, 'https://openlibrary.org/books/OL16262504M')
|
||||
self.assertEqual(result.author, 'Pascal Quignard')
|
||||
self.assertEqual(result.year, '2002')
|
||||
self.assertEqual(result.connector, self.connector)
|
||||
|
||||
|
||||
@responses.activate
|
||||
def test_load_edition_data(self):
|
||||
''' format url from key and make request '''
|
||||
|
|
45
bookwyrm/tests/data/ol_isbn_search.json
Normal file
45
bookwyrm/tests/data/ol_isbn_search.json
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"ISBN:9782070427796": {
|
||||
"url": "https://openlibrary.org/books/OL16262504M/Les_ombres_errantes",
|
||||
"key": "/books/OL16262504M",
|
||||
"title": "Les ombres errantes",
|
||||
"authors": [
|
||||
{
|
||||
"url": "https://openlibrary.org/authors/OL269675A/Pascal_Quignard",
|
||||
"name": "Pascal Quignard"
|
||||
}
|
||||
],
|
||||
"by_statement": "Pascal Quignard.",
|
||||
"identifiers": {
|
||||
"goodreads": [
|
||||
"1835483"
|
||||
],
|
||||
"librarything": [
|
||||
"983474"
|
||||
],
|
||||
"isbn_10": [
|
||||
"207042779X"
|
||||
],
|
||||
"openlibrary": [
|
||||
"OL16262504M"
|
||||
]
|
||||
},
|
||||
"classifications": {
|
||||
"dewey_decimal_class": [
|
||||
"848/.91403"
|
||||
]
|
||||
},
|
||||
"publishers": [
|
||||
{
|
||||
"name": "Gallimard"
|
||||
}
|
||||
],
|
||||
"publish_places": [
|
||||
{
|
||||
"name": "Paris"
|
||||
}
|
||||
],
|
||||
"publish_date": "2002",
|
||||
"notes": "Hardback published Grasset, 2002."
|
||||
}
|
||||
}
|
|
@ -81,7 +81,7 @@ class Book(TestCase):
|
|||
book.save()
|
||||
self.assertEqual(book.edition_info, 'worm, Glorbish language, 2020')
|
||||
self.assertEqual(
|
||||
book.alt_text, 'Test Edition cover (worm, Glorbish language, 2020)')
|
||||
book.alt_text, 'Test Edition (worm, Glorbish language, 2020)')
|
||||
|
||||
|
||||
def test_get_rank(self):
|
||||
|
|
|
@ -150,7 +150,7 @@ class Status(TestCase):
|
|||
self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \
|
||||
(settings.DOMAIN, self.book.cover.url))
|
||||
self.assertEqual(
|
||||
activity['attachment'][0].name, 'Test Edition cover')
|
||||
activity['attachment'][0].name, 'Test Edition')
|
||||
|
||||
def test_comment_to_activity(self, _):
|
||||
''' subclass of the base model version with a "pure" serializer '''
|
||||
|
@ -177,7 +177,7 @@ class Status(TestCase):
|
|||
self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \
|
||||
(settings.DOMAIN, self.book.cover.url))
|
||||
self.assertEqual(
|
||||
activity['attachment'][0].name, 'Test Edition cover')
|
||||
activity['attachment'][0].name, 'Test Edition')
|
||||
|
||||
def test_quotation_to_activity(self, _):
|
||||
''' subclass of the base model version with a "pure" serializer '''
|
||||
|
@ -207,7 +207,7 @@ class Status(TestCase):
|
|||
self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \
|
||||
(settings.DOMAIN, self.book.cover.url))
|
||||
self.assertEqual(
|
||||
activity['attachment'][0].name, 'Test Edition cover')
|
||||
activity['attachment'][0].name, 'Test Edition')
|
||||
|
||||
def test_review_to_activity(self, _):
|
||||
''' subclass of the base model version with a "pure" serializer '''
|
||||
|
@ -238,7 +238,7 @@ class Status(TestCase):
|
|||
self.assertEqual(activity['attachment'][0].url, 'https://%s%s' % \
|
||||
(settings.DOMAIN, self.book.cover.url))
|
||||
self.assertEqual(
|
||||
activity['attachment'][0].name, 'Test Edition cover')
|
||||
activity['attachment'][0].name, 'Test Edition')
|
||||
|
||||
def test_favorite(self, _):
|
||||
''' fav a status '''
|
||||
|
|
54
bookwyrm/tests/views/test_isbn.py
Normal file
54
bookwyrm/tests/views/test_isbn.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
''' test for app action functionality '''
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
|
||||
from django.http import JsonResponse
|
||||
from django.template.response import TemplateResponse
|
||||
from django.test import TestCase
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
from bookwyrm import models, views
|
||||
from bookwyrm.connectors import abstract_connector
|
||||
from bookwyrm.settings import DOMAIN
|
||||
|
||||
|
||||
class IsbnViews(TestCase):
|
||||
''' tag views'''
|
||||
def setUp(self):
|
||||
''' we need basic test data and mocks '''
|
||||
self.factory = RequestFactory()
|
||||
self.local_user = models.User.objects.create_user(
|
||||
'mouse@local.com', 'mouse@mouse.com', 'mouseword',
|
||||
local=True, localname='mouse',
|
||||
remote_id='https://example.com/users/mouse',
|
||||
)
|
||||
self.work = models.Work.objects.create(title='Test Work')
|
||||
self.book = models.Edition.objects.create(
|
||||
title='Test Book',
|
||||
isbn_13='1234567890123',
|
||||
remote_id='https://example.com/book/1',
|
||||
parent_work=self.work
|
||||
)
|
||||
models.Connector.objects.create(
|
||||
identifier='self',
|
||||
connector_file='self_connector',
|
||||
local=True
|
||||
)
|
||||
models.SiteSettings.objects.create()
|
||||
|
||||
|
||||
def test_isbn_json_response(self):
|
||||
''' searches local data only and returns book data in json format '''
|
||||
view = views.Isbn.as_view()
|
||||
request = self.factory.get('')
|
||||
with patch('bookwyrm.views.isbn.is_api_request') as is_api:
|
||||
is_api.return_value = True
|
||||
response = view(request, isbn='1234567890123')
|
||||
self.assertIsInstance(response, JsonResponse)
|
||||
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(len(data), 1)
|
||||
self.assertEqual(data[0]['title'], 'Test Book')
|
||||
self.assertEqual(
|
||||
data[0]['key'], 'https://%s/book/%d' % (DOMAIN, self.book.id))
|
||||
|
|
@ -64,6 +64,10 @@ class ShelfViews(TestCase):
|
|||
pass
|
||||
def parse_search_data(self, data):
|
||||
pass
|
||||
def format_isbn_search_result(self, search_result):
|
||||
return search_result
|
||||
def parse_isbn_search_data(self, data):
|
||||
return data
|
||||
models.Connector.objects.create(
|
||||
identifier='example.com',
|
||||
connector_file='openlibrary',
|
||||
|
|
|
@ -135,6 +135,9 @@ urlpatterns = [
|
|||
re_path(r'^resolve-book/?$', views.resolve_book),
|
||||
re_path(r'^switch-edition/?$', views.switch_edition),
|
||||
|
||||
# isbn
|
||||
re_path(r'^isbn/(?P<isbn>\d+)(.json)?/?$', views.Isbn.as_view()),
|
||||
|
||||
# author
|
||||
re_path(r'^author/(?P<author_id>\d+)(.json)?/?$', views.Author.as_view()),
|
||||
re_path(r'^author/(?P<author_id>\d+)/edit/?$', views.EditAuthor.as_view()),
|
||||
|
|
|
@ -31,3 +31,4 @@ from .site import Site
|
|||
from .status import CreateStatus, DeleteStatus
|
||||
from .updates import Updates
|
||||
from .user import User, EditUser, Followers, Following
|
||||
from .isbn import Isbn
|
||||
|
|
|
@ -89,7 +89,7 @@ class Book(View):
|
|||
'rating': reviews.aggregate(Avg('rating'))['rating__avg'],
|
||||
'tags': models.UserTag.objects.filter(book=book),
|
||||
'lists': privacy_filter(
|
||||
request.user, book.list_set.all()
|
||||
request.user, book.list_set.filter(listitem__approved=True)
|
||||
),
|
||||
'user_tags': user_tags,
|
||||
'user_shelves': user_shelves,
|
||||
|
|
29
bookwyrm/views/isbn.py
Normal file
29
bookwyrm/views/isbn.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
''' isbn search view '''
|
||||
from django.http import HttpResponseNotFound
|
||||
from django.http import JsonResponse
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.template.response import TemplateResponse
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.views import View
|
||||
from django.views.decorators.http import require_POST
|
||||
|
||||
from bookwyrm import forms, models
|
||||
from bookwyrm.connectors import connector_manager
|
||||
from .helpers import is_api_request
|
||||
|
||||
# pylint: disable= no-self-use
|
||||
class Isbn(View):
|
||||
''' search a book by isbn '''
|
||||
def get(self, request, isbn):
|
||||
''' info about a book '''
|
||||
book_results = connector_manager.isbn_local_search(isbn)
|
||||
|
||||
if is_api_request(request):
|
||||
return JsonResponse([r.json() for r in book_results], safe=False)
|
||||
|
||||
data = {
|
||||
'title': 'ISBN Search Results',
|
||||
'results': book_results,
|
||||
'query': isbn,
|
||||
}
|
||||
return TemplateResponse(request, 'isbn_search_results.html', data)
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-02 21:36+0000\n"
|
||||
"POT-Creation-Date: 2021-03-04 22:24+0000\n"
|
||||
"PO-Revision-Date: 2021-03-02 17:19-0800\n"
|
||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||
"Language-Team: English <LL@li.org>\n"
|
||||
|
@ -55,7 +55,7 @@ msgstr "%(value)s ist keine gültige remote_id"
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr "%(value)s ist kein gültiger Username"
|
||||
|
||||
#: bookwyrm/models/fields.py:164
|
||||
#: bookwyrm/models/fields.py:164 bookwyrm/templates/layout.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Server name"
|
||||
msgid "username"
|
||||
|
@ -74,10 +74,14 @@ msgid "German"
|
|||
msgstr "Deutsch"
|
||||
|
||||
#: bookwyrm/settings.py:144
|
||||
msgid "Spanish"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:145
|
||||
msgid "French"
|
||||
msgstr "Französisch"
|
||||
|
||||
#: bookwyrm/settings.py:145
|
||||
#: bookwyrm/settings.py:146
|
||||
msgid "Simplified Chinese"
|
||||
msgstr "Vereinfachtes Chinesisch"
|
||||
|
||||
|
@ -96,6 +100,8 @@ msgid "Books by %(name)s"
|
|||
msgstr "Bücher von %(name)s"
|
||||
|
||||
#: bookwyrm/templates/book.html:21
|
||||
#: bookwyrm/templates/discover/large-book.html:12
|
||||
#: bookwyrm/templates/discover/small-book.html:9
|
||||
msgid "by"
|
||||
msgstr "von"
|
||||
|
||||
|
@ -428,7 +434,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr "Direktnachrichten mit <a href=\"%(path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:79
|
||||
#: bookwyrm/templates/layout.html:87
|
||||
msgid "Direct Messages"
|
||||
msgstr "Direktnachrichten"
|
||||
|
||||
|
@ -538,7 +544,7 @@ msgid "%(username)s's %(year)s Books"
|
|||
msgstr "%(username)ss %(year)s Bücher"
|
||||
|
||||
#: bookwyrm/templates/import.html:5 bookwyrm/templates/import.html:9
|
||||
#: bookwyrm/templates/layout.html:94
|
||||
#: bookwyrm/templates/layout.html:102
|
||||
msgid "Import Books"
|
||||
msgstr "Bücher importieren"
|
||||
|
||||
|
@ -661,55 +667,72 @@ msgstr "Deine Regale"
|
|||
msgid "Feed"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:84
|
||||
#: bookwyrm/templates/layout.html:92
|
||||
#: bookwyrm/templates/preferences/preferences_layout.html:14
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:89
|
||||
#: bookwyrm/templates/layout.html:97
|
||||
msgid "Settings"
|
||||
msgstr "Einstellungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:103
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
#: bookwyrm/templates/settings/admin_layout.html:19
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
msgid "Invites"
|
||||
msgstr "Einladungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:110
|
||||
#: bookwyrm/templates/layout.html:118
|
||||
msgid "Site Configuration"
|
||||
msgstr "Seiteneinstellungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:117
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
msgid "Log out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: bookwyrm/templates/layout.html:125 bookwyrm/templates/layout.html:126
|
||||
#: bookwyrm/templates/layout.html:133 bookwyrm/templates/layout.html:134
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:10
|
||||
msgid "Notifications"
|
||||
msgstr "Benachrichtigungen"
|
||||
|
||||
#: bookwyrm/templates/layout.html:143 bookwyrm/templates/layout.html:147
|
||||
#: bookwyrm/templates/layout.html:151 bookwyrm/templates/layout.html:155
|
||||
#: bookwyrm/templates/login.html:17
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:152 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/layout.html:156
|
||||
msgid "password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: bookwyrm/templates/layout.html:157 bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Passwort vergessen?"
|
||||
|
||||
#: bookwyrm/templates/layout.html:160 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/login.html:33
|
||||
msgid "Log in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: bookwyrm/templates/layout.html:183
|
||||
#: bookwyrm/templates/layout.html:168
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:191
|
||||
msgid "About this server"
|
||||
msgstr "Über diesen Server"
|
||||
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
#: bookwyrm/templates/layout.html:195
|
||||
msgid "Contact site admin"
|
||||
msgstr "Admin kontaktieren"
|
||||
|
||||
#: bookwyrm/templates/layout.html:198
|
||||
#: bookwyrm/templates/layout.html:202
|
||||
#, python-format
|
||||
msgid "Support %(site.name)s on <a href=\"%(site.support_link)s\" target=\"_blank\">%(site.support_title)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:206
|
||||
msgid "BookWyrm is open source software. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr "BookWyrm ist open source Software. Du kannst dich auf <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> beteiligen oder etwas melden."
|
||||
|
||||
|
@ -855,10 +878,6 @@ msgstr ""
|
|||
msgid "Password:"
|
||||
msgstr "Passwort:"
|
||||
|
||||
#: bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Passwort vergessen?"
|
||||
|
||||
#: bookwyrm/templates/login.html:49
|
||||
msgid "Contact an administrator to get an invite"
|
||||
msgstr "Kontaktiere für eine Einladung eine*n Admin"
|
||||
|
@ -872,7 +891,7 @@ msgid "Not Found"
|
|||
msgstr "Nicht gefunden"
|
||||
|
||||
#: bookwyrm/templates/notfound.html:9
|
||||
msgid "The page your requested doesn't seem to exist!"
|
||||
msgid "The page you requested doesn't seem to exist!"
|
||||
msgstr "Die Seite die du angefordert hast scheint nicht zu existieren!"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:14
|
||||
|
@ -949,18 +968,18 @@ msgstr "hat dir eine Folgeanfrage geschickt"
|
|||
|
||||
#: bookwyrm/templates/notifications.html:90
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book.title)s</em></a>"
|
||||
msgstr "hat deine <a href=\"%(related_path)s\">Bewertung von <em>%(book.title)s</em></a> geteilt"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "hat deine <a href=\"%(related_path)s\">Bewertung von <em>%(book_title)s</em></a> geteilt"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:92
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book.title)s</em></a>"
|
||||
msgstr "hat deinen <a href=\"%(related_path)s\">Kommentar zu<em>%(book.title)s</em></a> geteilt"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book_title)s</em></a>"
|
||||
msgstr "hat deinen <a href=\"%(related_path)s\">Kommentar zu<em>%(book_title)s</em></a> geteilt"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:94
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book.title)s</em></a>"
|
||||
msgstr "hat dein <a href=\"%(related_path)s\">Zitat aus <em>%(book.title)s</em></a> geteilt"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "hat dein <a href=\"%(related_path)s\">Zitat aus <em>%(book_title)s</em></a> geteilt"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:96
|
||||
#, python-format
|
||||
|
@ -1648,17 +1667,17 @@ msgstr "geteilt"
|
|||
msgid "Reply"
|
||||
msgstr "Antwort"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:16
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:12
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:18
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:15
|
||||
msgid "Show more"
|
||||
msgstr "Mehr anzeigen"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:23
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:18
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:25
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:25
|
||||
msgid "Show less"
|
||||
msgstr "Weniger anzeigen"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:44
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:46
|
||||
msgid "Open image in new window"
|
||||
msgstr "Bild in neuem Fenster öffnen"
|
||||
|
||||
|
@ -1668,8 +1687,6 @@ msgid "More options"
|
|||
msgstr "Mehr Optionen"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_options.html:17
|
||||
#, fuzzy
|
||||
#| msgid "Delete post"
|
||||
msgid "Delete status"
|
||||
msgstr "Post löschen"
|
||||
|
||||
|
@ -1693,8 +1710,6 @@ msgstr "Mit \"%(tag.name)s\" markierte Bücher"
|
|||
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:5
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:22
|
||||
#, fuzzy
|
||||
#| msgid "Create shelf"
|
||||
msgid "Create Shelf"
|
||||
msgstr "Regal erstellen"
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.0.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-02 21:36+0000\n"
|
||||
"POT-Creation-Date: 2021-03-04 22:24+0000\n"
|
||||
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
|
||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||
"Language-Team: English <LL@li.org>\n"
|
||||
|
@ -53,7 +53,7 @@ msgstr ""
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/fields.py:164
|
||||
#: bookwyrm/models/fields.py:164 bookwyrm/templates/layout.html:152
|
||||
msgid "username"
|
||||
msgstr ""
|
||||
|
||||
|
@ -70,10 +70,14 @@ msgid "German"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:144
|
||||
msgid "French"
|
||||
msgid "Spanish"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:145
|
||||
msgid "French"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:146
|
||||
msgid "Simplified Chinese"
|
||||
msgstr ""
|
||||
|
||||
|
@ -92,6 +96,8 @@ msgid "Books by %(name)s"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/book.html:21
|
||||
#: bookwyrm/templates/discover/large-book.html:12
|
||||
#: bookwyrm/templates/discover/small-book.html:9
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
|
@ -419,7 +425,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:79
|
||||
#: bookwyrm/templates/layout.html:87
|
||||
msgid "Direct Messages"
|
||||
msgstr ""
|
||||
|
||||
|
@ -525,7 +531,7 @@ msgid "%(username)s's %(year)s Books"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/import.html:5 bookwyrm/templates/import.html:9
|
||||
#: bookwyrm/templates/layout.html:94
|
||||
#: bookwyrm/templates/layout.html:102
|
||||
msgid "Import Books"
|
||||
msgstr ""
|
||||
|
||||
|
@ -648,55 +654,72 @@ msgstr ""
|
|||
msgid "Feed"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:84
|
||||
#: bookwyrm/templates/layout.html:92
|
||||
#: bookwyrm/templates/preferences/preferences_layout.html:14
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:89
|
||||
#: bookwyrm/templates/layout.html:97
|
||||
msgid "Settings"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:103
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
#: bookwyrm/templates/settings/admin_layout.html:19
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
msgid "Invites"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:110
|
||||
#: bookwyrm/templates/layout.html:118
|
||||
msgid "Site Configuration"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:117
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
msgid "Log out"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:125 bookwyrm/templates/layout.html:126
|
||||
#: bookwyrm/templates/layout.html:133 bookwyrm/templates/layout.html:134
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:10
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:143 bookwyrm/templates/layout.html:147
|
||||
#: bookwyrm/templates/layout.html:151 bookwyrm/templates/layout.html:155
|
||||
#: bookwyrm/templates/login.html:17
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:152 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/layout.html:156
|
||||
msgid "password"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:157 bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:160 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/login.html:33
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:183
|
||||
#: bookwyrm/templates/layout.html:168
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:191
|
||||
msgid "About this server"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
#: bookwyrm/templates/layout.html:195
|
||||
msgid "Contact site admin"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:198
|
||||
#: bookwyrm/templates/layout.html:202
|
||||
#, python-format
|
||||
msgid "Support %(site.name)s on <a href=\"%(site.support_link)s\" target=\"_blank\">%(site.support_title)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:206
|
||||
msgid "BookWyrm is open source software. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr ""
|
||||
|
||||
|
@ -840,10 +863,6 @@ msgstr ""
|
|||
msgid "Password:"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/login.html:49
|
||||
msgid "Contact an administrator to get an invite"
|
||||
msgstr ""
|
||||
|
@ -857,7 +876,7 @@ msgid "Not Found"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/notfound.html:9
|
||||
msgid "The page your requested doesn't seem to exist!"
|
||||
msgid "The page you requested doesn't seem to exist!"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/notifications.html:14
|
||||
|
@ -934,17 +953,17 @@ msgstr ""
|
|||
|
||||
#: bookwyrm/templates/notifications.html:90
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book.title)s</em></a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/notifications.html:92
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book.title)s</em></a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book_title)s</em></a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/notifications.html:94
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book.title)s</em></a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/notifications.html:96
|
||||
|
@ -1633,17 +1652,17 @@ msgstr ""
|
|||
msgid "Reply"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:16
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:12
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:18
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:15
|
||||
msgid "Show more"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:23
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:18
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:25
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:25
|
||||
msgid "Show less"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:44
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:46
|
||||
msgid "Open image in new window"
|
||||
msgstr ""
|
||||
|
||||
|
|
BIN
locale/es/LC_MESSAGES/django.mo
Normal file
BIN
locale/es/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
1831
locale/es/LC_MESSAGES/django.po
Normal file
1831
locale/es/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.1.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-02 21:36+0000\n"
|
||||
"POT-Creation-Date: 2021-03-05 14:10+0000\n"
|
||||
"PO-Revision-Date: 2021-03-02 12:37+0100\n"
|
||||
"Last-Translator: Fabien Basmaison <contact@arkhi.org>\n"
|
||||
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
||||
|
@ -55,7 +55,7 @@ msgstr ""
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/fields.py:164
|
||||
#: bookwyrm/models/fields.py:164 bookwyrm/templates/layout.html:152
|
||||
#, fuzzy
|
||||
#| msgid "Username:"
|
||||
msgid "username"
|
||||
|
@ -74,10 +74,14 @@ msgid "German"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:144
|
||||
msgid "French"
|
||||
msgid "Spanish"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:145
|
||||
msgid "French"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:146
|
||||
msgid "Simplified Chinese"
|
||||
msgstr ""
|
||||
|
||||
|
@ -96,6 +100,8 @@ msgid "Books by %(name)s"
|
|||
msgstr "Livres par %(name)s"
|
||||
|
||||
#: bookwyrm/templates/book.html:21
|
||||
#: bookwyrm/templates/discover/large-book.html:12
|
||||
#: bookwyrm/templates/discover/small-book.html:9
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
|
@ -431,15 +437,12 @@ msgid "Something went wrong! Sorry about that."
|
|||
msgstr "Une erreur s’est produite ; désolé !"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:8
|
||||
#, fuzzy, python-format
|
||||
#| msgid "favorited your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||
msgstr "Messages directs avec <a href=\"%(path)s\">%(username)s</a>"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:79
|
||||
#, fuzzy
|
||||
#| msgid "Send direct message"
|
||||
#: bookwyrm/templates/layout.html:87
|
||||
msgid "Direct Messages"
|
||||
msgstr "Messages directs"
|
||||
|
||||
|
@ -555,7 +558,7 @@ msgid "%(username)s's %(year)s Books"
|
|||
msgstr "Livres de %(username)s en %(year)s"
|
||||
|
||||
#: bookwyrm/templates/import.html:5 bookwyrm/templates/import.html:9
|
||||
#: bookwyrm/templates/layout.html:94
|
||||
#: bookwyrm/templates/layout.html:102
|
||||
msgid "Import Books"
|
||||
msgstr "Importer des livres"
|
||||
|
||||
|
@ -610,37 +613,42 @@ msgstr "(Rechargez la page pour mettre à jour !"
|
|||
|
||||
#: bookwyrm/templates/import_status.html:35
|
||||
msgid "Failed to load"
|
||||
msgstr "Le chargement a échoué"
|
||||
msgstr "Items non importés"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:59
|
||||
#: bookwyrm/templates/import_status.html:42
|
||||
#, python-format
|
||||
msgid "Jump to the bottom of the list to select the %(failed_count)s items which failed to import."
|
||||
msgstr "Sauter en bas de liste pour sélectionner les %(failed_count)s items n’ayant pu être importés."
|
||||
|
||||
#: bookwyrm/templates/import_status.html:74
|
||||
msgid "Select all"
|
||||
msgstr "Tout sélectionner"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:62
|
||||
#: bookwyrm/templates/import_status.html:79
|
||||
msgid "Retry items"
|
||||
msgstr "Essayer d’importer les objets sélectionnés de nouveau"
|
||||
msgstr "Essayer d’importer les items sélectionnés de nouveau"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:84
|
||||
#: bookwyrm/templates/import_status.html:101
|
||||
msgid "Successfully imported"
|
||||
msgstr "Importation réussie"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:88
|
||||
#: bookwyrm/templates/import_status.html:105
|
||||
#: bookwyrm/templates/lists/curate.html:14
|
||||
msgid "Book"
|
||||
msgstr "Livre"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:91
|
||||
#: bookwyrm/templates/import_status.html:108
|
||||
#: bookwyrm/templates/snippets/create_status_form.html:10
|
||||
#: bookwyrm/templates/snippets/shelf.html:10
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:94
|
||||
#: bookwyrm/templates/import_status.html:111
|
||||
#: bookwyrm/templates/snippets/shelf.html:11
|
||||
msgid "Author"
|
||||
msgstr "Auteur ou autrice"
|
||||
|
||||
#: bookwyrm/templates/import_status.html:117
|
||||
#: bookwyrm/templates/import_status.html:134
|
||||
msgid "Imported"
|
||||
msgstr "Importé"
|
||||
|
||||
|
@ -658,8 +666,6 @@ msgid "Sorry! This invite code is no longer valid."
|
|||
msgstr "Cette invitation n’est plus valide ; désolé !"
|
||||
|
||||
#: bookwyrm/templates/layout.html:33
|
||||
#, fuzzy
|
||||
#| msgid "Search for a book"
|
||||
msgid "Search for a book or user"
|
||||
msgstr "Chercher un livre ou un compte"
|
||||
|
||||
|
@ -680,59 +686,76 @@ msgstr "Vos étagères"
|
|||
msgid "Feed"
|
||||
msgstr "Fil d’actualité"
|
||||
|
||||
#: bookwyrm/templates/layout.html:84
|
||||
#: bookwyrm/templates/layout.html:92
|
||||
#: bookwyrm/templates/preferences/preferences_layout.html:14
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: bookwyrm/templates/layout.html:89
|
||||
#: bookwyrm/templates/layout.html:97
|
||||
#, fuzzy
|
||||
#| msgid "Instance Settings"
|
||||
msgid "Settings"
|
||||
msgstr "Paramètres de l’instance"
|
||||
|
||||
#: bookwyrm/templates/layout.html:103
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
#: bookwyrm/templates/settings/admin_layout.html:19
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
msgid "Invites"
|
||||
msgstr "Invitations"
|
||||
|
||||
#: bookwyrm/templates/layout.html:110
|
||||
#: bookwyrm/templates/layout.html:118
|
||||
msgid "Site Configuration"
|
||||
msgstr "Configuration du site"
|
||||
|
||||
#: bookwyrm/templates/layout.html:117
|
||||
#, fuzzy
|
||||
#| msgid "Log in"
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
msgid "Log out"
|
||||
msgstr "Se déconnecter"
|
||||
|
||||
#: bookwyrm/templates/layout.html:125 bookwyrm/templates/layout.html:126
|
||||
#: bookwyrm/templates/layout.html:133 bookwyrm/templates/layout.html:134
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:10
|
||||
msgid "Notifications"
|
||||
msgstr "Notifications"
|
||||
|
||||
#: bookwyrm/templates/layout.html:143 bookwyrm/templates/layout.html:147
|
||||
#: bookwyrm/templates/layout.html:151 bookwyrm/templates/layout.html:155
|
||||
#: bookwyrm/templates/login.html:17
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr "Nom d’utilisateur :"
|
||||
|
||||
#: bookwyrm/templates/layout.html:152 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/layout.html:156
|
||||
#, fuzzy
|
||||
#| msgid "Password:"
|
||||
msgid "password"
|
||||
msgstr "Mot de passe :"
|
||||
|
||||
#: bookwyrm/templates/layout.html:157 bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Mot de passe oublié ?"
|
||||
|
||||
#: bookwyrm/templates/layout.html:160 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/login.html:33
|
||||
msgid "Log in"
|
||||
msgstr "Se connecter"
|
||||
|
||||
#: bookwyrm/templates/layout.html:183
|
||||
#: bookwyrm/templates/layout.html:168
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:191
|
||||
msgid "About this server"
|
||||
msgstr "À propos de ce serveur"
|
||||
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
#: bookwyrm/templates/layout.html:195
|
||||
msgid "Contact site admin"
|
||||
msgstr "Contacter l’administrateur du site"
|
||||
|
||||
#: bookwyrm/templates/layout.html:198
|
||||
#: bookwyrm/templates/layout.html:202
|
||||
#, python-format
|
||||
msgid "Support %(site.name)s on <a href=\"%(site.support_link)s\" target=\"_blank\">%(site.support_title)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:206
|
||||
msgid "BookWyrm is open source software. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr "Bookwyrm est un logiciel libre. Vous pouvez contribuer ou faire des rapports de bogues via <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
|
||||
|
@ -878,10 +901,6 @@ msgstr "Connexion"
|
|||
msgid "Password:"
|
||||
msgstr "Mot de passe :"
|
||||
|
||||
#: bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "Mot de passe oublié ?"
|
||||
|
||||
#: bookwyrm/templates/login.html:49
|
||||
msgid "Contact an administrator to get an invite"
|
||||
msgstr "Contacter un administrateur pour obtenir une invitation"
|
||||
|
@ -895,7 +914,7 @@ msgid "Not Found"
|
|||
msgstr "Introuvable"
|
||||
|
||||
#: bookwyrm/templates/notfound.html:9
|
||||
msgid "The page your requested doesn't seem to exist!"
|
||||
msgid "The page you requested doesn't seem to exist!"
|
||||
msgstr "Il semblerait que la page que vous avez demandée n’existe pas !"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:14
|
||||
|
@ -903,74 +922,62 @@ msgid "Delete notifications"
|
|||
msgstr "Supprimer les notifications"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:49
|
||||
#, fuzzy, python-format
|
||||
#| msgid "favorited your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "favorited your <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "a ajouté votre <a href=\"%(related_path)s\">critique de <em>%(book_title)s</em></a> à ses favoris"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:51
|
||||
#, fuzzy, python-format
|
||||
#| msgid "favorited your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "favorited your <a href=\"%(related_path)s\">comment on <em>%(book_title)s</em></a>"
|
||||
msgstr "a ajouté votre <a href=\"%(related_path)s\">commentaire sur <em>%(book_title)s</em></a> à ses favoris"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:53
|
||||
#, fuzzy, python-format
|
||||
#| msgid "favorited your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "favorited your <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "a ajouté votre <a href=\"%(related_path)s\">citation de <em>%(book_title)s</em></a> à ses favoris"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:55
|
||||
#, fuzzy, python-format
|
||||
#| msgid "favorited your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "favorited your <a href=\"%(related_path)s\">status</a>"
|
||||
msgstr "a ajouté votre <a href=\"%(related_path)s\">statut</a> à ses favoris"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:60
|
||||
#, fuzzy, python-format
|
||||
#| msgid "mentioned you in a <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "mentioned you in a <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "vous a mentionné dans sa <a href=\"%(related_path)s\">critique de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:62
|
||||
#, fuzzy, python-format
|
||||
#| msgid "mentioned you in a <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "mentioned you in a <a href=\"%(related_path)s\">comment on <em>%(book_title)s</em></a>"
|
||||
msgstr "vous a mentionné dans son <a href=\"%(related_path)s\">commentaire sur <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:64
|
||||
#, fuzzy, python-format
|
||||
#| msgid "mentioned you in a <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "mentioned you in a <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "vous a mentionné dans sa <a href=\"%(related_path)s\">citation de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:66
|
||||
#, fuzzy, python-format
|
||||
#| msgid "mentioned you in a <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "mentioned you in a <a href=\"%(related_path)s\">status</a>"
|
||||
msgstr "vous a mentionné dans son <a href=\"%(related_path)s\">statut</a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:71
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "<a href=\"%(related_path)s\">a répondu</a> à votre <a href=\"%(parent_path)s\">critique de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:73
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">comment on <em>%(book_title)s</em></a>"
|
||||
msgstr "<a href=\"%(related_path)s\">a répondu</a> à votre <a href=\"%(parent_path)s\">commentaire sur <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:75
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "<a href=\"%(related_path)s\">a répondu</a> à votre <a href=\"%(parent_path)s\">citation de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:77
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">status</a>"
|
||||
msgstr "<a href=\"%(related_path)s\">a répondu</a> à votre <a href=\"%(parent_path)s\">statut</a>"
|
||||
|
||||
|
@ -983,38 +990,32 @@ msgid "sent you a follow request"
|
|||
msgstr "vous a envoyé une demande d’abonnement"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:90
|
||||
#, fuzzy, python-format
|
||||
#| msgid "boosted your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book.title)s</em></a>"
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "a partagé votre <a href=\"%(related_path)s\">critique de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:92
|
||||
#, fuzzy, python-format
|
||||
#| msgid "boosted your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book.title)s</em></a>"
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book_title)s</em></a>"
|
||||
msgstr "a partagé votre <a href=\"%(related_path)s\">commentaire sur <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:94
|
||||
#, fuzzy, python-format
|
||||
#| msgid "boosted your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book.title)s</em></a>"
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "a partagé votre <a href=\"%(related_path)s\">citation de <em>%(book_title)s</em></a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:96
|
||||
#, fuzzy, python-format
|
||||
#| msgid "boosted your <a href=\"%(related_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">status</a>"
|
||||
msgstr "a partagé votre <a href=\"%(related_path)s\">statut</a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:100
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid " added <em><a href=\"%(book_path)s\">%(book_title)s</a></em> to your list \"<a href=\"%(list_path)s\">%(list_name)s</a>\""
|
||||
msgstr " a ajouté <em><a href=\"%(book_path)s\">%(book_title)s</a></em> à votre liste « <a href=\"%(list_path)s\">%(list_name)s</a> »"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:102
|
||||
#, fuzzy, python-format
|
||||
#| msgid "<a href=\"%(related_path)s\">replied</a> to your <a href=\"%(parent_path)s\">%(preview_name)s</a>"
|
||||
#, python-format
|
||||
msgid " suggested adding <em><a href=\"%(book_path)s\">%(book_title)s</a></em> to your list \"<a href=\"%(list_path)s/curate\">%(list_name)s</a>\""
|
||||
msgstr " a suggégré l’ajout de <em><a href=\"%(book_path)s\">%(book_title)s</a></em> à votre liste « <a href=\"%(list_path)s/curate\">%(list_name)s</a> »"
|
||||
|
||||
|
@ -1108,8 +1109,6 @@ msgid "Relationships"
|
|||
msgstr "Relations"
|
||||
|
||||
#: bookwyrm/templates/search_results.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Search Results for \"%(query)s\""
|
||||
msgid "Search Results"
|
||||
msgstr "Résultats de recherche"
|
||||
|
||||
|
@ -1158,8 +1157,6 @@ msgid "No lists found for \"%(query)s\""
|
|||
msgstr "Aucune liste trouvée pour « %(query)s »"
|
||||
|
||||
#: bookwyrm/templates/settings/admin_layout.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Registration"
|
||||
msgid "Administration"
|
||||
msgstr "Administration"
|
||||
|
||||
|
@ -1313,8 +1310,7 @@ msgid "Un-block"
|
|||
msgstr "Débloquer"
|
||||
|
||||
#: bookwyrm/templates/snippets/book_titleby.html:3
|
||||
#, fuzzy, python-format
|
||||
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
||||
#, python-format
|
||||
msgid "<a href=\"%(path)s\">%(title)s</a> by "
|
||||
msgstr "<a href=\"%(path)s\">%(title)s</a> par "
|
||||
|
||||
|
@ -1363,8 +1359,6 @@ msgid "No rating"
|
|||
msgstr "Aucune note"
|
||||
|
||||
#: bookwyrm/templates/snippets/create_status_form.html:54
|
||||
#, fuzzy
|
||||
#| msgid "Spoiler alert:"
|
||||
msgid "Include spoiler alert"
|
||||
msgstr "Afficher une alerte spoiler"
|
||||
|
||||
|
@ -1704,17 +1698,17 @@ msgstr "partagé"
|
|||
msgid "Reply"
|
||||
msgstr "Répondre"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:16
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:12
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:18
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:15
|
||||
msgid "Show more"
|
||||
msgstr "Déplier"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:23
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:18
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:25
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:25
|
||||
msgid "Show less"
|
||||
msgstr "Replier"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:44
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:46
|
||||
msgid "Open image in new window"
|
||||
msgstr "Ouvrir l’image dans une nouvelle fenêtre"
|
||||
|
||||
|
@ -1724,8 +1718,6 @@ msgid "More options"
|
|||
msgstr "Plus d’options"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_options.html:17
|
||||
#, fuzzy
|
||||
#| msgid "Delete post"
|
||||
msgid "Delete status"
|
||||
msgstr "Supprimer le statut"
|
||||
|
||||
|
@ -1749,8 +1741,6 @@ msgstr "Livres tagués « %(tag.name)s »"
|
|||
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:5
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:22
|
||||
#, fuzzy
|
||||
#| msgid "Create shelf"
|
||||
msgid "Create Shelf"
|
||||
msgstr "Créer l’étagère"
|
||||
|
||||
|
@ -1764,8 +1754,6 @@ msgstr "Mettre l’étagère à jour"
|
|||
|
||||
#: bookwyrm/templates/user/followers.html:7
|
||||
#: bookwyrm/templates/user/following.html:7 bookwyrm/templates/user/user.html:9
|
||||
#, fuzzy
|
||||
#| msgid "User profile"
|
||||
msgid "User Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
|
@ -1784,8 +1772,6 @@ msgid "%(username)s isn't following any users"
|
|||
msgstr "%(username)s n’est abonné(e) à personne"
|
||||
|
||||
#: bookwyrm/templates/user/lists.html:9
|
||||
#, fuzzy
|
||||
#| msgid "Your lists"
|
||||
msgid "Your Lists"
|
||||
msgstr "Vos listes"
|
||||
|
||||
|
@ -1800,14 +1786,11 @@ msgid "Create list"
|
|||
msgstr "Créer une liste"
|
||||
|
||||
#: bookwyrm/templates/user/shelf.html:9
|
||||
#, fuzzy
|
||||
#| msgid "Your shelves"
|
||||
msgid "Your Shelves"
|
||||
msgstr "Vos étagères"
|
||||
|
||||
#: bookwyrm/templates/user/shelf.html:11
|
||||
#, fuzzy, python-format
|
||||
#| msgid "%(username)s has no followers"
|
||||
#, python-format
|
||||
msgid "%(username)s: Shelves"
|
||||
msgstr "%(username)s : Étagères"
|
||||
|
||||
|
@ -1816,8 +1799,6 @@ msgid "Create shelf"
|
|||
msgstr "Créer l’étagère"
|
||||
|
||||
#: bookwyrm/templates/user/shelf.html:54
|
||||
#, fuzzy
|
||||
#| msgid "Edit Shelf"
|
||||
msgid "Edit shelf"
|
||||
msgstr "Modifier l’étagère"
|
||||
|
||||
|
|
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: 0.1.1\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-03-02 21:36+0000\n"
|
||||
"POT-Creation-Date: 2021-03-04 22:24+0000\n"
|
||||
"PO-Revision-Date: 2021-03-02 10:35+0000\n"
|
||||
"Last-Translator: Kana <gudzpoz@live.com>\n"
|
||||
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
||||
|
@ -55,11 +55,9 @@ msgstr ""
|
|||
msgid "%(value)s is not a valid username"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/models/fields.py:164
|
||||
#, fuzzy
|
||||
#| msgid "Username:"
|
||||
#: bookwyrm/models/fields.py:164 bookwyrm/templates/layout.html:152
|
||||
msgid "username"
|
||||
msgstr "用户名:"
|
||||
msgstr "用户名"
|
||||
|
||||
#: bookwyrm/models/fields.py:169
|
||||
msgid "A user with that username already exists."
|
||||
|
@ -74,10 +72,14 @@ msgid "German"
|
|||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:144
|
||||
msgid "French"
|
||||
msgid "Spanish"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:145
|
||||
msgid "French"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/settings.py:146
|
||||
msgid "Simplified Chinese"
|
||||
msgstr ""
|
||||
|
||||
|
@ -96,6 +98,8 @@ msgid "Books by %(name)s"
|
|||
msgstr "%(name)s 所著的书"
|
||||
|
||||
#: bookwyrm/templates/book.html:21
|
||||
#: bookwyrm/templates/discover/large-book.html:12
|
||||
#: bookwyrm/templates/discover/small-book.html:9
|
||||
msgid "by"
|
||||
msgstr ""
|
||||
|
||||
|
@ -427,7 +431,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
|||
msgstr "与 <a href=\"%(path)s\">%(username)s</a> 私信"
|
||||
|
||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||
#: bookwyrm/templates/layout.html:79
|
||||
#: bookwyrm/templates/layout.html:87
|
||||
msgid "Direct Messages"
|
||||
msgstr "私信"
|
||||
|
||||
|
@ -537,7 +541,7 @@ msgid "%(username)s's %(year)s Books"
|
|||
msgstr "%(username)s 在 %(year)s 的书目"
|
||||
|
||||
#: bookwyrm/templates/import.html:5 bookwyrm/templates/import.html:9
|
||||
#: bookwyrm/templates/layout.html:94
|
||||
#: bookwyrm/templates/layout.html:102
|
||||
msgid "Import Books"
|
||||
msgstr "导入书目"
|
||||
|
||||
|
@ -660,55 +664,72 @@ msgstr "你的书架"
|
|||
msgid "Feed"
|
||||
msgstr "动态"
|
||||
|
||||
#: bookwyrm/templates/layout.html:84
|
||||
#: bookwyrm/templates/layout.html:92
|
||||
#: bookwyrm/templates/preferences/preferences_layout.html:14
|
||||
msgid "Profile"
|
||||
msgstr "个人资料"
|
||||
|
||||
#: bookwyrm/templates/layout.html:89
|
||||
#: bookwyrm/templates/layout.html:97
|
||||
msgid "Settings"
|
||||
msgstr "设置"
|
||||
|
||||
#: bookwyrm/templates/layout.html:103
|
||||
#: bookwyrm/templates/layout.html:111
|
||||
#: bookwyrm/templates/settings/admin_layout.html:19
|
||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||
msgid "Invites"
|
||||
msgstr "邀请"
|
||||
|
||||
#: bookwyrm/templates/layout.html:110
|
||||
#: bookwyrm/templates/layout.html:118
|
||||
msgid "Site Configuration"
|
||||
msgstr "站点配置"
|
||||
|
||||
#: bookwyrm/templates/layout.html:117
|
||||
#: bookwyrm/templates/layout.html:125
|
||||
msgid "Log out"
|
||||
msgstr "登出"
|
||||
|
||||
#: bookwyrm/templates/layout.html:125 bookwyrm/templates/layout.html:126
|
||||
#: bookwyrm/templates/layout.html:133 bookwyrm/templates/layout.html:134
|
||||
#: bookwyrm/templates/notifications.html:6
|
||||
#: bookwyrm/templates/notifications.html:10
|
||||
msgid "Notifications"
|
||||
msgstr "通知"
|
||||
|
||||
#: bookwyrm/templates/layout.html:143 bookwyrm/templates/layout.html:147
|
||||
#: bookwyrm/templates/layout.html:151 bookwyrm/templates/layout.html:155
|
||||
#: bookwyrm/templates/login.html:17
|
||||
#: bookwyrm/templates/snippets/register_form.html:4
|
||||
msgid "Username:"
|
||||
msgstr "用户名:"
|
||||
|
||||
#: bookwyrm/templates/layout.html:152 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/layout.html:156
|
||||
msgid "password"
|
||||
msgstr "密码"
|
||||
|
||||
#: bookwyrm/templates/layout.html:157 bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "忘记了密码?"
|
||||
|
||||
#: bookwyrm/templates/layout.html:160 bookwyrm/templates/login.html:10
|
||||
#: bookwyrm/templates/login.html:33
|
||||
msgid "Log in"
|
||||
msgstr "登录"
|
||||
|
||||
#: bookwyrm/templates/layout.html:183
|
||||
#: bookwyrm/templates/layout.html:168
|
||||
msgid "Join"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:191
|
||||
msgid "About this server"
|
||||
msgstr "关于本服务器"
|
||||
|
||||
#: bookwyrm/templates/layout.html:187
|
||||
#: bookwyrm/templates/layout.html:195
|
||||
msgid "Contact site admin"
|
||||
msgstr "联系站点管理员"
|
||||
|
||||
#: bookwyrm/templates/layout.html:198
|
||||
#: bookwyrm/templates/layout.html:202
|
||||
#, python-format
|
||||
msgid "Support %(site.name)s on <a href=\"%(site.support_link)s\" target=\"_blank\">%(site.support_title)s</a>"
|
||||
msgstr ""
|
||||
|
||||
#: bookwyrm/templates/layout.html:206
|
||||
msgid "BookWyrm is open source software. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||
msgstr "BookWyrm 是开源软件。你可以在<a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> 贡献或报告问题。"
|
||||
|
||||
|
@ -854,10 +875,6 @@ msgstr "登录"
|
|||
msgid "Password:"
|
||||
msgstr "密码:"
|
||||
|
||||
#: bookwyrm/templates/login.html:36
|
||||
msgid "Forgot your password?"
|
||||
msgstr "忘记了密码?"
|
||||
|
||||
#: bookwyrm/templates/login.html:49
|
||||
msgid "Contact an administrator to get an invite"
|
||||
msgstr "联系管理员以取得邀请"
|
||||
|
@ -871,7 +888,7 @@ msgid "Not Found"
|
|||
msgstr "未找到"
|
||||
|
||||
#: bookwyrm/templates/notfound.html:9
|
||||
msgid "The page your requested doesn't seem to exist!"
|
||||
msgid "The page you requested doesn't seem to exist!"
|
||||
msgstr "你请求的页面似乎并不存在!"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:14
|
||||
|
@ -948,18 +965,18 @@ msgstr "向你发送了关注请求"
|
|||
|
||||
#: bookwyrm/templates/notifications.html:90
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book.title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book.title)s</em> 的书评</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">review of <em>%(book_title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book_title)s</em> 的书评</a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:92
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book.title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book.title)s</em> 的评论</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">comment on<em>%(book_title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book_title)s</em> 的评论</a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:94
|
||||
#, python-format
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book.title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book.title)s</em> 的引用</a>"
|
||||
msgid "boosted your <a href=\"%(related_path)s\">quote from <em>%(book_title)s</em></a>"
|
||||
msgstr "转发了你的 <a href=\"%(related_path)s\">对 <em>%(book_title)s</em> 的引用</a>"
|
||||
|
||||
#: bookwyrm/templates/notifications.html:96
|
||||
#, python-format
|
||||
|
@ -989,7 +1006,6 @@ msgstr "你什么也没错过!"
|
|||
#: bookwyrm/templates/password_reset.html:10
|
||||
#: bookwyrm/templates/password_reset_request.html:4
|
||||
#: bookwyrm/templates/password_reset_request.html:10
|
||||
#, fuzzy
|
||||
msgid "Reset Password"
|
||||
msgstr "重设密码"
|
||||
|
||||
|
@ -1647,17 +1663,17 @@ msgstr "转发了"
|
|||
msgid "Reply"
|
||||
msgstr "回复"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:16
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:12
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:18
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:15
|
||||
msgid "Show more"
|
||||
msgstr "显示更多"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:23
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:18
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:25
|
||||
#: bookwyrm/templates/snippets/trimmed_text.html:25
|
||||
msgid "Show less"
|
||||
msgstr "显示更少"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:44
|
||||
#: bookwyrm/templates/snippets/status/status_content.html:46
|
||||
msgid "Open image in new window"
|
||||
msgstr "在新窗口中打开图像"
|
||||
|
||||
|
@ -1667,8 +1683,6 @@ msgid "More options"
|
|||
msgstr "更多选项"
|
||||
|
||||
#: bookwyrm/templates/snippets/status/status_options.html:17
|
||||
#, fuzzy
|
||||
#| msgid "Delete post"
|
||||
msgid "Delete status"
|
||||
msgstr "删除发文"
|
||||
|
||||
|
@ -1692,8 +1706,6 @@ msgstr "标有 \"%(tag.name)s\" 标签的书"
|
|||
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:5
|
||||
#: bookwyrm/templates/user/create_shelf_form.html:22
|
||||
#, fuzzy
|
||||
#| msgid "Create shelf"
|
||||
msgid "Create Shelf"
|
||||
msgstr "创建书架"
|
||||
|
||||
|
|
Loading…
Reference in a new issue