-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
120 lines (91 loc) · 3.62 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import csv
import os
from pathlib import Path
import argparse
import sys
from typing import Dict, List, Tuple
def load_rename_mapping(csv_path: str) -> Dict[str, str]:
"""
Load the mapping of original names to new names from CSV file.
Args:
csv_path: Path to CSV file containing original_name,new_name columns
Returns:
Dictionary mapping original filenames to new filenames
"""
rename_mapping = {}
try:
with open(csv_path, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
if not {'original_name', 'new_name'}.issubset(reader.fieldnames):
raise ValueError("CSV must have 'original_name' and 'new_name' columns")
for row in reader:
rename_mapping[row['original_name']] = row['new_name']
except FileNotFoundError:
print(f"Error: CSV file '{csv_path}' not found")
sys.exit(1)
except Exception as e:
print(f"Error reading CSV file: {e}")
sys.exit(1)
return rename_mapping
def validate_rename_operations(folder_path: str, rename_mapping: Dict[str, str]) -> List[Tuple[str, str]]:
"""
Validate rename operations before executing them.
Args:
folder_path: Path to folder containing files to rename
rename_mapping: Dictionary mapping original names to new names
Returns:
List of valid (source_path, dest_path) tuples
"""
valid_operations = []
folder = Path(folder_path)
# Check if destination names would clash
used_names = set()
for orig_name, new_name in rename_mapping.items():
source_path = folder / orig_name
dest_path = folder / new_name
if not source_path.exists():
print(f"Warning: Source file '{orig_name}' not found in folder")
continue
if new_name in used_names:
print(f"Error: Multiple files would be renamed to '{new_name}'")
continue
if dest_path.exists() and orig_name != new_name:
print(f"Warning: Destination '{new_name}' already exists")
continue
used_names.add(new_name)
valid_operations.append((str(source_path), str(dest_path)))
return valid_operations
def rename_files(operations: List[Tuple[str, str]], dry_run: bool = False) -> None:
"""
Execute the rename operations.
Args:
operations: List of (source_path, dest_path) tuples
dry_run: If True, only print what would be done without executing
"""
for source, dest in operations:
if dry_run:
print(f"Would rename '{source}' to '{dest}'")
else:
try:
os.rename(source, dest)
print(f"Renamed '{source}' to '{dest}'")
except Exception as e:
print(f"Error renaming '{source}' to '{dest}': {e}")
def main():
parser = argparse.ArgumentParser(description='Rename files based on CSV mapping')
parser.add_argument('csv_file', help='Path to CSV file with original_name,new_name columns')
parser.add_argument('folder', help='Path to folder containing files to rename')
parser.add_argument('--dry-run', action='store_true',
help='Print what would be done without executing')
args = parser.parse_args()
# Load rename mapping from CSV
rename_mapping = load_rename_mapping(args.csv_file)
# Validate operations
operations = validate_rename_operations(args.folder, rename_mapping)
if not operations:
print("No valid rename operations found")
return
# Execute renames
rename_files(operations, args.dry_run)
if __name__ == '__main__':
main()