import shutil from pathlib import Path def flatten_gpx_files(source_dir: str = ".", target_dir: str = "ALL_GPX"): """ Find all .gpx files under source_dir (including subfolders) and copy them into a single flat folder. """ source_path = Path(source_dir).resolve() target_path = Path(target_dir).resolve() # Create target folder target_path.mkdir(parents=True, exist_ok=True) print(f"Searching for .gpx files in: {source_path}") print(f"Copying to flat folder: {target_path}\n") gpx_files = list(source_path.rglob("*.gpx")) if not gpx_files: print("No .gpx files found.") return copied = 0 for gpx_file in gpx_files: # New filename: original_name__parent_folder.gpx (helps avoid name collisions) parent_name = gpx_file.parent.name new_name = f"{gpx_file.stem}__{parent_name}{gpx_file.suffix}" destination = target_path / new_name # If filename already exists, add a number counter = 1 while destination.exists(): destination = target_path / f"{gpx_file.stem}__{parent_name}_{counter}{gpx_file.suffix}" counter += 1 try: shutil.copy2(gpx_file, destination) print(f"Copied: {gpx_file.name} → {new_name}") copied += 1 except Exception as e: print(f"Failed {gpx_file.name}: {e}") print("\n" + "="*50) print(f"Done! {copied} .gpx files flattened into '{target_path.name}/'") print("="*50) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser(description="Flatten all .gpx files into one folder") parser.add_argument("source", nargs="?", default=".", help="Source directory to search (default: current)") parser.add_argument("-o", "--output", default="ALL_GPX", help="Output folder name (default: ALL_GPX)") args = parser.parse_args() flatten_gpx_files(args.source, args.output)