photolib/photoapp/ingest.py

118 lines
3.7 KiB
Python
Raw Normal View History

2018-09-08 15:49:16 -07:00
import argparse
2018-09-09 23:43:17 -07:00
import traceback
2019-07-04 13:10:52 -07:00
from photoapp.image import get_jpg_info, get_hash, get_mtime, special_magic
2018-09-08 15:49:16 -07:00
from itertools import chain
2019-06-25 21:34:32 -07:00
from photoapp.types import Photo, PhotoSet, known_extensions, regular_images, files_raw, files_video, map_extension
2018-09-08 15:49:16 -07:00
import os
2019-06-21 09:22:42 -07:00
2018-09-08 15:49:16 -07:00
"""
Photo sorting rules:
jpeg
exif date
file modification date
raw
group with exif date of jpeg with same name
file modification date
mov, video, or other
modification date
"""
2018-09-09 23:43:17 -07:00
def pprogress(done, total=None):
print(" complete: {}{}\r".format(done, " / {} ".format(total) if total else ''), end='')
2019-06-25 21:34:32 -07:00
def group_by_extension(files):
2018-09-08 15:49:16 -07:00
byext = {k: [] for k in known_extensions}
2019-06-25 21:34:32 -07:00
excluded = []
2018-09-08 15:49:16 -07:00
for item in files:
2019-06-25 21:34:32 -07:00
if not os.path.isfile(item): # Not a file
2019-07-04 16:59:58 -07:00
excluded.append(item)
2018-09-08 15:49:16 -07:00
continue
extension = item.split(".")
2019-06-25 21:34:32 -07:00
if len(extension) < 2: # no extension
excluded.append(item)
2018-09-08 15:49:16 -07:00
continue
2019-06-25 21:34:32 -07:00
extension = map_extension(extension[-1].lower())
if extension not in known_extensions: # an extension we don't support
excluded.append(item)
2018-09-08 15:49:16 -07:00
continue
byext[extension.lower()].append(item)
2019-06-25 21:34:32 -07:00
return (byext, excluded)
def get_photosets(files):
byext, skipped = group_by_extension(files)
photosets = []
2018-09-08 15:49:16 -07:00
# process regular images first.
for item in chain(*[byext[ext] for ext in regular_images]):
2019-06-25 21:34:32 -07:00
photosets.append(get_jpg_info(item))
2018-09-08 15:49:16 -07:00
# process raws
for item in chain(*[byext[ext] for ext in files_raw]):
2018-09-09 12:05:13 -07:00
itemmeta = Photo(hash=get_hash(item), path=item, size=os.path.getsize(item),
2019-07-04 14:25:19 -07:00
format=special_magic(item), fname=os.path.basename(item))
2018-09-08 15:49:16 -07:00
fprefix = os.path.basename(item)[::-1].split(".", 1)[-1][::-1]
2019-06-25 21:34:32 -07:00
fmatch = "{}.jpg".format(fprefix.lower()) # if we're inspecting "foobar.raw", match it with "foobar.jpg"
# TODO does this account for extension mappinh like jpeg->jpg?
2018-09-08 15:49:16 -07:00
foundmatch = False
2019-06-25 21:34:32 -07:00
for photo in photosets:
2018-09-08 15:49:16 -07:00
for fmt in photo.files[:]:
if os.path.basename(fmt.path).lower() == fmatch:
foundmatch = True
photo.files.append(itemmeta)
break
if foundmatch:
break
if not foundmatch:
2018-09-15 16:48:47 -07:00
mtime = get_mtime(item)
2019-06-25 21:34:32 -07:00
print("no match found for", itemmeta.path, "but importing anyway")
photosets.append(PhotoSet(date=mtime, date_real=mtime, files=[itemmeta]))
# TODO handle any xmp without an associated regular image or cr2
2018-09-08 15:49:16 -07:00
2019-06-25 21:34:32 -07:00
# process other known formats
2018-09-08 15:49:16 -07:00
for item in chain(*[byext[ext] for ext in files_video]):
2018-09-09 12:05:13 -07:00
itemmeta = Photo(hash=get_hash(item), path=item, size=os.path.getsize(item),
2019-07-04 14:25:19 -07:00
format=special_magic(item), fname=os.path.basename(item))
2018-09-15 16:48:47 -07:00
mtime = get_mtime(item)
2019-06-25 21:34:32 -07:00
photosets.append(PhotoSet(date=mtime, date_real=mtime, files=[itemmeta]))
return photosets, skipped
def batch_ingest(library, files):
sets, skipped = get_photosets(files)
2018-09-08 15:49:16 -07:00
2018-09-09 23:43:17 -07:00
print("\nUpdating database")
done = 0
2019-06-25 21:34:32 -07:00
total = len(sets)
for photoset in sets:
2018-09-09 23:43:17 -07:00
try:
library.add_photoset(photoset)
pprogress(done, total)
done += 1
2019-07-04 16:59:58 -07:00
except Exception:
2018-09-09 23:43:17 -07:00
traceback.print_exc()
pass
print("\nUpdate complete")
2018-09-09 12:05:13 -07:00
2018-09-08 15:49:16 -07:00
def main():
parser = argparse.ArgumentParser(description="Library ingestion tool")
parser.add_argument("files", nargs="+")
args = parser.parse_args()
2019-06-17 22:43:57 -07:00
library = PhotoLibrary("photos.db", "./library", "./cache")
2018-09-08 15:49:16 -07:00
batch_ingest(library, args.files)
if __name__ == '__main__':
main()