mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2025-01-10 09:15:28 +00:00
Merge branch 'main' into production
This commit is contained in:
commit
697924ebc6
61 changed files with 697 additions and 495 deletions
2
.github/workflows/pylint.yml
vendored
2
.github/workflows/pylint.yml
vendored
|
@ -24,5 +24,5 @@ jobs:
|
||||||
pip install pylint
|
pip install pylint
|
||||||
- name: Analysing the code with pylint
|
- name: Analysing the code with pylint
|
||||||
run: |
|
run: |
|
||||||
pylint bookwyrm/ --ignore=migrations,tests --disable=E1101,E1135,E1136,R0903,R0901,R0902,W0707,W0511,W0406,R0401,R0801,C0209
|
pylint bookwyrm/ --ignore=migrations,tests --disable=E1101,E1135,E1136,R0903,R0901,R0902,W0707,W0511,W0406,R0401,R0801
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ class ActivityObject:
|
||||||
except KeyError:
|
except KeyError:
|
||||||
if field.default == MISSING and field.default_factory == MISSING:
|
if field.default == MISSING and field.default_factory == MISSING:
|
||||||
raise ActivitySerializerError(
|
raise ActivitySerializerError(
|
||||||
"Missing required field: %s" % field.name
|
f"Missing required field: {field.name}"
|
||||||
)
|
)
|
||||||
value = field.default
|
value = field.default
|
||||||
setattr(self, field.name, value)
|
setattr(self, field.name, value)
|
||||||
|
@ -219,8 +219,8 @@ def set_related_field(
|
||||||
model_name, origin_model_name, related_field_name, related_remote_id, data
|
model_name, origin_model_name, related_field_name, related_remote_id, data
|
||||||
):
|
):
|
||||||
"""load reverse related fields (editions, attachments) without blocking"""
|
"""load reverse related fields (editions, attachments) without blocking"""
|
||||||
model = apps.get_model("bookwyrm.%s" % model_name, require_ready=True)
|
model = apps.get_model(f"bookwyrm.{model_name}", require_ready=True)
|
||||||
origin_model = apps.get_model("bookwyrm.%s" % origin_model_name, require_ready=True)
|
origin_model = apps.get_model(f"bookwyrm.{origin_model_name}", require_ready=True)
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
if isinstance(data, str):
|
if isinstance(data, str):
|
||||||
|
@ -234,7 +234,7 @@ def set_related_field(
|
||||||
# this must exist because it's the object that triggered this function
|
# this must exist because it's the object that triggered this function
|
||||||
instance = origin_model.find_existing_by_remote_id(related_remote_id)
|
instance = origin_model.find_existing_by_remote_id(related_remote_id)
|
||||||
if not instance:
|
if not instance:
|
||||||
raise ValueError("Invalid related remote id: %s" % related_remote_id)
|
raise ValueError(f"Invalid related remote id: {related_remote_id}")
|
||||||
|
|
||||||
# set the origin's remote id on the activity so it will be there when
|
# set the origin's remote id on the activity so it will be there when
|
||||||
# the model instance is created
|
# the model instance is created
|
||||||
|
@ -265,7 +265,7 @@ def get_model_from_type(activity_type):
|
||||||
]
|
]
|
||||||
if not model:
|
if not model:
|
||||||
raise ActivitySerializerError(
|
raise ActivitySerializerError(
|
||||||
'No model found for activity type "%s"' % activity_type
|
f'No model found for activity type "{activity_type}"'
|
||||||
)
|
)
|
||||||
return model[0]
|
return model[0]
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ def resolve_remote_id(
|
||||||
data = get_data(remote_id)
|
data = get_data(remote_id)
|
||||||
except ConnectorException:
|
except ConnectorException:
|
||||||
raise ActivitySerializerError(
|
raise ActivitySerializerError(
|
||||||
"Could not connect to host for remote_id in: %s" % (remote_id)
|
f"Could not connect to host for remote_id: {remote_id}"
|
||||||
)
|
)
|
||||||
# determine the model implicitly, if not provided
|
# determine the model implicitly, if not provided
|
||||||
# or if it's a model with subclasses like Status, check again
|
# or if it's a model with subclasses like Status, check again
|
||||||
|
|
|
@ -16,11 +16,12 @@ class ActivityStream(RedisStore):
|
||||||
|
|
||||||
def stream_id(self, user):
|
def stream_id(self, user):
|
||||||
"""the redis key for this user's instance of this stream"""
|
"""the redis key for this user's instance of this stream"""
|
||||||
return "{}-{}".format(user.id, self.key)
|
return f"{user.id}-{self.key}"
|
||||||
|
|
||||||
def unread_id(self, user):
|
def unread_id(self, user):
|
||||||
"""the redis key for this user's unread count for this stream"""
|
"""the redis key for this user's unread count for this stream"""
|
||||||
return "{}-unread".format(self.stream_id(user))
|
stream_id = self.stream_id(user)
|
||||||
|
return f"{stream_id}-unread"
|
||||||
|
|
||||||
def get_rank(self, obj): # pylint: disable=no-self-use
|
def get_rank(self, obj): # pylint: disable=no-self-use
|
||||||
"""statuses are sorted by date published"""
|
"""statuses are sorted by date published"""
|
||||||
|
|
|
@ -43,7 +43,7 @@ class AbstractMinimalConnector(ABC):
|
||||||
params["min_confidence"] = min_confidence
|
params["min_confidence"] = min_confidence
|
||||||
|
|
||||||
data = self.get_search_data(
|
data = self.get_search_data(
|
||||||
"%s%s" % (self.search_url, query),
|
f"{self.search_url}{query}",
|
||||||
params=params,
|
params=params,
|
||||||
timeout=timeout,
|
timeout=timeout,
|
||||||
)
|
)
|
||||||
|
@ -57,7 +57,7 @@ class AbstractMinimalConnector(ABC):
|
||||||
"""isbn search"""
|
"""isbn search"""
|
||||||
params = {}
|
params = {}
|
||||||
data = self.get_search_data(
|
data = self.get_search_data(
|
||||||
"%s%s" % (self.isbn_search_url, query),
|
f"{self.isbn_search_url}{query}",
|
||||||
params=params,
|
params=params,
|
||||||
)
|
)
|
||||||
results = []
|
results = []
|
||||||
|
@ -131,7 +131,7 @@ class AbstractConnector(AbstractMinimalConnector):
|
||||||
work_data = data
|
work_data = data
|
||||||
|
|
||||||
if not work_data or not edition_data:
|
if not work_data or not edition_data:
|
||||||
raise ConnectorException("Unable to load book data: %s" % remote_id)
|
raise ConnectorException(f"Unable to load book data: {remote_id}")
|
||||||
|
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
# create activitypub object
|
# create activitypub object
|
||||||
|
@ -222,9 +222,7 @@ def get_data(url, params=None, timeout=10):
|
||||||
"""wrapper for request.get"""
|
"""wrapper for request.get"""
|
||||||
# check if the url is blocked
|
# check if the url is blocked
|
||||||
if models.FederatedServer.is_blocked(url):
|
if models.FederatedServer.is_blocked(url):
|
||||||
raise ConnectorException(
|
raise ConnectorException(f"Attempting to load data from blocked url: {url}")
|
||||||
"Attempting to load data from blocked url: {:s}".format(url)
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
resp = requests.get(
|
resp = requests.get(
|
||||||
|
@ -283,6 +281,7 @@ class SearchResult:
|
||||||
confidence: int = 1
|
confidence: int = 1
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# pylint: disable=consider-using-f-string
|
||||||
return "<SearchResult key={!r} title={!r} author={!r}>".format(
|
return "<SearchResult key={!r} title={!r} author={!r}>".format(
|
||||||
self.key, self.title, self.author
|
self.key, self.title, self.author
|
||||||
)
|
)
|
||||||
|
|
|
@ -109,10 +109,10 @@ def get_or_create_connector(remote_id):
|
||||||
connector_info = models.Connector.objects.create(
|
connector_info = models.Connector.objects.create(
|
||||||
identifier=identifier,
|
identifier=identifier,
|
||||||
connector_file="bookwyrm_connector",
|
connector_file="bookwyrm_connector",
|
||||||
base_url="https://%s" % identifier,
|
base_url=f"https://{identifier}",
|
||||||
books_url="https://%s/book" % identifier,
|
books_url=f"https://{identifier}/book",
|
||||||
covers_url="https://%s/images/covers" % identifier,
|
covers_url=f"https://{identifier}/images/covers",
|
||||||
search_url="https://%s/search?q=" % identifier,
|
search_url=f"https://{identifier}/search?q=",
|
||||||
priority=2,
|
priority=2,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ def load_more_data(connector_id, book_id):
|
||||||
def load_connector(connector_info):
|
def load_connector(connector_info):
|
||||||
"""instantiate the connector class"""
|
"""instantiate the connector class"""
|
||||||
connector = importlib.import_module(
|
connector = importlib.import_module(
|
||||||
"bookwyrm.connectors.%s" % connector_info.connector_file
|
f"bookwyrm.connectors.{connector_info.connector_file}"
|
||||||
)
|
)
|
||||||
return connector.Connector(connector_info.identifier)
|
return connector.Connector(connector_info.identifier)
|
||||||
|
|
||||||
|
@ -141,4 +141,4 @@ def load_connector(connector_info):
|
||||||
def create_connector(sender, instance, created, *args, **kwargs):
|
def create_connector(sender, instance, created, *args, **kwargs):
|
||||||
"""create a connector to an external bookwyrm server"""
|
"""create a connector to an external bookwyrm server"""
|
||||||
if instance.application_type == "bookwyrm":
|
if instance.application_type == "bookwyrm":
|
||||||
get_or_create_connector("https://{:s}".format(instance.server_name))
|
get_or_create_connector(f"https://{instance.server_name}")
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Connector(AbstractConnector):
|
||||||
|
|
||||||
def get_remote_id(self, value):
|
def get_remote_id(self, value):
|
||||||
"""convert an id/uri into a url"""
|
"""convert an id/uri into a url"""
|
||||||
return "{:s}?action=by-uris&uris={:s}".format(self.books_url, value)
|
return f"{self.books_url}?action=by-uris&uris={value}"
|
||||||
|
|
||||||
def get_book_data(self, remote_id):
|
def get_book_data(self, remote_id):
|
||||||
data = get_data(remote_id)
|
data = get_data(remote_id)
|
||||||
|
@ -87,11 +87,7 @@ class Connector(AbstractConnector):
|
||||||
|
|
||||||
def format_search_result(self, search_result):
|
def format_search_result(self, search_result):
|
||||||
images = search_result.get("image")
|
images = search_result.get("image")
|
||||||
cover = (
|
cover = f"{self.covers_url}/img/entities/{images[0]}" if images else None
|
||||||
"{:s}/img/entities/{:s}".format(self.covers_url, images[0])
|
|
||||||
if images
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
# a deeply messy translation of inventaire's scores
|
# a deeply messy translation of inventaire's scores
|
||||||
confidence = float(search_result.get("_score", 0.1))
|
confidence = float(search_result.get("_score", 0.1))
|
||||||
confidence = 0.1 if confidence < 150 else 0.999
|
confidence = 0.1 if confidence < 150 else 0.999
|
||||||
|
@ -99,9 +95,7 @@ class Connector(AbstractConnector):
|
||||||
title=search_result.get("label"),
|
title=search_result.get("label"),
|
||||||
key=self.get_remote_id(search_result.get("uri")),
|
key=self.get_remote_id(search_result.get("uri")),
|
||||||
author=search_result.get("description"),
|
author=search_result.get("description"),
|
||||||
view_link="{:s}/entity/{:s}".format(
|
view_link=f"{self.base_url}/entity/{search_result.get('uri')}",
|
||||||
self.base_url, search_result.get("uri")
|
|
||||||
),
|
|
||||||
cover=cover,
|
cover=cover,
|
||||||
confidence=confidence,
|
confidence=confidence,
|
||||||
connector=self,
|
connector=self,
|
||||||
|
@ -123,9 +117,7 @@ class Connector(AbstractConnector):
|
||||||
title=title[0],
|
title=title[0],
|
||||||
key=self.get_remote_id(search_result.get("uri")),
|
key=self.get_remote_id(search_result.get("uri")),
|
||||||
author=search_result.get("description"),
|
author=search_result.get("description"),
|
||||||
view_link="{:s}/entity/{:s}".format(
|
view_link=f"{self.base_url}/entity/{search_result.get('uri')}",
|
||||||
self.base_url, search_result.get("uri")
|
|
||||||
),
|
|
||||||
cover=self.get_cover_url(search_result.get("image")),
|
cover=self.get_cover_url(search_result.get("image")),
|
||||||
connector=self,
|
connector=self,
|
||||||
)
|
)
|
||||||
|
@ -135,11 +127,7 @@ class Connector(AbstractConnector):
|
||||||
|
|
||||||
def load_edition_data(self, work_uri):
|
def load_edition_data(self, work_uri):
|
||||||
"""get a list of editions for a work"""
|
"""get a list of editions for a work"""
|
||||||
url = (
|
url = f"{self.books_url}?action=reverse-claims&property=wdt:P629&value={work_uri}&sort=true"
|
||||||
"{:s}?action=reverse-claims&property=wdt:P629&value={:s}&sort=true".format(
|
|
||||||
self.books_url, work_uri
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return get_data(url)
|
return get_data(url)
|
||||||
|
|
||||||
def get_edition_from_work_data(self, data):
|
def get_edition_from_work_data(self, data):
|
||||||
|
@ -195,7 +183,7 @@ class Connector(AbstractConnector):
|
||||||
# cover may or may not be an absolute url already
|
# cover may or may not be an absolute url already
|
||||||
if re.match(r"^http", cover_id):
|
if re.match(r"^http", cover_id):
|
||||||
return cover_id
|
return cover_id
|
||||||
return "%s%s" % (self.covers_url, cover_id)
|
return f"{self.covers_url}{cover_id}"
|
||||||
|
|
||||||
def resolve_keys(self, keys):
|
def resolve_keys(self, keys):
|
||||||
"""cool, it's "wd:Q3156592" now what the heck does that mean"""
|
"""cool, it's "wd:Q3156592" now what the heck does that mean"""
|
||||||
|
@ -213,9 +201,7 @@ class Connector(AbstractConnector):
|
||||||
link = links.get("enwiki")
|
link = links.get("enwiki")
|
||||||
if not link:
|
if not link:
|
||||||
return ""
|
return ""
|
||||||
url = "{:s}/api/data?action=wp-extract&lang=en&title={:s}".format(
|
url = f"{self.base_url}/api/data?action=wp-extract&lang=en&title={link}"
|
||||||
self.base_url, link
|
|
||||||
)
|
|
||||||
try:
|
try:
|
||||||
data = get_data(url)
|
data = get_data(url)
|
||||||
except ConnectorException:
|
except ConnectorException:
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Connector(AbstractConnector):
|
||||||
key = data["key"]
|
key = data["key"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ConnectorException("Invalid book data")
|
raise ConnectorException("Invalid book data")
|
||||||
return "%s%s" % (self.books_url, key)
|
return f"{self.books_url}{key}"
|
||||||
|
|
||||||
def is_work_data(self, data):
|
def is_work_data(self, data):
|
||||||
return bool(re.match(r"^[\/\w]+OL\d+W$", data["key"]))
|
return bool(re.match(r"^[\/\w]+OL\d+W$", data["key"]))
|
||||||
|
@ -81,7 +81,7 @@ class Connector(AbstractConnector):
|
||||||
key = data["key"]
|
key = data["key"]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise ConnectorException("Invalid book data")
|
raise ConnectorException("Invalid book data")
|
||||||
url = "%s%s/editions" % (self.books_url, key)
|
url = f"{self.books_url}{key}/editions"
|
||||||
data = self.get_book_data(url)
|
data = self.get_book_data(url)
|
||||||
edition = pick_default_edition(data["entries"])
|
edition = pick_default_edition(data["entries"])
|
||||||
if not edition:
|
if not edition:
|
||||||
|
@ -93,7 +93,7 @@ class Connector(AbstractConnector):
|
||||||
key = data["works"][0]["key"]
|
key = data["works"][0]["key"]
|
||||||
except (IndexError, KeyError):
|
except (IndexError, KeyError):
|
||||||
raise ConnectorException("No work found for edition")
|
raise ConnectorException("No work found for edition")
|
||||||
url = "%s%s" % (self.books_url, key)
|
url = f"{self.books_url}{key}"
|
||||||
return self.get_book_data(url)
|
return self.get_book_data(url)
|
||||||
|
|
||||||
def get_authors_from_data(self, data):
|
def get_authors_from_data(self, data):
|
||||||
|
@ -102,7 +102,7 @@ class Connector(AbstractConnector):
|
||||||
author_blob = author_blob.get("author", author_blob)
|
author_blob = author_blob.get("author", author_blob)
|
||||||
# this id is "/authors/OL1234567A"
|
# this id is "/authors/OL1234567A"
|
||||||
author_id = author_blob["key"]
|
author_id = author_blob["key"]
|
||||||
url = "%s%s" % (self.base_url, author_id)
|
url = f"{self.base_url}{author_id}"
|
||||||
author = self.get_or_create_author(url)
|
author = self.get_or_create_author(url)
|
||||||
if not author:
|
if not author:
|
||||||
continue
|
continue
|
||||||
|
@ -113,8 +113,8 @@ class Connector(AbstractConnector):
|
||||||
if not cover_blob:
|
if not cover_blob:
|
||||||
return None
|
return None
|
||||||
cover_id = cover_blob[0]
|
cover_id = cover_blob[0]
|
||||||
image_name = "%s-%s.jpg" % (cover_id, size)
|
image_name = f"{cover_id}-{size}.jpg"
|
||||||
return "%s/b/id/%s" % (self.covers_url, image_name)
|
return f"{self.covers_url}/b/id/{image_name}"
|
||||||
|
|
||||||
def parse_search_data(self, data):
|
def parse_search_data(self, data):
|
||||||
return data.get("docs")
|
return data.get("docs")
|
||||||
|
@ -152,7 +152,7 @@ class Connector(AbstractConnector):
|
||||||
|
|
||||||
def load_edition_data(self, olkey):
|
def load_edition_data(self, olkey):
|
||||||
"""query openlibrary for editions of a work"""
|
"""query openlibrary for editions of a work"""
|
||||||
url = "%s/works/%s/editions" % (self.books_url, olkey)
|
url = f"{self.books_url}/works/{olkey}/editions"
|
||||||
return self.get_book_data(url)
|
return self.get_book_data(url)
|
||||||
|
|
||||||
def expand_book_data(self, book):
|
def expand_book_data(self, book):
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Connector(AbstractConnector):
|
||||||
def format_search_result(self, search_result):
|
def format_search_result(self, search_result):
|
||||||
cover = None
|
cover = None
|
||||||
if search_result.cover:
|
if search_result.cover:
|
||||||
cover = "%s%s" % (self.covers_url, search_result.cover)
|
cover = f"{self.covers_url}{search_result.cover}"
|
||||||
|
|
||||||
return SearchResult(
|
return SearchResult(
|
||||||
title=search_result.title,
|
title=search_result.title,
|
||||||
|
|
|
@ -11,7 +11,7 @@ def email_data():
|
||||||
"""fields every email needs"""
|
"""fields every email needs"""
|
||||||
site = models.SiteSettings.objects.get()
|
site = models.SiteSettings.objects.get()
|
||||||
if site.logo_small:
|
if site.logo_small:
|
||||||
logo_path = "/images/{}".format(site.logo_small.url)
|
logo_path = f"/images/{site.logo_small.url}"
|
||||||
else:
|
else:
|
||||||
logo_path = "/static/images/logo-small.png"
|
logo_path = "/static/images/logo-small.png"
|
||||||
|
|
||||||
|
@ -48,18 +48,12 @@ def password_reset_email(reset_code):
|
||||||
|
|
||||||
def format_email(email_name, data):
|
def format_email(email_name, data):
|
||||||
"""render the email templates"""
|
"""render the email templates"""
|
||||||
subject = (
|
subject = get_template(f"email/{email_name}/subject.html").render(data).strip()
|
||||||
get_template("email/{}/subject.html".format(email_name)).render(data).strip()
|
|
||||||
)
|
|
||||||
html_content = (
|
html_content = (
|
||||||
get_template("email/{}/html_content.html".format(email_name))
|
get_template(f"email/{email_name}/html_content.html").render(data).strip()
|
||||||
.render(data)
|
|
||||||
.strip()
|
|
||||||
)
|
)
|
||||||
text_content = (
|
text_content = (
|
||||||
get_template("email/{}/text_content.html".format(email_name))
|
get_template(f"email/{email_name}/text_content.html").render(data).strip()
|
||||||
.render(data)
|
|
||||||
.strip()
|
|
||||||
)
|
)
|
||||||
return (subject, html_content, text_content)
|
return (subject, html_content, text_content)
|
||||||
|
|
||||||
|
|
|
@ -260,10 +260,7 @@ class CreateInviteForm(CustomForm):
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
"use_limit": widgets.Select(
|
"use_limit": widgets.Select(
|
||||||
choices=[
|
choices=[(i, _(f"{i} uses")) for i in [1, 5, 10, 25, 50, 100]]
|
||||||
(i, _("%(count)d uses" % {"count": i}))
|
|
||||||
for i in [1, 5, 10, 25, 50, 100]
|
|
||||||
]
|
|
||||||
+ [(None, _("Unlimited"))]
|
+ [(None, _("Unlimited"))]
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,6 +127,7 @@ def handle_imported_book(source, user, item, include_reviews, privacy):
|
||||||
# but "now" is a bad guess
|
# but "now" is a bad guess
|
||||||
published_date_guess = item.date_read or item.date_added
|
published_date_guess = item.date_read or item.date_added
|
||||||
if item.review:
|
if item.review:
|
||||||
|
# pylint: disable=consider-using-f-string
|
||||||
review_title = (
|
review_title = (
|
||||||
"Review of {!r} on {!r}".format(
|
"Review of {!r} on {!r}".format(
|
||||||
item.book.title,
|
item.book.title,
|
||||||
|
|
|
@ -266,7 +266,7 @@ class ObjectMixin(ActivitypubMixin):
|
||||||
signed_message = signer.sign(SHA256.new(content.encode("utf8")))
|
signed_message = signer.sign(SHA256.new(content.encode("utf8")))
|
||||||
|
|
||||||
signature = activitypub.Signature(
|
signature = activitypub.Signature(
|
||||||
creator="%s#main-key" % user.remote_id,
|
creator=f"{user.remote_id}#main-key",
|
||||||
created=activity_object.published,
|
created=activity_object.published,
|
||||||
signatureValue=b64encode(signed_message).decode("utf8"),
|
signatureValue=b64encode(signed_message).decode("utf8"),
|
||||||
)
|
)
|
||||||
|
@ -285,16 +285,16 @@ class ObjectMixin(ActivitypubMixin):
|
||||||
return activitypub.Delete(
|
return activitypub.Delete(
|
||||||
id=self.remote_id + "/activity",
|
id=self.remote_id + "/activity",
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
to=["%s/followers" % user.remote_id],
|
to=[f"{user.remote_id}/followers"],
|
||||||
cc=["https://www.w3.org/ns/activitystreams#Public"],
|
cc=["https://www.w3.org/ns/activitystreams#Public"],
|
||||||
object=self,
|
object=self,
|
||||||
).serialize()
|
).serialize()
|
||||||
|
|
||||||
def to_update_activity(self, user):
|
def to_update_activity(self, user):
|
||||||
"""wrapper for Updates to an activity"""
|
"""wrapper for Updates to an activity"""
|
||||||
activity_id = "%s#update/%s" % (self.remote_id, uuid4())
|
uuid = uuid4()
|
||||||
return activitypub.Update(
|
return activitypub.Update(
|
||||||
id=activity_id,
|
id=f"{self.remote_id}#update/{uuid}",
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
to=["https://www.w3.org/ns/activitystreams#Public"],
|
to=["https://www.w3.org/ns/activitystreams#Public"],
|
||||||
object=self,
|
object=self,
|
||||||
|
@ -337,8 +337,8 @@ class OrderedCollectionPageMixin(ObjectMixin):
|
||||||
paginated = Paginator(queryset, PAGE_LENGTH)
|
paginated = Paginator(queryset, PAGE_LENGTH)
|
||||||
# add computed fields specific to orderd collections
|
# add computed fields specific to orderd collections
|
||||||
activity["totalItems"] = paginated.count
|
activity["totalItems"] = paginated.count
|
||||||
activity["first"] = "%s?page=1" % remote_id
|
activity["first"] = f"{remote_id}?page=1"
|
||||||
activity["last"] = "%s?page=%d" % (remote_id, paginated.num_pages)
|
activity["last"] = f"{remote_id}?page={paginated.num_pages}"
|
||||||
|
|
||||||
return serializer(**activity)
|
return serializer(**activity)
|
||||||
|
|
||||||
|
@ -420,7 +420,7 @@ class CollectionItemMixin(ActivitypubMixin):
|
||||||
"""AP for shelving a book"""
|
"""AP for shelving a book"""
|
||||||
collection_field = getattr(self, self.collection_field)
|
collection_field = getattr(self, self.collection_field)
|
||||||
return activitypub.Add(
|
return activitypub.Add(
|
||||||
id="{:s}#add".format(collection_field.remote_id),
|
id=f"{collection_field.remote_id}#add",
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
object=self.to_activity_dataclass(),
|
object=self.to_activity_dataclass(),
|
||||||
target=collection_field.remote_id,
|
target=collection_field.remote_id,
|
||||||
|
@ -430,7 +430,7 @@ class CollectionItemMixin(ActivitypubMixin):
|
||||||
"""AP for un-shelving a book"""
|
"""AP for un-shelving a book"""
|
||||||
collection_field = getattr(self, self.collection_field)
|
collection_field = getattr(self, self.collection_field)
|
||||||
return activitypub.Remove(
|
return activitypub.Remove(
|
||||||
id="{:s}#remove".format(collection_field.remote_id),
|
id=f"{collection_field.remote_id}#remove",
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
object=self.to_activity_dataclass(),
|
object=self.to_activity_dataclass(),
|
||||||
target=collection_field.remote_id,
|
target=collection_field.remote_id,
|
||||||
|
@ -458,7 +458,7 @@ class ActivityMixin(ActivitypubMixin):
|
||||||
"""undo an action"""
|
"""undo an action"""
|
||||||
user = self.user if hasattr(self, "user") else self.user_subject
|
user = self.user if hasattr(self, "user") else self.user_subject
|
||||||
return activitypub.Undo(
|
return activitypub.Undo(
|
||||||
id="%s#undo" % self.remote_id,
|
id=f"{self.remote_id}#undo",
|
||||||
actor=user.remote_id,
|
actor=user.remote_id,
|
||||||
object=self,
|
object=self,
|
||||||
).serialize()
|
).serialize()
|
||||||
|
@ -555,11 +555,11 @@ def to_ordered_collection_page(
|
||||||
|
|
||||||
prev_page = next_page = None
|
prev_page = next_page = None
|
||||||
if activity_page.has_next():
|
if activity_page.has_next():
|
||||||
next_page = "%s?page=%d" % (remote_id, activity_page.next_page_number())
|
next_page = f"{remote_id}?page={activity_page.next_page_number()}"
|
||||||
if activity_page.has_previous():
|
if activity_page.has_previous():
|
||||||
prev_page = "%s?page=%d" % (remote_id, activity_page.previous_page_number())
|
prev_page = f"{remote_id}?page=%d{activity_page.previous_page_number()}"
|
||||||
return activitypub.OrderedCollectionPage(
|
return activitypub.OrderedCollectionPage(
|
||||||
id="%s?page=%s" % (remote_id, page),
|
id=f"{remote_id}?page={page}",
|
||||||
partOf=remote_id,
|
partOf=remote_id,
|
||||||
orderedItems=items,
|
orderedItems=items,
|
||||||
next=next_page,
|
next=next_page,
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Author(BookDataModel):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""editions and works both use "book" instead of model_name"""
|
"""editions and works both use "book" instead of model_name"""
|
||||||
return "https://%s/author/%s" % (DOMAIN, self.id)
|
return f"https://{DOMAIN}/author/{self.id}"
|
||||||
|
|
||||||
activity_serializer = activitypub.Author
|
activity_serializer = activitypub.Author
|
||||||
|
|
||||||
|
|
|
@ -32,11 +32,11 @@ class BookWyrmModel(models.Model):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""generate a url that resolves to the local object"""
|
"""generate a url that resolves to the local object"""
|
||||||
base_path = "https://%s" % DOMAIN
|
base_path = f"https://{DOMAIN}"
|
||||||
if hasattr(self, "user"):
|
if hasattr(self, "user"):
|
||||||
base_path = "%s%s" % (base_path, self.user.local_path)
|
base_path = f"{base_path}{self.user.local_path}"
|
||||||
model_name = type(self).__name__.lower()
|
model_name = type(self).__name__.lower()
|
||||||
return "%s/%s/%d" % (base_path, model_name, self.id)
|
return f"{base_path}/{model_name}/{self.id}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""this is just here to provide default fields for other models"""
|
"""this is just here to provide default fields for other models"""
|
||||||
|
@ -46,7 +46,7 @@ class BookWyrmModel(models.Model):
|
||||||
@property
|
@property
|
||||||
def local_path(self):
|
def local_path(self):
|
||||||
"""how to link to this object in the local app"""
|
"""how to link to this object in the local app"""
|
||||||
return self.get_remote_id().replace("https://%s" % DOMAIN, "")
|
return self.get_remote_id().replace(f"https://{DOMAIN}", "")
|
||||||
|
|
||||||
def visible_to_user(self, viewer):
|
def visible_to_user(self, viewer):
|
||||||
"""is a user authorized to view an object?"""
|
"""is a user authorized to view an object?"""
|
||||||
|
|
|
@ -164,9 +164,9 @@ class Book(BookDataModel):
|
||||||
@property
|
@property
|
||||||
def alt_text(self):
|
def alt_text(self):
|
||||||
"""image alt test"""
|
"""image alt test"""
|
||||||
text = "%s" % self.title
|
text = self.title
|
||||||
if self.edition_info:
|
if self.edition_info:
|
||||||
text += " (%s)" % self.edition_info
|
text += f" ({self.edition_info})"
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
|
@ -177,9 +177,10 @@ class Book(BookDataModel):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""editions and works both use "book" instead of model_name"""
|
"""editions and works both use "book" instead of model_name"""
|
||||||
return "https://%s/book/%d" % (DOMAIN, self.id)
|
return f"https://{DOMAIN}/book/{self.id}"
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# pylint: disable=consider-using-f-string
|
||||||
return "<{} key={!r} title={!r}>".format(
|
return "<{} key={!r} title={!r}>".format(
|
||||||
self.__class__,
|
self.__class__,
|
||||||
self.openlibrary_key,
|
self.openlibrary_key,
|
||||||
|
@ -216,7 +217,7 @@ class Work(OrderedCollectionPageMixin, Book):
|
||||||
"""an ordered collection of editions"""
|
"""an ordered collection of editions"""
|
||||||
return self.to_ordered_collection(
|
return self.to_ordered_collection(
|
||||||
self.editions.order_by("-edition_rank").all(),
|
self.editions.order_by("-edition_rank").all(),
|
||||||
remote_id="%s/editions" % self.remote_id,
|
remote_id=f"{self.remote_id}/editions",
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,4 @@ class Connector(BookWyrmModel):
|
||||||
isbn_search_url = models.CharField(max_length=255, null=True, blank=True)
|
isbn_search_url = models.CharField(max_length=255, null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "{} ({})".format(
|
return f"{self.identifier} ({self.id})"
|
||||||
self.identifier,
|
|
||||||
self.id,
|
|
||||||
)
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ class ActivitypubFieldMixin:
|
||||||
activitypub_field=None,
|
activitypub_field=None,
|
||||||
activitypub_wrapper=None,
|
activitypub_wrapper=None,
|
||||||
deduplication_field=False,
|
deduplication_field=False,
|
||||||
**kwargs
|
**kwargs,
|
||||||
):
|
):
|
||||||
self.deduplication_field = deduplication_field
|
self.deduplication_field = deduplication_field
|
||||||
if activitypub_wrapper:
|
if activitypub_wrapper:
|
||||||
|
@ -308,7 +308,7 @@ class ManyToManyField(ActivitypubFieldMixin, models.ManyToManyField):
|
||||||
|
|
||||||
def field_to_activity(self, value):
|
def field_to_activity(self, value):
|
||||||
if self.link_only:
|
if self.link_only:
|
||||||
return "%s/%s" % (value.instance.remote_id, self.name)
|
return f"{value.instance.remote_id}/{self.name}"
|
||||||
return [i.remote_id for i in value.all()]
|
return [i.remote_id for i in value.all()]
|
||||||
|
|
||||||
def field_from_activity(self, value):
|
def field_from_activity(self, value):
|
||||||
|
@ -388,7 +388,7 @@ def image_serializer(value, alt):
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
if not url[:4] == "http":
|
if not url[:4] == "http":
|
||||||
url = "https://{:s}{:s}".format(DOMAIN, url)
|
url = f"https://{DOMAIN}{url}"
|
||||||
return activitypub.Document(url=url, name=alt)
|
return activitypub.Document(url=url, name=alt)
|
||||||
|
|
||||||
|
|
||||||
|
@ -448,7 +448,7 @@ class ImageField(ActivitypubFieldMixin, models.ImageField):
|
||||||
|
|
||||||
image_content = ContentFile(response.content)
|
image_content = ContentFile(response.content)
|
||||||
extension = imghdr.what(None, image_content.read()) or ""
|
extension = imghdr.what(None, image_content.read()) or ""
|
||||||
image_name = "{:s}.{:s}".format(str(uuid4()), extension)
|
image_name = f"{uuid4()}.{extension}"
|
||||||
return [image_name, image_content]
|
return [image_name, image_content]
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
|
|
@ -198,7 +198,9 @@ class ImportItem(models.Model):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
|
# pylint: disable=consider-using-f-string
|
||||||
return "<{!r}Item {!r}>".format(self.data["import_source"], self.data["Title"])
|
return "<{!r}Item {!r}>".format(self.data["import_source"], self.data["Title"])
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
# pylint: disable=consider-using-f-string
|
||||||
return "{} by {}".format(self.data["Title"], self.data["Author"])
|
return "{} by {}".format(self.data["Title"], self.data["Author"])
|
||||||
|
|
|
@ -42,7 +42,7 @@ class List(OrderedCollectionMixin, BookWyrmModel):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""don't want the user to be in there in this case"""
|
"""don't want the user to be in there in this case"""
|
||||||
return "https://%s/list/%d" % (DOMAIN, self.id)
|
return f"https://{DOMAIN}/list/{self.id}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def collection_queryset(self):
|
def collection_queryset(self):
|
||||||
|
|
|
@ -53,7 +53,7 @@ class UserRelationship(BookWyrmModel):
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""use shelf identifier in remote_id"""
|
"""use shelf identifier in remote_id"""
|
||||||
base_path = self.user_subject.remote_id
|
base_path = self.user_subject.remote_id
|
||||||
return "%s#follows/%d" % (base_path, self.id)
|
return f"{base_path}#follows/{self.id}"
|
||||||
|
|
||||||
|
|
||||||
class UserFollows(ActivityMixin, UserRelationship):
|
class UserFollows(ActivityMixin, UserRelationship):
|
||||||
|
@ -144,7 +144,8 @@ class UserFollowRequest(ActivitypubMixin, UserRelationship):
|
||||||
"""get id for sending an accept or reject of a local user"""
|
"""get id for sending an accept or reject of a local user"""
|
||||||
|
|
||||||
base_path = self.user_object.remote_id
|
base_path = self.user_object.remote_id
|
||||||
return "%s#%s/%d" % (base_path, status, self.id or 0)
|
status_id = self.id or 0
|
||||||
|
return f"{base_path}#{status}/{status_id}"
|
||||||
|
|
||||||
def accept(self, broadcast_only=False):
|
def accept(self, broadcast_only=False):
|
||||||
"""turn this request into the real deal"""
|
"""turn this request into the real deal"""
|
||||||
|
|
|
@ -44,7 +44,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
||||||
def get_identifier(self):
|
def get_identifier(self):
|
||||||
"""custom-shelf-123 for the url"""
|
"""custom-shelf-123 for the url"""
|
||||||
slug = re.sub(r"[^\w]", "", self.name).lower()
|
slug = re.sub(r"[^\w]", "", self.name).lower()
|
||||||
return "{:s}-{:d}".format(slug, self.id)
|
return f"{slug}-{self.id}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def collection_queryset(self):
|
def collection_queryset(self):
|
||||||
|
@ -55,7 +55,7 @@ class Shelf(OrderedCollectionMixin, BookWyrmModel):
|
||||||
"""shelf identifier instead of id"""
|
"""shelf identifier instead of id"""
|
||||||
base_path = self.user.remote_id
|
base_path = self.user.remote_id
|
||||||
identifier = self.identifier or self.get_identifier()
|
identifier = self.identifier or self.get_identifier()
|
||||||
return "%s/books/%s" % (base_path, identifier)
|
return f"{base_path}/books/{identifier}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""user/shelf unqiueness"""
|
"""user/shelf unqiueness"""
|
||||||
|
|
|
@ -87,7 +87,7 @@ class SiteInvite(models.Model):
|
||||||
@property
|
@property
|
||||||
def link(self):
|
def link(self):
|
||||||
"""formats the invite link"""
|
"""formats the invite link"""
|
||||||
return "https://{}/invite/{}".format(DOMAIN, self.code)
|
return f"https://{DOMAIN}/invite/{self.code}"
|
||||||
|
|
||||||
|
|
||||||
class InviteRequest(BookWyrmModel):
|
class InviteRequest(BookWyrmModel):
|
||||||
|
@ -127,7 +127,7 @@ class PasswordReset(models.Model):
|
||||||
@property
|
@property
|
||||||
def link(self):
|
def link(self):
|
||||||
"""formats the invite link"""
|
"""formats the invite link"""
|
||||||
return "https://{}/password-reset/{}".format(DOMAIN, self.code)
|
return f"https://{DOMAIN}/password-reset/{self.code}"
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
|
|
|
@ -179,9 +179,9 @@ class Status(OrderedCollectionPageMixin, BookWyrmModel):
|
||||||
"""helper function for loading AP serialized replies to a status"""
|
"""helper function for loading AP serialized replies to a status"""
|
||||||
return self.to_ordered_collection(
|
return self.to_ordered_collection(
|
||||||
self.replies(self),
|
self.replies(self),
|
||||||
remote_id="%s/replies" % self.remote_id,
|
remote_id=f"{self.remote_id}/replies",
|
||||||
collection_only=True,
|
collection_only=True,
|
||||||
**kwargs
|
**kwargs,
|
||||||
).serialize()
|
).serialize()
|
||||||
|
|
||||||
def to_activity_dataclass(self, pure=False): # pylint: disable=arguments-differ
|
def to_activity_dataclass(self, pure=False): # pylint: disable=arguments-differ
|
||||||
|
@ -226,10 +226,10 @@ class GeneratedNote(Status):
|
||||||
"""indicate the book in question for mastodon (or w/e) users"""
|
"""indicate the book in question for mastodon (or w/e) users"""
|
||||||
message = self.content
|
message = self.content
|
||||||
books = ", ".join(
|
books = ", ".join(
|
||||||
'<a href="%s">"%s"</a>' % (book.remote_id, book.title)
|
f'<a href="{book.remote_id}">"{book.title}"</a>'
|
||||||
for book in self.mention_books.all()
|
for book in self.mention_books.all()
|
||||||
)
|
)
|
||||||
return "%s %s %s" % (self.user.display_name, message, books)
|
return f"{self.user.display_name} {message} {books}"
|
||||||
|
|
||||||
activity_serializer = activitypub.GeneratedNote
|
activity_serializer = activitypub.GeneratedNote
|
||||||
pure_type = "Note"
|
pure_type = "Note"
|
||||||
|
@ -277,10 +277,9 @@ class Comment(BookStatus):
|
||||||
@property
|
@property
|
||||||
def pure_content(self):
|
def pure_content(self):
|
||||||
"""indicate the book in question for mastodon (or w/e) users"""
|
"""indicate the book in question for mastodon (or w/e) users"""
|
||||||
return '%s<p>(comment on <a href="%s">"%s"</a>)</p>' % (
|
return (
|
||||||
self.content,
|
f'{self.content}<p>(comment on <a href="{self.book.remote_id}">'
|
||||||
self.book.remote_id,
|
f'"{self.book.title}"</a>)</p>'
|
||||||
self.book.title,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
activity_serializer = activitypub.Comment
|
activity_serializer = activitypub.Comment
|
||||||
|
@ -306,11 +305,9 @@ class Quotation(BookStatus):
|
||||||
"""indicate the book in question for mastodon (or w/e) users"""
|
"""indicate the book in question for mastodon (or w/e) users"""
|
||||||
quote = re.sub(r"^<p>", '<p>"', self.quote)
|
quote = re.sub(r"^<p>", '<p>"', self.quote)
|
||||||
quote = re.sub(r"</p>$", '"</p>', quote)
|
quote = re.sub(r"</p>$", '"</p>', quote)
|
||||||
return '%s <p>-- <a href="%s">"%s"</a></p>%s' % (
|
return (
|
||||||
quote,
|
f'{quote} <p>-- <a href="{self.book.remote_id}">'
|
||||||
self.book.remote_id,
|
f'"{self.book.title}"</a></p>{self.content}'
|
||||||
self.book.title,
|
|
||||||
self.content,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
activity_serializer = activitypub.Quotation
|
activity_serializer = activitypub.Quotation
|
||||||
|
|
|
@ -152,12 +152,13 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
@property
|
@property
|
||||||
def following_link(self):
|
def following_link(self):
|
||||||
"""just how to find out the following info"""
|
"""just how to find out the following info"""
|
||||||
return "{:s}/following".format(self.remote_id)
|
return f"{self.remote_id}/following"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def alt_text(self):
|
def alt_text(self):
|
||||||
"""alt text with username"""
|
"""alt text with username"""
|
||||||
return "avatar for %s" % (self.localname or self.username)
|
# pylint: disable=consider-using-f-string
|
||||||
|
return "avatar for {:s}".format(self.localname or self.username)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def display_name(self):
|
def display_name(self):
|
||||||
|
@ -197,9 +198,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
def to_outbox(self, filter_type=None, **kwargs):
|
def to_outbox(self, filter_type=None, **kwargs):
|
||||||
"""an ordered collection of statuses"""
|
"""an ordered collection of statuses"""
|
||||||
if filter_type:
|
if filter_type:
|
||||||
filter_class = apps.get_model(
|
filter_class = apps.get_model(f"bookwyrm.{filter_type}", require_ready=True)
|
||||||
"bookwyrm.%s" % filter_type, require_ready=True
|
|
||||||
)
|
|
||||||
if not issubclass(filter_class, Status):
|
if not issubclass(filter_class, Status):
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"filter_status_class must be a subclass of models.Status"
|
"filter_status_class must be a subclass of models.Status"
|
||||||
|
@ -223,7 +222,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
|
|
||||||
def to_following_activity(self, **kwargs):
|
def to_following_activity(self, **kwargs):
|
||||||
"""activitypub following list"""
|
"""activitypub following list"""
|
||||||
remote_id = "%s/following" % self.remote_id
|
remote_id = f"{self.remote_id}/following"
|
||||||
return self.to_ordered_collection(
|
return self.to_ordered_collection(
|
||||||
self.following.order_by("-updated_date").all(),
|
self.following.order_by("-updated_date").all(),
|
||||||
remote_id=remote_id,
|
remote_id=remote_id,
|
||||||
|
@ -266,7 +265,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
if not self.local and not re.match(regex.FULL_USERNAME, self.username):
|
if not self.local and not re.match(regex.FULL_USERNAME, self.username):
|
||||||
# generate a username that uses the domain (webfinger format)
|
# generate a username that uses the domain (webfinger format)
|
||||||
actor_parts = urlparse(self.remote_id)
|
actor_parts = urlparse(self.remote_id)
|
||||||
self.username = "%s@%s" % (self.username, actor_parts.netloc)
|
self.username = f"{self.username}@{actor_parts.netloc}"
|
||||||
|
|
||||||
# this user already exists, no need to populate fields
|
# this user already exists, no need to populate fields
|
||||||
if not created:
|
if not created:
|
||||||
|
@ -320,7 +319,8 @@ class User(OrderedCollectionPageMixin, AbstractUser):
|
||||||
@property
|
@property
|
||||||
def local_path(self):
|
def local_path(self):
|
||||||
"""this model doesn't inherit bookwyrm model, so here we are"""
|
"""this model doesn't inherit bookwyrm model, so here we are"""
|
||||||
return "/user/%s" % (self.localname or self.username)
|
# pylint: disable=consider-using-f-string
|
||||||
|
return "/user/{:s}".format(self.localname or self.username)
|
||||||
|
|
||||||
def create_shelves(self):
|
def create_shelves(self):
|
||||||
"""default shelves for a new user"""
|
"""default shelves for a new user"""
|
||||||
|
@ -361,7 +361,7 @@ class KeyPair(ActivitypubMixin, BookWyrmModel):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
# self.owner is set by the OneToOneField on User
|
# self.owner is set by the OneToOneField on User
|
||||||
return "%s/#main-key" % self.owner.remote_id
|
return f"{self.owner.remote_id}/#main-key"
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
def save(self, *args, **kwargs):
|
||||||
"""create a key pair"""
|
"""create a key pair"""
|
||||||
|
@ -398,7 +398,7 @@ class AnnualGoal(BookWyrmModel):
|
||||||
|
|
||||||
def get_remote_id(self):
|
def get_remote_id(self):
|
||||||
"""put the year in the path"""
|
"""put the year in the path"""
|
||||||
return "{:s}/goal/{:d}".format(self.user.remote_id, self.year)
|
return f"{self.user.remote_id}/goal/{self.year}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def books(self):
|
def books(self):
|
||||||
|
@ -454,7 +454,7 @@ def get_or_create_remote_server(domain):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
try:
|
try:
|
||||||
data = get_data("https://%s/.well-known/nodeinfo" % domain)
|
data = get_data(f"https://{domain}/.well-known/nodeinfo")
|
||||||
try:
|
try:
|
||||||
nodeinfo_url = data.get("links")[0].get("href")
|
nodeinfo_url = data.get("links")[0].get("href")
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
|
|
|
@ -220,6 +220,7 @@ def generate_default_inner_img():
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=too-many-locals
|
# pylint: disable=too-many-locals
|
||||||
|
# pylint: disable=too-many-statements
|
||||||
def generate_preview_image(
|
def generate_preview_image(
|
||||||
texts=None, picture=None, rating=None, show_instance_layer=True
|
texts=None, picture=None, rating=None, show_instance_layer=True
|
||||||
):
|
):
|
||||||
|
@ -237,7 +238,8 @@ def generate_preview_image(
|
||||||
|
|
||||||
# Color
|
# Color
|
||||||
if BG_COLOR in ["use_dominant_color_light", "use_dominant_color_dark"]:
|
if BG_COLOR in ["use_dominant_color_light", "use_dominant_color_dark"]:
|
||||||
image_bg_color = "rgb(%s, %s, %s)" % dominant_color
|
red, green, blue = dominant_color
|
||||||
|
image_bg_color = f"rgb({red}, {green}, {blue})"
|
||||||
|
|
||||||
# Adjust color
|
# Adjust color
|
||||||
image_bg_color_rgb = [x / 255.0 for x in ImageColor.getrgb(image_bg_color)]
|
image_bg_color_rgb = [x / 255.0 for x in ImageColor.getrgb(image_bg_color)]
|
||||||
|
@ -315,7 +317,8 @@ def save_and_cleanup(image, instance=None):
|
||||||
"""Save and close the file"""
|
"""Save and close the file"""
|
||||||
if not isinstance(instance, (models.Book, models.User, models.SiteSettings)):
|
if not isinstance(instance, (models.Book, models.User, models.SiteSettings)):
|
||||||
return False
|
return False
|
||||||
file_name = "%s-%s.jpg" % (str(instance.id), str(uuid4()))
|
uuid = uuid4()
|
||||||
|
file_name = f"{instance.id}-{uuid}.jpg"
|
||||||
image_buffer = BytesIO()
|
image_buffer = BytesIO()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -412,7 +415,7 @@ def generate_user_preview_image_task(user_id):
|
||||||
|
|
||||||
texts = {
|
texts = {
|
||||||
"text_one": user.display_name,
|
"text_one": user.display_name,
|
||||||
"text_three": "@{}@{}".format(user.localname, settings.DOMAIN),
|
"text_three": f"@{user.localname}@{settings.DOMAIN}",
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.avatar:
|
if user.avatar:
|
||||||
|
|
|
@ -48,7 +48,7 @@ class InputHtmlParser(HTMLParser): # pylint: disable=abstract-method
|
||||||
return
|
return
|
||||||
|
|
||||||
self.tag_stack = self.tag_stack[:-1]
|
self.tag_stack = self.tag_stack[:-1]
|
||||||
self.output.append(("tag", "</%s>" % tag))
|
self.output.append(("tag", f"</{tag}>"))
|
||||||
|
|
||||||
def handle_data(self, data):
|
def handle_data(self, data):
|
||||||
"""extract the answer, if we're in an answer tag"""
|
"""extract the answer, if we're in an answer tag"""
|
||||||
|
|
|
@ -23,7 +23,7 @@ EMAIL_HOST_USER = env("EMAIL_HOST_USER")
|
||||||
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
|
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD")
|
||||||
EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", True)
|
EMAIL_USE_TLS = env.bool("EMAIL_USE_TLS", True)
|
||||||
EMAIL_USE_SSL = env.bool("EMAIL_USE_SSL", False)
|
EMAIL_USE_SSL = env.bool("EMAIL_USE_SSL", False)
|
||||||
DEFAULT_FROM_EMAIL = "admin@{:s}".format(env("DOMAIN"))
|
DEFAULT_FROM_EMAIL = f"admin@{DOMAIN}"
|
||||||
|
|
||||||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||||||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
@ -178,11 +178,8 @@ USE_L10N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
USER_AGENT = "%s (BookWyrm/%s; +https://%s/)" % (
|
agent = requests.utils.default_user_agent()
|
||||||
requests.utils.default_user_agent(),
|
USER_AGENT = f"{agent} (BookWyrm/{VERSION}; +https://{DOMAIN}/)"
|
||||||
VERSION,
|
|
||||||
DOMAIN,
|
|
||||||
)
|
|
||||||
|
|
||||||
# Imagekit generated thumbnails
|
# Imagekit generated thumbnails
|
||||||
ENABLE_THUMBNAIL_GENERATION = env.bool("ENABLE_THUMBNAIL_GENERATION", False)
|
ENABLE_THUMBNAIL_GENERATION = env.bool("ENABLE_THUMBNAIL_GENERATION", False)
|
||||||
|
@ -213,11 +210,11 @@ if USE_S3:
|
||||||
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
|
AWS_S3_OBJECT_PARAMETERS = {"CacheControl": "max-age=86400"}
|
||||||
# S3 Static settings
|
# S3 Static settings
|
||||||
STATIC_LOCATION = "static"
|
STATIC_LOCATION = "static"
|
||||||
STATIC_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, STATIC_LOCATION)
|
STATIC_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{STATIC_LOCATION}/"
|
||||||
STATICFILES_STORAGE = "bookwyrm.storage_backends.StaticStorage"
|
STATICFILES_STORAGE = "bookwyrm.storage_backends.StaticStorage"
|
||||||
# S3 Media settings
|
# S3 Media settings
|
||||||
MEDIA_LOCATION = "images"
|
MEDIA_LOCATION = "images"
|
||||||
MEDIA_URL = "https://%s/%s/" % (AWS_S3_CUSTOM_DOMAIN, MEDIA_LOCATION)
|
MEDIA_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIA_LOCATION}/"
|
||||||
MEDIA_FULL_URL = MEDIA_URL
|
MEDIA_FULL_URL = MEDIA_URL
|
||||||
DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage"
|
DEFAULT_FILE_STORAGE = "bookwyrm.storage_backends.ImagesStorage"
|
||||||
# I don't know if it's used, but the site crashes without it
|
# I don't know if it's used, but the site crashes without it
|
||||||
|
@ -227,5 +224,5 @@ else:
|
||||||
STATIC_URL = "/static/"
|
STATIC_URL = "/static/"
|
||||||
STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static"))
|
STATIC_ROOT = os.path.join(BASE_DIR, env("STATIC_ROOT", "static"))
|
||||||
MEDIA_URL = "/images/"
|
MEDIA_URL = "/images/"
|
||||||
MEDIA_FULL_URL = "%s://%s%s" % (PROTOCOL, DOMAIN, MEDIA_URL)
|
MEDIA_FULL_URL = f"{PROTOCOL}://{DOMAIN}{MEDIA_URL}"
|
||||||
MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))
|
MEDIA_ROOT = os.path.join(BASE_DIR, env("MEDIA_ROOT", "images"))
|
||||||
|
|
|
@ -26,21 +26,21 @@ def make_signature(sender, destination, date, digest):
|
||||||
"""uses a private key to sign an outgoing message"""
|
"""uses a private key to sign an outgoing message"""
|
||||||
inbox_parts = urlparse(destination)
|
inbox_parts = urlparse(destination)
|
||||||
signature_headers = [
|
signature_headers = [
|
||||||
"(request-target): post %s" % inbox_parts.path,
|
f"(request-target): post {inbox_parts.path}",
|
||||||
"host: %s" % inbox_parts.netloc,
|
f"host: {inbox_parts.netloc}",
|
||||||
"date: %s" % date,
|
f"date: {date}",
|
||||||
"digest: %s" % digest,
|
f"digest: {digest}",
|
||||||
]
|
]
|
||||||
message_to_sign = "\n".join(signature_headers)
|
message_to_sign = "\n".join(signature_headers)
|
||||||
signer = pkcs1_15.new(RSA.import_key(sender.key_pair.private_key))
|
signer = pkcs1_15.new(RSA.import_key(sender.key_pair.private_key))
|
||||||
signed_message = signer.sign(SHA256.new(message_to_sign.encode("utf8")))
|
signed_message = signer.sign(SHA256.new(message_to_sign.encode("utf8")))
|
||||||
signature = {
|
signature = {
|
||||||
"keyId": "%s#main-key" % sender.remote_id,
|
"keyId": f"{sender.remote_id}#main-key",
|
||||||
"algorithm": "rsa-sha256",
|
"algorithm": "rsa-sha256",
|
||||||
"headers": "(request-target) host date digest",
|
"headers": "(request-target) host date digest",
|
||||||
"signature": b64encode(signed_message).decode("utf8"),
|
"signature": b64encode(signed_message).decode("utf8"),
|
||||||
}
|
}
|
||||||
return ",".join('%s="%s"' % (k, v) for (k, v) in signature.items())
|
return ",".join(f'{k}="{v}"' for (k, v) in signature.items())
|
||||||
|
|
||||||
|
|
||||||
def make_digest(data):
|
def make_digest(data):
|
||||||
|
@ -58,7 +58,7 @@ def verify_digest(request):
|
||||||
elif algorithm == "SHA-512":
|
elif algorithm == "SHA-512":
|
||||||
hash_function = hashlib.sha512
|
hash_function = hashlib.sha512
|
||||||
else:
|
else:
|
||||||
raise ValueError("Unsupported hash function: {}".format(algorithm))
|
raise ValueError(f"Unsupported hash function: {algorithm}")
|
||||||
|
|
||||||
expected = hash_function(request.body).digest()
|
expected = hash_function(request.body).digest()
|
||||||
if b64decode(digest) != expected:
|
if b64decode(digest) != expected:
|
||||||
|
@ -95,18 +95,18 @@ class Signature:
|
||||||
def verify(self, public_key, request):
|
def verify(self, public_key, request):
|
||||||
"""verify rsa signature"""
|
"""verify rsa signature"""
|
||||||
if http_date_age(request.headers["date"]) > MAX_SIGNATURE_AGE:
|
if http_date_age(request.headers["date"]) > MAX_SIGNATURE_AGE:
|
||||||
raise ValueError("Request too old: %s" % (request.headers["date"],))
|
raise ValueError(f"Request too old: {request.headers['date']}")
|
||||||
public_key = RSA.import_key(public_key)
|
public_key = RSA.import_key(public_key)
|
||||||
|
|
||||||
comparison_string = []
|
comparison_string = []
|
||||||
for signed_header_name in self.headers.split(" "):
|
for signed_header_name in self.headers.split(" "):
|
||||||
if signed_header_name == "(request-target)":
|
if signed_header_name == "(request-target)":
|
||||||
comparison_string.append("(request-target): post %s" % request.path)
|
comparison_string.append(f"(request-target): post {request.path}")
|
||||||
else:
|
else:
|
||||||
if signed_header_name == "digest":
|
if signed_header_name == "digest":
|
||||||
verify_digest(request)
|
verify_digest(request)
|
||||||
comparison_string.append(
|
comparison_string.append(
|
||||||
"%s: %s" % (signed_header_name, request.headers[signed_header_name])
|
f"{signed_header_name}: {request.headers[signed_header_name]}"
|
||||||
)
|
)
|
||||||
comparison_string = "\n".join(comparison_string)
|
comparison_string = "\n".join(comparison_string)
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,8 @@ class SuggestedUsers(RedisStore):
|
||||||
def store_id(self, user): # pylint: disable=no-self-use
|
def store_id(self, user): # pylint: disable=no-self-use
|
||||||
"""the key used to store this user's recs"""
|
"""the key used to store this user's recs"""
|
||||||
if isinstance(user, int):
|
if isinstance(user, int):
|
||||||
return "{:d}-suggestions".format(user)
|
return f"{user}-suggestions"
|
||||||
return "{:d}-suggestions".format(user.id)
|
return f"{user.id}-suggestions"
|
||||||
|
|
||||||
def get_counts_from_rank(self, rank): # pylint: disable=no-self-use
|
def get_counts_from_rank(self, rank): # pylint: disable=no-self-use
|
||||||
"""calculate mutuals count and shared books count from rank"""
|
"""calculate mutuals count and shared books count from rank"""
|
||||||
|
|
|
@ -37,7 +37,12 @@
|
||||||
<form class="navbar-item column" action="/search/">
|
<form class="navbar-item column" action="/search/">
|
||||||
<div class="field has-addons">
|
<div class="field has-addons">
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<input aria-label="{% trans 'Search for a book or user' %}" id="search_input" class="input" type="text" name="q" placeholder="{% trans 'Search for a book or user' %}" value="{{ query }}">
|
{% if user.is_authenticated %}
|
||||||
|
{% trans "Search for a book, user, or list" as search_placeholder %}
|
||||||
|
{% else %}
|
||||||
|
{% trans "Search for a book" as search_placeholder %}
|
||||||
|
{% endif %}
|
||||||
|
<input aria-label="{{ search_placeholder }}" id="search_input" class="input" type="text" name="q" placeholder="{{ search_placeholder }}" value="{{ query }}">
|
||||||
</div>
|
</div>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
<button class="button" type="submit">
|
<button class="button" type="submit">
|
||||||
|
|
|
@ -45,8 +45,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if list.id %}
|
||||||
<div class="column is-narrow">
|
<div class="column is-narrow">
|
||||||
{% trans "Delete list" as button_text %}
|
{% trans "Delete list" as button_text %}
|
||||||
{% include 'snippets/toggle/toggle_button.html' with class="is-danger" text=button_text icon_with_text="x" controls_text="delete_list" controls_uid=list.id focus="modal_title_delete_list" %}
|
{% include 'snippets/toggle/toggle_button.html' with class="is-danger" text=button_text icon_with_text="x" controls_text="delete_list" controls_uid=list.id focus="modal_title_delete_list" %}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
min="0"
|
min="0"
|
||||||
name="progress"
|
name="progress"
|
||||||
size="3"
|
size="3"
|
||||||
value="{{ readthrough.progress|default:'' }}">
|
value="{{ readthrough.progress|default:'' }}"
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="control select">
|
<div class="control select">
|
||||||
<select name="progress_mode" aria-label="Progress mode">
|
<select name="progress_mode" aria-label="Progress mode">
|
||||||
|
|
|
@ -12,7 +12,7 @@ register = template.Library()
|
||||||
def get_rating(book, user):
|
def get_rating(book, user):
|
||||||
"""get the overall rating of a book"""
|
"""get the overall rating of a book"""
|
||||||
queryset = views.helpers.privacy_filter(
|
queryset = views.helpers.privacy_filter(
|
||||||
user, models.Review.objects.filter(book__in=book.parent_work.editions.all())
|
user, models.Review.objects.filter(book__parent_work__editions=book)
|
||||||
)
|
)
|
||||||
return queryset.aggregate(Avg("rating"))["rating__avg"]
|
return queryset.aggregate(Avg("rating"))["rating__avg"]
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ def active_shelf(context, book):
|
||||||
shelf = (
|
shelf = (
|
||||||
models.ShelfBook.objects.filter(
|
models.ShelfBook.objects.filter(
|
||||||
shelf__user=context["request"].user,
|
shelf__user=context["request"].user,
|
||||||
book__in=book.parent_work.editions.all(),
|
book__parent_work__editions=book,
|
||||||
)
|
)
|
||||||
.select_related("book", "shelf")
|
.select_related("book", "shelf")
|
||||||
.first()
|
.first()
|
||||||
|
@ -97,4 +97,4 @@ def mutuals_count(context, user):
|
||||||
viewer = context["request"].user
|
viewer = context["request"].user
|
||||||
if not viewer.is_authenticated:
|
if not viewer.is_authenticated:
|
||||||
return None
|
return None
|
||||||
return user.followers.filter(id__in=viewer.following.all()).count()
|
return user.followers.filter(followers=viewer).count()
|
||||||
|
|
|
@ -12,7 +12,7 @@ register = template.Library()
|
||||||
@register.filter(name="uuid")
|
@register.filter(name="uuid")
|
||||||
def get_uuid(identifier):
|
def get_uuid(identifier):
|
||||||
"""for avoiding clashing ids when there are many forms"""
|
"""for avoiding clashing ids when there are many forms"""
|
||||||
return "%s%s" % (identifier, uuid4())
|
return f"{identifier}{uuid4()}"
|
||||||
|
|
||||||
|
|
||||||
@register.filter(name="username")
|
@register.filter(name="username")
|
||||||
|
@ -50,7 +50,7 @@ def truncatepath(value, arg):
|
||||||
length = int(arg)
|
length = int(arg)
|
||||||
except ValueError: # invalid literal for int()
|
except ValueError: # invalid literal for int()
|
||||||
return path_list[-1] # Fail silently.
|
return path_list[-1] # Fail silently.
|
||||||
return "%s/…%s" % (path_list[0], path_list[-1][-length:])
|
return f"{path_list[0]}/…{path_list[-1][-length:]}"
|
||||||
|
|
||||||
|
|
||||||
@register.simple_tag(takes_context=False)
|
@register.simple_tag(takes_context=False)
|
||||||
|
@ -60,7 +60,7 @@ def get_book_cover_thumbnail(book, size="medium", ext="jpg"):
|
||||||
if size == "":
|
if size == "":
|
||||||
size = "medium"
|
size = "medium"
|
||||||
try:
|
try:
|
||||||
cover_thumbnail = getattr(book, "cover_bw_book_%s_%s" % (size, ext))
|
cover_thumbnail = getattr(book, f"cover_bw_book_{size}_{ext}")
|
||||||
return cover_thumbnail.url
|
return cover_thumbnail.url
|
||||||
except OSError:
|
except OSError:
|
||||||
return static("images/no_cover.jpg")
|
return static("images/no_cover.jpg")
|
||||||
|
|
95
bookwyrm/tests/models/test_site.py
Normal file
95
bookwyrm/tests/models/test_site.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
""" testing models """
|
||||||
|
from datetime import timedelta
|
||||||
|
from unittest.mock import patch
|
||||||
|
|
||||||
|
from django.db import IntegrityError
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from bookwyrm import models, settings
|
||||||
|
|
||||||
|
|
||||||
|
class SiteModels(TestCase):
|
||||||
|
"""tests for site models"""
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""we need basic test data and mocks"""
|
||||||
|
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"), patch(
|
||||||
|
"bookwyrm.activitystreams.populate_stream_task.delay"
|
||||||
|
):
|
||||||
|
self.local_user = models.User.objects.create_user(
|
||||||
|
"mouse@local.com",
|
||||||
|
"mouse@mouse.com",
|
||||||
|
"mouseword",
|
||||||
|
local=True,
|
||||||
|
localname="mouse",
|
||||||
|
remote_id="https://example.com/users/mouse",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_site_settings_absent(self):
|
||||||
|
"""create and load site settings"""
|
||||||
|
self.assertFalse(models.SiteSettings.objects.exists())
|
||||||
|
result = models.SiteSettings.get()
|
||||||
|
self.assertTrue(models.SiteSettings.objects.exists())
|
||||||
|
self.assertEqual(result.id, 1)
|
||||||
|
self.assertEqual(result.name, "BookWyrm")
|
||||||
|
|
||||||
|
def test_site_settings_present(self):
|
||||||
|
"""load site settings"""
|
||||||
|
models.SiteSettings.objects.create(id=1, name="Fish Town")
|
||||||
|
result = models.SiteSettings.get()
|
||||||
|
self.assertEqual(result.id, 1)
|
||||||
|
self.assertEqual(result.name, "Fish Town")
|
||||||
|
self.assertEqual(models.SiteSettings.objects.all().count(), 1)
|
||||||
|
|
||||||
|
def test_site_invite(self):
|
||||||
|
"""default invite"""
|
||||||
|
invite = models.SiteInvite.objects.create(
|
||||||
|
user=self.local_user,
|
||||||
|
)
|
||||||
|
self.assertTrue(invite.valid())
|
||||||
|
|
||||||
|
def test_site_invite_with_limit(self):
|
||||||
|
"""with use limit"""
|
||||||
|
# valid
|
||||||
|
invite = models.SiteInvite.objects.create(user=self.local_user, use_limit=1)
|
||||||
|
self.assertTrue(invite.valid())
|
||||||
|
|
||||||
|
# invalid
|
||||||
|
invite = models.SiteInvite.objects.create(user=self.local_user, use_limit=0)
|
||||||
|
self.assertFalse(invite.valid())
|
||||||
|
invite = models.SiteInvite.objects.create(
|
||||||
|
user=self.local_user, use_limit=1, times_used=1
|
||||||
|
)
|
||||||
|
self.assertFalse(invite.valid())
|
||||||
|
|
||||||
|
def test_site_invite_with_expiry(self):
|
||||||
|
"""with expiration date"""
|
||||||
|
date = timezone.now() + timedelta(days=1)
|
||||||
|
invite = models.SiteInvite.objects.create(user=self.local_user, expiry=date)
|
||||||
|
self.assertTrue(invite.valid())
|
||||||
|
|
||||||
|
date = timezone.now() - timedelta(days=1)
|
||||||
|
invite = models.SiteInvite.objects.create(user=self.local_user, expiry=date)
|
||||||
|
self.assertFalse(invite.valid())
|
||||||
|
|
||||||
|
def test_site_invite_link(self):
|
||||||
|
"""invite link generator"""
|
||||||
|
invite = models.SiteInvite.objects.create(user=self.local_user, code="hello")
|
||||||
|
self.assertEqual(invite.link, f"https://{settings.DOMAIN}/invite/hello")
|
||||||
|
|
||||||
|
def test_invite_request(self):
|
||||||
|
"""someone wants an invite"""
|
||||||
|
# normal and good
|
||||||
|
request = models.InviteRequest.objects.create(email="mouse.reeve@gmail.com")
|
||||||
|
self.assertIsNone(request.invite)
|
||||||
|
|
||||||
|
# already in use
|
||||||
|
with self.assertRaises(IntegrityError):
|
||||||
|
request = models.InviteRequest.objects.create(email="mouse@mouse.com")
|
||||||
|
|
||||||
|
def test_password_reset(self):
|
||||||
|
"""password reset token"""
|
||||||
|
token = models.PasswordReset.objects.create(user=self.local_user, code="hello")
|
||||||
|
self.assertTrue(token.valid())
|
||||||
|
self.assertEqual(token.link, f"https://{settings.DOMAIN}/password-reset/hello")
|
|
@ -20,6 +20,7 @@ from bookwyrm.preview_images import (
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
# pylint: disable=missing-function-docstring
|
# pylint: disable=missing-function-docstring
|
||||||
|
# pylint: disable=consider-using-with
|
||||||
class PreviewImages(TestCase):
|
class PreviewImages(TestCase):
|
||||||
"""every response to a get request, html or json"""
|
"""every response to a get request, html or json"""
|
||||||
|
|
||||||
|
@ -120,3 +121,11 @@ class PreviewImages(TestCase):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
self.local_user.preview_image.height, settings.PREVIEW_IMG_HEIGHT
|
self.local_user.preview_image.height, settings.PREVIEW_IMG_HEIGHT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_generate_user_preview_images_task(self, *args, **kwargs):
|
||||||
|
"""test task's external calls"""
|
||||||
|
with patch("bookwyrm.preview_images.generate_preview_image") as generate_mock:
|
||||||
|
generate_user_preview_image_task(self.local_user.id)
|
||||||
|
args = generate_mock.call_args.kwargs
|
||||||
|
self.assertEqual(args["texts"]["text_one"], "possum")
|
||||||
|
self.assertEqual(args["texts"]["text_three"], f"@possum@{settings.DOMAIN}")
|
||||||
|
|
|
@ -7,8 +7,8 @@ from django.views.generic.base import TemplateView
|
||||||
from bookwyrm import settings, views
|
from bookwyrm import settings, views
|
||||||
from bookwyrm.utils import regex
|
from bookwyrm.utils import regex
|
||||||
|
|
||||||
USER_PATH = r"^user/(?P<username>%s)" % regex.USERNAME
|
USER_PATH = rf"^user/(?P<username>{regex.USERNAME})"
|
||||||
LOCAL_USER_PATH = r"^user/(?P<username>%s)" % regex.LOCALNAME
|
LOCAL_USER_PATH = rf"^user/(?P<username>{regex.LOCALNAME})"
|
||||||
|
|
||||||
status_types = [
|
status_types = [
|
||||||
"status",
|
"status",
|
||||||
|
@ -19,7 +19,9 @@ status_types = [
|
||||||
"boost",
|
"boost",
|
||||||
"generatednote",
|
"generatednote",
|
||||||
]
|
]
|
||||||
STATUS_PATH = r"%s/(%s)/(?P<status_id>\d+)" % (USER_PATH, "|".join(status_types))
|
|
||||||
|
STATUS_TYPES_STRING = "|".join(status_types)
|
||||||
|
STATUS_PATH = rf"{USER_PATH}/({STATUS_TYPES_STRING})/(?P<status_id>\d+)"
|
||||||
|
|
||||||
BOOK_PATH = r"^book/(?P<book_id>\d+)"
|
BOOK_PATH = r"^book/(?P<book_id>\d+)"
|
||||||
|
|
||||||
|
@ -33,8 +35,8 @@ urlpatterns = [
|
||||||
),
|
),
|
||||||
# federation endpoints
|
# federation endpoints
|
||||||
re_path(r"^inbox/?$", views.Inbox.as_view()),
|
re_path(r"^inbox/?$", views.Inbox.as_view()),
|
||||||
re_path(r"%s/inbox/?$" % LOCAL_USER_PATH, views.Inbox.as_view()),
|
re_path(rf"{LOCAL_USER_PATH}/inbox/?$", views.Inbox.as_view()),
|
||||||
re_path(r"%s/outbox/?$" % LOCAL_USER_PATH, views.Outbox.as_view()),
|
re_path(rf"{LOCAL_USER_PATH}/outbox/?$", views.Outbox.as_view()),
|
||||||
re_path(r"^\.well-known/webfinger/?$", views.webfinger),
|
re_path(r"^\.well-known/webfinger/?$", views.webfinger),
|
||||||
re_path(r"^\.well-known/nodeinfo/?$", views.nodeinfo_pointer),
|
re_path(r"^\.well-known/nodeinfo/?$", views.nodeinfo_pointer),
|
||||||
re_path(r"^\.well-known/host-meta/?$", views.host_meta),
|
re_path(r"^\.well-known/host-meta/?$", views.host_meta),
|
||||||
|
@ -220,12 +222,12 @@ urlpatterns = [
|
||||||
name="get-started-users",
|
name="get-started-users",
|
||||||
),
|
),
|
||||||
# feeds
|
# feeds
|
||||||
re_path(r"^(?P<tab>{:s})/?$".format(STREAMS), views.Feed.as_view()),
|
re_path(rf"^(?P<tab>{STREAMS})/?$", views.Feed.as_view()),
|
||||||
re_path(
|
re_path(
|
||||||
r"^direct-messages/?$", views.DirectMessage.as_view(), name="direct-messages"
|
r"^direct-messages/?$", views.DirectMessage.as_view(), name="direct-messages"
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^direct-messages/(?P<username>%s)?$" % regex.USERNAME,
|
rf"^direct-messages/(?P<username>{regex.USERNAME})?$",
|
||||||
views.DirectMessage.as_view(),
|
views.DirectMessage.as_view(),
|
||||||
name="direct-messages-user",
|
name="direct-messages-user",
|
||||||
),
|
),
|
||||||
|
@ -235,22 +237,22 @@ urlpatterns = [
|
||||||
re_path(r"^import/?$", views.Import.as_view(), name="import"),
|
re_path(r"^import/?$", views.Import.as_view(), name="import"),
|
||||||
re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"),
|
re_path(r"^import/(\d+)/?$", views.ImportStatus.as_view(), name="import-status"),
|
||||||
# users
|
# users
|
||||||
re_path(r"%s\.json$" % USER_PATH, views.User.as_view()),
|
re_path(rf"{USER_PATH}\.json$", views.User.as_view()),
|
||||||
re_path(r"%s/?$" % USER_PATH, views.User.as_view(), name="user-feed"),
|
re_path(rf"{USER_PATH}/?$", views.User.as_view(), name="user-feed"),
|
||||||
re_path(r"%s/rss" % USER_PATH, views.rss_feed.RssFeed(), name="user-rss"),
|
re_path(rf"{USER_PATH}/rss/?$", views.rss_feed.RssFeed(), name="user-rss"),
|
||||||
re_path(
|
re_path(
|
||||||
r"%s/followers(.json)?/?$" % USER_PATH,
|
rf"{USER_PATH}/followers(.json)?/?$",
|
||||||
views.Followers.as_view(),
|
views.Followers.as_view(),
|
||||||
name="user-followers",
|
name="user-followers",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"%s/following(.json)?/?$" % USER_PATH,
|
rf"{USER_PATH}/following(.json)?/?$",
|
||||||
views.Following.as_view(),
|
views.Following.as_view(),
|
||||||
name="user-following",
|
name="user-following",
|
||||||
),
|
),
|
||||||
re_path(r"^hide-suggestions/?$", views.hide_suggestions, name="hide-suggestions"),
|
re_path(r"^hide-suggestions/?$", views.hide_suggestions, name="hide-suggestions"),
|
||||||
# lists
|
# lists
|
||||||
re_path(r"%s/lists/?$" % USER_PATH, views.UserLists.as_view(), name="user-lists"),
|
re_path(rf"{USER_PATH}/lists/?$", views.UserLists.as_view(), name="user-lists"),
|
||||||
re_path(r"^list/?$", views.Lists.as_view(), name="lists"),
|
re_path(r"^list/?$", views.Lists.as_view(), name="lists"),
|
||||||
re_path(r"^list/saved/?$", views.SavedLists.as_view(), name="saved-lists"),
|
re_path(r"^list/saved/?$", views.SavedLists.as_view(), name="saved-lists"),
|
||||||
re_path(r"^list/(?P<list_id>\d+)(.json)?/?$", views.List.as_view(), name="list"),
|
re_path(r"^list/(?P<list_id>\d+)(.json)?/?$", views.List.as_view(), name="list"),
|
||||||
|
@ -272,14 +274,14 @@ urlpatterns = [
|
||||||
re_path(r"^save-list/(?P<list_id>\d+)/?$", views.save_list, name="list-save"),
|
re_path(r"^save-list/(?P<list_id>\d+)/?$", views.save_list, name="list-save"),
|
||||||
re_path(r"^unsave-list/(?P<list_id>\d+)/?$", views.unsave_list, name="list-unsave"),
|
re_path(r"^unsave-list/(?P<list_id>\d+)/?$", views.unsave_list, name="list-unsave"),
|
||||||
# User books
|
# User books
|
||||||
re_path(r"%s/books/?$" % USER_PATH, views.Shelf.as_view(), name="user-shelves"),
|
re_path(rf"{USER_PATH}/books/?$", views.Shelf.as_view(), name="user-shelves"),
|
||||||
re_path(
|
re_path(
|
||||||
r"^%s/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % USER_PATH,
|
rf"^{USER_PATH}/(helf|books)/(?P<shelf_identifier>[\w-]+)(.json)?/?$",
|
||||||
views.Shelf.as_view(),
|
views.Shelf.as_view(),
|
||||||
name="shelf",
|
name="shelf",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^%s/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$" % LOCAL_USER_PATH,
|
rf"^{LOCAL_USER_PATH}/(books|shelf)/(?P<shelf_identifier>[\w-]+)(.json)?/?$",
|
||||||
views.Shelf.as_view(),
|
views.Shelf.as_view(),
|
||||||
name="shelf",
|
name="shelf",
|
||||||
),
|
),
|
||||||
|
@ -289,7 +291,7 @@ urlpatterns = [
|
||||||
re_path(r"^unshelve/?$", views.unshelve),
|
re_path(r"^unshelve/?$", views.unshelve),
|
||||||
# goals
|
# goals
|
||||||
re_path(
|
re_path(
|
||||||
r"%s/goal/(?P<year>\d{4})/?$" % USER_PATH,
|
rf"{USER_PATH}/goal/(?P<year>\d{4})/?$",
|
||||||
views.Goal.as_view(),
|
views.Goal.as_view(),
|
||||||
name="user-goal",
|
name="user-goal",
|
||||||
),
|
),
|
||||||
|
@ -306,10 +308,10 @@ urlpatterns = [
|
||||||
re_path(r"^block/(?P<user_id>\d+)/?$", views.Block.as_view()),
|
re_path(r"^block/(?P<user_id>\d+)/?$", views.Block.as_view()),
|
||||||
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),
|
re_path(r"^unblock/(?P<user_id>\d+)/?$", views.unblock),
|
||||||
# statuses
|
# statuses
|
||||||
re_path(r"%s(.json)?/?$" % STATUS_PATH, views.Status.as_view(), name="status"),
|
re_path(rf"{STATUS_PATH}(.json)?/?$", views.Status.as_view(), name="status"),
|
||||||
re_path(r"%s/activity/?$" % STATUS_PATH, views.Status.as_view(), name="status"),
|
re_path(rf"{STATUS_PATH}/activity/?$", views.Status.as_view(), name="status"),
|
||||||
re_path(
|
re_path(
|
||||||
r"%s/replies(.json)?/?$" % STATUS_PATH, views.Replies.as_view(), name="replies"
|
rf"{STATUS_PATH}/replies(.json)?/?$", views.Replies.as_view(), name="replies"
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
r"^post/?$",
|
r"^post/?$",
|
||||||
|
@ -339,17 +341,17 @@ urlpatterns = [
|
||||||
re_path(r"^boost/(?P<status_id>\d+)/?$", views.Boost.as_view()),
|
re_path(r"^boost/(?P<status_id>\d+)/?$", views.Boost.as_view()),
|
||||||
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
|
re_path(r"^unboost/(?P<status_id>\d+)/?$", views.Unboost.as_view()),
|
||||||
# books
|
# books
|
||||||
re_path(r"%s(.json)?/?$" % BOOK_PATH, views.Book.as_view(), name="book"),
|
re_path(rf"{BOOK_PATH}(.json)?/?$", views.Book.as_view(), name="book"),
|
||||||
re_path(
|
re_path(
|
||||||
r"%s/(?P<user_statuses>review|comment|quote)/?$" % BOOK_PATH,
|
rf"{BOOK_PATH}/(?P<user_statuses>review|comment|quote)/?$",
|
||||||
views.Book.as_view(),
|
views.Book.as_view(),
|
||||||
name="book-user-statuses",
|
name="book-user-statuses",
|
||||||
),
|
),
|
||||||
re_path(r"%s/edit/?$" % BOOK_PATH, views.EditBook.as_view(), name="edit-book"),
|
re_path(rf"{BOOK_PATH}/edit/?$", views.EditBook.as_view(), name="edit-book"),
|
||||||
re_path(r"%s/confirm/?$" % BOOK_PATH, views.ConfirmEditBook.as_view()),
|
re_path(rf"{BOOK_PATH}/confirm/?$", views.ConfirmEditBook.as_view()),
|
||||||
re_path(r"^create-book/?$", views.EditBook.as_view(), name="create-book"),
|
re_path(r"^create-book/?$", views.EditBook.as_view(), name="create-book"),
|
||||||
re_path(r"^create-book/confirm?$", views.ConfirmEditBook.as_view()),
|
re_path(r"^create-book/confirm?$", views.ConfirmEditBook.as_view()),
|
||||||
re_path(r"%s/editions(.json)?/?$" % BOOK_PATH, views.Editions.as_view()),
|
re_path(rf"{BOOK_PATH}/editions(.json)?/?$", views.Editions.as_view()),
|
||||||
re_path(
|
re_path(
|
||||||
r"^upload-cover/(?P<book_id>\d+)/?$", views.upload_cover, name="upload-cover"
|
r"^upload-cover/(?P<book_id>\d+)/?$", views.upload_cover, name="upload-cover"
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
DOMAIN = r"[\w_\-\.]+\.[a-z]{2,}"
|
DOMAIN = r"[\w_\-\.]+\.[a-z]{2,}"
|
||||||
LOCALNAME = r"@?[a-zA-Z_\-\.0-9]+"
|
LOCALNAME = r"@?[a-zA-Z_\-\.0-9]+"
|
||||||
STRICT_LOCALNAME = r"@[a-zA-Z_\-\.0-9]+"
|
STRICT_LOCALNAME = r"@[a-zA-Z_\-\.0-9]+"
|
||||||
USERNAME = r"%s(@%s)?" % (LOCALNAME, DOMAIN)
|
USERNAME = rf"{LOCALNAME}(@{DOMAIN})?"
|
||||||
STRICT_USERNAME = r"\B%s(@%s)?\b" % (STRICT_LOCALNAME, DOMAIN)
|
STRICT_USERNAME = rf"\B{STRICT_LOCALNAME}(@{DOMAIN})?\b"
|
||||||
FULL_USERNAME = r"%s@%s\b" % (LOCALNAME, DOMAIN)
|
FULL_USERNAME = rf"{LOCALNAME}@{DOMAIN}\b"
|
||||||
# should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2;
|
# should match (BookWyrm/1.0.0; or (BookWyrm/99.1.2;
|
||||||
BOOKWYRM_USER_AGENT = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"
|
BOOKWYRM_USER_AGENT = r"\(BookWyrm/[0-9]+\.[0-9]+\.[0-9]+;"
|
||||||
|
|
|
@ -55,4 +55,4 @@ class EditAuthor(View):
|
||||||
return TemplateResponse(request, "author/edit_author.html", data)
|
return TemplateResponse(request, "author/edit_author.html", data)
|
||||||
author = form.save()
|
author = form.save()
|
||||||
|
|
||||||
return redirect("/author/%s" % author.id)
|
return redirect(f"/author/{author.id}")
|
||||||
|
|
|
@ -174,7 +174,7 @@ class EditBook(View):
|
||||||
# check if this is an edition of an existing work
|
# check if this is an edition of an existing work
|
||||||
author_text = book.author_text if book else add_author
|
author_text = book.author_text if book else add_author
|
||||||
data["book_matches"] = connector_manager.local_search(
|
data["book_matches"] = connector_manager.local_search(
|
||||||
"%s %s" % (form.cleaned_data.get("title"), author_text),
|
f'{form.cleaned_data.get("title")} {author_text}',
|
||||||
min_confidence=0.5,
|
min_confidence=0.5,
|
||||||
raw=True,
|
raw=True,
|
||||||
)[:5]
|
)[:5]
|
||||||
|
@ -212,7 +212,7 @@ class EditBook(View):
|
||||||
if image:
|
if image:
|
||||||
book.cover.save(*image, save=False)
|
book.cover.save(*image, save=False)
|
||||||
book.save()
|
book.save()
|
||||||
return redirect("/book/%s" % book.id)
|
return redirect(f"/book/{book.id}")
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(login_required, name="dispatch")
|
@method_decorator(login_required, name="dispatch")
|
||||||
|
@ -238,14 +238,14 @@ class ConfirmEditBook(View):
|
||||||
|
|
||||||
# get or create author as needed
|
# get or create author as needed
|
||||||
for i in range(int(request.POST.get("author-match-count", 0))):
|
for i in range(int(request.POST.get("author-match-count", 0))):
|
||||||
match = request.POST.get("author_match-%d" % i)
|
match = request.POST.get(f"author_match-{i}")
|
||||||
if not match:
|
if not match:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
try:
|
try:
|
||||||
# if it's an int, it's an ID
|
# if it's an int, it's an ID
|
||||||
match = int(match)
|
match = int(match)
|
||||||
author = get_object_or_404(
|
author = get_object_or_404(
|
||||||
models.Author, id=request.POST["author_match-%d" % i]
|
models.Author, id=request.POST[f"author_match-{i}"]
|
||||||
)
|
)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# otherwise it's a name
|
# otherwise it's a name
|
||||||
|
@ -267,7 +267,7 @@ class ConfirmEditBook(View):
|
||||||
for author_id in request.POST.getlist("remove_authors"):
|
for author_id in request.POST.getlist("remove_authors"):
|
||||||
book.authors.remove(author_id)
|
book.authors.remove(author_id)
|
||||||
|
|
||||||
return redirect("/book/%s" % book.id)
|
return redirect(f"/book/{book.id}")
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -283,7 +283,7 @@ def upload_cover(request, book_id):
|
||||||
if image:
|
if image:
|
||||||
book.cover.save(*image)
|
book.cover.save(*image)
|
||||||
|
|
||||||
return redirect("{:s}?cover_error=True".format(book.local_path))
|
return redirect(f"{book.local_path}?cover_error=True")
|
||||||
|
|
||||||
form = forms.CoverForm(request.POST, request.FILES, instance=book)
|
form = forms.CoverForm(request.POST, request.FILES, instance=book)
|
||||||
if not form.is_valid() or not form.files.get("cover"):
|
if not form.is_valid() or not form.files.get("cover"):
|
||||||
|
|
|
@ -79,7 +79,7 @@ def save_user_form(form):
|
||||||
|
|
||||||
# set the name to a hash
|
# set the name to a hash
|
||||||
extension = form.files["avatar"].name.split(".")[-1]
|
extension = form.files["avatar"].name.split(".")[-1]
|
||||||
filename = "%s.%s" % (uuid4(), extension)
|
filename = f"{uuid4()}.{extension}"
|
||||||
user.avatar.save(filename, image, save=False)
|
user.avatar.save(filename, image, save=False)
|
||||||
user.save()
|
user.save()
|
||||||
return user
|
return user
|
||||||
|
|
|
@ -96,4 +96,4 @@ def switch_edition(request):
|
||||||
readthrough.book = new_edition
|
readthrough.book = new_edition
|
||||||
readthrough.save()
|
readthrough.save()
|
||||||
|
|
||||||
return redirect("/book/%d" % new_edition.id)
|
return redirect(f"/book/{new_edition.id}")
|
||||||
|
|
|
@ -42,7 +42,7 @@ class Feed(View):
|
||||||
"tab": tab,
|
"tab": tab,
|
||||||
"streams": STREAMS,
|
"streams": STREAMS,
|
||||||
"goal_form": forms.GoalForm(),
|
"goal_form": forms.GoalForm(),
|
||||||
"path": "/%s" % tab["key"],
|
"path": f"/{tab['key']}",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
return TemplateResponse(request, "feed/feed.html", data)
|
return TemplateResponse(request, "feed/feed.html", data)
|
||||||
|
|
|
@ -86,4 +86,4 @@ def delete_follow_request(request):
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
follow_request.delete()
|
follow_request.delete()
|
||||||
return redirect("/user/%s" % request.user.localname)
|
return redirect(f"/user/{request.user.localname}")
|
||||||
|
|
|
@ -77,7 +77,7 @@ def privacy_filter(viewer, queryset, privacy_levels=None, following_only=False):
|
||||||
elif "followers" in privacy_levels:
|
elif "followers" in privacy_levels:
|
||||||
queryset = queryset.exclude(
|
queryset = queryset.exclude(
|
||||||
~Q( # user isn't following and it isn't their own status
|
~Q( # user isn't following and it isn't their own status
|
||||||
Q(user__in=viewer.following.all()) | Q(user=viewer)
|
Q(user__followers=viewer) | Q(user=viewer)
|
||||||
),
|
),
|
||||||
privacy="followers", # and the status is followers only
|
privacy="followers", # and the status is followers only
|
||||||
)
|
)
|
||||||
|
@ -113,7 +113,7 @@ def handle_remote_webfinger(query):
|
||||||
try:
|
try:
|
||||||
user = models.User.objects.get(username__iexact=query)
|
user = models.User.objects.get(username__iexact=query)
|
||||||
except models.User.DoesNotExist:
|
except models.User.DoesNotExist:
|
||||||
url = "https://%s/.well-known/webfinger?resource=acct:%s" % (domain, query)
|
url = f"https://{domain}/.well-known/webfinger?resource=acct:{query}"
|
||||||
try:
|
try:
|
||||||
data = get_data(url)
|
data = get_data(url)
|
||||||
except (ConnectorException, HTTPError):
|
except (ConnectorException, HTTPError):
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Import(View):
|
||||||
|
|
||||||
importer.start_import(job)
|
importer.start_import(job)
|
||||||
|
|
||||||
return redirect("/import/%d" % job.id)
|
return redirect(f"/import/{job.id}")
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,4 +112,4 @@ class ImportStatus(View):
|
||||||
items,
|
items,
|
||||||
)
|
)
|
||||||
importer.start_import(job)
|
importer.start_import(job)
|
||||||
return redirect("/import/%d" % job.id)
|
return redirect(f"/import/{job.id}")
|
||||||
|
|
|
@ -71,7 +71,7 @@ def is_blocked_user_agent(request):
|
||||||
user_agent = request.headers.get("User-Agent")
|
user_agent = request.headers.get("User-Agent")
|
||||||
if not user_agent:
|
if not user_agent:
|
||||||
return False
|
return False
|
||||||
url = re.search(r"https?://{:s}/?".format(regex.DOMAIN), user_agent)
|
url = re.search(rf"https?://{regex.DOMAIN}/?", user_agent)
|
||||||
if not url:
|
if not url:
|
||||||
return False
|
return False
|
||||||
url = url.group()
|
url = url.group()
|
||||||
|
|
|
@ -36,6 +36,8 @@ class Lists(View):
|
||||||
item_count=Count("listitem", filter=Q(listitem__approved=True))
|
item_count=Count("listitem", filter=Q(listitem__approved=True))
|
||||||
)
|
)
|
||||||
.filter(item_count__gt=0)
|
.filter(item_count__gt=0)
|
||||||
|
.select_related("user")
|
||||||
|
.prefetch_related("listitem_set")
|
||||||
.order_by("-updated_date")
|
.order_by("-updated_date")
|
||||||
.distinct()
|
.distinct()
|
||||||
)
|
)
|
||||||
|
@ -322,7 +324,7 @@ def add_book(request):
|
||||||
path = reverse("list", args=[book_list.id])
|
path = reverse("list", args=[book_list.id])
|
||||||
params = request.GET.copy()
|
params = request.GET.copy()
|
||||||
params["updated"] = True
|
params["updated"] = True
|
||||||
return redirect("{:s}?{:s}".format(path, urlencode(params)))
|
return redirect(f"{path}?{urlencode(params)}")
|
||||||
|
|
||||||
|
|
||||||
@require_POST
|
@require_POST
|
||||||
|
@ -396,7 +398,7 @@ def set_book_position(request, list_item_id):
|
||||||
def increment_order_in_reverse(
|
def increment_order_in_reverse(
|
||||||
book_list_id: int, start: int, end: Optional[int] = None
|
book_list_id: int, start: int, end: Optional[int] = None
|
||||||
):
|
):
|
||||||
"""increase the order nu,ber for every item in a list"""
|
"""increase the order number for every item in a list"""
|
||||||
try:
|
try:
|
||||||
book_list = models.List.objects.get(id=book_list_id)
|
book_list = models.List.objects.get(id=book_list_id)
|
||||||
except models.List.DoesNotExist:
|
except models.List.DoesNotExist:
|
||||||
|
|
|
@ -46,7 +46,7 @@ class Login(View):
|
||||||
except models.User.DoesNotExist: # maybe it's a full username?
|
except models.User.DoesNotExist: # maybe it's a full username?
|
||||||
username = localname
|
username = localname
|
||||||
else:
|
else:
|
||||||
username = "%s@%s" % (localname, DOMAIN)
|
username = f"{localname}@{DOMAIN}"
|
||||||
password = login_form.data["password"]
|
password = login_form.data["password"]
|
||||||
|
|
||||||
# perform authentication
|
# perform authentication
|
||||||
|
|
|
@ -38,7 +38,7 @@ class PasswordResetRequest(View):
|
||||||
# create a new reset code
|
# create a new reset code
|
||||||
code = models.PasswordReset.objects.create(user=user)
|
code = models.PasswordReset.objects.create(user=user)
|
||||||
password_reset_email(code)
|
password_reset_email(code)
|
||||||
data = {"message": _("A password reset link sent to %s" % email)}
|
data = {"message": _(f"A password reset link sent to {email}")}
|
||||||
return TemplateResponse(request, "password_reset_request.html", data)
|
return TemplateResponse(request, "password_reset_request.html", data)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class Register(View):
|
||||||
return TemplateResponse(request, "invite.html", data)
|
return TemplateResponse(request, "invite.html", data)
|
||||||
return TemplateResponse(request, "login.html", data)
|
return TemplateResponse(request, "login.html", data)
|
||||||
|
|
||||||
username = "%s@%s" % (localname, DOMAIN)
|
username = f"{localname}@{DOMAIN}"
|
||||||
user = models.User.objects.create_user(
|
user = models.User.objects.create_user(
|
||||||
username,
|
username,
|
||||||
email,
|
email,
|
||||||
|
|
|
@ -63,7 +63,7 @@ class Search(View):
|
||||||
data["results"] = paginated
|
data["results"] = paginated
|
||||||
data["remote"] = search_remote
|
data["remote"] = search_remote
|
||||||
|
|
||||||
return TemplateResponse(request, "search/{:s}.html".format(search_type), data)
|
return TemplateResponse(request, f"search/{search_type}.html", data)
|
||||||
|
|
||||||
|
|
||||||
def book_search(query, _, min_confidence, search_remote=False):
|
def book_search(query, _, min_confidence, search_remote=False):
|
||||||
|
|
|
@ -36,7 +36,7 @@ class CreateStatus(View):
|
||||||
status_type = status_type[0].upper() + status_type[1:]
|
status_type = status_type[0].upper() + status_type[1:]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
form = getattr(forms, "%sForm" % status_type)(request.POST)
|
form = getattr(forms, f"{status_type}Form")(request.POST)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
return HttpResponseBadRequest()
|
return HttpResponseBadRequest()
|
||||||
if not form.is_valid():
|
if not form.is_valid():
|
||||||
|
@ -58,8 +58,8 @@ class CreateStatus(View):
|
||||||
|
|
||||||
# turn the mention into a link
|
# turn the mention into a link
|
||||||
content = re.sub(
|
content = re.sub(
|
||||||
r"%s([^@]|$)" % mention_text,
|
rf"{mention_text}([^@]|$)",
|
||||||
r'<a href="%s">%s</a>\g<1>' % (mention_user.remote_id, mention_text),
|
rf'<a href="{mention_user.remote_id}">{mention_text}</a>\g<1>',
|
||||||
content,
|
content,
|
||||||
)
|
)
|
||||||
# add reply parent to mentions
|
# add reply parent to mentions
|
||||||
|
@ -182,7 +182,7 @@ def format_links(content):
|
||||||
if url.fragment != "":
|
if url.fragment != "":
|
||||||
link += "#" + url.fragment
|
link += "#" + url.fragment
|
||||||
|
|
||||||
formatted_content += '<a href="%s">%s</a>' % (potential_link, link)
|
formatted_content += f'<a href="{potential_link}">{link}</a>'
|
||||||
except (ValidationError, UnicodeError):
|
except (ValidationError, UnicodeError):
|
||||||
formatted_content += potential_link
|
formatted_content += potential_link
|
||||||
|
|
||||||
|
|
|
@ -59,8 +59,18 @@ class User(View):
|
||||||
request.user,
|
request.user,
|
||||||
user.status_set.select_subclasses(),
|
user.status_set.select_subclasses(),
|
||||||
)
|
)
|
||||||
.select_related("reply_parent")
|
.select_related(
|
||||||
.prefetch_related("mention_books", "mention_users")
|
"user",
|
||||||
|
"reply_parent",
|
||||||
|
"review__book",
|
||||||
|
"comment__book",
|
||||||
|
"quotation__book",
|
||||||
|
)
|
||||||
|
.prefetch_related(
|
||||||
|
"mention_books",
|
||||||
|
"mention_users",
|
||||||
|
"attachments",
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
paginated = Paginator(activities, PAGE_LENGTH)
|
paginated = Paginator(activities, PAGE_LENGTH)
|
||||||
|
|
|
@ -26,7 +26,7 @@ def webfinger(request):
|
||||||
|
|
||||||
return JsonResponse(
|
return JsonResponse(
|
||||||
{
|
{
|
||||||
"subject": "acct:%s" % (user.username),
|
"subject": f"acct:{user.username}",
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"rel": "self",
|
"rel": "self",
|
||||||
|
@ -46,7 +46,7 @@ def nodeinfo_pointer(_):
|
||||||
"links": [
|
"links": [
|
||||||
{
|
{
|
||||||
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
|
"rel": "http://nodeinfo.diaspora.software/ns/schema/2.0",
|
||||||
"href": "https://%s/nodeinfo/2.0" % DOMAIN,
|
"href": f"https://{DOMAIN}/nodeinfo/2.0",
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-03-02 17:19-0800\n"
|
"PO-Revision-Date: 2021-03-02 17:19-0800\n"
|
||||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||||
"Language-Team: English <LL@li.org>\n"
|
"Language-Team: English <LL@li.org>\n"
|
||||||
|
@ -143,7 +143,7 @@ msgstr "%(value)s ist keine gültige remote_id"
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr "%(value)s ist kein gültiger Username"
|
msgstr "%(value)s ist kein gültiger Username"
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "Username"
|
msgstr "Username"
|
||||||
|
|
||||||
|
@ -359,7 +359,7 @@ msgstr ""
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Speichern"
|
msgstr "Speichern"
|
||||||
|
@ -374,7 +374,7 @@ msgstr "Speichern"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Abbrechen"
|
msgstr "Abbrechen"
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ msgstr "Themen"
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "Orte"
|
msgstr "Orte"
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -876,7 +876,7 @@ msgstr "Föderiert"
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr "Vereichnis"
|
msgstr "Vereichnis"
|
||||||
|
|
||||||
|
@ -959,7 +959,7 @@ msgstr "Alle bekannten Nutzer*innen"
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Discard"
|
#| msgid "Discard"
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
|
@ -1095,7 +1095,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr "Direktnachrichten mit <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/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr "Direktnachrichten"
|
msgstr "Direktnachrichten"
|
||||||
|
|
||||||
|
@ -1182,7 +1182,7 @@ msgid "What are you reading?"
|
||||||
msgstr "Zu lesen angefangen"
|
msgstr "Zu lesen angefangen"
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr "Nach einem Buch suchen"
|
msgstr "Nach einem Buch suchen"
|
||||||
|
|
||||||
|
@ -1200,7 +1200,7 @@ msgstr "Du kannst Bücher hinzufügen, wenn du %(site_name)s benutzt."
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1538,29 +1538,31 @@ msgstr "Danke! Deine Anfrage ist eingegangen."
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr "Dein Account"
|
msgstr "Dein Account"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
#, fuzzy
|
||||||
|
#| msgid "Search for a book or user"
|
||||||
|
msgid "Search for a book, user, or list"
|
||||||
msgstr "Suche nach Buch oder Benutzer*in"
|
msgstr "Suche nach Buch oder Benutzer*in"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr "Navigationshauptmenü"
|
msgstr "Navigationshauptmenü"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Your books"
|
#| msgid "Your books"
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr "Deine Bücher"
|
msgstr "Deine Bücher"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1568,77 +1570,77 @@ msgstr "Einstellungen"
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr "Einladungen"
|
msgstr "Einladungen"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Benachrichtigungen"
|
msgstr "Benachrichtigungen"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr "Passwort"
|
msgstr "Passwort"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr "Passwort vergessen?"
|
msgstr "Passwort vergessen?"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr "Anmelden"
|
msgstr "Anmelden"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Successfully imported"
|
#| msgid "Successfully imported"
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr "Erfolgreich importiert"
|
msgstr "Erfolgreich importiert"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Boost status"
|
#| msgid "Boost status"
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr "Status teilen"
|
msgstr "Status teilen"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "About this server"
|
#| msgid "About this server"
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr "Über diesen Server"
|
msgstr "Über diesen Server"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr "Admin kontaktieren"
|
msgstr "Admin kontaktieren"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "List curation:"
|
#| msgid "List curation:"
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr "Listenkuratierung:"
|
msgstr "Listenkuratierung:"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr "%(site_name)s auf <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> unterstützen"
|
msgstr "%(site_name)s auf <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> unterstützen"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. 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."
|
msgstr "BookWyrm ist open source Software. Du kannst dich auf <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> beteiligen oder etwas melden."
|
||||||
|
|
||||||
|
@ -3041,19 +3043,19 @@ msgid "Progress:"
|
||||||
msgstr "Fortschritt:"
|
msgstr "Fortschritt:"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr "Seiten"
|
msgstr "Seiten"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr "Prozent"
|
msgstr "Prozent"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr "von %(pages)s Seiten"
|
msgstr "von %(pages)s Seiten"
|
||||||
|
@ -3085,7 +3087,7 @@ msgstr "Spoileralarm!"
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr "Spoileralarm aktivieren"
|
msgstr "Spoileralarm aktivieren"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Comment"
|
#| msgid "Comment"
|
||||||
|
@ -3443,32 +3445,40 @@ msgstr "Listen: %(username)s"
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr "Lesen abschließen"
|
msgstr "Lesen abschließen"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
#, fuzzy
|
||||||
msgid "Show more"
|
#| msgid "Footer Content"
|
||||||
msgstr "Mehr anzeigen"
|
msgid "Content warning"
|
||||||
|
msgstr "Inhalt des Footers"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
#, fuzzy
|
||||||
msgid "Show less"
|
#| msgid "Like status"
|
||||||
msgstr "Weniger anzeigen"
|
msgid "Show status"
|
||||||
|
msgstr "Status favorisieren"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "%(pages)s pages"
|
#| msgid "%(pages)s pages"
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr "%(pages)s Seiten"
|
msgstr "%(pages)s Seiten"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "%(percent)s%% complete!"
|
#| msgid "%(percent)s%% complete!"
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr "%(percent)s%% komplett!"
|
msgstr "%(percent)s%% komplett!"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr "Bild in neuem Fenster öffnen"
|
msgstr "Bild in neuem Fenster öffnen"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Like status"
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr "Status favorisieren"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
||||||
|
@ -3590,6 +3600,14 @@ msgstr "Zu lesen angefangen"
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr "Zu lesen angefangen"
|
msgstr "Zu lesen angefangen"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr "Mehr anzeigen"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr "Weniger anzeigen"
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr "Benutzerprofil"
|
msgstr "Benutzerprofil"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
|
"PO-Revision-Date: 2021-02-28 17:19-0800\n"
|
||||||
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
"Last-Translator: Mouse Reeve <mousereeve@riseup.net>\n"
|
||||||
"Language-Team: English <LL@li.org>\n"
|
"Language-Team: English <LL@li.org>\n"
|
||||||
|
@ -125,7 +125,7 @@ msgstr ""
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ msgstr ""
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -342,7 +342,7 @@ msgstr ""
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ msgstr ""
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -795,7 +795,7 @@ msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -993,7 +993,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1073,7 +1073,7 @@ msgid "What are you reading?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -1091,7 +1091,7 @@ msgstr ""
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1408,27 +1408,27 @@ msgstr ""
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
msgid "Search for a book, user, or list"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1436,69 +1436,69 @@ msgstr ""
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2712,19 +2712,19 @@ msgid "Progress:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -2752,7 +2752,7 @@ msgstr ""
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -3076,30 +3076,32 @@ msgstr ""
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
msgid "Content warning"
|
||||||
msgid "Show more"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
msgid "Show status"
|
||||||
msgid "Show less"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
||||||
|
@ -3205,6 +3207,14 @@ msgstr ""
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
|
"PO-Revision-Date: 2021-03-19 11:49+0800\n"
|
||||||
"Last-Translator: Reese Porter <reesedporter@gmail.com>\n"
|
"Last-Translator: Reese Porter <reesedporter@gmail.com>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -125,7 +125,7 @@ msgstr "%(value)s no es un remote_id válido"
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr "%(value)s no es un usuario válido"
|
msgstr "%(value)s no es un usuario válido"
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "nombre de usuario"
|
msgstr "nombre de usuario"
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ msgstr "Clave Goodreads:"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Guardar"
|
msgstr "Guardar"
|
||||||
|
@ -342,7 +342,7 @@ msgstr "Guardar"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Cancelar"
|
msgstr "Cancelar"
|
||||||
|
|
||||||
|
@ -438,7 +438,7 @@ msgstr "Sujetos"
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "Lugares"
|
msgstr "Lugares"
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -795,7 +795,7 @@ msgstr "Comunidad federalizada"
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr "Directorio"
|
msgstr "Directorio"
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ msgstr "Todos los usuarios conocidos"
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
msgstr "Descubrir"
|
msgstr "Descubrir"
|
||||||
|
|
||||||
|
@ -993,7 +993,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr "Mensajes directos con <a href=\"%(path)s\">%(username)s</a>"
|
msgstr "Mensajes directos con <a href=\"%(path)s\">%(username)s</a>"
|
||||||
|
|
||||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr "Mensajes directos"
|
msgstr "Mensajes directos"
|
||||||
|
|
||||||
|
@ -1073,7 +1073,7 @@ msgid "What are you reading?"
|
||||||
msgstr "¿Qué estás leyendo?"
|
msgstr "¿Qué estás leyendo?"
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr "Buscar libros"
|
msgstr "Buscar libros"
|
||||||
|
|
||||||
|
@ -1091,7 +1091,7 @@ msgstr "Puedes agregar libros cuando comiences a usar %(site_name)s."
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1409,27 +1409,29 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido."
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr "Tu cuenta"
|
msgstr "Tu cuenta"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
#, fuzzy
|
||||||
|
#| msgid "Search for a book or user"
|
||||||
|
msgid "Search for a book, user, or list"
|
||||||
msgstr "Buscar un libro o un usuario"
|
msgstr "Buscar un libro o un usuario"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr "Menú de navigación central"
|
msgstr "Menú de navigación central"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr "Actividad"
|
msgstr "Actividad"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr "Tus libros"
|
msgstr "Tus libros"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Configuración"
|
msgstr "Configuración"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1437,69 +1439,69 @@ msgstr "Configuración"
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr "Invitaciones"
|
msgstr "Invitaciones"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Cerrar sesión"
|
msgstr "Cerrar sesión"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Notificaciones"
|
msgstr "Notificaciones"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr "Nombre de usuario:"
|
msgstr "Nombre de usuario:"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr "contraseña"
|
msgstr "contraseña"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr "¿Olvidaste tu contraseña?"
|
msgstr "¿Olvidaste tu contraseña?"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr "Iniciar sesión"
|
msgstr "Iniciar sesión"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Unirse"
|
msgstr "Unirse"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr "Status publicado exitosamente"
|
msgstr "Status publicado exitosamente"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr "Error en publicar status"
|
msgstr "Error en publicar status"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr "Sobre esta instancia"
|
msgstr "Sobre esta instancia"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr "Contactarse con administradores del sitio"
|
msgstr "Contactarse con administradores del sitio"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr "Documentación de Django"
|
msgstr "Documentación de Django"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr "Apoyar %(site_name)s en <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgstr "Apoyar %(site_name)s en <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||||
msgstr "BookWyrm es software de código abierto. Puedes contribuir o reportar problemas en <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgstr "BookWyrm es software de código abierto. Puedes contribuir o reportar problemas en <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
||||||
|
|
||||||
|
@ -2723,19 +2725,19 @@ msgid "Progress:"
|
||||||
msgstr "Progreso:"
|
msgstr "Progreso:"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr "páginas"
|
msgstr "páginas"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr "por ciento"
|
msgstr "por ciento"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr "de %(pages)s páginas"
|
msgstr "de %(pages)s páginas"
|
||||||
|
@ -2765,7 +2767,7 @@ msgstr "¡Advertencia, ya vienen spoilers!"
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr "Incluir alerta de spoiler"
|
msgstr "Incluir alerta de spoiler"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr "Comentario:"
|
msgstr "Comentario:"
|
||||||
|
@ -3089,30 +3091,38 @@ msgstr "Quitar de %(name)s"
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr "Terminar de leer"
|
msgstr "Terminar de leer"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
#, fuzzy
|
||||||
msgid "Show more"
|
#| msgid "Content:"
|
||||||
msgstr "Mostrar más"
|
msgid "Content warning"
|
||||||
|
msgstr "Contenido:"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
#, fuzzy
|
||||||
msgid "Show less"
|
#| msgid "View status"
|
||||||
msgstr "Mostrar menos"
|
msgid "Show status"
|
||||||
|
msgstr "Ver status"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr "(Página %(page)s)"
|
msgstr "(Página %(page)s)"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr "(%(percent)s%%)"
|
msgstr "(%(percent)s%%)"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr "Abrir imagen en una nueva ventana"
|
msgstr "Abrir imagen en una nueva ventana"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Like status"
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr "Me gusta status"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
||||||
|
@ -3218,6 +3228,14 @@ msgstr "En orden ascendente"
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr "En orden descendente"
|
msgstr "En orden descendente"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr "Mostrar más"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr "Mostrar menos"
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr "Perfil de usuario"
|
msgstr "Perfil de usuario"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.1.1\n"
|
"Project-Id-Version: 0.1.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-04-05 12:44+0100\n"
|
"PO-Revision-Date: 2021-04-05 12:44+0100\n"
|
||||||
"Last-Translator: Fabien Basmaison <contact@arkhi.org>\n"
|
"Last-Translator: Fabien Basmaison <contact@arkhi.org>\n"
|
||||||
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
||||||
|
@ -133,7 +133,7 @@ msgstr "%(value)s n’est pas une remote_id valide."
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr "%(value)s n’est pas un nom de compte valide."
|
msgstr "%(value)s n’est pas un nom de compte valide."
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "nom du compte :"
|
msgstr "nom du compte :"
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ msgstr "Clé Goodreads :"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "Enregistrer"
|
msgstr "Enregistrer"
|
||||||
|
@ -354,7 +354,7 @@ msgstr "Enregistrer"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "Annuler"
|
msgstr "Annuler"
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ msgstr "Sujets"
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "Lieux"
|
msgstr "Lieux"
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -809,7 +809,7 @@ msgstr "Communauté fédérée"
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr "Répertoire"
|
msgstr "Répertoire"
|
||||||
|
|
||||||
|
@ -883,7 +883,7 @@ msgstr "Tous les comptes connus"
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Discard"
|
#| msgid "Discard"
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
|
@ -1013,7 +1013,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr "Messages directs avec <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/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr "Messages directs"
|
msgstr "Messages directs"
|
||||||
|
|
||||||
|
@ -1098,7 +1098,7 @@ msgid "What are you reading?"
|
||||||
msgstr "Que lisez‑vous ?"
|
msgstr "Que lisez‑vous ?"
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr "Chercher un livre"
|
msgstr "Chercher un livre"
|
||||||
|
|
||||||
|
@ -1116,7 +1116,7 @@ msgstr "Vous pourrez ajouter des livres lorsque vous commencerez à utiliser %(s
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1438,27 +1438,29 @@ msgstr "Merci ! Votre demande a bien été reçue."
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr "Votre compte"
|
msgstr "Votre compte"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
#, fuzzy
|
||||||
|
#| msgid "Search for a book or user"
|
||||||
|
msgid "Search for a book, user, or list"
|
||||||
msgstr "Chercher un livre ou un compte"
|
msgstr "Chercher un livre ou un compte"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr "Menu de navigation principal "
|
msgstr "Menu de navigation principal "
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr "Fil d’actualité"
|
msgstr "Fil d’actualité"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr "Vos Livres"
|
msgstr "Vos Livres"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Paramètres"
|
msgstr "Paramètres"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1466,73 +1468,73 @@ msgstr "Paramètres"
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr "Invitations"
|
msgstr "Invitations"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "Se déconnecter"
|
msgstr "Se déconnecter"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "Notifications"
|
msgstr "Notifications"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr "Nom du compte :"
|
msgstr "Nom du compte :"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr "Mot de passe"
|
msgstr "Mot de passe"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr "Mot de passe oublié ?"
|
msgstr "Mot de passe oublié ?"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr "Se connecter"
|
msgstr "Se connecter"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "Rejoindre"
|
msgstr "Rejoindre"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Successfully imported"
|
#| msgid "Successfully imported"
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr "Importation réussie"
|
msgstr "Importation réussie"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Boost status"
|
#| msgid "Boost status"
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr "Partager le statut"
|
msgstr "Partager le statut"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr "À propos de cette instance"
|
msgstr "À propos de cette instance"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr "Contacter l’administrateur du site"
|
msgstr "Contacter l’administrateur du site"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr "Documentation"
|
msgstr "Documentation"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr "Soutenez %(site_name)s avec <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgstr "Soutenez %(site_name)s avec <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. 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>."
|
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>."
|
||||||
|
|
||||||
|
@ -2813,19 +2815,19 @@ msgid "Progress:"
|
||||||
msgstr "Progression :"
|
msgstr "Progression :"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr "pages"
|
msgstr "pages"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr "pourcent"
|
msgstr "pourcent"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr "sur %(pages)s pages"
|
msgstr "sur %(pages)s pages"
|
||||||
|
@ -2855,7 +2857,7 @@ msgstr "Attention spoilers !"
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr "Afficher une alerte spoiler"
|
msgstr "Afficher une alerte spoiler"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr "Commentaire :"
|
msgstr "Commentaire :"
|
||||||
|
@ -3193,32 +3195,40 @@ msgstr "Retirer de %(name)s"
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr "Terminer la lecture"
|
msgstr "Terminer la lecture"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
#, fuzzy
|
||||||
msgid "Show more"
|
#| msgid "Content"
|
||||||
msgstr "Déplier"
|
msgid "Content warning"
|
||||||
|
msgstr "Contenu"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
#, fuzzy
|
||||||
msgid "Show less"
|
#| msgid "Like status"
|
||||||
msgstr "Replier"
|
msgid "Show status"
|
||||||
|
msgstr "Ajouter le statut aux favoris"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "page %(page)s"
|
#| msgid "page %(page)s"
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr "page %(page)s"
|
msgstr "page %(page)s"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "%(percent)s%% complete!"
|
#| msgid "%(percent)s%% complete!"
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr "%(percent)s%% terminé !"
|
msgstr "%(percent)s%% terminé !"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr "Ouvrir l’image dans une nouvelle fenêtre"
|
msgstr "Ouvrir l’image dans une nouvelle fenêtre"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Like status"
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr "Ajouter le statut aux favoris"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
||||||
|
@ -3333,6 +3343,14 @@ msgstr "Trié par ordre croissant"
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr "Trié par ordre décroissant"
|
msgstr "Trié par ordre décroissant"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr "Déplier"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr "Replier"
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr "Profil"
|
msgstr "Profil"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.1.1\n"
|
"Project-Id-Version: 0.1.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-03-20 00:56+0000\n"
|
"PO-Revision-Date: 2021-03-20 00:56+0000\n"
|
||||||
"Last-Translator: Kana <gudzpoz@live.com>\n"
|
"Last-Translator: Kana <gudzpoz@live.com>\n"
|
||||||
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
"Language-Team: Mouse Reeve <LL@li.org>\n"
|
||||||
|
@ -133,7 +133,7 @@ msgstr "%(value)s 不是有效的 remote_id"
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr "%(value)s 不是有效的用户名"
|
msgstr "%(value)s 不是有效的用户名"
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "用户名"
|
msgstr "用户名"
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ msgstr "Goodreads key:"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "保存"
|
msgstr "保存"
|
||||||
|
@ -350,7 +350,7 @@ msgstr "保存"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "取消"
|
msgstr "取消"
|
||||||
|
|
||||||
|
@ -445,7 +445,7 @@ msgstr "主题"
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "地点"
|
msgstr "地点"
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -804,7 +804,7 @@ msgstr "跨站社区"
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr "目录"
|
msgstr "目录"
|
||||||
|
|
||||||
|
@ -874,7 +874,7 @@ msgstr "所有已知用户"
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
msgstr "发现"
|
msgstr "发现"
|
||||||
|
|
||||||
|
@ -1000,7 +1000,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr "与 <a href=\"%(path)s\">%(username)s</a> 私信"
|
msgstr "与 <a href=\"%(path)s\">%(username)s</a> 私信"
|
||||||
|
|
||||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr "私信"
|
msgstr "私信"
|
||||||
|
|
||||||
|
@ -1084,7 +1084,7 @@ msgid "What are you reading?"
|
||||||
msgstr "你在阅读什么?"
|
msgstr "你在阅读什么?"
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr "搜索书目"
|
msgstr "搜索书目"
|
||||||
|
|
||||||
|
@ -1102,7 +1102,7 @@ msgstr "你可以在开始使用 %(site_name)s 后添加书目。"
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1420,27 +1420,29 @@ msgstr "谢谢你!我们已经收到了你的请求。"
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr "你的帐号"
|
msgstr "你的帐号"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
#, fuzzy
|
||||||
|
#| msgid "Search for a book or user"
|
||||||
|
msgid "Search for a book, user, or list"
|
||||||
msgstr "搜索书目或用户"
|
msgstr "搜索书目或用户"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr "主导航菜单"
|
msgstr "主导航菜单"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr "动态"
|
msgstr "动态"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr "你的书目"
|
msgstr "你的书目"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "设置"
|
msgstr "设置"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1448,73 +1450,73 @@ msgstr "设置"
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr "邀请"
|
msgstr "邀请"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "管理员"
|
msgstr "管理员"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "登出"
|
msgstr "登出"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "通知"
|
msgstr "通知"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr "用户名:"
|
msgstr "用户名:"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr "密码"
|
msgstr "密码"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr "忘记了密码?"
|
msgstr "忘记了密码?"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr "登录"
|
msgstr "登录"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "加入"
|
msgstr "加入"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Successfully imported"
|
#| msgid "Successfully imported"
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr "成功导入了"
|
msgstr "成功导入了"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Boost status"
|
#| msgid "Boost status"
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr "转发状态"
|
msgstr "转发状态"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr "关于本实例"
|
msgstr "关于本实例"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr "联系站点管理员"
|
msgstr "联系站点管理员"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr "文档"
|
msgstr "文档"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr "在 <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> 上支持 %(site_name)s"
|
msgstr "在 <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> 上支持 %(site_name)s"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. 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> 贡献或报告问题。"
|
msgstr "BookWyrm 是开源软件。你可以在 <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> 贡献或报告问题。"
|
||||||
|
|
||||||
|
@ -2780,19 +2782,19 @@ msgid "Progress:"
|
||||||
msgstr "进度:"
|
msgstr "进度:"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr "页数"
|
msgstr "页数"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr "百分比"
|
msgstr "百分比"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr "全书 %(pages)s 页"
|
msgstr "全书 %(pages)s 页"
|
||||||
|
@ -2822,7 +2824,7 @@ msgstr "前有剧透!"
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr "加入剧透警告"
|
msgstr "加入剧透警告"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr "评论:"
|
msgstr "评论:"
|
||||||
|
@ -3149,32 +3151,40 @@ msgstr "从 %(name)s 移除"
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr "完成阅读"
|
msgstr "完成阅读"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
#, fuzzy
|
||||||
msgid "Show more"
|
#| msgid "Content"
|
||||||
msgstr "显示更多"
|
msgid "Content warning"
|
||||||
|
msgstr "内容"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
#, fuzzy
|
||||||
msgid "Show less"
|
#| msgid "View status"
|
||||||
msgstr "显示更少"
|
msgid "Show status"
|
||||||
|
msgstr "浏览状态"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "page %(page)s"
|
#| msgid "page %(page)s"
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr "第 %(page)s 页"
|
msgstr "第 %(page)s 页"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "%(percent)s%% complete!"
|
#| msgid "%(percent)s%% complete!"
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr "完成了 %(percent)s%% !"
|
msgstr "完成了 %(percent)s%% !"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr "在新窗口中打开图像"
|
msgstr "在新窗口中打开图像"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Like status"
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr "喜欢状态"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
msgid "commented on <a href=\"%(book_path)s\">%(book)s</a>"
|
||||||
|
@ -3278,6 +3288,14 @@ msgstr "升序排序"
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr "降序排序"
|
msgstr "降序排序"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr "显示更多"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr "显示更少"
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr "用户个人资料"
|
msgstr "用户个人资料"
|
||||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: 0.0.1\n"
|
"Project-Id-Version: 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2021-09-18 22:57+0000\n"
|
"POT-Creation-Date: 2021-09-20 19:44+0000\n"
|
||||||
"PO-Revision-Date: 2021-06-30 10:36+0000\n"
|
"PO-Revision-Date: 2021-06-30 10:36+0000\n"
|
||||||
"Last-Translator: Grace Cheng <chengracecwy@gmail.com>\n"
|
"Last-Translator: Grace Cheng <chengracecwy@gmail.com>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -133,7 +133,7 @@ msgstr "%(value)s 不是有效的 remote_id"
|
||||||
msgid "%(value)s is not a valid username"
|
msgid "%(value)s is not a valid username"
|
||||||
msgstr "%(value)s 不是有效的使用者名稱"
|
msgstr "%(value)s 不是有效的使用者名稱"
|
||||||
|
|
||||||
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:164
|
#: bookwyrm/models/fields.py:181 bookwyrm/templates/layout.html:169
|
||||||
msgid "username"
|
msgid "username"
|
||||||
msgstr "使用者名稱"
|
msgstr "使用者名稱"
|
||||||
|
|
||||||
|
@ -341,7 +341,7 @@ msgstr "Goodreads key:"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:98
|
#: bookwyrm/templates/settings/federated_server.html:98
|
||||||
#: bookwyrm/templates/settings/site.html:120
|
#: bookwyrm/templates/settings/site.html:120
|
||||||
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
#: bookwyrm/templates/snippets/reading_modals/layout.html:16
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:42
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
||||||
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
#: bookwyrm/templates/user_admin/user_moderation_actions.html:64
|
||||||
msgid "Save"
|
msgid "Save"
|
||||||
msgstr "儲存"
|
msgstr "儲存"
|
||||||
|
@ -356,7 +356,7 @@ msgstr "儲存"
|
||||||
#: bookwyrm/templates/settings/federated_server.html:99
|
#: bookwyrm/templates/settings/federated_server.html:99
|
||||||
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
#: bookwyrm/templates/snippets/delete_readthrough_modal.html:17
|
||||||
#: bookwyrm/templates/snippets/goal_form.html:32
|
#: bookwyrm/templates/snippets/goal_form.html:32
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:43
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:44
|
||||||
msgid "Cancel"
|
msgid "Cancel"
|
||||||
msgstr "取消"
|
msgstr "取消"
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ msgstr "主題"
|
||||||
msgid "Places"
|
msgid "Places"
|
||||||
msgstr "地點"
|
msgstr "地點"
|
||||||
|
|
||||||
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:68
|
#: bookwyrm/templates/book/book.html:292 bookwyrm/templates/layout.html:73
|
||||||
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
#: bookwyrm/templates/lists/lists.html:5 bookwyrm/templates/lists/lists.html:12
|
||||||
#: bookwyrm/templates/search/layout.html:25
|
#: bookwyrm/templates/search/layout.html:25
|
||||||
#: bookwyrm/templates/search/layout.html:50
|
#: bookwyrm/templates/search/layout.html:50
|
||||||
|
@ -820,7 +820,7 @@ msgstr "跨站社群"
|
||||||
|
|
||||||
#: bookwyrm/templates/directory/directory.html:4
|
#: bookwyrm/templates/directory/directory.html:4
|
||||||
#: bookwyrm/templates/directory/directory.html:9
|
#: bookwyrm/templates/directory/directory.html:9
|
||||||
#: bookwyrm/templates/layout.html:94
|
#: bookwyrm/templates/layout.html:99
|
||||||
msgid "Directory"
|
msgid "Directory"
|
||||||
msgstr "目錄"
|
msgstr "目錄"
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ msgstr "所有已知使用者"
|
||||||
|
|
||||||
#: bookwyrm/templates/discover/discover.html:4
|
#: bookwyrm/templates/discover/discover.html:4
|
||||||
#: bookwyrm/templates/discover/discover.html:10
|
#: bookwyrm/templates/discover/discover.html:10
|
||||||
#: bookwyrm/templates/layout.html:71
|
#: bookwyrm/templates/layout.html:76
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Discard"
|
#| msgid "Discard"
|
||||||
msgid "Discover"
|
msgid "Discover"
|
||||||
|
@ -1024,7 +1024,7 @@ msgid "Direct Messages with <a href=\"%(path)s\">%(username)s</a>"
|
||||||
msgstr "與 <a href=\"%(path)s\">%(username)s</a> 私信"
|
msgstr "與 <a href=\"%(path)s\">%(username)s</a> 私信"
|
||||||
|
|
||||||
#: bookwyrm/templates/feed/direct_messages.html:10
|
#: bookwyrm/templates/feed/direct_messages.html:10
|
||||||
#: bookwyrm/templates/layout.html:104
|
#: bookwyrm/templates/layout.html:109
|
||||||
msgid "Direct Messages"
|
msgid "Direct Messages"
|
||||||
msgstr "私信"
|
msgstr "私信"
|
||||||
|
|
||||||
|
@ -1109,7 +1109,7 @@ msgid "What are you reading?"
|
||||||
msgstr "你在閱讀什麼?"
|
msgstr "你在閱讀什麼?"
|
||||||
|
|
||||||
#: bookwyrm/templates/get_started/books.html:9
|
#: bookwyrm/templates/get_started/books.html:9
|
||||||
#: bookwyrm/templates/lists/list.html:135
|
#: bookwyrm/templates/layout.html:43 bookwyrm/templates/lists/list.html:135
|
||||||
msgid "Search for a book"
|
msgid "Search for a book"
|
||||||
msgstr "搜尋書目"
|
msgstr "搜尋書目"
|
||||||
|
|
||||||
|
@ -1127,7 +1127,7 @@ msgstr "你可以在開始使用 %(site_name)s 後新增書目。"
|
||||||
#: bookwyrm/templates/get_started/books.html:17
|
#: bookwyrm/templates/get_started/books.html:17
|
||||||
#: bookwyrm/templates/get_started/users.html:18
|
#: bookwyrm/templates/get_started/users.html:18
|
||||||
#: bookwyrm/templates/get_started/users.html:19
|
#: bookwyrm/templates/get_started/users.html:19
|
||||||
#: bookwyrm/templates/layout.html:44 bookwyrm/templates/layout.html:45
|
#: bookwyrm/templates/layout.html:49 bookwyrm/templates/layout.html:50
|
||||||
#: bookwyrm/templates/lists/list.html:139
|
#: bookwyrm/templates/lists/list.html:139
|
||||||
#: bookwyrm/templates/search/layout.html:4
|
#: bookwyrm/templates/search/layout.html:4
|
||||||
#: bookwyrm/templates/search/layout.html:9
|
#: bookwyrm/templates/search/layout.html:9
|
||||||
|
@ -1449,27 +1449,29 @@ msgstr "謝謝你!我們已經受到了你的請求。"
|
||||||
msgid "Your Account"
|
msgid "Your Account"
|
||||||
msgstr "你的帳號"
|
msgstr "你的帳號"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:40
|
#: bookwyrm/templates/layout.html:41
|
||||||
msgid "Search for a book or user"
|
#, fuzzy
|
||||||
|
#| msgid "Search for a book or user"
|
||||||
|
msgid "Search for a book, user, or list"
|
||||||
msgstr "搜尋書目或使用者"
|
msgstr "搜尋書目或使用者"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:54 bookwyrm/templates/layout.html:55
|
#: bookwyrm/templates/layout.html:59 bookwyrm/templates/layout.html:60
|
||||||
msgid "Main navigation menu"
|
msgid "Main navigation menu"
|
||||||
msgstr "主導航選單"
|
msgstr "主導航選單"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:65
|
#: bookwyrm/templates/layout.html:70
|
||||||
msgid "Feed"
|
msgid "Feed"
|
||||||
msgstr "動態"
|
msgstr "動態"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:99
|
#: bookwyrm/templates/layout.html:104
|
||||||
msgid "Your Books"
|
msgid "Your Books"
|
||||||
msgstr "你的書目"
|
msgstr "你的書目"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:109
|
#: bookwyrm/templates/layout.html:114
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "設定"
|
msgstr "設定"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:118
|
#: bookwyrm/templates/layout.html:123
|
||||||
#: bookwyrm/templates/settings/layout.html:40
|
#: bookwyrm/templates/settings/layout.html:40
|
||||||
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
#: bookwyrm/templates/settings/manage_invite_requests.html:15
|
||||||
#: bookwyrm/templates/settings/manage_invites.html:3
|
#: bookwyrm/templates/settings/manage_invites.html:3
|
||||||
|
@ -1477,73 +1479,73 @@ msgstr "設定"
|
||||||
msgid "Invites"
|
msgid "Invites"
|
||||||
msgstr "邀請"
|
msgstr "邀請"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:125
|
#: bookwyrm/templates/layout.html:130
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "管理員"
|
msgstr "管理員"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:132
|
#: bookwyrm/templates/layout.html:137
|
||||||
msgid "Log out"
|
msgid "Log out"
|
||||||
msgstr "登出"
|
msgstr "登出"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:140 bookwyrm/templates/layout.html:141
|
#: bookwyrm/templates/layout.html:145 bookwyrm/templates/layout.html:146
|
||||||
#: bookwyrm/templates/notifications.html:6
|
#: bookwyrm/templates/notifications.html:6
|
||||||
#: bookwyrm/templates/notifications.html:11
|
#: bookwyrm/templates/notifications.html:11
|
||||||
msgid "Notifications"
|
msgid "Notifications"
|
||||||
msgstr "通知"
|
msgstr "通知"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:163 bookwyrm/templates/layout.html:167
|
#: bookwyrm/templates/layout.html:168 bookwyrm/templates/layout.html:172
|
||||||
#: bookwyrm/templates/login.html:21
|
#: bookwyrm/templates/login.html:21
|
||||||
#: bookwyrm/templates/snippets/register_form.html:4
|
#: bookwyrm/templates/snippets/register_form.html:4
|
||||||
msgid "Username:"
|
msgid "Username:"
|
||||||
msgstr "使用者名稱:"
|
msgstr "使用者名稱:"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:168
|
#: bookwyrm/templates/layout.html:173
|
||||||
msgid "password"
|
msgid "password"
|
||||||
msgstr "密碼"
|
msgstr "密碼"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:169 bookwyrm/templates/login.html:40
|
#: bookwyrm/templates/layout.html:174 bookwyrm/templates/login.html:40
|
||||||
msgid "Forgot your password?"
|
msgid "Forgot your password?"
|
||||||
msgstr "忘記了密碼?"
|
msgstr "忘記了密碼?"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:172 bookwyrm/templates/login.html:7
|
#: bookwyrm/templates/layout.html:177 bookwyrm/templates/login.html:7
|
||||||
#: bookwyrm/templates/login.html:37
|
#: bookwyrm/templates/login.html:37
|
||||||
msgid "Log in"
|
msgid "Log in"
|
||||||
msgstr "登入"
|
msgstr "登入"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:180
|
#: bookwyrm/templates/layout.html:185
|
||||||
msgid "Join"
|
msgid "Join"
|
||||||
msgstr "加入"
|
msgstr "加入"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:214
|
#: bookwyrm/templates/layout.html:219
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Successfully imported"
|
#| msgid "Successfully imported"
|
||||||
msgid "Successfully posted status"
|
msgid "Successfully posted status"
|
||||||
msgstr "成功匯入了"
|
msgstr "成功匯入了"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:215
|
#: bookwyrm/templates/layout.html:220
|
||||||
#, fuzzy
|
#, fuzzy
|
||||||
#| msgid "Boost status"
|
#| msgid "Boost status"
|
||||||
msgid "Error posting status"
|
msgid "Error posting status"
|
||||||
msgstr "轉發狀態"
|
msgstr "轉發狀態"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:223
|
#: bookwyrm/templates/layout.html:228
|
||||||
msgid "About this instance"
|
msgid "About this instance"
|
||||||
msgstr "關於本實例"
|
msgstr "關於本實例"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:227
|
#: bookwyrm/templates/layout.html:232
|
||||||
msgid "Contact site admin"
|
msgid "Contact site admin"
|
||||||
msgstr "聯絡網站管理員"
|
msgstr "聯絡網站管理員"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:231
|
#: bookwyrm/templates/layout.html:236
|
||||||
msgid "Documentation"
|
msgid "Documentation"
|
||||||
msgstr "文件:"
|
msgstr "文件:"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:238
|
#: bookwyrm/templates/layout.html:243
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
msgid "Support %(site_name)s on <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a>"
|
||||||
msgstr "在 <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> 上支援 %(site_name)s"
|
msgstr "在 <a href=\"%(support_link)s\" target=\"_blank\">%(support_title)s</a> 上支援 %(site_name)s"
|
||||||
|
|
||||||
#: bookwyrm/templates/layout.html:242
|
#: bookwyrm/templates/layout.html:247
|
||||||
msgid "BookWyrm's source code is freely available. You can contribute or report issues on <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a>."
|
msgid "BookWyrm's source code is freely available. 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> 貢獻或報告問題。"
|
msgstr "BookWyrm 是開源軟體。你可以在 <a href=\"https://github.com/mouse-reeve/bookwyrm\">GitHub</a> 貢獻或報告問題。"
|
||||||
|
|
||||||
|
@ -2820,19 +2822,19 @@ msgid "Progress:"
|
||||||
msgstr "進度:"
|
msgstr "進度:"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
#: bookwyrm/templates/snippets/create_status/comment.html:52
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:30
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
#: bookwyrm/templates/snippets/readthrough_form.html:22
|
||||||
msgid "pages"
|
msgid "pages"
|
||||||
msgstr "頁數"
|
msgstr "頁數"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
#: bookwyrm/templates/snippets/create_status/comment.html:58
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:31
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:32
|
||||||
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
#: bookwyrm/templates/snippets/readthrough_form.html:23
|
||||||
msgid "percent"
|
msgid "percent"
|
||||||
msgstr "百分比"
|
msgstr "百分比"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
#: bookwyrm/templates/snippets/create_status/comment.html:65
|
||||||
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:36
|
#: bookwyrm/templates/snippets/reading_modals/progress_update_modal.html:37
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "of %(pages)s pages"
|
msgid "of %(pages)s pages"
|
||||||
msgstr "全書 %(pages)s 頁"
|
msgstr "全書 %(pages)s 頁"
|
||||||
|
@ -2862,7 +2864,7 @@ msgstr "前有劇透!"
|
||||||
msgid "Include spoiler alert"
|
msgid "Include spoiler alert"
|
||||||
msgstr "加入劇透警告"
|
msgstr "加入劇透警告"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/create_status/layout.html:35
|
#: bookwyrm/templates/snippets/create_status/layout.html:41
|
||||||
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
#: bookwyrm/templates/snippets/reading_modals/form.html:7
|
||||||
msgid "Comment:"
|
msgid "Comment:"
|
||||||
msgstr "評論:"
|
msgstr "評論:"
|
||||||
|
@ -3195,32 +3197,40 @@ msgstr "從 %(name)s 移除"
|
||||||
msgid "Finish reading"
|
msgid "Finish reading"
|
||||||
msgstr "完成閱讀"
|
msgstr "完成閱讀"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:73
|
#: bookwyrm/templates/snippets/status/content_status.html:72
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
#, fuzzy
|
||||||
msgid "Show more"
|
#| msgid "Content"
|
||||||
msgstr "顯示更多"
|
msgid "Content warning"
|
||||||
|
msgstr "內容"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:88
|
#: bookwyrm/templates/snippets/status/content_status.html:79
|
||||||
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
#, fuzzy
|
||||||
msgid "Show less"
|
#| msgid "Like status"
|
||||||
msgstr "顯示更少"
|
msgid "Show status"
|
||||||
|
msgstr "喜歡狀態"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:103
|
#: bookwyrm/templates/snippets/status/content_status.html:101
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "page %(page)s"
|
#| msgid "page %(page)s"
|
||||||
msgid "(Page %(page)s)"
|
msgid "(Page %(page)s)"
|
||||||
msgstr "第 %(page)s 頁"
|
msgstr "第 %(page)s 頁"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:105
|
#: bookwyrm/templates/snippets/status/content_status.html:103
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "%(percent)s%% complete!"
|
#| msgid "%(percent)s%% complete!"
|
||||||
msgid "(%(percent)s%%)"
|
msgid "(%(percent)s%%)"
|
||||||
msgstr "完成了 %(percent)s%% !"
|
msgstr "完成了 %(percent)s%% !"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/content_status.html:127
|
#: bookwyrm/templates/snippets/status/content_status.html:125
|
||||||
msgid "Open image in new window"
|
msgid "Open image in new window"
|
||||||
msgstr "在新視窗中開啟圖片"
|
msgstr "在新視窗中開啟圖片"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/status/content_status.html:144
|
||||||
|
#, fuzzy
|
||||||
|
#| msgid "Like status"
|
||||||
|
msgid "Hide status"
|
||||||
|
msgstr "喜歡狀態"
|
||||||
|
|
||||||
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
#: bookwyrm/templates/snippets/status/headers/comment.html:2
|
||||||
#, fuzzy, python-format
|
#, fuzzy, python-format
|
||||||
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
#| msgid "Editions of <a href=\"%(work_path)s\">\"%(work_title)s\"</a>"
|
||||||
|
@ -3333,6 +3343,14 @@ msgstr "升序排序"
|
||||||
msgid "Sorted descending"
|
msgid "Sorted descending"
|
||||||
msgstr "降序排序"
|
msgstr "降序排序"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:17
|
||||||
|
msgid "Show more"
|
||||||
|
msgstr "顯示更多"
|
||||||
|
|
||||||
|
#: bookwyrm/templates/snippets/trimmed_text.html:34
|
||||||
|
msgid "Show less"
|
||||||
|
msgstr "顯示更少"
|
||||||
|
|
||||||
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
#: bookwyrm/templates/user/layout.html:18 bookwyrm/templates/user/user.html:10
|
||||||
msgid "User Profile"
|
msgid "User Profile"
|
||||||
msgstr "使用者使用者資料"
|
msgstr "使用者使用者資料"
|
||||||
|
|
Loading…
Reference in a new issue