89 lines
2.4 KiB
Python
89 lines
2.4 KiB
Python
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/<path:tgt>')
|
|
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/<path:tgt>')
|
|
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('/<path:tgt>')
|
|
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)
|