Merge branch 'main' into bookwyrm-groups

This commit is contained in:
Mouse Reeve 2021-10-07 17:27:11 -07:00 committed by GitHub
commit 4ba3234f6c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 95872 additions and 4016 deletions

View file

@ -144,6 +144,7 @@ class EditUserForm(CustomForm):
"default_post_privacy", "default_post_privacy",
"discoverable", "discoverable",
"preferred_timezone", "preferred_timezone",
"preferred_language",
] ]
help_texts = {f: None for f in fields} help_texts = {f: None for f in fields}

View file

@ -0,0 +1,30 @@
# Generated by Django 3.2.5 on 2021-10-06 19:17
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("bookwyrm", "0105_alter_connector_connector_file"),
]
operations = [
migrations.AddField(
model_name="user",
name="preferred_language",
field=models.CharField(
blank=True,
choices=[
("en-us", "English"),
("de-de", "German"),
("es", "Spanish"),
("fr-fr", "French"),
("zh-hans", "Simplified Chinese"),
("zh-hant", "Traditional Chinese"),
],
max_length=255,
null=True,
),
),
]

View file

@ -17,7 +17,7 @@ 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, USE_HTTPS from bookwyrm.settings import DOMAIN, ENABLE_PREVIEW_IMAGES, USE_HTTPS, LANGUAGES
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
@ -133,6 +133,12 @@ class User(OrderedCollectionPageMixin, AbstractUser):
default=str(pytz.utc), default=str(pytz.utc),
max_length=255, max_length=255,
) )
preferred_language = models.CharField(
choices=LANGUAGES,
null=True,
blank=True,
max_length=255,
)
deactivation_reason = models.CharField( deactivation_reason = models.CharField(
max_length=255, choices=DeactivationReason, null=True, blank=True max_length=255, choices=DeactivationReason, null=True, blank=True
) )

View file

@ -30,6 +30,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
LOCALE_PATHS = [ LOCALE_PATHS = [
os.path.join(BASE_DIR, "locale"), os.path.join(BASE_DIR, "locale"),
] ]
LANGUAGE_COOKIE_NAME = env.str("LANGUAGE_COOKIE_NAME", "django_language")
DEFAULT_AUTO_FIELD = "django.db.models.AutoField" DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
@ -161,11 +162,11 @@ AUTH_PASSWORD_VALIDATORS = [
LANGUAGE_CODE = "en-us" LANGUAGE_CODE = "en-us"
LANGUAGES = [ LANGUAGES = [
("en-us", _("English")), ("en-us", _("English")),
("de-de", _("German")), ("de-de", _("Deutsch (German)")), # German
("es", _("Spanish")), ("es", _("Español (Spanish)")), # Spanish
("fr-fr", _("French")), ("fr-fr", _("Français (French)")), # French
("zh-hans", _("Simplified Chinese")), ("zh-hans", _("简体中文 (Simplified Chinese)")), # Simplified Chinese
("zh-hant", _("Traditional Chinese")), ("zh-hant", _("繁體中文 (Traditional Chinese)")), # Traditional Chinese
] ]

View file

@ -29,7 +29,7 @@
</label> </label>
<label class="field" data-hides="list_group_selector"> <label class="field" data-hides="list_group_selector">
<input type="radio" name="curation" value="open"{% if list.curation == 'open' %} checked{% endif %}> {% trans "Open" %} <input type="radio" name="curation" value="open"{% if list.curation == 'open' %} checked{% endif %}> {% trans "Open" context "curation type" %}
<p class="help mb-2">{% trans "Anyone can add books to this list" %}</p> <p class="help mb-2">{% trans "Anyone can add books to this list" %}</p>
</label> </label>

View file

@ -91,6 +91,12 @@
{{ form.preferred_timezone }} {{ form.preferred_timezone }}
</div> </div>
</div> </div>
<div class="field">
<label class="label" for="id_preferred_language">{% trans "Language:" %}</label>
<div class="select">
{{ form.preferred_language }}
</div>
</div>
</div> </div>
</section> </section>

View file

@ -7,8 +7,9 @@ from dateutil.parser import ParserError
from requests import HTTPError from requests import HTTPError
from django.http import Http404 from django.http import Http404
from django.utils import translation
from bookwyrm import activitypub, models from bookwyrm import activitypub, models, settings
from bookwyrm.connectors import ConnectorException, get_data from bookwyrm.connectors import ConnectorException, get_data
from bookwyrm.status import create_generated_note from bookwyrm.status import create_generated_note
from bookwyrm.utils import regex from bookwyrm.utils import regex
@ -144,3 +145,11 @@ def load_date_in_user_tz_as_utc(date_str: str, user: models.User) -> datetime:
return date.replace(tzinfo=user_tz).astimezone(dateutil.tz.UTC) return date.replace(tzinfo=user_tz).astimezone(dateutil.tz.UTC)
except ParserError: except ParserError:
return None return None
def set_language(user, response):
"""Updates a user's language"""
if user.preferred_language:
translation.activate(user.preferred_language)
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, user.preferred_language)
return response

