#!/usr/bin/env python3 """ Same as picture_name_date except it's tailored for OpenCamera. It uses filenames, that way: - Easier to get metadata - JPG/DNG, MP4/SRT keep the same filename """ import argparse import logging import os import re import coloredlogs log = logging.getLogger(__name__) coloredlogs.install(level="DEBUG", fmt="%(levelname)s %(message)s", logger=log) PATTERNS = [ re.compile( # OpenCamera r"^(?PIMG|VID)_" # No TRIM. We don't want those as they're a short copy of an existing VID. r"(?P\d\d\d\d)(?P\d\d)(?P\d\d)_" r"(?P\d\d)(?P\d\d)(?P\d\d)" r"(?P_(\d+))?" r"(?P_(PANO|HDR))?" r"\.(?Pjpg|dng|mp4|srt)$" ), re.compile( # Samsung camera app (?) r"(?P\d\d\d\d)(?P\d\d)(?P\d\d)_" r"(?P\d\d)(?P\d\d)(?P\d\d)" r"\.(?Pjpg|mp4)$" ), re.compile( # Telegram Media Downloader photo r"photo_" r"(?P\d\d\d\d)-(?P\d\d)-(?P\d\d)_" r"(?P\d\d)-(?P\d\d)-(?P\d\d)" r"(?P_\d{19})" r"\.(?Pjpg)$" ), # Time of publication, not time of photo! re.compile( # Telegram Media Downloader video r"video_" r"(?P\d\d\d\d)-(?P\d\d)-(?P\d\d)_" r"(?P\d\d)-(?P\d\d)-(?P\d\d)" r"(?P_\d{19})" r"\.(?Pmp4)$" ), # Time of publication, not time of video! ] def main(args: argparse.Namespace) -> None: for root, _, files in os.walk(args.dir): for filename in files: full_path = os.path.join(root, filename) for pattern in PATTERNS: match = re.match(pattern, filename) if match: break else: log.warning(f"{full_path} doesn't any pattern") continue # Build new filename m = match.groupdict() new_filename = ( f"{m['Y']}-{m['M']}-{m['D']}_" f"{m['h']}-{m['m']}-{m['s']}" f"{m.get('dup') or ''}" f"{m.get('spec') or ''}" f"{args.suffix}" f".{m['ext']}" ) new_path = os.path.join(args.dir, new_filename) # TODO Allow keeping image in same folder # Rename file if full_path == new_path: log.debug(f"{full_path} already at required filename") continue log.info(f"{full_path} →\t{new_path}") if os.path.exists(new_path): raise FileExistsError(f"{new_path} already exists!") if not args.dry: os.rename(full_path, new_path) if __name__ == "__main__": parser = argparse.ArgumentParser( description="Rename OpenCamera files based on their dates" ) parser.add_argument( "dir", metavar="DIRECTORY", type=str, default=".", nargs="?", help="Directory containing the pictures", ) parser.add_argument( "-d", "--dry", action="store_true", help="Do not actually rename, just show old and new path", ) parser.add_argument( "-s", "--suffix", default="", help="Text to add before the extension", ) args = parser.parse_args() main(args)