From 4e18aea5ffc0b6722176e64df2d0caa5c239de0e Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Tue, 19 Nov 2024 15:44:50 +0100 Subject: [PATCH] UI - Show local timezone info in settings (for future functionality) #2793 --- changedetectionio/flask_app.py | 33 ++++++++++++++++++++--- changedetectionio/model/App.py | 3 ++- changedetectionio/templates/settings.html | 4 +++ docker-compose.yml | 3 +++ requirements.txt | 1 - 5 files changed, 39 insertions(+), 5 deletions(-) diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py index 2f6be5c131a..b616600611f 100644 --- a/changedetectionio/flask_app.py +++ b/changedetectionio/flask_app.py @@ -84,7 +84,7 @@ csrf.init_app(app) notification_debug_log=[] -# get locale ready +# Locale for correct presentation of prices etc default_locale = locale.getdefaultlocale() logger.info(f"System locale default is {default_locale}") try: @@ -159,6 +159,21 @@ def _jinja2_filter_pagination_slice(arr, skip): return arr +def app_get_system_time(): + from zoneinfo import ZoneInfo # Built-in timezone support in Python 3.9+ + + system_timezone = datastore.data['settings']['application'].get('timezone') + if not system_timezone: + system_timezone = os.environ.get("TZ") + + try: + system_zone = ZoneInfo(system_timezone) + except Exception as e: + logger.warning(f'Warning, unable to use timezone "{system_timezone}" defaulting to UTC- {str(e)}') + system_zone = ZoneInfo("UTC") # Fallback to UTC if the timezone is invalid + + return system_zone + @app.template_filter('format_seconds_ago') def _jinja2_filter_seconds_precise(timestamp): if timestamp == False: @@ -243,6 +258,9 @@ def changedetection_app(config=None, datastore_o=None): # (instead of the global var) app.config['DATASTORE'] = datastore_o + # Just to check (it will output some debug if not) + app_get_system_time() + login_manager = flask_login.LoginManager(app) login_manager.login_view = 'login' app.secret_key = init_app_secret(config['datastore_path']) @@ -882,6 +900,7 @@ def edit_page(uuid): @login_optionally_required def settings_page(): from changedetectionio import forms + from datetime import datetime default = deepcopy(datastore.data['settings']) if datastore.proxy_list is not None: @@ -949,6 +968,13 @@ def settings_page(): else: flash("An error occurred, please see below.", "error") + + system_timezone = app_get_system_time() + system_time = datetime.now(system_timezone) + + # Fallback for locale formatting + formatted_system_time = system_time.strftime("%Y-%m-%d %H:%M:%S %Z%z") # Locale-aware time + output = render_template("settings.html", api_key=datastore.data['settings']['application'].get('api_access_token'), emailprefix=os.getenv('NOTIFICATION_MAIL_BUTTON_PREFIX', False), @@ -956,7 +982,9 @@ def settings_page(): form=form, hide_remove_pass=os.getenv("SALTED_PASS", False), min_system_recheck_seconds=int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 3)), - settings_application=datastore.data['settings']['application'] + settings_application=datastore.data['settings']['application'], + system_time=formatted_system_time, + timezone_name=system_timezone ) return output @@ -1709,7 +1737,6 @@ def notification_runner(): def ticker_thread_check_time_launch_checks(): import random from changedetectionio import update_worker - proxy_last_called_time = {} recheck_time_minimum_seconds = int(os.getenv('MINIMUM_SECONDS_RECHECK_TIME', 3)) diff --git a/changedetectionio/model/App.py b/changedetectionio/model/App.py index fdd627ed978..f148671c7c1 100644 --- a/changedetectionio/model/App.py +++ b/changedetectionio/model/App.py @@ -52,7 +52,8 @@ class model(dict): 'schema_version' : 0, 'shared_diff_access': False, 'webdriver_delay': None , # Extra delay in seconds before extracting text - 'tags': {} #@todo use Tag.model initialisers + 'tags': {}, #@todo use Tag.model initialisers + 'timezone': None, } } } diff --git a/changedetectionio/templates/settings.html b/changedetectionio/templates/settings.html index 53006c6229e..50ffebf5dc0 100644 --- a/changedetectionio/templates/settings.html +++ b/changedetectionio/templates/settings.html @@ -78,6 +78,10 @@ {{ render_checkbox_field(form.application.form.empty_pages_are_a_change) }} When a request returns no content, or the HTML does not contain any text, is this considered a change? +
+

Local Time: {{ system_time }}

+

Timezone: {{ timezone_name }}

+
{% if form.requests.proxy %}
{{ render_field(form.requests.form.proxy, class="fetch-backend-proxy") }} diff --git a/docker-compose.yml b/docker-compose.yml index 57c413c523d..3ec186e727d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -64,6 +64,9 @@ services: # # For complete privacy if you don't want to use the 'check version' / telemetry service # - DISABLE_VERSION_CHECK=true + # + # A valid timezone name to run as (for scheduling watch checking) see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones + # - TZ=America/Los_Angeles # Comment out ports: when using behind a reverse proxy , enable networks: etc. ports: diff --git a/requirements.txt b/requirements.txt index b5d58f410f1..8182f0b4c86 100644 --- a/requirements.txt +++ b/requirements.txt @@ -95,4 +95,3 @@ babel # Needed for > 3.10, https://github.com/microsoft/playwright-python/issues/2096 greenlet >= 3.0.3 -