diff --git a/docker/routlin-dash/app/view_page.py b/docker/routlin-dash/app/view_page.py index dd8af80..567d619 100644 --- a/docker/routlin-dash/app/view_page.py +++ b/docker/routlin-dash/app/view_page.py @@ -5,7 +5,7 @@ import sanitize import validation as validate from datetime import datetime, timezone 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, WEB_APP_DISPLAY_NAME, CONFIGS_DIR, DATA_DIR, DDNS_TIMER_NAME +from config_utils import core_hash, get_pending_entries, get_dashboard_pending, _seconds_until_next_run, _format_timing, _is_locked, _lock_mtime, WEB_APP_DISPLAY_NAME, CONFIGS_DIR, DATA_DIR bp = Blueprint('view_page', __name__) @@ -566,17 +566,14 @@ def _public_ip_info(ddns_cfg): return 'DDNS Offline', domains_sub, next_interval, '' def _ddns_last_checked(): - """Return 'Last checked: X ago' based on when the DDNS timer last fired, or ''.""" + """Return 'Last checked: X ago' by scanning ddns.log in reverse for 'Public IP retrieved from'.""" try: - out = _run(f'systemctl show {DDNS_TIMER_NAME}.timer --property=LastTriggerUSec --timestamp=utc') - val = out.split('=', 1)[1].strip() if '=' in out else '' - if not val or val == '0' or val == 'n/a': - return '' - parts = val.split() # ['Mon', '2026-05-25', '04:28:00', 'UTC'] - if len(parts) >= 3: - dt = datetime.strptime(f'{parts[1]} {parts[2]}', '%Y-%m-%d %H:%M:%S') - mtime = dt.replace(tzinfo=timezone.utc).timestamp() - return f'Last checked: {_relative_time(mtime)}' + with open(f'{CONFIGS_DIR}/ddns.log') as f: + lines = f.read().splitlines() + for line in reversed(lines): + if 'Public IP retrieved from' in line: + dt = datetime.strptime(line[:19], '%Y-%m-%d %H:%M:%S') + return f'Last checked: {_relative_time(dt.timestamp())}' except Exception: pass return ''