#!python # https://github.com/hMatoba/Piexif # http://ce3wiki.theturninggate.net/doku.php?id=file_name_convention # destination: // /ab---.jpg from pathlib import Path import datetime as dt import piexif from collections import defaultdict import re SRC = r'E:\RawTriage' DRY_RUN = False # def constant_factory(value): # return lambda: value # fileidx = defaultdict(constant_factory(0)) fileidx = defaultdict(int) CAMERAS = ("GoPro Hero3+", "Ricoh Theta V", "Ricoh Theta S", "Sony a5100", "Sony a65", "Sony TRV-25E") def recurse(dir, md, camera=None): for fp in dir.iterdir(): if fp.is_dir(): if fp.name in CAMERAS: recurse(fp, md, camera=fp.name) elif camera: recurse(fp, md, camera=camera) else: recurse(fp, md) continue if not fp.is_file(): print(f"{fp} neither dir nor file, skipping") continue # defaults use_ts = True use_camera = True author = "th" mtime = fp.stat().st_mtime rawdt = dt.datetime.fromtimestamp(mtime) if fp.suffix.lower() == ".jpg": try: exif_dict = piexif.load(str(fp)) idto = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal].decode("ascii") rawdt = dt.datetime.strptime(idto, "%Y:%m:%d %H:%M:%S") except: print(f"no exif in {fp.name}, skipping") continue try: model = exif_dict["0th"][piexif.ImageIFD.Model].decode("ascii") except: model = None pass use_camera = False if model == 'Canon EOS 5D': print(f"{fp.name} scanned photo, use directory date") rawdt = dt.datetime.strptime(md['dt'], "%Y%m%d") use_ts = False if model in ('FinePix S602 ZOOM', 'Canon EOS 6D', 'NIKON D5100'): author = "nn" if model == 'PULP 4G': author = "jb" if model == 'ASUS_Z00ED': author = "sb" elif fp.suffix.upper() == ".ARW": use_camera = False elif fp.suffix.upper() == ".MRW": use_camera = False elif fp.suffix.upper() == ".MP4": pass elif fp.suffix.upper() == ".MTS": pass elif fp.suffix.upper() == ".AVI": pass else: continue year = rawdt.year day = f"{rawdt:%Y%m%d}" ts = f"{rawdt:%H%M%S}" stem = f"{author}-{day}" if use_ts: stem += f"-{ts}" else: index = fileidx[day] + 1 fileidx[day] = index stem += f"-{index:04}" if use_camera: stem += f"-{camera}" rename(fp, fp.parent / f"{stem}{fp.suffix}") # rename derivative files i = len(fp.stem) dvs = dir.rglob(f"{fp.stem}*.*") for dv in dvs: if dv.name == fp.name: continue # print(fp.name, stem, dv.name) rename(dv, dv.parent / f"{stem}{dv.name[i:]}") def rename(old, new): print(old.name, "->", new.name) if not DRY_RUN: if not new.exists(): old.rename(new) else: print(f"skipped {old.name}, {new.name}, already exists") for daydir in Path(SRC).iterdir(): if not daydir.is_dir(): continue if daydir.name != "iPhone": continue print(f"[{daydir.name}] -------------------------------------------------") mo = re.match("(?P
\S*)\s?(?P.*)", daydir.name) md = mo.groupdict() title = md['title'] recurse(daydir, md)