purrpic/purrpic.py

261 lines
8.0 KiB
Python

#!/usr/bin/python3
"""!@brief:generates static html imagelibrary
@author: Luzia Christiane Tesar
@date Mo 13. Jul 20:52:54 CEST 2026
"""
import os
import sys
import glob
# import exif
from PIL import Image
import argparse
import configparser
from pathlib import Path
import datetime
BUILD_DIR = Path("./build").resolve()
CONF_DIR = Path("./conf").resolve()
THUMBSIZE = (300, 300)
GLOBALNAME = "Chrissys random Imagelibrary"
LICENCE = "CC BY-NC-SA 4.0"
AUTHOR = "Luzia Christiane Tesar"
LANGUAGE = "en"
DESCRIPTION = ""
TODAY = datetime.datetime.today().strftime("%Y-%m-%d")
CANONICALURL = "https://dm2lct.radio"
exclude = set([".thumbnails", ".git", "conf", "build"])
class HTML:
def __init__(self, **kwargs):
self.header = Path(CONF_DIR / "header.html").read_text()
self.footer = Path(CONF_DIR / "footer.html").read_text()
for key, value in kwargs.items():
setattr(self, key, value)
def title(self, title):
return f"""<h1>{title}</h1>\n"""
def par(self, text):
return f"""<p>{text}</p>\n"""
def ul(self):
return f"""<ul>\n"""
def endUl(self):
return f"""</ul>\n"""
def li(self, text):
return f"""<li> {text}\n"""
def div(self, divclass):
return f"""<div class="{divclass}">\n"""
def endDiv(self):
return f"""</div>\n"""
def img(self, src, alt=None, width=None, title=None):
return f"""<img src="{src}" alt="{alt}" title="{title}" />\n"""
def aimg(self, src, dest, alt=None, width=None, title=None):
return f"""<a href = "{dest}"><img src="{src}" alt="{alt}" title="{title}"/></a>\n"""
def link(self, dest, data):
return f"""<a href="{dest}">{data}</a>"""
def headermeta(self, title):
header = self.header.replace("{{title}}", title)
header = header.replace("{{cannonical_url}}", CANONICALURL)
header = header.replace("{{global_name}}", GLOBALNAME)
header = header.replace("{{global_name}}", GLOBALNAME)
header = header.replace("{{author}}", AUTHOR)
header = header.replace("{{language}}", LANGUAGE)
header = header.replace("{{description}}", DESCRIPTION)
header = header.replace("{{published_date}}", TODAY)
header = header.replace("{{modified_date}}", TODAY)
header = header.replace("{{canonical_url}}", CANONICALURL)
return header
def writeIndex(self, odir, meta) -> None:
try:
title=meta['title']
desc=meta['description']
buf = self.headermeta(title)
buf += self.title(title)
if len(desc) > 0:
buf += self.ul()
for line in desc:
buf += self.li(line)
buf += self.li(f"© {AUTHOR}, {LICENCE}")
buf += self.endUl()
buf += self.div("row")
#imglist = glob.glob(str(odir) + "/.thumbnails/*")
imglist =[]
for img in Path.iterdir(odir / ".thumbnails"):
imglist.append(img)
for n in range(0, 3):
buf += self.div("column")
breakpoint()
for i in range(n, len(imglist), 3):
buf += self.aimg(
".thumbnails/" + imglist[i].name,
imglist[i].name)
buf += self.endDiv()
buf += self.endDiv()
buf += self.footer
with open(f"{odir}/index.html", "w", encoding="utf-8") as file:
file.write(buf)
except:
pass
def writeDetail(self, img, previmg, nextimg):
buf = self.headermeta(title)
buf += self.title(title)
buf += self.img(image)
buf += self.footer
with open(f"build/{self.outfolder}/index.html", "w", encoding="utf-8") as file:
file.write(buf)
def writeMain(self, titles):
with open(f"{str(BUILD_DIR)}/index.html", "w", encoding="utf-8") as file:
title = "Chrissys random Imagelibrary"
file.write(self.headermeta(title))
file.write(self.title(title))
file.write(self.div("row"))
dirs = list(
filter(lambda x: x.is_dir() and x not in exclude, os.scandir(BUILD_DIR))
)
for n in range(0, 3):
file.write(self.div("column"))
for i in range(n, len(dirs), 3):
thumbs = os.listdir(
str(BUILD_DIR) + "/" + dirs[i].name + "/.thumbnails"
)
file.write(self.div("desc"))
file.write(titles[dirs[i].name])
file.write(self.endDiv())
file.write(
self.aimg(
str(dirs[i].name) + "/.thumbnails/" + thumbs[0],
str(dirs[i].name) + "/",
),
)
file.write(self.endDiv())
file.write(self.endDiv())
file.write(self.footer)
class EXIF:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
class IMG:
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
def createThumb(img, thumbdir):
file = Path(img).stem
with Image.open(img) as im:
im.thumbnail(THUMBSIZE)
im.convert("RGB").save(str(thumbdir) + "/" + file + ".jpg", "JPEG")
def processImage(img, odir):
file = Path(img).stem
with Image.open(img) as im:
im.convert("RGB").save(str(odir) + "/" + file + ".jpg", "JPEG")
def generateDir(path):
odir = BUILD_DIR / path.name
thumbdir = BUILD_DIR / path.name / ".thumbnails"
Path.mkdir(odir, parents=True, exist_ok=True)
Path.mkdir(thumbdir, parents=True, exist_ok=True)
return odir, thumbdir
def parseIni(file):
meta = {"title": None, "category": None, "description": [], "files": []}
try:
with open(file, "r") as f:
for line in f:
if line.startswith("desc = "):
meta["description"].append(line.removeprefix("desc = ").strip())
elif line.endswith(".jpg\n" or ".png\n" or ".jpeg\n"):
meta["files"].append(line.strip())
elif line.startswith("title = "):
meta["title"] = line.removeprefix("title = ").strip()
elif line.startswith("category = "):
meta["category"] = line.removeprefix("category = ").strip()
else:
next
except:
pass
return meta
def processDir(path):
try:
if Path.is_file(path /".purrpic.ini"):
breakpoint()
meta = parseIni(path / ".purrpic.ini")
odir, thumbdir = generateDir(path)
for img in meta["files"]:
createThumb(path / img, thumbdir)
processImage(path / img, odir)
return odir, thumbdir, meta
except:
pass
def writeIndex(odir, meta):
html = HTML()
html.writeIndex(odir, meta)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
prog="PurrPic",
description="Creates a static image gallery from a given Filelist",
epilog="Meow! =^.^=",
)
parser.add_argument(
"--inpath",
type=lambda p: Path(p).resolve(),
help="",
)
parser.add_argument(
"--outpath",
type=lambda p: Path(p).resvolve(),
help="",
)
parser.add_argument(
"--start",
"-s",
type=str,
help="",
)
args = parser.parse_args()
breakpoint()
if args.outpath:
BUILD_DIR = args.outpath
metadata = {}
for d in args.inpath.iterdir():
if d.is_dir() and d.name not in exclude:
# processDir(d.name)
try:
odir, thumbdir, meta = processDir(d)
metadata[d.name] = meta
writeIndex(odir, meta)
except:
next
# html = HTML()
# html.writeMain(metadata)