#!/usr/bin/python3

import os.path
import sys

import glob
import subprocess

from pprint import pprint

def _exif_parse_key(raw_key: str) -> str:
    lowered = [fragment.lower() for fragment in raw_key.split()]
    return "_".join(lowered)

def _exif_parse_line(line: str) -> (str, str):
    (raw_key, raw_val) = line.split(":", maxsplit=1)
    return (_exif_parse_key(raw_key), raw_val.strip())

def _exif_parse(command_output: str) -> dict:
    parsed = dict()
    for line in command_output.splitlines():
        if not line.strip():
            continue
        (key, val) = _exif_parse_line(line)
        if not val:
            continue
        parsed[key] = val
    return parsed

def _run_exiv(path: str) -> str:
    assert os.path.isfile(path)
    exif = subprocess.Popen(
            args=("exiv2", path),
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
    )
    (stdout, _) = exif.communicate()
    return stdout.decode()

class Exif:
    def __init__(self, path):
        self.path = path
        self.raw_data = _run_exiv(path)
        self.data = _exif_parse(self.raw_data)

def iter_exif_cb(exif: Exif) -> None:
    model = exif.data.get("camera_model")
    if not model or not model.startswith("Pixel 4"):
        print("{}: {}".format(exif.path, model))

def main():
    target = sys.argv[1]
    exifs = [Exif(path) for path in
                glob.glob(os.path.join(target, "*.jpg"))]
    for exif in exifs:
        iter_exif_cb(exif)

if __name__ == "__main__":
    sys.exit(main())

@@ -40,16 +40,32 @@
 rt sys%0A%0A
+import datetime%0A
 import g
@@ -112,16 +112,440 @@
 t pprint
+%0Afrom zoneinfo import ZoneInfo%0A%0Adef datetime_from_basename(name: str) -%3E datetime.datetime:%0A    assert name.startswith(%22PXL_%22)%0A    return datetime.datetime.strptime(name%5B4:19%5D, %22%25Y%25m%25d_%25H%25M%25S%22)%0A%0Adef datetime_from_exif(exif_datetime: str) -%3E datetime.datetime:%0A    no_timezone = datetime.datetime.strptime(%0A            exif_datetime, %22%25Y:%25m:%25d %25H:%25M:%25S%22)%0A    return no_timezone.replace(tzinfo=ZoneInfo(%22America/Los_Angeles%22))
 %0A%0Adef _e
@@ -1552,188 +1552,666 @@
 a)%0A%0A
-def iter_exif_cb(exif: Exif) -%3E None:%0A    model = exif.data.get(%22camera_model%22)%0A    if not model or not model.startswith(%22Pixel 4%22):%0A        print(%22%7B%7D: %7B%7D%22.format(exif.path, model)
+        self.basename_datetime = datetime_from_basename(%0A                os.path.basename(path))%0A        self.basename_utc_datetime = self.basename_datetime.astimezone(%0A                datetime.timezone.utc)%0A%0A        try:%0A            self.exif_datetime = datetime_from_exif(%0A                    self.data%5B%22image_timestamp%22%5D)%0A            self.exif_utc_datetime = self.exif_datetime.astimezone(%0A                    datetime.timezone.utc)%0A        except KeyError:%0A            self.exif_datetime = None%0A            self.exif_utc_datetime = None%0A%0Adef iter_exif_cb(exif: Exif) -%3E None:%0A    if exif.exif_datetime:%0A        return%0A    print(exif.basename_utc_datetime
 )%0A%0Ad
@@ -2298,16 +2298,23 @@
         
+sorted(
 glob.glo
@@ -2345,16 +2345,17 @@
 *.jpg%22))
+)
 %5D%0A    fo

Add UTC conversions