From f0fb5f0d9fa7e06e49f8c46d590fd3bc355c3c3d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 3 Nov 2018 13:21:26 +0100 Subject: [PATCH 01/23] Serve images from a separate direcory configured in an external config file (config.py) --- .gitignore | 1 + config.py | 1 + slider.py | 9 ++++++++- templates/hello.html | 1 + 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 config.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c18dd8d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ diff --git a/config.py b/config.py new file mode 100644 index 0000000..0b692c8 --- /dev/null +++ b/config.py @@ -0,0 +1 @@ +imgdir = "/home/mandlm/Foto Export/2018/09/2018-09-03" diff --git a/slider.py b/slider.py index db343c8..a695783 100755 --- a/slider.py +++ b/slider.py @@ -1,8 +1,10 @@ #!/usr/bin/python3 -from flask import Flask, render_template +from flask import Flask, render_template, send_from_directory from random import randint +import config + app = Flask(__name__) @@ -11,5 +13,10 @@ def hello(): return render_template("hello.html", num=randint(1, 23)) +@app.route("/img/") +def image(filename): + return send_from_directory(config.imgdir, filename) + + if __name__ == "__main__": app.run() diff --git a/templates/hello.html b/templates/hello.html index 77172c2..1a0f266 100644 --- a/templates/hello.html +++ b/templates/hello.html @@ -2,5 +2,6 @@

Hello slider number {{ num }}!

+

Image

From 96993ac3d0dadc91b3e9125b6e5bab7107c38e5e Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 3 Nov 2018 14:00:06 +0100 Subject: [PATCH 02/23] Serve a random image from imgfolder on /random_image endpoint --- config.py | 2 +- slider.py | 10 +++++++++- templates/hello.html | 1 + 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/config.py b/config.py index 0b692c8..533ba28 100644 --- a/config.py +++ b/config.py @@ -1 +1 @@ -imgdir = "/home/mandlm/Foto Export/2018/09/2018-09-03" +imgdir = "." diff --git a/slider.py b/slider.py index a695783..62456c3 100755 --- a/slider.py +++ b/slider.py @@ -1,7 +1,9 @@ #!/usr/bin/python3 -from flask import Flask, render_template, send_from_directory +from flask import Flask, render_template, send_from_directory, redirect, url_for from random import randint +from os import listdir +import random import config @@ -13,6 +15,12 @@ def hello(): return render_template("hello.html", num=randint(1, 23)) +@app.route("/random_image") +def random_image(): + filename = random.choice(listdir(config.imgdir)) + return redirect(url_for("image", filename=filename)) + + @app.route("/img/") def image(filename): return send_from_directory(config.imgdir, filename) diff --git a/templates/hello.html b/templates/hello.html index 1a0f266..49add83 100644 --- a/templates/hello.html +++ b/templates/hello.html @@ -3,5 +3,6 @@

Hello slider number {{ num }}!

Image

+

Random Image

From 5031b1e8a2094477768114fbad1350dd78b60f1d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Mon, 5 Nov 2018 21:57:26 +0100 Subject: [PATCH 03/23] Serve random images with automatic refresh --- slider.py | 10 +++++----- templates/hello.html | 8 -------- templates/random.html | 8 ++++++++ 3 files changed, 13 insertions(+), 13 deletions(-) delete mode 100644 templates/hello.html create mode 100644 templates/random.html diff --git a/slider.py b/slider.py index 62456c3..f4f8bcf 100755 --- a/slider.py +++ b/slider.py @@ -3,7 +3,7 @@ from flask import Flask, render_template, send_from_directory, redirect, url_for from random import randint from os import listdir -import random +from random import choice import config @@ -11,13 +11,13 @@ app = Flask(__name__) @app.route("/") -def hello(): - return render_template("hello.html", num=randint(1, 23)) +def random(): + return render_template("random.html") -@app.route("/random_image") +@app.route("/random_image/") def random_image(): - filename = random.choice(listdir(config.imgdir)) + filename = choice(listdir(config.imgdir)) return redirect(url_for("image", filename=filename)) diff --git a/templates/hello.html b/templates/hello.html deleted file mode 100644 index 49add83..0000000 --- a/templates/hello.html +++ /dev/null @@ -1,8 +0,0 @@ - - -

