From 410f1b7913f5b85bb49fd552ed061d93b33f919a Mon Sep 17 00:00:00 2001 From: Ana Custura Date: Tue, 7 Apr 2026 20:14:57 +0100 Subject: [PATCH] Update translations strings, add setting datetime and improve DC login flow --- app/forms.py | 6 +- app/routes.py | 6 + app/static/time.js | 6 + app/templates/admin.html | 40 +- app/templates/base.html | 2 + app/templates/bulma_wtf.html | 9 + app/templates/deltachat_creds.html | 11 +- app/templates/step2.html | 3 + app/translations/ru/LC_MESSAGES/messages.po | 0 messages.pot | 188 +++---- translations/ru/LC_MESSAGES/messages.po | 582 -------------------- 11 files changed, 151 insertions(+), 702 deletions(-) create mode 100644 app/static/time.js create mode 100644 app/translations/ru/LC_MESSAGES/messages.po delete mode 100644 translations/ru/LC_MESSAGES/messages.po diff --git a/app/forms.py b/app/forms.py index 1de53bb..977675c 100644 --- a/app/forms.py +++ b/app/forms.py @@ -1,6 +1,6 @@ from flask_wtf import FlaskForm 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 flask_babel import lazy_gettext as _l import re @@ -32,8 +32,10 @@ class Step1Form(FlaskForm): class Step2Form(FlaskForm): 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_date = DateTimeField(_l('Butterbox Date'), format='%d/%m/%Y, %H:%M:%S') + submit = SubmitField(_l('Next')) class Step3Form(FlaskForm): diff --git a/app/routes.py b/app/routes.py index cd7926e..c316fec 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,5 +1,6 @@ import io import re +import subprocess from app import app 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: set_setting('butterbox_logo', new_value) 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')) + if get_setting("first_setup") == "true": return render_template('step2.html', form=form, get_setting=get_setting) return redirect(url_for('admin')) diff --git a/app/static/time.js b/app/static/time.js new file mode 100644 index 0000000..ba1d54c --- /dev/null +++ b/app/static/time.js @@ -0,0 +1,6 @@ +document.addEventListener('DOMContentLoaded', () => { +var currentTime = new Date(); +const $myDatetimeField = document.querySelector('#butterbox_date') + $myDatetimeField.value = currentTime.toLocaleString(); + +}); \ No newline at end of file diff --git a/app/templates/admin.html b/app/templates/admin.html index e5df09d..3fd9a3e 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -18,61 +18,62 @@ - +
{{ wtf.form_bool_field(form.enable_chat) }} -

Whether Matrix chat services are enabled.

+

{{ _("Whether Matrix chat services are enabled.")}}

{{ wtf.form_bool_field(form.enable_deltachat) }} -

Whether messaging using DeltaChat is enabled.

+

{{ _("Whether messaging using DeltaChat is enabled.")}}

{{ wtf.form_bool_field(form.enable_file_viewer) }} -

Whether files services via USB are enabled.

+

{{ _("Whether files services via USB are enabled.")}}


- +
{{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }} -

This is the name shown in the UI. - Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.

+

{{ _("This is the name shown in the UI. + Current name:")}} {{ get_setting('butterbox_name') }}, {{ _("accessed at")}} {{ get_setting('butterbox_name') }}.local.

{{ form.butterbox_logo(class='label', style="width: 280px") }}
{{ wtf.field_errors(form.butterbox_logo.errors) }} -

This is the logo shown in the UI. Current logo:

+

{{ _("This is the logo shown in the UI. Current logo:")}}


- + {% if raspap_installed %}
{{ wtf.form_input_field(form.ssid, form.ssid.errors) }} -

This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}

+

{{ _("This is the name of the advertised Wi-Fi network. Current SSID:")}} {{ get_setting('ssid') }}

{{ wtf.form_input_field(form.wifi_password, form.wifi_password.errors) }} -

This is the secret key needed to connect to the Wi-Fi network. By default, this is not set and everyone can join. - Current password: {{ get_setting('wifi_password') or 'Not set' }}

+

{{ _("This is the secret key needed to connect to the Wi-Fi network. By default, this is not set + and everyone can join. + Current password:")}} {{ get_setting('wifi_password') or _('Not set') }}

{{ wtf.form_bool_field(form.enable_access_point) }} -

Whether this box will advertise a Wi-Fi network.

+

{{ _("Whether this box will advertise a Wi-Fi network.")}}

{{ wtf.form_bool_field(form.enable_wifi_sharing) }} -

Whether a share button for the Wi-Fi network is available.

+

{{ _("Whether a share button for the Wi-Fi network is available.")}}

{% else %} -

Access point is only enabled when using a Raspberry Pi.

+

{{ _("Access point is only enabled when using a Raspberry Pi.") }}

{{ wtf.form_input_field(form.ssid, form.ssid.errors) }} @@ -95,10 +96,10 @@ {% endif %}
- +
{{ wtf.form_password_field(form.admin_password, form.admin_password.errors) }} -

Password for accessing this browser interface.

+

{{ _("Password for accessing this admin interface.")}}

@@ -113,12 +114,13 @@ {% endfor %} {{ wtf.field_errors(form.root_account_settings.errors)}} -

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.

+

{{ _("You need to set a root password, and choose whether you want to lock the root + account.")}}

{{ wtf.form_password_field(form.root_password, form.root_password.errors) }} -

Password for accessing the box root account.

+

{{ _("Password for accessing the root account.")}}

diff --git a/app/templates/base.html b/app/templates/base.html index 9e12f9b..8db020c 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -12,6 +12,8 @@ + +
diff --git a/app/templates/bulma_wtf.html b/app/templates/bulma_wtf.html index ada16e4..e9222cd 100644 --- a/app/templates/bulma_wtf.html +++ b/app/templates/bulma_wtf.html @@ -19,6 +19,15 @@
{% endmacro %} +{% macro form_datetime_field(field, errors=[]) %} +
+ {{ field.label(class='label')}} + {{ field(id='butterbox_date', class='input', type="text") }} + {% for error in errors %} +

{{ error }}

+ {% endfor %} +
+{% endmacro %} {% macro form_password_field(field, errors=[]) %}
diff --git a/app/templates/deltachat_creds.html b/app/templates/deltachat_creds.html index afa9f25..e49bc53 100644 --- a/app/templates/deltachat_creds.html +++ b/app/templates/deltachat_creds.html @@ -5,17 +5,14 @@
-
-

{{ _('Scan the following QR code with a device where DeltaChat is installed:') }}

-
- +
+
-

{{ _('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') }}:

-
{{ dclink}}
+

{{ _('If the above button does not work, scan the following QR code with a device where DeltaChat is installed:') }}

+
-