View file

@ -11,6 +11,7 @@ from django.views.decorators.debug import sensitive_variables, sensitive_post_pa
from bookwyrm import forms, models from bookwyrm import forms, models
from bookwyrm.settings import DOMAIN from bookwyrm.settings import DOMAIN
from bookwyrm.views.helpers import set_language
# pylint: disable=no-self-use # pylint: disable=no-self-use
@ -55,8 +56,8 @@ class Login(View):
login(request, user) login(request, user)
user.update_active_date() user.update_active_date()
if request.POST.get("first_login"): if request.POST.get("first_login"):
return redirect("get-started-profile") return set_language(user, redirect("get-started-profile"))
return redirect(request.GET.get("next", "/")) return set_language(user, redirect(request.GET.get("next", "/")))
# maybe the user is pending email confirmation # maybe the user is pending email confirmation
if models.User.objects.filter( if models.User.objects.filter(

View file

@ -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": _(f"A password reset link sent to {email}")} data = {"message": _(f"A password reset link was sent to {email}")}
return TemplateResponse(request, "password_reset_request.html", data) return TemplateResponse(request, "password_reset_request.html", data)

View file

@ -11,6 +11,7 @@ from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from bookwyrm import forms from bookwyrm import forms
from bookwyrm.views.helpers import set_language
# pylint: disable=no-self-use # pylint: disable=no-self-use
@ -33,9 +34,9 @@ class EditUser(View):
data = {"form": form, "user": request.user} data = {"form": form, "user": request.user}
return TemplateResponse(request, "preferences/edit_user.html", data) return TemplateResponse(request, "preferences/edit_user.html", data)
save_user_form(form) user = save_user_form(form)
return redirect("user-feed", request.user.localname) return set_language(user, redirect("user-feed", request.user.localname))
def save_user_form(form): def save_user_form(form):

6
bw-dev
View file

@ -105,6 +105,9 @@ case "$CMD" in
collectstatic) collectstatic)
runweb python manage.py collectstatic --no-input runweb python manage.py collectstatic --no-input
;; ;;
add_locale)
runweb django-admin makemessages --no-wrap --ignore=venv -l $@
;;
makemessages) makemessages)
runweb django-admin makemessages --no-wrap --ignore=venv --all $@ runweb django-admin makemessages --no-wrap --ignore=venv --all $@
;; ;;
@ -167,7 +170,8 @@ case "$CMD" in
echo " test [path]" echo " test [path]"
echo " pytest [path]" echo " pytest [path]"
echo " collectstatic" echo " collectstatic"
echo " makemessages [locale]" echo " add_locale [locale]"
echo " makemessages"
echo " compilemessages [locale]" echo " compilemessages [locale]"
echo " build" echo " build"
echo " clean" echo " clean"

3
crowdin.yml Normal file
View file

@ -0,0 +1,3 @@
files:
- source: /locale/en_US/LC_MESSAGES/django.po
translation: /locale/%locale_with_underscore%/LC_MESSAGES/django.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff