#!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 Hero", "DJI Mini 2", "Ricoh Theta V", "Ricoh Theta S", "Sony a5100", "Sony a65", "Sony a68", "Sony TRV-25E", "Fuji Finepix Real 3D W3", "DJI Mini 2", "Samsung Galaxy A40", "Samsung Galaxy A41", 'Realme 7 5G', 'Realme GT Neo 2') def recurse(dir, md, camera=None): for fp in dir.iterdir(): if fp.is_dir() and camera is None: if fp.name in CAMERAS: print(f"[{fp.name}] -------------------------------------------------") recurse(fp, md, camera=fp.name) elif camera: recurse(fp, md, camera=camera) if fp.is_dir() and camera is not None: print(f"[{fp.name}] - [{camera}] ------------------------------------------------") mo = re.match(r"(?P
\S*)\s?(?P.*)", fp.name) md = mo.groupdict() # title = md['title'] recurse(fp, md, camera=camera) if not fp.is_file(): # print(f"{fp} neither dir nor file, skipping") continue # defaults use_ts = True use_camera = True author = "ab" mtime = fp.stat().st_mtime rawdt = dt.datetime.fromtimestamp(mtime) if fp.suffix.lower() in [".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: print(exif_dict) model = None 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' or camera == 'Realme 7 5G': author = "jb" if model == 'ASUS_Z00ED' or camera == 'Realme GT Neo 2': author = "sb" if model == 'SM-A405FN': author = "ab" if model == 'SM-A415F' or camera == "Samsung Galaxy A41": author = "kb" elif fp.suffix.lower() == ".heic": use_camera = False author = "kb" elif fp.suffix.upper() == ".ARW": use_camera = False elif fp.suffix.upper() == ".MRW": use_camera = False elif fp.suffix.upper() == ".MPO": 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 new.exists(): if old == new: print(f"skipped {old.name}, {new.name}, already exists") else: for c in "abcdefghijklmnopqrstuvwxyz": alt = new.parent / f"{new.stem}{c}{new.suffix}" if not alt.exists(): old.rename(alt) break else: old.rename(new) recurse(Path(SRC), None)