Merge branch 'main' into production

This commit is contained in:
Mouse Reeve 2021-08-07 08:34:05 -07:00
commit c105490178
31 changed files with 1185 additions and 191 deletions

View file

@ -36,6 +36,7 @@ jobs:
env: env:
SECRET_KEY: beepbeep SECRET_KEY: beepbeep
DEBUG: false DEBUG: false
USE_HTTPS: true
DOMAIN: your.domain.here DOMAIN: your.domain.here
BOOKWYRM_DATABASE_BACKEND: postgres BOOKWYRM_DATABASE_BACKEND: postgres
MEDIA_ROOT: images/ MEDIA_ROOT: images/

View file

@ -23,6 +23,14 @@ def email_data():
} }
def email_confirmation_email(user):
"""newly registered users confirm email address"""
data = email_data()
data["confirmation_code"] = user.confirmation_code
data["confirmation_link"] = user.confirmation_link
send_email.delay(user.email, *format_email("confirm", data))
def invite_email(invite_request): def invite_email(invite_request):
"""send out an invite code""" """send out an invite code"""
data = email_data() data = email_data()

View file

@ -0,0 +1,56 @@
# Generated by Django 3.2.4 on 2021-08-06 23:24
import bookwyrm.models.base_model
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0081_alter_user_last_active_date"),
]
operations = [
migrations.AddField(
model_name="sitesettings",
name="require_confirm_email",
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name="user",
name="confirmation_code",
field=models.CharField(
default=bookwyrm.models.base_model.new_access_code, max_length=32
),
),
migrations.AlterField(
model_name="connector",
name="deactivation_reason",
field=models.CharField(
blank=True,
choices=[
("pending", "Pending"),
("self_deletion", "Self Deletion"),
("moderator_deletion", "Moderator Deletion"),
("domain_block", "Domain Block"),
],
max_length=255,
null=True,
),
),
migrations.AlterField(
model_name="user",
name="deactivation_reason",
field=models.CharField(
blank=True,
choices=[
("pending", "Pending"),
("self_deletion", "Self Deletion"),
("moderator_deletion", "Moderator Deletion"),
("domain_block", "Domain Block"),
],
max_length=255,
null=True,
),
),
]

View file

