improved exif...

This commit is contained in:
Luzia Christiane Tesar 2026-08-28 18:16:48 +02:00
parent 03aff17cc7
commit 5797dc585d
4 changed files with 67 additions and 32 deletions

View File

@ -63,12 +63,12 @@
<!-- Navigation --> <!-- Navigation -->
<nav class="topbar"> <nav class="topbar">
<ul> <ul>
<li><a href="/" >Main</a></li> <li><a href="https://dm2lct.radio/" >Main</a></li>
<li><a href="/projekte">Projects</a></li> <li><a href="https://dm2lct.radio/projekte">Projects</a></li>
<li><a href="/blog">Blog</a></li> <li><a href="https://dm2lct.radio/blog">Blog</a></li>
<li><a href="/pics">Photography</a></li> <li><a href="https://lib.chrissy.cat">Photography</a></li>
<li><a href="/kontakt">Contact</a></li> <li><a href="https://dm2lct.radio/kontakt">Contact</a></li>
<li><a href="/rss.xml">RSS-Feed</a></li> <li><a href="https://dm2lct.radio/rss.xml">RSS-Feed</a></li>
</ul> </ul>
</nav> </nav>

View File

@ -292,6 +292,10 @@ nav li {
} }
} }
p {
margin-top:3cm;
}
/* Arise Index Style */ /* Arise Index Style */
.arise-toc-td { .arise-toc-td {
border-width: 1px; border-width: 1px;

View File

@ -8,6 +8,7 @@ import os
import sys import sys
import requests import requests
import json import json
import time
from datetime import datetime from datetime import datetime
from PIL import Image from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS from PIL.ExifTags import TAGS, GPSTAGS
@ -80,8 +81,10 @@ def get_lat_lon(exif_data):
return lat, lon return lat, lon
def getReverseAPI(lat, lon): def getReverseAPI(lat, lon):
try: try:
time.sleep(1)
payload = {"lat": lat, "lon": lon, "format": "json", "addressdetails": "1"} payload = {"lat": lat, "lon": lon, "format": "json", "addressdetails": "1"}
r = requests.get(REV_API_URL, headers=headers, params=payload) r = requests.get(REV_API_URL, headers=headers, params=payload)
return r.json() return r.json()
@ -94,6 +97,15 @@ def getReverseAPI(lat, lon):
except requests.exceptions.RequestException as err: except requests.exceptions.RequestException as err:
print("OOps: Something Else", err) print("OOps: Something Else", err)
def getPlace(geo):
if geo.get('name'):
return geo.get('name')
else:
place = geo['address'].get('city') or geo['address'].get('town') or geo['address'].get('village') or geo['address'].get('hamlet') or geo['address'].get('isolated_dwelling')
if geo['address'].get('road'):
place += ", " + geo['address'].get('road')
return place
def getCity(geo): def getCity(geo):
return geo["address"]["city"] or "" return geo["address"]["city"] or ""

63
purrpic.py Normal file → Executable file
View File

@ -6,7 +6,6 @@
import os import os
import sys import sys
import glob
from PIL import Image from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS from PIL.ExifTags import TAGS, GPSTAGS
@ -14,10 +13,11 @@ import argparse
import configparser import configparser
from pathlib import Path from pathlib import Path
import datetime import datetime
from gps_location import get_lat_lon, getReverseAPI from gps_location import get_lat_lon, getReverseAPI, getPlace
from fractions import Fraction
BUILD_DIR = Path("./build").resolve() BUILD_DIR = Path("/home/chrissy/repos/purrpic/build").resolve()
CONF_DIR = Path("./conf").resolve() CONF_DIR = Path("/home/chrissy/repos/purrpic//conf").resolve()
THUMBSIZE = (800, 800) THUMBSIZE = (800, 800)
GLOBALNAME = "Chrissys random Photogallery" GLOBALNAME = "Chrissys random Photogallery"
LICENCE = "CC BY-NC-SA 4.0" LICENCE = "CC BY-NC-SA 4.0"
@ -42,6 +42,7 @@ class HTML:
self.lat = None self.lat = None
self.lon = None self.lon = None
self.geo = None self.geo = None
self.place = None
self.datetime = None self.datetime = None
self.file_link = None self.file_link = None
self.make = None self.make = None
@ -53,9 +54,11 @@ class HTML:
self.exposure = None self.exposure = None
self.exposure_mode = None self.exposure_mode = None
self.exposure_program = None self.exposure_program = None
self.exposure_bias = None
self.f_num = None self.f_num = None
self.flash = None self.flash = None
self.focal_length = None self.focal_length = None
self.focal_length_35mm = None
self.focus_distance = None self.focus_distance = None
self.focus_mode = None self.focus_mode = None
self.iso = None self.iso = None
@ -133,11 +136,17 @@ class HTML:
if "FocalLength" in exifdata: if "FocalLength" in exifdata:
self.focal_length = exifdata["FocalLength"] self.focal_length = exifdata["FocalLength"]
if 'FocalLengthIn35mmFilm' in exifdata and exifdata.get('FocalLengthIn35mmFilm') != 0:
self.focal_length_35mm = exifdata.get('FocalLengthIn35mmFilm')
if "LensModel" in exifdata: if "LensModel" in exifdata:
self.lens_model = exifdata["LensModel"] self.lens_model = exifdata["LensModel"]
if "ExposureTime" in exifdata: if "ExposureTime" in exifdata:
self.exposure = exifdata["ExposureTime"] self.exposure = f"1/{round(1/float(exifdata.get('ExposureTime')))}"
if 'ExposureBiasValue' in exifdata:
self.exposure_bias = exifdata.get('ExposureBiasValue')
if "FNumber" in exifdata: if "FNumber" in exifdata:
self.f_num = exifdata["FNumber"] self.f_num = exifdata["FNumber"]
@ -151,12 +160,14 @@ class HTML:
if "GPSInfo" in exifdata: if "GPSInfo" in exifdata:
self.lat, self.lon = get_lat_lon(exifdata) self.lat, self.lon = get_lat_lon(exifdata)
self.geo = getReverseAPI(self.lat, self.lon) self.geo = getReverseAPI(self.lat, self.lon)
self.place = getPlace(self.geo)
def writeGrid(self, imglist, linklist): def writeGrid(self, imglist, linklist):
try: try:
buf: "" buf: ""
buf += self.div("row") buf += self.div("row")
# imglist = glob.glob(str(odir) + "/.thumbnails/*")
imglist = [] imglist = []
for img in Path.iterdir(odir / ".thumbnails"): for img in Path.iterdir(odir / ".thumbnails"):
imglist.append(img) imglist.append(img)
@ -172,6 +183,7 @@ class HTML:
def writeIndex(self, odir, meta) -> None: def writeIndex(self, odir, meta) -> None:
try: try:
print(f"Writing index.html for {odir}")
title = meta["title"] title = meta["title"]
desc = meta["description"] desc = meta["description"]
buf = self.headermeta(title) buf = self.headermeta(title)
@ -180,7 +192,7 @@ class HTML:
buf += self.ul() buf += self.ul()
for line in desc: for line in desc:
buf += self.li(line) buf += self.li(line)
buf += self.li(f"© {AUTHOR}, {LICENCE}") buf += self.li(f"© {AUTHOR}, <a href=https://creativecommons.org/licenses/by-nc-sa/4.0/>{LICENCE}</a>")
buf += self.endUl() buf += self.endUl()
buf += self.div("row") buf += self.div("row")
imglist = [] imglist = []
@ -202,7 +214,6 @@ class HTML:
def writeDetail(self, odir): def writeDetail(self, odir):
try: try:
breakpoint()
imglist = [] imglist = []
for file in Path.iterdir(odir): for file in Path.iterdir(odir):
if file.suffix in [".jpg", ".png", "JPEG", "PNG"]: if file.suffix in [".jpg", ".png", "JPEG", "PNG"]:
@ -216,9 +227,10 @@ class HTML:
buf += self.div("div") buf += self.div("div")
buf += self.div("divleft") buf += self.div("divleft")
buf += self.link("index.html", "Back") buf += self.link("index.html", "Back")
buf +="<br><br>"
buf += self.endDiv() buf += self.endDiv()
buf += self.endDiv() buf += self.endDiv()
buf += self.img(img) buf += self.aimg(img.name, img.name)
buf += self.div("div") buf += self.div("div")
if imglist.index(img) != 0: if imglist.index(img) != 0:
buf += self.div("divleft") buf += self.div("divleft")
@ -237,41 +249,46 @@ class HTML:
buf += self.endDiv() buf += self.endDiv()
buf += self.endDiv() buf += self.endDiv()
buf +="<br><br>"
buf += self.div("div") buf += self.div("div")
buf += '<p style="margin-top:3cm;"><table>\n' buf += '<p><table>\n'
if self.datetime: if self.datetime:
buf += f"<tr><td><b>Time </td><td>{self.datetime.strftime('%Y-%m-%d %H:%M')}</td></tr>\n" buf += f"<tr><td><b>Time</b></td><td>{self.datetime.strftime('%Y-%m-%d %H:%M')}</td></tr>\n"
if self.geo: if self.geo:
buf += f"<tr><td><b>Place </td><td><a href = https://www.openstreetmap.org/?mlat={self.lat}&mlon={self.lon}map=17/{self.lat}/{self.lon}>{self.geo['address']['road']}, {self.geo['address']['town']}</a></td></tr>\n" buf += f"<tr><td><b>Place</b></td><td><a href = https://www.openstreetmap.org/?mlat={self.lat}&mlon={self.lon}map=17/{self.lat}/{self.lon}>{self.place}</a></td></tr>\n"
buf += f"<tr><td><b></b></td><td></td></tr>\n"
if self.make: if self.make:
buf += f"<tr><td><b>Camera</td><td>{self.make} {self.model}</td></tr>\n" buf += f"<tr><td><b>Camera</b></td><td>{self.make} {self.model}</td></tr>\n"
if self.lens_model: if self.lens_model:
buf += ( buf += (
f"<tr><td><b>Lens Model </td><td>{self.lens_model}</td></tr>\n" f"<tr><td><b>Lens Model</b></td><td>{self.lens_model}</td></tr>\n"
) )
if self.focal_length: if self.focal_length:
buf += f"<tr><td><b>Focal Length </td><td>{self.focal_length}</td></tr>\n" buf += f"<tr><td><b>Focal Length</b></td><td>{self.focal_length}</td></tr>\n"
if self.f_num: if self.f_num:
buf += ( buf += (
f"<tr><td><b>Aperture </td><td>{self.focal_length}</td></tr>\n" f"<tr><td><b>Aperture</b></td><td>{self.f_num}</td></tr>\n"
) )
if self.exposure: if self.exposure:
buf += ( buf += (
f"<tr><td><b>Exposure Time </td><td>{self.exposure}</td></tr>\n" f"<tr><td><b>Exposure Time</b></td><td>{self.exposure}</td></tr>\n"
) )
if self.iso: if self.iso:
buf += f"<tr><td><b>ISO </td><td>{self.iso}</td></tr>\n" buf += f"<tr><td><b>ISO</b></td><td>{self.iso}</td></tr>\n"
buf += f"<tr><td><b></b></td><td></td></tr>\n"
if self.software: if self.software:
buf += f"<tr><td><b>Software </td><td>{self.software}</td></tr>\n" buf += f"<tr><td><b>Software</b></td><td>{self.software}</td></tr>\n"
buf += "</table></p>\n" buf += "</table></p>\n"
buf += self.endDiv() buf += self.endDiv()
@ -284,7 +301,6 @@ class HTML:
def writeMain(self, metadata): def writeMain(self, metadata):
with open(BUILD_DIR / "index.html", "w", encoding="utf-8") as file: with open(BUILD_DIR / "index.html", "w", encoding="utf-8") as file:
breakpoint()
file.write(self.headermeta(GLOBALNAME)) file.write(self.headermeta(GLOBALNAME))
file.write(self.title(GLOBALNAME)) file.write(self.title(GLOBALNAME))
file.write(self.div("row")) file.write(self.div("row"))
@ -292,6 +308,7 @@ class HTML:
dirlist = [] dirlist = []
for d in dirs: for d in dirs:
dirlist.append(d) dirlist.append(d)
dirlist.sort(key=lambda x:metadata[x]["date"], reverse=True)
for n in range(0, 3): for n in range(0, 3):
file.write(self.div("column")) file.write(self.div("column"))
for i in range(n, len(dirlist), 3): for i in range(n, len(dirlist), 3):
@ -353,7 +370,6 @@ def createThumb(img, thumbdir):
def processImage(img, odir): def processImage(img, odir):
breakpoint()
with Image.open(img) as im: with Image.open(img) as im:
exif = im.getexif() exif = im.getexif()
exif[315] = AUTHOR exif[315] = AUTHOR
@ -370,7 +386,7 @@ def generateDir(path):
def parseIni(file): def parseIni(file):
meta = {"title": None, "category": None, "description": [], "files": []} meta = {"title": None, "category": None, "date": None, "description": [], "files": []}
try: try:
with open(file, "r") as f: with open(file, "r") as f:
for line in f: for line in f:
@ -382,6 +398,8 @@ def parseIni(file):
meta["title"] = line.removeprefix("title = ").strip() meta["title"] = line.removeprefix("title = ").strip()
elif line.startswith("category = "): elif line.startswith("category = "):
meta["category"] = line.removeprefix("category = ").strip() meta["category"] = line.removeprefix("category = ").strip()
elif line.startswith("date = "):
meta["date"] = datetime.datetime.strptime(line.removeprefix("date = ").strip(),"%Y-%m-%d")
else: else:
continue continue
except: except:
@ -392,6 +410,7 @@ def parseIni(file):
def processDir(path): def processDir(path):
try: try:
if Path.is_file(path / ".purrpic.ini"): if Path.is_file(path / ".purrpic.ini"):
print(f"Processing {path}")
meta = parseIni(path / ".purrpic.ini") meta = parseIni(path / ".purrpic.ini")
odir, thumbdir = generateDir(path) odir, thumbdir = generateDir(path)
for img in meta["files"]: for img in meta["files"]: