Skip to content

capturegraph.adapters.add_dates #

Add Dates Adapter#

Extract EXIF dates from images in a CaptureTarget and save them as PTime-formatted JSON files.

Example
from pathlib import Path
from capturegraph.data import CaptureTarget
from capturegraph.adapters import add_dates

# Load target
target = CaptureTarget(Path("./MyCapture"))

# Add date files for all images
add_dates(target)

# Each image like "photo.dng" will have a companion "photo_date.json" with:
# {"time_since_1970": 1705315800.0}

add_dates(target) #

Add date JSON files for all images with EXIF data in a CaptureTarget.

Traverses the entire target, finds all image files, extracts the DateTimeOriginal timestamp, and writes a companion JSON file with the date in PTime format.

The output file is named {original_filename_without_extension}_date.json and contains {"time_since_1970": <seconds>} matching the CaptureGraph PTime format.

Parameters:

Name Type Description Default
target CaptureTarget

The CaptureTarget to process

required

Returns:

Type Description
list[Path]

List of paths to created JSON files.

Example
target = CaptureTarget(Path("./MyCapture"))
created_files = add_dates(target)
print(f"Created {len(created_files)} date files")

# For a file "photos/session_0.dng" with EXIF date "2024:01:15 10:30:00":
# Creates "photos/session_0_date.json" containing:
# {"time_since_1970": 1705315800.0}
Source code in capturegraph-lib/capturegraph/adapters/add_dates.py
def add_dates(target: cg.CaptureTarget) -> list[Path]:
    """Add date JSON files for all images with EXIF data in a CaptureTarget.

    Traverses the entire target, finds all image files, extracts the DateTimeOriginal
    timestamp, and writes a companion JSON file with the date in PTime format.

    The output file is named `{original_filename_without_extension}_date.json` and
    contains `{"time_since_1970": <seconds>}` matching the CaptureGraph PTime format.

    Args:
        target: The CaptureTarget to process

    Returns:
        List of paths to created JSON files.

    Example:
        ```python
        target = CaptureTarget(Path("./MyCapture"))
        created_files = add_dates(target)
        print(f"Created {len(created_files)} date files")

        # For a file "photos/session_0.dng" with EXIF date "2024:01:15 10:30:00":
        # Creates "photos/session_0_date.json" containing:
        # {"time_since_1970": 1705315800.0}
        ```
    """
    # Flatten all files and filter for ImageFile instances
    all_files = cg.flatten(target)
    images = cg.filter(all_files, lambda f: isinstance(f, cg.ImageFile))

    # Vectorized: get dates and output paths
    dates = images.exif.DateTimeOriginal.map(_parse_exif_datetime)
    output_paths = images.path.map(lambda p: p.with_name(p.stem + "_date.json"))

    created_files: list[Path] = []

    for row in cg.zip(date=dates, output=output_paths):
        if row.date is None or cg.is_missing(row.date):
            continue

        # Write PTime format: {"time_since_1970": seconds}
        ptime_data = {"time_since_1970": row.date.timestamp()}
        row.output.write_text(json.dumps(ptime_data, indent=2))
        created_files.append(row.output)

    return created_files