import os import re import mimetypes from os.path import isdir, abspath, exists, split from flask import Flask, render_template, abort, send_file, safe_join from PIL import Image from jinja2 import contextfilter, FileSystemLoader app = Flask('gallery') app.config.from_pyfile('gallery.cfg') app.jinja_loader = FileSystemLoader(app.config['TEMPLATE_DIR']) picmime = re.compile(app.config['MIME']) base = app.config['DIRECTORY'] thumb = app.config['THUMB_DIR'] thsize = app.config['THUMB_SIZE'] def is_image(path): return picmime.match(mimetypes.guess_type(path)[0] or 'NOPE') def relurl(ctx, tgt): return safe_join(ctx['path'], tgt) @app.template_filter('gallery') @contextfilter def url_gallery(ctx, tgt): return safe_join('/', relurl(ctx, tgt)) @app.template_filter('picture') @contextfilter def url_picture(ctx, tgt): return safe_join('/pictures', relurl(ctx, tgt)) @app.template_filter('thumb') @contextfilter def url_thumb(ctx, tgt): return safe_join('/thumb', relurl(ctx, tgt)) @app.route('/pictures/') def send_pic(tgt): path = safe_join(base, tgt) if is_image(path): return send_file(path) else: abort(403) def ensure_dir(path): try: os.makedirs(split(path)[0]) except OSError as e: if e.errno == 17: pass else: raise @app.route('/thumb/') def send_thumb(tgt): orig_path = safe_join(base, tgt) if not is_image(orig_path): abort(403) thumb_path = safe_join(thumb, tgt) if not exists(thumb_path) or \ os.stat(thumb_path).st_mtime < os.stat(orig_path).st_mtime: ensure_dir(thumb_path) image = Image.open(orig_path) sz = image.size scale = min(float(b) / a for a,b in zip(sz, thsize)) scale = min(scale, 1) image.resize(list(map(int, (scale * sz[0], scale * sz[1]))), Image.ANTIALIAS).save(thumb_path) return send_file(thumb_path) @app.route('/') @app.route('/') def view(tgt=''): try: path = abspath(safe_join(base, tgt)) names = [s for s in sorted(os.listdir(path))] dirs = [f for f in names if isdir(safe_join(path,f))] pics = list(filter(is_image, names)) return render_template('main.html', dirs=dirs, pics=pics, path=tgt, parent = '/' + os.path.split(tgt)[0]) except OSError as e: if e.errno == 2: abort(404) if __name__ == '__main__': app.run('::', 8080, debug=True)