diff --git a/engine.py b/engine.py index 1a7dd40..3fd8a93 100644 --- a/engine.py +++ b/engine.py @@ -254,7 +254,7 @@ class SorterEngine: @staticmethod def commit_global(output_root, cleanup_mode, operation="Move", source_root=None): - """Commits ALL staged files (Global Apply).""" + """Commits ALL staged files and fixes permissions.""" data = SorterEngine.get_staged_data() conn = sqlite3.connect(SorterEngine.DB_PATH) cursor = conn.cursor() @@ -278,20 +278,26 @@ class SorterEngine: else: shutil.move(old_p, final_dst) + # --- FIX PERMISSIONS --- + SorterEngine.fix_permissions(final_dst) + # Log History cursor.execute("INSERT OR REPLACE INTO processed_log VALUES (?, ?, ?)", (old_p, info['cat'], operation)) - # 2. Global Cleanup (Optional) - # Only run cleanup if explicitly asked, as global cleanup is risky + # 2. Global Cleanup if cleanup_mode != "Keep" and source_root: all_imgs = SorterEngine.get_images(source_root, recursive=True) for img_p in all_imgs: - if img_p not in data: # Not currently staged + if img_p not in data: if cleanup_mode == "Move to Unused": unused_dir = os.path.join(source_root, "unused") os.makedirs(unused_dir, exist_ok=True) - shutil.move(img_p, os.path.join(unused_dir, os.path.basename(img_p))) + dest_unused = os.path.join(unused_dir, os.path.basename(img_p)) + + shutil.move(img_p, dest_unused) + SorterEngine.fix_permissions(dest_unused) + elif cleanup_mode == "Delete": os.remove(img_p) @@ -398,9 +404,18 @@ class SorterEngine: conn.close() return {r[0]: {"cat": r[1], "action": r[2]} for r in rows} + @staticmethod + def fix_permissions(path): + """Forces file to be fully accessible (rwxrwxrwx).""" + try: + # 0o777 gives Read, Write, and Execute access to Owner, Group, and Others. + os.chmod(path, 0o777) + except Exception: + pass # Ignore errors if OS doesn't support chmod (e.g. some Windows setups) + @staticmethod def commit_batch(file_list, output_root, cleanup_mode, operation="Move"): - """Commits specified files and LOGS them to history.""" + """Commits files and fixes permissions.""" data = SorterEngine.get_staged_data() conn = sqlite3.connect(SorterEngine.DB_PATH) cursor = conn.cursor() @@ -423,13 +438,16 @@ class SorterEngine: final_dst = os.path.join(output_root, f"{root}_{c}{ext}") c += 1 - # Action + # Perform Action if operation == "Copy": shutil.copy2(file_path, final_dst) else: shutil.move(file_path, final_dst) - # Update DB: Remove from Staging, Add to History + # --- FIX PERMISSIONS --- + SorterEngine.fix_permissions(final_dst) + + # Update DB cursor.execute("DELETE FROM staging_area WHERE original_path = ?", (file_path,)) cursor.execute("INSERT OR REPLACE INTO processed_log VALUES (?, ?, ?)", (file_path, info['cat'], operation)) @@ -439,7 +457,11 @@ class SorterEngine: if cleanup_mode == "Move to Unused": unused_dir = os.path.join(os.path.dirname(file_path), "unused") os.makedirs(unused_dir, exist_ok=True) - shutil.move(file_path, os.path.join(unused_dir, os.path.basename(file_path))) + dest_unused = os.path.join(unused_dir, os.path.basename(file_path)) + + shutil.move(file_path, dest_unused) + SorterEngine.fix_permissions(dest_unused) # Fix here too + elif cleanup_mode == "Delete": os.remove(file_path)