File size: 1,931 Bytes
4247de9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Local EXIF GPS extraction to prefill the map pin (no pixels touched)."""

from typing import Optional, Tuple


def _to_degrees(tag):
    try:
        d, m, s = (float(p.num) / float(p.den) for p in tag.values)
        return d + m / 60.0 + s / 3600.0
    except (AttributeError, TypeError, ValueError, ZeroDivisionError):
        return None


def extract_gps(path) -> Optional[Tuple[float, float]]:
    try:
        import exifread
    except ImportError:
        return None
    try:
        with open(path, "rb") as fh:
            tags = exifread.process_file(fh, details=False)
    except Exception:
        return None

    lat = _to_degrees(tags.get("GPS GPSLatitude"))
    lng = _to_degrees(tags.get("GPS GPSLongitude"))
    if lat is None or lng is None:
        return None
    if str(tags.get("GPS GPSLatitudeRef", "N")).strip().upper().startswith("S"):
        lat = -lat
    if str(tags.get("GPS GPSLongitudeRef", "E")).strip().upper().startswith("W"):
        lng = -lng
    if not (-90 <= lat <= 90 and -180 <= lng <= 180):
        return None
    return (lat, lng)


def extract_month(path) -> Optional[int]:
    """Calendar month (1-12) from the EXIF capture date, or None."""
    try:
        import exifread
    except ImportError:
        return None
    try:
        with open(path, "rb") as fh:
            tags = exifread.process_file(fh, details=False)
    except Exception:
        return None

    for key in ("EXIF DateTimeOriginal", "EXIF DateTimeDigitized", "Image DateTime"):
        raw = str(tags.get(key, "")).strip()
        if not raw:
            continue
        date_part = raw.split()[0]  # "YYYY:MM:DD" or "YYYY-MM-DD"
        bits = date_part.replace("-", ":").split(":")
        if len(bits) >= 2:
            try:
                month = int(bits[1])
            except ValueError:
                continue
            if 1 <= month <= 12:
                return month
    return None