summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-04-03 23:12:04 +0200
committerJulian T <julian@jtle.dk>2021-04-03 23:15:25 +0200
commit4cbc2eae6335222b74129c9eaedab39250c3b7b9 (patch)
tree109eb8b854896aa5b8e8777dbebcd08c615f578b
parent556f61555c022946e80bd5815232867bfab77f6b (diff)
Moved to python based builder
-rwxr-xr-xbuild.py173
-rwxr-xr-xbuild.rb145
-rw-r--r--imginfo.yml39
-rw-r--r--index.html.j242
-rw-r--r--index.tmpl22
-rw-r--r--shell.nix7
6 files changed, 246 insertions, 182 deletions
diff --git a/build.py b/build.py
new file mode 100755
index 0000000..05b05bd
--- /dev/null
+++ b/build.py
@@ -0,0 +1,173 @@
+#!/usr/bin/env python3
+import jinja2
+from PIL import Image
+import argparse
+from pathlib import Path
+import yaml
+import os
+import re
+import hashlib
+
+imagereg = re.compile("([a-z0-9]*)\\..*")
+resreg = re.compile("([0-9]*)x([0-9]*)")
+
+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):
+ m = resreg.match(res)
+ return (int(m.group(1)), int(m.group(2)))
+
+class FileLoader(jinja2.BaseLoader):
+ def get_source(self, environment, template):
+ if not os.path.exists(template):
+ raise TemplateNotFound(template)
+ mtime = os.path.getmtime(template)
+ with open(template, "r") as f:
+ source = f.read()
+ return source, template, lambda: mtime == getmtime(template)
+
+class ImageLocation:
+ def __init__(self, folder):
+ self.folder = folder
+ self.stuff = {}
+
+ 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, settings):
+ # First determine the hash from settings
+ thash = hashlib.md5(bytes(
+ f"{settings['res']}+{settings['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}.{settings['ext']}"
+ print(f"Converting file {imgname} to {fname}")
+
+ im = Image.open(imgname)
+ im = im.resize(settings["res"], Image.ANTIALIAS)
+ tmpname = f"{self.tmpname}.{settings['ext']}"
+ 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, settings, relto=None):
+ # Check if we already have it
+ fname, hash = self.convert(imgname, settings)
+
+ # 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 Renderer:
+ def __init__(self, config_file, loadpath, resolution, extension):
+ self.config = Renderer.__load_config(config_file)
+ self.loadpath = loadpath
+ self.scaled = None
+
+ self.settings = {
+ "res": parse_res(resolution),
+ "ext": extension,
+ }
+
+ 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 imgfetch_gen(self, loc, dest):
+ def fn(img):
+ return loc.fetch(img, self.settings, relto=dest)
+
+ return fn
+
+ def build_to(self, dest, template, context, loc=None, clean=False):
+ if loc is None:
+ loc = ImageLocation(os.path.join(dest, "imgs"))
+
+ jenv = jinja2.Environment(
+ loader = FileLoader(),
+ autoescape=jinja2.select_autoescape(['html', 'xml'])
+ )
+ jenv.globals.update(
+ imgfetch=self.imgfetch_gen(loc, dest)
+ )
+
+ tmpl = jenv.get_template(template)
+
+ with open(os.path.join(dest, "index.html"), "w") as f:
+ f.write(tmpl.render({**self.config, **context}))
+
+ if clean:
+ loc.clean()
+
+parser = argparse.ArgumentParser()
+parser.add_argument("--dest", "-d", default="build", help="where to put resulting files")
+parser.add_argument("--size", "-s", default="1920x1080", 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="imginfo.yml", 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", "-l", default=".", help="where to load full size images from")
+parser.add_argument("--ext", "-e", default="png", help="image extension to use")
+
+args = parser.parse_args()
+
+context = {
+ "cgit": args.cgit,
+ "git": args.commit
+ }
+
+rend = Renderer(args.config, args.load, args.size, args.ext)
+rend.build_to(args.dest, args.template, context, clean=args.clean)
+
+
diff --git a/build.rb b/build.rb
deleted file mode 100755
index 9f4ef88..0000000
--- a/build.rb
+++ /dev/null
@@ -1,145 +0,0 @@
-#!/usr/bin/env ruby
-
-require 'yaml'
-require 'optparse'
-require 'digest'
-require 'mini_magick'
-require 'fileutils'
-require 'erb'
-
-def copyimage(path, file, target, extension)
- hash = Digest::MD5.file(file).hexdigest
- hash = Digest::MD5.hexdigest(hash.to_s + target)
- filename = "#{hash}.#{extension}"
- dest = File.join(path, filename)
-
- if File.exist?(dest)
- puts "Skipping"
- return filename
- end
-
- puts "Writing #{dest}"
- # Resize image and write it to destination
- image = MiniMagick::Image.open(file)
- image.resize(target)
- image.format(extension)
- image.write(dest)
-
- return filename
-end
-
-def forImgs(imgs, &block)
- if imgs.respond_to?("each")
- imgs.each &block
- else
- block.call(imgs)
- end
-end
-
-def placeImage(file, src, href = nil)
- if href
- file.puts "<a href=\"#{href}\">"
- end
- file.puts "<img src=\"#{src}\">"
- if href
- file.puts "</a>"
- end
-end
-
-options = {}
-OptionParser.new do |opts|
- opts.banner = "Usage: build.rb dest"
-
- opts.on("-d", "--dest PATH", "PATH to put build files") do |path|
- options[:path] = path
- end
- opts.on("-s", "--size SIZE", "Size to resize images to") do |size|
- options[:size] = size
- end
- opts.on("-g", "--commit HASH", "Commit to display on website") do |hash|
- options[:commit] = hash
- end
- opts.on("-c", "--clean", "Cleanup unused images") do |v|
- options[:clean] = true
- end
- opts.on("-b", "--linkbase URL", "Add links to images, with URL as base") do |url|
- options[:base] = url
- end
- opts.on("-e", "--extension EXT", "Image extension to use with imagemagick") do |ext|
- options[:extension] = ext
- end
-end.parse!
-
-options[:path] = "build" unless options[:path]
-options[:size] = "1920x1080" unless options[:size]
-options[:clean] = false unless options[:clean]
-options[:extension] = "jpg" unless options[:extension]
-puts options
-
-# Create build dir
-FileUtils.mkdir_p(options[:path])
-
-defs = YAML.load(File.read("imginfo.yml"))
-files = {}
-
-puts defs
-
-defs["groups"].each do |value|
-
- # For each image inside group
- forImgs(value["imgs"]) do |img|
- puts "Converting file #{img}"
- dest = copyimage(options[:path], img, options[:size], options[:extension])
- files[img] = dest
- end
-
-end
-
-puts files
-
-template = File.read("index.tmpl")
-template = template.split("%BODY%")
-
-# Cleanup old files
-if options[:clean]
- Dir.glob(File.join(options[:path], "*")) do |file|
- hash = File.basename(file)
- if !files.values.include? hash
- puts "Cleaning #{hash}"
- File.delete(file)
- end
- end
-end
-
-File.open(File.join(options[:path], "index.html"), "w") do |file|
- # Print preample
- file.write(template[0])
-
- defs["groups"].each do |value|
- file.puts "<div class=\"group\">"
- if value[:title]
- file.puts "<h2>#{value[:title]}</h2>"
- end
- forImgs(value["imgs"]) do |img|
- href = options[:base]
- # If href is given add a filename at the end
- if href
- href = File.join(href, img)
- end
-
- placeImage(file, files[img], href)
- end
-
- if value["what"]
- file.puts "<p>#{value["what"]}"
- end
- file.puts "</div>"
- end
-
- if options[:commit]
- file.puts "<p>Bygget fra commit #{options[:commit]}</p>"
- end
-
- # Print postampleee?
- file.write(template[1])
-end
diff --git a/imginfo.yml b/imginfo.yml
index 9a2419e..fbcc628 100644
--- a/imginfo.yml
+++ b/imginfo.yml
@@ -1,21 +1,30 @@
-groups:
- - imgs: kirke.jpg
- what: Kirke i Århus
- - imgs: bi.jpg
- - imgs: olie.jpg
- what: Boreplatform i Grenå
- - imgs: bakker.jpg
- - imgs: vindmøller.jpg
+posts:
+ - imgs:
+ - kirke.jpg
+ text: Kirke i Århus
+ - imgs:
+ - bi.jpg
+ - imgs:
+ - olie.jpg
+ text: Boreplatform i Grenå
- imgs:
+ - bakker.jpg
+ - imgs:
+ - vindmøller.jpg
+ - imgs:
- vinge.jpg
- imgs:
- blomster2.jpg
- blomster.jpg
- blomster3.jpg
- - imgs: maskiner.jpg
- what: Taget ved Tangeværket.
- - imgs: Struktur.jpg
- what: Taget ved Dwingeloo Radiotelescoop.
- - imgs: bænk.jpg
- what: Taget ved fyrtårn på Helgenæs.
- - imgs: saks.jpg
+ - imgs:
+ - maskiner.jpg
+ text: Taget ved Tangeværket.
+ - imgs:
+ - Struktur.jpg
+ text: Taget ved Dwingeloo Radiotelescoop.
+ - imgs:
+ - bænk.jpg
+ text: Taget ved fyrtårn på Helgenæs.
+ - imgs:
+ - saks.jpg
diff --git a/index.html.j2 b/index.html.j2
new file mode 100644
index 0000000..d25e242
--- /dev/null
+++ b/index.html.j2
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Jtle images</title>
+ <link rel="icon" href="/favicon.png">
+ <meta name="robots" content="noindex,nofollow">
+ <style>
+ img {
+ width: 50%;
+ }
+ .post {
+ background-color: lightgray;
+ margin-bottom: 20px;
+ padding: 10px;
+ }
+ </style>
+ </head>
+ <body>
+ <p>Billeder taget på forskellige ferier etc, som jeg bruger til baggrund. Filer kan også findes <a href="https://git.jtle.dk/wallpapers">her</a>.</p>
+ {% for post in posts %}
+ <div class="post">
+ <p>{{ post.text }}</p>
+ {% for img in post.imgs %}
+ {% if cgit is not none %}
+ <a href="{{cgit}}/plain/{{img}}">
+ <img src="{{ imgfetch(img) }}" />
+ </a>
+ {% else %}
+ <img src="{{ imgfetch(img) }}" />
+ {% endif %}
+
+ {% endfor %}
+ </div>
+ {% endfor %}
+
+
+ {% if git is not none %}
+ <p>Bygget fra commit {{ git }}</p>
+ {% endif %}
+ </body>
+</html>
diff --git a/index.tmpl b/index.tmpl
deleted file mode 100644
index a9dfadb..0000000
--- a/index.tmpl
+++ /dev/null
@@ -1,22 +0,0 @@
-<html>
- <head>
- <meta charset="utf-8">
- <title>Jtle images</title>
- <link rel="icon" href="/favicon.png">
- <meta name="robots" content="noindex,nofollow">
- <style>
-img {
- width: 90%;
-}
-.group {
- background-color: lightgray;
- margin-bottom: 20px;
- padding: 10px;
-}
- </style>
- </head>
- <body>
- <p>Billeder taget på forskellige ferier etc, som jeg bruger til baggrund. Filer kan også findes <a href="https://git.jtle.dk/wallpapers">her</a>.</p>
- %BODY%
- </body>
-</html>
diff --git a/shell.nix b/shell.nix
new file mode 100644
index 0000000..d452969
--- /dev/null
+++ b/shell.nix
@@ -0,0 +1,7 @@
+{ pkgs ? import <nixpkgs> {}, pythonPackages ? pkgs.python38Packages }:
+
+pkgs.mkShell {
+ buildInputs = with pythonPackages; [
+ jinja2 schema pillow pyyaml
+ ];
+}