From 70c503f58e6f399f70ce409f01c9d478b20cf077 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Wed, 8 Jul 2026 11:14:40 +0200 Subject: [PATCH] fix non-english git and add faster stat Signed-off-by: Vladimir Mandic --- CHANGELOG.md | 2 + installer.py | 5 +- modules/modelstats.py | 77 +++++++++++++------------------ modules/ui_extra_networks_unet.py | 2 +- 4 files changed, 39 insertions(+), 47 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69e26749..35deff4d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ - lora: fix lora text-encoder loader - amd: hipBLASLt improved detection, thanks @0xDELUXA - api: validate swagger schema + - installer: handle detached branch on non-english setups + - fs: faster stat ## Update for 2026-07-07 diff --git a/installer.py b/installer.py index c5066d307..5ce533735 100644 --- a/installer.py +++ b/installer.py @@ -389,7 +389,7 @@ def branch(folder=None): marked = [x for x in branches if x.startswith('*')] if len(branches) > 0 and len(marked) > 0: b = marked[0] - if 'detached' in b and len(branches) > 1: + if ('detached' in b or 'HEAD' in b) and len(branches) > 1: b = branches[1].strip() log.debug(f'Git detached head detected: folder="{folder}" reattach={b}') except Exception: @@ -429,6 +429,9 @@ def update(folder, keep_branch = False, rebase = True): if b is None: res = git(f'pull {arg}', folder) debug(f'Install update: folder={folder} branch={b} args={arg} {res}') + elif ' ' in b or '(' in b or ')' in b: + res = f'Install update: folder="{folder}" branch="{b}" branch name invalid' + log.error(res) else: res = git(f'pull origin {b} {arg}', folder) debug(f'Install update: folder={folder} branch={b} args={arg} {res}') diff --git a/modules/modelstats.py b/modules/modelstats.py index ab67dd21e..1d086ce9f 100644 --- a/modules/modelstats.py +++ b/modules/modelstats.py @@ -13,57 +13,44 @@ def walk(folder: str): return files -def stat(fn: str): - if fn is None or len(fn) == 0 or not os.path.exists(fn): - return 0, datetime.fromtimestamp(0) - fs_stat = os.stat(fn, follow_symlinks=False) - mtime = datetime.fromtimestamp(fs_stat.st_mtime).replace(microsecond=0) - if os.path.islink(fn): - size = 0 - elif os.path.isfile(fn): - size = round(fs_stat.st_size) - elif os.path.isdir(fn): - size = round(sum(stat(fn)[0] for fn in walk(fn))) - else: - size = 0 - return size, mtime +def stat(folder: str) -> tuple[int, datetime]: + _size = 0 + _mtime = 0.0 - -""" -def stat(path: str): - try: # 1. Base Case: Check if path exists safely - root_stat = os.stat(path, follow_symlinks=False) # We fetch the stat of the root path once - except (FileNotFoundError, PermissionError): - return 0, datetime.fromtimestamp(0) - if os.path.stat.S_ISLNK(root_stat.st_mode): # 2. Handle Symlinks (Checking st_mode is faster than os.path.islink) - return 0, datetime.fromtimestamp(root_stat.st_mtime).replace(microsecond=0) - if os.path.stat.S_ISREG(root_stat.st_mode): # 3. Handle Single Files - return root_stat.st_size, datetime.fromtimestamp(root_stat.st_mtime).replace(microsecond=0) - # 4. Handle Directories - total_size = 0 - latest_mtime = root_stat.st_mtime - try: - with os.scandir(path) as entries: + def recurse(folder: str): + nonlocal _size, _mtime + with os.scandir(folder) as entries: for entry in entries: try: - entry_stat = entry.stat(follow_symlinks=False) # Fetch cached stat object from the entry - if entry_stat.st_mtime > latest_mtime: # Track the latest modification time across everything - latest_mtime = entry_stat.st_mtime - if entry.is_symlink(): - continue - if entry.is_file(): - total_size += entry_stat.st_size - elif entry.is_dir(): - sub_size, sub_mtime = stat(entry.path) # Recursively scan subfolders - total_size += sub_size - if sub_mtime.timestamp() > latest_mtime: - latest_mtime = sub_mtime.timestamp() - except (FileNotFoundError, PermissionError): # Skip files that disappear or lack permissions during runtime + if entry.is_file(follow_symlinks=False): + try: + _stat = entry.stat(follow_symlinks=False) + except Exception: + _stat = os.stat(entry.path, follow_symlinks=False) + _size += _stat.st_size + if _stat.st_mtime > _mtime: + _mtime = _stat.st_mtime + elif entry.is_dir(follow_symlinks=False): + recurse(entry.path) + except (FileNotFoundError, PermissionError): continue + + try: + if os.path.isfile(folder): + _stat = os.stat(folder, follow_symlinks=False) + _size = _stat.st_size + _mtime = _stat.st_mtime + elif os.path.isdir(folder): + recurse(folder) + else: + pass except (FileNotFoundError, PermissionError): pass - return total_size, datetime.fromtimestamp(latest_mtime).replace(microsecond=0) -""" + try: + _datetime = datetime.fromtimestamp(_mtime).replace(microsecond=0) + except (OSError, ValueError): + _datetime = datetime.fromtimestamp(0) + return _size, _datetime class Module: diff --git a/modules/ui_extra_networks_unet.py b/modules/ui_extra_networks_unet.py index 7d6e016d6..6b03b7be0 100644 --- a/modules/ui_extra_networks_unet.py +++ b/modules/ui_extra_networks_unet.py @@ -37,7 +37,7 @@ class ExtraNetworksPageUNets(ui_extra_networks.ExtraNetworksPage): } yield record except Exception as e: - log.debug(f'Networks error: type=vae file="{filename}" {e}') + log.debug(f'Networks error: type=unet file="{filename}" {e}') def allowed_directories_for_previews(self): return [v for v in [shared.opts.unet_dir] if v is not None]