You've already forked snikket-web-portal
Compare commits
112 Commits
feature/fi
...
beta.20210
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f02746f63 | ||
|
|
f2788aeb36 | ||
|
|
536a05b0eb | ||
|
|
e0226d47e3 | ||
|
|
0fe10a44ce | ||
|
|
e892d81815 | ||
|
|
c58ce8450f | ||
|
|
03573d1f05 | ||
|
|
486596f89f | ||
|
|
425b4d4295 | ||
|
|
87de808046 | ||
|
|
05455ac743 | ||
|
|
1e926714cb | ||
|
|
e1602f3140 | ||
|
|
2e89973263 | ||
|
|
a6f1361ddd | ||
|
|
552a3bbd41 | ||
|
|
3f2de1e5bf | ||
|
|
059a10f475 | ||
|
|
a48abacf1d | ||
|
|
ea7ed7c030 | ||
|
|
cca899bd8c | ||
|
|
359e6b4ce2 | ||
|
|
6650dd2046 | ||
|
|
97b4a7be0f | ||
|
|
329916e200 | ||
|
|
3571b8909b | ||
|
|
c6c01b82f5 | ||
|
|
c4b575f091 | ||
|
|
fdb55568ec | ||
|
|
a9a651be09 | ||
|
|
d2069289b0 | ||
|
|
552b5d2940 | ||
|
|
b0f9ae5d57 | ||
|
|
dd4a012612 | ||
|
|
e7aa0a2c45 | ||
|
|
ad229d6700 | ||
|
|
b822000f2e | ||
|
|
a6b67b3fdd | ||
|
|
885db355ab | ||
|
|
c3d5b06313 | ||
|
|
2dd8838852 | ||
|
|
5df2c3945a | ||
|
|
3eb8036ebd | ||
|
|
02ed390cd2 | ||
|
|
2506810b90 | ||
|
|
05d1b42dc4 | ||
|
|
5ef5b93eb9 | ||
|
|
0ff6e00e9d | ||
|
|
c04ac4bee0 | ||
|
|
3e19d42c2a | ||
|
|
03732ac06b | ||
|
|
c70228fed7 | ||
|
|
025172592f | ||
|
|
6de1e5313f | ||
|
|
3083c118a3 | ||
|
|
fa1b13fbdb | ||
|
|
ba30d728f4 | ||
|
|
af87301fa4 | ||
|
|
8ee0b0dd30 | ||
|
|
4a27ef9d72 | ||
|
|
9e9fdaf8d4 | ||
|
|
bdb186ca81 | ||
|
|
4ca9b82bce | ||
|
|
6dbe2c2d5e | ||
|
|
e410aedfef | ||
|
|
1713da61e7 | ||
|
|
53aac690df | ||
|
|
5e4009ca11 | ||
|
|
80860a3ac6 | ||
|
|
e9d479a78b | ||
|
|
aac56f49e9 | ||
|
|
52f0bee006 | ||
|
|
97c91b432d | ||
|
|
60647159f3 | ||
|
|
a21730f136 | ||
|
|
e35ab1b723 | ||
|
|
4de4509fc9 | ||
|
|
93e3b325b1 | ||
|
|
ceecfc861c | ||
|
|
2467e73781 | ||
|
|
2f34d39a09 | ||
|
|
de8589923b | ||
|
|
db3a1ac22f | ||
|
|
b48d130659 | ||
|
|
1aed573eb2 | ||
|
|
d4707196ec | ||
|
|
8a8d4c54bd | ||
|
|
ab534e3a59 | ||
|
|
4c128f1af2 | ||
|
|
8b551a8946 | ||
|
|
182d2301be | ||
|
|
6dba5e3a65 | ||
|
|
713da89445 | ||
|
|
9876e42fb7 | ||
|
|
8b66c5a063 | ||
|
|
ddf9f89d77 | ||
|
|
53e023f9ae | ||
|
|
e4d339627e | ||
|
|
cd3026911b | ||
|
|
d7da16f780 | ||
|
|
8ed0fbec25 | ||
|
|
5b812c773d | ||
|
|
fa61ee4e11 | ||
|
|
7402480c62 | ||
|
|
a68a469319 | ||
|
|
961f285fa5 | ||
|
|
7456295cb6 | ||
|
|
96f4b0d4f8 | ||
|
|
245434126e | ||
|
|
725dffc458 | ||
|
|
22783b837e |
41
Dockerfile
41
Dockerfile
@@ -1,46 +1,31 @@
|
||||
FROM debian:buster
|
||||
FROM debian:buster-slim
|
||||
|
||||
ARG BUILD_SERIES=dev
|
||||
ARG BUILD_ID=0
|
||||
|
||||
ENV DEBIAN_FRONTEND noninteractive
|
||||
COPY requirements.txt /opt/snikket-web-portal/requirements.txt
|
||||
COPY build-requirements.txt /opt/snikket-web-portal/build-requirements.txt
|
||||
COPY Makefile /opt/snikket-web-portal/Makefile
|
||||
COPY snikket_web/ /opt/snikket-web-portal/snikket_web
|
||||
COPY babel.cfg /opt/snikket-web-portal/babel.cfg
|
||||
|
||||
# This Dockerfile attempts to strike a balance between image size and time it
|
||||
# takes to do an incremental build on changes.
|
||||
# Improvements welcome.
|
||||
WORKDIR /opt/snikket-web-portal
|
||||
|
||||
RUN set -eu; \
|
||||
export DEBIAN_FRONTEND=noninteractive ; \
|
||||
apt-get update ; \
|
||||
apt-get install -y --no-install-recommends \
|
||||
python3 python3-pip python3-setuptools python3-wheel \
|
||||
libpython3-dev \
|
||||
make build-essential \
|
||||
netcat \
|
||||
; \
|
||||
apt-get clean ; rm -rf /var/lib/apt/lists
|
||||
|
||||
COPY requirements.txt /opt/snikket-web-portal/requirements.txt
|
||||
COPY build-requirements.txt /opt/snikket-web-portal/build-requirements.txt
|
||||
|
||||
WORKDIR /opt/snikket-web-portal
|
||||
|
||||
RUN set -eu; \
|
||||
pip3 install -r requirements.txt; \
|
||||
pip3 install -r build-requirements.txt; \
|
||||
rm -rf /root/.cache;
|
||||
|
||||
COPY Makefile /opt/snikket-web-portal/Makefile
|
||||
COPY snikket_web/ /opt/snikket-web-portal/snikket_web
|
||||
COPY babel.cfg /opt/snikket-web-portal/babel.cfg
|
||||
|
||||
# NOTE: abusing true(1) as a terrible way to disable a specific command. If
|
||||
# one merged all the RUN commands into one, one would want to run the
|
||||
# uninstall/remove commands there, but with the split up RUN commands it is
|
||||
# rather pointless.
|
||||
RUN set -eu; \
|
||||
make; \
|
||||
true pip3 uninstall -yr build-requirements.txt; \
|
||||
true apt-get remove -y build-essential make libpython3-dev; \
|
||||
true apt-get autoremove -y; \
|
||||
pip3 uninstall -yr build-requirements.txt; \
|
||||
apt-get remove -y build-essential make libpython3-dev; \
|
||||
apt-get autoremove -y; \
|
||||
pip3 install hypercorn; \
|
||||
rm -rf /root/.cache; \
|
||||
apt-get clean ; rm -rf /var/lib/apt/lists
|
||||
@@ -50,5 +35,7 @@ ENV SNIKKET_WEB_PYENV=/etc/snikket-web-portal/env.py
|
||||
|
||||
ENV SNIKKET_WEB_PROSODY_ENDPOINT=http://127.0.0.1:5280/
|
||||
|
||||
HEALTHCHECK CMD nc -zv ${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE:-127.0.0.1} ${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT:-5765}
|
||||
|
||||
ADD docker/entrypoint.sh /entrypoint.sh
|
||||
ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]
|
||||
|
||||
@@ -2,4 +2,7 @@
|
||||
|
||||
export SNIKKET_WEB_DOMAIN="$SNIKKET_DOMAIN"
|
||||
|
||||
exec hypercorn -b "127.0.0.1:5765" 'snikket_web:create_app()'
|
||||
export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE-127.0.0.1}"
|
||||
export SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT="${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT-5765}"
|
||||
|
||||
exec hypercorn -b "${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_INTERFACE}:${SNIKKET_TWEAK_PORTAL_INTERNAL_HTTP_PORT}" 'snikket_web:create_app()'
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 421 KiB |
@@ -1,5 +1,5 @@
|
||||
aiohttp~=3.6
|
||||
quart~=0.11
|
||||
quart~=0.15
|
||||
flask-wtf~=0.14
|
||||
hsluv~=0.0.2
|
||||
flask-babel~=1.0
|
||||
|
||||
@@ -17,6 +17,7 @@ from quart import (
|
||||
redirect,
|
||||
jsonify,
|
||||
)
|
||||
import werkzeug.exceptions
|
||||
|
||||
import environ
|
||||
|
||||
@@ -40,7 +41,7 @@ async def proc() -> typing.Dict[str, typing.Any]:
|
||||
|
||||
try:
|
||||
user_info = await infra.client.get_user_info()
|
||||
except (aiohttp.ClientError, quart.exceptions.HTTPException):
|
||||
except (aiohttp.ClientError, werkzeug.exceptions.HTTPException):
|
||||
user_info = {}
|
||||
|
||||
return {
|
||||
@@ -48,6 +49,7 @@ async def proc() -> typing.Dict[str, typing.Any]:
|
||||
"text_to_css": colour.text_to_css,
|
||||
"lang": infra.selected_locale(),
|
||||
"user_info": user_info,
|
||||
"is_in_debug_mode": current_app.debug,
|
||||
}
|
||||
|
||||
|
||||
@@ -104,16 +106,16 @@ async def backend_error_handler(exc: Exception) -> quart.Response:
|
||||
|
||||
|
||||
async def generic_http_error(
|
||||
exc: quart.exceptions.HTTPException,
|
||||
exc: werkzeug.exceptions.HTTPException,
|
||||
) -> quart.Response:
|
||||
return quart.Response(
|
||||
await render_template(
|
||||
"generic_http_error.html",
|
||||
status=exc.status_code,
|
||||
status=exc.code,
|
||||
description=exc.description,
|
||||
name=exc.name,
|
||||
),
|
||||
status=exc.status_code,
|
||||
status=exc.code,
|
||||
)
|
||||
|
||||
|
||||
@@ -144,13 +146,21 @@ class AppConfig:
|
||||
site_name = environ.var("")
|
||||
avatar_cache_ttl = environ.var(1800, converter=int)
|
||||
languages = environ.var([
|
||||
"da",
|
||||
"de",
|
||||
"en",
|
||||
"fr",
|
||||
"id",
|
||||
"po",
|
||||
"it",
|
||||
"pl",
|
||||
"sv",
|
||||
], converter=autosplit)
|
||||
apple_store_url = environ.var("")
|
||||
# Default limit of 1 MiB is what was discovered to be the effective limit
|
||||
# in #67, hence we set that here for now.
|
||||
# Future versions may change this default, and the standard deployment
|
||||
# tools may also very well override it.
|
||||
max_avatar_size = environ.var(1024*1024, converter=int)
|
||||
|
||||
|
||||
_UPPER_CASE = "".join(map(chr, range(ord("A"), ord("Z")+1)))
|
||||
@@ -181,29 +191,30 @@ def create_app() -> quart.Quart:
|
||||
app.config["SITE_NAME"] = config.site_name or config.domain
|
||||
app.config["AVATAR_CACHE_TTL"] = config.avatar_cache_ttl
|
||||
app.config["APPLE_STORE_URL"] = config.apple_store_url
|
||||
app.config["MAX_AVATAR_SIZE"] = config.max_avatar_size
|
||||
|
||||
app.context_processor(proc)
|
||||
app.register_error_handler(
|
||||
aiohttp.ClientConnectorError,
|
||||
backend_error_handler, # type:ignore
|
||||
backend_error_handler,
|
||||
)
|
||||
app.register_error_handler(
|
||||
quart.exceptions.HTTPException,
|
||||
generic_http_error, # type:ignore
|
||||
werkzeug.exceptions.HTTPException,
|
||||
generic_http_error,
|
||||
)
|
||||
app.register_error_handler(
|
||||
Exception,
|
||||
generic_error_handler, # type:ignore
|
||||
generic_error_handler,
|
||||
)
|
||||
|
||||
@app.route("/")
|
||||
@app.route("/") # type: ignore
|
||||
async def index() -> quart.Response:
|
||||
if infra.client.has_session:
|
||||
return redirect(url_for('user.index'))
|
||||
|
||||
return redirect(url_for('main.login'))
|
||||
|
||||
@app.route("/site.webmanifest")
|
||||
@app.route("/site.webmanifest") # type: ignore
|
||||
def site_manifest() -> quart.Response:
|
||||
# this is needed for icons
|
||||
return jsonify(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version_info = (0, 1, 0, "a0")
|
||||
version_info = (0, 1, 2, "a0")
|
||||
version = (
|
||||
".".join(map(str, version_info[:3])) +
|
||||
(f"-{version_info[3]}" if version_info[3] else "")
|
||||
|
||||
@@ -17,50 +17,133 @@ from quart import (
|
||||
url_for,
|
||||
request,
|
||||
abort,
|
||||
flash,
|
||||
)
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from . import prosodyclient
|
||||
from .infra import client, circle_name
|
||||
from .infra import client, circle_name, BaseForm
|
||||
|
||||
bp = Blueprint("admin", __name__, url_prefix="/admin")
|
||||
|
||||
|
||||
@bp.route("/")
|
||||
@bp.route("/") # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def index() -> str:
|
||||
return await render_template("admin_home.html")
|
||||
|
||||
|
||||
class PasswordResetLinkPost(flask_wtf.FlaskForm): # type: ignore
|
||||
action_create = wtforms.StringField()
|
||||
class PasswordResetLinkPost(BaseForm):
|
||||
action_revoke = wtforms.StringField()
|
||||
|
||||
|
||||
@bp.route("/users")
|
||||
@bp.route("/users") # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def users() -> str:
|
||||
users = sorted(
|
||||
await client.list_users(),
|
||||
key=lambda x: x.localpart
|
||||
)
|
||||
invite_form = InvitePost()
|
||||
await invite_form.init_choices()
|
||||
reset_form = PasswordResetLinkPost()
|
||||
return await render_template(
|
||||
"admin_users.html",
|
||||
users=users,
|
||||
reset_form=reset_form,
|
||||
invite_form=invite_form,
|
||||
)
|
||||
|
||||
|
||||
class DeleteUserForm(flask_wtf.FlaskForm): # type:ignore
|
||||
_LIMITED_ROLE_NAME = _("Limited")
|
||||
|
||||
|
||||
class EditUserForm(BaseForm):
|
||||
localpart = wtforms.StringField(
|
||||
_l("Login name"),
|
||||
)
|
||||
|
||||
display_name = wtforms.StringField(
|
||||
_l("Display name"),
|
||||
)
|
||||
|
||||
role = wtforms.RadioField(
|
||||
_l("Access Level"),
|
||||
choices=[
|
||||
# NOTE: enable this only after something has been done which
|
||||
# actually enforces the described restrictions :).
|
||||
# ("prosody:restricted", _LIMITED_ROLE_NAME),
|
||||
("prosody:normal", _l("Normal user")),
|
||||
("prosody:admin", _l("Administrator")),
|
||||
],
|
||||
)
|
||||
|
||||
action_save = wtforms.SubmitField(
|
||||
_l("Update user"),
|
||||
)
|
||||
|
||||
action_create_reset = wtforms.SubmitField(
|
||||
_l("Create password reset link"),
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/user/<localpart>/", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def edit_user(localpart: str) -> typing.Union[quart.Response, str]:
|
||||
target_user_info = await client.get_user_by_localpart(localpart)
|
||||
|
||||
form = EditUserForm()
|
||||
if form.validate_on_submit():
|
||||
if form.action_create_reset.data:
|
||||
target_user_info = await client.get_user_by_localpart(localpart)
|
||||
reset_link = await client.create_password_reset_invite(
|
||||
localpart=localpart,
|
||||
ttl=86400,
|
||||
)
|
||||
await flash(
|
||||
_("Password reset link created"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(
|
||||
".user_password_reset_link",
|
||||
id_=reset_link.id_,
|
||||
))
|
||||
|
||||
await client.update_user(
|
||||
localpart,
|
||||
display_name=form.display_name.data,
|
||||
roles=[form.role.data],
|
||||
)
|
||||
|
||||
await flash(
|
||||
_("User information updated."),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".edit_user", localpart=localpart))
|
||||
|
||||
elif request.method == "GET":
|
||||
form.localpart.data = target_user_info.localpart
|
||||
form.display_name.data = target_user_info.display_name
|
||||
if target_user_info.roles:
|
||||
form.role.data = target_user_info.roles[0]
|
||||
else:
|
||||
form.role.data = "prosody:normal"
|
||||
|
||||
return await render_template(
|
||||
"admin_edit_user.html",
|
||||
target_user=target_user_info,
|
||||
form=form,
|
||||
)
|
||||
|
||||
|
||||
class DeleteUserForm(BaseForm):
|
||||
action_delete = wtforms.SubmitField(
|
||||
_l("Delete user permanently")
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/user/<localpart>/delete", methods=["GET", "POST"])
|
||||
@bp.route("/user/<localpart>/delete", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def delete_user(localpart: str) -> typing.Union[str, quart.Response]:
|
||||
target_user_info = await client.get_user_by_localpart(localpart)
|
||||
@@ -68,6 +151,10 @@ async def delete_user(localpart: str) -> typing.Union[str, quart.Response]:
|
||||
if form.validate_on_submit():
|
||||
if form.action_delete.data:
|
||||
await client.delete_user_by_localpart(localpart)
|
||||
await flash(
|
||||
_("User deleted"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".users"))
|
||||
|
||||
return await render_template(
|
||||
@@ -77,7 +164,7 @@ async def delete_user(localpart: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/user/<localpart>/debug")
|
||||
@bp.route("/user/<localpart>/debug") # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def debug_user(localpart: str) -> typing.Union[str, quart.Response]:
|
||||
target_user_info = await client.get_user_by_localpart(localpart)
|
||||
@@ -93,37 +180,47 @@ async def debug_user(localpart: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/users/password-reset/-", methods=["POST"])
|
||||
@bp.route("/users/password-reset/<id_>", methods=["GET", "POST"]) # type:ignore # noqa:E501
|
||||
@client.require_admin_session()
|
||||
async def create_password_reset_link() -> typing.Union[str, quart.Response]:
|
||||
form = PasswordResetLinkPost()
|
||||
if not form.validate_on_submit():
|
||||
abort(400)
|
||||
|
||||
if form.action_create.data:
|
||||
localpart = form.action_create.data
|
||||
target_user_info = await client.get_user_by_localpart(localpart)
|
||||
reset_link = await client.create_password_reset_invite(
|
||||
localpart=localpart,
|
||||
ttl=86400,
|
||||
async def user_password_reset_link(
|
||||
id_: str,
|
||||
) -> typing.Union[str, quart.Response]:
|
||||
invite_info = await client.get_invite_by_id(
|
||||
id_,
|
||||
)
|
||||
if invite_info.jid is None:
|
||||
await flash(
|
||||
_("Password reset link not found"),
|
||||
"alert",
|
||||
)
|
||||
elif form.action_revoke.data:
|
||||
await client.delete_invite(form.action_revoke.data)
|
||||
return redirect(url_for(".users"))
|
||||
|
||||
localpart = prosodyclient.split_jid(invite_info.jid)[0]
|
||||
|
||||
form = PasswordResetLinkPost()
|
||||
if form.validate_on_submit():
|
||||
if form.action_revoke.data:
|
||||
await client.delete_invite(id_)
|
||||
await flash(
|
||||
_("Password reset link deleted"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".edit_user", localpart=localpart))
|
||||
abort(400)
|
||||
|
||||
return await render_template(
|
||||
"admin_reset_user_password.html",
|
||||
target_user=target_user_info,
|
||||
reset_link=reset_link,
|
||||
localpart=localpart,
|
||||
reset_link=invite_info,
|
||||
form=form,
|
||||
)
|
||||
|
||||
|
||||
class InvitesListForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class InvitesListForm(BaseForm):
|
||||
action_revoke = wtforms.StringField()
|
||||
|
||||
|
||||
class InvitePost(flask_wtf.FlaskForm): # type:ignore
|
||||
class InvitePost(BaseForm):
|
||||
circles = wtforms.SelectMultipleField(
|
||||
_l("Invite to circle"),
|
||||
# NOTE: This is for when/if we ever support multi-group invites.
|
||||
@@ -177,7 +274,7 @@ class InvitePost(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/invitations", methods=["GET", "POST"])
|
||||
@bp.route("/invitations", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def invitations() -> typing.Union[str, quart.Response]:
|
||||
invites = sorted(
|
||||
@@ -217,13 +314,13 @@ async def invitations() -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class InviteForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class InviteForm(BaseForm):
|
||||
action_revoke = wtforms.SubmitField(
|
||||
_l("Revoke")
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/invitation/-/new", methods=["POST"])
|
||||
@bp.route("/invitation/-/new", methods=["POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def create_invite() -> typing.Union[str, quart.Response]:
|
||||
form = InvitePost()
|
||||
@@ -242,19 +339,27 @@ async def create_invite() -> typing.Union[str, quart.Response]:
|
||||
group_ids=form.circles.data,
|
||||
ttl=form.lifetime.data,
|
||||
)
|
||||
await flash(
|
||||
_("Invitation created"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".edit_invite", id_=invite.id_))
|
||||
return await render_template("admin_create_invite.html",
|
||||
invite_form=form)
|
||||
|
||||
|
||||
@bp.route("/invitation/<id_>", methods=["GET", "POST"])
|
||||
@bp.route("/invitation/<id_>", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
||||
try:
|
||||
invite_info = await client.get_invite_by_id(id_)
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 404:
|
||||
abort(404)
|
||||
await flash(
|
||||
_("No such invitation exists"),
|
||||
"alert",
|
||||
)
|
||||
return redirect(url_for(".invitations"))
|
||||
circles = await client.list_groups()
|
||||
circle_map = {
|
||||
circle.id_: circle
|
||||
@@ -265,6 +370,10 @@ async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
||||
if form.validate_on_submit():
|
||||
if form.action_revoke.data:
|
||||
await client.delete_invite(id_)
|
||||
await flash(
|
||||
_("Invitation revoked"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".invitations"))
|
||||
return redirect(url_for(".edit_invite", id_=id_))
|
||||
|
||||
@@ -277,7 +386,7 @@ async def edit_invite(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class CirclePost(flask_wtf.FlaskForm): # type:ignore
|
||||
class CirclePost(BaseForm):
|
||||
name = wtforms.StringField(
|
||||
_l("Name"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
@@ -288,7 +397,7 @@ class CirclePost(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/circles")
|
||||
@bp.route("/circles") # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def circles() -> str:
|
||||
circles = sorted(
|
||||
@@ -305,7 +414,7 @@ async def circles() -> str:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/circle/-/new", methods=["POST"])
|
||||
@bp.route("/circle/-/new", methods=["POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def create_circle() -> typing.Union[str, quart.Response]:
|
||||
create_form = CirclePost()
|
||||
@@ -313,6 +422,10 @@ async def create_circle() -> typing.Union[str, quart.Response]:
|
||||
circle = await client.create_group(
|
||||
name=create_form.name.data,
|
||||
)
|
||||
await flash(
|
||||
_("Circle created"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".edit_circle", id_=circle.id_))
|
||||
|
||||
return await render_template(
|
||||
@@ -321,7 +434,7 @@ async def create_circle() -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class EditCircleForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class EditCircleForm(BaseForm):
|
||||
name = wtforms.StringField(
|
||||
_l("Name"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
@@ -347,7 +460,7 @@ class EditCircleForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/circle/<id_>", methods=["GET", "POST"])
|
||||
@bp.route("/circle/<id_>", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_admin_session()
|
||||
async def edit_circle(id_: str) -> typing.Union[str, quart.Response]:
|
||||
async with client.authenticated_session() as session:
|
||||
@@ -358,6 +471,10 @@ async def edit_circle(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 404:
|
||||
await flash(
|
||||
_("No such circle exists"),
|
||||
"alert",
|
||||
)
|
||||
return redirect(url_for(".circles"))
|
||||
raise
|
||||
|
||||
@@ -391,21 +508,36 @@ async def edit_circle(id_: str) -> typing.Union[str, quart.Response]:
|
||||
id_,
|
||||
new_name=form.name.data,
|
||||
)
|
||||
await flash(
|
||||
_("Circle data updated"),
|
||||
"success",
|
||||
)
|
||||
elif form.action_delete.data:
|
||||
await client.delete_group(id_)
|
||||
await flash(
|
||||
_("Circle deleted"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".circles"))
|
||||
elif form.action_add_user.data:
|
||||
if form.user_to_add.data in valid_users:
|
||||
print("is valid")
|
||||
await client.add_group_member(
|
||||
id_,
|
||||
form.user_to_add.data,
|
||||
)
|
||||
await flash(
|
||||
_("User added to circle"),
|
||||
"success",
|
||||
)
|
||||
elif form.action_remove_user.data:
|
||||
await client.remove_group_member(
|
||||
id_,
|
||||
form.action_remove_user.data,
|
||||
)
|
||||
await flash(
|
||||
_("User removed from circle"),
|
||||
"success",
|
||||
)
|
||||
|
||||
return redirect(url_for(".edit_circle", id_=id_))
|
||||
else:
|
||||
|
||||
@@ -10,6 +10,7 @@ from quart import (
|
||||
)
|
||||
|
||||
import flask_babel
|
||||
import flask_wtf
|
||||
from flask_babel import _
|
||||
|
||||
from . import prosodyclient
|
||||
@@ -25,7 +26,7 @@ babel = flask_babel.Babel()
|
||||
def selected_locale() -> str:
|
||||
selected = request.accept_languages.best_match(
|
||||
current_app.config['LANGUAGES']
|
||||
)
|
||||
) or current_app.config['LANGUAGES'][0]
|
||||
return selected
|
||||
|
||||
|
||||
@@ -55,3 +56,14 @@ def generate_error_id() -> str:
|
||||
return base64.b32encode(secrets.token_bytes(8)).decode(
|
||||
"ascii"
|
||||
).rstrip("=")
|
||||
|
||||
|
||||
class BaseForm(flask_wtf.FlaskForm): # type:ignore
|
||||
def __init__(self, *args: typing.Any, **kwargs: typing.Any):
|
||||
meta = kwargs["meta"] = dict(kwargs.get("meta", {}))
|
||||
if "locales" not in meta:
|
||||
locale = flask_babel.get_locale()
|
||||
if locale:
|
||||
meta["locales"] = [str(locale)]
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@@ -16,10 +16,9 @@ from quart import (
|
||||
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
from flask_babel import lazy_gettext as _l
|
||||
|
||||
from .infra import client, selected_locale
|
||||
from .infra import client, selected_locale, BaseForm
|
||||
|
||||
|
||||
bp = Blueprint("invite", __name__)
|
||||
@@ -47,14 +46,21 @@ def context() -> typing.Mapping[str, typing.Any]:
|
||||
}
|
||||
|
||||
|
||||
@bp.route("/<id_>")
|
||||
async def view(id_: str) -> str:
|
||||
@bp.route("/<id_>") # type:ignore
|
||||
async def view_old(id_: str) -> quart.Response:
|
||||
return redirect(url_for(".view", id_=id_))
|
||||
|
||||
|
||||
@bp.route("/<id_>/") # type:ignore
|
||||
async def view(id_: str) -> typing.Union[quart.Response,
|
||||
typing.Tuple[str, int],
|
||||
str]:
|
||||
try:
|
||||
invite = await client.get_public_invite_by_id(id_)
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 404:
|
||||
# invite expired
|
||||
return await render_template("invite_invalid.html")
|
||||
return await render_template("invite_invalid.html"), 404
|
||||
raise
|
||||
|
||||
if invite.reset_localpart is not None:
|
||||
@@ -79,16 +85,23 @@ async def view(id_: str) -> str:
|
||||
)
|
||||
apple_store_url = current_app.config["APPLE_STORE_URL"]
|
||||
|
||||
return await render_template(
|
||||
body = await render_template(
|
||||
"invite_view.html",
|
||||
invite=invite,
|
||||
play_store_url=play_store_url,
|
||||
apple_store_url=apple_store_url,
|
||||
f_droid_url="market://details?id=org.snikket.android",
|
||||
invite_id=id_,
|
||||
)
|
||||
return quart.Response(
|
||||
body,
|
||||
headers={
|
||||
"Link": "<{}> rel=\"alternate\"".format(invite.xmpp_uri),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class RegisterForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class RegisterForm(BaseForm):
|
||||
localpart = wtforms.StringField(
|
||||
_l("Username"),
|
||||
)
|
||||
@@ -102,7 +115,7 @@ class RegisterForm(flask_wtf.FlaskForm): # type:ignore
|
||||
validators=[wtforms.validators.InputRequired(),
|
||||
wtforms.validators.EqualTo(
|
||||
"password",
|
||||
_l("The passwords must match")
|
||||
_l("The passwords must match.")
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -111,7 +124,7 @@ class RegisterForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/<id_>/register", methods=["GET", "POST"])
|
||||
@bp.route("/<id_>/register", methods=["GET", "POST"]) # type:ignore
|
||||
async def register(id_: str) -> typing.Union[str, quart.Response]:
|
||||
try:
|
||||
invite = await client.get_public_invite_by_id(id_)
|
||||
@@ -134,15 +147,15 @@ async def register(id_: str) -> typing.Union[str, quart.Response]:
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 409:
|
||||
form.localpart.errors.append(
|
||||
_l("That username is already taken")
|
||||
_l("That username is already taken.")
|
||||
)
|
||||
elif exc.status == 403:
|
||||
form.localpart.errors.append(
|
||||
_l("Registration was declined for unknown reasons")
|
||||
_l("Registration was declined for unknown reasons.")
|
||||
)
|
||||
elif exc.status == 400:
|
||||
form.localpart.errors.append(
|
||||
_l("The username is not valid")
|
||||
_l("The username is not valid.")
|
||||
)
|
||||
elif exc.status == 404:
|
||||
return redirect(url_for(".view", id_=id_))
|
||||
@@ -159,7 +172,7 @@ async def register(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
class ResetForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ResetForm(BaseForm):
|
||||
password = wtforms.PasswordField(
|
||||
_l("Password"),
|
||||
)
|
||||
@@ -169,7 +182,7 @@ class ResetForm(flask_wtf.FlaskForm): # type:ignore
|
||||
validators=[wtforms.validators.InputRequired(),
|
||||
wtforms.validators.EqualTo(
|
||||
"password",
|
||||
_l("The passwords must match")
|
||||
_l("The passwords must match.")
|
||||
)]
|
||||
)
|
||||
|
||||
@@ -178,7 +191,7 @@ class ResetForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/<id_>/reset", methods=["GET", "POST"])
|
||||
@bp.route("/<id_>/reset", methods=["GET", "POST"]) # type:ignore
|
||||
async def reset(id_: str) -> typing.Union[str, quart.Response]:
|
||||
try:
|
||||
invite = await client.get_public_invite_by_id(id_)
|
||||
@@ -202,7 +215,7 @@ async def reset(id_: str) -> typing.Union[str, quart.Response]:
|
||||
except aiohttp.ClientResponseError as exc:
|
||||
if exc.status == 403:
|
||||
form.localpart.errors.append(
|
||||
_l("Registration was declined for unknown reasons")
|
||||
_l("Registration was declined for unknown reasons.")
|
||||
)
|
||||
elif exc.status == 404:
|
||||
return redirect(url_for(".view", id_=id_))
|
||||
@@ -219,7 +232,7 @@ async def reset(id_: str) -> typing.Union[str, quart.Response]:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/success", methods=["GET", "POST"])
|
||||
@bp.route("/success", methods=["GET", "POST"]) # type:ignore
|
||||
async def success() -> str:
|
||||
return await render_template(
|
||||
"invite_success.html",
|
||||
@@ -227,7 +240,7 @@ async def success() -> str:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/success/reset", methods=["GET", "POST"])
|
||||
@bp.route("/success/reset", methods=["GET", "POST"]) # type:ignore
|
||||
async def reset_success() -> str:
|
||||
return await render_template(
|
||||
"invite_reset_success.html",
|
||||
@@ -235,6 +248,6 @@ async def reset_success() -> str:
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/-")
|
||||
@bp.route("/-") # type:ignore
|
||||
async def index() -> quart.Response:
|
||||
return redirect(url_for("index"))
|
||||
|
||||
@@ -15,23 +15,24 @@ from quart import (
|
||||
render_template,
|
||||
request,
|
||||
Response,
|
||||
flash,
|
||||
)
|
||||
import werkzeug.exceptions
|
||||
|
||||
import babel
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from . import xmpputil, _version
|
||||
from .infra import client
|
||||
from .infra import client, BaseForm
|
||||
|
||||
|
||||
bp = quart.Blueprint("main", __name__)
|
||||
|
||||
|
||||
class LoginForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class LoginForm(BaseForm):
|
||||
address = wtforms.TextField(
|
||||
_l("Address"),
|
||||
validators=[wtforms.validators.InputRequired()],
|
||||
@@ -47,12 +48,15 @@ class LoginForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/-")
|
||||
@bp.route("/-") # type:ignore
|
||||
async def index() -> quart.Response:
|
||||
return redirect(url_for("index"))
|
||||
|
||||
|
||||
@bp.route("/login", methods=["GET", "POST"])
|
||||
ERR_CREDENTIALS_INVALID = _l("Invalid username or password.")
|
||||
|
||||
|
||||
@bp.route("/login", methods=["GET", "POST"]) # type:ignore
|
||||
async def login() -> typing.Union[str, quart.Response]:
|
||||
if client.has_session and (await client.test_session()):
|
||||
return redirect(url_for('user.index'))
|
||||
@@ -63,38 +67,53 @@ async def login() -> typing.Union[str, quart.Response]:
|
||||
localpart, domain, resource = xmpputil.split_jid(jid)
|
||||
if not localpart:
|
||||
localpart, domain = domain, current_app.config["SNIKKET_DOMAIN"]
|
||||
jid = "{}@{}".format(localpart, domain)
|
||||
password = form.password.data
|
||||
try:
|
||||
await client.login(jid, password)
|
||||
except quart.exceptions.Unauthorized:
|
||||
form.password.errors.append(
|
||||
_("Invalid username or password.")
|
||||
)
|
||||
if domain != current_app.config["SNIKKET_DOMAIN"]:
|
||||
# (a) prosody throws a 400 at us and I prefer to catch that here
|
||||
# and (b) I don’t want to pass on this obviously not-for-here
|
||||
# password further than necessary.
|
||||
form.password.errors.append(ERR_CREDENTIALS_INVALID)
|
||||
else:
|
||||
return redirect(url_for('user.index'))
|
||||
jid = "{}@{}".format(localpart, domain)
|
||||
password = form.password.data
|
||||
try:
|
||||
await client.login(jid, password)
|
||||
except werkzeug.exceptions.Unauthorized:
|
||||
form.password.errors.append(ERR_CREDENTIALS_INVALID)
|
||||
else:
|
||||
await flash(
|
||||
_("Login successful!"),
|
||||
"success"
|
||||
)
|
||||
return redirect(url_for('user.index'))
|
||||
|
||||
return await render_template("login.html", form=form)
|
||||
|
||||
|
||||
@bp.route("/meta/about.html")
|
||||
@bp.route("/meta/about.html") # type:ignore
|
||||
async def about() -> str:
|
||||
version = None
|
||||
extra_versions = {}
|
||||
if current_app.debug:
|
||||
|
||||
if current_app.debug or client.is_admin_session:
|
||||
version = _version.version
|
||||
extra_versions["Quart"] = quart.__version__
|
||||
extra_versions["aiohttp"] = aiohttp.__version__
|
||||
extra_versions["babel"] = babel.__version__
|
||||
extra_versions["wtforms"] = wtforms.__version__
|
||||
extra_versions["flask-wtf"] = flask_wtf.__version__
|
||||
try:
|
||||
extra_versions["Prosody"] = await client.get_server_version()
|
||||
except werkzeug.exceptions.Unauthorized:
|
||||
extra_versions["Prosody"] = "unknown"
|
||||
|
||||
return await render_template(
|
||||
"about.html",
|
||||
version=_version.version,
|
||||
version=version,
|
||||
extra_versions=extra_versions,
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/meta/demo.html")
|
||||
@bp.route("/meta/demo.html") # type:ignore
|
||||
async def demo() -> str:
|
||||
return await render_template("demo.html")
|
||||
|
||||
@@ -103,8 +122,9 @@ def repad(s: str) -> str:
|
||||
return s + "=" * (4 - len(s) % 4)
|
||||
|
||||
|
||||
@bp.route("/avatar/<from_>/<code>")
|
||||
@bp.route("/avatar/<from_>/<code>") # type:ignore
|
||||
async def avatar(from_: str, code: str) -> quart.Response:
|
||||
etag: typing.Optional[str]
|
||||
try:
|
||||
etag = request.headers["if-none-match"]
|
||||
except KeyError:
|
||||
@@ -144,3 +164,8 @@ async def avatar(from_: str, code: str) -> quart.Response:
|
||||
|
||||
response.set_data(data)
|
||||
return response
|
||||
|
||||
|
||||
@bp.route("/_health") # type:ignore
|
||||
async def health() -> Response:
|
||||
return Response("STATUS OK", content_type="text/plain")
|
||||
|
||||
@@ -19,7 +19,8 @@ from quart import (
|
||||
current_app, _app_ctx_stack, session as http_session, abort, redirect,
|
||||
url_for,
|
||||
)
|
||||
import quart.exceptions
|
||||
import werkzeug.exceptions
|
||||
import quart
|
||||
|
||||
from . import xmpputil
|
||||
from .xmpputil import split_jid
|
||||
@@ -44,6 +45,15 @@ class AdminUserInfo:
|
||||
display_name: typing.Optional[str]
|
||||
email: typing.Optional[str]
|
||||
phone: typing.Optional[str]
|
||||
roles: typing.Optional[typing.List[str]]
|
||||
|
||||
@property
|
||||
def has_admin_role(self) -> bool:
|
||||
return bool(self.roles and "prosody:admin" in self.roles)
|
||||
|
||||
@property
|
||||
def has_restricted_role(self) -> bool:
|
||||
return bool(self.roles and "prosody:restricted" in self.roles)
|
||||
|
||||
@classmethod
|
||||
def from_api_response(
|
||||
@@ -55,6 +65,7 @@ class AdminUserInfo:
|
||||
display_name=data.get("display_name") or None,
|
||||
email=data.get("email") or None,
|
||||
phone=data.get("phone") or None,
|
||||
roles=data.get("roles"),
|
||||
)
|
||||
|
||||
|
||||
@@ -261,8 +272,9 @@ class ProsodyClient:
|
||||
|
||||
def init_app(self, app: quart.Quart) -> None:
|
||||
app.config[self.CONFIG_ENDPOINT]
|
||||
app.teardown_appcontext(self._plain_session.teardown)
|
||||
app.teardown_appcontext(self._auth_session.teardown)
|
||||
# the type annotation in quart seems to be wrong here
|
||||
app.teardown_appcontext(self._plain_session.teardown) # type:ignore
|
||||
app.teardown_appcontext(self._auth_session.teardown) # type:ignore
|
||||
|
||||
@property
|
||||
def _endpoint_base(self) -> str:
|
||||
@@ -332,15 +344,18 @@ class ProsodyClient:
|
||||
)
|
||||
)
|
||||
|
||||
def _store_token_in_session(self, token_info: TokenInfo) -> None:
|
||||
http_session[self.SESSION_TOKEN] = token_info.token
|
||||
http_session[self.SESSION_CACHED_SCOPE] = " ".join(token_info.scopes)
|
||||
|
||||
async def login(self, jid: str, password: str) -> bool:
|
||||
async with self._plain_session as session:
|
||||
token_info = await self._oauth2_bearer_token(
|
||||
session, jid, password,
|
||||
)
|
||||
|
||||
http_session[self.SESSION_TOKEN] = token_info.token
|
||||
self._store_token_in_session(token_info)
|
||||
http_session[self.SESSION_ADDRESS] = jid
|
||||
http_session[self.SESSION_CACHED_SCOPE] = " ".join(token_info.scopes)
|
||||
return True
|
||||
|
||||
@property
|
||||
@@ -445,6 +460,13 @@ class ProsodyClient:
|
||||
headers=final_headers,
|
||||
data=serialised) as resp:
|
||||
if resp.status != 200:
|
||||
self.logger.debug(
|
||||
"IQ HTTP response (in-reply-to id=%s) with non-OK status "
|
||||
"%s: %s",
|
||||
id_,
|
||||
resp.status,
|
||||
resp.reason,
|
||||
)
|
||||
abort(resp.status)
|
||||
reply_payload = await resp.read()
|
||||
self.logger.debug(
|
||||
@@ -469,7 +491,7 @@ class ProsodyClient:
|
||||
session=session,
|
||||
)
|
||||
avatar_hash = avatar_info["sha1"]
|
||||
except quart.exceptions.HTTPException:
|
||||
except werkzeug.exceptions.HTTPException:
|
||||
avatar_hash = None
|
||||
|
||||
return {
|
||||
@@ -490,9 +512,32 @@ class ProsodyClient:
|
||||
"to": self.session_address,
|
||||
}
|
||||
|
||||
async with session.post(self._rest_endpoint, data=req) as resp:
|
||||
async with session.post(self._rest_endpoint, json=req) as resp:
|
||||
return resp.status == 200
|
||||
|
||||
@autosession
|
||||
async def get_server_version(self, session: aiohttp.ClientSession) -> str:
|
||||
_, domain, _ = split_jid(self.session_address)
|
||||
req = {
|
||||
"kind": "iq",
|
||||
"type": "get",
|
||||
"version": {},
|
||||
"to": domain,
|
||||
}
|
||||
|
||||
async with session.post(self._rest_endpoint, json=req) as resp:
|
||||
if resp.status != 200:
|
||||
return "unknwn"
|
||||
try:
|
||||
return (await resp.json())["version"]["version"]
|
||||
except Exception as exc:
|
||||
self.logger.debug(
|
||||
"failed to parse prosody version from response"
|
||||
" (%s: %s)",
|
||||
type(exc), exc,
|
||||
)
|
||||
return "unknown"
|
||||
|
||||
@autosession
|
||||
async def get_user_nickname(
|
||||
self,
|
||||
@@ -598,7 +643,7 @@ class ProsodyClient:
|
||||
new_access_model,
|
||||
)
|
||||
))
|
||||
except quart.exceptions.NotFound:
|
||||
except werkzeug.exceptions.NotFound:
|
||||
if ignore_not_found:
|
||||
return
|
||||
raise
|
||||
@@ -728,7 +773,7 @@ class ProsodyClient:
|
||||
session: aiohttp.ClientSession,
|
||||
) -> str:
|
||||
access_models = filter(
|
||||
lambda x: not isinstance(x, quart.exceptions.NotFound),
|
||||
lambda x: not isinstance(x, werkzeug.exceptions.NotFound),
|
||||
await asyncio.gather(
|
||||
self.get_avatar_access_model(session=session),
|
||||
self.get_nickname_access_model(session=session),
|
||||
@@ -767,7 +812,7 @@ class ProsodyClient:
|
||||
# got there, replacing the current session token on the way.
|
||||
|
||||
async with self._plain_session as session:
|
||||
token = await self._oauth2_bearer_token(
|
||||
token_info = await self._oauth2_bearer_token(
|
||||
session,
|
||||
self.session_address,
|
||||
current_password,
|
||||
@@ -779,14 +824,14 @@ class ProsodyClient:
|
||||
new_password
|
||||
),
|
||||
headers={
|
||||
"Authorization": "Bearer {}".format(token),
|
||||
"Authorization": "Bearer {}".format(token_info.token),
|
||||
},
|
||||
sensitive=True,
|
||||
)
|
||||
# TODO: error handling
|
||||
# TODO: obtain a new token using the new password to allow the
|
||||
# server to expire/revoke all tokens on password change.
|
||||
http_session[self.SESSION_TOKEN] = token
|
||||
self._store_token_in_session(token_info)
|
||||
|
||||
def _raise_error_from_response(
|
||||
self,
|
||||
@@ -825,6 +870,29 @@ class ProsodyClient:
|
||||
self._raise_error_from_response(resp)
|
||||
return AdminUserInfo.from_api_response(await resp.json())
|
||||
|
||||
@autosession
|
||||
async def update_user(
|
||||
self,
|
||||
localpart: str,
|
||||
*,
|
||||
display_name: typing.Optional[str],
|
||||
roles: typing.Optional[typing.Collection[str]],
|
||||
session: aiohttp.ClientSession,
|
||||
) -> None:
|
||||
payload: typing.Dict[str, typing.Any] = {
|
||||
"username": localpart,
|
||||
}
|
||||
if display_name is not None:
|
||||
payload["display_name"] = display_name
|
||||
if roles is not None:
|
||||
payload["roles"] = list(roles)
|
||||
|
||||
async with session.put(
|
||||
self._admin_v1_endpoint("/users/{}".format(localpart)),
|
||||
json=payload,
|
||||
) as resp:
|
||||
self._raise_error_from_response(resp)
|
||||
|
||||
@autosession
|
||||
async def get_user_debug_info(
|
||||
self,
|
||||
|
||||
@@ -252,3 +252,4 @@ $h-sizes: [200.0%, 174.11011266%, 151.57165665%, 131.95079108%, 114.8698355%, 10
|
||||
$h-small-sizes: [150.0%, 138.31618672%, 127.54245006%, 117.60790225%, 108.44717712%, 100.0%];
|
||||
$small-screen-threshold: 40rem;
|
||||
$medium-screen-threshold: 60rem;
|
||||
$large-screen-threshold: 80rem;
|
||||
|
||||
@@ -33,13 +33,35 @@ body {
|
||||
|
||||
main {
|
||||
padding: $w-l1;
|
||||
margin-left: auto;
|
||||
max-width: 60rem;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
#mwrap {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
|
||||
> .filler, > .flashbox {
|
||||
flex: 1 1 1rem;
|
||||
}
|
||||
|
||||
> main {
|
||||
flex: 0 1 60rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: $large-screen-threshold) {
|
||||
#mwrap {
|
||||
display: block;
|
||||
|
||||
> main {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flashbox > div.box > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* top bar */
|
||||
@@ -67,6 +89,10 @@ div#topbar {
|
||||
font-size: $_top-h-size;
|
||||
line-height: 1.5;
|
||||
|
||||
body.debug & {
|
||||
color: red;
|
||||
}
|
||||
|
||||
@media screen and (max-width: $small-screen-threshold) {
|
||||
font-size: $_top-h-small-size;
|
||||
}
|
||||
@@ -134,22 +160,20 @@ body > footer {
|
||||
background-color: $gray-100;
|
||||
color: $gray-800;
|
||||
padding: 0 $w-l1;
|
||||
font-size: 92.21079115%;
|
||||
|
||||
ul {
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
list-style-type: none;
|
||||
text-align: center;
|
||||
line-height: 1.6267076567643135;
|
||||
}
|
||||
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: $w-l1 0;
|
||||
}
|
||||
|
||||
li:before {
|
||||
content: '•';
|
||||
padding-right: $w-s2;
|
||||
display: block;
|
||||
margin: $w-s1 0;
|
||||
}
|
||||
|
||||
a, a:visited, a:hover, a:active, a:focus {
|
||||
@@ -330,6 +354,15 @@ div.form.layout-expanded {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.radio-button-ext > label > p {
|
||||
margin-left: 1.75rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.radio-button-ext > label .icon {
|
||||
margin-left: 0.25em;
|
||||
}
|
||||
|
||||
div.select-wrap {
|
||||
display: block;
|
||||
border-bottom: $w-s4 solid $primary-500;
|
||||
@@ -993,6 +1026,23 @@ div.profile-card {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
input[type="submit"], button, .button {
|
||||
&.slimmify {
|
||||
> svg.icon {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
> span {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
top: -100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* clipboard button */
|
||||
|
||||
@@ -54,6 +54,8 @@ div.install-buttons {
|
||||
ul {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
list-style-type: none;
|
||||
margin: $w-l1 0;
|
||||
padding: 0;
|
||||
@@ -74,6 +76,10 @@ img.play {
|
||||
height: $w-l3;
|
||||
}
|
||||
|
||||
img.fdroid {
|
||||
height: $w-l3;
|
||||
}
|
||||
|
||||
.tabbox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
BIN
snikket_web/static/img/f-droid-badge.png
Normal file
BIN
snikket_web/static/img/f-droid-badge.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
@@ -37,6 +37,11 @@ licensed under the terms of the Apache 2.0 License -->
|
||||
<path d="M0 0h24v24H0V0z" fill="none" />
|
||||
<path d="M10.79 16.29c.39.39 1.02.39 1.41 0l3.59-3.59c.39-.39.39-1.02 0-1.41L12.2 7.7c-.39-.39-1.02-.39-1.41 0-.39.39-.39 1.02 0 1.41L12.67 11H4c-.55 0-1 .45-1 1s.45 1 1 1h8.67l-1.88 1.88c-.39.39-.38 1.03 0 1.41zM19 3H5c-1.11 0-2 .9-2 2v3c0 .55.45 1 1 1s1-.45 1-1V6c0-.55.45-1 1-1h12c.55 0 1 .45 1 1v12c0 .55-.45 1-1 1H6c-.55 0-1-.45-1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1v3c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z" />
|
||||
</symbol>
|
||||
<!-- from: action/lock/materialiconsround/24px.svg -->
|
||||
<symbol id="icon-lock" viewBox="0 0 24 24">
|
||||
<g fill="none"><path d="M0 0h24v24H0V0z" /><path d="M0 0h24v24H0V0z" opacity=".87" /></g>
|
||||
<path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zm-6 9c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zM9 8V6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9z" />
|
||||
</symbol>
|
||||
<!-- from: communication/qr_code/materialiconsround/24px.svg -->
|
||||
<symbol id="icon-qrcode" viewBox="0 0 24 24">
|
||||
<g><rect fill="none" height="24" width="24" /><rect fill="none" height="24" width="24" /></g>
|
||||
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 15 KiB |
@@ -3,5 +3,7 @@
|
||||
{#- -#}
|
||||
<li>{% trans about_url=url_for('main.about') %}A <a href="{{ about_url }}">Snikket</a> service{% endtrans %}</li>
|
||||
{#- -#}
|
||||
<li>{% trans %}“Snikket” and the parrot logo are trademarks of Snikket Community Interest Company.{% endtrans %}</li>
|
||||
{#- -#}
|
||||
</ul>
|
||||
</footer>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "library.j2" import standard_button %}
|
||||
{% block head_lead %}
|
||||
<title>About Snikket</title>
|
||||
<title>{% trans %}About Snikket{% endtrans %}</title>
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<main>
|
||||
@@ -14,10 +14,12 @@
|
||||
<p>{% trans agpl_url="https://www.gnu.org/licenses/agpl.html" %}The web portal software is licensed under the terms of the <a href="{{ agpl_url }}">Affero GNU General Public License, version 3.0 or later</a>. The full terms of the license can be reviewed using the aforementioned link.{% endtrans %}</p>
|
||||
<p>{% trans source_url="https://github.com/snikket-im/snikket-web-portal/" %}The source code of the web portal can be downloaded and viewed in <a href="{{ source_url }}">its GitHub repository</a>.{% endtrans %}</p>
|
||||
<p>{% trans source_url="https://material.io/resources/icons/", apache20_url="https://www.apache.org/licenses/LICENSE-2.0.txt" %}The icons used in the web portal are <a href="{{ source_url }}">Google’s Material Icons</a>, made available by Google under the terms of the <a href="{{ apache20_url }}">Apache 2.0 License</a>.{% endtrans %}</p>
|
||||
<h3>{% trans %}Trademarks{% endtrans %}</h3>
|
||||
<p>{% trans trademarks_url="https://snikket.org/about/trademarks/" %}“Snikket” and the parrot logo are trademarks of Snikket Community Interest Company. For more information about the trademarks, visit the <a href="{{ trademarks_url }}">Snikket Trademarks information page</a>.{% endtrans %}
|
||||
<h3>{% trans %}Software Versions{% endtrans %}</h3>
|
||||
<pre>Snikket Server
|
||||
Domain: {{ config["SNIKKET_DOMAIN"] }}
|
||||
Snikket Web Portal ({{ version }})
|
||||
Snikket Web Portal{% if version %} ({{ version }}){% endif %}
|
||||
{%- if extra_versions -%}
|
||||
{% for name, version in extra_versions.items() %}
|
||||
{{ name }} ({{ version }}){% endfor %}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<p>{% trans %}The user and their data will be deleted irrevocably, permanently and immediately upon pushing the below button. <strong>There is no way back!</strong>{% endtrans %}</p>
|
||||
{% endcall %}
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for(".index"), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call standard_button("back", url_for(".edit_user", localpart=target_user.localpart), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call form_button("delete", form.action_delete, class="primary danger") %}{% endcall -%}
|
||||
</div>
|
||||
</form></div>
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
{%- endif -%}
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for(".circles"), class="secondary") -%}
|
||||
{% trans %}Back{% endtrans %}
|
||||
{%- call standard_button("back", url_for(".circles"), class="tertiary") -%}
|
||||
{% trans %}Return to circle list{% endtrans %}
|
||||
{%- endcall -%}
|
||||
{%- call form_button("done", form.action_save, class="primary") %}{% endcall -%}
|
||||
</div>
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
<dd>{{ invite.created_at | format_date }}</dd>
|
||||
</dl>
|
||||
<div class="f-bbox">
|
||||
{%- call form_button("remove_link", form.action_revoke, class="secondary danger") %}{% endcall -%}
|
||||
{%- call standard_button("back", url_for(".invitations"), class="primary") %}
|
||||
{% trans %}Back{% endtrans %}
|
||||
{%- call standard_button("back", url_for(".invitations"), class="tertiary") %}
|
||||
{% trans %}Return to invitation list{% endtrans %}
|
||||
{%- endcall %}
|
||||
{%- call form_button("remove_link", form.action_revoke, class="primary danger") %}{% endcall -%}
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
78
snikket_web/templates/admin_edit_user.html
Normal file
78
snikket_web/templates/admin_edit_user.html
Normal file
@@ -0,0 +1,78 @@
|
||||
{% extends "admin_app.html" %}
|
||||
{% from "library.j2" import box, form_button, standard_button, icon %}
|
||||
{% macro access_level_description(role, caller=None) %}
|
||||
{%- if role == "prosody:restricted" -%}
|
||||
{% trans %}Limited users can interact with users on the same Snikket service and be members of circles.{% endtrans %}
|
||||
{%- elif role == "prosody:normal" -%}
|
||||
{% trans %}Like limited users and can also interact with users on other Snikket services.{% endtrans %}
|
||||
{%- elif role == "prosody:admin" -%}
|
||||
{% trans %}Like normal users and can access the admin panel in the web portal.{% endtrans %}
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
{% macro access_level_icon(role, caller=None) %}
|
||||
{%- if role == "prosody:restricted" -%}
|
||||
{% call icon("lock") %}{% endcall %}
|
||||
{%- elif role == "prosody:admin" -%}
|
||||
{% call icon("admin") %}{% endcall %}
|
||||
{%- endif -%}
|
||||
{% endmacro %}
|
||||
{% block content %}
|
||||
<h1>{% trans user_name=target_user.localpart %}Edit user {{ user_name }}{% endtrans %}</h1>
|
||||
<form method="POST">{{ form.csrf_token }}<div class="form layout-expanded">
|
||||
<h2 class="form-title">{% trans %}Edit user{% endtrans %}</h2>
|
||||
<div class="f-ebox">
|
||||
{{ form.localpart.label }}
|
||||
{{ form.localpart(readonly="readonly") }}
|
||||
<p class="form-desc weak">{% trans %}The login name cannot be changed.{% endtrans %}</p>
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
{{ form.display_name.label }}
|
||||
{{ form.display_name }}
|
||||
</div>
|
||||
<h3 class="form-title">{% trans %}Access Level{% endtrans %}</h3>
|
||||
<p class="form-descr weak">{% trans %}The access level of a user determines what interactions are allowed for them on your Snikket service.{% endtrans %}</p>
|
||||
<div class="f-ebox">
|
||||
<fieldset>{#- -#}
|
||||
<legend class="a11y-only">{{ form.role.label.text }}</legend>
|
||||
{%- for level in form.role -%}
|
||||
<div class="radio-button-ext">
|
||||
{{ level }}<label for="{{ level.id }}">
|
||||
{%- trans title=level.label.text, icon=access_level_icon(level.data), description=access_level_description(level.data) -%}
|
||||
<strong>{{ title }}{{ icon }}</strong><p>{{ description }}</p>
|
||||
{%- endtrans -%}
|
||||
</label>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for(".users"), class="tertiary") -%}
|
||||
{%- trans -%}Return to user list{%- endtrans -%}
|
||||
{%- endcall -%}
|
||||
{%- call standard_button("delete", url_for(".delete_user", localpart=target_user.localpart), class="secondary") -%}
|
||||
{%- trans -%}Delete user{%- endtrans -%}
|
||||
{%- endcall -%}
|
||||
{%- call form_button("done", form.action_save, class="primary") %}{% endcall -%}
|
||||
</div>
|
||||
</div>
|
||||
<h2>{% trans %}Further actions{% endtrans %}</h2>
|
||||
<div class="form layout-expanded">
|
||||
<h2 class="form-title">{% trans %}Reset password{% endtrans %}</h2>
|
||||
{{ form.csrf_token }}
|
||||
<p class="form-desc">
|
||||
{% trans %}If the user has lost their password, you can use the button below to create a special link which allows to change the password of the account, once.{% endtrans %}
|
||||
</p>
|
||||
<div class="f-bbox">
|
||||
{%- call form_button("passwd", form.action_create_reset, class="primary") -%}{%- endcall -%}
|
||||
</div>
|
||||
<h2 class="form-title">{% trans %}Debug information{% endtrans %}</h2>
|
||||
<p class="form-desc">
|
||||
{% trans %}In some cases, extended information about the user account and the connected devices is necessary to troubleshoot issues. The button below reveals this (sensitive) information.{% endtrans %}
|
||||
</p>
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("bug_report", url_for(".debug_user", localpart=target_user.localpart), class="primary") -%}
|
||||
{%- trans -%}Show debug information{%- endtrans -%}
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
</div></form>
|
||||
{% endblock %}
|
||||
@@ -18,7 +18,7 @@
|
||||
<col/>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans %}Valid until{% endtrans %}</th>
|
||||
<th>{% trans %}Expires{% endtrans %}</th>
|
||||
<th class="collapsible">{% trans %}Type{% endtrans %}</th>
|
||||
<th class="collapsible">{% trans %}Circle{% endtrans %}</th>
|
||||
<th>{% trans %}Actions{% endtrans %}</th>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<form method="POST">
|
||||
{{- form.csrf_token -}}
|
||||
<div class="form layout-expanded">
|
||||
<h2 class="form-title">{% trans user_name=target_user.localpart %}Password reset link for {{ user_name }}{% endtrans %}</h2>
|
||||
<h2 class="form-title">{% trans user_name=localpart %}Password reset link for {{ user_name }}{% endtrans %}</h2>
|
||||
<p class="form-desc">{% trans %}The following link will allow the user to reset their password on their device, once.{% endtrans %}</p>
|
||||
<dd>
|
||||
<dt>{% trans %}Valid until{% endtrans %}</dt>
|
||||
@@ -21,7 +21,7 @@
|
||||
{%- call custom_form_button("remove_link", form.action_revoke.name, reset_link.id_, class="secondary danger") -%}
|
||||
{% trans %}Destroy link{% endtrans %}
|
||||
{%- endcall -%}
|
||||
{%- call standard_button("back", url_for(".users"), class="primary") -%}
|
||||
{%- call standard_button("back", url_for(".edit_user", localpart=localpart), class="primary") -%}
|
||||
{% trans %}Back{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
{% extends "admin_app.html" %}
|
||||
{% from "library.j2" import action_button, value_or_hint, custom_form_button %}
|
||||
{% from "library.j2" import action_button, icon, value_or_hint, custom_form_button %}
|
||||
{% block content %}
|
||||
<h1>{% trans %}Manage users{% endtrans %}</h1>
|
||||
<form method="POST" action="{{ url_for(".create_password_reset_link") }}">
|
||||
{{- reset_form.csrf_token -}}
|
||||
<div class="elevated el-2"><table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -15,17 +13,19 @@
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.localpart }}</td>
|
||||
<td>
|
||||
{{- user.localpart -}}
|
||||
{%- if user.has_admin_role -%}
|
||||
<span class="with-tooltip above" data-tooltip="{% trans %}The user is an administrator.{% endtrans %}">{% call icon("admin") %}{% trans %} (Administrator){% endtrans %}{% endcall %}</span>
|
||||
{%- endif -%}
|
||||
{%- if user.has_restricted_role -%}
|
||||
<span class="with-tooltip above" data-tooltip="{% trans %}The user is restricted.{% endtrans %}">{% call icon("lock") %}{% trans %} (Restricted){% endtrans %}{% endcall %}</span>
|
||||
{%- endif -%}
|
||||
</td>
|
||||
<td>{% call value_or_hint(user.display_name) %}{% endcall %}</td>
|
||||
<td class="nowrap">
|
||||
{%- call action_button("delete", url_for(".delete_user", localpart=user.localpart), class="secondary") -%}
|
||||
{% trans user_name=user.localpart %}Delete user {{ user_name }}{% endtrans %}
|
||||
{%- endcall -%}
|
||||
{%- call action_button("bug_report", url_for(".debug_user", localpart=user.localpart), class="secondary") -%}
|
||||
{% trans user_name=user.localpart %}Show debug information for {{ user_name }}{% endtrans %}
|
||||
{%- endcall -%}
|
||||
{%- call custom_form_button("passwd", reset_form.action_create.name, user.localpart, class="secondary", slim=True) -%}
|
||||
{% trans user_name=user.localpart %}Create password reset link for {{ user_name }}{% endtrans %}
|
||||
{%- call action_button("edit", url_for(".edit_user", localpart=user.localpart), class="primary") -%}
|
||||
{% trans user_name=user.localpart %}Edit user {{ user_name }}{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</form>
|
||||
</td>
|
||||
@@ -33,5 +33,5 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table></div>
|
||||
</form>
|
||||
{%- include "admin_create_invite_form.html" -%}
|
||||
{% endblock %}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
{% endblock %}
|
||||
{% block topbar_right %}
|
||||
{{- super() -}}
|
||||
{% call standard_button("logout", url_for("user.logout"), class="tertiary") %}{% trans %}Log out{% endtrans %}{% endcall %}
|
||||
{% call standard_button("logout", url_for("user.logout"), class="tertiary slimmify") %}{% trans %}Log out{% endtrans %}{% endcall %}
|
||||
{%- endblock %}
|
||||
|
||||
@@ -16,5 +16,5 @@
|
||||
<meta name="msapplication-TileColor" content="#fbd308">
|
||||
<meta name="theme-color" content="#fbd308">
|
||||
</head>
|
||||
<body{% if body_id | default(False) %} id="{{ body_id }}"{% endif %}{% if body_class | default(False) %} class="{{ body_class }}"{% endif %}{% if onload | default(False) %} onload="{{ onload }}"{% endif %}>{% block body %}{% endblock %}</body>
|
||||
<body{% if body_id | default(False) %} id="{{ body_id }}"{% endif %} class="{% if is_in_debug_mode %}debug{% endif %}{% if body_class | default(False) %} {{ body_class }}{% endif %}"{% if onload | default(False) %} onload="{{ onload }}"{% endif %}>{% block body %}{% endblock %}</body>
|
||||
</html>
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename="css/invite.css") }}">
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div id="mwrap"><main>{% block content %}{% endblock %}</main></div>
|
||||
<div id="mwrap"><div class="filler"></div><main>{% block content %}{% endblock %}</main><div class="filler"></div></div>
|
||||
{%- include "_footer.html" -%}
|
||||
{% endblock %}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<title>{% trans site_name=config["SITE_NAME"] %}Invite to {{ site_name }} | Snikket{% endtrans %}</title>
|
||||
<script async type="text/javascript" src="{{ url_for("static", filename="js/invite-magic.js") }}"></script>
|
||||
<script async type="text/javascript" src="{{ url_for("static", filename="js/qrcode.min.js") }}"></script>
|
||||
<link rel="alternate" href="{{ invite.xmpp_uri }}">
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="elevated box el-3">
|
||||
@@ -26,11 +27,12 @@
|
||||
<ul>
|
||||
<li><a href="{{ play_store_url }}"><img alt='{% trans %}Get it on Google Play{% endtrans %}' src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png' class="play"/></a></li>
|
||||
{%- if apple_store_url -%}
|
||||
<li><a href="{{ apple_store_url }}"><img alt='{% trans %}Download on the App Store{% endtrans %}' src="{{ apple_store_badge() }}" class="apple"></a></li>
|
||||
<li><a href="{{ apple_store_url }}" class="popover" data-popover-id="apple-popover"><img alt='{% trans %}Download on the App Store{% endtrans %}' src="{{ apple_store_badge() }}" class="apple"></a></li>
|
||||
{%- endif -%}
|
||||
<li><a href="{{ f_droid_url }}" class="popover" data-popover-id="fdroid-popover"><img alt='{% trans %}Get it on F-Droid{% endtrans %}' src='{{ url_for('static', filename='img/f-droid-badge.png') }}' class="fdroid"/></a></li>
|
||||
</ul>
|
||||
{%- call standard_button("qrcode", "#qr-modal", class="primary", onclick="open_modal(this); return false;") -%}
|
||||
{% trans %}Not on mobile?{% endtrans %}
|
||||
{% trans %}Send to mobile device{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
<p>{% trans %}After installation the app should automatically open and prompt you to create an account. If not, simply click the button below.{% endtrans %}</p>
|
||||
@@ -83,10 +85,77 @@
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
</div>
|
||||
{%- if apple_store_url -%}
|
||||
<div id="apple-popover" class="modal" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;" onclick="close_modal(this); return false;">
|
||||
<div role="document" class="elevated box el-2" onclick="event.stopPropagation();">
|
||||
<header class="modal-title">
|
||||
{#- -#}
|
||||
<span>{% trans %}Install on iOS{% endtrans %}</span>
|
||||
{#- -#}
|
||||
{%- call action_button("close", "#", onclick="close_modal(this.parentNode.parentNode.parentNode); return false;", class="tertiary") -%}
|
||||
{% trans %}Close{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</header>
|
||||
<p>{% trans %}After downloading Snikket from the App Store, you have to return to this invite link and tap on "Open the app" to proceed.{% endtrans %}</p>
|
||||
<ol>
|
||||
<li><p>{% trans %}First download Snikket from the App Store using the button below:{% endtrans %}</p>
|
||||
<p><a href="{{ apple_store_url }}"><img alt='{% trans %}Download on the App Store{% endtrans %}' src="{{ apple_store_badge() }}" class="apple"></a></p>
|
||||
<li><p>{% trans %}After the installation is complete, you can return to this page and tap the "Open the app" button to continue with the setup:{% endtrans %}</p>
|
||||
<p>
|
||||
{%- call standard_button("exit_to_app", invite.xmpp_uri, class="primary") -%}
|
||||
{% trans %}Open the app{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</p></li>
|
||||
</ol>
|
||||
{#- -#}
|
||||
{%- call standard_button("close", "#", onclick="close_modal(this.parentNode.parentNode); return false;", class="secondary") -%}
|
||||
{% trans %}Close{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
</div>
|
||||
{%- endif -%}
|
||||
<div id="fdroid-popover" class="modal" tabindex="-1" role="dialog" aria-hidden="true" style="display: none;" onclick="close_modal(this); return false;">
|
||||
<div role="document" class="elevated box el-2" onclick="event.stopPropagation();">
|
||||
<header class="modal-title">
|
||||
{#- -#}
|
||||
<span>{% trans %}Install via F-Droid{% endtrans %}</span>
|
||||
{#- -#}
|
||||
{%- call action_button("close", "#", onclick="close_modal(this.parentNode.parentNode.parentNode); return false;", class="tertiary") -%}
|
||||
{% trans %}Close{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</header>
|
||||
<p>{% trans %}After installing Snikket via F-Droid, you have to return to this invite link and tap on "Open the app" to proceed.{% endtrans %}</p>
|
||||
<ol>
|
||||
<li><p>{% trans %}First install Snikket from F-Droid using the button below:{% endtrans %}</p>
|
||||
<p><a href="{{ f_droid_url }}" class="popover" data-popover-id="fdroid-popover"><img alt='{% trans %}Install via F-Droid{% endtrans %}' src='{{ url_for('static', filename='img/f-droid-badge.png') }}' class="fdroid"/></a></p></li>
|
||||
<li><p>{% trans %}After the installation is complete, you can return to this page and tap the "Open the app" button to continue with the setup:{% endtrans %}</p>
|
||||
<p>
|
||||
{%- call standard_button("exit_to_app", invite.xmpp_uri, class="primary") -%}
|
||||
{% trans %}Open the app{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</p></li>
|
||||
</ol>
|
||||
{#- -#}
|
||||
{%- call standard_button("close", "#", onclick="close_modal(this.parentNode.parentNode); return false;", class="secondary") -%}
|
||||
{% trans %}Close{% endtrans %}
|
||||
{%- endcall -%}
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
var catch_popover = function() {
|
||||
open_modal(this);
|
||||
return false;
|
||||
}
|
||||
|
||||
var onload = function() {
|
||||
apply_qr_code(document.getElementById("qr-invite-page"));
|
||||
apply_qr_code(document.getElementById("qr-uri"));
|
||||
var popover_as = document.getElementsByClassName("popover");
|
||||
for (var i = 0; i < popover_as.length; ++i) {
|
||||
var a = popover_as[i];
|
||||
a.onclick = catch_popover;
|
||||
a.href = "#" + a.dataset.popoverId;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
<div class="box warning">{#- -#}
|
||||
<header>{% trans %}Invalid input{% endtrans %}</header>
|
||||
{%- if error_list | length == 1 -%}
|
||||
<p>{{ error_list[0] }}.</p>
|
||||
<p>{{ error_list[0] }}</p>
|
||||
{%- else -%}
|
||||
<ul>
|
||||
{%- for error in error_list -%}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
{% from "library.j2" import box, form_button %}
|
||||
{% from "library.j2" import box, form_button, render_errors %}
|
||||
{% set body_id = "login" %}
|
||||
{% block head_lead %}
|
||||
<title>{{ _("Snikket Login") }}</title>
|
||||
@@ -9,16 +9,16 @@
|
||||
{{ super() }}
|
||||
{% endblock %}
|
||||
{% block body %}
|
||||
<div id="mwrap"><main><div class="form layout-expanded">
|
||||
<div id="mwrap"><div class="filler"></div><main><div class="form layout-expanded">
|
||||
<h1 class="form-title">{{ config["SITE_NAME"] }}</h1>
|
||||
<p class="form-desc">{{ _("Enter your Snikket address and password to manage your account.") }}</p>
|
||||
<form method="POST" action="{{ url_for('.login') }}" name="login">
|
||||
<form method="POST" action="{{ url_for('.login') }}" name="login" id="login-form" onsubmit="return domainCheck();" data-addressid="{{ form.address.id }}" data-domain="{{ config["SNIKKET_DOMAIN"] }}">
|
||||
{{ form.csrf_token }}
|
||||
{% if form.errors %}
|
||||
{% call box("alert", _("Login failed")) %}
|
||||
<p>{{ form.errors.values() | flatten | join(", ")}}</p>
|
||||
{% endcall %}
|
||||
{% endif %}
|
||||
{% call render_errors(form) %}{% endcall %}
|
||||
<div class="box alert" role="alert" style="display: none;" id="id-warning">
|
||||
<header>{% trans %}Incorrect address{% endtrans %}</header>
|
||||
<p>{% trans snikket_domain=config["SNIKKET_DOMAIN"] %}This Snikket service only hosts addresses ending in <em>@{{ snikket_domain }}</em>. Your password was not sent.{% endtrans %}</p>
|
||||
</div>
|
||||
<div class="f-ebox">
|
||||
{{ form.address.label(class="a11y-only") }}
|
||||
{{ form.address(placeholder=form.address.label.text) }}
|
||||
@@ -31,8 +31,22 @@
|
||||
{%- call form_button("login", form.action_signin, class="primary") -%}{% endcall -%}
|
||||
</div>
|
||||
</from>
|
||||
</div></main></div>
|
||||
<footer>
|
||||
<ul><li>{% trans about_url=url_for('.about') %}A <a href="{{ about_url }}">Snikket</a> service{% endtrans %}</li></ul>
|
||||
</footer>
|
||||
<script type="text/javascript">
|
||||
var domainCheck = function() {
|
||||
var form = document.getElementById("login-form");
|
||||
var addressId = form.dataset.addressid;
|
||||
var addressField = document.getElementById(addressId);
|
||||
var domain = form.dataset.domain;
|
||||
var address = addressField.value;
|
||||
var errorBox = document.getElementById("id-warning");
|
||||
if (address.includes("@") && !address.endsWith(domain)) {
|
||||
errorBox.style.display = "block";
|
||||
return false;
|
||||
}
|
||||
errorBox.style.display = "none";
|
||||
return true;
|
||||
};
|
||||
</script>
|
||||
</div></main><div class="filler"></div></div>
|
||||
{%- include "_footer.html" -%}
|
||||
{% endblock %}
|
||||
|
||||
@@ -7,6 +7,25 @@
|
||||
<div class="filler"></div>
|
||||
{% block topbar_right %}{% endblock %}
|
||||
</div>
|
||||
<div id="mwrap"><main>{% block content %}{% endblock %}</main></div>
|
||||
<div id="mwrap">
|
||||
{#- -#}
|
||||
<div class="flashbox" id="flashbox">
|
||||
{%- for category, message in get_flashed_messages(True) -%}
|
||||
<div class="box {{ category }} el-5" role="alert">
|
||||
{% if category == "success" %}
|
||||
<header>{% trans %}Operation successful{% endtrans %}</header>
|
||||
{% elif category == "alert" %}
|
||||
<header>{% trans %}Error{% endtrans %}</header>
|
||||
{% endif %}
|
||||
<p>{{ message }}</p>
|
||||
</div>
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
{#- -#}
|
||||
<main>{% block content %}{% endblock %}</main>
|
||||
{#- -#}
|
||||
<div class="filler"></div>
|
||||
{#- -#}
|
||||
</div>
|
||||
{%- include "_footer.html" -%}
|
||||
{% endblock %}
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
{% extends "app.html" %}
|
||||
{% from "library.j2" import standard_button, form_button %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="form layout-expanded"><form method="POST">
|
||||
<h2 class="form-title">{% trans %}Sign out of the Snikket Web Portal{% endtrans %}</h2>
|
||||
<p class="form-desc">{% trans %}Click below to log yourself out of the web portal. This does not affect any other connected devices.{% endtrans %}</p>
|
||||
{{ form.csrf_token }}
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for("user.index"), class="secondary") -%}
|
||||
{%- call standard_button("back", url_for("user.index"), class="tertiary") -%}
|
||||
{% trans %}Back{% endtrans %}
|
||||
{%- endcall -%}
|
||||
{%- call form_button("logout", form.action_signout, class="primary") %}{% endcall -%}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
{% extends "app.html" %}
|
||||
{% from "library.j2" import standard_button, custom_form_button, render_errors %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="form layout-expanded"><form method="POST">
|
||||
<h1 class="form-title">{% trans %}Change your password{% endtrans %}</h1>
|
||||
@@ -27,7 +24,7 @@
|
||||
<p>{% trans %}After changing your password, you will have to enter the new password on all of your devices.{% endtrans %}</p>
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for('.index'), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call standard_button("back", url_for('.index'), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call custom_form_button("passwd", "", "", class="primary") -%}
|
||||
{% trans %}Change password{% endtrans %}
|
||||
{%- endcall -%}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
{% extends "app.html" %}
|
||||
{% from "library.j2" import standard_button, form_button, avatar with context %}
|
||||
{% block head_lead %}
|
||||
<title>Snikket Web Portal</title>
|
||||
{% endblock %}
|
||||
{% from "library.j2" import standard_button, form_button, render_errors, avatar with context %}
|
||||
{% block content %}
|
||||
<h1>{% trans %}Update your profile{% endtrans %}</h1>
|
||||
<div class="form layout-expanded"><form method="POST" enctype="multipart/form-data">
|
||||
<h2 class="form-title">{% trans %}Profile{% endtrans %}</h2>
|
||||
{{ form.csrf_token }}
|
||||
{% call render_errors(form) %}{% endcall %}
|
||||
<div class="f-ebox">
|
||||
{{ form.nickname.label }}
|
||||
{{ form.nickname(placeholder=user_info.username) }}
|
||||
@@ -16,7 +14,10 @@
|
||||
{{ form.avatar.label }}
|
||||
<div class="avatar-wrap">
|
||||
{%- call avatar(user_info.address, user_info.avatar_hash ) %}{% endcall -%}
|
||||
{{ form.avatar }}
|
||||
{{ form.avatar(accept="image/png",
|
||||
data_maxsize=max_avatar_size,
|
||||
data_warning_header=avatar_too_big_warning_header,
|
||||
data_maxsize_warning=avatar_too_big_warning) }}
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="form-title">{% trans %}Visibility{% endtrans %}</h3>
|
||||
@@ -28,8 +29,27 @@
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="f-bbox">
|
||||
{%- call standard_button("back", url_for('.index'), class="secondary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call standard_button("back", url_for('.index'), class="tertiary") %}{% trans %}Back{% endtrans %}{% endcall -%}
|
||||
{%- call form_button("done", form.action_save, class="primary") %}{% endcall -%}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("{{ form.avatar.id }}").onchange = function() {
|
||||
var maxsize_s = this.dataset.maxsize;
|
||||
var maxsize = parseInt(maxsize_s);
|
||||
var existing_alert = document.getElementById("avatar-alert");
|
||||
if (existing_alert) {
|
||||
existing_alert.parentNode.removeChild(existing_alert);
|
||||
}
|
||||
if (this.files[0].size > maxsize) {
|
||||
var warning_header = this.dataset.warningHeader;
|
||||
var warning_text = this.dataset.maxsizeWarning;
|
||||
this.setCustomValidity(warning_text);
|
||||
this.reportValidity();
|
||||
this.value = null;
|
||||
} else {
|
||||
this.setCustomValidity("");
|
||||
}
|
||||
};
|
||||
</script>
|
||||
</form></div>
|
||||
{% endblock %}
|
||||
|
||||
BIN
snikket_web/translations/da/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/da/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
1432
snikket_web/translations/da/LC_MESSAGES/messages.po
Normal file
1432
snikket_web/translations/da/LC_MESSAGES/messages.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
snikket_web/translations/de/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/de/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: SnikketWeb 0.1.0\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-01-30 12:45+0100\n"
|
||||
"PO-Revision-Date: 2021-01-31 12:54+0000\n"
|
||||
"POT-Creation-Date: 2021-03-25 17:32+0100\n"
|
||||
"PO-Revision-Date: 2021-05-18 13:28+0000\n"
|
||||
"Last-Translator: Jonas Schäfer <jonas@zombofant.net>\n"
|
||||
"Language-Team: German <https://i18n.sotecware.net/projects/snikket/"
|
||||
"web-portal/de/>\n"
|
||||
@@ -17,127 +17,217 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.4.2\n"
|
||||
"X-Generator: Weblate 4.5.1\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Limited"
|
||||
msgstr "Eingeschränkt"
|
||||
|
||||
#: snikket_web/admin.py:64 snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:8
|
||||
msgid "Login name"
|
||||
msgstr "Anmeldename"
|
||||
|
||||
#: snikket_web/admin.py:68 snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr "Anzeigename"
|
||||
|
||||
#: snikket_web/admin.py:72 snikket_web/templates/admin_edit_user.html:33
|
||||
msgid "Access Level"
|
||||
msgstr "Berechtigungen"
|
||||
|
||||
#: snikket_web/admin.py:77
|
||||
msgid "Normal user"
|
||||
msgstr "Normaler Benutzer"
|
||||
|
||||
#: snikket_web/admin.py:78
|
||||
msgid "Administrator"
|
||||
msgstr "Administrator"
|
||||
|
||||
#: snikket_web/admin.py:83
|
||||
msgid "Update user"
|
||||
msgstr "Benutzer ändern"
|
||||
|
||||
#: snikket_web/admin.py:87
|
||||
msgid "Create password reset link"
|
||||
msgstr "Passwort-Link erzeugen"
|
||||
|
||||
#: snikket_web/admin.py:105
|
||||
msgid "Password reset link created"
|
||||
msgstr "Link zum Zurücksetzen des Passwortes erzeugt"
|
||||
|
||||
#: snikket_web/admin.py:120
|
||||
msgid "User information updated."
|
||||
msgstr "Benutzerinformationen gespeichert."
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
msgid "Delete user permanently"
|
||||
msgstr "Benutzer endgültig löschen"
|
||||
|
||||
#: snikket_web/admin.py:129
|
||||
#: snikket_web/admin.py:155
|
||||
msgid "User deleted"
|
||||
msgstr "Benutzer gelöscht"
|
||||
|
||||
#: snikket_web/admin.py:193
|
||||
msgid "Password reset link not found"
|
||||
msgstr "Link zum Zurücksetzen des Passwortes nicht gefunden"
|
||||
|
||||
#: snikket_web/admin.py:205
|
||||
msgid "Password reset link deleted"
|
||||
msgstr "Link gelöscht"
|
||||
|
||||
#: snikket_web/admin.py:225
|
||||
msgid "Invite to circle"
|
||||
msgstr "In Gemeinschaft einladen"
|
||||
|
||||
#: snikket_web/admin.py:135
|
||||
#: snikket_web/admin.py:231
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr "Mindestens eine Gemeinschaft muss ausgewählt sein"
|
||||
|
||||
#: snikket_web/admin.py:140
|
||||
#: snikket_web/admin.py:236
|
||||
msgid "Valid for"
|
||||
msgstr "Gültig für"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
#: snikket_web/admin.py:238
|
||||
msgid "One hour"
|
||||
msgstr "Eine Stunde"
|
||||
|
||||
#: snikket_web/admin.py:143
|
||||
#: snikket_web/admin.py:239
|
||||
msgid "Twelve hours"
|
||||
msgstr "Zwölf Stunden"
|
||||
|
||||
#: snikket_web/admin.py:144
|
||||
#: snikket_web/admin.py:240
|
||||
msgid "One day"
|
||||
msgstr "Ein Tag"
|
||||
|
||||
#: snikket_web/admin.py:145
|
||||
#: snikket_web/admin.py:241
|
||||
msgid "One week"
|
||||
msgstr "Eine Woche"
|
||||
|
||||
#: snikket_web/admin.py:146
|
||||
#: snikket_web/admin.py:242
|
||||
msgid "Four weeks"
|
||||
msgstr "Vier Wochen"
|
||||
|
||||
#: snikket_web/admin.py:152 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:248 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr "Art der Einladung"
|
||||
|
||||
#: snikket_web/admin.py:154 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:250 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr "Einzelperson"
|
||||
|
||||
#: snikket_web/admin.py:155 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:251 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr "Gruppe"
|
||||
|
||||
#: snikket_web/admin.py:161
|
||||
#: snikket_web/admin.py:257
|
||||
msgid "New invitation link"
|
||||
msgstr "Neuer Einladungslink"
|
||||
|
||||
#: snikket_web/admin.py:223
|
||||
#: snikket_web/admin.py:319
|
||||
msgid "Revoke"
|
||||
msgstr "Löschen"
|
||||
|
||||
#: snikket_web/admin.py:283 snikket_web/admin.py:327
|
||||
#: snikket_web/admin.py:343
|
||||
msgid "Invitation created"
|
||||
msgstr "Einladung angelegt"
|
||||
|
||||
#: snikket_web/admin.py:359
|
||||
msgid "No such invitation exists"
|
||||
msgstr "Diese Einladung existiert nicht"
|
||||
|
||||
#: snikket_web/admin.py:374
|
||||
msgid "Invitation revoked"
|
||||
msgstr "Einladung gelöscht"
|
||||
|
||||
#: snikket_web/admin.py:391 snikket_web/admin.py:439
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: snikket_web/admin.py:288 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:396 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr "Gemeinschaft gründen"
|
||||
|
||||
#: snikket_web/admin.py:332
|
||||
#: snikket_web/admin.py:426
|
||||
msgid "Circle created"
|
||||
msgstr "Gemeinschaft gegründet"
|
||||
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "Select user"
|
||||
msgstr "Benutzer auswählen"
|
||||
|
||||
#: snikket_web/admin.py:337
|
||||
#: snikket_web/admin.py:449
|
||||
msgid "Update circle"
|
||||
msgstr "Gemeinschaft ändern"
|
||||
|
||||
#: snikket_web/admin.py:341
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "Delete circle permanently"
|
||||
msgstr "Gemeinschaft endgültig löschen"
|
||||
|
||||
#: snikket_web/admin.py:347
|
||||
#: snikket_web/admin.py:459
|
||||
msgid "Add user"
|
||||
msgstr "Benutzer hinzufügen"
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/admin.py:475
|
||||
msgid "No such circle exists"
|
||||
msgstr "Diese Gemeinschaft existiert nicht"
|
||||
|
||||
#: snikket_web/admin.py:512
|
||||
msgid "Circle data updated"
|
||||
msgstr "Gemeinschaftsdaten aktualisiert"
|
||||
|
||||
#: snikket_web/admin.py:518
|
||||
msgid "Circle deleted"
|
||||
msgstr "Gemeinschaft gelöscht"
|
||||
|
||||
#: snikket_web/admin.py:529
|
||||
msgid "User added to circle"
|
||||
msgstr "Benutzer zur Gemeinschaft hinzugefügt"
|
||||
|
||||
#: snikket_web/admin.py:538
|
||||
msgid "User removed from circle"
|
||||
msgstr "Benutzer aus der Gemeinschaft entfernt"
|
||||
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr "Kern"
|
||||
|
||||
#: snikket_web/invite.py:93
|
||||
#: snikket_web/invite.py:106
|
||||
msgid "Username"
|
||||
msgstr "Benutzername"
|
||||
|
||||
#: snikket_web/invite.py:97 snikket_web/invite.py:164 snikket_web/main.py:41
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr "Passwort"
|
||||
|
||||
#: snikket_web/invite.py:101 snikket_web/invite.py:168
|
||||
#: snikket_web/invite.py:114 snikket_web/invite.py:181
|
||||
msgid "Confirm password"
|
||||
msgstr "Passwort (Bestätigung)"
|
||||
|
||||
#: snikket_web/invite.py:105 snikket_web/invite.py:172
|
||||
msgid "The passwords must match"
|
||||
msgstr "Die Passwörter müssen übereinstimmen"
|
||||
#: snikket_web/invite.py:118 snikket_web/invite.py:185
|
||||
msgid "The passwords must match."
|
||||
msgstr "Die Passwörter müssen übereinstimmen."
|
||||
|
||||
#: snikket_web/invite.py:110
|
||||
#: snikket_web/invite.py:123
|
||||
msgid "Create account"
|
||||
msgstr "Konto anlegen"
|
||||
|
||||
#: snikket_web/invite.py:137
|
||||
msgid "That username is already taken"
|
||||
msgstr "Dieser Benutzername ist bereits belegt"
|
||||
#: snikket_web/invite.py:150
|
||||
msgid "That username is already taken."
|
||||
msgstr "Dieser Benutzername ist bereits belegt."
|
||||
|
||||
#: snikket_web/invite.py:141 snikket_web/invite.py:205
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
msgstr "Die Registrierung wurde aus unbekannten Gründen abgelehnt"
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr "Die Registrierung wurde aus unbekannten Gründen abgelehnt."
|
||||
|
||||
#: snikket_web/invite.py:145
|
||||
msgid "The username is not valid"
|
||||
msgstr "Der Benutzername ist ungültig"
|
||||
#: snikket_web/invite.py:158
|
||||
msgid "The username is not valid."
|
||||
msgstr "Der Benutzername ist ungültig."
|
||||
|
||||
#: snikket_web/invite.py:177 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:32
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:29
|
||||
msgid "Change password"
|
||||
msgstr "Passwort ändern"
|
||||
|
||||
@@ -149,69 +239,96 @@ msgstr "Adresse"
|
||||
msgid "Sign in"
|
||||
msgstr "Anmelden"
|
||||
|
||||
#: snikket_web/main.py:72
|
||||
#: snikket_web/main.py:55
|
||||
msgid "Invalid username or password."
|
||||
msgstr "Benutzername oder Passwort falsch."
|
||||
|
||||
#: snikket_web/user.py:21
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr "Anmeldung erfolgreich!"
|
||||
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr "Aktuelles Passwort"
|
||||
|
||||
#: snikket_web/user.py:26
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr "Neues Passwort"
|
||||
|
||||
#: snikket_web/user.py:31
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr "Neues Passwort (Bestätigung)"
|
||||
|
||||
#: snikket_web/user.py:35
|
||||
msgid "The new passwords must match"
|
||||
msgstr "Die neuen Passwörter müssen übereinstimmen"
|
||||
#: snikket_web/user.py:41
|
||||
msgid "The new passwords must match."
|
||||
msgstr "Die neuen Passwörter müssen übereinstimmen."
|
||||
|
||||
#: snikket_web/user.py:42
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr "Abmelden"
|
||||
|
||||
#: snikket_web/user.py:47
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr "Niemand"
|
||||
|
||||
#: snikket_web/user.py:48
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr "Nur Freunde"
|
||||
|
||||
#: snikket_web/user.py:49
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr "Jeder"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:55
|
||||
msgid "Display name"
|
||||
msgstr "Anzeigename"
|
||||
|
||||
#: snikket_web/user.py:59
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr "Bild"
|
||||
|
||||
#: snikket_web/user.py:63
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr "Profilsichtbarkeit"
|
||||
|
||||
#: snikket_web/user.py:68
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr "Profil bearbeiten"
|
||||
|
||||
#: snikket_web/user.py:93
|
||||
msgid "Incorrect password"
|
||||
msgstr "Ungültiges Passwort"
|
||||
#: snikket_web/user.py:99
|
||||
msgid "Incorrect password."
|
||||
msgstr "Ungültiges Passwort."
|
||||
|
||||
#: snikket_web/templates/_footer.html:4 snikket_web/templates/login.html:36
|
||||
#: snikket_web/user.py:103
|
||||
msgid "Password changed"
|
||||
msgstr "Passwort geändert"
|
||||
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please "
|
||||
"use the app."
|
||||
msgstr ""
|
||||
"Das gewählte Profilbild ist zu groß. Benutze die App um größere Bilder "
|
||||
"hochladen zu können."
|
||||
|
||||
#: snikket_web/user.py:159
|
||||
msgid "Profile updated"
|
||||
msgstr "Profil gespeichert"
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr "Fehler"
|
||||
|
||||
#: snikket_web/templates/_footer.html:4
|
||||
#, python-format
|
||||
msgid "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
msgstr "Ein <a href=\"%(about_url)s\">Snikket</a>-Dienst"
|
||||
|
||||
#: snikket_web/templates/about.html:9
|
||||
#: snikket_web/templates/_footer.html:6
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company."
|
||||
msgstr ""
|
||||
"„Snikket“ und das Papageienlogo sind Markenzeichen der Snikket Community "
|
||||
"Interest Company."
|
||||
|
||||
#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9
|
||||
msgid "About Snikket"
|
||||
msgstr "Über Snikket"
|
||||
|
||||
@@ -271,10 +388,25 @@ msgstr ""
|
||||
"\"%(apache20_url)s\">Apache 2.0 Lizenz</a> bereitgestellt werden."
|
||||
|
||||
#: snikket_web/templates/about.html:17
|
||||
msgid "Trademarks"
|
||||
msgstr "Markenzeichen"
|
||||
|
||||
#: snikket_web/templates/about.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company. For more information about the trademarks, visit the <a href="
|
||||
"\"%(trademarks_url)s\">Snikket Trademarks information page</a>."
|
||||
msgstr ""
|
||||
"„Snikket“ und das Papageienlogo sind Markenzeichen der Snikket Community "
|
||||
"Interest Company. Mehr Informationen über die Markenzeichen gibt es auf der "
|
||||
"<a href=\"%(trademarks_url)s\">„Snikket Trademarks“ Informationsseite</a>."
|
||||
|
||||
#: snikket_web/templates/about.html:19
|
||||
msgid "Software Versions"
|
||||
msgstr "Softwareversionen"
|
||||
|
||||
#: snikket_web/templates/about.html:27
|
||||
#: snikket_web/templates/about.html:29
|
||||
msgid "Back to the main page"
|
||||
msgstr "Zurück zur Hauptseite"
|
||||
|
||||
@@ -315,7 +447,7 @@ msgstr "Mitglieder"
|
||||
|
||||
#: snikket_web/templates/admin_circles.html:15
|
||||
#: snikket_web/templates/admin_invites.html:24
|
||||
#: snikket_web/templates/admin_users.html:12
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Actions"
|
||||
msgstr "Aktionen"
|
||||
|
||||
@@ -353,7 +485,7 @@ msgstr "Neue Gemeinschaft"
|
||||
|
||||
#: snikket_web/templates/admin_create_invite.html:3
|
||||
msgid "Create invitation"
|
||||
msgstr "Gemeinschaft gründen"
|
||||
msgstr "Einladung erzeugen"
|
||||
|
||||
#: snikket_web/templates/admin_create_invite_form.html:5
|
||||
msgid "Create new invitation"
|
||||
@@ -373,7 +505,7 @@ msgid "Debug information for %(user_name)s"
|
||||
msgstr "Debugging-Informationen für %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_debug_user.html:11
|
||||
#: snikket_web/templates/user_passwd.html:26
|
||||
#: snikket_web/templates/user_passwd.html:23
|
||||
msgid "Warning"
|
||||
msgstr "Warnung"
|
||||
|
||||
@@ -390,12 +522,12 @@ msgid "Copy complete output"
|
||||
msgstr "Komplette Ausgabe kopieren"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:4
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, python-format
|
||||
msgid "Delete user %(user_name)s"
|
||||
msgstr "Benutzer %(user_name)s löschen"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:6
|
||||
#: snikket_web/templates/admin_edit_user.html:54
|
||||
msgid "Delete user"
|
||||
msgstr "Benutzer löschen"
|
||||
|
||||
@@ -403,11 +535,6 @@ msgstr "Benutzer löschen"
|
||||
msgid "Are you sure you want to delete the following user?"
|
||||
msgstr "Bist du sicher dass du den folgenden Benutzer löschen willst?"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Login name"
|
||||
msgstr "Anmeldename"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:15
|
||||
msgid "Danger"
|
||||
msgstr "Gefahr"
|
||||
@@ -423,12 +550,10 @@ msgstr ""
|
||||
"keinen Weg zurück!</strong>"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:19
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
#: snikket_web/templates/admin_edit_invite.html:49
|
||||
#: snikket_web/templates/admin_reset_user_password.html:25
|
||||
#: snikket_web/templates/user_logout.html:13
|
||||
#: snikket_web/templates/user_passwd.html:30
|
||||
#: snikket_web/templates/user_profile.html:31
|
||||
#: snikket_web/templates/user_logout.html:10
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_profile.html:32
|
||||
msgid "Back"
|
||||
msgstr "Zurück"
|
||||
|
||||
@@ -462,6 +587,10 @@ msgstr "Gemeinschaftsinformationen"
|
||||
msgid "This circle has no group chat associated."
|
||||
msgstr "Diese Gemeinschaft hat keinen zugehörigen Gruppenchat."
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
msgid "Return to circle list"
|
||||
msgstr "Zurück zur Gemeinschaftsliste"
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:48
|
||||
msgid "Delete circle"
|
||||
msgstr "Gemeinschaft löschen"
|
||||
@@ -506,7 +635,6 @@ msgid "View invitation"
|
||||
msgstr "Einladung anzeigen"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:13
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
#: snikket_web/templates/admin_reset_user_password.html:15
|
||||
msgid "Valid until"
|
||||
msgstr "Gültig bis"
|
||||
@@ -552,6 +680,99 @@ msgstr "Der Benutzer wird als Kontakt von %(peer_jid)s hinzugefügt."
|
||||
msgid "Created"
|
||||
msgstr "Erzeugt"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:48
|
||||
msgid "Return to invitation list"
|
||||
msgstr "Zurück zur Einladungsliste"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:5
|
||||
msgid ""
|
||||
"Limited users can interact with users on the same Snikket service and be "
|
||||
"members of circles."
|
||||
msgstr ""
|
||||
"Eingeschränkte Benutzer können mit anderen Benutzern auf dem selben Snikket-"
|
||||
"Server interagieren und Mitglieder in Gemeinschaften sein."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:7
|
||||
msgid ""
|
||||
"Like limited users and can also interact with users on other Snikket "
|
||||
"services."
|
||||
msgstr ""
|
||||
"Wie eingeschränkte Benutzer, zusätzlich können normale Benutzer auch mit "
|
||||
"Benutzern auf anderen Snikket-Servern interagieren."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:9
|
||||
msgid "Like normal users and can access the admin panel in the web portal."
|
||||
msgstr ""
|
||||
"Wie normale Benutzer, zusätzlich können Administratoren auf den Adminbereich "
|
||||
"zugreifen."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:20
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Edit user %(user_name)s"
|
||||
msgstr "Benutzer %(user_name)s bearbeiten"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:23
|
||||
msgid "Edit user"
|
||||
msgstr "Benutzer bearbeiten"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:27
|
||||
msgid "The login name cannot be changed."
|
||||
msgstr "Der Anmeldename kann nicht geändert werden."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:34
|
||||
msgid ""
|
||||
"The access level of a user determines what interactions are allowed for them "
|
||||
"on your Snikket service."
|
||||
msgstr ""
|
||||
"Die Berechtigungen von Benutzern bestimmen, welche Interaktionen ihnen auf "
|
||||
"deinem Snikket-Server erlaubt sind."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:41
|
||||
#, python-format
|
||||
msgid "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
msgstr "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:51
|
||||
msgid "Return to user list"
|
||||
msgstr "Zurück zur Benutzerliste"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:59
|
||||
msgid "Further actions"
|
||||
msgstr "Weitere Aktionen"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:61
|
||||
msgid "Reset password"
|
||||
msgstr "Passwort zurücksetzen"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:64
|
||||
msgid ""
|
||||
"If the user has lost their password, you can use the button below to create "
|
||||
"a special link which allows to change the password of the account, once."
|
||||
msgstr ""
|
||||
"Wenn ein Benutzer das Passwort verloren oder vergessen hat, kannst du den "
|
||||
"folgenden Button verwenden um einen Link zu erzeugen. Dieser Link erlaubt es "
|
||||
"einmalig, das Passwort des Kontos zu ändern."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:69
|
||||
msgid "Debug information"
|
||||
msgstr "Informationen zur Fehlerbehebung"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:71
|
||||
msgid ""
|
||||
"In some cases, extended information about the user account and the connected "
|
||||
"devices is necessary to troubleshoot issues. The button below reveals this "
|
||||
"(sensitive) information."
|
||||
msgstr ""
|
||||
"In seltenen Fällen kann es vorkommen, dass weiterführende Informationen über "
|
||||
"das Benutzerkonto sowie die verbundenen Geräte erforderlich sind um ein "
|
||||
"Problem zu beheben. Der folgende Button zeigt diese (teilweise vertraulichen)"
|
||||
" Informationen an."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:75
|
||||
msgid "Show debug information"
|
||||
msgstr "Debugging-Informationen anzeigen"
|
||||
|
||||
#: snikket_web/templates/admin_home.html:4
|
||||
msgid "Welcome to the admin panel!"
|
||||
msgstr "Willkommen im Adminbereich!"
|
||||
@@ -604,6 +825,10 @@ msgstr "Adminbereich verlassen"
|
||||
msgid "Pending invitations"
|
||||
msgstr "Ausstehende Einladungen"
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
msgid "Expires"
|
||||
msgstr "Läuft ab"
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:22
|
||||
msgid "Type"
|
||||
msgstr "Art"
|
||||
@@ -645,15 +870,21 @@ msgstr ""
|
||||
msgid "Destroy link"
|
||||
msgstr "Link zerstören"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:25
|
||||
#, python-format
|
||||
msgid "Show debug information for %(user_name)s"
|
||||
msgstr "Debugging-Informationen für %(user_name)s anzeigen"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid "The user is an administrator."
|
||||
msgstr "Der Benutzer ist ein Administrator."
|
||||
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Create password reset link for %(user_name)s"
|
||||
msgstr "Benutzer %(user_name)s löschen"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid " (Administrator)"
|
||||
msgstr " (Administrator)"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid "The user is restricted."
|
||||
msgstr "Dieser Benutzer ist eingeschränkt."
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid " (Restricted)"
|
||||
msgstr " (Eingeschränkt)"
|
||||
|
||||
#: snikket_web/templates/app.html:4
|
||||
msgid "Snikket Web Portal"
|
||||
@@ -689,7 +920,7 @@ msgid "The web portal encountered an internal error."
|
||||
msgstr "Das Webportal hatte einen internen Fehler."
|
||||
|
||||
#: snikket_web/templates/invite_invalid.html:5
|
||||
#: snikket_web/templates/invite_view.html:12
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#, python-format
|
||||
msgid "Invite to %(site_name)s"
|
||||
msgstr "Einladung zu %(site_name)s"
|
||||
@@ -697,7 +928,7 @@ msgstr "Einladung zu %(site_name)s"
|
||||
#: snikket_web/templates/invite_invalid.html:6
|
||||
#: snikket_web/templates/invite_register.html:10
|
||||
#: snikket_web/templates/invite_success.html:11
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#: snikket_web/templates/invite_view.html:14
|
||||
#, python-format
|
||||
msgid "Powered by <img src=\"%(logo_url)s\" alt=\"Snikket\">"
|
||||
msgstr "Betrieben mit <img alt=\"Snikket\" src=\"%(logo_url)s\">"
|
||||
@@ -744,18 +975,20 @@ msgstr ""
|
||||
"innerhalb der App zu machen. Das geht, indem du den folgenden Knopf drückst:"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr "App schon installiert?"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr "App öffnen"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr "Dieser Knopf funktioniert nur, wenn du die App schon installiert hast!"
|
||||
|
||||
@@ -831,8 +1064,8 @@ msgid ""
|
||||
"This page allows you to reset the password of your account, <strong>"
|
||||
"%(account_jid)s</strong>, once."
|
||||
msgstr ""
|
||||
"Diese Seite erlaubt es dir einmalig, das Passwort deines Kontos "
|
||||
"<strong>%(account_jid)s</strong> zurückzusetzen."
|
||||
"Diese Seite erlaubt es dir einmalig, das Passwort deines Kontos <strong>"
|
||||
"%(account_jid)s</strong> zurückzusetzen."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:17
|
||||
msgid "Using the app"
|
||||
@@ -853,7 +1086,7 @@ msgstr ""
|
||||
"Das geht mit Hilfe des Scan-Knopfes in der oberen Leiste."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -869,7 +1102,7 @@ msgstr ""
|
||||
"Du wirst dann aufgefordert, ein neues Passwort für deinen Account einzugeben."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr "Alternativen"
|
||||
|
||||
@@ -917,7 +1150,7 @@ msgstr ""
|
||||
msgid "Invite to %(site_name)s | Snikket"
|
||||
msgstr "Einladung zu %(site_name)s | Snikket"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:15
|
||||
#: snikket_web/templates/invite_view.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat with %(inviter_name)s using Snikket, a secure, "
|
||||
@@ -926,7 +1159,7 @@ msgstr ""
|
||||
"%(inviter_name)s hat dich zum Chatten mit Snikket auf %(site_name)s "
|
||||
"eingeladen, einer sicheren, privatsphärefreundlichen Chat-App."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:17
|
||||
#: snikket_web/templates/invite_view.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat on %(site_name)s using Snikket, a secure, "
|
||||
@@ -935,37 +1168,42 @@ msgstr ""
|
||||
"Dies ist eine Einladung zum Chatten auf %(site_name)s mit Snikket, einer "
|
||||
"sicheren, privatsphärefreundlichen Chat-App."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:19
|
||||
#: snikket_web/templates/invite_view.html:20
|
||||
msgid "Get started"
|
||||
msgstr "Leg los!"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:22
|
||||
msgid "Install the Snikket App on your Android or iOS device."
|
||||
msgstr "Installiere die Snikket-App auf deinem Android- oder iOS-Gerät."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:23
|
||||
#: snikket_web/templates/invite_view.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Install the Snikket App on your Android device (<a href=\"%(ios_info_url)s\" "
|
||||
"rel=\"noopener noreferrer\" target=\"_blank\">iOS coming soon!</a>)."
|
||||
msgstr ""
|
||||
"Installiere die Snikket-App auf deinem Android-Gerät (<a href=\""
|
||||
"%(ios_info_url)s\" rel=\"noopener noreferrer\" target=\"_blank\">iOS folgt "
|
||||
"Installiere die Snikket-App auf deinem Android-Gerät (<a href="
|
||||
"\"%(ios_info_url)s\" rel=\"noopener noreferrer\" target=\"_blank\">iOS folgt "
|
||||
"bald!</a>)."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:27
|
||||
#: snikket_web/templates/invite_view.html:28
|
||||
msgid "Get it on Google Play"
|
||||
msgstr "Von Google Play installieren"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr "Laden im App Store"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:33
|
||||
msgid "Not on mobile?"
|
||||
msgstr "Nicht am Smartphone?"
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr "Hole die App von F-Droid"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:36
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr "An mobiles Gerät übertragen"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
@@ -974,7 +1212,7 @@ msgstr ""
|
||||
"ein Benutzerkonto anzulegen. Falls nicht, tippe einfach auf die folgende "
|
||||
"Schaltfläche."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the button "
|
||||
@@ -986,16 +1224,20 @@ msgstr ""
|
||||
"dass du <a href=\"%(register_url)s\">manuell ein Benutzerkonto anlegen</a> "
|
||||
"musst."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:50
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
msgid "Scan invite code"
|
||||
msgstr "Einladungscode scannen"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:53
|
||||
#: snikket_web/templates/invite_view.html:82
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr "Schließen"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:56
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code with "
|
||||
"your camera. You can use either a QR scanner app or the Snikket app itself."
|
||||
@@ -1004,22 +1246,22 @@ msgstr ""
|
||||
"untenstehenden Code mit deiner Kamera scannst. Dafür kannst du entweder "
|
||||
"einen normalen QR-Scanner nehmen oder die Snikket-App selbst."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:61
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr "Mit einem QR-Code-Scanner"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr "Mit der Snikket-App"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:68
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code below:"
|
||||
msgstr ""
|
||||
"Benutze einen <em>QR-Code</em>-Scanner auf deinem mobilen Gerät um den "
|
||||
"untenstehenden Code zu scannen:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:74
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the 'Scan' "
|
||||
"button at the top."
|
||||
@@ -1027,6 +1269,51 @@ msgstr ""
|
||||
"Installiere die Snikket-App auf deinem mobilen Gerät, öffne sie und tippe "
|
||||
"dann auf den 'Scan'-Knopf in der oberen Leiste."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr "Installation auf iOS"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the App Store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
"Nachdem du Snikket vom App Store heruntergeladen hast musst du zu diesem "
|
||||
"Einladungslink zurückkehren und \"App öffnen\" antippen um fortzufahren."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the App Store using the button below:"
|
||||
msgstr ""
|
||||
"Lade zunächst Snikket aus dem App Store herunter indem du den folgenden "
|
||||
"Button benutzt:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap the "
|
||||
"\"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
"Nachdem die Installation abgeschlossen ist kannst du zu dieser Seite "
|
||||
"zurückkehren und unten auf \"App öffnen\" tippen um die Einrichtung "
|
||||
"abzuschließen:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr "Installation über F-Droid"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite link "
|
||||
"and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
"Nachdem du Snikket über F-Droid installiert hast, musst du auf diese Seite "
|
||||
"zurückkehren und \"App öffnen\" antippen um fortzufahren."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr "Installiere Snikket zunächst aus F-Droid mit dem folgenden Button:"
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr "Link kopieren"
|
||||
@@ -1060,9 +1347,22 @@ msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr ""
|
||||
"Gib deine Snikket-Adresse und -Passwort ein um dein Konto zu verwalten."
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
msgstr "Anmeldung fehlgeschlagen"
|
||||
#: snikket_web/templates/login.html:19
|
||||
msgid "Incorrect address"
|
||||
msgstr "Ungültige Adresse"
|
||||
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in <em>@%(snikket_domain)s</"
|
||||
"em>. Your password was not sent."
|
||||
msgstr ""
|
||||
"Dieser Snikket-Server ist nur für Adressen, die auf <em>@%(snikket_domain)s</"
|
||||
"em> enden zuständig. Dein Passwort wurde nicht abgesendet."
|
||||
|
||||
#: snikket_web/templates/unauth.html:16
|
||||
msgid "Operation successful"
|
||||
msgstr "Aktion erfolgreich"
|
||||
|
||||
#: snikket_web/templates/user_home.html:9
|
||||
msgid "Welcome!"
|
||||
@@ -1098,11 +1398,11 @@ msgstr ""
|
||||
msgid "Admin panel"
|
||||
msgstr "Adminbereich"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:8
|
||||
#: snikket_web/templates/user_logout.html:5
|
||||
msgid "Sign out of the Snikket Web Portal"
|
||||
msgstr "Aus dem Webportal abmelden"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:9
|
||||
#: snikket_web/templates/user_logout.html:6
|
||||
msgid ""
|
||||
"Click below to log yourself out of the web portal. This does not affect any "
|
||||
"other connected devices."
|
||||
@@ -1110,11 +1410,11 @@ msgstr ""
|
||||
"Klicke unten um dich aus dem Webportal abzumelden. Dies betrifft keine "
|
||||
"anderen Geräte von dir."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:8
|
||||
#: snikket_web/templates/user_passwd.html:5
|
||||
msgid "Change your password"
|
||||
msgstr "Ändere dein Passwort"
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:9
|
||||
#: snikket_web/templates/user_passwd.html:6
|
||||
msgid ""
|
||||
"To change your password, you need to provide the current password as well as "
|
||||
"the new one. To reduce the chance of typos, we ask for your new password "
|
||||
@@ -1124,7 +1424,7 @@ msgstr ""
|
||||
"dein neues Passwort angeben. Damit Tippfehler dich nicht aussperren bitten "
|
||||
"wir dich, dein neues Passwort zweimal einzutippen."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_passwd.html:24
|
||||
msgid ""
|
||||
"After changing your password, you will have to enter the new password on all "
|
||||
"of your devices."
|
||||
@@ -1132,19 +1432,19 @@ msgstr ""
|
||||
"Nachdem du das Passwort geändert hast, musst du das neue Passwort auf allen "
|
||||
"Geräten manuell eintragen."
|
||||
|
||||
#: snikket_web/templates/user_profile.html:7
|
||||
#: snikket_web/templates/user_profile.html:4
|
||||
msgid "Update your profile"
|
||||
msgstr "Dein Profil bearbeiten"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:9
|
||||
#: snikket_web/templates/user_profile.html:6
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:22
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
msgid "Visibility"
|
||||
msgstr "Sichtbarkeit"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
#: snikket_web/templates/user_profile.html:24
|
||||
msgid ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
@@ -1152,23 +1452,14 @@ msgstr ""
|
||||
"Hier kannst du einstellen, wer deine Profilinformationen, wie Bild oder "
|
||||
"Anzeigename einsehen kann."
|
||||
|
||||
#~ msgid "Edit user %(user_name)s"
|
||||
#~ msgstr "Benutzer %(user_name)s bearbeiten"
|
||||
#~ msgid "Create password reset link for %(user_name)s"
|
||||
#~ msgstr "Link zum Zurücksetzen des Passwortes von %(user_name)s erzeugen"
|
||||
|
||||
#~ msgid "User information"
|
||||
#~ msgstr "Benutzerinformationen"
|
||||
#~ msgid "Login failed"
|
||||
#~ msgstr "Anmeldung fehlgeschlagen"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If the user has forgotten their password, use the below button to create "
|
||||
#~ "a password reset link. The password reset link can be used once to change "
|
||||
#~ "the password of the account. Transmit the link to the user via a secure "
|
||||
#~ "channel."
|
||||
#~ msgstr ""
|
||||
#~ "Wenn ein Benutzer das Passwort vergessen hat, kannst du den folgenden "
|
||||
#~ "Button benutzen um einen Link zum Zurücksetzen des Passworts zu erzeugen. "
|
||||
#~ "Dieser Link kann dann ein einziges Mal verwendet werden um das Passwort "
|
||||
#~ "des Kontos zu ändern. Lasse den Link dem Benutzer auf einem sicheren "
|
||||
#~ "Übertragungsweg zukommen."
|
||||
#~ msgid "Not on mobile?"
|
||||
#~ msgstr "Nicht am Smartphone?"
|
||||
|
||||
#~ msgid "No users left"
|
||||
#~ msgstr "Keine Benutzer übrig"
|
||||
@@ -1235,8 +1526,5 @@ msgstr ""
|
||||
#~ msgid "Copy operation failed"
|
||||
#~ msgstr "Kopieren fehlgeschlagen"
|
||||
|
||||
#~ msgid "Password change failed"
|
||||
#~ msgstr "Passwortänderung fehlgeschlagen"
|
||||
|
||||
#~ msgid "Allow multiple uses"
|
||||
#~ msgstr "Mehrfach verwendbar"
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-01-30 12:45+0100\n"
|
||||
"POT-Creation-Date: 2021-03-25 17:32+0100\n"
|
||||
"PO-Revision-Date: 2021-02-02 21:01+0000\n"
|
||||
"Last-Translator: riccio <unriccio@email.it>\n"
|
||||
"Language-Team: English (United Kingdom) <https://i18n.sotecware.net/projects/"
|
||||
@@ -20,130 +20,256 @@ msgstr ""
|
||||
"X-Generator: Weblate 4.4.2\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Limited"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:64 snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:8
|
||||
msgid "Login name"
|
||||
msgstr "Login name"
|
||||
|
||||
#: snikket_web/admin.py:68 snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr "Display name"
|
||||
|
||||
#: snikket_web/admin.py:72 snikket_web/templates/admin_edit_user.html:33
|
||||
msgid "Access Level"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:77
|
||||
msgid "Normal user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:78
|
||||
#, fuzzy
|
||||
#| msgid "Admin dashboard"
|
||||
msgid "Administrator"
|
||||
msgstr "Admin dashboard"
|
||||
|
||||
#: snikket_web/admin.py:83
|
||||
#, fuzzy
|
||||
#| msgid "Create circle"
|
||||
msgid "Update user"
|
||||
msgstr "Create circle"
|
||||
|
||||
#: snikket_web/admin.py:87
|
||||
#, fuzzy
|
||||
#| msgid "Create password reset links or delete users."
|
||||
msgid "Create password reset link"
|
||||
msgstr "Create password reset links or delete users."
|
||||
|
||||
#: snikket_web/admin.py:105
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Password reset link created"
|
||||
msgstr "Password reset link for %(user_name)s"
|
||||
|
||||
#: snikket_web/admin.py:120
|
||||
#, fuzzy
|
||||
#| msgid "User information"
|
||||
msgid "User information updated."
|
||||
msgstr "User information"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
msgid "Delete user permanently"
|
||||
msgstr "Delete user permanently"
|
||||
|
||||
#: snikket_web/admin.py:129
|
||||
#: snikket_web/admin.py:155
|
||||
#, fuzzy
|
||||
#| msgid "deleted"
|
||||
msgid "User deleted"
|
||||
msgstr "deleted"
|
||||
|
||||
#: snikket_web/admin.py:193
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Password reset link not found"
|
||||
msgstr "Password reset link for %(user_name)s"
|
||||
|
||||
#: snikket_web/admin.py:205
|
||||
#, fuzzy
|
||||
#| msgid "Create password reset links or delete users."
|
||||
msgid "Password reset link deleted"
|
||||
msgstr "Create password reset links or delete users."
|
||||
|
||||
#: snikket_web/admin.py:225
|
||||
msgid "Invite to circle"
|
||||
msgstr "Invite to circle"
|
||||
|
||||
#: snikket_web/admin.py:135
|
||||
#: snikket_web/admin.py:231
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr "At least one circle must be selected"
|
||||
|
||||
#: snikket_web/admin.py:140
|
||||
#: snikket_web/admin.py:236
|
||||
msgid "Valid for"
|
||||
msgstr "Valid for"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
#: snikket_web/admin.py:238
|
||||
msgid "One hour"
|
||||
msgstr "One hour"
|
||||
|
||||
#: snikket_web/admin.py:143
|
||||
#: snikket_web/admin.py:239
|
||||
msgid "Twelve hours"
|
||||
msgstr "Twelve hours"
|
||||
|
||||
#: snikket_web/admin.py:144
|
||||
#: snikket_web/admin.py:240
|
||||
msgid "One day"
|
||||
msgstr "One day"
|
||||
|
||||
#: snikket_web/admin.py:145
|
||||
#: snikket_web/admin.py:241
|
||||
msgid "One week"
|
||||
msgstr "One week"
|
||||
|
||||
#: snikket_web/admin.py:146
|
||||
#: snikket_web/admin.py:242
|
||||
msgid "Four weeks"
|
||||
msgstr "Four weeks"
|
||||
|
||||
#: snikket_web/admin.py:152 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:248 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr "Invitation type"
|
||||
|
||||
#: snikket_web/admin.py:154 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:250 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:155 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:251 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:161
|
||||
#: snikket_web/admin.py:257
|
||||
msgid "New invitation link"
|
||||
msgstr "New invitation link"
|
||||
|
||||
#: snikket_web/admin.py:223
|
||||
#: snikket_web/admin.py:319
|
||||
msgid "Revoke"
|
||||
msgstr "Revoke"
|
||||
|
||||
#: snikket_web/admin.py:283 snikket_web/admin.py:327
|
||||
#: snikket_web/admin.py:343
|
||||
#, fuzzy
|
||||
#| msgid "Invitation type"
|
||||
msgid "Invitation created"
|
||||
msgstr "Invitation type"
|
||||
|
||||
#: snikket_web/admin.py:359
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "No such invitation exists"
|
||||
msgstr "New invitation link"
|
||||
|
||||
#: snikket_web/admin.py:374
|
||||
#, fuzzy
|
||||
#| msgid "Invitation type"
|
||||
msgid "Invitation revoked"
|
||||
msgstr "Invitation type"
|
||||
|
||||
#: snikket_web/admin.py:391 snikket_web/admin.py:439
|
||||
msgid "Name"
|
||||
msgstr "Name"
|
||||
|
||||
#: snikket_web/admin.py:288 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:396 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr "Create circle"
|
||||
|
||||
#: snikket_web/admin.py:332
|
||||
#: snikket_web/admin.py:426
|
||||
#, fuzzy
|
||||
#| msgid "Circle name"
|
||||
msgid "Circle created"
|
||||
msgstr "Circle name"
|
||||
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "Select user"
|
||||
msgstr "Select user"
|
||||
|
||||
#: snikket_web/admin.py:337
|
||||
#: snikket_web/admin.py:449
|
||||
#, fuzzy
|
||||
#| msgid "Create circle"
|
||||
msgid "Update circle"
|
||||
msgstr "Create circle"
|
||||
|
||||
#: snikket_web/admin.py:341
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "Delete circle permanently"
|
||||
msgstr "Delete circle permanently"
|
||||
|
||||
#: snikket_web/admin.py:347
|
||||
#: snikket_web/admin.py:459
|
||||
msgid "Add user"
|
||||
msgstr "Add user"
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/admin.py:475
|
||||
#, fuzzy
|
||||
#| msgid "No circles"
|
||||
msgid "No such circle exists"
|
||||
msgstr "No circles"
|
||||
|
||||
#: snikket_web/admin.py:512
|
||||
#, fuzzy
|
||||
#| msgid "Circle name"
|
||||
msgid "Circle data updated"
|
||||
msgstr "Circle name"
|
||||
|
||||
#: snikket_web/admin.py:518
|
||||
#, fuzzy
|
||||
#| msgid "deleted"
|
||||
msgid "Circle deleted"
|
||||
msgstr "deleted"
|
||||
|
||||
#: snikket_web/admin.py:529
|
||||
#, fuzzy
|
||||
#| msgid "Invite to circle"
|
||||
msgid "User added to circle"
|
||||
msgstr "Invite to circle"
|
||||
|
||||
#: snikket_web/admin.py:538
|
||||
#, fuzzy
|
||||
#| msgid "Remove user %(username)s from circle"
|
||||
msgid "User removed from circle"
|
||||
msgstr "Remove user %(username)s from circle"
|
||||
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr "Main"
|
||||
|
||||
#: snikket_web/invite.py:93
|
||||
#: snikket_web/invite.py:106
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:97 snikket_web/invite.py:164 snikket_web/main.py:41
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr "Password"
|
||||
|
||||
#: snikket_web/invite.py:101 snikket_web/invite.py:168
|
||||
#: snikket_web/invite.py:114 snikket_web/invite.py:181
|
||||
#, fuzzy
|
||||
#| msgid "Confirm new password"
|
||||
msgid "Confirm password"
|
||||
msgstr "Confirm new password"
|
||||
|
||||
#: snikket_web/invite.py:105 snikket_web/invite.py:172
|
||||
msgid "The passwords must match"
|
||||
#: snikket_web/invite.py:118 snikket_web/invite.py:185
|
||||
#, fuzzy
|
||||
#| msgid "The passwords must match"
|
||||
msgid "The passwords must match."
|
||||
msgstr "The passwords must match"
|
||||
|
||||
#: snikket_web/invite.py:110
|
||||
#: snikket_web/invite.py:123
|
||||
#, fuzzy
|
||||
#| msgid "Create circle"
|
||||
msgid "Create account"
|
||||
msgstr "Create circle"
|
||||
|
||||
#: snikket_web/invite.py:137
|
||||
msgid "That username is already taken"
|
||||
#: snikket_web/invite.py:150
|
||||
msgid "That username is already taken."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:141 snikket_web/invite.py:205
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:145
|
||||
msgid "The username is not valid"
|
||||
#: snikket_web/invite.py:158
|
||||
msgid "The username is not valid."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:177 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:32
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:29
|
||||
msgid "Change password"
|
||||
msgstr "Change password"
|
||||
|
||||
@@ -155,71 +281,102 @@ msgstr "Address"
|
||||
msgid "Sign in"
|
||||
msgstr "Sign in"
|
||||
|
||||
#: snikket_web/main.py:72
|
||||
#: snikket_web/main.py:55
|
||||
#, fuzzy
|
||||
#| msgid "Invalid user name or password."
|
||||
msgid "Invalid username or password."
|
||||
msgstr "Invalid user name or password."
|
||||
|
||||
#: snikket_web/user.py:21
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr "Current password"
|
||||
|
||||
#: snikket_web/user.py:26
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr "New password"
|
||||
|
||||
#: snikket_web/user.py:31
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr "Confirm new password"
|
||||
|
||||
#: snikket_web/user.py:35
|
||||
msgid "The new passwords must match"
|
||||
#: snikket_web/user.py:41
|
||||
#, fuzzy
|
||||
#| msgid "The new passwords must match"
|
||||
msgid "The new passwords must match."
|
||||
msgstr "The new passwords must match"
|
||||
|
||||
#: snikket_web/user.py:42
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr "Sign out"
|
||||
|
||||
#: snikket_web/user.py:47
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr "Nobody"
|
||||
|
||||
#: snikket_web/user.py:48
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr "Friends only"
|
||||
|
||||
#: snikket_web/user.py:49
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr "Everyone"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:55
|
||||
msgid "Display name"
|
||||
msgstr "Display name"
|
||||
|
||||
#: snikket_web/user.py:59
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr "Avatar"
|
||||
|
||||
#: snikket_web/user.py:63
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr "Profile visibility"
|
||||
|
||||
#: snikket_web/user.py:68
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr "Update profile"
|
||||
|
||||
#: snikket_web/user.py:93
|
||||
msgid "Incorrect password"
|
||||
#: snikket_web/user.py:99
|
||||
#, fuzzy
|
||||
#| msgid "Incorrect password"
|
||||
msgid "Incorrect password."
|
||||
msgstr "Incorrect password"
|
||||
|
||||
#: snikket_web/templates/_footer.html:4 snikket_web/templates/login.html:36
|
||||
#: snikket_web/user.py:103
|
||||
#, fuzzy
|
||||
#| msgid "Password change failed"
|
||||
msgid "Password changed"
|
||||
msgstr "Password change failed"
|
||||
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please "
|
||||
"use the app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:159
|
||||
#, fuzzy
|
||||
#| msgid "Profile"
|
||||
msgid "Profile updated"
|
||||
msgstr "Profile"
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/_footer.html:4
|
||||
#, python-format
|
||||
msgid "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
msgstr "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
|
||||
#: snikket_web/templates/about.html:9
|
||||
#: snikket_web/templates/_footer.html:6
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9
|
||||
msgid "About Snikket"
|
||||
msgstr "About Snikket"
|
||||
|
||||
@@ -279,10 +436,22 @@ msgstr ""
|
||||
"\"%(apache20_url)s\">Apache 2.0 License</a>."
|
||||
|
||||
#: snikket_web/templates/about.html:17
|
||||
msgid "Trademarks"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company. For more information about the trademarks, visit the <a href="
|
||||
"\"%(trademarks_url)s\">Snikket Trademarks information page</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:19
|
||||
msgid "Software Versions"
|
||||
msgstr "Software Versions"
|
||||
|
||||
#: snikket_web/templates/about.html:27
|
||||
#: snikket_web/templates/about.html:29
|
||||
msgid "Back to the main page"
|
||||
msgstr "Back to the main page"
|
||||
|
||||
@@ -320,7 +489,7 @@ msgstr "Members"
|
||||
|
||||
#: snikket_web/templates/admin_circles.html:15
|
||||
#: snikket_web/templates/admin_invites.html:24
|
||||
#: snikket_web/templates/admin_users.html:12
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Actions"
|
||||
msgstr "Actions"
|
||||
|
||||
@@ -379,7 +548,7 @@ msgid "Debug information for %(user_name)s"
|
||||
msgstr "Debug information for %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_debug_user.html:11
|
||||
#: snikket_web/templates/user_passwd.html:26
|
||||
#: snikket_web/templates/user_passwd.html:23
|
||||
msgid "Warning"
|
||||
msgstr "Warning"
|
||||
|
||||
@@ -396,12 +565,12 @@ msgid "Copy complete output"
|
||||
msgstr "Copy complete output"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:4
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, python-format
|
||||
msgid "Delete user %(user_name)s"
|
||||
msgstr "Delete user %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:6
|
||||
#: snikket_web/templates/admin_edit_user.html:54
|
||||
msgid "Delete user"
|
||||
msgstr "Delete user"
|
||||
|
||||
@@ -409,11 +578,6 @@ msgstr "Delete user"
|
||||
msgid "Are you sure you want to delete the following user?"
|
||||
msgstr "Are you sure you want to delete the following user?"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Login name"
|
||||
msgstr "Login name"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:15
|
||||
msgid "Danger"
|
||||
msgstr "Danger"
|
||||
@@ -426,12 +590,10 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:19
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
#: snikket_web/templates/admin_edit_invite.html:49
|
||||
#: snikket_web/templates/admin_reset_user_password.html:25
|
||||
#: snikket_web/templates/user_logout.html:13
|
||||
#: snikket_web/templates/user_passwd.html:30
|
||||
#: snikket_web/templates/user_profile.html:31
|
||||
#: snikket_web/templates/user_logout.html:10
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_profile.html:32
|
||||
msgid "Back"
|
||||
msgstr "Back"
|
||||
|
||||
@@ -467,6 +629,10 @@ msgstr "Circle information"
|
||||
msgid "This circle has no group chat associated."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
msgid "Return to circle list"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:48
|
||||
msgid "Delete circle"
|
||||
msgstr "Delete circle"
|
||||
@@ -509,7 +675,6 @@ msgid "View invitation"
|
||||
msgstr "View invitation"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:13
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
#: snikket_web/templates/admin_reset_user_password.html:15
|
||||
msgid "Valid until"
|
||||
msgstr "Valid until"
|
||||
@@ -552,6 +717,105 @@ msgstr ""
|
||||
msgid "Created"
|
||||
msgstr "Created"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:48
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "Return to invitation list"
|
||||
msgstr "New invitation link"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:5
|
||||
msgid ""
|
||||
"Limited users can interact with users on the same Snikket service and be "
|
||||
"members of circles."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:7
|
||||
msgid ""
|
||||
"Like limited users and can also interact with users on other Snikket "
|
||||
"services."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:9
|
||||
msgid "Like normal users and can access the admin panel in the web portal."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:20
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Edit user %(user_name)s"
|
||||
msgstr "Edit user %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:23
|
||||
#, fuzzy
|
||||
#| msgid "Add user"
|
||||
msgid "Edit user"
|
||||
msgstr "Add user"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:27
|
||||
msgid "The login name cannot be changed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:34
|
||||
msgid ""
|
||||
"The access level of a user determines what interactions are allowed for them "
|
||||
"on your Snikket service."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:41
|
||||
#, python-format
|
||||
msgid "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:51
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "Return to user list"
|
||||
msgstr "New invitation link"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:59
|
||||
msgid "Further actions"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:61
|
||||
#, fuzzy
|
||||
#| msgid "Change your password"
|
||||
msgid "Reset password"
|
||||
msgstr "Change your password"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:64
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "If the user has forgotten their password, use the below button to create "
|
||||
#| "a password reset link. The password reset link can be used once to change "
|
||||
#| "the password of the account. Transmit the link to the user via a secure "
|
||||
#| "channel."
|
||||
msgid ""
|
||||
"If the user has lost their password, you can use the button below to create "
|
||||
"a special link which allows to change the password of the account, once."
|
||||
msgstr ""
|
||||
"If the user has forgotten their password, use the below button to create a "
|
||||
"password reset link. The password reset link can be used once to change the "
|
||||
"password of the account. Transmit the link to the user via a secure channel."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:69
|
||||
#, fuzzy
|
||||
#| msgid "User information"
|
||||
msgid "Debug information"
|
||||
msgstr "User information"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:71
|
||||
msgid ""
|
||||
"In some cases, extended information about the user account and the connected "
|
||||
"devices is necessary to troubleshoot issues. The button below reveals this "
|
||||
"(sensitive) information."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:75
|
||||
#, fuzzy
|
||||
#| msgid "Show debug information for %(user_name)s"
|
||||
msgid "Show debug information"
|
||||
msgstr "Show debug information for %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_home.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Welcome to the administration dashboard!"
|
||||
@@ -611,6 +875,10 @@ msgstr ""
|
||||
msgid "Pending invitations"
|
||||
msgstr "Pending invitations"
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
msgid "Expires"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:22
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
@@ -652,15 +920,21 @@ msgstr ""
|
||||
msgid "Destroy link"
|
||||
msgstr "Destroy link"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:25
|
||||
#, python-format
|
||||
msgid "Show debug information for %(user_name)s"
|
||||
msgstr "Show debug information for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid "The user is an administrator."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Create password reset link for %(user_name)s"
|
||||
msgstr "Create password reset link for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid " (Administrator)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid "The user is restricted."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid " (Restricted)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/app.html:4
|
||||
msgid "Snikket Web Portal"
|
||||
@@ -694,7 +968,7 @@ msgid "The web portal encountered an internal error."
|
||||
msgstr "The web portal encountered an internal error."
|
||||
|
||||
#: snikket_web/templates/invite_invalid.html:5
|
||||
#: snikket_web/templates/invite_view.html:12
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#, python-format
|
||||
msgid "Invite to %(site_name)s"
|
||||
msgstr "Invite to %(site_name)s"
|
||||
@@ -702,7 +976,7 @@ msgstr "Invite to %(site_name)s"
|
||||
#: snikket_web/templates/invite_invalid.html:6
|
||||
#: snikket_web/templates/invite_register.html:10
|
||||
#: snikket_web/templates/invite_success.html:11
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#: snikket_web/templates/invite_view.html:14
|
||||
#, python-format
|
||||
msgid "Powered by <img src=\"%(logo_url)s\" alt=\"Snikket\">"
|
||||
msgstr ""
|
||||
@@ -747,18 +1021,20 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr ""
|
||||
|
||||
@@ -851,7 +1127,7 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -863,7 +1139,7 @@ msgid "You will then be prompted to enter a new password for your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr ""
|
||||
|
||||
@@ -907,54 +1183,59 @@ msgstr ""
|
||||
msgid "Invite to %(site_name)s | Snikket"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:15
|
||||
#: snikket_web/templates/invite_view.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat with %(inviter_name)s using Snikket, a secure, "
|
||||
"privacy-friendly chat app on %(site_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:17
|
||||
#: snikket_web/templates/invite_view.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat on %(site_name)s using Snikket, a secure, "
|
||||
"privacy-friendly chat app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:19
|
||||
#: snikket_web/templates/invite_view.html:20
|
||||
msgid "Get started"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:22
|
||||
msgid "Install the Snikket App on your Android or iOS device."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:23
|
||||
#: snikket_web/templates/invite_view.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Install the Snikket App on your Android device (<a href=\"%(ios_info_url)s\" "
|
||||
"rel=\"noopener noreferrer\" target=\"_blank\">iOS coming soon!</a>)."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:27
|
||||
#: snikket_web/templates/invite_view.html:28
|
||||
msgid "Get it on Google Play"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:33
|
||||
msgid "Not on mobile?"
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:36
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the button "
|
||||
@@ -962,42 +1243,82 @@ msgid ""
|
||||
"\">register an account manually</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:50
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
#, fuzzy
|
||||
#| msgid "Show invite details"
|
||||
msgid "Scan invite code"
|
||||
msgstr "Show invite details"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:53
|
||||
#: snikket_web/templates/invite_view.html:82
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:56
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code with "
|
||||
"your camera. You can use either a QR scanner app or the Snikket app itself."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:61
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:68
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:74
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the 'Scan' "
|
||||
"button at the top."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the App Store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the App Store using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap the "
|
||||
"\"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite link "
|
||||
"and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr "Copy link"
|
||||
@@ -1030,9 +1351,22 @@ msgstr "Snikket Login"
|
||||
msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr "Enter your Snikket address and password to manage your account."
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
msgstr "Login failed"
|
||||
#: snikket_web/templates/login.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Incorrect password"
|
||||
msgid "Incorrect address"
|
||||
msgstr "Incorrect password"
|
||||
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in <em>@%(snikket_domain)s</"
|
||||
"em>. Your password was not sent."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/unauth.html:16
|
||||
msgid "Operation successful"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_home.html:9
|
||||
msgid "Welcome!"
|
||||
@@ -1079,11 +1413,11 @@ msgstr "Manage users and invitations of this Snikket service."
|
||||
msgid "Admin panel"
|
||||
msgstr "Admin dashboard"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:8
|
||||
#: snikket_web/templates/user_logout.html:5
|
||||
msgid "Sign out of the Snikket Web Portal"
|
||||
msgstr "Sign out of the Snikket Web Portal"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:9
|
||||
#: snikket_web/templates/user_logout.html:6
|
||||
msgid ""
|
||||
"Click below to log yourself out of the web portal. This does not affect any "
|
||||
"other connected devices."
|
||||
@@ -1091,11 +1425,11 @@ msgstr ""
|
||||
"Click below to log yourself out of the web portal. This does not affect any "
|
||||
"other connected devices."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:8
|
||||
#: snikket_web/templates/user_passwd.html:5
|
||||
msgid "Change your password"
|
||||
msgstr "Change your password"
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:9
|
||||
#: snikket_web/templates/user_passwd.html:6
|
||||
msgid ""
|
||||
"To change your password, you need to provide the current password as well as "
|
||||
"the new one. To reduce the chance of typos, we ask for your new password "
|
||||
@@ -1105,7 +1439,7 @@ msgstr ""
|
||||
"the new one. To reduce the chance of typos, we ask for your new password "
|
||||
"twice."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_passwd.html:24
|
||||
msgid ""
|
||||
"After changing your password, you will have to enter the new password on all "
|
||||
"of your devices."
|
||||
@@ -1113,21 +1447,21 @@ msgstr ""
|
||||
"After changing your password, you will have to enter the new password on all "
|
||||
"of your devices."
|
||||
|
||||
#: snikket_web/templates/user_profile.html:7
|
||||
#: snikket_web/templates/user_profile.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Update profile"
|
||||
msgid "Update your profile"
|
||||
msgstr "Update profile"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:9
|
||||
#: snikket_web/templates/user_profile.html:6
|
||||
msgid "Profile"
|
||||
msgstr "Profile"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:22
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
msgid "Visibility"
|
||||
msgstr "Visibility"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
#: snikket_web/templates/user_profile.html:24
|
||||
msgid ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
@@ -1135,22 +1469,11 @@ msgstr ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
|
||||
#~ msgid "Edit user %(user_name)s"
|
||||
#~ msgstr "Edit user %(user_name)s"
|
||||
#~ msgid "Create password reset link for %(user_name)s"
|
||||
#~ msgstr "Create password reset link for %(user_name)s"
|
||||
|
||||
#~ msgid "User information"
|
||||
#~ msgstr "User information"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If the user has forgotten their password, use the below button to create "
|
||||
#~ "a password reset link. The password reset link can be used once to change "
|
||||
#~ "the password of the account. Transmit the link to the user via a secure "
|
||||
#~ "channel."
|
||||
#~ msgstr ""
|
||||
#~ "If the user has forgotten their password, use the below button to create "
|
||||
#~ "a password reset link. The password reset link can be used once to change "
|
||||
#~ "the password of the account. Transmit the link to the user via a secure "
|
||||
#~ "channel."
|
||||
#~ msgid "Login failed"
|
||||
#~ msgstr "Login failed"
|
||||
|
||||
#~ msgid "No users left"
|
||||
#~ msgstr "No users left"
|
||||
@@ -1214,6 +1537,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Copy operation failed"
|
||||
#~ msgstr "Copy operation failed"
|
||||
|
||||
#~ msgid "Password change failed"
|
||||
#~ msgstr "Password change failed"
|
||||
|
||||
BIN
snikket_web/translations/es_MX/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/es_MX/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
1398
snikket_web/translations/es_MX/LC_MESSAGES/messages.po
Normal file
1398
snikket_web/translations/es_MX/LC_MESSAGES/messages.po
Normal file
File diff suppressed because it is too large
Load Diff
BIN
snikket_web/translations/fr/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/fr/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
BIN
snikket_web/translations/id/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/id/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
@@ -7,8 +7,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-01-30 12:45+0100\n"
|
||||
"PO-Revision-Date: 2021-02-02 21:01+0000\n"
|
||||
"POT-Creation-Date: 2021-03-25 17:32+0100\n"
|
||||
"PO-Revision-Date: 2021-05-19 15:12+0000\n"
|
||||
"Last-Translator: uira <inboxriau@andriana.id>\n"
|
||||
"Language-Team: Indonesian <https://i18n.sotecware.net/projects/snikket/"
|
||||
"web-portal/id/>\n"
|
||||
@@ -17,127 +17,217 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.4.2\n"
|
||||
"X-Generator: Weblate 4.5.1\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Limited"
|
||||
msgstr "Terbatas"
|
||||
|
||||
#: snikket_web/admin.py:64 snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:8
|
||||
msgid "Login name"
|
||||
msgstr "Nama login"
|
||||
|
||||
#: snikket_web/admin.py:68 snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr "Nama tampilan"
|
||||
|
||||
#: snikket_web/admin.py:72 snikket_web/templates/admin_edit_user.html:33
|
||||
msgid "Access Level"
|
||||
msgstr "Level akses"
|
||||
|
||||
#: snikket_web/admin.py:77
|
||||
msgid "Normal user"
|
||||
msgstr "Pengguna normal"
|
||||
|
||||
#: snikket_web/admin.py:78
|
||||
msgid "Administrator"
|
||||
msgstr "Administrator"
|
||||
|
||||
#: snikket_web/admin.py:83
|
||||
msgid "Update user"
|
||||
msgstr "Memperbarui pengguna"
|
||||
|
||||
#: snikket_web/admin.py:87
|
||||
msgid "Create password reset link"
|
||||
msgstr "Buat tautan setel ulang kata sandi"
|
||||
|
||||
#: snikket_web/admin.py:105
|
||||
msgid "Password reset link created"
|
||||
msgstr "Tautan setel ulang kata sandi dibuat"
|
||||
|
||||
#: snikket_web/admin.py:120
|
||||
msgid "User information updated."
|
||||
msgstr "Informasi pengguna diperbarui."
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
msgid "Delete user permanently"
|
||||
msgstr "Hapus permanen pengguna"
|
||||
|
||||
#: snikket_web/admin.py:129
|
||||
#: snikket_web/admin.py:155
|
||||
msgid "User deleted"
|
||||
msgstr "Pengguna dihapus"
|
||||
|
||||
#: snikket_web/admin.py:193
|
||||
msgid "Password reset link not found"
|
||||
msgstr "Tautan setel ulang kata sandi tidak ditemukan"
|
||||
|
||||
#: snikket_web/admin.py:205
|
||||
msgid "Password reset link deleted"
|
||||
msgstr "Tautan setel ulang kata sandi dihapus"
|
||||
|
||||
#: snikket_web/admin.py:225
|
||||
msgid "Invite to circle"
|
||||
msgstr "Undang masuk kelompok"
|
||||
|
||||
#: snikket_web/admin.py:135
|
||||
#: snikket_web/admin.py:231
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr "Minimal satu kelompok harus dipilih"
|
||||
|
||||
#: snikket_web/admin.py:140
|
||||
#: snikket_web/admin.py:236
|
||||
msgid "Valid for"
|
||||
msgstr "Valid selama"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
#: snikket_web/admin.py:238
|
||||
msgid "One hour"
|
||||
msgstr "Satu jam"
|
||||
|
||||
#: snikket_web/admin.py:143
|
||||
#: snikket_web/admin.py:239
|
||||
msgid "Twelve hours"
|
||||
msgstr "Dua belas jam"
|
||||
|
||||
#: snikket_web/admin.py:144
|
||||
#: snikket_web/admin.py:240
|
||||
msgid "One day"
|
||||
msgstr "Satu hari"
|
||||
|
||||
#: snikket_web/admin.py:145
|
||||
#: snikket_web/admin.py:241
|
||||
msgid "One week"
|
||||
msgstr "Satu minggu"
|
||||
|
||||
#: snikket_web/admin.py:146
|
||||
#: snikket_web/admin.py:242
|
||||
msgid "Four weeks"
|
||||
msgstr "Empat minggu"
|
||||
|
||||
#: snikket_web/admin.py:152 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:248 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr "Jenis undangan"
|
||||
|
||||
#: snikket_web/admin.py:154 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:250 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr "Individu"
|
||||
|
||||
#: snikket_web/admin.py:155 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:251 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr "Grup"
|
||||
|
||||
#: snikket_web/admin.py:161
|
||||
#: snikket_web/admin.py:257
|
||||
msgid "New invitation link"
|
||||
msgstr "Tautan undangan baru"
|
||||
|
||||
#: snikket_web/admin.py:223
|
||||
#: snikket_web/admin.py:319
|
||||
msgid "Revoke"
|
||||
msgstr "Batalkan"
|
||||
|
||||
#: snikket_web/admin.py:283 snikket_web/admin.py:327
|
||||
#: snikket_web/admin.py:343
|
||||
msgid "Invitation created"
|
||||
msgstr "Undangan dibuat"
|
||||
|
||||
#: snikket_web/admin.py:359
|
||||
msgid "No such invitation exists"
|
||||
msgstr "Undangan tidak tersedia"
|
||||
|
||||
#: snikket_web/admin.py:374
|
||||
msgid "Invitation revoked"
|
||||
msgstr "Undangan dibatalkan"
|
||||
|
||||
#: snikket_web/admin.py:391 snikket_web/admin.py:439
|
||||
msgid "Name"
|
||||
msgstr "Nama"
|
||||
|
||||
#: snikket_web/admin.py:288 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:396 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr "Buat kelompok"
|
||||
|
||||
#: snikket_web/admin.py:332
|
||||
#: snikket_web/admin.py:426
|
||||
msgid "Circle created"
|
||||
msgstr "Kelompok dibuat"
|
||||
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "Select user"
|
||||
msgstr "Pilih pengguna"
|
||||
|
||||
#: snikket_web/admin.py:337
|
||||
#: snikket_web/admin.py:449
|
||||
msgid "Update circle"
|
||||
msgstr "Memperbarui kelompok"
|
||||
|
||||
#: snikket_web/admin.py:341
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "Delete circle permanently"
|
||||
msgstr "Hapus kelompok secara permanen"
|
||||
|
||||
#: snikket_web/admin.py:347
|
||||
#: snikket_web/admin.py:459
|
||||
msgid "Add user"
|
||||
msgstr "Tambah pengguna"
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/admin.py:475
|
||||
msgid "No such circle exists"
|
||||
msgstr "Kelompok tersebut tidak ada"
|
||||
|
||||
#: snikket_web/admin.py:512
|
||||
msgid "Circle data updated"
|
||||
msgstr "Data kelompok diperbarui"
|
||||
|
||||
#: snikket_web/admin.py:518
|
||||
msgid "Circle deleted"
|
||||
msgstr "Kelompok dihapus"
|
||||
|
||||
#: snikket_web/admin.py:529
|
||||
msgid "User added to circle"
|
||||
msgstr "Pengguna ditambahkan ke kelompok"
|
||||
|
||||
#: snikket_web/admin.py:538
|
||||
msgid "User removed from circle"
|
||||
msgstr "Pengguna dihapus dari kelompok"
|
||||
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr "Utama"
|
||||
|
||||
#: snikket_web/invite.py:93
|
||||
#: snikket_web/invite.py:106
|
||||
msgid "Username"
|
||||
msgstr "Nama pengguna"
|
||||
|
||||
#: snikket_web/invite.py:97 snikket_web/invite.py:164 snikket_web/main.py:41
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr "Kata sandi"
|
||||
|
||||
#: snikket_web/invite.py:101 snikket_web/invite.py:168
|
||||
#: snikket_web/invite.py:114 snikket_web/invite.py:181
|
||||
msgid "Confirm password"
|
||||
msgstr "Konfirmasi kata sandi"
|
||||
|
||||
#: snikket_web/invite.py:105 snikket_web/invite.py:172
|
||||
msgid "The passwords must match"
|
||||
msgstr "Kata sandi harus cocok"
|
||||
#: snikket_web/invite.py:118 snikket_web/invite.py:185
|
||||
msgid "The passwords must match."
|
||||
msgstr "Kata sandi harus cocok."
|
||||
|
||||
#: snikket_web/invite.py:110
|
||||
#: snikket_web/invite.py:123
|
||||
msgid "Create account"
|
||||
msgstr "Buat akun"
|
||||
|
||||
#: snikket_web/invite.py:137
|
||||
msgid "That username is already taken"
|
||||
msgstr "Nama pengguna itu sudah dipakai"
|
||||
#: snikket_web/invite.py:150
|
||||
msgid "That username is already taken."
|
||||
msgstr "Nama pengguna itu sudah dipakai."
|
||||
|
||||
#: snikket_web/invite.py:141 snikket_web/invite.py:205
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
msgstr "Pendaftaran ditolak karena alasan yang tidak diketahui"
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr "Pendaftaran ditolak karena alasan yang tidak diketahui."
|
||||
|
||||
#: snikket_web/invite.py:145
|
||||
msgid "The username is not valid"
|
||||
msgstr "Nama pengguna tidak valid"
|
||||
#: snikket_web/invite.py:158
|
||||
msgid "The username is not valid."
|
||||
msgstr "Nama pengguna tidak valid."
|
||||
|
||||
#: snikket_web/invite.py:177 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:32
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:29
|
||||
msgid "Change password"
|
||||
msgstr "Ganti kata sandi"
|
||||
|
||||
@@ -149,69 +239,96 @@ msgstr "Alamat"
|
||||
msgid "Sign in"
|
||||
msgstr "Masuk"
|
||||
|
||||
#: snikket_web/main.py:72
|
||||
#: snikket_web/main.py:55
|
||||
msgid "Invalid username or password."
|
||||
msgstr "Nama pengguna atau kata sandi salah."
|
||||
|
||||
#: snikket_web/user.py:21
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr "Login berhasil!"
|
||||
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr "Kata sandi sekarang"
|
||||
|
||||
#: snikket_web/user.py:26
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr "Kata sandi baru"
|
||||
|
||||
#: snikket_web/user.py:31
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr "Konfirmasi kata sandi"
|
||||
|
||||
#: snikket_web/user.py:35
|
||||
msgid "The new passwords must match"
|
||||
msgstr "Kata sandi baru harus cocok"
|
||||
#: snikket_web/user.py:41
|
||||
msgid "The new passwords must match."
|
||||
msgstr "Kata sandi baru harus cocok."
|
||||
|
||||
#: snikket_web/user.py:42
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr "Keluar"
|
||||
|
||||
#: snikket_web/user.py:47
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr "Tak seorangpun"
|
||||
|
||||
#: snikket_web/user.py:48
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr "Hanya teman"
|
||||
|
||||
#: snikket_web/user.py:49
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr "Semua orang"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:55
|
||||
msgid "Display name"
|
||||
msgstr "Nama tampilan"
|
||||
|
||||
#: snikket_web/user.py:59
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr "Gambar profil"
|
||||
|
||||
#: snikket_web/user.py:63
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr "Visibilitas profil"
|
||||
|
||||
#: snikket_web/user.py:68
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr "Perbaharui profil"
|
||||
msgstr "Perbarui profil"
|
||||
|
||||
#: snikket_web/user.py:93
|
||||
msgid "Incorrect password"
|
||||
msgstr "Kata sandi salah"
|
||||
#: snikket_web/user.py:99
|
||||
msgid "Incorrect password."
|
||||
msgstr "Kata sandi salah."
|
||||
|
||||
#: snikket_web/templates/_footer.html:4 snikket_web/templates/login.html:36
|
||||
#: snikket_web/user.py:103
|
||||
msgid "Password changed"
|
||||
msgstr "Kata sandi diganti"
|
||||
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please "
|
||||
"use the app."
|
||||
msgstr ""
|
||||
"Avatar yang dipilih terlalu besar. Untuk dapat mengunggah avatar yang lebih "
|
||||
"besar, sila gunakan aplikasi."
|
||||
|
||||
#: snikket_web/user.py:159
|
||||
msgid "Profile updated"
|
||||
msgstr "Profil diperbarui"
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr "Kesalahan"
|
||||
|
||||
#: snikket_web/templates/_footer.html:4
|
||||
#, python-format
|
||||
msgid "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
msgstr "<a href=\"%(about_url)s\">Layanan</a> Snikket"
|
||||
|
||||
#: snikket_web/templates/about.html:9
|
||||
#: snikket_web/templates/_footer.html:6
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company."
|
||||
msgstr ""
|
||||
"“Snikket” dan logo burung beo adalah merek dagang dari Snikket Community "
|
||||
"Interest Company."
|
||||
|
||||
#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9
|
||||
msgid "About Snikket"
|
||||
msgstr "Tentang Snikket"
|
||||
|
||||
@@ -271,10 +388,26 @@ msgstr ""
|
||||
"href=\"%(apache20_url)s\">Lisensi Apache 2.0</a>."
|
||||
|
||||
#: snikket_web/templates/about.html:17
|
||||
msgid "Trademarks"
|
||||
msgstr "Merek dagang"
|
||||
|
||||
#: snikket_web/templates/about.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company. For more information about the trademarks, visit the <a href="
|
||||
"\"%(trademarks_url)s\">Snikket Trademarks information page</a>."
|
||||
msgstr ""
|
||||
"“Snikket” dan logo burung beo adalah merek dagang dari Snikket Community "
|
||||
"Interest Company. Untuk informasi lebih lanjut tentang merek dagang, "
|
||||
"kunjungi <a href=\"%(trademarks_url)s\">halaman informasi merek dagang "
|
||||
"Snikket</a>."
|
||||
|
||||
#: snikket_web/templates/about.html:19
|
||||
msgid "Software Versions"
|
||||
msgstr "Versi perangkat lunak"
|
||||
|
||||
#: snikket_web/templates/about.html:27
|
||||
#: snikket_web/templates/about.html:29
|
||||
msgid "Back to the main page"
|
||||
msgstr "Kembali ke halaman depan"
|
||||
|
||||
@@ -315,7 +448,7 @@ msgstr "Anggota"
|
||||
|
||||
#: snikket_web/templates/admin_circles.html:15
|
||||
#: snikket_web/templates/admin_invites.html:24
|
||||
#: snikket_web/templates/admin_users.html:12
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Actions"
|
||||
msgstr "Tindakan"
|
||||
|
||||
@@ -373,7 +506,7 @@ msgid "Debug information for %(user_name)s"
|
||||
msgstr "Informasi debug untuk %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_debug_user.html:11
|
||||
#: snikket_web/templates/user_passwd.html:26
|
||||
#: snikket_web/templates/user_passwd.html:23
|
||||
msgid "Warning"
|
||||
msgstr "Peringatan"
|
||||
|
||||
@@ -390,12 +523,12 @@ msgid "Copy complete output"
|
||||
msgstr "Salin keluaran lengkap"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:4
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, python-format
|
||||
msgid "Delete user %(user_name)s"
|
||||
msgstr "Hapus pengguna %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:6
|
||||
#: snikket_web/templates/admin_edit_user.html:54
|
||||
msgid "Delete user"
|
||||
msgstr "Hapus pengguna"
|
||||
|
||||
@@ -403,11 +536,6 @@ msgstr "Hapus pengguna"
|
||||
msgid "Are you sure you want to delete the following user?"
|
||||
msgstr "Apakah anda yakin mau menghapus pengguna tersebut?"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Login name"
|
||||
msgstr "Nama login"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:15
|
||||
msgid "Danger"
|
||||
msgstr "Berbahaya"
|
||||
@@ -423,12 +551,10 @@ msgstr ""
|
||||
"strong>"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:19
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
#: snikket_web/templates/admin_edit_invite.html:49
|
||||
#: snikket_web/templates/admin_reset_user_password.html:25
|
||||
#: snikket_web/templates/user_logout.html:13
|
||||
#: snikket_web/templates/user_passwd.html:30
|
||||
#: snikket_web/templates/user_profile.html:31
|
||||
#: snikket_web/templates/user_logout.html:10
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_profile.html:32
|
||||
msgid "Back"
|
||||
msgstr "Kembali"
|
||||
|
||||
@@ -461,6 +587,10 @@ msgstr "Informasi kelompok"
|
||||
msgid "This circle has no group chat associated."
|
||||
msgstr "Kelompok ini tidak memiliki percakapan grup."
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
msgid "Return to circle list"
|
||||
msgstr "Kembali ke daftar circle"
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:48
|
||||
msgid "Delete circle"
|
||||
msgstr "Hapus kelompok"
|
||||
@@ -505,7 +635,6 @@ msgid "View invitation"
|
||||
msgstr "Lihat undangan"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:13
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
#: snikket_web/templates/admin_reset_user_password.html:15
|
||||
msgid "Valid until"
|
||||
msgstr "Valid hingga"
|
||||
@@ -551,6 +680,96 @@ msgstr "Pengguna akan ditambahkan ke kontak %(peer_jid)s."
|
||||
msgid "Created"
|
||||
msgstr "Dibuat"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:48
|
||||
msgid "Return to invitation list"
|
||||
msgstr "Kembali ke daftar undangan"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:5
|
||||
msgid ""
|
||||
"Limited users can interact with users on the same Snikket service and be "
|
||||
"members of circles."
|
||||
msgstr ""
|
||||
"Pengguna terbatas dapat berinteraksi dengan pengguna di layanan Snikket yang "
|
||||
"sama dan menjadi anggota kelompok."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:7
|
||||
msgid ""
|
||||
"Like limited users and can also interact with users on other Snikket "
|
||||
"services."
|
||||
msgstr ""
|
||||
"Seperti pengguna terbatas dan juga dapat berinteraksi dengan pengguna di "
|
||||
"layanan Snikket lain."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:9
|
||||
msgid "Like normal users and can access the admin panel in the web portal."
|
||||
msgstr "Seperti pengguna biasa dan dapat mengakses panel admin di portal web."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:20
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Edit user %(user_name)s"
|
||||
msgstr "Edit pengguna %(user_name)s"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:23
|
||||
msgid "Edit user"
|
||||
msgstr "Edit pengguna"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:27
|
||||
msgid "The login name cannot be changed."
|
||||
msgstr "Nama login tidak dapat diganti."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:34
|
||||
msgid ""
|
||||
"The access level of a user determines what interactions are allowed for them "
|
||||
"on your Snikket service."
|
||||
msgstr ""
|
||||
"Level akses pengguna menentukan interaksi apa yang diizinkan untuk mereka di "
|
||||
"layanan Snikket Anda."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:41
|
||||
#, python-format
|
||||
msgid "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
msgstr "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:51
|
||||
msgid "Return to user list"
|
||||
msgstr "Kembali ke daftar pengguna"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:59
|
||||
msgid "Further actions"
|
||||
msgstr "Tindakan lanjutan"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:61
|
||||
msgid "Reset password"
|
||||
msgstr "Setel kata sandi"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:64
|
||||
msgid ""
|
||||
"If the user has lost their password, you can use the button below to create "
|
||||
"a special link which allows to change the password of the account, once."
|
||||
msgstr ""
|
||||
"Jika pengguna lupa kata sandi, Anda dapat menggunakan tombol di bawah ini "
|
||||
"untuk membuat tautan khusus yang memungkinkan untuk mengubah kata sandi "
|
||||
"akun, sekali."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:69
|
||||
msgid "Debug information"
|
||||
msgstr "Informasi debug"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:71
|
||||
msgid ""
|
||||
"In some cases, extended information about the user account and the connected "
|
||||
"devices is necessary to troubleshoot issues. The button below reveals this "
|
||||
"(sensitive) information."
|
||||
msgstr ""
|
||||
"Dalam beberapa kasus, informasi tambahan tentang akun pengguna dan perangkat "
|
||||
"yang terhubung diperlukan untuk memecahkan masalah. Tombol di bawah "
|
||||
"mengungkapkan informasi (sensitif) ini."
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:75
|
||||
msgid "Show debug information"
|
||||
msgstr "Tampilkan informasi debug"
|
||||
|
||||
#: snikket_web/templates/admin_home.html:4
|
||||
msgid "Welcome to the admin panel!"
|
||||
msgstr "Selamat datang di panel administrator!"
|
||||
@@ -602,6 +821,10 @@ msgstr "Keluar panel administrator"
|
||||
msgid "Pending invitations"
|
||||
msgstr "Undangan menunggu jawaban"
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
msgid "Expires"
|
||||
msgstr "Kadaluarsa"
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:22
|
||||
msgid "Type"
|
||||
msgstr "Jenis"
|
||||
@@ -643,15 +866,21 @@ msgstr ""
|
||||
msgid "Destroy link"
|
||||
msgstr "Hancurkan tautan"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:25
|
||||
#, python-format
|
||||
msgid "Show debug information for %(user_name)s"
|
||||
msgstr "Lihat informasi debug untuk %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid "The user is an administrator."
|
||||
msgstr "Pengguna adalah administrator."
|
||||
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Create password reset link for %(user_name)s"
|
||||
msgstr "Buat tautan setel ulang kata sandi untuk %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid " (Administrator)"
|
||||
msgstr " (Admin)"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid "The user is restricted."
|
||||
msgstr "Pengguna terbatas."
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid " (Restricted)"
|
||||
msgstr " (Terbatas)"
|
||||
|
||||
#: snikket_web/templates/app.html:4
|
||||
msgid "Snikket Web Portal"
|
||||
@@ -685,7 +914,7 @@ msgid "The web portal encountered an internal error."
|
||||
msgstr "Portal web mengalami kesalahan internal."
|
||||
|
||||
#: snikket_web/templates/invite_invalid.html:5
|
||||
#: snikket_web/templates/invite_view.html:12
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#, python-format
|
||||
msgid "Invite to %(site_name)s"
|
||||
msgstr "Undang ke %(site_name)s"
|
||||
@@ -693,7 +922,7 @@ msgstr "Undang ke %(site_name)s"
|
||||
#: snikket_web/templates/invite_invalid.html:6
|
||||
#: snikket_web/templates/invite_register.html:10
|
||||
#: snikket_web/templates/invite_success.html:11
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#: snikket_web/templates/invite_view.html:14
|
||||
#, python-format
|
||||
msgid "Powered by <img src=\"%(logo_url)s\" alt=\"Snikket\">"
|
||||
msgstr "Didukung oleh <img alt=\"Snikket\" src=\"%(logo_url)s\">"
|
||||
@@ -740,18 +969,20 @@ msgstr ""
|
||||
"menggunakan aplikasi dengan mengklik tombol di bawah ini:"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr "Aplikasi sudah dipasang?"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr "Buka aplikasi"
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr "Tombol ini hanya berfungsi jika Anda sudah memasang aplikasinya!"
|
||||
|
||||
@@ -827,8 +1058,8 @@ msgid ""
|
||||
"This page allows you to reset the password of your account, <strong>"
|
||||
"%(account_jid)s</strong>, once."
|
||||
msgstr ""
|
||||
"Halaman ini memungkinkan Anda untuk mengatur ulang kata sandi akun, "
|
||||
"<strong>%(account_jid)s</strong>, sekali."
|
||||
"Halaman ini memungkinkan Anda untuk mengatur ulang kata sandi akun, <strong>"
|
||||
"%(account_jid)s</strong>, sekali."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:17
|
||||
msgid "Using the app"
|
||||
@@ -849,7 +1080,7 @@ msgstr ""
|
||||
"tombol Pindai di bagian atas."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -864,7 +1095,7 @@ msgid "You will then be prompted to enter a new password for your account."
|
||||
msgstr "Anda akan diminta untuk memasukkan kata sandi baru untuk akun Anda."
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr "Alternatif"
|
||||
|
||||
@@ -910,7 +1141,7 @@ msgstr ""
|
||||
msgid "Invite to %(site_name)s | Snikket"
|
||||
msgstr "Mengundang ke %(site_name)s | Snikket"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:15
|
||||
#: snikket_web/templates/invite_view.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat with %(inviter_name)s using Snikket, a secure, "
|
||||
@@ -919,7 +1150,7 @@ msgstr ""
|
||||
"Anda diundang untuk bercakap-cakap dengan %(inviter_name)s menggunakan "
|
||||
"Snikket, aplikasi percakapan yang aman dan ramah privasi di %(site_name)s."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:17
|
||||
#: snikket_web/templates/invite_view.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat on %(site_name)s using Snikket, a secure, "
|
||||
@@ -928,15 +1159,15 @@ msgstr ""
|
||||
"Anda telah diundang untuk bercakap-cakap di %(site_name)s menggunakan "
|
||||
"Snikket, aplikasi percakapan yang aman dan ramah privasi."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:19
|
||||
#: snikket_web/templates/invite_view.html:20
|
||||
msgid "Get started"
|
||||
msgstr "Mulailah"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:22
|
||||
msgid "Install the Snikket App on your Android or iOS device."
|
||||
msgstr "Instal Snikket di perangkat Android atau iOS Anda."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:23
|
||||
#: snikket_web/templates/invite_view.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Install the Snikket App on your Android device (<a href=\"%(ios_info_url)s\" "
|
||||
@@ -945,19 +1176,24 @@ msgstr ""
|
||||
"Instal aplikasi Snikket di perangkat Android anda (<a href=\"%(ios_info_url)s"
|
||||
"\" rel=\"noopener noreferrer\" target=\"_blank\">iOS segera tersedia!</a>)."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:27
|
||||
#: snikket_web/templates/invite_view.html:28
|
||||
msgid "Get it on Google Play"
|
||||
msgstr "Dapatkan di Google Play"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr "Unduh di App Store"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:33
|
||||
msgid "Not on mobile?"
|
||||
msgstr "Bukan di ponsel?"
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr "Dapatkan di F-Droid"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:36
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr "Dikirim ke telepon seluler"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
@@ -965,7 +1201,7 @@ msgstr ""
|
||||
"Setelah instalasi, aplikasi akan terbuka otomatis dan meminta Anda untuk "
|
||||
"membuat akun. Jika tidak, cukup klik tombol di bawah."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the button "
|
||||
@@ -976,16 +1212,20 @@ msgstr ""
|
||||
"XMPP. Jika tombol di atas tidak berfungsi dengan aplikasi, Anda mungkin "
|
||||
"perlu <a href=\"%(register_url)s\">mendaftarkan akun secara manual</a>."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:50
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
msgid "Scan invite code"
|
||||
msgstr "Pindai kode undangan"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:53
|
||||
#: snikket_web/templates/invite_view.html:82
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr "Tutup"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:56
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code with "
|
||||
"your camera. You can use either a QR scanner app or the Snikket app itself."
|
||||
@@ -994,22 +1234,22 @@ msgstr ""
|
||||
"kode dengan kamera. Anda dapat menggunakan aplikasi pemindai QR atau "
|
||||
"aplikasi Snikket."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:61
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr "Menggunakan pemindai kode QR"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr "Menggunakan Snikket"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:68
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code below:"
|
||||
msgstr ""
|
||||
"Gunakan pemindai <em>kode QR</em> di perangkat seluler Anda untuk memindai "
|
||||
"kode di bawah:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:74
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the 'Scan' "
|
||||
"button at the top."
|
||||
@@ -1017,6 +1257,48 @@ msgstr ""
|
||||
"Instal aplikasi Snikket di perangkat seluler Anda, buka, dan ketuk tombol "
|
||||
"'Pindai'."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr "Pasang di iOS"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the App Store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
"Setelah mengunduh Snikket dari App Store, Anda harus kembali ke tautan "
|
||||
"undangan ini dan klik \"Buka aplikasi\" untuk melanjutkan."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the App Store using the button below:"
|
||||
msgstr "Pertama, unduh Snikket dari App Store menggunakan tombol di bawah ini:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap the "
|
||||
"\"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
"Setelah instalasi selesai, Anda dapat kembali ke halaman ini dan mengetuk "
|
||||
"tombol \"Buka aplikasi\" untuk melanjutkan pemasangan:"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr "Install melalui F-Droid"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite link "
|
||||
"and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
"Setelah menginstal Snikket melalui F-Droid, Anda harus kembali ke tautan "
|
||||
"undangan ini dan ketuk \"Buka aplikasi\" untuk melanjutkan."
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr "Pertama install Snikket dari F-Droid menggunakan tombol di bawah ini:"
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr "Salin tautan"
|
||||
@@ -1046,9 +1328,22 @@ msgstr "Login Snikket"
|
||||
msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr "Ketik alamat Snikket dan kata sandinya untuk mengelola akun anda."
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
msgstr "Percobaan masuk gagal"
|
||||
#: snikket_web/templates/login.html:19
|
||||
msgid "Incorrect address"
|
||||
msgstr "Alamat salah"
|
||||
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in <em>@%(snikket_domain)s</"
|
||||
"em>. Your password was not sent."
|
||||
msgstr ""
|
||||
"Layanan Snikket ini hanya menghosting alamat yang diakhiri dengan <em>@"
|
||||
"%(snikket_domain)s</em>. Kata sandi Anda tidak terkirim."
|
||||
|
||||
#: snikket_web/templates/unauth.html:16
|
||||
msgid "Operation successful"
|
||||
msgstr "Operasi berhasil"
|
||||
|
||||
#: snikket_web/templates/user_home.html:9
|
||||
msgid "Welcome!"
|
||||
@@ -1083,11 +1378,11 @@ msgstr "Kelola pengguna, undangan dan kelompok pengguna layanan Snikket."
|
||||
msgid "Admin panel"
|
||||
msgstr "Panel Administrator"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:8
|
||||
#: snikket_web/templates/user_logout.html:5
|
||||
msgid "Sign out of the Snikket Web Portal"
|
||||
msgstr "Keluar dari Portal Web Snikket"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:9
|
||||
#: snikket_web/templates/user_logout.html:6
|
||||
msgid ""
|
||||
"Click below to log yourself out of the web portal. This does not affect any "
|
||||
"other connected devices."
|
||||
@@ -1095,11 +1390,11 @@ msgstr ""
|
||||
"Klik tombol untuk keluar dari portal web. Ini tidak mempengaruhi perangkat "
|
||||
"lain yang terhubung."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:8
|
||||
#: snikket_web/templates/user_passwd.html:5
|
||||
msgid "Change your password"
|
||||
msgstr "Ganti kata sandi anda"
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:9
|
||||
#: snikket_web/templates/user_passwd.html:6
|
||||
msgid ""
|
||||
"To change your password, you need to provide the current password as well as "
|
||||
"the new one. To reduce the chance of typos, we ask for your new password "
|
||||
@@ -1109,7 +1404,7 @@ msgstr ""
|
||||
"baru. Untuk mengurangi kemungkinan salah ketik, kami meminta anda mengetik "
|
||||
"sandi baru dua kali."
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_passwd.html:24
|
||||
msgid ""
|
||||
"After changing your password, you will have to enter the new password on all "
|
||||
"of your devices."
|
||||
@@ -1117,19 +1412,19 @@ msgstr ""
|
||||
"Sesudah penggantian kata sandi, anda perlu memasukkan kata sandi baru ke "
|
||||
"semua perangkat anda."
|
||||
|
||||
#: snikket_web/templates/user_profile.html:7
|
||||
#: snikket_web/templates/user_profile.html:4
|
||||
msgid "Update your profile"
|
||||
msgstr "Perbaharui profil anda"
|
||||
msgstr "Perbarui profil anda"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:9
|
||||
#: snikket_web/templates/user_profile.html:6
|
||||
msgid "Profile"
|
||||
msgstr "Profil"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:22
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
msgid "Visibility"
|
||||
msgstr "Visibilitas"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
#: snikket_web/templates/user_profile.html:24
|
||||
msgid ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
@@ -1137,22 +1432,14 @@ msgstr ""
|
||||
"Bagian ini memungkinkan Anda untuk mengontrol siapa yang bisa melihat profil "
|
||||
"Anda, seperti avatar dan nama panggilan."
|
||||
|
||||
#~ msgid "Edit user %(user_name)s"
|
||||
#~ msgstr "Edit pengguna %(user_name)s"
|
||||
#~ msgid "Create password reset link for %(user_name)s"
|
||||
#~ msgstr "Buat tautan setel ulang kata sandi untuk %(user_name)s"
|
||||
|
||||
#~ msgid "User information"
|
||||
#~ msgstr "Informasi pengguna"
|
||||
#~ msgid "Login failed"
|
||||
#~ msgstr "Percobaan masuk gagal"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If the user has forgotten their password, use the below button to create "
|
||||
#~ "a password reset link. The password reset link can be used once to change "
|
||||
#~ "the password of the account. Transmit the link to the user via a secure "
|
||||
#~ "channel."
|
||||
#~ msgstr ""
|
||||
#~ "Jika pengguna lupa kata sandi, gunakan tombol di bawah untuk membuat "
|
||||
#~ "tautan setel ulang kata sandi. Tautan pengaturan ulang kata sandi dapat "
|
||||
#~ "digunakan satu kali untuk mengubah kata sandi akun. Kirimkan link ke "
|
||||
#~ "pengguna melalui saluran aman."
|
||||
#~ msgid "Not on mobile?"
|
||||
#~ msgstr "Bukan di ponsel?"
|
||||
|
||||
#~ msgid "<label for=\"link-field\">Link</label>"
|
||||
#~ msgstr "<label for=\"link-field\">Tautan</label>"
|
||||
@@ -1223,6 +1510,3 @@ msgstr ""
|
||||
|
||||
#~ msgid "Copy operation failed"
|
||||
#~ msgstr "Proses penyalinan gagal"
|
||||
|
||||
#~ msgid "Password change failed"
|
||||
#~ msgstr "Gagal mengganti kata kunci"
|
||||
|
||||
BIN
snikket_web/translations/it/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/it/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-01-30 12:45+0100\n"
|
||||
"POT-Creation-Date: 2021-03-25 17:32+0100\n"
|
||||
"PO-Revision-Date: 2021-01-28 17:55+0000\n"
|
||||
"Last-Translator: pep <pep@bouah.net>\n"
|
||||
"Language-Team: Japanese <https://i18n.sotecware.net/projects/snikket/web-"
|
||||
@@ -20,124 +20,254 @@ msgstr ""
|
||||
"X-Generator: Weblate 4.4.2\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Limited"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:64 snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:8
|
||||
msgid "Login name"
|
||||
msgstr "ロゲイン名"
|
||||
|
||||
#: snikket_web/admin.py:68 snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr "表示名"
|
||||
|
||||
#: snikket_web/admin.py:72 snikket_web/templates/admin_edit_user.html:33
|
||||
msgid "Access Level"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:77
|
||||
msgid "Normal user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:78
|
||||
#, fuzzy
|
||||
#| msgid "Admin area"
|
||||
msgid "Administrator"
|
||||
msgstr "管理"
|
||||
|
||||
#: snikket_web/admin.py:83
|
||||
#, fuzzy
|
||||
#| msgid "Update circle"
|
||||
msgid "Update user"
|
||||
msgstr "サークルを更新"
|
||||
|
||||
#: snikket_web/admin.py:87
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Create password reset link"
|
||||
msgstr "%(user_name)s のパスワード再設定リンク"
|
||||
|
||||
#: snikket_web/admin.py:105
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Password reset link created"
|
||||
msgstr "%(user_name)s のパスワード再設定リンク"
|
||||
|
||||
#: snikket_web/admin.py:120
|
||||
#, fuzzy
|
||||
#| msgid "User information"
|
||||
msgid "User information updated."
|
||||
msgstr "ユーザー詳細"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
msgid "Delete user permanently"
|
||||
msgstr "ユーザーを削除する"
|
||||
|
||||
#: snikket_web/admin.py:129
|
||||
#: snikket_web/admin.py:155
|
||||
msgid "User deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:193
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Password reset link not found"
|
||||
msgstr "%(user_name)s のパスワード再設定リンク"
|
||||
|
||||
#: snikket_web/admin.py:205
|
||||
#, fuzzy
|
||||
#| msgid "Password reset link for %(user_name)s"
|
||||
msgid "Password reset link deleted"
|
||||
msgstr "%(user_name)s のパスワード再設定リンク"
|
||||
|
||||
#: snikket_web/admin.py:225
|
||||
msgid "Invite to circle"
|
||||
msgstr "サークルに紹介する"
|
||||
|
||||
#: snikket_web/admin.py:135
|
||||
#: snikket_web/admin.py:231
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr "サークルを選択してください"
|
||||
|
||||
#: snikket_web/admin.py:140
|
||||
#: snikket_web/admin.py:236
|
||||
msgid "Valid for"
|
||||
msgstr "有効期限"
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
#: snikket_web/admin.py:238
|
||||
msgid "One hour"
|
||||
msgstr "一時間"
|
||||
|
||||
#: snikket_web/admin.py:143
|
||||
#: snikket_web/admin.py:239
|
||||
msgid "Twelve hours"
|
||||
msgstr "12時間"
|
||||
|
||||
#: snikket_web/admin.py:144
|
||||
#: snikket_web/admin.py:240
|
||||
msgid "One day"
|
||||
msgstr "一日"
|
||||
|
||||
#: snikket_web/admin.py:145
|
||||
#: snikket_web/admin.py:241
|
||||
msgid "One week"
|
||||
msgstr "一週間"
|
||||
|
||||
#: snikket_web/admin.py:146
|
||||
#: snikket_web/admin.py:242
|
||||
msgid "Four weeks"
|
||||
msgstr "4週間"
|
||||
|
||||
#: snikket_web/admin.py:152 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:248 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr "紹介の種類"
|
||||
|
||||
#: snikket_web/admin.py:154 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:250 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr "一回"
|
||||
|
||||
#: snikket_web/admin.py:155 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:251 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr "複数回"
|
||||
|
||||
#: snikket_web/admin.py:161
|
||||
#: snikket_web/admin.py:257
|
||||
msgid "New invitation link"
|
||||
msgstr "新しい紹介状"
|
||||
|
||||
#: snikket_web/admin.py:223
|
||||
#: snikket_web/admin.py:319
|
||||
msgid "Revoke"
|
||||
msgstr "取り消す"
|
||||
|
||||
#: snikket_web/admin.py:283 snikket_web/admin.py:327
|
||||
#: snikket_web/admin.py:343
|
||||
#, fuzzy
|
||||
#| msgid "Invitation type"
|
||||
msgid "Invitation created"
|
||||
msgstr "紹介の種類"
|
||||
|
||||
#: snikket_web/admin.py:359
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "No such invitation exists"
|
||||
msgstr "新しい紹介状"
|
||||
|
||||
#: snikket_web/admin.py:374
|
||||
#, fuzzy
|
||||
#| msgid "Invitation type"
|
||||
msgid "Invitation revoked"
|
||||
msgstr "紹介の種類"
|
||||
|
||||
#: snikket_web/admin.py:391 snikket_web/admin.py:439
|
||||
msgid "Name"
|
||||
msgstr "名"
|
||||
|
||||
#: snikket_web/admin.py:288 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:396 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr "サークルを作成"
|
||||
|
||||
#: snikket_web/admin.py:332
|
||||
#: snikket_web/admin.py:426
|
||||
#, fuzzy
|
||||
#| msgid "Circle name"
|
||||
msgid "Circle created"
|
||||
msgstr "サークル名"
|
||||
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "Select user"
|
||||
msgstr "ユーザー選択"
|
||||
|
||||
#: snikket_web/admin.py:337
|
||||
#: snikket_web/admin.py:449
|
||||
msgid "Update circle"
|
||||
msgstr "サークルを更新"
|
||||
|
||||
#: snikket_web/admin.py:341
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "Delete circle permanently"
|
||||
msgstr "サークルを削除"
|
||||
|
||||
#: snikket_web/admin.py:347
|
||||
#: snikket_web/admin.py:459
|
||||
msgid "Add user"
|
||||
msgstr "ユーザーを追加する"
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/admin.py:475
|
||||
#, fuzzy
|
||||
#| msgid "No circles"
|
||||
msgid "No such circle exists"
|
||||
msgstr "なし"
|
||||
|
||||
#: snikket_web/admin.py:512
|
||||
#, fuzzy
|
||||
#| msgid "Circle name"
|
||||
msgid "Circle data updated"
|
||||
msgstr "サークル名"
|
||||
|
||||
#: snikket_web/admin.py:518
|
||||
#, fuzzy
|
||||
#| msgid "Circle members"
|
||||
msgid "Circle deleted"
|
||||
msgstr "サークル会員"
|
||||
|
||||
#: snikket_web/admin.py:529
|
||||
#, fuzzy
|
||||
#| msgid "Invite to circle"
|
||||
msgid "User added to circle"
|
||||
msgstr "サークルに紹介する"
|
||||
|
||||
#: snikket_web/admin.py:538
|
||||
#, fuzzy
|
||||
#| msgid "Remove user %(username)s from circle"
|
||||
msgid "User removed from circle"
|
||||
msgstr "%(username)s をサークルから外す"
|
||||
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr "第一サークル"
|
||||
|
||||
#: snikket_web/invite.py:93
|
||||
#: snikket_web/invite.py:106
|
||||
msgid "Username"
|
||||
msgstr "ユーザー名"
|
||||
|
||||
#: snikket_web/invite.py:97 snikket_web/invite.py:164 snikket_web/main.py:41
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr "パスワード"
|
||||
|
||||
#: snikket_web/invite.py:101 snikket_web/invite.py:168
|
||||
#: snikket_web/invite.py:114 snikket_web/invite.py:181
|
||||
msgid "Confirm password"
|
||||
msgstr "確認用パスワード"
|
||||
|
||||
#: snikket_web/invite.py:105 snikket_web/invite.py:172
|
||||
msgid "The passwords must match"
|
||||
#: snikket_web/invite.py:118 snikket_web/invite.py:185
|
||||
#, fuzzy
|
||||
#| msgid "The passwords must match"
|
||||
msgid "The passwords must match."
|
||||
msgstr "確認用パスワードが一致しません"
|
||||
|
||||
#: snikket_web/invite.py:110
|
||||
#: snikket_web/invite.py:123
|
||||
msgid "Create account"
|
||||
msgstr "アカウント作成"
|
||||
|
||||
#: snikket_web/invite.py:137
|
||||
msgid "That username is already taken"
|
||||
#: snikket_web/invite.py:150
|
||||
#, fuzzy
|
||||
#| msgid "That username is already taken"
|
||||
msgid "That username is already taken."
|
||||
msgstr "このユーザー名は存在しています"
|
||||
|
||||
#: snikket_web/invite.py:141 snikket_web/invite.py:205
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
#, fuzzy
|
||||
#| msgid "Registration was declined for unknown reasons"
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr "理由不明の登録エラー"
|
||||
|
||||
#: snikket_web/invite.py:145
|
||||
msgid "The username is not valid"
|
||||
#: snikket_web/invite.py:158
|
||||
#, fuzzy
|
||||
#| msgid "The username is not valid"
|
||||
msgid "The username is not valid."
|
||||
msgstr "ユーザー名が不正"
|
||||
|
||||
#: snikket_web/invite.py:177 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:32
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:29
|
||||
msgid "Change password"
|
||||
msgstr "パスワード変更"
|
||||
|
||||
@@ -149,69 +279,100 @@ msgstr "アドレス"
|
||||
msgid "Sign in"
|
||||
msgstr "サインイン"
|
||||
|
||||
#: snikket_web/main.py:72
|
||||
#: snikket_web/main.py:55
|
||||
msgid "Invalid username or password."
|
||||
msgstr "ユーザー名またはパスワードが不正。"
|
||||
|
||||
#: snikket_web/user.py:21
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr "現在のパスワード"
|
||||
|
||||
#: snikket_web/user.py:26
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr "新しいパスワード"
|
||||
|
||||
#: snikket_web/user.py:31
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr "新しいパスワードの確認"
|
||||
|
||||
#: snikket_web/user.py:35
|
||||
msgid "The new passwords must match"
|
||||
#: snikket_web/user.py:41
|
||||
#, fuzzy
|
||||
#| msgid "The new passwords must match"
|
||||
msgid "The new passwords must match."
|
||||
msgstr "新しいパスワードが不一致"
|
||||
|
||||
#: snikket_web/user.py:42
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr "サインアウト"
|
||||
|
||||
#: snikket_web/user.py:47
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:48
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr "コンタクト限定"
|
||||
|
||||
#: snikket_web/user.py:49
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr "全員"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:55
|
||||
msgid "Display name"
|
||||
msgstr "表示名"
|
||||
|
||||
#: snikket_web/user.py:59
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr "アバター"
|
||||
|
||||
#: snikket_web/user.py:63
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:68
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr "プロファイル管理"
|
||||
|
||||
#: snikket_web/user.py:93
|
||||
msgid "Incorrect password"
|
||||
#: snikket_web/user.py:99
|
||||
#, fuzzy
|
||||
#| msgid "Incorrect password"
|
||||
msgid "Incorrect password."
|
||||
msgstr "パスワード不正"
|
||||
|
||||
#: snikket_web/templates/_footer.html:4 snikket_web/templates/login.html:36
|
||||
#: snikket_web/user.py:103
|
||||
#, fuzzy
|
||||
#| msgid "Password reset"
|
||||
msgid "Password changed"
|
||||
msgstr "パスワード再設定"
|
||||
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please "
|
||||
"use the app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:159
|
||||
#, fuzzy
|
||||
#| msgid "Profile"
|
||||
msgid "Profile updated"
|
||||
msgstr "プロファイル"
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/_footer.html:4
|
||||
#, python-format
|
||||
msgid "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:9
|
||||
#: snikket_web/templates/_footer.html:6
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9
|
||||
msgid "About Snikket"
|
||||
msgstr "Snikketについて"
|
||||
|
||||
@@ -262,10 +423,22 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:17
|
||||
msgid "Trademarks"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community Interest "
|
||||
"Company. For more information about the trademarks, visit the <a href="
|
||||
"\"%(trademarks_url)s\">Snikket Trademarks information page</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:19
|
||||
msgid "Software Versions"
|
||||
msgstr "ソフトウェアバーション"
|
||||
|
||||
#: snikket_web/templates/about.html:27
|
||||
#: snikket_web/templates/about.html:29
|
||||
msgid "Back to the main page"
|
||||
msgstr "戻る"
|
||||
|
||||
@@ -301,7 +474,7 @@ msgstr "サークル員"
|
||||
|
||||
#: snikket_web/templates/admin_circles.html:15
|
||||
#: snikket_web/templates/admin_invites.html:24
|
||||
#: snikket_web/templates/admin_users.html:12
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Actions"
|
||||
msgstr "操作"
|
||||
|
||||
@@ -355,7 +528,7 @@ msgid "Debug information for %(user_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_debug_user.html:11
|
||||
#: snikket_web/templates/user_passwd.html:26
|
||||
#: snikket_web/templates/user_passwd.html:23
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
@@ -372,12 +545,12 @@ msgid "Copy complete output"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:4
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, python-format
|
||||
msgid "Delete user %(user_name)s"
|
||||
msgstr "%(user_name)s を削除"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:6
|
||||
#: snikket_web/templates/admin_edit_user.html:54
|
||||
msgid "Delete user"
|
||||
msgstr "ユーザー削除"
|
||||
|
||||
@@ -385,11 +558,6 @@ msgstr "ユーザー削除"
|
||||
msgid "Are you sure you want to delete the following user?"
|
||||
msgstr "本当にこのユーザーを削除していいですか?"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Login name"
|
||||
msgstr "ロゲイン名"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:15
|
||||
msgid "Danger"
|
||||
msgstr "警告"
|
||||
@@ -404,12 +572,10 @@ msgstr ""
|
||||
"strong>"
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:19
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
#: snikket_web/templates/admin_edit_invite.html:49
|
||||
#: snikket_web/templates/admin_reset_user_password.html:25
|
||||
#: snikket_web/templates/user_logout.html:13
|
||||
#: snikket_web/templates/user_passwd.html:30
|
||||
#: snikket_web/templates/user_profile.html:31
|
||||
#: snikket_web/templates/user_logout.html:10
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_profile.html:32
|
||||
msgid "Back"
|
||||
msgstr "戻る"
|
||||
|
||||
@@ -441,6 +607,10 @@ msgstr "詳細"
|
||||
msgid "This circle has no group chat associated."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
msgid "Return to circle list"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:48
|
||||
msgid "Delete circle"
|
||||
msgstr "サークル削除"
|
||||
@@ -483,7 +653,6 @@ msgid "View invitation"
|
||||
msgstr "紹介状表示"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:13
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
#: snikket_web/templates/admin_reset_user_password.html:15
|
||||
msgid "Valid until"
|
||||
msgstr "有効期限"
|
||||
@@ -525,6 +694,96 @@ msgstr ""
|
||||
msgid "Created"
|
||||
msgstr "作成時"
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:48
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "Return to invitation list"
|
||||
msgstr "新しい紹介状"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:5
|
||||
msgid ""
|
||||
"Limited users can interact with users on the same Snikket service and be "
|
||||
"members of circles."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:7
|
||||
msgid ""
|
||||
"Like limited users and can also interact with users on other Snikket "
|
||||
"services."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:9
|
||||
msgid "Like normal users and can access the admin panel in the web portal."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:20
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Edit user %(user_name)s"
|
||||
msgstr "%(user_name)s を更新"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:23
|
||||
#, fuzzy
|
||||
#| msgid "Add user"
|
||||
msgid "Edit user"
|
||||
msgstr "ユーザーを追加する"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:27
|
||||
msgid "The login name cannot be changed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:34
|
||||
msgid ""
|
||||
"The access level of a user determines what interactions are allowed for them "
|
||||
"on your Snikket service."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:41
|
||||
#, python-format
|
||||
msgid "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:51
|
||||
#, fuzzy
|
||||
#| msgid "New invitation link"
|
||||
msgid "Return to user list"
|
||||
msgstr "新しい紹介状"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:59
|
||||
msgid "Further actions"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:61
|
||||
#, fuzzy
|
||||
#| msgid "Change your password"
|
||||
msgid "Reset password"
|
||||
msgstr "パスワード変更"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:64
|
||||
msgid ""
|
||||
"If the user has lost their password, you can use the button below to create "
|
||||
"a special link which allows to change the password of the account, once."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:69
|
||||
#, fuzzy
|
||||
#| msgid "User information"
|
||||
msgid "Debug information"
|
||||
msgstr "ユーザー詳細"
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:71
|
||||
msgid ""
|
||||
"In some cases, extended information about the user account and the connected "
|
||||
"devices is necessary to troubleshoot issues. The button below reveals this "
|
||||
"(sensitive) information."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:75
|
||||
#, fuzzy
|
||||
#| msgid "User information"
|
||||
msgid "Show debug information"
|
||||
msgstr "ユーザー詳細"
|
||||
|
||||
#: snikket_web/templates/admin_home.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Back to the main page"
|
||||
@@ -588,6 +847,10 @@ msgstr ""
|
||||
msgid "Pending invitations"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
msgid "Expires"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:22
|
||||
msgid "Type"
|
||||
msgstr "種類"
|
||||
@@ -627,14 +890,24 @@ msgstr "このリンクはパスワードを一回きり再設定可能にする
|
||||
msgid "Destroy link"
|
||||
msgstr "リンク取り消す"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:25
|
||||
#, python-format
|
||||
msgid "Show debug information for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
#, fuzzy
|
||||
#| msgid "The username is not valid"
|
||||
msgid "The user is an administrator."
|
||||
msgstr "ユーザー名が不正"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid " (Administrator)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Create password reset link for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, fuzzy
|
||||
#| msgid "The username is not valid"
|
||||
msgid "The user is restricted."
|
||||
msgstr "ユーザー名が不正"
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid " (Restricted)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/app.html:4
|
||||
@@ -669,7 +942,7 @@ msgid "The web portal encountered an internal error."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_invalid.html:5
|
||||
#: snikket_web/templates/invite_view.html:12
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#, python-format
|
||||
msgid "Invite to %(site_name)s"
|
||||
msgstr "%(site_name)s に紹介する"
|
||||
@@ -677,7 +950,7 @@ msgstr "%(site_name)s に紹介する"
|
||||
#: snikket_web/templates/invite_invalid.html:6
|
||||
#: snikket_web/templates/invite_register.html:10
|
||||
#: snikket_web/templates/invite_success.html:11
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#: snikket_web/templates/invite_view.html:14
|
||||
#, python-format
|
||||
msgid "Powered by <img src=\"%(logo_url)s\" alt=\"Snikket\">"
|
||||
msgstr "Powered by <img alt=\"Snikket\" src=\"%(logo_url)s\">"
|
||||
@@ -720,18 +993,20 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr ""
|
||||
|
||||
@@ -824,7 +1099,7 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -836,7 +1111,7 @@ msgid "You will then be prompted to enter a new password for your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr ""
|
||||
|
||||
@@ -881,54 +1156,59 @@ msgstr ""
|
||||
msgid "Invite to %(site_name)s | Snikket"
|
||||
msgstr "%(site_name)s に紹介 | Snikket"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:15
|
||||
#: snikket_web/templates/invite_view.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat with %(inviter_name)s using Snikket, a secure, "
|
||||
"privacy-friendly chat app on %(site_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:17
|
||||
#: snikket_web/templates/invite_view.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat on %(site_name)s using Snikket, a secure, "
|
||||
"privacy-friendly chat app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:19
|
||||
#: snikket_web/templates/invite_view.html:20
|
||||
msgid "Get started"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:22
|
||||
msgid "Install the Snikket App on your Android or iOS device."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:23
|
||||
#: snikket_web/templates/invite_view.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Install the Snikket App on your Android device (<a href=\"%(ios_info_url)s\" "
|
||||
"rel=\"noopener noreferrer\" target=\"_blank\">iOS coming soon!</a>)."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:27
|
||||
#: snikket_web/templates/invite_view.html:28
|
||||
msgid "Get it on Google Play"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:33
|
||||
msgid "Not on mobile?"
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:36
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the button "
|
||||
@@ -936,40 +1216,80 @@ msgid ""
|
||||
"\">register an account manually</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:50
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
msgid "Scan invite code"
|
||||
msgstr "紹介状をスキャン"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:53
|
||||
#: snikket_web/templates/invite_view.html:82
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr "閉める"
|
||||
|
||||
#: snikket_web/templates/invite_view.html:56
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code with "
|
||||
"your camera. You can use either a QR scanner app or the Snikket app itself."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:61
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:68
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:74
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the 'Scan' "
|
||||
"button at the top."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the App Store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the App Store using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap the "
|
||||
"\"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite link "
|
||||
"and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr "リンクをコピーする"
|
||||
@@ -998,8 +1318,21 @@ msgstr "Snikket ログイン"
|
||||
msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
#: snikket_web/templates/login.html:19
|
||||
#, fuzzy
|
||||
#| msgid "Incorrect password"
|
||||
msgid "Incorrect address"
|
||||
msgstr "パスワード不正"
|
||||
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in <em>@%(snikket_domain)s</"
|
||||
"em>. Your password was not sent."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/unauth.html:16
|
||||
msgid "Operation successful"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_home.html:9
|
||||
@@ -1045,59 +1378,53 @@ msgstr ""
|
||||
msgid "Admin panel"
|
||||
msgstr "管理"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:8
|
||||
#: snikket_web/templates/user_logout.html:5
|
||||
msgid "Sign out of the Snikket Web Portal"
|
||||
msgstr "Snikket ホームページからログアウト"
|
||||
|
||||
#: snikket_web/templates/user_logout.html:9
|
||||
#: snikket_web/templates/user_logout.html:6
|
||||
msgid ""
|
||||
"Click below to log yourself out of the web portal. This does not affect any "
|
||||
"other connected devices."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:8
|
||||
#: snikket_web/templates/user_passwd.html:5
|
||||
msgid "Change your password"
|
||||
msgstr "パスワード変更"
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:9
|
||||
#: snikket_web/templates/user_passwd.html:6
|
||||
msgid ""
|
||||
"To change your password, you need to provide the current password as well as "
|
||||
"the new one. To reduce the chance of typos, we ask for your new password "
|
||||
"twice."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_passwd.html:24
|
||||
msgid ""
|
||||
"After changing your password, you will have to enter the new password on all "
|
||||
"of your devices."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:7
|
||||
#: snikket_web/templates/user_profile.html:4
|
||||
#, fuzzy
|
||||
#| msgid "Update profile"
|
||||
msgid "Update your profile"
|
||||
msgstr "プロファイル管理"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:9
|
||||
#: snikket_web/templates/user_profile.html:6
|
||||
msgid "Profile"
|
||||
msgstr "プロファイル"
|
||||
|
||||
#: snikket_web/templates/user_profile.html:22
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
msgid "Visibility"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
#: snikket_web/templates/user_profile.html:24
|
||||
msgid ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
msgstr ""
|
||||
|
||||
#~ msgid "Edit user %(user_name)s"
|
||||
#~ msgstr "%(user_name)s を更新"
|
||||
|
||||
#~ msgid "User information"
|
||||
#~ msgstr "ユーザー詳細"
|
||||
|
||||
#~ msgid "This circle cannot be modified"
|
||||
#~ msgstr "このサークルの更新ができません"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PROJECT VERSION\n"
|
||||
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
||||
"POT-Creation-Date: 2021-01-30 12:45+0100\n"
|
||||
"POT-Creation-Date: 2021-03-25 17:32+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -17,124 +17,214 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Generated-By: Babel 2.9.0\n"
|
||||
|
||||
#: snikket_web/admin.py:60
|
||||
msgid "Delete user permanently"
|
||||
#: snikket_web/admin.py:59
|
||||
msgid "Limited"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:129
|
||||
msgid "Invite to circle"
|
||||
#: snikket_web/admin.py:64 snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:8
|
||||
msgid "Login name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:135
|
||||
msgid "At least one circle must be selected"
|
||||
#: snikket_web/admin.py:68 snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:9 snikket_web/user.py:61
|
||||
msgid "Display name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:140
|
||||
msgid "Valid for"
|
||||
#: snikket_web/admin.py:72 snikket_web/templates/admin_edit_user.html:33
|
||||
msgid "Access Level"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:77
|
||||
msgid "Normal user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:78
|
||||
msgid "Administrator"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:83
|
||||
msgid "Update user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:87
|
||||
msgid "Create password reset link"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:105
|
||||
msgid "Password reset link created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:120
|
||||
msgid "User information updated."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:142
|
||||
msgid "Delete user permanently"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:155
|
||||
msgid "User deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:193
|
||||
msgid "Password reset link not found"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:205
|
||||
msgid "Password reset link deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:225
|
||||
msgid "Invite to circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:231
|
||||
msgid "At least one circle must be selected"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:236
|
||||
msgid "Valid for"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:238
|
||||
msgid "One hour"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:143
|
||||
#: snikket_web/admin.py:239
|
||||
msgid "Twelve hours"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:144
|
||||
#: snikket_web/admin.py:240
|
||||
msgid "One day"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:145
|
||||
#: snikket_web/admin.py:241
|
||||
msgid "One week"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:146
|
||||
#: snikket_web/admin.py:242
|
||||
msgid "Four weeks"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:152 snikket_web/templates/admin_edit_invite.html:17
|
||||
#: snikket_web/admin.py:248 snikket_web/templates/admin_edit_invite.html:17
|
||||
msgid "Invitation type"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:154 snikket_web/templates/library.j2:116
|
||||
#: snikket_web/admin.py:250 snikket_web/templates/library.j2:116
|
||||
msgid "Individual"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:155 snikket_web/templates/library.j2:114
|
||||
#: snikket_web/admin.py:251 snikket_web/templates/library.j2:114
|
||||
msgid "Group"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:161
|
||||
#: snikket_web/admin.py:257
|
||||
msgid "New invitation link"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:223
|
||||
#: snikket_web/admin.py:319
|
||||
msgid "Revoke"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:283 snikket_web/admin.py:327
|
||||
#: snikket_web/admin.py:343
|
||||
msgid "Invitation created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:359
|
||||
msgid "No such invitation exists"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:374
|
||||
msgid "Invitation revoked"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:391 snikket_web/admin.py:439
|
||||
msgid "Name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:288 snikket_web/templates/admin_circles.html:47
|
||||
#: snikket_web/admin.py:396 snikket_web/templates/admin_circles.html:47
|
||||
msgid "Create circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:332
|
||||
#: snikket_web/admin.py:426
|
||||
msgid "Circle created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:444
|
||||
msgid "Select user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:337
|
||||
#: snikket_web/admin.py:449
|
||||
msgid "Update circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:341
|
||||
#: snikket_web/admin.py:453
|
||||
msgid "Delete circle permanently"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:347
|
||||
#: snikket_web/admin.py:459
|
||||
msgid "Add user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/infra.py:40
|
||||
#: snikket_web/admin.py:475
|
||||
msgid "No such circle exists"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:512
|
||||
msgid "Circle data updated"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:518
|
||||
msgid "Circle deleted"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:529
|
||||
msgid "User added to circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/admin.py:538
|
||||
msgid "User removed from circle"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/infra.py:41
|
||||
msgid "Main"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:93
|
||||
#: snikket_web/invite.py:106
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:97 snikket_web/invite.py:164 snikket_web/main.py:41
|
||||
#: snikket_web/invite.py:110 snikket_web/invite.py:177 snikket_web/main.py:41
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:101 snikket_web/invite.py:168
|
||||
#: snikket_web/invite.py:114 snikket_web/invite.py:181
|
||||
msgid "Confirm password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:105 snikket_web/invite.py:172
|
||||
msgid "The passwords must match"
|
||||
#: snikket_web/invite.py:118 snikket_web/invite.py:185
|
||||
msgid "The passwords must match."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:110
|
||||
#: snikket_web/invite.py:123
|
||||
msgid "Create account"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:137
|
||||
msgid "That username is already taken"
|
||||
#: snikket_web/invite.py:150
|
||||
msgid "That username is already taken."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:141 snikket_web/invite.py:205
|
||||
msgid "Registration was declined for unknown reasons"
|
||||
#: snikket_web/invite.py:154 snikket_web/invite.py:218
|
||||
msgid "Registration was declined for unknown reasons."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:145
|
||||
msgid "The username is not valid"
|
||||
#: snikket_web/invite.py:158
|
||||
msgid "The username is not valid."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/invite.py:177 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:32
|
||||
#: snikket_web/invite.py:190 snikket_web/templates/user_home.html:32
|
||||
#: snikket_web/templates/user_passwd.html:29
|
||||
msgid "Change password"
|
||||
msgstr ""
|
||||
|
||||
@@ -146,69 +236,92 @@ msgstr ""
|
||||
msgid "Sign in"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/main.py:72
|
||||
#: snikket_web/main.py:55
|
||||
msgid "Invalid username or password."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:21
|
||||
#: snikket_web/main.py:83
|
||||
msgid "Login successful!"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:27
|
||||
msgid "Current password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:26
|
||||
#: snikket_web/user.py:32
|
||||
msgid "New password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:31
|
||||
#: snikket_web/user.py:37
|
||||
msgid "Confirm new password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:35
|
||||
msgid "The new passwords must match"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:42
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:47
|
||||
msgid "Nobody"
|
||||
#: snikket_web/user.py:41
|
||||
msgid "The new passwords must match."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:48
|
||||
msgid "Sign out"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:53
|
||||
msgid "Nobody"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:54
|
||||
msgid "Friends only"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:49
|
||||
#: snikket_web/user.py:55
|
||||
msgid "Everyone"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:12
|
||||
#: snikket_web/templates/admin_users.html:11 snikket_web/user.py:55
|
||||
msgid "Display name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:59
|
||||
#: snikket_web/user.py:65
|
||||
msgid "Avatar"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:63
|
||||
#: snikket_web/user.py:69
|
||||
msgid "Profile visibility"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:68
|
||||
#: snikket_web/user.py:74
|
||||
msgid "Update profile"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:93
|
||||
msgid "Incorrect password"
|
||||
#: snikket_web/user.py:99
|
||||
msgid "Incorrect password."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/_footer.html:4 snikket_web/templates/login.html:36
|
||||
#: snikket_web/user.py:103
|
||||
msgid "Password changed"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:111
|
||||
msgid ""
|
||||
"The chosen avatar is too big. To be able to upload larger avatars, please"
|
||||
" use the app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/user.py:159
|
||||
msgid "Profile updated"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/unauth.html:18 snikket_web/user.py:167
|
||||
msgid "Error"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/_footer.html:4
|
||||
#, python-format
|
||||
msgid "A <a href=\"%(about_url)s\">Snikket</a> service"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:9
|
||||
#: snikket_web/templates/_footer.html:6
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community "
|
||||
"Interest Company."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:4 snikket_web/templates/about.html:9
|
||||
msgid "About Snikket"
|
||||
msgstr ""
|
||||
|
||||
@@ -257,10 +370,22 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:17
|
||||
msgid "Trademarks"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"“Snikket” and the parrot logo are trademarks of Snikket Community "
|
||||
"Interest Company. For more information about the trademarks, visit the <a"
|
||||
" href=\"%(trademarks_url)s\">Snikket Trademarks information page</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:19
|
||||
msgid "Software Versions"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/about.html:27
|
||||
#: snikket_web/templates/about.html:29
|
||||
msgid "Back to the main page"
|
||||
msgstr ""
|
||||
|
||||
@@ -296,7 +421,7 @@ msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_circles.html:15
|
||||
#: snikket_web/templates/admin_invites.html:24
|
||||
#: snikket_web/templates/admin_users.html:12
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
@@ -350,7 +475,7 @@ msgid "Debug information for %(user_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_debug_user.html:11
|
||||
#: snikket_web/templates/user_passwd.html:26
|
||||
#: snikket_web/templates/user_passwd.html:23
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
@@ -367,12 +492,12 @@ msgid "Copy complete output"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:4
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
#, python-format
|
||||
msgid "Delete user %(user_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:6
|
||||
#: snikket_web/templates/admin_edit_user.html:54
|
||||
msgid "Delete user"
|
||||
msgstr ""
|
||||
|
||||
@@ -380,11 +505,6 @@ msgstr ""
|
||||
msgid "Are you sure you want to delete the following user?"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:10
|
||||
#: snikket_web/templates/admin_users.html:10
|
||||
msgid "Login name"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:15
|
||||
msgid "Danger"
|
||||
msgstr ""
|
||||
@@ -397,12 +517,10 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_delete_user.html:19
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
#: snikket_web/templates/admin_edit_invite.html:49
|
||||
#: snikket_web/templates/admin_reset_user_password.html:25
|
||||
#: snikket_web/templates/user_logout.html:13
|
||||
#: snikket_web/templates/user_passwd.html:30
|
||||
#: snikket_web/templates/user_profile.html:31
|
||||
#: snikket_web/templates/user_logout.html:10
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_profile.html:32
|
||||
msgid "Back"
|
||||
msgstr ""
|
||||
|
||||
@@ -434,6 +552,10 @@ msgstr ""
|
||||
msgid "This circle has no group chat associated."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:44
|
||||
msgid "Return to circle list"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_circle.html:48
|
||||
msgid "Delete circle"
|
||||
msgstr ""
|
||||
@@ -476,7 +598,6 @@ msgid "View invitation"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:13
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
#: snikket_web/templates/admin_reset_user_password.html:15
|
||||
msgid "Valid until"
|
||||
msgstr ""
|
||||
@@ -517,6 +638,85 @@ msgstr ""
|
||||
msgid "Created"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_invite.html:48
|
||||
msgid "Return to invitation list"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:5
|
||||
msgid ""
|
||||
"Limited users can interact with users on the same Snikket service and be "
|
||||
"members of circles."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:7
|
||||
msgid ""
|
||||
"Like limited users and can also interact with users on other Snikket "
|
||||
"services."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:9
|
||||
msgid "Like normal users and can access the admin panel in the web portal."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:20
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Edit user %(user_name)s"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:23
|
||||
msgid "Edit user"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:27
|
||||
msgid "The login name cannot be changed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:34
|
||||
msgid ""
|
||||
"The access level of a user determines what interactions are allowed for "
|
||||
"them on your Snikket service."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:41
|
||||
#, python-format
|
||||
msgid "<strong>%(title)s%(icon)s</strong><p>%(description)s</p>"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:51
|
||||
msgid "Return to user list"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:59
|
||||
msgid "Further actions"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:61
|
||||
msgid "Reset password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:64
|
||||
msgid ""
|
||||
"If the user has lost their password, you can use the button below to "
|
||||
"create a special link which allows to change the password of the account,"
|
||||
" once."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:69
|
||||
msgid "Debug information"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:71
|
||||
msgid ""
|
||||
"In some cases, extended information about the user account and the "
|
||||
"connected devices is necessary to troubleshoot issues. The button below "
|
||||
"reveals this (sensitive) information."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_edit_user.html:75
|
||||
msgid "Show debug information"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_home.html:4
|
||||
msgid "Welcome to the admin panel!"
|
||||
msgstr ""
|
||||
@@ -568,6 +768,10 @@ msgstr ""
|
||||
msgid "Pending invitations"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:21
|
||||
msgid "Expires"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_invites.html:22
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
@@ -607,14 +811,20 @@ msgstr ""
|
||||
msgid "Destroy link"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:25
|
||||
#, python-format
|
||||
msgid "Show debug information for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid "The user is an administrator."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:28
|
||||
#, python-format
|
||||
msgid "Create password reset link for %(user_name)s"
|
||||
#: snikket_web/templates/admin_users.html:19
|
||||
msgid " (Administrator)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid "The user is restricted."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/admin_users.html:22
|
||||
msgid " (Restricted)"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/app.html:4
|
||||
@@ -649,7 +859,7 @@ msgid "The web portal encountered an internal error."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_invalid.html:5
|
||||
#: snikket_web/templates/invite_view.html:12
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#, python-format
|
||||
msgid "Invite to %(site_name)s"
|
||||
msgstr ""
|
||||
@@ -657,7 +867,7 @@ msgstr ""
|
||||
#: snikket_web/templates/invite_invalid.html:6
|
||||
#: snikket_web/templates/invite_register.html:10
|
||||
#: snikket_web/templates/invite_success.html:11
|
||||
#: snikket_web/templates/invite_view.html:13
|
||||
#: snikket_web/templates/invite_view.html:14
|
||||
#, python-format
|
||||
msgid "Powered by <img src=\"%(logo_url)s\" alt=\"Snikket\">"
|
||||
msgstr ""
|
||||
@@ -698,18 +908,20 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:14
|
||||
#: snikket_web/templates/invite_view.html:37
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
msgid "App already installed?"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:16
|
||||
#: snikket_web/templates/invite_reset_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:39
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:106
|
||||
#: snikket_web/templates/invite_view.html:134
|
||||
msgid "Open the app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_register.html:18
|
||||
#: snikket_web/templates/invite_view.html:41
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
msgid "This button works only if you have the app installed already!"
|
||||
msgstr ""
|
||||
|
||||
@@ -795,7 +1007,7 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:26
|
||||
#: snikket_web/templates/invite_view.html:75
|
||||
#: snikket_web/templates/invite_view.html:77
|
||||
msgid ""
|
||||
"Your camera will turn on. Point it at the square code below until it is "
|
||||
"within the highlighted square on your screen, and wait until the app "
|
||||
@@ -807,7 +1019,7 @@ msgid "You will then be prompted to enter a new password for your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_reset_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:43
|
||||
#: snikket_web/templates/invite_view.html:45
|
||||
msgid "Alternatives"
|
||||
msgstr ""
|
||||
|
||||
@@ -848,29 +1060,29 @@ msgstr ""
|
||||
msgid "Invite to %(site_name)s | Snikket"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:15
|
||||
#: snikket_web/templates/invite_view.html:16
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat with %(inviter_name)s using Snikket, a "
|
||||
"secure, privacy-friendly chat app on %(site_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:17
|
||||
#: snikket_web/templates/invite_view.html:18
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have been invited to chat on %(site_name)s using Snikket, a secure, "
|
||||
"privacy-friendly chat app."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:19
|
||||
#: snikket_web/templates/invite_view.html:20
|
||||
msgid "Get started"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:21
|
||||
#: snikket_web/templates/invite_view.html:22
|
||||
msgid "Install the Snikket App on your Android or iOS device."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:23
|
||||
#: snikket_web/templates/invite_view.html:24
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Install the Snikket App on your Android device (<a "
|
||||
@@ -878,25 +1090,30 @@ msgid ""
|
||||
"target=\"_blank\">iOS coming soon!</a>)."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:27
|
||||
#: snikket_web/templates/invite_view.html:28
|
||||
msgid "Get it on Google Play"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:29
|
||||
#: snikket_web/templates/invite_view.html:30
|
||||
#: snikket_web/templates/invite_view.html:102
|
||||
msgid "Download on the App Store"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:33
|
||||
msgid "Not on mobile?"
|
||||
#: snikket_web/templates/invite_view.html:32
|
||||
msgid "Get it on F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:36
|
||||
#: snikket_web/templates/invite_view.html:35
|
||||
msgid "Send to mobile device"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:38
|
||||
msgid ""
|
||||
"After installation the app should automatically open and prompt you to "
|
||||
"create an account. If not, simply click the button below."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:44
|
||||
#: snikket_web/templates/invite_view.html:46
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You can connect to Snikket using any XMPP-compatible software. If the "
|
||||
@@ -904,42 +1121,82 @@ msgid ""
|
||||
"href=\"%(register_url)s\">register an account manually</a>."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:50
|
||||
#: snikket_web/templates/invite_view.html:52
|
||||
msgid "Scan invite code"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:53
|
||||
#: snikket_web/templates/invite_view.html:82
|
||||
#: snikket_web/templates/invite_view.html:55
|
||||
#: snikket_web/templates/invite_view.html:84
|
||||
#: snikket_web/templates/invite_view.html:96
|
||||
#: snikket_web/templates/invite_view.html:112
|
||||
#: snikket_web/templates/invite_view.html:124
|
||||
#: snikket_web/templates/invite_view.html:140
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:56
|
||||
#: snikket_web/templates/invite_view.html:58
|
||||
msgid ""
|
||||
"You can transfer this invite to your mobile device by scanning a code "
|
||||
"with your camera. You can use either a QR scanner app or the Snikket app "
|
||||
"itself."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:61
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
msgid "Using a QR code scanner"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:63
|
||||
#: snikket_web/templates/invite_view.html:65
|
||||
msgid "Using the Snikket app"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:68
|
||||
#: snikket_web/templates/invite_view.html:70
|
||||
msgid ""
|
||||
"Use a <em>QR code</em> scanner on your mobile device to scan the code "
|
||||
"below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:74
|
||||
#: snikket_web/templates/invite_view.html:76
|
||||
msgid ""
|
||||
"Install the Snikket app on your mobile device, open it, and tap the "
|
||||
"'Scan' button at the top."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:93
|
||||
msgid "Install on iOS"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:99
|
||||
msgid ""
|
||||
"After downloading Snikket from the App Store, you have to return to this "
|
||||
"invite link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:101
|
||||
msgid "First download Snikket from the App Store using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:103
|
||||
#: snikket_web/templates/invite_view.html:131
|
||||
msgid ""
|
||||
"After the installation is complete, you can return to this page and tap "
|
||||
"the \"Open the app\" button to continue with the setup:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:121
|
||||
#: snikket_web/templates/invite_view.html:130
|
||||
msgid "Install via F-Droid"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:127
|
||||
msgid ""
|
||||
"After installing Snikket via F-Droid, you have to return to this invite "
|
||||
"link and tap on \"Open the app\" to proceed."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/invite_view.html:129
|
||||
msgid "First install Snikket from F-Droid using the button below:"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/library.j2:18
|
||||
msgid "Copy link"
|
||||
msgstr ""
|
||||
@@ -968,8 +1225,19 @@ msgstr ""
|
||||
msgid "Enter your Snikket address and password to manage your account."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:18
|
||||
msgid "Login failed"
|
||||
#: snikket_web/templates/login.html:19
|
||||
msgid "Incorrect address"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/login.html:20
|
||||
#, python-format
|
||||
msgid ""
|
||||
"This Snikket service only hosts addresses ending in "
|
||||
"<em>@%(snikket_domain)s</em>. Your password was not sent."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/unauth.html:16
|
||||
msgid "Operation successful"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_home.html:9
|
||||
@@ -1005,46 +1273,46 @@ msgstr ""
|
||||
msgid "Admin panel"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_logout.html:8
|
||||
#: snikket_web/templates/user_logout.html:5
|
||||
msgid "Sign out of the Snikket Web Portal"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_logout.html:9
|
||||
#: snikket_web/templates/user_logout.html:6
|
||||
msgid ""
|
||||
"Click below to log yourself out of the web portal. This does not affect "
|
||||
"any other connected devices."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:8
|
||||
#: snikket_web/templates/user_passwd.html:5
|
||||
msgid "Change your password"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:9
|
||||
#: snikket_web/templates/user_passwd.html:6
|
||||
msgid ""
|
||||
"To change your password, you need to provide the current password as well"
|
||||
" as the new one. To reduce the chance of typos, we ask for your new "
|
||||
"password twice."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_passwd.html:27
|
||||
#: snikket_web/templates/user_passwd.html:24
|
||||
msgid ""
|
||||
"After changing your password, you will have to enter the new password on "
|
||||
"all of your devices."
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:7
|
||||
#: snikket_web/templates/user_profile.html:4
|
||||
msgid "Update your profile"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:9
|
||||
#: snikket_web/templates/user_profile.html:6
|
||||
msgid "Profile"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:22
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
msgid "Visibility"
|
||||
msgstr ""
|
||||
|
||||
#: snikket_web/templates/user_profile.html:23
|
||||
#: snikket_web/templates/user_profile.html:24
|
||||
msgid ""
|
||||
"This section allows you to control who can see your profile information, "
|
||||
"like avatar and nickname."
|
||||
|
||||
BIN
snikket_web/translations/pl/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/pl/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
BIN
snikket_web/translations/sv/LC_MESSAGES/messages.mo
Normal file
BIN
snikket_web/translations/sv/LC_MESSAGES/messages.mo
Normal file
Binary file not shown.
1431
snikket_web/translations/sv/LC_MESSAGES/messages.po
Normal file
1431
snikket_web/translations/sv/LC_MESSAGES/messages.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,29 @@
|
||||
import asyncio
|
||||
import typing
|
||||
|
||||
import quart
|
||||
import quart.flask_patch
|
||||
from quart import Blueprint, render_template, request, redirect, url_for
|
||||
import quart.exceptions
|
||||
from quart import (
|
||||
Blueprint,
|
||||
render_template,
|
||||
request,
|
||||
redirect,
|
||||
url_for,
|
||||
flash,
|
||||
current_app,
|
||||
)
|
||||
import werkzeug.exceptions
|
||||
|
||||
import wtforms
|
||||
|
||||
import flask_wtf
|
||||
|
||||
from flask_babel import lazy_gettext as _l, _
|
||||
|
||||
from .infra import client
|
||||
from .infra import client, BaseForm
|
||||
|
||||
bp = Blueprint('user', __name__)
|
||||
|
||||
|
||||
class ChangePasswordForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ChangePasswordForm(BaseForm):
|
||||
current_password = wtforms.PasswordField(
|
||||
_l("Current password"),
|
||||
validators=[wtforms.validators.InputRequired()]
|
||||
@@ -32,12 +39,12 @@ class ChangePasswordForm(flask_wtf.FlaskForm): # type:ignore
|
||||
validators=[wtforms.validators.InputRequired(),
|
||||
wtforms.validators.EqualTo(
|
||||
"new_password",
|
||||
_l("The new passwords must match")
|
||||
_l("The new passwords must match.")
|
||||
)]
|
||||
)
|
||||
|
||||
|
||||
class LogoutForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class LogoutForm(BaseForm):
|
||||
action_signout = wtforms.SubmitField(
|
||||
_l("Sign out"),
|
||||
)
|
||||
@@ -50,7 +57,7 @@ _ACCESS_MODEL_CHOICES = [
|
||||
]
|
||||
|
||||
|
||||
class ProfileForm(flask_wtf.FlaskForm): # type:ignore
|
||||
class ProfileForm(BaseForm):
|
||||
nickname = wtforms.TextField(
|
||||
_l("Display name"),
|
||||
)
|
||||
@@ -69,14 +76,14 @@ class ProfileForm(flask_wtf.FlaskForm): # type:ignore
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/")
|
||||
@bp.route("/") # type:ignore
|
||||
@client.require_session()
|
||||
async def index() -> str:
|
||||
user_info = await client.get_user_info()
|
||||
return await render_template("user_home.html", user_info=user_info)
|
||||
|
||||
|
||||
@bp.route('/passwd', methods=["GET", "POST"])
|
||||
@bp.route('/passwd', methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_session()
|
||||
async def change_pw() -> typing.Union[str, quart.Response]:
|
||||
form = ChangePasswordForm()
|
||||
@@ -86,21 +93,33 @@ async def change_pw() -> typing.Union[str, quart.Response]:
|
||||
form.current_password.data,
|
||||
form.new_password.data,
|
||||
)
|
||||
except (quart.exceptions.Unauthorized,
|
||||
quart.exceptions.Forbidden):
|
||||
except (werkzeug.exceptions.Unauthorized,
|
||||
werkzeug.exceptions.Forbidden):
|
||||
# server refused current password, set an appropriate error
|
||||
form.current_password.errors.append(
|
||||
_("Incorrect password"),
|
||||
_("Incorrect password."),
|
||||
)
|
||||
else:
|
||||
await flash(
|
||||
_("Password changed"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for("user.change_pw"))
|
||||
|
||||
return await render_template("user_passwd.html", form=form)
|
||||
|
||||
|
||||
@bp.route("/profile", methods=["GET", "POST"])
|
||||
EAVATARTOOBIG = _l(
|
||||
"The chosen avatar is too big. To be able to upload larger "
|
||||
"avatars, please use the app."
|
||||
)
|
||||
|
||||
|
||||
@bp.route("/profile", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_session()
|
||||
async def profile() -> typing.Union[str, quart.Response]:
|
||||
max_avatar_size = current_app.config["MAX_AVATAR_SIZE"]
|
||||
|
||||
form = ProfileForm()
|
||||
if request.method != "POST":
|
||||
user_info = await client.get_user_info()
|
||||
@@ -114,34 +133,54 @@ async def profile() -> typing.Union[str, quart.Response]:
|
||||
if form.validate_on_submit():
|
||||
user_info = await client.get_user_info()
|
||||
|
||||
ok = True
|
||||
file_info = (await request.files).get(form.avatar.name)
|
||||
if file_info is not None:
|
||||
mimetype = file_info.mimetype
|
||||
data = file_info.stream.read()
|
||||
if len(data) > 0:
|
||||
if len(data) > max_avatar_size:
|
||||
print(len(data), max_avatar_size)
|
||||
form.avatar.errors.append(EAVATARTOOBIG)
|
||||
ok = False
|
||||
elif len(data) > 0:
|
||||
await client.set_user_avatar(data, mimetype)
|
||||
|
||||
if user_info.get("nickname") != form.nickname.data:
|
||||
await client.set_user_nickname(form.nickname.data)
|
||||
if ok:
|
||||
if user_info.get("nickname") != form.nickname.data:
|
||||
await client.set_user_nickname(form.nickname.data)
|
||||
|
||||
access_model = form.profile_access_model.data
|
||||
await asyncio.gather(
|
||||
client.set_avatar_access_model(access_model),
|
||||
client.set_vcard_access_model(access_model),
|
||||
client.set_nickname_access_model(access_model),
|
||||
)
|
||||
access_model = form.profile_access_model.data
|
||||
await asyncio.gather(
|
||||
client.set_avatar_access_model(access_model),
|
||||
client.set_vcard_access_model(access_model),
|
||||
client.set_nickname_access_model(access_model),
|
||||
)
|
||||
|
||||
return redirect(url_for(".profile"))
|
||||
await flash(
|
||||
_("Profile updated"),
|
||||
"success",
|
||||
)
|
||||
return redirect(url_for(".profile"))
|
||||
|
||||
return await render_template("user_profile.html", form=form)
|
||||
return await render_template("user_profile.html",
|
||||
form=form,
|
||||
max_avatar_size=max_avatar_size,
|
||||
avatar_too_big_warning_header=_l("Error"),
|
||||
avatar_too_big_warning=EAVATARTOOBIG)
|
||||
|
||||
|
||||
@bp.route("/logout", methods=["GET", "POST"])
|
||||
@bp.route("/logout", methods=["GET", "POST"]) # type:ignore
|
||||
@client.require_session()
|
||||
async def logout() -> typing.Union[quart.Response, str]:
|
||||
form = LogoutForm()
|
||||
if form.validate_on_submit():
|
||||
await client.logout()
|
||||
# No flashing here because we don’t collect flashes in the login page
|
||||
# and it’d be weird.
|
||||
# await flash(
|
||||
# _("Logged out"),
|
||||
# "success",
|
||||
# )
|
||||
return redirect(url_for("main.index"))
|
||||
|
||||
return await render_template("user_logout.html", form=form)
|
||||
|
||||
@@ -4,7 +4,7 @@ import typing
|
||||
import xml.etree.ElementTree as ET
|
||||
|
||||
from quart import abort
|
||||
import quart.exceptions
|
||||
import werkzeug.exceptions
|
||||
|
||||
|
||||
TAG_XMPP_ERROR = "error"
|
||||
@@ -234,7 +234,7 @@ def extract_pubsub_item_get_reply(
|
||||
) -> typing.Optional[ET.Element]:
|
||||
try:
|
||||
pubsub = extract_iq_reply(iq_tree, TAG_PUBSUB)
|
||||
except quart.exceptions.NotFound:
|
||||
except werkzeug.exceptions.NotFound:
|
||||
return None
|
||||
|
||||
if pubsub is None:
|
||||
|
||||
@@ -5,6 +5,7 @@ action/delete:delete
|
||||
action/logout:logout
|
||||
action/login:login
|
||||
action/exit_to_app:exit_to_app
|
||||
action/lock:lock
|
||||
communication/qr_code:qrcode
|
||||
communication/vpn_key:passwd
|
||||
content/add_circle_outline:add
|
||||
|
||||
Reference in New Issue
Block a user