import os import shutil import sys def sync_media_from_b_to_a(dir_a, dir_b, dry_run=False, dry_run_file="sync_dry_run.txt", error_file="sync_errors.txt"): """ For each subdirectory in A, use its name to search B for a media file (.mkv or .mp4) with the same base name. If found, move all files from that B subdirectory into the corresponding A subdirectory. If dry_run is True, only print and save what would be moved. Also record directories where no match or exceptions occur. """ media_exts = ('.mkv', '.mp4') dry_run_lines = [] error_lines = [] for subdir_a in os.listdir(dir_a): path_a = os.path.join(dir_a, subdir_a) if not os.path.isdir(path_a): continue base_name = subdir_a found = False try: for root_b, dirs_b, files_b in os.walk(dir_b): for file_b in files_b: name_b, ext_b = os.path.splitext(file_b) if ext_b.lower() in media_exts and name_b == base_name: found = True msg = f"Found match for '{base_name}' in '{root_b}'." print(msg) dry_run_lines.append(msg) for src_file in os.listdir(root_b): src_file_path = os.path.join(root_b, src_file) dest_file_path = os.path.join(path_a, src_file) if dry_run: line = f"[DRY-RUN] Would move: {src_file_path} -> {dest_file_path}" print(line) dry_run_lines.append(line) else: shutil.move(src_file_path, dest_file_path) print(f"Moved: {src_file_path} -> {dest_file_path}") break if found: break if not found: msg = f"No match found in B for '{base_name}' in '{path_a}'." print(msg) error_lines.append(msg) except Exception as e: msg = f"Exception for '{base_name}' in '{path_a}': {e}" print(msg) error_lines.append(msg) # Save dry run and error logs if dry_run if dry_run: with open(dry_run_file, "w", encoding="utf-8") as f: for line in dry_run_lines: f.write(line + "\n") print(f"Dry run output saved to {dry_run_file}") if error_lines: with open(error_file, "w", encoding="utf-8") as f: for line in error_lines: f.write(line + "\n") print(f"Errors/unmatched directories saved to {error_file}") if __name__ == "__main__": # python3 sync_media.py [--dry-run] if len(sys.argv) < 3: print("Usage: python sync_media.py [--dry-run]") else: dry_run = "--dry-run" in sys.argv sync_media_from_b_to_a( sys.argv[1], sys.argv[2], dry_run=dry_run, dry_run_file="sync_dry_run.txt", error_file="sync_errors.txt" )