From 85c020cd129ffadefd7090849cead89bb495118e Mon Sep 17 00:00:00 2001 From: Will Miao Date: Sun, 31 May 2026 15:52:50 +0800 Subject: [PATCH] fix(update): preserve wildcards, backups dirs during ZIP upgrade, add log rotation - Add wildcards and backups to skip_files in all three ZIP upgrade skip locations: _clean_plugin_folder, copy loop, .tracking generation - Remove logs from skip_files (logs are transient and rotate automatically) - Add _prune_old_logs() to session_logging.py: keeps only the 3 newest session log files, deletes older ones on each standalone startup --- py/routes/update_routes.py | 19 +++++++++++-------- py/utils/session_logging.py | 22 ++++++++++++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/py/routes/update_routes.py b/py/routes/update_routes.py index 95038838..79012582 100644 --- a/py/routes/update_routes.py +++ b/py/routes/update_routes.py @@ -225,7 +225,7 @@ class UpdateRoutes: logger.debug("Could not close downloaded-version history database", exc_info=True) # Skip settings.json, civitai, model cache and runtime cache folders - UpdateRoutes._clean_plugin_folder(plugin_root, skip_files=['settings.json', 'civitai', 'model_cache', 'cache']) + UpdateRoutes._clean_plugin_folder(plugin_root, skip_files=['settings.json', 'civitai', 'model_cache', 'cache', 'wildcards', 'backups']) # Extract ZIP to temp dir with tempfile.TemporaryDirectory() as tmp_dir: @@ -234,16 +234,17 @@ class UpdateRoutes: # Find extracted folder (GitHub ZIP contains a root folder) extracted_root = next(os.scandir(tmp_dir)).path - # Copy files, skipping settings.json and civitai folder + # Copy files, skipping user data that should be preserved + skip_items = {'settings.json', 'civitai', 'wildcards', 'backups'} for item in os.listdir(extracted_root): - if item == 'settings.json' or item == 'civitai': + if item in skip_items: continue src = os.path.join(extracted_root, item) dst = os.path.join(plugin_root, item) if os.path.isdir(src): if os.path.exists(dst): shutil.rmtree(dst) - shutil.copytree(src, dst, ignore=shutil.ignore_patterns('settings.json', 'civitai')) + shutil.copytree(src, dst, ignore=shutil.ignore_patterns(*skip_items)) else: shutil.copy2(src, dst) @@ -251,15 +252,17 @@ class UpdateRoutes: # for ComfyUI Manager to work properly tracking_info_file = os.path.join(plugin_root, '.tracking') tracking_files = [] + skip_tracked = {'civitai', 'wildcards', 'backups'} for root, dirs, files in os.walk(extracted_root): - # Skip civitai folder and its contents + # Skip user data directories and their contents rel_root = os.path.relpath(root, extracted_root) - if rel_root == 'civitai' or rel_root.startswith('civitai' + os.sep): + top_dir = rel_root.split(os.sep)[0] if rel_root != '.' else '' + if top_dir in skip_tracked: continue for file in files: rel_path = os.path.relpath(os.path.join(root, file), extracted_root) - # Skip settings.json and any file under civitai - if rel_path == 'settings.json' or rel_path.startswith('civitai' + os.sep): + # Skip settings.json and any file under user data dirs + if rel_path == 'settings.json' or rel_path.split(os.sep)[0] in skip_tracked: continue tracking_files.append(rel_path.replace("\\", "/")) with open(tracking_info_file, "w", encoding='utf-8') as file: diff --git a/py/utils/session_logging.py b/py/utils/session_logging.py index 54903713..9b80a60f 100644 --- a/py/utils/session_logging.py +++ b/py/utils/session_logging.py @@ -64,6 +64,27 @@ def _build_log_file_path(settings_file: str | None, started_at: datetime) -> str return os.path.join(log_dir, f"standalone-session-{timestamp}.log") +_KEEP_LOG_COUNT = 3 + + +def _prune_old_logs(log_dir: str) -> None: + """Remove older session log files, keeping only the ``_KEEP_LOG_COUNT`` newest.""" + try: + files = [ + os.path.join(log_dir, name) + for name in os.listdir(log_dir) + if name.startswith("standalone-session-") and name.endswith(".log") + ] + except OSError: + return + files.sort(key=os.path.getmtime, reverse=True) + for path in files[_KEEP_LOG_COUNT:]: + try: + os.remove(path) + except OSError: + pass + + def setup_standalone_session_logging(settings_file: str | None) -> StandaloneSessionLogState: global _session_state @@ -90,6 +111,7 @@ def setup_standalone_session_logging(settings_file: str | None) -> StandaloneSes file_handler.set_name(_FILE_HANDLER_NAME) file_handler.setFormatter(formatter) root_logger.addHandler(file_handler) + _prune_old_logs(os.path.dirname(log_file_path)) _session_state = StandaloneSessionLogState( started_at=started_at,