From 8e5d9b4320234c211689a9f643484aca21c84c0a Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Sat, 17 Jan 2026 13:17:30 +0100 Subject: [PATCH] Update engine.py --- engine.py | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/engine.py b/engine.py index 31efd2c..fc1e7af 100644 --- a/engine.py +++ b/engine.py @@ -9,12 +9,16 @@ class SorterEngine: @staticmethod def get_images(path): + """Returns list of image files in a directory.""" exts = ('.jpg', '.jpeg', '.png', '.webp', '.bmp', '.tiff') if not path or not os.path.exists(path): return [] - return sorted([f for f in os.listdir(path) if f.lower().endswith(exts)]) + try: + return sorted([f for f in os.listdir(path) if f.lower().endswith(exts)]) + except: return [] @staticmethod def get_id_mapping(path): + """Maps idXXX prefixes to full filenames.""" mapping = {} for f in SorterEngine.get_images(path): if f.startswith("id") and "_" in f: @@ -24,19 +28,22 @@ class SorterEngine: @staticmethod def get_max_id_number(folder_path): + """Finds the highest idXXX_ prefix in a folder.""" max_id = 0 if not folder_path or not os.path.exists(folder_path): return 0 - for f in os.listdir(folder_path): - if f.startswith("id") and "_" in f: - try: - num_part = f[2:].split('_')[0] - num = int(num_part) - if num > max_id: max_id = num - except: continue + try: + for f in os.listdir(folder_path): + if f.startswith("id") and "_" in f: + try: + num = int(f[2:].split('_')[0]) + if num > max_id: max_id = num + except: continue + except: pass return max_id @staticmethod def compress_for_web(path, quality): + """Compresses image to BytesIO for Streamlit display.""" try: with Image.open(path) as img: buf = BytesIO() @@ -46,6 +53,7 @@ class SorterEngine: @staticmethod def execute_move(t_path, c_path, t_folder, c_folder, prefix, mode="standard"): + """Moves target and copies control into subfolders.""" t_fname = f"{prefix}{os.path.basename(t_path)}" c_fname = f"{prefix}{os.path.basename(c_path)}" subdirs = { @@ -62,6 +70,7 @@ class SorterEngine: @staticmethod def revert_action(action): + """Reverses the last filesystem action.""" if action['type'] in ['link_standard', 'link_solo']: if os.path.exists(action['t_dst']): shutil.move(action['t_dst'], action['t_src']) if os.path.exists(action['c_dst']): os.remove(action['c_dst']) @@ -69,8 +78,17 @@ class SorterEngine: if os.path.exists(action['t_dst']): shutil.move(action['t_dst'], action['t_src']) if os.path.exists(action['c_dst']): shutil.move(action['c_dst'], action['c_src']) + @staticmethod + def save_favorite(name, path_t, path_c): + """Saves a path pair to the JSON config.""" + favs = SorterEngine.load_favorites() + favs[name] = {"target": path_t, "control": path_c} + with open(SorterEngine.CONFIG_PATH, 'w') as f: + json.dump(favs, f) + @staticmethod def load_favorites(): + """Loads path pairs from the JSON config.""" if os.path.exists(SorterEngine.CONFIG_PATH): with open(SorterEngine.CONFIG_PATH, 'r') as f: return json.load(f) return {} \ No newline at end of file