snapshot
This commit is contained in:
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env python3.10
|
||||
|
||||
import argparse
|
||||
import dataclasses
|
||||
import datetime
|
||||
import json
|
||||
import logging
|
||||
from pathlib import Path
|
||||
import re
|
||||
|
||||
|
||||
def parse_args():
|
||||
arger = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
arger.add_argument('dirs', help='Path to the directories', type=Path, nargs='+')
|
||||
return arger.parse_args()
|
||||
|
||||
|
||||
def natural_sort_key(path: Path) -> tuple[str, ...]:
|
||||
s = path.stem
|
||||
return tuple(f'{int(p):010d}' if p.isnumeric() else p for p in re.findall(r'(\D+|\d+)', s))
|
||||
|
||||
|
||||
def rename_children(cwd: Path) -> None:
|
||||
assert cwd.is_dir()
|
||||
|
||||
files = [f for f in cwd.glob('*') if f.is_file()]
|
||||
files = sorted(files, key=natural_sort_key)
|
||||
|
||||
new_stem = cwd.name
|
||||
|
||||
jobs = []
|
||||
for i, f in enumerate(files):
|
||||
target = f.with_stem(f'{new_stem}__{i:04d}')
|
||||
if f.suffix == '.jpeg':
|
||||
target = target.with_suffix('.jpg')
|
||||
if target.is_file():
|
||||
logging.error(f'target already exists: {target}')
|
||||
continue
|
||||
jobs.append(MoveOp(source=f, target=target))
|
||||
f.rename(target)
|
||||
|
||||
if not jobs:
|
||||
return
|
||||
|
||||
write_undo_script(Path.cwd(), jobs)
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class MoveOp:
|
||||
source: Path
|
||||
target: Path
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
return {
|
||||
'source': str(self.source),
|
||||
'target': str(self.target),
|
||||
}
|
||||
|
||||
|
||||
def write_undo_script(save_dir: Path, ops: list[MoveOp]):
|
||||
now = datetime.datetime.now().isoformat().replace(':', '')
|
||||
save_path = save_dir / f'undo_{now}.json'
|
||||
with save_path.open('w', encoding='utf-8') as f:
|
||||
for it in ops:
|
||||
f.write(json.dumps(it.to_dict()) + '\n')
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
for d in args.dirs:
|
||||
rename_children(d)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user