diff --git a/app/routes.py b/app/routes.py
index 6babe30..94c1ddf 100644
--- a/app/routes.py
+++ b/app/routes.py
@@ -1,5 +1,5 @@
from app import app
-from flask import render_template, flash, redirect, url_for, request, session, send_file
+from flask import render_template, flash, redirect, url_for, send_file
from app.forms import LoginForm, SettingsForm
from flask_login import login_user, current_user, logout_user, login_required
import sqlalchemy as sa
@@ -16,7 +16,7 @@ import string
import glob
import time
import qrcode
-from app.change_manager import CHANGES_REQUIRING_RESTART, check_settings
+from app.change_manager import CHANGES_REQUIRING_RESTART
def gen_username() -> str:
words = top_n_list("en", 5000)
@@ -155,6 +155,7 @@ def logout():
@app.route('/admin', methods=['GET', 'POST'])
@login_required
def admin():
+ raspap_installed = os.path.exists("/var/www/html/raspap")
form = SettingsForm()
populate_settings = ['butterbox_name', 'wifi_password', 'ssid', 'butterbox_hostname', 'root_account_settings', 'ssh_access_settings']
bool_settings = ['enable_access_point','enable_file_viewer', 'enable_map_viewer', 'enable_app_store', 'enable_chat', 'enable_deltachat', 'enable_wifi_sharing']
@@ -214,10 +215,9 @@ def admin():
if form.apply_changes.data:
set_setting('apply_changes', "true")
dump_settings("settings.txt")
- check_settings()
flash(_("⚠️ Changes applied! Please wait for the box to restart."))
- return render_template('admin.html', get_setting=get_setting, form=form)
+ return render_template('admin.html', raspap_installed=raspap_installed, get_setting=get_setting, form=form)
@app.route('/messaging', methods=['GET', 'POST'])
diff --git a/app/static/css/butter_styles.css b/app/static/css/butter_styles.css
index 472306f..97eb2cd 100644
--- a/app/static/css/butter_styles.css
+++ b/app/static/css/butter_styles.css
@@ -4,7 +4,9 @@
.butter-title {
text-align: center;
}
-
+.butter-form-margin {
+ margin-right: 10px;
+}
.butter-service {
border-radius: 20px;
}
diff --git a/app/templates/admin.html b/app/templates/admin.html
index 82b8693..5e60663 100644
--- a/app/templates/admin.html
+++ b/app/templates/admin.html
@@ -16,61 +16,90 @@
{{ form.apply_changes(class="button is-warning") }}
{% endif %}
-
- {{ wtf.form_input_field(form.ssid, form.ssid.errors) }}
-
This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}
+
+
+
Services
+
+
+ {{ wtf.form_bool_field(form.enable_map_viewer) }}
+
Whether map services are enabled.
-
- {{ 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' }}
+
+ {{ wtf.form_bool_field(form.enable_chat) }}
+
Whether Matrix chat services are enabled.
+
+ {{ wtf.form_bool_field(form.enable_deltachat) }}
+
Whether messaging using DeltaChat is enabled.
+
+
+ {{ wtf.form_bool_field(form.enable_file_viewer) }}
+
Whether files services via USB are enabled.
+
+
+ {{ wtf.form_bool_field(form.enable_app_store) }}
+
Whether app store services are enabled.
+
+
+
+
Branding and name
+
{{ 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.
-
{{ wtf.form_input_field(form.butterbox_hostname, form.butterbox_hostname.errors) }}
-
This is used to access the box locally by adding .local or .lan in your browser.
+
This is the URL used to access the box by adding .local in your browser.
Current hostname: {{ get_setting('butterbox_hostname') }}.local.
-
- {{ wtf.form_bool_field(form.enable_access_point) }}
-
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.
-
-
- {{ wtf.form_bool_field(form.enable_map_viewer) }}
-
Whether map services are enabled.
-
-
- {{ wtf.form_bool_field(form.enable_chat) }}
-
Whether chat services are enabled.
-
-
- {{ wtf.form_bool_field(form.enable_deltachat) }}
-
Whether secure messaging using DeltaChat is enabled.
-
-
- {{ wtf.form_bool_field(form.enable_file_viewer) }}
-
Whether files services via USB are enabled.
-
-
- {{ wtf.form_bool_field(form.enable_app_store) }}
-
Whether app store services are enabled.
+
{{ form.butterbox_logo.label }}
+
{{ 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:
+
+
+
+
+
+
Wi-Fi and access point
+
+ {% 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') }}
+
+
+ {{ 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' }}
+
+
+
+ {{ wtf.form_bool_field(form.enable_access_point) }}
+
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.
+
+ {% else %}
+
Access point is only enabled when using a Raspberry Pi.
+ {% endif %}
+
+
+
Access and security
+
+
{{ wtf.form_password_field(form.admin_password, form.admin_password.errors) }}
Password for accessing this browser interface.
-
+
{{ form.root_account_settings.label }}
{% for subfield in form.root_account_settings %}
-
+
{% if get_setting('root_account_settings') == subfield._value() %}
{% else %}
@@ -85,7 +114,7 @@
{{ form.ssh_access_settings.label }}
{% for subfield in form.ssh_access_settings %}
-
+
{% if get_setting('ssh_access_settings') == subfield._value() %}
{% else %}
@@ -96,13 +125,7 @@
{% endfor %}
{{ wtf.field_errors(form.ssh_access_settings.errors) }}
-
-
{{ form.butterbox_logo.label }}
-
{{ 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:
-
-
+
diff --git a/app/change_manager.py b/change_manager.py
similarity index 81%
rename from app/change_manager.py
rename to change_manager.py
index 1ef4119..79f96eb 100644
--- a/app/change_manager.py
+++ b/change_manager.py
@@ -1,8 +1,9 @@
import os
import re
+import time
+from datetime import datetime
from subprocess import run
import json
-from app import app
CHANGES_REQUIRING_RESTART = ['wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat', 'butterbox_hostname']
# 'ssh_access_settings', 'root_account_settings']
@@ -15,6 +16,8 @@ def lock_root_account():
def enable_service(service: str):
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
+ if 'not_found' in is_enabled.stdout:
+ return False
if 'disabled' in is_enabled.stdout:
enable = run(["sudo", "systemctl", "enable", service], capture_output = True, text = True)
if enable.returncode != 0:
@@ -23,6 +26,8 @@ def enable_service(service: str):
def disable_service(service: str):
is_enabled = run(["sudo", "systemctl", "is-enabled", service], capture_output = True, text = True)
+ if 'not_found' in is_enabled.stdout:
+ return False
if 'enabled' in is_enabled.stdout:
result = run(["sudo", "systemctl", "disable", service])
if result.returncode != 0:
@@ -30,7 +35,7 @@ def disable_service(service: str):
return True
def load_setting(setting):
- with open("settings.txt", "r") as f:
+ with open("./app/settings.txt", "r") as f:
settings = json.load(f)
return settings[setting]
@@ -61,7 +66,6 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
else:
with open(target_file, "r") as f:
lines = f.readlines()
- print(f"Existing lines are: {lines}")
for i, line in enumerate(lines):
match = re.fullmatch(replacement, line)
if match:
@@ -71,24 +75,24 @@ def change_line_in_file(target_file: str, regex: str, replacement: str):
match = re.fullmatch(regex, line)
if match:
lines.pop(i)
- print(f"Found a match at line {i}, {match.string}")
break
try:
lines.append(replacement)
except NameError:
raise NameError(f"File {target_file} is empty.")
- print(f"Lines to be written to file are {lines}")
new_lines = "".join(lines)
with open(target_file, "w") as f:
f.write(new_lines)
-def check_settings():
- print(f"Checking settings...")
- print(f"App config is {app.config['SETTINGS_CHANGED']}")
- if app.config['SETTINGS_CHANGED']:
+def check_settings(raspap_installed: bool):
+ if not os.path.exists("./settings.txt"):
+ return
+ last_modified = os.path.getmtime('./settings.txt')
+ diff_in_minutes = (datetime.now().timestamp() - last_modified)/60
+ if diff_in_minutes < 2:
for s in CHANGES_REQUIRING_RESTART:
- if s == "wifi_password":
+ if s == "wifi_password" and raspap_installed:
regex_wpa_method = "wpa=.*?\n"
if load_setting("wifi_password") == "":
change_line_in_file("/etc/hostapd/hostapd.conf", regex_wpa_method, f"wpa=none\n")
@@ -98,25 +102,26 @@ def check_settings():
change_line_in_file("/etc/hostapd/hostapd.conf", regex_pass,
f"wpa_passphrase={load_setting("wifi_password")}\n")
- if s == "ssid":
+ if s == "ssid" and raspap_installed:
regex_ssid = "ssid=.*?\n"
change_line_in_file("/etc/hostapd/hostapd.conf", regex_ssid, f"ssid={load_setting("ssid")}\n")
if s == "enable_chat":
change_service_status("enable_chat", "dendrite")
- if s == "enable_access_point":
+ if s == "enable_access_point" and raspap_installed:
change_service_status("enable_access_point", "raspapd")
if s == "enable_delta_chat":
change_service_status("enable_delta_chat", "madmail")
if s == "butterbox_hostname":
pass
# change in butterbox-dendrite.conf
- regex_matrix_server = "server_name:.*?.lan\n"
+ regex_matrix_server = "server_name:.*?.local\n"
change_line_in_file("../dendrite/butterbox-dendrite.conf", regex_matrix_server,
- f"server_name: {load_setting("butterbox_hostname")}.lan\n")
+ f"server_name: {load_setting("butterbox_hostname")}.local\n")
# change in butterbox-dnsmasq.conf
- regex_dns = "address=/.*?.lan/10.3.141.1\n"
- change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns,
- f"address=/{load_setting("butterbox_hostname")}.lan/10.3.141.1\n")
+ if raspap_installed:
+ regex_dns = "address=/.*?.local/10.3.141.1\n"
+ change_line_in_file("/etc/dnsmasq.d/butterbox-dnsmasq.conf", regex_dns,
+ f"address=/{load_setting("butterbox_hostname")}.local/10.3.141.1\n")
# change in keanu-weblite compiled assets
change_keanu_weblite_config(load_setting("butterbox_hostname"))
if s == "ssh_access_settings":
@@ -140,6 +145,13 @@ def check_settings():
if load_setting("root_account_settings") == "lock_root_account":
lock_root_account()
else:
+ # root password implementation here
pass
+if __name__ == "__main__":
+ raspap_installed = os.path.exists("/var/www/html/raspapd")
+ while True:
+ check_settings(raspap_installed)
+ time.sleep(30)
+
diff --git a/config.py b/config.py
index 4eda425..c24ea41 100644
--- a/config.py
+++ b/config.py
@@ -24,4 +24,4 @@ class Config:
ENABLE_FILE_VIEWER = "true"
ENABLE_DELTACHAT = "true"
CONVENE_INSTALL_PATH = "/chat"
- ENABLE_WIFI_SHARING = "true"
\ No newline at end of file
+ ENABLE_WIFI_SHARING = "true" if os.path.exists("/var/www/html/raspap") else "false"
\ No newline at end of file