| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- 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 <dir_A> <dir_B> [--dry-run]
- if len(sys.argv) < 3:
- print("Usage: python sync_media.py <dir_A> <dir_B> [--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"
- )
|