photo_rename updates.

This commit is contained in:
voussoir 2025-03-24 22:14:29 -07:00
parent 9256fca829
commit 47781f0b01

View file

@ -4,6 +4,7 @@ import os
import re import re
import sys import sys
from voussoirkit import betterhelp
from voussoirkit import imagetools from voussoirkit import imagetools
from voussoirkit import interactive from voussoirkit import interactive
from voussoirkit import pathclass from voussoirkit import pathclass
@ -13,13 +14,14 @@ from voussoirkit import vlogging
log = vlogging.getLogger(__name__) log = vlogging.getLogger(__name__)
def makename(file, read_exif=False): def makename(file, read_exif=False, read_mtime=False):
old = file.replace_extension('').basename old = file.replace_extension('').basename
new = old new = old
final_pattern = r'^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)(?:x\d+)?$'
# Already optimized filenames need not apply # Already optimized filenames need not apply
# This is also important when the filename and the exif disagree # This is also important when the filename and the exif disagree
if re.match(r'^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)(?:x\d+)?$', old) and not read_exif: if re.match(final_pattern, old) and not read_exif:
return file return file
# Microsoft ICE # Microsoft ICE
@ -106,6 +108,13 @@ def makename(file, read_exif=False):
new, new,
) )
# Sony videos
new = re.sub(
r'^VideoPro_(\d\d\d\d)(\d\d)(\d\d)_(\d\d)(\d\d)(\d\d)+$',
r'\1-\2-\3_\4-\5-\6',
new,
)
new = re.sub( new = re.sub(
r'^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)[_-](\d+)$', r'^(\d\d\d\d)-(\d\d)-(\d\d)_(\d\d)-(\d\d)-(\d\d)[_-](\d+)$',
r'\1-\2-\3_\4-\5-\6x\7', r'\1-\2-\3_\4-\5-\6x\7',
@ -147,6 +156,13 @@ def makename(file, read_exif=False):
if new == old and read_exif and file.extension in {'jpg', 'jpeg'}: if new == old and read_exif and file.extension in {'jpg', 'jpeg'}:
new = makename_exif(file, old) new = makename_exif(file, old)
if new == old and re.match(final_pattern, new):
return file
if new == old and read_mtime:
date = datetime.datetime.fromtimestamp(file.stat.st_mtime)
new = date.strftime('%Y-%m-%d_%H-%M-%S')
new = file.parent.with_child(new).add_extension(file.extension) new = file.parent.with_child(new).add_extension(file.extension)
return new return new
@ -156,11 +172,16 @@ def makename_exif(file, fallback):
return fallback return fallback
return dt.strftime('%Y-%m-%d_%H-%M-%S') return dt.strftime('%Y-%m-%d_%H-%M-%S')
def makenames(files, read_exif=False): def makename_ffmpeg(file, fallback):
import kkroening_ffmpeg
probe = kkroening_ffmpeg.probe(file.absolute_path)
zulu = probe['streams'][0]['tags']['creation_time']
def makenames(files, read_exif=False, read_mtime=False):
pairs = {} pairs = {}
new_duplicates = {} new_duplicates = {}
for file in files: for file in files:
newname = makename(file, read_exif=read_exif) newname = makename(file, read_exif=read_exif, read_mtime=read_mtime)
new_duplicates.setdefault(newname, []).append(file) new_duplicates.setdefault(newname, []).append(file)
if file.basename == newname.basename: if file.basename == newname.basename:
continue continue
@ -193,7 +214,7 @@ def photo_rename_argparse(args):
else: else:
files = pathclass.glob_many_files(patterns) files = pathclass.glob_many_files(patterns)
pairs = makenames(files, read_exif=args.read_exif) pairs = makenames(files, read_exif=args.read_exif, read_mtime=args.read_mtime)
if not pairs: if not pairs:
return 0 return 0
@ -212,12 +233,26 @@ def main(argv):
parser.add_argument('patterns', nargs='+') parser.add_argument('patterns', nargs='+')
parser.add_argument('--recurse', action='store_true') parser.add_argument('--recurse', action='store_true')
parser.add_argument('--exif', dest='read_exif', action='store_true') parser.add_argument(
'--exif',
dest='read_exif',
action='store_true',
help='''
Program will look for EXIF metadata and use ImageDateTime, if available.
''',
)
parser.add_argument(
'--mtime',
dest='read_mtime',
action='store_true',
help='''
Program will use the file's mtime as a last resort.
''',
)
parser.add_argument('--yes', dest='autoyes', action='store_true') parser.add_argument('--yes', dest='autoyes', action='store_true')
parser.set_defaults(func=photo_rename_argparse) parser.set_defaults(func=photo_rename_argparse)
args = parser.parse_args(argv) return betterhelp.go(parser, argv)
return args.func(args)
if __name__ == '__main__': if __name__ == '__main__':
raise SystemExit(main(sys.argv[1:])) raise SystemExit(main(sys.argv[1:]))