From 4f362385e169831bd6518c7f3171ecbfc8c1de4a Mon Sep 17 00:00:00 2001 From: dgtlmoon Date: Mon, 16 Jun 2025 17:49:50 +0200 Subject: [PATCH] Better path cross-platform file handling (#3265) --- changedetectionio/flask_app.py | 2 +- changedetectionio/store.py | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/changedetectionio/flask_app.py b/changedetectionio/flask_app.py index a254e886..f556753e 100644 --- a/changedetectionio/flask_app.py +++ b/changedetectionio/flask_app.py @@ -100,7 +100,7 @@ watch_api = Api(app, decorators=[csrf.exempt]) def init_app_secret(datastore_path): secret = "" - path = "{}/secret.txt".format(datastore_path) + path = os.path.join(datastore_path, "secret.txt") try: with open(path, "r") as f: diff --git a/changedetectionio/store.py b/changedetectionio/store.py index 5606999f..a7b7d809 100644 --- a/changedetectionio/store.py +++ b/changedetectionio/store.py @@ -13,6 +13,7 @@ import json import os import re import secrets +import sys import threading import time import uuid as uuid_builder @@ -45,7 +46,7 @@ class ChangeDetectionStore: # logging.basicConfig(filename='/dev/stdout', level=logging.INFO) self.__data = App.model() self.datastore_path = datastore_path - self.json_store_path = "{}/url-watches.json".format(self.datastore_path) + self.json_store_path = os.path.join(self.datastore_path, "url-watches.json") logger.info(f"Datastore path is '{self.json_store_path}'") self.needs_write = False self.start_time = time.time() @@ -118,14 +119,12 @@ class ChangeDetectionStore: test_list = self.proxy_list # Helper to remove password protection - password_reset_lockfile = "{}/removepassword.lock".format(self.datastore_path) + password_reset_lockfile = os.path.join(self.datastore_path, "removepassword.lock") if path.isfile(password_reset_lockfile): self.__data['settings']['application']['password'] = False unlink(password_reset_lockfile) if not 'app_guid' in self.__data: - import os - import sys if "pytest" in sys.modules or "PYTEST_CURRENT_TEST" in os.environ: self.__data['app_guid'] = "test-" + str(uuid_builder.uuid4()) else: @@ -386,9 +385,9 @@ class ChangeDetectionStore: return new_uuid def visualselector_data_is_ready(self, watch_uuid): - output_path = "{}/{}".format(self.datastore_path, watch_uuid) - screenshot_filename = "{}/last-screenshot.png".format(output_path) - elements_index_filename = "{}/elements.deflate".format(output_path) + output_path = os.path.join(self.datastore_path, watch_uuid) + screenshot_filename = os.path.join(output_path, "last-screenshot.png") + elements_index_filename = os.path.join(output_path, "elements.deflate") if path.isfile(screenshot_filename) and path.isfile(elements_index_filename) : return True @@ -474,7 +473,7 @@ class ChangeDetectionStore: # Load from external config file if path.isfile(proxy_list_file): - with open("{}/proxies.json".format(self.datastore_path)) as f: + with open(os.path.join(self.datastore_path, "proxies.json")) as f: proxy_list = json.load(f) # Mapping from UI config if available @@ -732,10 +731,10 @@ class ChangeDetectionStore: logger.critical(f"Applying update_{update_n}") # Wont exist on fresh installs if os.path.exists(self.json_store_path): - shutil.copyfile(self.json_store_path, self.datastore_path+"/url-watches-before-{}.json".format(update_n)) + shutil.copyfile(self.json_store_path, os.path.join(self.datastore_path, f"url-watches-before-{update_n}.json")) try: - update_method = getattr(self, "update_{}".format(update_n))() + update_method = getattr(self, f"update_{update_n}")() except Exception as e: logger.error(f"Error while trying update_{update_n}") logger.error(e)