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.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):

View file

@ -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'))

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>
<label class="label is-large">Services</label>
<label class="label is-large">{{ _("Choose Services") }}</label>
<div class="field checkbox">
{{ 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 class="field checkbox">
{{ 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 class="field checkbox">
{{ 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>
<hr>
<label class="label is-large">Branding and name</label>
<label class="label is-large">{{ _("Customise Portal") }}</label>
<div class="field">
{{ wtf.form_input_field(form.butterbox_name, form.butterbox_name.errors) }}
<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>
<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>
</div>
<div class="field">
<label class="label">{{ form.butterbox_logo.label }} </label>
<div class="control block">{{ form.butterbox_logo(class='label', style="width: 280px") }}</div>
{{ 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">
</div>
<hr>
<label class="label is-large">Wi-Fi and access point</label>
<label class="label is-large">{{ _("Secure Portal") }}</label>
{% if raspap_installed %}
<div class="field">
{{ 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 class="field password">
{{ 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.
Current password: {{ get_setting('wifi_password') or 'Not set' }}</p>
<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.
Current password:")}} {{ get_setting('wifi_password') or _('Not set') }}</p>
</div>
<div class="field checkbox">
{{ 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 class="field checkbox">
{{ 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>
{% 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 class="field">
{{ wtf.form_input_field(form.ssid, form.ssid.errors) }}
@ -95,10 +96,10 @@
{% endif %}
<hr>
<label class="label is-large">Access and security</label>
<label class="label is-large">{{ _("Secure Admin Settings") }}</label>
<div class="control field">
{{ 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 class="control block">
<label class="label">{{ form.root_account_settings.label }} </label>
@ -113,12 +114,13 @@
</label>
{% endfor %}
{{ 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 class="control field">
{{ 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 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='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='time.js') }}"></script>
</head>
<body>
<div class="container">

View file

@ -19,6 +19,15 @@
</div>
{% 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=[]) %}
<div class="control block">

View file

@ -5,17 +5,14 @@
<div class="block">
<div class="block">
<p>{{ _('Scan the following QR code with a device where DeltaChat is installed:') }}</p>
</div>
<img src="{{ base64img }}"/>
<button class="button is-large"><a href="{{ dclink }}">Add account to DeltaChat</a></button>
</div>
<hr>
<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>
<pre>{{ dclink}}</pre>
<p>{{ _('If the above button does not work, scan the following QR code with a device where DeltaChat is installed:') }}</p>
<img class="image is-128x128" src="{{ base64img }}"/>
</div>
<div class="block"></div>
<form action="{{ url_for('deltachat_credentials') }}" method="post">
<button type="submit" class="button is-link is-fullwidth block">
<p>{{ _("Generate new credentials") }} </p>

View file

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