From 6a0424b7660ec47256fc06a18c009d2bffbe094e Mon Sep 17 00:00:00 2001 From: Markus Pawlata Date: Sun, 14 Jul 2019 01:20:35 +0200 Subject: [PATCH] - seriously refactored so imports hurt less - changed imports to python3 --- scanner/floatapp/__init__.py | 176 ++++++++++++++++++++++++++++++++-- scanner/floatapp/endpoints.py | 153 ----------------------------- scanner/floatapp/login.py | 26 +---- scanner/floatapp/process.py | 1 - web/js/012-display.js | 2 +- 5 files changed, 176 insertions(+), 182 deletions(-) delete mode 100644 scanner/floatapp/endpoints.py diff --git a/scanner/floatapp/__init__.py b/scanner/floatapp/__init__.py index d624526..27b90b5 100644 --- a/scanner/floatapp/__init__.py +++ b/scanner/floatapp/__init__.py @@ -1,12 +1,176 @@ -from flask import Flask -from flask_login import LoginManager -import os.path +import os +from TreeWalker import TreeWalker +from functools import wraps +from mimetypes import guess_type +from random import shuffle + +from flask import Flask, Response, abort, json, jsonify, request +from flask_login import current_user, login_user, logout_user + +from .process import send_process +from .jsonp import jsonp +from .login import admin_user, load_user +from .login import login_manager app = Flask(__name__) app.config.from_pyfile( os.path.join(os.path.dirname(os.path.abspath(__file__)), "app.cfg")) -login_manager = LoginManager() -import login login_manager.setup_app(app) -import endpoints + +cwd = os.path.dirname(os.path.abspath(__file__)) +permission_map = app.config.get('PERMISSION_MAP', []) + + +def accel_redirect(internal, real, relative_name): + real_path = os.path.join(real, relative_name) + internal_path = os.path.join(internal, relative_name) + if not os.path.isfile(real_path): + abort(404) + mimetype = None + types = guess_type(real_path) + if len(types) != 0: + mimetype = types[0] + response = Response(mimetype=mimetype) + response.headers.add("X-Accel-Redirect", internal_path) + response.cache_control.public = True + if mimetype == "application/json": + response.cache_control.max_age = 3600 + else: + response.cache_control.max_age = 29030400 + return response + + +def cache_base(path): + path = path.replace( + '/', '-').replace( + ' ', '_').replace( + '(', '').replace( + '&', '').replace( + ',', '').replace( + ')', '').replace( + '#', '').replace( + '[', '').replace( + ']', '').replace( + '"', '').replace( + "'", '').replace( + '_-_', '-').lower() + + while path.find("--") != -1: + path = path.replace("--", "-") + + while path.find("__") != -1: + path = path.replace("__", "_") + + if len(path) == 0: + path = "root" + + return path + + +def has_permission(path): + if not current_user.is_anonymous and current_user.is_admin: + return True + + for auth_path in permission_map.keys(): + # this is a protected object + if (path.startswith(auth_path) or + path.startswith(cache_base(auth_path))): + if current_user.is_anonymous: + return False + if current_user.id in permission_map.get(auth_path, []): + return True + else: + return False + return True + + +def admin_required(fn): + @wraps(fn) + def decorated_view(*args, **kwargs): + if (query_is_admin_user(request.args) or + (current_user.is_authenticated and current_user.admin)): + return fn(*args, **kwargs) + return app.login_manager.unauthorized() + return decorated_view + + +def query_is_admin_user(query): + username = query.get("username", None) + password = query.get("password", None) + return (username == app.config["ADMIN_USERNAME"] and + password == app.config["ADMIN_PASSWORD"]) + + +@app.route("/scan") +@admin_required +def scan_photos(): + global cwd + response = send_process([ + "stdbuf", + "-oL", + os.path.abspath(os.path.join(cwd, "../main.py")), + os.path.abspath(app.config["ALBUM_PATH"]), + os.path.abspath(app.config["CACHE_PATH"]) + ], + os.path.join(cwd, "scanner.pid")) + response.headers.add("X-Accel-Buffering", "no") + response.cache_control.no_cache = True + return response + + +@app.route("/auth") +def login(): + if 'logout' in request.args: + logout_user() + + if current_user.is_authenticated: + logout_user() + + if (query_is_admin_user(request.form) or + query_is_admin_user(request.args)): + login_user(admin_user, remember=True) + else: + user_id = (request.form.get('username') or + request.args.get('username', None)) + if user_id: + login_user(load_user(user_id), remember=True) + return 'You are now logged in.' + + return "" + + +@app.route("/albums/") +def albums(path): + if not has_permission(path): + abort(403) + + return accel_redirect( + app.config["ALBUM_ACCEL"], app.config["ALBUM_PATH"], path) + + +@app.route("/cache/") +def cache(path): + if not has_permission(path): + abort(403) + + return accel_redirect( + app.config["CACHE_ACCEL"], app.config["CACHE_PATH"], path) + + +@app.route("/photos") +@jsonp +def photos(): + f = open(os.path.join(app.config["CACHE_PATH"], "all_photos.json"), "r") + photos = json.load(f) + f.close() + photos = [photo for photo in photos if has_permission(photo)] + count = int(request.args.get("count", len(photos))) + random = request.args.get("random") == "true" + if random: + shuffle(photos) + else: + photos.reverse() + response = jsonify(photos=photos[0:count]) + response.cache_control.no_cache = True + return response diff --git a/scanner/floatapp/endpoints.py b/scanner/floatapp/endpoints.py deleted file mode 100644 index ceb0f4d..0000000 --- a/scanner/floatapp/endpoints.py +++ /dev/null @@ -1,153 +0,0 @@ -import os -from mimetypes import guess_type -from random import shuffle - -from flask import Response, abort, json, jsonify, request -from flask_login import current_user, login_user, logout_user - -from floatapp import app -from floatapp.jsonp import jsonp -from floatapp.login import (admin_required, admin_user, - query_is_admin_user, load_user) -from process import send_process -from TreeWalker import TreeWalker - -cwd = os.path.dirname(os.path.abspath(__file__)) -permission_map = app.config.get('PERMISSION_MAP', []) - - -@app.route("/scan") -@admin_required -def scan_photos(): - global cwd - response = send_process([ - "stdbuf", - "-oL", - os.path.abspath(os.path.join(cwd, "../main.py")), - os.path.abspath(app.config["ALBUM_PATH"]), - os.path.abspath(app.config["CACHE_PATH"]) - ], - os.path.join(cwd, "scanner.pid")) - response.headers.add("X-Accel-Buffering", "no") - response.cache_control.no_cache = True - return response - - -@app.route("/auth") -def login(): - if 'logout' in request.args: - logout_user() - - if current_user.is_authenticated: - logout_user() - - if (query_is_admin_user(request.form) or - query_is_admin_user(request.args)): - login_user(admin_user, remember=True) - else: - user_id = (request.form.get('username') or - request.args.get('username', None)) - if user_id: - login_user(load_user(user_id), remember=True) - return 'You are now logged in.' - - return "" - - -@app.route("/albums/") -def albums(path): - if not has_permission(path): - abort(403) - - return accel_redirect( - app.config["ALBUM_ACCEL"], app.config["ALBUM_PATH"], path) - - -@app.route("/cache/") -def cache(path): - if not has_permission(path): - abort(403) - - return accel_redirect( - app.config["CACHE_ACCEL"], app.config["CACHE_PATH"], path) - - -@app.route("/photos") -@jsonp -def photos(): - f = open(os.path.join(app.config["CACHE_PATH"], "all_photos.json"), "r") - photos = json.load(f) - f.close() - photos = [photo for photo in photos if has_permission(photo)] - count = int(request.args.get("count", len(photos))) - random = request.args.get("random") == "true" - if random: - shuffle(photos) - else: - photos.reverse() - response = jsonify(photos=photos[0:count]) - response.cache_control.no_cache = True - return response - - -def accel_redirect(internal, real, relative_name): - real_path = os.path.join(real, relative_name) - internal_path = os.path.join(internal, relative_name) - if not os.path.isfile(real_path): - abort(404) - mimetype = None - types = guess_type(real_path) - if len(types) != 0: - mimetype = types[0] - response = Response(mimetype=mimetype) - response.headers.add("X-Accel-Redirect", internal_path) - response.cache_control.public = True - if mimetype == "application/json": - response.cache_control.max_age = 3600 - else: - response.cache_control.max_age = 29030400 - return response - - -def cache_base(path): - path = path.replace( - '/', '-').replace( - ' ', '_').replace( - '(', '').replace( - '&', '').replace( - ',', '').replace( - ')', '').replace( - '#', '').replace( - '[', '').replace( - ']', '').replace( - '"', '').replace( - "'", '').replace( - '_-_', '-').lower() - - while path.find("--") != -1: - path = path.replace("--", "-") - - while path.find("__") != -1: - path = path.replace("__", "_") - - if len(path) == 0: - path = "root" - - return path - - -def has_permission(path): - if not current_user.is_anonymous and current_user.is_admin: - return True - - for auth_path in permission_map.keys(): - # this is a protected object - if (path.startswith(auth_path) or - path.startswith(cache_base(auth_path))): - if current_user.is_anonymous: - return False - if current_user.id in permission_map.get(auth_path, []): - return True - else: - return False - return True diff --git a/scanner/floatapp/login.py b/scanner/floatapp/login.py index e7b5404..5f54968 100644 --- a/scanner/floatapp/login.py +++ b/scanner/floatapp/login.py @@ -1,7 +1,7 @@ -from floatapp import app, login_manager -from flask import request, abort -from flask_login import current_user, UserMixin -from functools import wraps +from flask import abort +from flask_login import UserMixin, LoginManager + +login_manager = LoginManager() class User(UserMixin): @@ -19,6 +19,7 @@ class User(UserMixin): def is_admin(self): return self.admin + admin_user = User("admin", True) @@ -32,20 +33,3 @@ def load_user(id): @login_manager.unauthorized_handler def unauthorized(): return abort(403) - - -def admin_required(fn): - @wraps(fn) - def decorated_view(*args, **kwargs): - if (query_is_admin_user(request.args) or - (current_user.is_authenticated and current_user.admin)): - return fn(*args, **kwargs) - return app.login_manager.unauthorized() - return decorated_view - - -def query_is_admin_user(query): - username = query.get("username", None) - password = query.get("password", None) - return (username == app.config["ADMIN_USERNAME"] and - password == app.config["ADMIN_PASSWORD"]) diff --git a/scanner/floatapp/process.py b/scanner/floatapp/process.py index 8f29b7b..855477a 100644 --- a/scanner/floatapp/process.py +++ b/scanner/floatapp/process.py @@ -1,7 +1,6 @@ from flask import Response import subprocess import os -import sys class ProcessWrapper(object): diff --git a/web/js/012-display.js b/web/js/012-display.js index f8bb2f8..461ad82 100644 --- a/web/js/012-display.js +++ b/web/js/012-display.js @@ -244,7 +244,7 @@ $(document).ready(function() { $("#next-photo").attr("href", nextLink); $("#next").attr("href", nextLink); $("#back").attr("href", "#!/" + photoFloat.photoHash(currentAlbum, previousPhoto)); - $("#original-link").attr("target", "_blank").attr("href", photoFloat.originalPhotoPath(currentAlbum, currentPhoto)); + $("#original-link").attr("href", photoFloat.originalPhotoPath(currentAlbum, currentPhoto)); text = ""; if (typeof currentPhoto.make !== "undefined") text += "";
Camera Maker" + currentPhoto.make + "