Hello slider number {{ num }}!

-

-

Image

-

Random Image

- - diff --git a/templates/random.html b/templates/random.html new file mode 100644 index 0000000..1e3837f --- /dev/null +++ b/templates/random.html @@ -0,0 +1,8 @@ + + + + + + + + From 0f07fb70c8aae673b73ed069c54640baa74fd93b Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Mon, 5 Nov 2018 22:01:57 +0100 Subject: [PATCH 04/23] Configure refresh via config file --- config.py | 1 + slider.py | 2 +- templates/random.html | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/config.py b/config.py index 533ba28..ced3d85 100644 --- a/config.py +++ b/config.py @@ -1 +1,2 @@ imgdir = "." +refresh = 5 diff --git a/slider.py b/slider.py index f4f8bcf..9b0259e 100755 --- a/slider.py +++ b/slider.py @@ -12,7 +12,7 @@ app = Flask(__name__) @app.route("/") def random(): - return render_template("random.html") + return render_template("random.html", refresh=config.refresh) @app.route("/random_image/") diff --git a/templates/random.html b/templates/random.html index 1e3837f..4050ccb 100644 --- a/templates/random.html +++ b/templates/random.html @@ -1,6 +1,6 @@ - + From 8a3edce278d66aec1a05663536b13ef0df43bdd7 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Tue, 6 Nov 2018 20:13:35 +0100 Subject: [PATCH 05/23] Pre-scale and cache images to full-hd resolution --- slider.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/slider.py b/slider.py index 9b0259e..5ebca0b 100755 --- a/slider.py +++ b/slider.py @@ -2,8 +2,10 @@ from flask import Flask, render_template, send_from_directory, redirect, url_for from random import randint -from os import listdir +from os import listdir, makedirs from random import choice +from pathlib import Path +from PIL import Image import config @@ -23,7 +25,15 @@ def random_image(): @app.route("/img/") def image(filename): - return send_from_directory(config.imgdir, filename) + scaled_img_dir = Path(config.imgdir) / ".slider" / "fhd" + if not scaled_img_dir.exists(): + makedirs(scaled_img_dir) + if not (scaled_img_dir / filename).exists(): + img = Image.open(Path(config.imgdir) / filename) + img.thumbnail((1920, 1080)) + img.save(scaled_img_dir / filename) + + return send_from_directory(scaled_img_dir, filename) if __name__ == "__main__": From 71b1b29c3fc7913f3b0596b4177641b48fafef37 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 7 Nov 2018 10:58:52 +0100 Subject: [PATCH 06/23] Cleanup --- requirements.txt | 1 + slider.py | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index f2e1e50..f1a6954 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ Flask==1.0.2 +Pillow==5.3.0 diff --git a/slider.py b/slider.py index 5ebca0b..d17fa05 100755 --- a/slider.py +++ b/slider.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from flask import Flask, render_template, send_from_directory, redirect, url_for -from random import randint from os import listdir, makedirs from random import choice from pathlib import Path From e4de3b31488d6f42a1065d99282cfcb678b6ab98 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Wed, 7 Nov 2018 23:43:29 +0100 Subject: [PATCH 07/23] Ported from os to pathlib --- slider.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/slider.py b/slider.py index d17fa05..56d13f7 100755 --- a/slider.py +++ b/slider.py @@ -1,7 +1,6 @@ #!/usr/bin/python3 from flask import Flask, render_template, send_from_directory, redirect, url_for -from os import listdir, makedirs from random import choice from pathlib import Path from PIL import Image @@ -18,15 +17,17 @@ def random(): @app.route("/random_image/") def random_image(): - filename = choice(listdir(config.imgdir)) - return redirect(url_for("image", filename=filename)) + imgdir = Path(config.imgdir) + images = list(imgdir.glob("*.jpg")) + selected_image = choice(images).relative_to(imgdir) + return redirect(url_for("image", filename=selected_image)) @app.route("/img/") def image(filename): scaled_img_dir = Path(config.imgdir) / ".slider" / "fhd" if not scaled_img_dir.exists(): - makedirs(scaled_img_dir) + scaled_img_dir.mkdir(parents=True) if not (scaled_img_dir / filename).exists(): img = Image.open(Path(config.imgdir) / filename) img.thumbnail((1920, 1080)) From 41d7c104afd328679136b6d8a9e513a8a7ce9788 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 8 Nov 2018 00:10:08 +0100 Subject: [PATCH 08/23] Prefer recent images --- slider.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/slider.py b/slider.py index 56d13f7..4fa7cff 100755 --- a/slider.py +++ b/slider.py @@ -4,6 +4,7 @@ from flask import Flask, render_template, send_from_directory, redirect, url_for from random import choice from pathlib import Path from PIL import Image +from time import time import config @@ -18,16 +19,26 @@ def random(): @app.route("/random_image/") def random_image(): imgdir = Path(config.imgdir) - images = list(imgdir.glob("*.jpg")) - selected_image = choice(images).relative_to(imgdir) + last_modified_time, last_modified_file = max( + (f.stat().st_mtime, f) for f in imgdir.glob("*.jpg") + ) + + if time() - last_modified_time <= 60: + selected_image = last_modified_file.relative_to(imgdir) + else: + images = list(imgdir.glob("*.jpg")) + selected_image = choice(images).relative_to(imgdir) + return redirect(url_for("image", filename=selected_image)) @app.route("/img/") def image(filename): scaled_img_dir = Path(config.imgdir) / ".slider" / "fhd" + if not scaled_img_dir.exists(): scaled_img_dir.mkdir(parents=True) + if not (scaled_img_dir / filename).exists(): img = Image.open(Path(config.imgdir) / filename) img.thumbnail((1920, 1080)) From 13dc09c5b390900dd270b40fbfdeff54bf0d6efe Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 8 Nov 2018 09:00:00 +0100 Subject: [PATCH 09/23] Configure locatoion of cache dir --- .gitignore | 1 + config.py | 1 + slider.py | 20 +++++++++++--------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index c18dd8d..f9d5764 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ __pycache__/ +.* diff --git a/config.py b/config.py index ced3d85..5e666a9 100644 --- a/config.py +++ b/config.py @@ -1,2 +1,3 @@ imgdir = "." refresh = 5 +cachedir = ".webslider" diff --git a/slider.py b/slider.py index 4fa7cff..9b43e77 100755 --- a/slider.py +++ b/slider.py @@ -18,15 +18,16 @@ def random(): @app.route("/random_image/") def random_image(): + img_glob = "*jpg" imgdir = Path(config.imgdir) last_modified_time, last_modified_file = max( - (f.stat().st_mtime, f) for f in imgdir.glob("*.jpg") + (f.stat().st_mtime, f) for f in imgdir.glob(img_glob) ) if time() - last_modified_time <= 60: selected_image = last_modified_file.relative_to(imgdir) else: - images = list(imgdir.glob("*.jpg")) + images = list(imgdir.glob(img_glob)) selected_image = choice(images).relative_to(imgdir) return redirect(url_for("image", filename=selected_image)) @@ -34,17 +35,18 @@ def random_image(): @app.route("/img/") def image(filename): - scaled_img_dir = Path(config.imgdir) / ".slider" / "fhd" + cache_resolution = (1920, 1080) + cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) - if not scaled_img_dir.exists(): - scaled_img_dir.mkdir(parents=True) + if not cache_dir.exists(): + cache_dir.mkdir(parents=True) - if not (scaled_img_dir / filename).exists(): + if not (cache_dir / filename).exists(): img = Image.open(Path(config.imgdir) / filename) - img.thumbnail((1920, 1080)) - img.save(scaled_img_dir / filename) + img.thumbnail(cache_resolution) + img.save(cache_dir / filename) - return send_from_directory(scaled_img_dir, filename) + return send_from_directory(cache_dir, filename) if __name__ == "__main__": From 9a6dd5b86d347b4a1b66206ab837b67f40244fee Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 8 Nov 2018 21:51:43 +0100 Subject: [PATCH 10/23] Html Formatting --- templates/random.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/random.html b/templates/random.html index 4050ccb..45d49ca 100644 --- a/templates/random.html +++ b/templates/random.html @@ -2,7 +2,7 @@ - - - + + + From 382a9896cf8b162a7ecf5f335cc89a909f484427 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Fri, 9 Nov 2018 08:27:26 +0100 Subject: [PATCH 11/23] Delay-load images via javascript --- static/clear.gif | Bin 0 -> 43 bytes static/loading.gif | Bin 0 -> 673 bytes templates/random.html | 19 +++++++++++++++++-- 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 static/clear.gif create mode 100755 static/loading.gif diff --git a/static/clear.gif b/static/clear.gif new file mode 100755 index 0000000000000000000000000000000000000000..f55d454174c86cf2a8bf76baec8c872de08c8992 GIT binary patch literal 43 rcmZ?wbhEHbWMp7uXkcUjg8%>jEB<5wG8q|kKzxu40~3=EBZD;nzy${b literal 0 HcmV?d00001 diff --git a/static/loading.gif b/static/loading.gif new file mode 100755 index 0000000000000000000000000000000000000000..d0bce1542342e912da81a2c260562df172f30d73 GIT binary patch literal 673 zcmZ?wbhEHb6krfw_{6~Q|Nnmm28Kh24mmkF0U1e2Nli^nlO|14{Lk&@8WQa67~pE8 zXTZz|lvDgC+Z`3#dv5h=E26FfcG1 zbL_hF&)}42ws10s6^G;;cE1^EoUR)U5A70}d2pLv!jVIT7j&Z~EblI3x0K*v_sV|m z0kj3v921Z^em#l`(k(o@H$3ZdDRc@9NidXDNbqrumReCGv$gd8+e8WW28HVqkJ_9i zH>s*<31KtHjANIPvi2#*6BEu%3Dak5O_t&NBI)H?V$TxT}#l{vOTn5naXTfF^&~Hhq+NX@#Ccc>y7T?;vjI&jdhsDsPJyAw*m0Qz>i}K7# zL9w50Ng{fT}A5JUe8lRK1h7_Y2;BWJDd=c6f&i?Wv5(5q?6|P zQw{>maxZP<537OA37Uk}7@%_$4o$EWe_Zl>&#id|lE-BpDC#+Fn|msJ%_2h{Hg1vP z#N8WAzfWasG}yq|xqE)DrWaOofX=z|?*pgc%{ig5vl!pqDlC|q&~Z0$&Rvsft&VO- z4MZj+%-+Vx%W}v;V76hyp=;+R;x+~t^Q%*xuFTQAF2})fSfTHDAs>sO!OBw`)&)o$ c0!CNZt))x~rAZP^^P&YOFfdqy5)K#u0POD40{{R3 literal 0 HcmV?d00001 diff --git a/templates/random.html b/templates/random.html index 45d49ca..1c75d0e 100644 --- a/templates/random.html +++ b/templates/random.html @@ -1,8 +1,23 @@ - + + + - + From f103fd05fc2b09a746b1df7d8a7879fd0dfaeafb Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Fri, 9 Nov 2018 16:51:01 +0100 Subject: [PATCH 12/23] Use element-id in javascript --- templates/random.html | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/templates/random.html b/templates/random.html index 1c75d0e..d0b81fa 100644 --- a/templates/random.html +++ b/templates/random.html @@ -9,15 +9,17 @@ background: url({{ url_for("static", filename="loading.gif") }}) 50% no-repeat; } - - + + From 8a79fda820664075b7a5afddd5e6b5de84fad5c9 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 15:18:43 +0100 Subject: [PATCH 13/23] Name cache files by absolute path hash --- slider.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/slider.py b/slider.py index 9b43e77..1e91fab 100755 --- a/slider.py +++ b/slider.py @@ -5,6 +5,7 @@ from random import choice from pathlib import Path from PIL import Image from time import time +from hashlib import sha256 import config @@ -39,14 +40,19 @@ def image(filename): cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) if not cache_dir.exists(): + print("Creating cache dir", cache_dir) cache_dir.mkdir(parents=True) - if not (cache_dir / filename).exists(): - img = Image.open(Path(config.imgdir) / filename) - img.thumbnail(cache_resolution) - img.save(cache_dir / filename) + original_file_path = Path(config.imgdir) / filename + cache_file = sha256(str(original_file_path.resolve()).encode("utf-8")).hexdigest() - return send_from_directory(cache_dir, filename) + if not (cache_dir / cache_file).exists(): + print("Creating cache file", filename) + img = Image.open(original_file_path) + img.thumbnail(cache_resolution) + img.save(cache_dir / cache_file, "JPEG") + + return send_from_directory(cache_dir, cache_file) if __name__ == "__main__": From e20ac0b62e6d88ca9710c2488b023b8caaaf1f97 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 16:26:35 +0100 Subject: [PATCH 14/23] Added options to clear and pre-build cache --- slider.py | 55 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/slider.py b/slider.py index 1e91fab..da7d743 100755 --- a/slider.py +++ b/slider.py @@ -6,11 +6,16 @@ from pathlib import Path from PIL import Image from time import time from hashlib import sha256 +import click +from shutil import rmtree import config app = Flask(__name__) +cache_resolution = (1920, 1080) +cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) + @app.route("/") def random(): @@ -36,24 +41,60 @@ def random_image(): @app.route("/img/") def image(filename): - cache_resolution = (1920, 1080) - cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) + cache_filename = create_cache_file(filename) + return send_from_directory(cache_dir, cache_filename) + + +def rm_cachedir(): + if Path(config.cachedir).exists(): + print("Removing cache dir", config.cachedir) + rmtree(config.cachedir) + + +def create_cachedir(): if not cache_dir.exists(): print("Creating cache dir", cache_dir) cache_dir.mkdir(parents=True) - original_file_path = Path(config.imgdir) / filename - cache_file = sha256(str(original_file_path.resolve()).encode("utf-8")).hexdigest() + +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(original_file_path) + img = Image.open(Path(config.imgdir) / filename) img.thumbnail(cache_resolution) img.save(cache_dir / cache_file, "JPEG") - return send_from_directory(cache_dir, cache_file) + return cache_file + + +def get_cache_filename(filename): + original_file_path = Path(config.imgdir) / filename + return sha256(str(original_file_path.resolve()).encode("utf-8")).hexdigest() + + +def pre_cache_images(): + imgdir = Path(config.imgdir) + for image_file in sorted(imgdir.glob("*.jpg")): + 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() if __name__ == "__main__": - app.run() + run_slider() From bc0ee53d88953e28a262c7826de7dbefb200aba2 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 16:23:04 +0100 Subject: [PATCH 15/23] Expand ~ in source dir path --- config.py | 3 ++- requirements.txt | 1 + slider.py | 9 ++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/config.py b/config.py index 5e666a9..ce3bda5 100644 --- a/config.py +++ b/config.py @@ -1,3 +1,4 @@ imgdir = "." refresh = 5 -cachedir = ".webslider" +cachedir = "/tmp/webslider" +resolution = (1920, 1080) diff --git a/requirements.txt b/requirements.txt index f1a6954..533b660 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ Flask==1.0.2 Pillow==5.3.0 +Click==7.0 diff --git a/slider.py b/slider.py index da7d743..52b56a1 100755 --- a/slider.py +++ b/slider.py @@ -13,7 +13,8 @@ import config app = Flask(__name__) -cache_resolution = (1920, 1080) +imgdir = Path(config.imgdir).expanduser().resolve() +cache_resolution = config.resolution cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) @@ -25,7 +26,6 @@ def random(): @app.route("/random_image/") def random_image(): img_glob = "*jpg" - imgdir = Path(config.imgdir) last_modified_time, last_modified_file = max( (f.stat().st_mtime, f) for f in imgdir.glob(img_glob) ) @@ -64,7 +64,7 @@ def create_cache_file(filename): if not (cache_dir / cache_file).exists(): print("Creating cache file", filename) - img = Image.open(Path(config.imgdir) / filename) + img = Image.open(imgdir / filename) img.thumbnail(cache_resolution) img.save(cache_dir / cache_file, "JPEG") @@ -72,12 +72,11 @@ def create_cache_file(filename): def get_cache_filename(filename): - original_file_path = Path(config.imgdir) / filename + original_file_path = imgdir / filename return sha256(str(original_file_path.resolve()).encode("utf-8")).hexdigest() def pre_cache_images(): - imgdir = Path(config.imgdir) for image_file in sorted(imgdir.glob("*.jpg")): create_cache_file(image_file.relative_to(imgdir)) From 0a3dd01f1a50b5145cbd7acf573db0f7a3e84c02 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 16:36:14 +0100 Subject: [PATCH 16/23] Prevent browsers from caching images with same filenames from different directories --- slider.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/slider.py b/slider.py index 52b56a1..382e270 100755 --- a/slider.py +++ b/slider.py @@ -36,7 +36,7 @@ def random_image(): images = list(imgdir.glob(img_glob)) selected_image = choice(images).relative_to(imgdir) - return redirect(url_for("image", filename=selected_image)) + return redirect(url_for("image", filename=selected_image) + "?hash=%s" % get_cache_filename(selected_image)) @app.route("/img/") From cf6845c30305e9321953bd91907922bad5e82629 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 16:58:19 +0100 Subject: [PATCH 17/23] Added waitress production server script --- requirements.txt | 1 + server.py | 8 ++++++++ 2 files changed, 9 insertions(+) create mode 100755 server.py diff --git a/requirements.txt b/requirements.txt index 533b660..2d2ba95 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ Flask==1.0.2 Pillow==5.3.0 Click==7.0 +waitress==1.1.0 diff --git a/server.py b/server.py new file mode 100755 index 0000000..d5e1cd4 --- /dev/null +++ b/server.py @@ -0,0 +1,8 @@ +#!/usr/bin/python3 + +from waitress import serve + +import slider + +serve(slider.app, host="0.0.0.0", port=8080) + From 1f60023b91b3cc0346dd649b7ae1bff41574e79d Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 18:28:52 +0100 Subject: [PATCH 18/23] Added option so serve images recursively --- config.py | 1 + slider.py | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/config.py b/config.py index ce3bda5..3098ac2 100644 --- a/config.py +++ b/config.py @@ -1,4 +1,5 @@ imgdir = "." +recursive = True refresh = 5 cachedir = "/tmp/webslider" resolution = (1920, 1080) diff --git a/slider.py b/slider.py index 382e270..556b926 100755 --- a/slider.py +++ b/slider.py @@ -14,6 +14,7 @@ import config app = Flask(__name__) imgdir = Path(config.imgdir).expanduser().resolve() +img_glob = "**/*.jpg" if config.recursive else "*.jpg" cache_resolution = config.resolution cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) @@ -25,7 +26,6 @@ def random(): @app.route("/random_image/") def random_image(): - img_glob = "*jpg" last_modified_time, last_modified_file = max( (f.stat().st_mtime, f) for f in imgdir.glob(img_glob) ) @@ -36,7 +36,10 @@ def random_image(): images = list(imgdir.glob(img_glob)) selected_image = choice(images).relative_to(imgdir) - return redirect(url_for("image", filename=selected_image) + "?hash=%s" % get_cache_filename(selected_image)) + return redirect( + url_for("image", filename=selected_image) + + "?hash=%s" % get_cache_filename(selected_image) + ) @app.route("/img/") @@ -77,7 +80,7 @@ def get_cache_filename(filename): def pre_cache_images(): - for image_file in sorted(imgdir.glob("*.jpg")): + for image_file in sorted(imgdir.glob(img_glob)): create_cache_file(image_file.relative_to(imgdir)) From d5f6b4bfd7a5f6a5598376f7d4319ec41d7e0a4b Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 18:33:27 +0100 Subject: [PATCH 19/23] Handle empty input folders --- slider.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/slider.py b/slider.py index 556b926..700ac90 100755 --- a/slider.py +++ b/slider.py @@ -26,15 +26,18 @@ def random(): @app.route("/random_image/") def random_image(): - last_modified_time, last_modified_file = max( - (f.stat().st_mtime, f) for f in imgdir.glob(img_glob) - ) + try: + last_modified_time, last_modified_file = max( + (f.stat().st_mtime, f) for f in imgdir.glob(img_glob) + ) - if time() - last_modified_time <= 60: - selected_image = last_modified_file.relative_to(imgdir) - else: - images = list(imgdir.glob(img_glob)) - selected_image = choice(images).relative_to(imgdir) + if time() - last_modified_time <= 60: + selected_image = last_modified_file.relative_to(imgdir) + else: + images = list(imgdir.glob(img_glob)) + 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) From d6c46f4060139138fca9db05d06478529448a340 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 18:34:24 +0100 Subject: [PATCH 20/23] Changed waitress port to 5000 --- server.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server.py b/server.py index d5e1cd4..8acd373 100755 --- a/server.py +++ b/server.py @@ -4,5 +4,4 @@ from waitress import serve import slider -serve(slider.app, host="0.0.0.0", port=8080) - +serve(slider.app, host="0.0.0.0", port=5000) From 07fd3bdce5109abbc39ba38aa87428ecd3b5c4d0 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 20:31:34 +0100 Subject: [PATCH 21/23] Added cachedir=auto config option --- config.py | 2 +- slider.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/config.py b/config.py index 3098ac2..ab20603 100644 --- a/config.py +++ b/config.py @@ -1,5 +1,5 @@ imgdir = "." recursive = True refresh = 5 -cachedir = "/tmp/webslider" +cachedir = "auto" resolution = (1920, 1080) diff --git a/slider.py b/slider.py index 700ac90..e7b2250 100755 --- a/slider.py +++ b/slider.py @@ -8,6 +8,7 @@ from time import time from hashlib import sha256 import click from shutil import rmtree +from tempfile import gettempdir import config @@ -16,7 +17,11 @@ app = Flask(__name__) imgdir = Path(config.imgdir).expanduser().resolve() img_glob = "**/*.jpg" if config.recursive else "*.jpg" cache_resolution = config.resolution -cache_dir = Path(config.cachedir) / ("%sx%s" % cache_resolution) +cache_dir = ( + Path(gettempdir()) / "webslider" + if config.cachedir == "auto" + else Path(config.cachedir) +) / ("%sx%s" % cache_resolution) @app.route("/") @@ -53,9 +58,9 @@ def image(filename): def rm_cachedir(): - if Path(config.cachedir).exists(): - print("Removing cache dir", config.cachedir) - rmtree(config.cachedir) + if cache_dir.exists(): + print("Removing cache dir", cache_dir) + rmtree(cache_dir) def create_cachedir(): @@ -98,7 +103,7 @@ def run_slider(build_cache, clear_cache): if build_cache: pre_cache_images() - app.run() + app.run(host="0.0.0.0") if __name__ == "__main__": From 30ee37bf74e3c194ebb82eae7b4c06e35762aa08 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Sat, 10 Nov 2018 20:32:06 +0100 Subject: [PATCH 22/23] Refresh via javascript --- templates/random.html | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/random.html b/templates/random.html index d0b81fa..e612e38 100644 --- a/templates/random.html +++ b/templates/random.html @@ -1,6 +1,5 @@ -