Update translations strings, add setting datetime and improve DC login flow

This commit is contained in:
Ana Custura 2026-04-07 20:14:57 +01:00
parent ed8723ee6b
commit 410f1b7913
11 changed files with 151 additions and 702 deletions

View file

@ -1,6 +1,6 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from flask_wtf.file import FileAllowed, FileRequired from flask_wtf.file import FileAllowed, FileRequired
from wtforms import StringField, PasswordField, SubmitField, BooleanField, FileField, RadioField from wtforms import StringField, PasswordField, SubmitField, BooleanField, FileField, RadioField, DateTimeField
from wtforms.validators import DataRequired, ValidationError, Length from wtforms.validators import DataRequired, ValidationError, Length
from flask_babel import lazy_gettext as _l from flask_babel import lazy_gettext as _l
import re import re
@ -32,8 +32,10 @@ class Step1Form(FlaskForm):
class Step2Form(FlaskForm): class Step2Form(FlaskForm):
butterbox_name = StringField(_l('Butterbox Name'), validators=[DataRequired()]) butterbox_name = StringField(_l('Butterbox Name'), validators=[DataRequired()])
butterbox_logo = FileField((_l('Butterbox Logo')), validators=[FileAllowed(['jpg', 'png', 'svg'], 'Images only!')]) butterbox_logo = FileField((_l('Butterbox Logo')), validators=[FileAllowed(['jpg', 'png', 'svg'], _l('Images only!'))])
butterbox_hostname = StringField(_l('Butterbox Hostname'), validators=[DataRequired(), Length(1, 64), hostname_check]) butterbox_hostname = StringField(_l('Butterbox Hostname'), validators=[DataRequired(), Length(1, 64), hostname_check])
butterbox_date = DateTimeField(_l('Butterbox Date'), format='%d/%m/%Y, %H:%M:%S')
submit = SubmitField(_l('Next')) submit = SubmitField(_l('Next'))
class Step3Form(FlaskForm): class Step3Form(FlaskForm):

View file

@ -1,5 +1,6 @@
import io import io
import re import re
import subprocess
from app import app from app import app
from flask import render_template, flash, redirect, url_for, send_file, send_from_directory from flask import render_template, flash, redirect, url_for, send_file, send_from_directory
@ -216,7 +217,12 @@ def step2():
if new_value != existing_value: if new_value != existing_value:
set_setting('butterbox_logo', new_value) set_setting('butterbox_logo', new_value)
db.session.commit() db.session.commit()
linux_date_arg = str(form.butterbox_date.data).replace(" ", "T") + "Z"
output = subprocess.run(["/usr/bin/date", "-s", linux_date_arg], capture_output=True, text=True)
if output.returncode != 0:
flash(f"Could not set date. Please set date manually.", category="error")
return redirect(url_for('step3')) return redirect(url_for('step3'))
if get_setting("first_setup") == "true": if get_setting("first_setup") == "true":
return render_template('step2.html', form=form, get_setting=get_setting) return render_template('step2.html', form=form, get_setting=get_setting)
return redirect(url_for('admin')) return redirect(url_for('admin'))

6
app/static/time.js Normal file
View file

@ -0,0 +1,6 @@
document.addEventListener('DOMContentLoaded', () => {
var currentTime = new Date();
const $myDatetimeField = document.querySelector('#butterbox_date')
$myDatetimeField.value = currentTime.toLocaleString();
});

View file

