summaryrefslogtreecommitdiff
path: root/build.py
diff options
context:
space:
mode:
Diffstat (limited to 'build.py')
-rwxr-xr-xbuild.py231
1 files changed, 0 insertions, 231 deletions
diff --git a/build.py b/build.py
deleted file mode 100755
index 9dccb8e..0000000
--- a/build.py
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/usr/bin/env python3
-import jinja2
-import PIL.Image
-import PIL.ImageOps
-import argparse
-import json
-import yaml
-import os
-import re
-import hashlib
-import glob
-from datetime import datetime
-
-imagereg = re.compile("([a-z0-9]*)\\..*")
-thumbsize = 480
-
-
-def hashfile(fname):
- md5 = hashlib.md5()
- print(fname)
- with open(fname, "rb") as f:
- for chunk in iter(lambda: f.read(4096), b""):
- md5.update(chunk)
-
- return md5
-
-
-def parse_res(res):
- return int(res)
-
-
-class FileLoader(jinja2.BaseLoader):
- def get_source(self, environment, template):
- if not os.path.exists(template):
- raise jinja2.TemplateNotFound(template)
- mtime = os.path.getmtime(template)
- with open(template, "r") as f:
- source = f.read()
- return source, template, lambda: mtime == os.path.getmtime(template)
-
-
-class ImageLocation:
- def __init__(self, folder, extension):
- self.folder = folder
- self.stuff = {}
- self.ext = extension
-
- self.unused = set()
- self.existing = {}
-
- if not os.path.isdir(folder):
- os.mkdir(folder)
-
- self.look()
-
- self.tmpname = os.path.join(folder, "tmp")
-
- def look(self):
- for name in os.listdir(self.folder):
- m = imagereg.match(name)
- if m is not None:
- fhash = m.group(1)
-
- self.unused.add(fhash)
- self.existing[fhash] = name
-
- def convert(self, imgname, resolution):
- # First determine the hash from settings
- thash = hashlib.md5(
- bytes(
- f"{resolution}+{self.ext}" + imgname,
- encoding="utf8")
- ).hexdigest()
-
- # Now check if it exists
- if thash in self.existing:
- print(f"Skipping file {imgname}[{thash}]")
- return self.existing[thash], thash
-
- # Okay convert it
- fname = f"{thash}.{self.ext}"
- print(f"Converting file {imgname} to {fname}")
-
- tmpname = f"{self.tmpname}.{self.ext}"
- with PIL.Image.open(imgname) as im:
- target_height = resolution
- im = PIL.ImageOps.exif_transpose(im)
- if im.size[0] > target_height:
- res = (int((im.size[0] / im.size[1]) * target_height), target_height)
- im = im.resize(res, PIL.Image.ANTIALIAS)
-
- im.save(tmpname)
-
- os.rename(tmpname, os.path.join(self.folder, fname))
-
- self.existing[thash] = fname
- self.unused.add(thash)
-
- return fname, thash
-
- def fetch(self, imgname, resolution, relto=None):
- # Check if we already have it
- fname, hash = self.convert(imgname, resolution)
-
- # Mark the hash as used
- self.unused.remove(hash)
-
- if relto is not None:
- full = os.path.join(self.folder, fname)
- return os.path.relpath(full, start=relto)
-
- return fname
-
- def clean(self):
- print("Running cleanup")
- for uhash in self.unused:
- fname = os.path.join(self.folder, self.existing[uhash])
- print(f"Removing file {fname}")
- os.remove(fname)
-
-
-class Image:
- def __init__(self, filename):
- self.name = os.path.basename(filename)
- self.filename = filename
- self.description = ""
- self.url = ""
- self.thumburl = ""
- self.fullurl = ""
- self.file = filename
-
- self.taken = None
- self.load_metadata()
-
- def load_metadata(self):
- try:
- with PIL.Image.open(self.filename) as im:
- taken_str = im.getexif()[36867]
- except KeyError:
- print(f"Could not load date from image {self.filename}")
- return
-
- self.taken = datetime.strptime(taken_str, "%Y:%m:%d %H:%M:%S")
-
-
-def value_or_default(val, default=None):
- if val is None:
- return default
- return val
-
-
-class Loader:
- def __init__(self, config_file, loadpath):
- self.config = Loader.__load_config(config_file)
-
- self.loadpath = loadpath
-
- self.images = []
-
- def __load_config(config_file):
- config = {}
- with open(config_file, "r") as f:
- config = yaml.safe_load(f)
-
- print(f"Loaded config: {config}")
- return config
-
- def load(self, imagehook=None, clear=False):
- # Clear if neccesary
- if clear:
- self.images = []
-
- # First find all images from glob
- for image in glob.iglob(os.path.join(self.loadpath, self.config["imageglob"])):
- img = Image(image)
- img.description = self.config["info"].get(img.name, "")
-
- if imagehook is not None:
- img = imagehook(img)
-
- self.images.append(img)
-
- self.images = sorted(self.images,
- key=lambda img: value_or_default(img.taken,
- datetime.min),
- reverse=True)
-
- def to_json(self):
- jsonable = [img.__dict__ for img in self.images]
- return json.dumps(jsonable)
-
-
-parser = argparse.ArgumentParser()
-parser.add_argument("--dest", "-d", default="dist", help="where to put resulting files")
-parser.add_argument("--size", "-s", type=int, default="1080", help="size to scale web images to")
-parser.add_argument("--commit", "-g", help="git commit hash to announce")
-parser.add_argument("--clean", help="clean unused image files", action="store_true")
-parser.add_argument("--config", "-c", default=None, help="where to load image definitions from")
-parser.add_argument("--template", "-t", default="index.html.j2", help="html template to use")
-parser.add_argument("--cgit", "-w", help="cgit repo base url")
-parser.add_argument("load", help="where to load full size images from")
-parser.add_argument("--ext", "-e", default="png", help="image extension to use")
-
-args = parser.parse_args()
-
-if args.config is None:
- args.config = os.path.join(args.load, "imginfo.yml")
-
-context = {
- "cgit": args.cgit,
- "git": args.commit
- }
-
-loader = Loader(args.config, args.load)
-loc = ImageLocation(os.path.join(args.dest, "imgs"), args.ext)
-
-
-def imgload(img):
- if context["cgit"] is not None:
- img.fullurl = os.path.join(context["cgit"], "plain", img.name)
-
- img.url = loc.fetch(img.file, args.size, relto=args.dest)
- img.thumburl = loc.fetch(img.file, thumbsize, relto=args.dest)
-
- return img
-
-
-loader.load(imgload, clear=True)
-
-with open(os.path.join(args.dest, "imgs", "index.json"), "w") as f:
- f.write(loader.to_json())