stable-diffusion-webui
138 строк · 4.1 Кб
1import os2import re3
4from modules import shared5from modules.paths_internal import script_path, cwd6
7
8def natural_sort_key(s, regex=re.compile('([0-9]+)')):9return [int(text) if text.isdigit() else text.lower() for text in regex.split(s)]10
11
12def listfiles(dirname):13filenames = [os.path.join(dirname, x) for x in sorted(os.listdir(dirname), key=natural_sort_key) if not x.startswith(".")]14return [file for file in filenames if os.path.isfile(file)]15
16
17def html_path(filename):18return os.path.join(script_path, "html", filename)19
20
21def html(filename):22path = html_path(filename)23
24try:25with open(path, encoding="utf8") as file:26return file.read()27except OSError:28return ""29
30
31def walk_files(path, allowed_extensions=None):32if not os.path.exists(path):33return34
35if allowed_extensions is not None:36allowed_extensions = set(allowed_extensions)37
38items = list(os.walk(path, followlinks=True))39items = sorted(items, key=lambda x: natural_sort_key(x[0]))40
41for root, _, files in items:42for filename in sorted(files, key=natural_sort_key):43if allowed_extensions is not None:44_, ext = os.path.splitext(filename)45if ext.lower() not in allowed_extensions:46continue47
48if not shared.opts.list_hidden_files and ("/." in root or "\\." in root):49continue50
51yield os.path.join(root, filename)52
53
54def ldm_print(*args, **kwargs):55if shared.opts.hide_ldm_prints:56return57
58print(*args, **kwargs)59
60
61def truncate_path(target_path, base_path=cwd):62abs_target, abs_base = os.path.abspath(target_path), os.path.abspath(base_path)63try:64if os.path.commonpath([abs_target, abs_base]) == abs_base:65return os.path.relpath(abs_target, abs_base)66except ValueError:67pass68return abs_target69
70
71class MassFileListerCachedDir:72"""A class that caches file metadata for a specific directory."""73
74def __init__(self, dirname):75self.files = None76self.files_cased = None77self.dirname = dirname78
79stats = ((x.name, x.stat(follow_symlinks=False)) for x in os.scandir(self.dirname))80files = [(n, s.st_mtime, s.st_ctime) for n, s in stats]81self.files = {x[0].lower(): x for x in files}82self.files_cased = {x[0]: x for x in files}83
84
85class MassFileLister:86"""A class that provides a way to check for the existence and mtime/ctile of files without doing more than one stat call per file."""87
88def __init__(self):89self.cached_dirs = {}90
91def find(self, path):92"""93Find the metadata for a file at the given path.
94
95Returns:
96tuple or None: A tuple of (name, mtime, ctime) if the file exists, or None if it does not.
97"""
98
99dirname, filename = os.path.split(path)100
101cached_dir = self.cached_dirs.get(dirname)102if cached_dir is None:103cached_dir = MassFileListerCachedDir(dirname)104self.cached_dirs[dirname] = cached_dir105
106stats = cached_dir.files_cased.get(filename)107if stats is not None:108return stats109
110stats = cached_dir.files.get(filename.lower())111if stats is None:112return None113
114try:115os_stats = os.stat(path, follow_symlinks=False)116return filename, os_stats.st_mtime, os_stats.st_ctime117except Exception:118return None119
120def exists(self, path):121"""Check if a file exists at the given path."""122
123return self.find(path) is not None124
125def mctime(self, path):126"""127Get the modification and creation times for a file at the given path.
128
129Returns:
130tuple: A tuple of (mtime, ctime) if the file exists, or (0, 0) if it does not.
131"""
132
133stats = self.find(path)134return (0, 0) if stats is None else stats[1:3]135
136def reset(self):137"""Clear the cache of all directories."""138self.cached_dirs.clear()139