@ -1,4 +1,6 @@
""" base model with default fields """ """ base model with default fields """
import base64
from Crypto import Random
from django.db import models from django.db import models
from django.dispatch import receiver from django.dispatch import receiver
@ -9,6 +11,7 @@ from .fields import RemoteIdField
DeactivationReason = models.TextChoices( DeactivationReason = models.TextChoices(
"DeactivationReason", "DeactivationReason",
[ [
"pending",
"self_deletion", "self_deletion",
"moderator_deletion", "moderator_deletion",
"domain_block", "domain_block",
@ -16,6 +19,11 @@ DeactivationReason = models.TextChoices(
) )
def new_access_code():
"""the identifier for a user invite"""
return base64.b32encode(Random.get_random_bytes(5)).decode("ascii")
class BookWyrmModel(models.Model): class BookWyrmModel(models.Model):
"""shared fields""" """shared fields"""

View file

@ -1,8 +1,6 @@
""" the particulars for this instance of BookWyrm """ """ the particulars for this instance of BookWyrm """
import base64
import datetime import datetime
from Crypto import Random
from django.db import models, IntegrityError from django.db import models, IntegrityError
from django.dispatch import receiver from django.dispatch import receiver
from django.utils import timezone from django.utils import timezone
@ -10,7 +8,7 @@ from model_utils import FieldTracker
from bookwyrm.preview_images import generate_site_preview_image_task from bookwyrm.preview_images import generate_site_preview_image_task
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES
from .base_model import BookWyrmModel from .base_model import BookWyrmModel, new_access_code
from .user import User from .user import User
@ -33,6 +31,7 @@ class SiteSettings(models.Model):
# registration # registration
allow_registration = models.BooleanField(default=True) allow_registration = models.BooleanField(default=True)
allow_invite_requests = models.BooleanField(default=True) allow_invite_requests = models.BooleanField(default=True)
require_confirm_email = models.BooleanField(default=True)
# images # images
logo = models.ImageField(upload_to="logos/", null=True, blank=True) logo = models.ImageField(upload_to="logos/", null=True, blank=True)
@ -61,11 +60,6 @@ class SiteSettings(models.Model):
return default_settings return default_settings
def new_access_code():
"""the identifier for a user invite"""
return base64.b32encode(Random.get_random_bytes(5)).decode("ascii")
class SiteInvite(models.Model): class SiteInvite(models.Model):
"""gives someone access to create an account on the instance""" """gives someone access to create an account on the instance"""

View file

@ -17,16 +17,22 @@ from bookwyrm.connectors import get_data, ConnectorException
from bookwyrm.models.shelf import Shelf from bookwyrm.models.shelf import Shelf
from bookwyrm.models.status import Status, Review from bookwyrm.models.status import Status, Review
from bookwyrm.preview_images import generate_user_preview_image_task from bookwyrm.preview_images import generate_user_preview_image_task
from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, USE_HTTPS
from bookwyrm.signatures import create_key_pair from bookwyrm.signatures import create_key_pair
from bookwyrm.tasks import app from bookwyrm.tasks import app
from bookwyrm.utils import regex from bookwyrm.utils import regex
from .activitypub_mixin import OrderedCollectionPageMixin, ActivitypubMixin from .activitypub_mixin import OrderedCollectionPageMixin, ActivitypubMixin
from .base_model import BookWyrmModel, DeactivationReason from .base_model import BookWyrmModel, DeactivationReason, new_access_code
from .federated_server import FederatedServer from .federated_server import FederatedServer
from . import fields, Review from . import fields, Review
def site_link():
"""helper for generating links to the site"""
protocol = "https" if USE_HTTPS else "http"
return f"{protocol}://{DOMAIN}"
class User(OrderedCollectionPageMixin, AbstractUser): class User(OrderedCollectionPageMixin, AbstractUser):
"""a user who wants to read books""" """a user who wants to read books"""
@ -123,11 +129,18 @@ class User(OrderedCollectionPageMixin, AbstractUser):
deactivation_reason = models.CharField( deactivation_reason = models.CharField(
max_length=255, choices=DeactivationReason.choices, null=True, blank=True max_length=255, choices=DeactivationReason.choices, null=True, blank=True
) )
confirmation_code = models.CharField(max_length=32, default=new_access_code)
name_field = "username" name_field = "username"
property_fields = [("following_link", "following")] property_fields = [("following_link", "following")]
field_tracker = FieldTracker(fields=["name", "avatar"]) field_tracker = FieldTracker(fields=["name", "avatar"])
@property
def confirmation_link(self):
"""helper for generating confirmation links"""
link = site_link()
return f"{link}/confirm-email/{self.confirmation_code}"
@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"""
@ -207,7 +220,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
self.following.order_by("-updated_date").all(), self.following.order_by("-updated_date").all(),
remote_id=remote_id, remote_id=remote_id,
id_only=True, id_only=True,
**kwargs **kwargs,
) )
def to_followers_activity(self, **kwargs): def to_followers_activity(self, **kwargs):
@ -217,7 +230,7 @@ class User(OrderedCollectionPageMixin, AbstractUser):
self.followers.order_by("-updated_date").all(), self.followers.order_by("-updated_date").all(),
remote_id=remote_id, remote_id=remote_id,
id_only=True, id_only=True,
**kwargs **kwargs,
) )
def to_activity(self, **kwargs): def to_activity(self, **kwargs):
@ -259,9 +272,9 @@ class User(OrderedCollectionPageMixin, AbstractUser):
return return
# populate fields for local users # populate fields for local users
self.remote_id = "https://%s/user/%s" % (DOMAIN, self.localname) self.remote_id = "%s/user/%s" % (site_link(), self.localname)
self.inbox = "%s/inbox" % self.remote_id self.inbox = "%s/inbox" % self.remote_id
self.shared_inbox = "https://%s/inbox" % DOMAIN self.shared_inbox = "%s/inbox" % site_link()
self.outbox = "%s/outbox" % self.remote_id self.outbox = "%s/outbox" % self.remote_id
# an id needs to be set before we can proceed with related models # an id needs to be set before we can proceed with related models

View file

@ -0,0 +1,44 @@
{% extends "layout.html" %}
{% load i18n %}
{% block title %}{% trans "Confirm email" %}{% endblock %}
{% block content %}
<h1 class="title">{% trans "Confirm your email address" %}</h1>
<div class="columns">
<div class="column">
<div class="block content">
<section class="block">
<p>{% trans "A confirmation code has been sent to the email address you used to register your account." %}</p>
{% if not valid %}
<p class="notification is-warning">{% trans "Sorry! We couldn't find that code." %}</p>
{% endif %}
<form name="confirm" method="post" action="{% url 'confirm-email' %}">
{% csrf_token %}
<label class="label" for="confirmation_code">{% trans "Confirmation code:" %}</label>
<div class="field has-addons">
<div class="control">
<input class="input" type="text" name="code" id="confirmation_code" required>
</div>
<div class="control">
<button class="button is-link" type="submit">{% trans "Submit" %}</button>
</div>
</div>
</form>
</section>
<section class="block">
{% trans "Can't find your code?" as button_text %}
{% include "snippets/toggle/open_button.html" with text=button_text controls_text="resend-form" focus="resend-form-header" %}
{% include "confirm_email/resend_form.html" with controls_text="resend-form" %}
</section>
</div>
</div>
<div class="column">
<div class="box">
{% include 'snippets/about.html' %}
</div>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends "components/inline_form.html" %}
{% load i18n %}
{% block header %}
{% trans "Resend confirmation link" %}
{% endblock %}
{% block form %}
<form name="resend" method="post" action="{% url 'resend-link' %}">
{% csrf_token %}
<div class="field">
<label class="label" for="email">{% trans "Email address:" %}</label>
<div class="control">
<input type="text" name="email" class="input" required id="email">
</div>
</div>
<div class="control">
<button class="button is-link">{% trans "Resend link" %}</button>
</div>
</form>
{% endblock %}

View file

@ -0,0 +1,20 @@
{% extends 'email/html_layout.html' %}
{% load i18n %}
{% block content %}
<p>
{% blocktrans trimmed %}
One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below:
{% endblocktrans %}
</p>
{% trans "Confirm Email" as text %}
{% include 'email/snippets/action.html' with path=confirmation_link text=text %}
<p>
{% blocktrans trimmed %}
Or enter the code "<code>{{ confirmation_code }}</code>" at login.
{% endblocktrans %}
</p>
{% endblock %}

View file

@ -0,0 +1,4 @@
{% load i18n %}
{% blocktrans trimmed %}
Please confirm your email
{% endblocktrans %}

View file

@ -0,0 +1,14 @@
{% extends 'email/text_layout.html' %}
{% load i18n %}
{% block content %}
{% blocktrans trimmed %}
One last step before you join {{ site_name }}! Please confirm your email address by clicking the link below:
{% endblocktrans %}
{{ confirmation_link }}
{% blocktrans trimmed %}
Or enter the code "{{ confirmation_code }}" at login.
{% endblocktrans %}
{% endblock %}

View file

@ -11,8 +11,13 @@
{% if login_form.non_field_errors %} {% if login_form.non_field_errors %}
<p class="notification is-danger">{{ login_form.non_field_errors }}</p> <p class="notification is-danger">{{ login_form.non_field_errors }}</p>
{% endif %} {% endif %}
{% if show_confirmed_email %}
<p class="notification is-success">{% trans "Success! Email address confirmed." %}</p>
{% endif %}
<form name="login" method="post" action="/login"> <form name="login" method="post" action="/login">
{% csrf_token %} {% csrf_token %}
{% if show_confirmed_email %}<input type="hidden" name="first_login" value="true">{% endif %}
<div class="field"> <div class="field">
<label class="label" for="id_localname">{% trans "Username:" %}</label> <label class="label" for="id_localname">{% trans "Username:" %}</label>
<div class="control"> <div class="control">

View file

@ -91,6 +91,13 @@
{% trans "Allow invite requests" %} {% trans "Allow invite requests" %}
</label> </label>
</div> </div>
<div class="field">
<label class="label mb-0" for="id_allow_invite_requests">
{{ site_form.require_confirm_email }}
{% trans "Require users to confirm email address" %}
</label>
<p class="help">{% trans "(Recommended if registration is open)" %}</p>
</div>
<div class="field"> <div class="field">
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label> <label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
{{ site_form.registration_closed_text }} {{ site_form.registration_closed_text }}

View file

@ -12,7 +12,7 @@
<div class="field"> <div class="field">
<label class="label" for="id_email_register">{% trans "Email address:" %}</label> <label class="label" for="id_email_register">{% trans "Email address:" %}</label>
<div class="control"> <div class="control">
<input type="email" name="email" maxlength="254" class="input" id="id_email_register" value="{% if register_form.email.value %}{{ register_form.email.value }}{% endif %}"> <input type="email" name="email" maxlength="254" class="input" id="id_email_register" value="{% if register_form.email.value %}{{ register_form.email.value }}{% endif %}" required>
{% for error in register_form.email.errors %} {% for error in register_form.email.errors %}
<p class="help is-danger">{{ error | escape }}</p> <p class="help is-danger">{{ error | escape }}</p>
{% endfor %} {% endfor %}

View file

@ -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=book) user, models.Review.objects.filter(book__in=book.parent_work.editions.all())
) )
return queryset.aggregate(Avg("rating"))["rating__avg"] return queryset.aggregate(Avg("rating"))["rating__avg"]

View file

@ -175,3 +175,10 @@ class TemplateTags(TestCase):
result = bookwyrm_tags.related_status(notification) result = bookwyrm_tags.related_status(notification)
self.assertIsInstance(result, models.Status) self.assertIsInstance(result, models.Status)
def test_get_next_shelf(self, *_):
"""self progress helper"""
self.assertEqual(bookwyrm_tags.get_next_shelf("to-read"), "reading")
self.assertEqual(bookwyrm_tags.get_next_shelf("reading"), "read")
self.assertEqual(bookwyrm_tags.get_next_shelf("read"), "read")
self.assertEqual(bookwyrm_tags.get_next_shelf("blooooga"), "to-read")

View file

@ -8,7 +8,7 @@ from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from bookwyrm import models, views from bookwyrm import forms, models, views
from bookwyrm.settings import DOMAIN from bookwyrm.settings import DOMAIN
@ -22,7 +22,7 @@ class AuthenticationViews(TestCase):
self.factory = RequestFactory() self.factory = RequestFactory()
with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"): with patch("bookwyrm.suggested_users.rerank_suggestions_task.delay"):
self.local_user = models.User.objects.create_user( self.local_user = models.User.objects.create_user(
"mouse@local.com", "mouse@your.domain.here",
"mouse@mouse.com", "mouse@mouse.com",
"password", "password",
local=True, local=True,
@ -31,7 +31,9 @@ class AuthenticationViews(TestCase):
self.anonymous_user = AnonymousUser self.anonymous_user = AnonymousUser
self.anonymous_user.is_authenticated = False self.anonymous_user.is_authenticated = False
self.settings = models.SiteSettings.objects.create(id=1) self.settings = models.SiteSettings.objects.create(
id=1, require_confirm_email=False
)
def test_login_get(self, _): def test_login_get(self, _):
"""there are so many views, this just makes sure it LOADS""" """there are so many views, this just makes sure it LOADS"""
@ -49,6 +51,66 @@ class AuthenticationViews(TestCase):
self.assertEqual(result.url, "/") self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
def test_login_post_localname(self, _):
"""there are so many views, this just makes sure it LOADS"""
view = views.Login.as_view()
form = forms.LoginForm()
form.data["localname"] = "mouse@mouse.com"
form.data["password"] = "password"
request = self.factory.post("", form.data)
request.user = self.anonymous_user
with patch("bookwyrm.views.authentication.login"):
result = view(request)
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)
def test_login_post_username(self, _):
"""there are so many views, this just makes sure it LOADS"""
view = views.Login.as_view()
form = forms.LoginForm()
form.data["localname"] = "mouse@your.domain.here"
form.data["password"] = "password"
request = self.factory.post("", form.data)
request.user = self.anonymous_user
with patch("bookwyrm.views.authentication.login"):
result = view(request)
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)
def test_login_post_email(self, _):
"""there are so many views, this just makes sure it LOADS"""
view = views.Login.as_view()
form = forms.LoginForm()
form.data["localname"] = "mouse"
form.data["password"] = "password"
request = self.factory.post("", form.data)
request.user = self.anonymous_user
with patch("bookwyrm.views.authentication.login"):
result = view(request)
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)
def test_login_post_invalid_credentials(self, _):
"""there are so many views, this just makes sure it LOADS"""
view = views.Login.as_view()
form = forms.LoginForm()
form.data["localname"] = "mouse"
form.data["password"] = "passsword1"
request = self.factory.post("", form.data)
request.user = self.anonymous_user
with patch("bookwyrm.views.authentication.login"):
result = view(request)
result.render()
self.assertEqual(result.status_code, 200)
self.assertEqual(
result.context_data["login_form"].non_field_errors,
"Username or password are incorrect",
)
def test_register(self, _): def test_register(self, _):
"""create a user""" """create a user"""
view = views.Register.as_view() view = views.Register.as_view()
@ -70,6 +132,33 @@ class AuthenticationViews(TestCase):
self.assertEqual(nutria.localname, "nutria-user.user_nutria") self.assertEqual(nutria.localname, "nutria-user.user_nutria")
self.assertEqual(nutria.local, True) self.assertEqual(nutria.local, True)
@patch("bookwyrm.emailing.send_email.delay")
def test_register_email_confirm(self, *_):
"""create a user"""
self.settings.require_confirm_email = True
self.settings.save()
view = views.Register.as_view()
self.assertEqual(models.User.objects.count(), 1)
request = self.factory.post(
"register/",
{
"localname": "nutria",
"password": "mouseword",
"email": "aa@bb.cccc",
},
)
with patch("bookwyrm.views.authentication.login"):
response = view(request)
self.assertEqual(response.status_code, 302)
nutria = models.User.objects.get(localname="nutria")
self.assertEqual(nutria.username, "nutria@%s" % DOMAIN)
self.assertEqual(nutria.local, True)
self.assertFalse(nutria.is_active)
self.assertEqual(nutria.deactivation_reason, "pending")
self.assertIsNotNone(nutria.confirmation_code)
def test_register_trailing_space(self, _): def test_register_trailing_space(self, _):
"""django handles this so weirdly""" """django handles this so weirdly"""
view = views.Register.as_view() view = views.Register.as_view()
@ -189,3 +278,74 @@ class AuthenticationViews(TestCase):
with self.assertRaises(Http404): with self.assertRaises(Http404):
response = view(request) response = view(request)
self.assertEqual(models.User.objects.count(), 2) self.assertEqual(models.User.objects.count(), 2)
def test_confirm_email_code_get(self, _):
"""there are so many views, this just makes sure it LOADS"""
self.settings.require_confirm_email = True
self.settings.save()
self.local_user.is_active = False
self.local_user.deactivation_reason = "pending"
self.local_user.confirmation_code = "12345"
self.local_user.save(
broadcast=False,
update_fields=["is_active", "deactivation_reason", "confirmation_code"],
)
view = views.ConfirmEmailCode.as_view()
request = self.factory.get("")
request.user = self.anonymous_user
result = view(request, "12345")
self.assertEqual(result.url, "/login/confirmed")
self.assertEqual(result.status_code, 302)
self.local_user.refresh_from_db()
self.assertTrue(self.local_user.is_active)
self.assertIsNone(self.local_user.deactivation_reason)
request.user = self.local_user
result = view(request, "12345")
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)
def test_confirm_email_code_get_invalid_code(self, _):
"""there are so many views, this just makes sure it LOADS"""
self.settings.require_confirm_email = True
self.settings.save()
self.local_user.is_active = False
self.local_user.deactivation_reason = "pending"
self.local_user.confirmation_code = "12345"
self.local_user.save(
broadcast=False,
update_fields=["is_active", "deactivation_reason", "confirmation_code"],
)
view = views.ConfirmEmailCode.as_view()
request = self.factory.get("")
request.user = self.anonymous_user
result = view(request, "abcde")
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
self.assertFalse(self.local_user.is_active)
self.assertEqual(self.local_user.deactivation_reason, "pending")
def test_confirm_email_get(self, _):
"""there are so many views, this just makes sure it LOADS"""
self.settings.require_confirm_email = True
self.settings.save()
login = views.ConfirmEmail.as_view()
request = self.factory.get("")
request.user = self.anonymous_user
result = login(request)
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
request.user = self.local_user
result = login(request)
self.assertEqual(result.url, "/")
self.assertEqual(result.status_code, 302)

View file

@ -12,6 +12,7 @@ from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from django.utils import timezone
from bookwyrm import forms, models, views from bookwyrm import forms, models, views
from bookwyrm.activitypub import ActivitypubResponse from bookwyrm.activitypub import ActivitypubResponse
@ -52,6 +53,11 @@ class BookViews(TestCase):
def test_book_page(self): def test_book_page(self):
"""there are so many views, this just makes sure it LOADS""" """there are so many views, this just makes sure it LOADS"""
view = views.Book.as_view() view = views.Book.as_view()
models.ReadThrough.objects.create(
user=self.local_user,
book=self.book,
start_date=timezone.now(),
)
request = self.factory.get("") request = self.factory.get("")
request.user = self.local_user request.user = self.local_user
with patch("bookwyrm.views.books.is_api_request") as is_api: with patch("bookwyrm.views.books.is_api_request") as is_api:
@ -67,6 +73,79 @@ class BookViews(TestCase):
self.assertIsInstance(result, ActivitypubResponse) self.assertIsInstance(result, ActivitypubResponse)
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
@patch("bookwyrm.models.activitypub_mixin.broadcast_task.delay")
@patch("bookwyrm.activitystreams.ActivityStream.add_status")
def test_book_page_statuses(self, *_):
"""there are so many views, this just makes sure it LOADS"""
view = views.Book.as_view()
review = models.Review.objects.create(
user=self.local_user,
book=self.book,
content="hi",
)
comment = models.Comment.objects.create(
user=self.local_user,
book=self.book,
content="hi",
)
quote = models.Quotation.objects.create(
user=self.local_user,
book=self.book,
content="hi",
quote="wow",
)
request = self.factory.get("")
request.user = self.local_user
with patch("bookwyrm.views.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.book.id, user_statuses="review")
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
self.assertEqual(result.context_data["statuses"].object_list[0], review)
with patch("bookwyrm.views.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.book.id, user_statuses="comment")
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
self.assertEqual(result.context_data["statuses"].object_list[0], comment)
with patch("bookwyrm.views.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.book.id, user_statuses="quotation")
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
self.assertEqual(result.context_data["statuses"].object_list[0], quote)
def test_book_page_invalid_id(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.Book.as_view()
request = self.factory.get("")
request.user = self.local_user
with patch("bookwyrm.views.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, 0)
self.assertEqual(result.status_code, 404)
def test_book_page_work_id(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.Book.as_view()
request = self.factory.get("")
request.user = self.local_user
with patch("bookwyrm.views.books.is_api_request") as is_api:
is_api.return_value = False
result = view(request, self.work.id)
result.render()
self.assertEqual(result.status_code, 200)
self.assertEqual(result.context_data["book"], self.book)
def test_edit_book_page(self): def test_edit_book_page(self):
"""there are so many views, this just makes sure it LOADS""" """there are so many views, this just makes sure it LOADS"""
view = views.EditBook.as_view() view = views.EditBook.as_view()

View file

@ -1,11 +1,12 @@
""" test for app action functionality """ """ test for app action functionality """
import pathlib
from unittest.mock import patch from unittest.mock import patch
from django.core.files.uploadedfile import SimpleUploadedFile
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.test import TestCase from django.test import TestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
from bookwyrm import models from bookwyrm import forms, models, views
from bookwyrm import views
class ImportViews(TestCase): class ImportViews(TestCase):
@ -47,6 +48,27 @@ class ImportViews(TestCase):
result.render() result.render()
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
def test_start_import(self):
"""retry failed items"""
view = views.Import.as_view()
form = forms.ImportForm()
form.data["source"] = "LibraryThing"
form.data["privacy"] = "public"
form.data["include_reviews"] = False
csv_file = pathlib.Path(__file__).parent.joinpath("../data/goodreads.csv")
form.data["csv_file"] = SimpleUploadedFile(
csv_file, open(csv_file, "rb").read(), content_type="text/csv"
)
request = self.factory.post("", form.data)
request.user = self.local_user
with patch("bookwyrm.importers.Importer.start_import"):
view(request)
job = models.ImportJob.objects.get()
self.assertFalse(job.include_reviews)
self.assertEqual(job.privacy, "public")
def test_retry_import(self): def test_retry_import(self):
"""retry failed items""" """retry failed items"""
view = views.ImportStatus.as_view() view = views.ImportStatus.as_view()

View file

@ -52,6 +52,26 @@ class InviteViews(TestCase):
result.render() result.render()
self.assertEqual(result.status_code, 200) self.assertEqual(result.status_code, 200)
def test_manage_invites_post(self):
"""there are so many views, this just makes sure it LOADS"""
view = views.ManageInvites.as_view()
form = forms.CreateInviteForm()
form.data["use_limit"] = 3
form.data["expiry"] = ""
request = self.factory.post("", form.data)
request.user = self.local_user
request.user.is_superuser = True
result = view(request)
self.assertIsInstance(result, TemplateResponse)
result.render()
self.assertEqual(result.status_code, 200)
invite = models.SiteInvite.objects.get()
self.assertEqual(invite.use_limit, 3)
self.assertIsNone(invite.expiry)
def test_invite_request(self): def test_invite_request(self):
"""request to join a server""" """request to join a server"""
form = forms.InviteRequestForm() form = forms.InviteRequestForm()

View file

@ -46,7 +46,15 @@ urlpatterns = [
re_path("^api/updates/stream/(?P<stream>[a-z]+)/?$", views.get_unread_status_count), re_path("^api/updates/stream/(?P<stream>[a-z]+)/?$", views.get_unread_status_count),
# authentication # authentication
re_path(r"^login/?$", views.Login.as_view(), name="login"), re_path(r"^login/?$", views.Login.as_view(), name="login"),
re_path(r"^login/(?P<confirmed>confirmed)?$", views.Login.as_view(), name="login"),
re_path(r"^register/?$", views.Register.as_view()), re_path(r"^register/?$", views.Register.as_view()),
re_path(r"confirm-email/?$", views.ConfirmEmail.as_view(), name="confirm-email"),
re_path(
r"confirm-email/(?P<code>[A-Za-z0-9]+)/?$",
views.ConfirmEmailCode.as_view(),
name="confirm-email-code",
),
re_path(r"resend-link", views.resend_link, name="resend-link"),
re_path(r"^logout/?$", views.Logout.as_view(), name="logout"), re_path(r"^logout/?$", views.Logout.as_view(), name="logout"),
re_path( re_path(
r"^password-reset/?$", r"^password-reset/?$",

View file

@ -1,6 +1,7 @@
""" make sure all our nice views are available """ """ make sure all our nice views are available """
from .announcements import Announcements, Announcement, delete_announcement from .announcements import Announcements, Announcement, delete_announcement
from .authentication import Login, Register, Logout from .authentication import Login, Register, Logout
from .authentication import ConfirmEmail, ConfirmEmailCode, resend_link
from .author import Author, EditAuthor from .author import Author, EditAuthor
from .block import Block, unblock from .block import Block, unblock
from .books import Book, EditBook, ConfirmEditBook, Editions from .books import Book, EditBook, ConfirmEditBook, Editions

View file

@ -6,24 +6,27 @@ from django.shortcuts import get_object_or_404, redirect
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils import timezone from django.utils import timezone
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
from django.views import View from django.views import View
from bookwyrm import forms, models from bookwyrm import emailing, forms, models
from bookwyrm.settings import DOMAIN from bookwyrm.settings import DOMAIN
# pylint: disable= no-self-use # pylint: disable=no-self-use
@method_decorator(csrf_exempt, name="dispatch") @method_decorator(csrf_exempt, name="dispatch")
class Login(View): class Login(View):
"""authenticate an existing user""" """authenticate an existing user"""
def get(self, request): def get(self, request, confirmed=None):
"""login page""" """login page"""
if request.user.is_authenticated: if request.user.is_authenticated:
return redirect("/") return redirect("/")
# sene user to the login page # send user to the login page
data = { data = {
"show_confirmed_email": confirmed,
"login_form": forms.LoginForm(), "login_form": forms.LoginForm(),
"register_form": forms.RegisterForm(), "register_form": forms.RegisterForm(),
} }
@ -37,35 +40,55 @@ class Login(View):
localname = login_form.data["localname"] localname = login_form.data["localname"]
if "@" in localname: # looks like an email address to me if "@" in localname: # looks like an email address to me
email = localname
try: try:
username = models.User.objects.get(email=email) username = models.User.objects.get(email=localname).username
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 = "%s@%s" % (localname, DOMAIN)
password = login_form.data["password"] password = login_form.data["password"]
# perform authentication
user = authenticate(request, username=username, password=password) user = authenticate(request, username=username, password=password)
if user is not None: if user is not None:
# successful login # successful login
login(request, user) login(request, user)
user.last_active_date = timezone.now() user.last_active_date = timezone.now()
user.save(broadcast=False, update_fields=["last_active_date"]) user.save(broadcast=False, update_fields=["last_active_date"])
if request.POST.get("first_login"):
return redirect("get-started-profile")
return redirect(request.GET.get("next", "/")) return redirect(request.GET.get("next", "/"))
# maybe the user is pending email confirmation
if models.User.objects.filter(
username=username, is_active=False, deactivation_reason="pending"
).exists():
return redirect("confirm-email")
# login errors # login errors
login_form.non_field_errors = "Username or password are incorrect" login_form.non_field_errors = _("Username or password are incorrect")
register_form = forms.RegisterForm() register_form = forms.RegisterForm()
data = {"login_form": login_form, "register_form": register_form} data = {"login_form": login_form, "register_form": register_form}
return TemplateResponse(request, "login.html", data) return TemplateResponse(request, "login.html", data)
@method_decorator(login_required, name="dispatch")
class Logout(View):
"""log out"""
def get(self, request):
"""done with this place! outa here!"""
logout(request)
return redirect("/")
class Register(View): class Register(View):
"""register a user""" """register a user"""
def post(self, request): def post(self, request):
"""join the server""" """join the server"""
if not models.SiteSettings.get().allow_registration: settings = models.SiteSettings.get()
if not settings.allow_registration:
invite_code = request.POST.get("invite_code") invite_code = request.POST.get("invite_code")
if not invite_code: if not invite_code:
@ -104,22 +127,76 @@ class Register(View):
username = "%s@%s" % (localname, DOMAIN) username = "%s@%s" % (localname, DOMAIN)
user = models.User.objects.create_user( user = models.User.objects.create_user(
username, email, password, localname=localname, local=True username,
email,
password,
localname=localname,
local=True,
deactivation_reason="pending" if settings.require_confirm_email else None,
is_active=not settings.require_confirm_email,
) )
if invite: if invite:
invite.times_used += 1 invite.times_used += 1
invite.invitees.add(user) invite.invitees.add(user)
invite.save() invite.save()
if settings.require_confirm_email:
emailing.email_confirmation_email(user)
return redirect("confirm-email")
login(request, user) login(request, user)
return redirect("get-started-profile") return redirect("get-started-profile")
@method_decorator(login_required, name="dispatch") class ConfirmEmailCode(View):
class Logout(View): """confirm email address"""
"""log out"""
def get(self, request): def get(self, request, code): # pylint: disable=unused-argument
"""done with this place! outa here!""" """you got the code! good work"""
logout(request) settings = models.SiteSettings.get()
return redirect("/") if request.user.is_authenticated or not settings.require_confirm_email:
return redirect("/")
# look up the user associated with this code
try:
user = models.User.objects.get(confirmation_code=code)
except models.User.DoesNotExist:
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": False}
)
# update the user
user.is_active = True
user.deactivation_reason = None
user.save(broadcast=False, update_fields=["is_active", "deactivation_reason"])
# direct the user to log in
return redirect("login", confirmed="confirmed")
class ConfirmEmail(View):
"""enter code to confirm email address"""
def get(self, request): # pylint: disable=unused-argument
"""you need a code! keep looking"""
settings = models.SiteSettings.get()
if request.user.is_authenticated or not settings.require_confirm_email:
return redirect("/")
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": True}
)
def post(self, request):
"""same as clicking the link"""
code = request.POST.get("code")
return ConfirmEmailCode().get(request, code)
@require_POST
def resend_link(request):
"""resend confirmation link"""
email = request.POST.get("email")
user = get_object_or_404(models.User, email=email)
emailing.email_confirmation_email(user)
return TemplateResponse(
request, "confirm_email/confirm_email.html", {"valid": True}
)

View file

@ -65,6 +65,13 @@ class Book(View):
queryset = queryset.select_related("user") queryset = queryset.select_related("user")
paginated = Paginator(queryset, PAGE_LENGTH) paginated = Paginator(queryset, PAGE_LENGTH)
lists = privacy_filter(
request.user,
models.List.objects.filter(
listitem__approved=True,
listitem__book__in=book.parent_work.editions.all(),
),
)
data = { data = {
"book": book, "book": book,
"statuses": paginated.get_page(request.GET.get("page")), "statuses": paginated.get_page(request.GET.get("page")),
@ -75,9 +82,7 @@ class Book(View):
if not user_statuses if not user_statuses
else None, else None,
"rating": reviews.aggregate(Avg("rating"))["rating__avg"], "rating": reviews.aggregate(Avg("rating"))["rating__avg"],
"lists": privacy_filter( "lists": lists,
request.user, book.list_set.filter(listitem__approved=True)
),
} }
if request.user.is_authenticated: if request.user.is_authenticated:

View file

@ -46,4 +46,6 @@ def email_preview(request):
data["text_content_path"] = "email/{}/text_content.html".format(template) data["text_content_path"] = "email/{}/text_content.html".format(template)
data["reset_link"] = "https://example.com/link" data["reset_link"] = "https://example.com/link"
data["invite_link"] = "https://example.com/link" data["invite_link"] = "https://example.com/link"
data["confirmation_link"] = "https://example.com/link"
data["confirmation_code"] = "AKJHKDGKJSDFG"
return TemplateResponse(request, "email/preview.html", data) return TemplateResponse(request, "email/preview.html", data)

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+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"
@ -306,7 +306,7 @@ msgstr ""
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -739,6 +739,58 @@ msgstr "Schließen"
msgid "Compose status" msgid "Compose status"
msgstr "Status teilen" msgstr "Status teilen"
#: bookwyrm/templates/confirm_email/confirm_email.html:4
#, fuzzy
#| msgid "Confirm"
msgid "Confirm email"
msgstr "Bestätigen"
#: bookwyrm/templates/confirm_email/confirm_email.html:7
#, fuzzy
#| msgid "Email address:"
msgid "Confirm your email address"
msgstr "E-Mail Adresse"
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
#, fuzzy
#| msgid "Confirm password:"
msgid "Confirmation code:"
msgstr "Passwort bestätigen:"
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Absenden"
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "E-Mail Adresse"
#: bookwyrm/templates/confirm_email/resend_form.html:17
msgid "Resend link"
msgstr ""
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
#, fuzzy #, fuzzy
#| msgid "Comment" #| msgid "Comment"
@ -882,7 +934,7 @@ msgid "Join %(name)s"
msgstr "Tritt %(name)s bei" msgstr "Tritt %(name)s bei"
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "Diese Instanz ist geschlossen" msgstr "Diese Instanz ist geschlossen"
@ -894,22 +946,26 @@ msgstr ""
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "" msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "E-Mail Adresse"
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Absenden"
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "Dein Account" msgstr "Dein Account"
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
#, fuzzy
#| msgid "Confirm"
msgid "Confirm Email"
msgstr "Bestätigen"
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1342,7 +1398,7 @@ msgid "Imported"
msgstr "Importiert" msgstr "Importiert"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "Erstelle einen Account" msgstr "Erstelle einen Account"
@ -1412,7 +1468,7 @@ msgid "Notifications"
msgstr "Benachrichtigungen" msgstr "Benachrichtigungen"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4 #: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:" msgid "Username:"
msgstr "" msgstr ""
@ -1421,12 +1477,12 @@ msgstr ""
msgid "password" msgid "password"
msgstr "Passwort" msgstr "Passwort"
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "Passwort vergessen?" msgstr "Passwort vergessen?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "Anmelden" msgstr "Anmelden"
@ -1619,16 +1675,20 @@ msgstr "Deine Listen"
msgid "Login" msgid "Login"
msgstr "" msgstr ""
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "Passwort:" msgstr "Passwort:"
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "Kontaktiere für eine Einladung eine*n Admin" msgstr "Kontaktiere für eine Einladung eine*n Admin"
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "Mehr über diese Seite" msgstr "Mehr über diese Seite"
@ -2554,7 +2614,15 @@ msgstr "Registrierungen erlauben"
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "Folgeanfragen" msgstr "Folgeanfragen"
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "Registrierungen geschlossen text" msgstr "Registrierungen geschlossen text"
@ -3295,6 +3363,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr ""
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
#, fuzzy #, fuzzy
#| msgid "Email address:" #| msgid "Email address:"
@ -3371,11 +3443,6 @@ msgstr ""
#~ msgid "Enter a valid integer." #~ msgid "Enter a valid integer."
#~ msgstr "E-Mail Adresse" #~ msgstr "E-Mail Adresse"
#, fuzzy
#~| msgid "Email address:"
#~ msgid "Enter a valid email address."
#~ msgstr "E-Mail Adresse"
#, fuzzy #, fuzzy
#~| msgid "Email address:" #~| msgid "Email address:"
#~ msgid "Enter a valid IPv4 address." #~ msgid "Enter a valid IPv4 address."

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+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"
@ -282,7 +282,7 @@ msgstr ""
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -680,6 +680,52 @@ msgstr ""
msgid "Compose status" msgid "Compose status"
msgstr "" msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:4
msgid "Confirm email"
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:7
msgid "Confirm your email address"
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
msgid "Confirmation code:"
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:17
msgid "Resend link"
msgstr ""
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
msgid "Community" msgid "Community"
msgstr "" msgstr ""
@ -806,7 +852,7 @@ msgid "Join %(name)s"
msgstr "" msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "" msgstr ""
@ -818,22 +864,24 @@ msgstr ""
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "" msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr ""
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "" msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
msgid "Confirm Email"
msgstr ""
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1235,7 +1283,7 @@ msgid "Imported"
msgstr "" msgstr ""
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "" msgstr ""
@ -1303,7 +1351,7 @@ msgid "Notifications"
msgstr "" msgstr ""
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4 #: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:" msgid "Username:"
msgstr "" msgstr ""
@ -1312,12 +1360,12 @@ msgstr ""
msgid "password" msgid "password"
msgstr "" msgstr ""
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "" msgstr ""
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "" msgstr ""
@ -1493,16 +1541,20 @@ msgstr ""
msgid "Login" msgid "Login"
msgstr "" msgstr ""
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "" msgstr ""
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "" msgstr ""
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "" msgstr ""
@ -2315,7 +2367,15 @@ msgstr ""
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "" msgstr ""
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "" msgstr ""
@ -2991,6 +3051,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr ""
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "" msgstr ""

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+0000\n"
"PO-Revision-Date: 2021-03-19 11:49+0800\n" "PO-Revision-Date: 2021-03-19 11:49+0800\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -288,7 +288,7 @@ msgstr "Clave Goodreads:"
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -688,6 +688,60 @@ msgstr "Cerrar"
msgid "Compose status" msgid "Compose status"
msgstr "Componer status" msgstr "Componer status"
#: bookwyrm/templates/confirm_email/confirm_email.html:4
#, fuzzy
#| msgid "Confirm"
msgid "Confirm email"
msgstr "Confirmar"
#: bookwyrm/templates/confirm_email/confirm_email.html:7
#, fuzzy
#| msgid "Enter a valid email address."
msgid "Confirm your email address"
msgstr "Ingrese una dirección de correo electrónico válida."
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
#, fuzzy
#| msgid "Confirm password:"
msgid "Confirmation code:"
msgstr "Confirmar contraseña:"
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Enviar"
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "Dirección de correo electrónico:"
#: bookwyrm/templates/confirm_email/resend_form.html:17
#, fuzzy
#| msgid "Re-send invite"
msgid "Resend link"
msgstr "Re-enviar invitación"
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
msgid "Community" msgid "Community"
msgstr "Comunidad" msgstr "Comunidad"
@ -816,7 +870,7 @@ msgid "Join %(name)s"
msgstr "Unirse con %(name)s" msgstr "Unirse con %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "Esta instancia está cerrada." msgstr "Esta instancia está cerrada."
@ -828,22 +882,26 @@ msgstr "¡Gracias! Tu solicitud ha sido recibido."
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "Solicitar una invitación" msgstr "Solicitar una invitación"
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "Dirección de correo electrónico:"
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Enviar"
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "Tu cuenta" msgstr "Tu cuenta"
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
#, fuzzy
#| msgid "Confirm"
msgid "Confirm Email"
msgstr "Confirmar"
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1250,7 +1308,7 @@ msgid "Imported"
msgstr "Importado" msgstr "Importado"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "Crear una cuenta" msgstr "Crear una cuenta"
@ -1318,7 +1376,7 @@ msgid "Notifications"
msgstr "Notificaciones" msgstr "Notificaciones"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: 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:"
@ -1327,12 +1385,12 @@ msgstr "Nombre de usuario:"
msgid "password" msgid "password"
msgstr "contraseña" msgstr "contraseña"
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "¿Olvidaste tu contraseña?" msgstr "¿Olvidaste tu contraseña?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "Iniciar sesión" msgstr "Iniciar sesión"
@ -1510,16 +1568,20 @@ msgstr "Tus listas"
msgid "Login" msgid "Login"
msgstr "Iniciar sesión" msgstr "Iniciar sesión"
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "Contraseña:" msgstr "Contraseña:"
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "Contactar a unx administradorx para recibir una invitación" msgstr "Contactar a unx administradorx para recibir una invitación"
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "Más sobre este sitio" msgstr "Más sobre este sitio"
@ -2351,7 +2413,15 @@ msgstr "Permitir registración:"
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "Permitir solicitudes de invitación:" msgstr "Permitir solicitudes de invitación:"
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "Texto de registración cerrada:" msgstr "Texto de registración cerrada:"
@ -3036,6 +3106,10 @@ msgstr ""
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr ""
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "No un archivo csv válido" msgstr "No un archivo csv válido"
@ -3113,9 +3187,6 @@ msgstr "Un enlace para reestablecer tu contraseña se enviará a %s"
#~ msgid "Enter a valid integer." #~ msgid "Enter a valid integer."
#~ msgstr "Ingrese un entero válido." #~ msgstr "Ingrese un entero válido."
#~ msgid "Enter a valid email address."
#~ msgstr "Ingrese una dirección de correo electrónico válida."
#~ msgid "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens." #~ msgid "Enter a valid “slug” consisting of letters, numbers, underscores or hyphens."
#~ msgstr "Ingrese un “slug” válido que consiste de letras, numeros, guiones bajos, o guiones" #~ msgstr "Ingrese un “slug” válido que consiste de letras, numeros, guiones bajos, o guiones"

View file

@ -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-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+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"
@ -286,7 +286,7 @@ msgstr "Clé Goodreads:"
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -684,6 +684,60 @@ msgstr "Fermer"
msgid "Compose status" msgid "Compose status"
msgstr "Rédiger un statut" msgstr "Rédiger un statut"
#: bookwyrm/templates/confirm_email/confirm_email.html:4
#, fuzzy
#| msgid "Confirm"
msgid "Confirm email"
msgstr "Confirmer"
#: bookwyrm/templates/confirm_email/confirm_email.html:7
#, fuzzy
#| msgid "Email address:"
msgid "Confirm your email address"
msgstr "Adresse email:"
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
#, fuzzy
#| msgid "Confirm password:"
msgid "Confirmation code:"
msgstr "Confirmez le mot de passe:"
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Valider"
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "Adresse email:"
#: bookwyrm/templates/confirm_email/resend_form.html:17
#, fuzzy
#| msgid "Re-send invite"
msgid "Resend link"
msgstr "Envoyer linvitation de nouveau"
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
msgid "Community" msgid "Community"
msgstr "Communauté" msgstr "Communauté"
@ -812,7 +866,7 @@ msgid "Join %(name)s"
msgstr "Rejoignez %(name)s" msgstr "Rejoignez %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "Cette instance est fermée" msgstr "Cette instance est fermée"
@ -824,22 +878,26 @@ msgstr "Merci! Votre demande a bien été reçue."
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "Demander une invitation" msgstr "Demander une invitation"
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "Adresse email:"
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "Valider"
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "Votre compte" msgstr "Votre compte"
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
#, fuzzy
#| msgid "Confirm"
msgid "Confirm Email"
msgstr "Confirmer"
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1246,7 +1304,7 @@ msgid "Imported"
msgstr "Importé" msgstr "Importé"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "Créer un compte" msgstr "Créer un compte"
@ -1314,7 +1372,7 @@ msgid "Notifications"
msgstr "Notifications" msgstr "Notifications"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: 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:"
@ -1323,12 +1381,12 @@ msgstr "Nom du compte:"
msgid "password" msgid "password"
msgstr "Mot de passe" msgstr "Mot de passe"
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "Mot de passe oublié?" msgstr "Mot de passe oublié?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "Se connecter" msgstr "Se connecter"
@ -1504,16 +1562,20 @@ msgstr "Vos listes"
msgid "Login" msgid "Login"
msgstr "Connexion" msgstr "Connexion"
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "Mot de passe:" msgstr "Mot de passe:"
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "Contacter un administrateur pour obtenir une invitation" msgstr "Contacter un administrateur pour obtenir une invitation"
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "En savoir plus sur ce site" msgstr "En savoir plus sur ce site"
@ -2333,7 +2395,15 @@ msgstr "Autoriser les inscriptions"
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "Autoriser les demandes dinvitation" msgstr "Autoriser les demandes dinvitation"
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "Texte affiché lorsque les inscriptions sont closes:" msgstr "Texte affiché lorsque les inscriptions sont closes:"
@ -3015,6 +3085,10 @@ msgstr "Ce fichier dépasse la taille limite: 10Mo"
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "%(title)s (%(subtitle)s)" msgstr "%(title)s (%(subtitle)s)"
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "Fichier CSV non valide" msgstr "Fichier CSV non valide"
@ -3062,11 +3136,6 @@ msgstr "Un lien de réinitialisation a été envoyé à %s."
#~ msgid "Enter a valid integer." #~ msgid "Enter a valid integer."
#~ msgstr "Adresse email:" #~ msgstr "Adresse email:"
#, fuzzy
#~| msgid "Email address:"
#~ msgid "Enter a valid email address."
#~ msgstr "Adresse email:"
#, fuzzy #, fuzzy
#~| msgid "Email address:" #~| msgid "Email address:"
#~ msgid "Enter a valid IPv4 address." #~ msgid "Enter a valid IPv4 address."

View file

@ -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-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+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"
@ -284,7 +284,7 @@ msgstr "Goodreads key:"
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -681,6 +681,60 @@ msgstr "关闭"
msgid "Compose status" msgid "Compose status"
msgstr "撰写状态" msgstr "撰写状态"
#: bookwyrm/templates/confirm_email/confirm_email.html:4
#, fuzzy
#| msgid "Confirm"
msgid "Confirm email"
msgstr "确认"
#: bookwyrm/templates/confirm_email/confirm_email.html:7
#, fuzzy
#| msgid "Email address:"
msgid "Confirm your email address"
msgstr "邮箱地址:"
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
#, fuzzy
#| msgid "Confirm password:"
msgid "Confirmation code:"
msgstr "确认密码:"
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "提交"
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "邮箱地址:"
#: bookwyrm/templates/confirm_email/resend_form.html:17
#, fuzzy
#| msgid "Re-send invite"
msgid "Resend link"
msgstr "重新发送请求"
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
msgid "Community" msgid "Community"
msgstr "社区" msgstr "社区"
@ -807,7 +861,7 @@ msgid "Join %(name)s"
msgstr "加入 %(name)s" msgstr "加入 %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "本实例不开放。" msgstr "本实例不开放。"
@ -819,22 +873,26 @@ msgstr "谢谢你!我们已经收到了你的请求。"
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "请求邀请" msgstr "请求邀请"
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "邮箱地址:"
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "提交"
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "你的帐号" msgstr "你的帐号"
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
#, fuzzy
#| msgid "Confirm"
msgid "Confirm Email"
msgstr "确认"
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1237,7 +1295,7 @@ msgid "Imported"
msgstr "已导入" msgstr "已导入"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "创建帐号" msgstr "创建帐号"
@ -1305,7 +1363,7 @@ msgid "Notifications"
msgstr "通知" msgstr "通知"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4 #: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:" msgid "Username:"
msgstr "用户名:" msgstr "用户名:"
@ -1314,12 +1372,12 @@ msgstr "用户名:"
msgid "password" msgid "password"
msgstr "密码" msgstr "密码"
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "忘记了密码?" msgstr "忘记了密码?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "登录" msgstr "登录"
@ -1495,16 +1553,20 @@ msgstr "你的列表"
msgid "Login" msgid "Login"
msgstr "登录" msgstr "登录"
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "密码:" msgstr "密码:"
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "联系管理员以取得邀请" msgstr "联系管理员以取得邀请"
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "更多关于本站点的信息" msgstr "更多关于本站点的信息"
@ -2319,7 +2381,15 @@ msgstr "允许注册"
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "允许请求邀请" msgstr "允许请求邀请"
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "注册关闭文字:" msgstr "注册关闭文字:"
@ -2992,6 +3062,10 @@ msgstr "文件超过了最大大小: 10MB"
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "%(title)s%(subtitle)s" msgstr "%(title)s%(subtitle)s"
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "不是有效的 csv 文件" msgstr "不是有效的 csv 文件"

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: 0.0.1\n" "Project-Id-Version: 0.0.1\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-08-05 01:33+0000\n" "POT-Creation-Date: 2021-08-07 01:35+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"
@ -288,7 +288,7 @@ msgstr "Goodreads key:"
#: bookwyrm/templates/settings/announcement_form.html:69 #: bookwyrm/templates/settings/announcement_form.html:69
#: bookwyrm/templates/settings/edit_server.html:68 #: bookwyrm/templates/settings/edit_server.html:68
#: bookwyrm/templates/settings/federated_server.html:98 #: bookwyrm/templates/settings/federated_server.html:98
#: bookwyrm/templates/settings/site.html:101 #: bookwyrm/templates/settings/site.html:108
#: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/finish_reading_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42 #: bookwyrm/templates/snippets/shelve_button/progress_update_modal.html:42
#: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36 #: bookwyrm/templates/snippets/shelve_button/start_reading_modal.html:36
@ -687,6 +687,60 @@ msgstr "關閉"
msgid "Compose status" msgid "Compose status"
msgstr "撰寫狀態" msgstr "撰寫狀態"
#: bookwyrm/templates/confirm_email/confirm_email.html:4
#, fuzzy
#| msgid "Confirm"
msgid "Confirm email"
msgstr "確認"
#: bookwyrm/templates/confirm_email/confirm_email.html:7
#, fuzzy
#| msgid "Email address:"
msgid "Confirm your email address"
msgstr "郵箱地址:"
#: bookwyrm/templates/confirm_email/confirm_email.html:13
msgid "A confirmation code has been sent to the email address you used to register your account."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:15
msgid "Sorry! We couldn't find that code."
msgstr ""
#: bookwyrm/templates/confirm_email/confirm_email.html:19
#, fuzzy
#| msgid "Confirm password:"
msgid "Confirmation code:"
msgstr "確認密碼:"
#: bookwyrm/templates/confirm_email/confirm_email.html:25
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "提交"
#: bookwyrm/templates/confirm_email/confirm_email.html:32
msgid "Can't find your code?"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:4
msgid "Resend confirmation link"
msgstr ""
#: bookwyrm/templates/confirm_email/resend_form.html:11
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "郵箱地址:"
#: bookwyrm/templates/confirm_email/resend_form.html:17
#, fuzzy
#| msgid "Re-send invite"
msgid "Resend link"
msgstr "重新發送請求"
#: bookwyrm/templates/directory/community_filter.html:5 #: bookwyrm/templates/directory/community_filter.html:5
msgid "Community" msgid "Community"
msgstr "社群" msgstr "社群"
@ -813,7 +867,7 @@ msgid "Join %(name)s"
msgstr "加入 %(name)s" msgstr "加入 %(name)s"
#: bookwyrm/templates/discover/landing_layout.html:51 #: bookwyrm/templates/discover/landing_layout.html:51
#: bookwyrm/templates/login.html:51 #: bookwyrm/templates/login.html:56
msgid "This instance is closed" msgid "This instance is closed"
msgstr "本實例不開放。" msgstr "本實例不開放。"
@ -825,22 +879,26 @@ msgstr "謝謝你!我們已經受到了你的請求。"
msgid "Request an Invitation" msgid "Request an Invitation"
msgstr "請求邀請" msgstr "請求邀請"
#: bookwyrm/templates/discover/landing_layout.html:64
#: bookwyrm/templates/password_reset_request.html:18
#: bookwyrm/templates/preferences/edit_user.html:38
#: bookwyrm/templates/snippets/register_form.html:13
msgid "Email address:"
msgstr "郵箱地址:"
#: bookwyrm/templates/discover/landing_layout.html:70
#: bookwyrm/templates/moderation/report_modal.html:33
msgid "Submit"
msgstr "提交"
#: bookwyrm/templates/discover/landing_layout.html:79 #: bookwyrm/templates/discover/landing_layout.html:79
msgid "Your Account" msgid "Your Account"
msgstr "你的帳號" msgstr "你的帳號"
#: bookwyrm/templates/email/confirm/html_content.html:6
#: bookwyrm/templates/email/confirm/text_content.html:4
#, python-format
msgid "One last step before you join %(site_name)s! Please confirm your email address by clicking the link below:"
msgstr ""
#: bookwyrm/templates/email/confirm/html_content.html:11
#, fuzzy
#| msgid "Confirm"
msgid "Confirm Email"
msgstr "確認"
#: bookwyrm/templates/email/confirm/subject.html:2
msgid "Please confirm your email"
msgstr ""
#: bookwyrm/templates/email/html_layout.html:15 #: bookwyrm/templates/email/html_layout.html:15
#: bookwyrm/templates/email/text_layout.html:2 #: bookwyrm/templates/email/text_layout.html:2
msgid "Hi there," msgid "Hi there,"
@ -1247,7 +1305,7 @@ msgid "Imported"
msgstr "已匯入" msgstr "已匯入"
#: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12 #: bookwyrm/templates/invite.html:4 bookwyrm/templates/invite.html:12
#: bookwyrm/templates/login.html:46 #: bookwyrm/templates/login.html:51
msgid "Create an Account" msgid "Create an Account"
msgstr "建立帳號" msgstr "建立帳號"
@ -1315,7 +1373,7 @@ msgid "Notifications"
msgstr "通知" msgstr "通知"
#: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162 #: bookwyrm/templates/layout.html:158 bookwyrm/templates/layout.html:162
#: bookwyrm/templates/login.html:17 #: bookwyrm/templates/login.html:22
#: bookwyrm/templates/snippets/register_form.html:4 #: bookwyrm/templates/snippets/register_form.html:4
msgid "Username:" msgid "Username:"
msgstr "使用者名稱:" msgstr "使用者名稱:"
@ -1324,12 +1382,12 @@ msgstr "使用者名稱:"
msgid "password" msgid "password"
msgstr "密碼" msgstr "密碼"
#: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:36 #: bookwyrm/templates/layout.html:164 bookwyrm/templates/login.html:41
msgid "Forgot your password?" msgid "Forgot your password?"
msgstr "忘記了密碼?" msgstr "忘記了密碼?"
#: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10 #: bookwyrm/templates/layout.html:167 bookwyrm/templates/login.html:10
#: bookwyrm/templates/login.html:33 #: bookwyrm/templates/login.html:38
msgid "Log in" msgid "Log in"
msgstr "登入" msgstr "登入"
@ -1505,16 +1563,20 @@ msgstr "你的列表"
msgid "Login" msgid "Login"
msgstr "登入" msgstr "登入"
#: bookwyrm/templates/login.html:23 bookwyrm/templates/password_reset.html:17 #: bookwyrm/templates/login.html:16
msgid "Success! Email address confirmed."
msgstr ""
#: bookwyrm/templates/login.html:28 bookwyrm/templates/password_reset.html:17
#: bookwyrm/templates/snippets/register_form.html:22 #: bookwyrm/templates/snippets/register_form.html:22
msgid "Password:" msgid "Password:"
msgstr "密碼:" msgstr "密碼:"
#: bookwyrm/templates/login.html:52 #: bookwyrm/templates/login.html:57
msgid "Contact an administrator to get an invite" msgid "Contact an administrator to get an invite"
msgstr "聯絡管理員以取得邀請" msgstr "聯絡管理員以取得邀請"
#: bookwyrm/templates/login.html:63 #: bookwyrm/templates/login.html:68
msgid "More about this site" msgid "More about this site"
msgstr "關於本網站的更多" msgstr "關於本網站的更多"
@ -2338,7 +2400,15 @@ msgstr "允許註冊:"
msgid "Allow invite requests" msgid "Allow invite requests"
msgstr "允許請求邀請:" msgstr "允許請求邀請:"
#: bookwyrm/templates/settings/site.html:95 #: bookwyrm/templates/settings/site.html:97
msgid "Require users to confirm email address"
msgstr ""
#: bookwyrm/templates/settings/site.html:99
msgid "(Recommended if registration is open)"
msgstr ""
#: bookwyrm/templates/settings/site.html:102
msgid "Registration closed text:" msgid "Registration closed text:"
msgstr "註冊關閉文字:" msgstr "註冊關閉文字:"
@ -3011,6 +3081,10 @@ msgstr "檔案超過了最大大小: 10MB"
msgid "%(title)s: %(subtitle)s" msgid "%(title)s: %(subtitle)s"
msgstr "" msgstr ""
#: bookwyrm/views/authentication.py:69
msgid "Username or password are incorrect"
msgstr ""
#: bookwyrm/views/import_data.py:67 #: bookwyrm/views/import_data.py:67
msgid "Not a valid csv file" msgid "Not a valid csv file"
msgstr "不是有效的 csv 檔案" msgstr "不是有效的 csv 檔案"