Dockerized app

This commit is contained in:
Michael Mandl 2019-12-30 15:59:58 +01:00
parent 10d491fa96
commit 9ee36727ef
10 changed files with 23 additions and 1 deletions

1
app/README.md Normal file
View file

@ -0,0 +1 @@
This is my port of FotoStream to python/flask.

6
app/config.py Normal file
View file

@ -0,0 +1,6 @@
imgdir = "/images"
recursive = True
refresh = 5
cachedir = "auto"
resolution = (1920, 1080)
filetypes = ["*.jpg", "*.JPG"]

4
app/requirements.txt Normal file
View file

@ -0,0 +1,4 @@
Flask==1.0.2
Pillow>=6.2.0
Click==7.0
waitress>=1.4.0

7
app/server.py Executable file
View file

@ -0,0 +1,7 @@
#!/usr/bin/python3
from waitress import serve
import slider
serve(slider.app, host="0.0.0.0", port=5000)

127
app/slider.py Executable file
View file

@ -0,0 +1,127 @@
#!/usr/bin/python3
from flask import (
Flask,
render_template,
send_from_directory,
redirect,
url_for,
request,
)
from random import choice
from pathlib import Path
from PIL import Image
from time import time
from hashlib import sha256
import click
from shutil import rmtree
from tempfile import gettempdir
import config
app = Flask(__name__)
imgdir = Path(config.imgdir).expanduser().resolve()
cache_resolution = config.resolution
cache_dir = (
Path(gettempdir()) / "webslider"
if config.cachedir == "auto"
else Path(config.cachedir)
) / ("%sx%s" % cache_resolution)
def find_images():
images = set()
for filetype in config.filetypes:
glob = "**/" + filetype if config.recursive else filetype
images.update(imgdir.glob(glob))
return list(images)
@app.route("/")
def random():
print(request.remote_addr, request.base_url)
return render_template("random.html", refresh=config.refresh)
@app.route("/random_image/")
def random_image():
print(request.remote_addr, request.base_url)
try:
last_modified_time, last_modified_file = max(
(f.stat().st_mtime, f) for f in find_images()
)
if time() - last_modified_time <= 60:
selected_image = last_modified_file.relative_to(imgdir)
else:
images = find_images()
selected_image = choice(images).relative_to(imgdir)
except ValueError:
return redirect(url_for("static", filename="clear.gif"))
return redirect(
url_for("image", filename=selected_image)
+ "?hash=%s" % get_cache_filename(selected_image)
)
@app.route("/img/<path:filename>")
def image(filename):
print(request.remote_addr, request.base_url)
cache_filename = create_cache_file(filename)
return send_from_directory(cache_dir, cache_filename)
def rm_cachedir():
if cache_dir.exists():
print("Removing cache dir", cache_dir)
rmtree(cache_dir)
def create_cachedir():
if not cache_dir.exists():
print("Creating cache dir", cache_dir)
cache_dir.mkdir(parents=True)
def create_cache_file(filename):
create_cachedir()
cache_file = get_cache_filename(filename)
if not (cache_dir / cache_file).exists():
print("Creating cache file", filename)
img = Image.open(imgdir / filename)
img.thumbnail(cache_resolution)
img.save(cache_dir / cache_file, "JPEG")
return cache_file
def get_cache_filename(filename):
original_file_path = imgdir / filename
return sha256(str(original_file_path.resolve()).encode("utf-8")).hexdigest()
def pre_cache_images():
for image_file in sorted(find_images()):
create_cache_file(image_file.relative_to(imgdir))
@click.command()
@click.option("--build-cache", is_flag=True, default=False, help="pre-cache images")
@click.option(
"--clear-cache", is_flag=True, default=False, help="clear cache directory"
)
def run_slider(build_cache, clear_cache):
if clear_cache:
rm_cachedir()
if build_cache:
pre_cache_images()
app.run(host="0.0.0.0")
if __name__ == "__main__":
run_slider()

BIN
app/static/clear.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

BIN
app/static/loading.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

30
app/templates/random.html Normal file
View file

@ -0,0 +1,30 @@
<html>
<head>
<style>
img {
width: 100%;
height: 98%;
object-fit: contain;
background: url({{ url_for("static", filename="loading.gif") }}) 50% no-repeat;
}
</style>
</head>
<body bgcolor="black">
<img id="slider" src="{{ url_for("static", filename="clear.gif") }}" />
<script>
var downloadingImage = new Image();
downloadingImage.onload = function()
{
document.getElementById("slider").src = this.src;
};
function updateImage()
{
downloadingImage.src = "{{ url_for("random_image") }}?" + new Date().getTime();
}
updateImage();
setInterval(updateImage, {{ refresh * 1000 }});
</script>
</body>
</html>