File size: 2,194 Bytes
23d337e
 
 
892fa81
 
23d337e
 
 
 
 
892fa81
23d337e
892fa81
23d337e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
892fa81
23d337e
 
 
892fa81
23d337e
 
892fa81
 
 
 
 
 
 
 
 
 
23d337e
 
892fa81
 
 
 
 
 
 
 
 
23d337e
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""
EXIF metadata provider.

Delegates all parsing to cores.metadata.extractor — no duplicated
Pillow open / EXIF tag walk / GPS conversion logic.
"""

from __future__ import annotations

from config.settings import Settings, settings as _default_settings
from cores.metadata import extract_all
from pipeline.feature_extraction import PipelineOutput
from providers.base import BaseProvider, ProviderCapability


class EXIFProvider(BaseProvider):
    name = "exif"
    capability = ProviderCapability.METADATA

    def __init__(self, settings: Settings | None = None) -> None:
        super().__init__(settings=settings or _default_settings)

    def is_available(self) -> bool:
        try:
            import PIL  # noqa: F401
            return True
        except ImportError:
            return False

    def _run(self, pipeline_output: PipelineOutput) -> tuple[dict, dict]:
        original = pipeline_output.original_bytes
        if not original:
            raw = {"error": "No original bytes available for EXIF extraction"}
            normalized = {
                "format": pipeline_output.original_format,
                "exif": {}, "xmp": {}, "iptc": {},
            }
            return raw, normalized

        data = extract_all(original)

        raw = {
            "format": data["format"],
            "exif_tags_count": len(data["exif"]),
            "gps_tags_count": len(data["gps"]),
            "exif": data["exif"],
            "gps": data["gps"],
            "camera_make": data["camera_make"],
            "camera_model": data["camera_model"],
            "software": data["software"],
            "capture_time": data["capture_time"],
            "error": data["error"],
        }
        normalized = {
            "format": data["format"],
            "exif": data["exif"],
            "xmp": {} if not data["xmp"] else {"raw_length": len(data["xmp"])},
            "iptc": data["iptc"],
            "gps": data["gps_coords"],
            "camera_make": data["camera_make"],
            "camera_model": data["camera_model"],
            "software": data["software"],
            "capture_time": data["capture_time"],
        }
        return raw, normalized