#!/usr/bin/env python3
import subprocess
import tempfile
import hashlib
import glob
import shutil
import os
from os import path
from urllib import parse
import sqlite3
import tqdm
import jinja2
MAIN_IDX_TEMPL = jinja2.Template('''
{{ title }}
{{ title }}
Books
{% for book, idx, pages, cats in books %}
-
{{ book }}:
Index,
Pages{{ "," if cats }}
{% for cat, cat_fn in cats %}
{{ cat }}{{ "," if not loop.last }}
{% endfor %}
{% endfor %}
Overall
Overall Page List
Entries
{% for title, path in entries %}
- {{ title }}
{% endfor %}
''')
CAT_PAGE_LIST_TEMPL = jinja2.Template('''
{{ title }}: {{ cat }} in {{ book }}
{{ cat }} in {{ book }}
Home
{% for pgnum, thumb, link in pages %}
{% endfor %}
''')
BOOK_PAGE_LIST_TEMPL = jinja2.Template('''
{{ title }}: Page listing of {{ book }}
Pages of {{ book }}
Home
{% for pgnum, thumb, _img, link, _hash in pages %}
{% endfor %}
''')
MAIN_PAGE_LIST_TEMPL = jinja2.Template('''
{{ title }}
{{ title }}: Overall Page Listing
Home
Books
{% for book, pages in books %}
- {{ book }}
{% endfor %}
Pages
{% for book, pages in books %}
Pages of {{ book }}
{% for pgnum, thumb, link in pages %}
{% endfor %}
{% endfor %}
''')
BOOK_IDX_TEMPL = jinja2.Template('''
{{ title }}: Index of {{ book }}
Index of {{ book }}
Home
Entries
{% for title, path in entries %}
- {{ title }}
{% endfor %}
''')
PAGE_TEMPL = jinja2.Template('''
{{ title }}: Page {{ pgnum }} of {{ book }}
Page {{ pgnum }} of {{ book }}{{ " ("+cat+")" if cat }}
Home, Pages, Index
{% for title in titles %}
{{ title }}
{% endfor %}
{% if has_prev %}
Previous
{% endif %}
{% if has_next %}
Next
{% endif %}
''')
imgname = lambda prefix, pgnum, orig_fn: f'ar-{prefix.lower()}-{pgnum:04}{path.splitext(orig_fn)[1].lower()}'
imgpath = lambda prefix, pgnum, orig_fn: path.join('images', imgname(prefix, pgnum, orig_fn))
thumbpath = lambda prefix, pgnum: path.join('thumbs', imgname(prefix, pgnum, '_.png'))
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--database', default='kochbuch.sqlite3', help='Metadata db path, default: kochbuch.sqlite3')
parser.add_argument('-t', '--title', default='Image Archive', help='Product title (for headings and file names)')
parser.add_argument('img_path', default='.', nargs='?', help='Base directory of image files')
parser.add_argument('out.zip', default='out', nargs='?', help='Output file')
args = parser.parse_args()
db = sqlite3.connect(args.database)
db.execute('PRAGMA foreign_keys = ON')
pics = {}
print('Building file index')
for pic in tqdm.tqdm(glob.glob(path.join(glob.escape(args.img_path), '**/*.jpg'), recursive=True)):
with open(pic, 'rb') as f:
hash = hashlib.sha3_256()
hash.update(f.read())
hash = hash.hexdigest()
pics[hash] = pic
with tempfile.TemporaryDirectory() as tmpdir:
### FIXME debug
out = '/tmp/tagomatic'
#shutil.rmtree(out) FIXME DEBUG
#os.mkdir(out) FIXME DEBUG
print('Copying images')
# os.mkdir(path.join(out, 'images')) FIXME DEBUG
for hash, prefix, pgnum, orig_fn in db.execute('SELECT sha3, prefix, pgnum, filename FROM pics'):
dst = path.join(out, imgpath(prefix, pgnum, orig_fn))
# shutil.copy(pics[hash], dst) FIXME DEBUG
pics[hash] = dst
print('Generating Thumbnails')
thumb_path = path.join(out, 'thumbs')
# os.mkdir(thumb_path) FIXME DEBUG
# subprocess.check_call([ FIXME DEBUG
# 'mogrify', '-format', 'png', '-path', thumb_path, '-thumbnail', '100x100',
# *pics.values()
# ])
print('Writing indices')
books = [ book for book, in db.execute('SELECT DISTINCT book FROM pics ORDER BY book') ]
book_indices = []
book_pages = []
for book in books:
book_dir = book
# os.mkdir(path.join(out, book_dir)) FIXME DEBUG
entries = [ (value, f'pages/pg{pgnum}.html') for value, pgnum in db.execute(
'''SELECT value, pgnum FROM pic_tags
JOIN pics ON pics.id=pic_tags.pic
WHERE pic_tags.tag=(SELECT id FROM tags WHERE name="title")
AND book=?
AND value NOT NULL AND value != ""
ORDER BY value''', (book,)) ]
idx_fn = path.join(book_dir, 'index.html')
with open(path.join(out, idx_fn), 'w') as f:
f.write(BOOK_IDX_TEMPL.render(title=args.title, book=book, entries=entries))
results = db.execute('SELECT prefix, pgnum, filename, sha3 FROM pics WHERE book=? ORDER BY pgnum',
(book,)).fetchall()
tmp = [ (pgnum, thumbpath(prefix, pgnum), f'{book}/pages/pg{pgnum}.html')
for prefix, pgnum, fn, hash in results ]
book_pages.append((book, tmp))
pages = [ (pgnum,
f'../{thumbpath(prefix, pgnum)}', f'../{imgpath(prefix, pgnum, fn)}', f'pages/pg{pgnum}.html',
hash)
for prefix, pgnum, fn, hash in results ]
pages_fn = path.join(book_dir, 'pages.html')
with open(path.join(out, pages_fn), 'w') as f:
f.write(BOOK_PAGE_LIST_TEMPL.render(title=args.title, book=book, pages=pages))
cats = [ (cat, path.join(book_dir, f'pages-{cat}.html')) for cat, in db.execute(
'SELECT DISTINCT category FROM pics WHERE book=? AND category NOT NULL', (book,)) ]
for cat, cat_fn in cats:
cat_pages = [ (pgnum, '../'+thumbpath(prefix, pgnum), f'pages/pg{pgnum}.html')
for prefix, pgnum, fn in
db.execute('SELECT prefix, pgnum, filename FROM pics WHERE book=? AND category=? ORDER BY pgnum',
(book, cat)) ]
with open(path.join(out, cat_fn), 'w') as f:
f.write(CAT_PAGE_LIST_TEMPL.render(title=args.title, book=book, cat=cat, pages=cat_pages))
book_indices.append((book, idx_fn, pages_fn, cats))
page_dir = path.join(book_dir, 'pages')
# os.mkdir(path.join(out, page_dir)) FIXME DEBUG
for prev, (pgnum, _thumb, img, link, hash), next in zip(
[None] + pages[:-1],
pages,
pages[1:] + [None]):
titles = [ title for title, in db.execute('''
SELECT value FROM pic_tags JOIN pics ON pics.id=pic_tags.pic
WHERE sha3=? AND value NOT NULL AND value!=""
''', (hash,)) ]
cat, = db.execute('SELECT category FROM pics WHERE sha3=?', (hash,)).fetchone()
has_prev = prev is not None
if prev:
has_prev = True
prev_num, prev_img, _1, prev_link, _2 = prev
prev_link = f'pg{prev_num}.html'
else:
has_prev, prev_num, prev_img, prev_link = False, None, None, None
has_next = next is not None
if next:
has_next = True
next_num, next_img, _1, next_link, _2 = next
next_link = f'pg{next_num}.html'
else:
has_next, next_num, next_img, next_link = False, None, None, None
page_fn = path.join(page_dir, f'pg{pgnum}.html')
with open(path.join(out, page_fn), 'w') as f:
f.write(PAGE_TEMPL.render(
title=args.title, page_list='../pages.html', index='../index.html', img=f'../{img}',
titles=titles, pgnum=pgnum, book=book, cat=cat, has_prev=has_prev, prev_link=prev_link,
prev_num=prev_num, prev_img=f'../{prev_img}', has_next=has_next, next_link=next_link,
next_num=next_num, next_img=f'../{next_img}'))
entries = [ (value, f'{book}/pages/pg{pgnum}.html') for value, book, pgnum in db.execute(
'''SELECT value, book, pgnum FROM pic_tags
JOIN pics ON pics.id=pic_tags.pic
WHERE pic_tags.tag=(SELECT id FROM tags WHERE name="title")
AND value NOT NULL AND value != ""
ORDER BY value''') ]
with open(path.join(out, f'index.html'), 'w') as f:
f.write(MAIN_IDX_TEMPL.render(title=args.title, entries=entries, books=book_indices))
with open(path.join(out, f'pages.html'), 'w') as f:
f.write(MAIN_PAGE_LIST_TEMPL.render(title=args.title, books=book_pages, parse=parse))
print('Done.')