diff --git a/cowcopy.py b/cowcopy.py new file mode 100644 index 0000000..91fec7a --- /dev/null +++ b/cowcopy.py @@ -0,0 +1,82 @@ +import argparse +from pathlib import Path + + +SAFETY = 'jellyfin' + +def get_args(): + parser = argparse.ArgumentParser() + parser.add_argument('source', type=Path) + parser.add_argument('dest', type=Path) + parser.add_argument('--dry', help='Only output changes', action="store_true") + return parser.parse_args() + + +def main(source: Path, dest: Path, dry: bool): + remove_deleted_files(source, dest, dry) + create_new_links(source, dest, dry) + +def remove_deleted_files(source: Path, dest: Path, dry: bool): + for file in dest.iterdir(): + if file.is_dir(): + original_dir = source / file.name + + if original_dir.is_dir(): + remove_deleted_files(original_dir, file, dry) + else: + remove_deleted_files(original_dir, file, dry) + if dry: + print(f"Remove directory: {file}") + else: + file.rmdir() # will fail if files have since been created + elif file.is_file(): + original_file = source / file.name + + if not original_file.exists() or original_file.is_dir(): + if SAFETY not in str(file): + raise Exception("Deletion path does not include jellyfin") + if dry: + print(f"Remove file: {file}") + else: + file.unlink() + +def create_new_links(source: Path, dest: Path, dry: bool): + for file in source.iterdir(): + if file.is_dir(): + new_dest = dest / file.name + + if not new_dest.exists(): + if dry: + print(f"Create directory: {new_dest}") + else: + new_dest.mkdir() + elif new_dest.exists() and not new_dest.is_dir(): + raise Exception("Directory expected") + + create_new_links(file, new_dest, dry) + + elif file.is_file(): + new_file = dest / file.name + + if not new_file.exists(): + if dry: + print(f"Create file: {new_file}") + else: + file.copy(new_file) + +if __name__ == '__main__': + args = get_args() + source_directory = args.source + destination_directory = args.dest + dryrun = args.dry + + if len(source_directory.parts) < 3 or len(destination_directory.parts) < 3: + raise Exception("Paths too short") + + if dryrun: + print("Dry run - no changes will be made") + + main(source_directory, destination_directory, dryrun) + + if dryrun: + print("Dry run - no changes have been made")