Development

This commit is contained in:
Matthew Grotke 2026-05-24 00:47:43 -04:00
parent 62fe75d7fd
commit c5d1c7890a
10 changed files with 24 additions and 21 deletions

View file

@ -2,12 +2,11 @@ from flask import Blueprint, request, session, redirect, flash
import json, re import json, re
from datetime import datetime, timezone from datetime import datetime, timezone
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
import sanitize import sanitize
bp = Blueprint('action_add_account', __name__) bp = Blueprint('action_add_account', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
VALID_LEVELS = {'viewer', 'administrator', 'manager'} VALID_LEVELS = {'viewer', 'administrator', 'manager'}

View file

@ -1,11 +1,10 @@
from flask import Blueprint, request, session, redirect, flash from flask import Blueprint, request, session, redirect, flash
import json, bcrypt import json, bcrypt
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
bp = Blueprint('action_change_password', __name__) bp = Blueprint('action_change_password', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
def _load_accounts(): def _load_accounts():

View file

@ -1,9 +1,10 @@
from flask import Blueprint, redirect, flash from flask import Blueprint, redirect, flash
from auth import require_level from auth import require_level
from config_utils import CONFIGS_DIR
bp = Blueprint('action_clear_ddns_log', __name__) bp = Blueprint('action_clear_ddns_log', __name__)
LOG_FILE = '/configs/ddns.log' LOG_FILE = f'{CONFIGS_DIR}/ddns.log'
@bp.route('/action/clear_ddns_log', methods=['POST']) @bp.route('/action/clear_ddns_log', methods=['POST'])

View file

@ -3,13 +3,11 @@ import json, os, bcrypt, secrets, smtplib
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
from email.message import EmailMessage from email.message import EmailMessage
from auth import require_level from auth import require_level
from config_utils import PRODUCT_DISPLAY_NAME from config_utils import PRODUCT_DISPLAY_NAME, ACCOUNTS_FILE
import sanitize import sanitize
bp = Blueprint('action_create_account', __name__) bp = Blueprint('action_create_account', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
CODE_TTL_MIN = 15 CODE_TTL_MIN = 15

View file

@ -1,11 +1,10 @@
from flask import Blueprint, request, session, redirect, flash from flask import Blueprint, request, session, redirect, flash
import json import json
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
bp = Blueprint('action_delete_account', __name__) bp = Blueprint('action_delete_account', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
def _load_accounts(): def _load_accounts():

View file

@ -1,16 +1,16 @@
from flask import Blueprint, request, session, redirect, flash from flask import Blueprint, request, session, redirect, flash
import json, bcrypt import json, bcrypt
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
import sanitize import sanitize
bp = Blueprint('action_log_in', __name__) bp = Blueprint('action_log_in', __name__)
DATA_DIR = '/data'
def _load_accounts(): def _load_accounts():
try: try:
with open(f'{DATA_DIR}/authorized_accounts.json') as f: with open(ACCOUNTS_FILE) as f:
return json.load(f) return json.load(f)
except Exception: except Exception:
return {'accounts': []} return {'accounts': []}

View file

@ -1,12 +1,11 @@
from flask import Blueprint, request, session, redirect, flash from flask import Blueprint, request, session, redirect, flash
import json import json
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
import sanitize import sanitize
bp = Blueprint('action_save_preferences', __name__) bp = Blueprint('action_save_preferences', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
def _load_accounts(): def _load_accounts():

View file

@ -2,11 +2,10 @@ from flask import Blueprint, request, session, redirect, flash
import json, os, secrets import json, os, secrets
from datetime import datetime, timezone, timedelta from datetime import datetime, timezone, timedelta
from auth import require_level from auth import require_level
from config_utils import ACCOUNTS_FILE
bp = Blueprint('action_verify_email', __name__) bp = Blueprint('action_verify_email', __name__)
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
def _load_accounts(): def _load_accounts():

View file

@ -3,6 +3,8 @@ from datetime import datetime, timezone
from flask import session from flask import session
CONFIGS_DIR = '/routlin_location' CONFIGS_DIR = '/routlin_location'
DATA_DIR = '/data'
ACCOUNTS_FILE = f'{DATA_DIR}/authorized_accounts.json'
CORE_FILE = f'{CONFIGS_DIR}/core.json' CORE_FILE = f'{CONFIGS_DIR}/core.json'
DASHBOARD_QUEUE = f'{CONFIGS_DIR}/.dashboard-queue' DASHBOARD_QUEUE = f'{CONFIGS_DIR}/.dashboard-queue'
DASHBOARD_DONE = f'{CONFIGS_DIR}/.dashboard-done' DASHBOARD_DONE = f'{CONFIGS_DIR}/.dashboard-done'

View file

@ -5,12 +5,10 @@ import sanitize
import validation as validate import validation as validate
from datetime import datetime, timezone from datetime import datetime, timezone
from zoneinfo import ZoneInfo, ZoneInfoNotFoundError from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from config_utils import core_hash, get_pending_entries, get_dashboard_pending, _seconds_until_next_run, _format_timing, _is_locked, _lock_mtime, PRODUCT_DISPLAY_NAME from config_utils import core_hash, get_pending_entries, get_dashboard_pending, _seconds_until_next_run, _format_timing, _is_locked, _lock_mtime, PRODUCT_DISPLAY_NAME, CONFIGS_DIR, DATA_DIR
bp = Blueprint('view_page', __name__) bp = Blueprint('view_page', __name__)
DATA_DIR = '/data'
CONFIGS_DIR = '/routlin_location'
LEVEL_RANK = {'nothing': 0, 'viewer': 1, 'administrator': 2, 'manager': 3} LEVEL_RANK = {'nothing': 0, 'viewer': 1, 'administrator': 2, 'manager': 3}
@ -1485,16 +1483,25 @@ def render_layout(view_id, content_html, tokens):
try: try:
import json as _j import json as _j
st = _j.load(open(f'{CONFIGS_DIR}/.status')) st = _j.load(open(f'{CONFIGS_DIR}/.status'))
grouped = {'error': [], 'warning': []}
for section in ('configurations', 'logs'): for section in ('configurations', 'logs'):
for item in st.get(section, []): for item in st.get(section, []):
if item.get('status') == 'problem': if item.get('status') == 'problem':
sev = item.get('severity', 'error') sev = item.get('severity', 'error')
cls = 'info-bar-danger' if sev == 'error' else 'info-bar-warning'
text = e(item.get('detail', item.get('name', ''))) text = e(item.get('detail', item.get('name', '')))
tip = item.get('suggestion', '') tip = item.get('suggestion', '')
if tip: if tip:
text += f' <span style="opacity:0.75">{e(tip)}</span>' text += f' <span style="opacity:0.75">{e(tip)}</span>'
problem_bars += f'<div class="info-bar {cls}">{text}</div>\n' grouped.setdefault(sev, []).append(text)
for sev, items in grouped.items():
if not items:
continue
cls = 'info-bar-danger' if sev == 'error' else 'info-bar-warning'
if len(items) == 1:
content = items[0]
else:
content = '<ul style="margin:0;padding-left:1.25em">' + ''.join(f'<li>{t}</li>' for t in items) + '</ul>'
problem_bars += f'<div class="info-bar {cls}">{content}</div>\n'
except Exception: except Exception:
pass pass