@ -18,61 +18,62 @@
</div> </div>
<label class="label is-large">Services</label> <label class="label is-large">{{ _("Choose Services") }}</label>
<div class="field checkbox"> <div class="field checkbox">
{{ wtf.form_bool_field(form.enable_chat) }} {{ wtf.form_bool_field(form.enable_chat) }}
<p class="help butter-form-margin">Whether Matrix chat services are enabled.</p> <p class="help butter-form-margin">{{ _("Whether Matrix chat services are enabled.")}}</p>
</div> </div>
<div class="field checkbox"> <div class="field checkbox">
{{ wtf.form_bool_field(form.enable_deltachat) }} {{ wtf.form_bool_field(form.enable_deltachat) }}
<p class="help butter-form-margin">Whether messaging using DeltaChat is enabled.</p> <p class="help butter-form-margin">{{ _("Whether messaging using DeltaChat is enabled.")}}</p>
</div> </div>
<div class="field checkbox"> <div class="field checkbox">
{{ wtf.form_bool_field(form.enable_file_viewer) }} {{ wtf.form_bool_field(form.enable_file_viewer) }}
<p class="help butter-form-margin">Whether files services via USB are enabled.</p> <p class="help butter-form-margin">{{ _("Whether files services via USB are enabled.")}}</p>
</div> </div>
<hr> <hr>
<label class="label is-large">Branding and name</label> <label class="label is-large">{{ _("Customise Portal") }}</label>
<div class="field"> <div class="field">
{{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }} {{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }}
<p class="help">This is the name shown in the UI. <p class="help">{{ _("This is the name shown in the UI.
Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.</p> Current name:")}} {{ get_setting('butterbox_name') }}, {{ _("accessed at")}} {{ get_setting('butterbox_name') }}.local.</p>
</div> </div>
<div class="field"> <div class="field">
<label class="label">{{ form.butterbox_logo.label }} </label> <label class="label">{{ form.butterbox_logo.label }} </label>
<div class="control block">{{ form.butterbox_logo(class='label', style="width: 280px") }}</div> <div class="control block">{{ form.butterbox_logo(class='label', style="width: 280px") }}</div>
{{ wtf.field_errors(form.butterbox_logo.errors) }} {{ wtf.field_errors(form.butterbox_logo.errors) }}
<div class="block"><p class="help">This is the logo shown in the UI. Current logo:</p></div> <div class="block"><p class="help">{{ _("This is the logo shown in the UI. Current logo:")}}</p></div>
<img src="{{ get_setting('butterbox_logo') }}" style="height: 50px"> <img src="{{ get_setting('butterbox_logo') }}" style="height: 50px">
</div> </div>
<hr> <hr>
<label class="label is-large">Wi-Fi and access point</label> <label class="label is-large">{{ _("Secure Portal") }}</label>
{% if raspap_installed %} {% if raspap_installed %}
<div class="field"> <div class="field">
{{ wtf.form_input_field(form.ssid, form.ssid.errors) }} {{ wtf.form_input_field(form.ssid, form.ssid.errors) }}
<p class="help"> This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}</p> <p class="help"> {{ _("This is the name of the advertised Wi-Fi network. Current SSID:")}} {{ get_setting('ssid') }}</p>
</div> </div>
<div class="field password"> <div class="field password">
{{ wtf.form_input_field(form.wifi_password, form.wifi_password.errors) }} {{ wtf.form_input_field(form.wifi_password, form.wifi_password.errors) }}
<p class="help"> This is the secret key needed to connect to the Wi-Fi network. By default, this is not set and everyone can join. <p class="help"> {{ _("This is the secret key needed to connect to the Wi-Fi network. By default, this is not set
Current password: {{ get_setting('wifi_password') or 'Not set' }}</p> and everyone can join.
Current password:")}} {{ get_setting('wifi_password') or _('Not set') }}</p>
</div> </div>
<div class="field checkbox"> <div class="field checkbox">
{{ wtf.form_bool_field(form.enable_access_point) }} {{ wtf.form_bool_field(form.enable_access_point) }}
<p class="butter-form-margin help">Whether this box will advertise a Wi-Fi network.</p> <p class="butter-form-margin help">{{ _("Whether this box will advertise a Wi-Fi network.")}}</p>
</div> </div>
<div class="field checkbox"> <div class="field checkbox">
{{ wtf.form_bool_field(form.enable_wifi_sharing) }} {{ wtf.form_bool_field(form.enable_wifi_sharing) }}
<p class="butter-form-margin help">Whether a share button for the Wi-Fi network is available.</p> <p class="butter-form-margin help">{{ _("Whether a share button for the Wi-Fi network is available.")}}</p>
</div> </div>
{% else %} {% else %}
<p> Access point is only enabled when using a Raspberry Pi. </p> <p> {{ _("Access point is only enabled when using a Raspberry Pi.") }} </p>
<div style="display: none"> <div style="display: none">
<div class="field"> <div class="field">
{{ wtf.form_input_field(form.ssid, form.ssid.errors) }} {{ wtf.form_input_field(form.ssid, form.ssid.errors) }}
@ -95,10 +96,10 @@
{% endif %} {% endif %}
<hr> <hr>
<label class="label is-large">Access and security</label> <label class="label is-large">{{ _("Secure Admin Settings") }}</label>
<div class="control field"> <div class="control field">
{{ wtf.form_password_field(form.admin_password, form.admin_password.errors) }} {{ wtf.form_password_field(form.admin_password, form.admin_password.errors) }}
<p class="block help">Password for accessing this browser interface.</p> <p class="block help">{{ _("Password for accessing this admin interface.")}}</p>
</div> </div>
<div class="control block"> <div class="control block">
<label class="label">{{ form.root_account_settings.label }} </label> <label class="label">{{ form.root_account_settings.label }} </label>
@ -113,12 +114,13 @@
</label> </label>
{% endfor %} {% endfor %}
{{ wtf.field_errors(form.root_account_settings.errors)}} {{ wtf.field_errors(form.root_account_settings.errors)}}
<p class="block help">If this is the first time configuring the box, you will need to set a root password, and choose whether you want to lock the root account.</p> <p class="block help">{{ _("You need to set a root password, and choose whether you want to lock the root
account.")}}</p>
</div> </div>
<div class="control field"> <div class="control field">
{{ wtf.form_password_field(form.root_password, form.root_password.errors) }} {{ wtf.form_password_field(form.root_password, form.root_password.errors) }}
<p class="help">Password for accessing the box root account.</p> <p class="help">{{ _("Password for accessing the root account.")}}</p>
</div> </div>
<div class="control block"> <div class="control block">

View file

@ -12,6 +12,8 @@
<link rel="stylesheet" href="{{ url_for('static', filename='css/butter_styles.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='css/butter_styles.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='font-awesome-4.7.0/css/font-awesome.min.css') }}"> <link rel="stylesheet" href="{{ url_for('static', filename='font-awesome-4.7.0/css/font-awesome.min.css') }}">
<script src="{{ url_for('static', filename='navbar.js') }}"></script> <script src="{{ url_for('static', filename='navbar.js') }}"></script>
<script src="{{ url_for('static', filename='time.js') }}"></script>
</head> </head>
<body> <body>
<div class="container"> <div class="container">

View file

@ -19,6 +19,15 @@
</div> </div>
{% endmacro %} {% endmacro %}
{% macro form_datetime_field(field, errors=[]) %}
<div class="control block">
{{ field.label(class='label')}}
{{ field(id='butterbox_date', class='input', type="text") }}
{% for error in errors %}
<p class="help is-danger">{{ error }}</p>
{% endfor %}
</div>
{% endmacro %}
{% macro form_password_field(field, errors=[]) %} {% macro form_password_field(field, errors=[]) %}
<div class="control block"> <div class="control block">

View file

@ -5,17 +5,14 @@
<div class="block"> <div class="block">
<div class="block"> <button class="button is-large"><a href="{{ dclink }}">Add account to DeltaChat</a></button>
<p>{{ _('Scan the following QR code with a device where DeltaChat is installed:') }}</p>
</div>
<img src="{{ base64img }}"/>
</div> </div>
<hr>
<div class="block"> <div class="block">
<div class="block"><p class="">{{ _('If your device does not have a camera, select "Create new profile" in DeltaChat, choose "Use Other Server" and find "Paste from clipboard", to paste the following link') }}:</p></div> <p>{{ _('If the above button does not work, scan the following QR code with a device where DeltaChat is installed:') }}</p>
<pre>{{ dclink}}</pre> <img class="image is-128x128" src="{{ base64img }}"/>
</div> </div>
<div class="block"></div>
<form action="{{ url_for('deltachat_credentials') }}" method="post"> <form action="{{ url_for('deltachat_credentials') }}" method="post">
<button type="submit" class="button is-link is-fullwidth block"> <button type="submit" class="button is-link is-fullwidth block">
<p>{{ _("Generate new credentials") }} </p> <p>{{ _("Generate new credentials") }} </p>

View file

@ -8,6 +8,9 @@
{% import "bulma_wtf.html" as wtf %} {% import "bulma_wtf.html" as wtf %}
<form action="" method="post" enctype="multipart/form-data" novalidate > <form action="" method="post" enctype="multipart/form-data" novalidate >
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
<div class="field">
{{ wtf.form_datetime_field(form.butterbox_date, form.butterbox_date.errors) }}
</div>
<div class="field"> <div class="field">
{{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }} {{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }}
<p class="help">{{ _("This is the name shown in the UI. <p class="help">{{ _("This is the name shown in the UI.

View file

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PROJECT VERSION\n" "Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-03-31 12:45+0100\n" "POT-Creation-Date: 2026-04-06 16:20+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -69,6 +69,10 @@ msgstr ""
msgid "Butterbox Logo" msgid "Butterbox Logo"
msgstr "" msgstr ""
#: app/forms.py:35 app/forms.py:63
msgid "Images only!"
msgstr ""
#: app/forms.py:36 #: app/forms.py:36
msgid "Butterbox Hostname" msgid "Butterbox Hostname"
msgstr "" msgstr ""
@ -133,53 +137,49 @@ msgstr ""
msgid "SSID" msgid "SSID"
msgstr "" msgstr ""
#: app/forms.py:63
msgid "Images only!"
msgstr ""
#: app/forms.py:77 #: app/forms.py:77
msgid "Submit" msgid "Submit"
msgstr "" msgstr ""
#: app/routes.py:104 app/templates/messaging.html:4 #: app/routes.py:106 app/templates/messaging.html:4
msgid "Secure Messenger" msgid "Secure Messenger"
msgstr "" msgstr ""
#: app/routes.py:106 #: app/routes.py:108
msgid "Local Chat" msgid "Local Chat"
msgstr "" msgstr ""
#: app/routes.py:108 #: app/routes.py:110
msgid "Apps" msgid "Apps"
msgstr "" msgstr ""
#: app/routes.py:110 #: app/routes.py:112
msgid "Maps" msgid "Maps"
msgstr "" msgstr ""
#: app/routes.py:112 #: app/routes.py:114
msgid "Files" msgid "Files"
msgstr "" msgstr ""
#: app/routes.py:114 #: app/routes.py:116
msgid "Insert USB to browse files" msgid "Insert USB to browse files"
msgstr "" msgstr ""
#: app/routes.py:151 #: app/routes.py:156
msgid "Invalid username or password" msgid "Invalid username or password"
msgstr "" msgstr ""
#: app/routes.py:336 #: app/routes.py:341
msgid "" msgid ""
"⚠️ Some settings may not fully take effect until the Butter Box restarts." "⚠️ Some settings may not fully take effect until the Butter Box restarts."
" Click 'Apply Changes' to restart." " Click 'Apply Changes' to restart."
msgstr "" msgstr ""
#: app/routes.py:340 #: app/routes.py:345
msgid "Settings successfully changed." msgid "Settings successfully changed."
msgstr "" msgstr ""
#: app/routes.py:346 #: app/routes.py:351
msgid "" msgid ""
"⚠️ Changes applied! If needed, the system will restart. This may take up " "⚠️ Changes applied! If needed, the system will restart. This may take up "
"to two minutes." "to two minutes."
@ -277,26 +277,99 @@ msgstr ""
msgid "Application Settings" msgid "Application Settings"
msgstr "" msgstr ""
#: app/templates/admin_setup.html:6 app/templates/base.html:36 #: app/templates/admin.html:21 app/templates/admin_setup.html:10
msgid "Admin Settings" #: app/templates/step1.html:4
msgstr ""
#: app/templates/admin_setup.html:10 app/templates/step1.html:4
msgid "Choose Services" msgid "Choose Services"
msgstr "" msgstr ""
#: app/templates/admin_setup.html:13 app/templates/step2.html:4 #: app/templates/admin.html:24 app/templates/step1.html:14
msgid "Whether Matrix chat services are enabled."
msgstr ""
#: app/templates/admin.html:28 app/templates/step1.html:18
msgid "Whether messaging using DeltaChat is enabled."
msgstr ""
#: app/templates/admin.html:32 app/templates/step1.html:22
msgid "Whether files services via USB are enabled."
msgstr ""
#: app/templates/admin.html:37 app/templates/admin_setup.html:13
#: app/templates/step2.html:4
msgid "Customise Portal" msgid "Customise Portal"
msgstr "" msgstr ""
#: app/templates/admin_setup.html:16 app/templates/step3.html:4 #: app/templates/admin.html:41 app/templates/step2.html:13
msgid ""
"This is the name shown in the UI.\n"
" Current name:"
msgstr ""
#: app/templates/admin.html:42 app/templates/step2.html:14
msgid "accessed at"
msgstr ""
#: app/templates/admin.html:48 app/templates/step2.html:25
msgid "This is the logo shown in the UI. Current logo:"
msgstr ""
#: app/templates/admin.html:54 app/templates/admin_setup.html:16
#: app/templates/step3.html:4
msgid "Secure Portal" msgid "Secure Portal"
msgstr "" msgstr ""
#: app/templates/admin_setup.html:19 app/templates/step4.html:4 #: app/templates/admin.html:59 app/templates/step3.html:14
msgid "This is the name of the advertised Wi-Fi network. Current SSID:"
msgstr ""
#: app/templates/admin.html:63 app/templates/step3.html:18
msgid ""
"This is the secret key needed to connect to the Wi-Fi network. By "
"default, this is not set\n"
" and everyone can join.\n"
" Current password:"
msgstr ""
#: app/templates/admin.html:65 app/templates/step3.html:20
msgid "Not set"
msgstr ""
#: app/templates/admin.html:69 app/templates/step3.html:24
msgid "Whether this box will advertise a Wi-Fi network."
msgstr ""
#: app/templates/admin.html:73 app/templates/step3.html:28
msgid "Whether a share button for the Wi-Fi network is available."
msgstr ""
#: app/templates/admin.html:76 app/templates/step3.html:31
msgid "Access point is only enabled when using a Raspberry Pi."
msgstr ""
#: app/templates/admin.html:99 app/templates/admin_setup.html:19
#: app/templates/step4.html:4
msgid "Secure Admin Settings" msgid "Secure Admin Settings"
msgstr "" msgstr ""
#: app/templates/admin.html:102 app/templates/step4.html:14
msgid "Password for accessing this admin interface."
msgstr ""
#: app/templates/admin.html:117 app/templates/step4.html:29
msgid ""
"You need to set a root password, and choose whether you want to lock the "
"root\n"
" account."
msgstr ""
#: app/templates/admin.html:123 app/templates/step4.html:35
msgid "Password for accessing the root account."
msgstr ""
#: app/templates/admin_setup.html:6 app/templates/base.html:36
msgid "Admin Settings"
msgstr ""
#: app/templates/deltachat_creds.html:4 #: app/templates/deltachat_creds.html:4
msgid "Secure Messenger Account" msgid "Secure Messenger Account"
msgstr "" msgstr ""
@ -408,18 +481,6 @@ msgid ""
" visit the Help Center. You can change the services anytime." " visit the Help Center. You can change the services anytime."
msgstr "" msgstr ""
#: app/templates/step1.html:14
msgid "Whether Matrix chat services are enabled."
msgstr ""
#: app/templates/step1.html:18
msgid "Whether messaging using DeltaChat is enabled."
msgstr ""
#: app/templates/step1.html:22
msgid "Whether files services via USB are enabled."
msgstr ""
#: app/templates/step1.html:25 app/templates/step2.html:29 #: app/templates/step1.html:25 app/templates/step2.html:29
#: app/templates/step3.html:53 app/templates/step4.html:54 #: app/templates/step3.html:53 app/templates/step4.html:54
msgid "Back" msgid "Back"
@ -432,69 +493,12 @@ msgid ""
"changed later." "changed later."
msgstr "" msgstr ""
#: app/templates/step2.html:13
msgid ""
"This is the name shown in the UI.\n"
" Current name:"
msgstr ""
#: app/templates/step2.html:14
msgid "accessed at"
msgstr ""
#: app/templates/step2.html:18 #: app/templates/step2.html:18
msgid "" msgid ""
"This is the URL used to access the box by adding .local in your browser.\n" "This is the URL used to access the box by adding .local in your browser.\n"
" Current hostname:" " Current hostname:"
msgstr "" msgstr ""
#: app/templates/step2.html:25
msgid "This is the logo shown in the UI. Current logo:"
msgstr ""
#: app/templates/step3.html:14
msgid "This is the name of the advertised Wi-Fi network. Current SSID:"
msgstr ""
#: app/templates/step3.html:18
msgid ""
"This is the secret key needed to connect to the Wi-Fi network. By "
"default, this is not set\n"
" and everyone can join.\n"
" Current password:"
msgstr ""
#: app/templates/step3.html:20
msgid "Not set"
msgstr ""
#: app/templates/step3.html:24
msgid "Whether this box will advertise a Wi-Fi network."
msgstr ""
#: app/templates/step3.html:28
msgid "Whether a share button for the Wi-Fi network is available."
msgstr ""
#: app/templates/step3.html:31
msgid "Access point is only enabled when using a Raspberry Pi."
msgstr ""
#: app/templates/step4.html:14
msgid "Password for accessing this admin interface."
msgstr ""
#: app/templates/step4.html:29
msgid ""
"You need to set a root password, and choose whether you want to lock the "
"root\n"
" account."
msgstr ""
#: app/templates/step4.html:35
msgid "Password for accessing the root account."
msgstr ""
#: app/templates/usb-file-viewer.html:5 #: app/templates/usb-file-viewer.html:5
msgid "File Viewer" msgid "File Viewer"
msgstr "" msgstr ""

View file

@ -1,582 +0,0 @@
# Russian translations for PROJECT.
# Copyright (C) 2026 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2026.
#
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2026-03-31 12:45+0100\n"
"PO-Revision-Date: 2026-04-05 10:08+0000\n"
"Last-Translator: irl <irl@sr2.uk>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/sr2/butter-"
"portal/ru/>\n"
"Language: ru\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Generator: Weblate 5.17-dev\n"
"Generated-By: Babel 2.18.0\n"
#: app/__init__.py:19
msgid "Please log in to access this page."
msgstr "Пожалуйста, авторизуйтесь, чтобы получить доступ к этой странице."
#: app/forms.py:13
msgid "Only dashes, underscores, letters and numbers allowed."
msgstr "Допускаются только дефисы, символы подчёркивания, буквы и цифры."
#: app/forms.py:17
msgid "Wifi password cannot be longer than 63 characters."
msgstr "Пароль Wi-Fi не может быть длиннее 63 символов."
#: app/forms.py:19
msgid "Wifi password cannot be shorter than 8 characters."
msgstr "The Wi-Fi password cannot be shorter than 8 characters."
#: app/forms.py:22
msgid "Username"
msgstr "Имя пользователя"
#: app/forms.py:23
msgid "Password"
msgstr "Пароль"
#: app/forms.py:24 app/templates/login.html:6
msgid "Sign In"
msgstr "Войти"
#: app/forms.py:28 app/forms.py:65
msgid "Enable File Viewer"
msgstr "Включить просмотр файлов"
#: app/forms.py:29 app/forms.py:66
msgid "Enable Chat"
msgstr "Включить чат"
#: app/forms.py:30 app/forms.py:67
msgid "Enable DeltaChat"
msgstr "Включить DeltaChat"
#: app/forms.py:31 app/forms.py:37 app/forms.py:44
msgid "Next"
msgstr "Далее"
#: app/forms.py:34 app/forms.py:62
msgid "Butterbox Name"
msgstr "Имя Butterbox"
#: app/forms.py:35 app/forms.py:63
msgid "Butterbox Logo"
msgstr "Логотип Butterbox"
#: app/forms.py:36
msgid "Butterbox Hostname"
msgstr "Имя хоста Butterbox"
#: app/forms.py:40
msgid "WiFi Name"
msgstr "Имя сети Wi-Fi"
#: app/forms.py:41 app/forms.py:59
msgid "WiFi Password"
msgstr "Пароль Wi-Fi"
#: app/forms.py:42 app/forms.py:68
msgid "Enable WiFi Sharing"
msgstr "Включить раздачу Wi-Fi"
#: app/forms.py:43 app/forms.py:60
msgid "Enable Access Point"
msgstr "Включить точку доступа"
#: app/forms.py:47 app/forms.py:70
msgid "Admin Password"
msgstr "Пароль администратора"
#: app/forms.py:48 app/forms.py:71
msgid "Root Password"
msgstr "Пароль root"
#: app/forms.py:49 app/forms.py:73
msgid "Secure Root Account Method"
msgstr "Метод защиты root аккаунта"
#: app/forms.py:49 app/forms.py:73
msgid "Lock root account"
msgstr "Заблокировать root аккаунт"
#: app/forms.py:49 app/forms.py:73
msgid "Use root password"
msgstr "Использовать пароль root аккаунта"
#: app/forms.py:50 app/forms.py:74
msgid "SSH Access Method"
msgstr "Метод доступа по SSH"
#: app/forms.py:50 app/forms.py:74
msgid "Disable SSH"
msgstr "Отключить SSH"
#: app/forms.py:50 app/forms.py:74
msgid "Enable SSH with root password"
msgstr "Включить SSH с паролем root"
#: app/forms.py:52 app/forms.py:76
msgid "Lock Root Account"
msgstr "Заблокировать root аккаунт"
#: app/forms.py:53 app/forms.py:78
msgid "Apply Changes"
msgstr "Применить изменения"
#: app/forms.py:58
msgid "SSID"
msgstr "SSID"
#: app/forms.py:63
msgid "Images only!"
msgstr "Только изображения!"
#: app/forms.py:77
msgid "Submit"
msgstr "Отправить"
#: app/routes.py:104 app/templates/messaging.html:4
msgid "Secure Messenger"
msgstr "Приватный мессенджер"
#: app/routes.py:106
msgid "Local Chat"
msgstr "Локальный чат"
#: app/routes.py:108
msgid "Apps"
msgstr "Приложения"
#: app/routes.py:110
msgid "Maps"
msgstr "Карты"
#: app/routes.py:112
msgid "Files"
msgstr "Файлы"
#: app/routes.py:114
msgid "Insert USB to browse files"
msgstr "Вставьте USB чтобы просмотреть файлы"
#: app/routes.py:151
msgid "Invalid username or password"
msgstr "Некорректное имя пользователя или пароль"
#: app/routes.py:336
msgid ""
"⚠️ Some settings may not fully take effect until the Butter Box restarts."
" Click 'Apply Changes' to restart."
msgstr ""
"⚠️ Некоторые настройки вступят в силу только после перезапуска Butter Box. "
"Нажмите «Применить изменения» для перезапуска."
#: app/routes.py:340
msgid "Settings successfully changed."
msgstr "Настройки успешно сохранены."
#: app/routes.py:346
msgid ""
"⚠️ Changes applied! If needed, the system will restart. This may take up "
"to two minutes."
msgstr ""
"⚠️ Изменения применены! Если это необходимо, система перезагрузится. Это "
"может занять до двух минут."
#: app/translation_refs.py:3
msgid ""
"The URL is the address users will enter into a browser after they connect"
" to the box network. From here, they can view the portal. "
msgstr ""
"URL это адрес, который пользователи вводят в браузере после подключения к "
"сети устройства. Далее они могут перейти в портал. "
#: app/translation_refs.py:4
msgid "Upload New Logo"
msgstr "Загрузить новый логотип"
#: app/translation_refs.py:5
msgid ""
"After the box is powered on, it will appear as a Wi-Fi network on nearby "
"devices. The Wi-Fi name will show up in the Wi-Fi list."
msgstr ""
"После включения Butterbox, он появится как сеть Wi-Fi на устройствах "
"поблизости. Название сети Wi-Fi появится в списке точек Wi-Fi."
#: app/translation_refs.py:6
msgid ""
"⚠️ This network only provides access to content on the box. No internet "
"access."
msgstr ""
"⚠️ Эта сеть предоставляет доступ только к содержимому Butterbox. Доступа к "
"интернету нет."
#: app/translation_refs.py:7
msgid "Set a password to limit access to the portal."
msgstr "Задайте пароль чтобы ограничить доступ к порталу."
#: app/translation_refs.py:8
msgid "Security"
msgstr "Безопасность"
#: app/translation_refs.py:9
msgid "Require a Wi-Fi Password"
msgstr "Требовать пароль Wi-Fi"
#: app/translation_refs.py:10
msgid ""
"Turn off the Wi-Fi access point if you do not want the box to appear as a"
" Wi-Fi network on nearby devices."
msgstr ""
"Отключите точку доступа Wi-Fi, если вы не хотите чтобы Butterbox появился "
"как точка доступа Wi-Fi на устройствах поблизости."
#: app/translation_refs.py:11
msgid "Wi-Fi Access Point (on)"
msgstr "Точка доступа Wi-Fi (вкл)"
#: app/translation_refs.py:12
msgid "Set Admin Password"
msgstr "Задать пароль администратора"
#: app/translation_refs.py:13
msgid ""
"Set an admin password to keep admin settings protected. Store somewhere "
"secure. It cannot be reset."
msgstr ""
"Задайте пароль администратора, чтобы защитить настройки. Сохраните его в "
"надёжном месте. Пароль нельзя будет сбросить."
#: app/translation_refs.py:14
msgid "⚠️ This password should not match the Wi-Fi password."
msgstr "⚠️ Этот пароль не должен совпадать с паролем Wi-Fi."
#: app/translation_refs.py:15
msgid "Enter password"
msgstr "Введите пароль"
#: app/translation_refs.py:16
msgid "Confirm password"
msgstr "Подтвердить пароль"
#: app/translation_refs.py:17
msgid "Help Center"
msgstr "Справочный центр"
#: app/translation_refs.py:18
msgid "Language"
msgstr "Язык"
#: app/templates/base.html:40 app/translation_refs.py:19
msgid "Share Access"
msgstr "Поделиться доступом"
#: app/translation_refs.py:20
msgid "512 x 512 px. Recommended size."
msgstr "512 × 512 px. Рекомендуемый размер."
#: app/translation_refs.py:21
msgid ""
"Continue to your box portal. The portal is the view others will see when "
"they connect to the box hotspot."
msgstr ""
"Перейдите в портал вашего устройства. Это страница, которую увидят другие "
"пользователи при подключении к точке доступа устройства."
#: app/templates/admin.html:8
msgid "Application Settings"
msgstr "Настройки приложения"
#: app/templates/admin_setup.html:6 app/templates/base.html:36
msgid "Admin Settings"
msgstr "Настройки Администратора"
#: app/templates/admin_setup.html:10 app/templates/step1.html:4
msgid "Choose Services"
msgstr "Выберите сервисы"
#: app/templates/admin_setup.html:13 app/templates/step2.html:4
msgid "Customise Portal"
msgstr "Настроить портал"
#: app/templates/admin_setup.html:16 app/templates/step3.html:4
msgid "Secure Portal"
msgstr "Защищённый портал"
#: app/templates/admin_setup.html:19 app/templates/step4.html:4
msgid "Secure Admin Settings"
msgstr "Безопасные настройки администратора"
#: app/templates/deltachat_creds.html:4
msgid "Secure Messenger Account"
msgstr "Учётная запись защищённого мессенджера"
#: app/templates/deltachat_creds.html:9
msgid "Scan the following QR code with a device where DeltaChat is installed:"
msgstr "Отсканируйте QR-код с устройства, на котором установлен DeltaChat:"
#: app/templates/deltachat_creds.html:14
msgid ""
"If your device does not have a camera, select \"Create new profile\" in "
"DeltaChat, choose \"Use Other Server\" and find \"Paste from clipboard\","
" to paste the following link"
msgstr ""
"Если на вашем устройстве нет камеры, в DeltaChat выберите \"Создать новый "
"профиль\", затем \"Использовать другой сервер\" и найдите пункт \"Вставить "
"из буфера обмена\", чтобы вставить следующую ссылку"
#: app/templates/deltachat_creds.html:21
msgid "Generate new credentials"
msgstr "Сгенерировать новые учётные данные"
#: app/templates/first_setup_main_page.html:6
msgid "Set up your box"
msgstr "Настроить ButterBox"
#: app/templates/first_setup_main_page.html:9
msgid "Version"
msgstr "Версия"
#: app/templates/first_setup_main_page.html:12
msgid ""
"You have full control over the services on this box and its security. "
"Continue to Admin Settings to personalize your setup."
msgstr ""
"Вы имеете полный контроль над сервисами на этом устройстве и его "
"безопасностью. Перейдите в настройки администратора, чтобы настроить систему "
"под себя."
#: app/templates/first_setup_main_page.html:13
msgid "Continue"
msgstr "Продолжить"
#: app/templates/index.html:4
msgid "Welcome."
msgstr "Добро пожаловать."
#: app/templates/index.html:5
msgid ""
"View and download the information you want from this offline\n"
" box."
msgstr ""
"Просматривайте и загружайте нужную вам информацию\n"
"\n"
" с этого офлайн ButterBox."
#: app/templates/messaging.html:7
msgid ""
"To use secure messaging, install Delta Chat and then create your local "
"offline account."
msgstr ""
"Чтобы использовать безопасный обмен сообщениями, установите Delta Chat, а "
"затем создайте свою локальную офлайн-учётную запись."
#: app/templates/messaging.html:10
msgid "Step 1"
msgstr "Шаг 1"
#: app/templates/messaging.html:10
msgid "Download and install"
msgstr "Загрузить и установить"
#: app/templates/messaging.html:16
msgid "Step 2"
msgstr "Шаг 2"
#: app/templates/messaging.html:16
msgid "Create offline account"
msgstr "Создать офлайн-учётную запись"
#: app/templates/setup_complete.html:4
msgid "Changes have been applied"
msgstr "Изменения применены"
#: app/templates/setup_complete.html:7
msgid "The box will now reboot to apply settings. This can take up to one minute."
msgstr ""
"ButterBox будет перезагружен для применения настроек. Это может занять до "
"одной минуты."
#: app/templates/setup_complete.html:8
msgid "Continue to Portal"
msgstr "Перейти к порталу"
#: app/templates/share.html:4
msgid "Share access to"
msgstr "Предоставить доступ к"
#: app/templates/share.html:9
msgid "Connect to WiFi name:"
msgstr "Подключиться к сети Wi-Fi:"
#: app/templates/share.html:9
msgid "with password:"
msgstr "с паролем:"
#: app/templates/share.html:11
msgid "Your WiFi name is"
msgstr "Имя вашей сети Wi-Fi"
#: app/templates/share.html:11
msgid "You will be able to join without a password."
msgstr "Вы сможете подключиться без пароля."
#: app/templates/share.html:13
msgid "You can also use the following QR code to join:"
msgstr "Также вы можете использовать следующий QR код для подключения:"
#: app/templates/step1.html:5
msgid ""
"To learn more about individual services and what is required to run them,"
" visit the Help Center. You can change the services anytime."
msgstr ""
"Чтобы узнать больше о каждом сервисе и о том, что требуется для их работы, "
"посетите справочный центр. Вы можете изменить сервисы в любое время."
#: app/templates/step1.html:14
msgid "Whether Matrix chat services are enabled."
msgstr "Включены ли сервисы чата Matrix."
#: app/templates/step1.html:18
msgid "Whether messaging using DeltaChat is enabled."
msgstr "Включён ли обмен сообщениями через DeltaChat."
#: app/templates/step1.html:22
msgid "Whether files services via USB are enabled."
msgstr "Включены ли файловые сервисы через USB."
#: app/templates/step1.html:25 app/templates/step2.html:29
#: app/templates/step3.html:53 app/templates/step4.html:54
msgid "Back"
msgstr "Назад"
#: app/templates/step2.html:5
msgid ""
"The URL is the address users will enter into a browser after they connect"
" to the box network. From here, they can view the portal. This cannot be "
"changed later."
msgstr ""
"URL это адрес, который пользователи вводят в браузере после подключения к "
"сети устройства. Далее они могут перейти в портал."
#: app/templates/step2.html:13
msgid ""
"This is the name shown in the UI.\n"
" Current name:"
msgstr ""
"Это имя отображается в интерфейсе..\n"
"\n"
" Текущее имя:"
#: app/templates/step2.html:14
msgid "accessed at"
msgstr "доступно по"
#: app/templates/step2.html:18
msgid ""
"This is the URL used to access the box by adding .local in your browser.\n"
" Current hostname:"
msgstr ""
"Это URL, который используется для доступа к устройству через добавление "
".local в браузере.\n"
"\n"
" Текущее имя хоста:"
#: app/templates/step2.html:25
msgid "This is the logo shown in the UI. Current logo:"
msgstr "Это логотип, отображаемый в интерфейсе. Текущее лого:"
#: app/templates/step3.html:14
msgid "This is the name of the advertised Wi-Fi network. Current SSID:"
msgstr "Это имя транслируемой сети Wi-Fi. Текущий SSID:"
#: app/templates/step3.html:18
msgid ""
"This is the secret key needed to connect to the Wi-Fi network. By "
"default, this is not set\n"
" and everyone can join.\n"
" Current password:"
msgstr ""
"Это секретный ключ, необходимый для подключения к сети Wi-Fi. По умолчанию "
"он не задан,\n"
" и к сети может подключиться любой пользователь.\n"
" Текущий пароль:"
#: app/templates/step3.html:20
msgid "Not set"
msgstr "Не задано"
#: app/templates/step3.html:24
msgid "Whether this box will advertise a Wi-Fi network."
msgstr "Будет ли ButterBox транслировать сеть Wi-Fi."
#: app/templates/step3.html:28
msgid "Whether a share button for the Wi-Fi network is available."
msgstr "Доступна ли кнопка \"Поделиться\" для сети Wi-Fi."
#: app/templates/step3.html:31
msgid "Access point is only enabled when using a Raspberry Pi."
msgstr "Точка доступа включается только при использовании Raspberry Pi."
#: app/templates/step4.html:14
msgid "Password for accessing this admin interface."
msgstr "Пароль для доступа к панели администратора."
#: app/templates/step4.html:29
msgid ""
"You need to set a root password, and choose whether you want to lock the "
"root\n"
" account."
msgstr ""
"Вам необходимо задать пароль root и выбрать, следует ли заблокировать\n"
" учётную запись root."
#: app/templates/step4.html:35
msgid "Password for accessing the root account."
msgstr "Пароль для доступа к root аккаунту."
#: app/templates/usb-file-viewer.html:5
msgid "File Viewer"
msgstr "Просмотр файлов"
#: app/templates/usb-file-viewer.html:11
msgid "File Name"
msgstr "Название файла"
#: app/templates/usb-file-viewer.html:12
msgid "Date modified"
msgstr "Дата изменения"
#: app/templates/usb-file-viewer.html:13 app/templates/usb-file-viewer.html:30
msgid "Download"
msgstr "Скачать"
#: app/templates/usb-file-viewer.html:39
msgid "Directory is empty"
msgstr "Директория пуста"
#~ msgid "Only dashes, underscores, letters and numbers allowed"
#~ msgstr ""
#~ msgid "Share WiFi"
#~ msgstr ""
#~ msgid ""
#~ "To use secure messaging, install Delta"
#~ " Chat and then return to this "
#~ "page to create your local offline "
#~ "account."
#~ msgstr ""
#~ msgid "Changes have been applied "
#~ msgstr ""