from flask import Flask from flask import render_template, request, g, redirect, url_for, make_response, flash, session from flask_login import LoginManager, current_user, login_user, logout_user, login_required from flask_log import Logging from urllib import parse from io import BytesIO from wand.image import Image import threading, os, datetime, pytz import scripts.func as func from scripts import database app = Flask(__name__) app.config["SECRET_KEY"] = "***REMOVED***" app.config["FLASK_LOG_LEVEL"] = "DEBUG" flask_log = Logging(app) login_manager = LoginManager(app) login_manager.login_view = "login" def get_comics(): with app.app_context(): func.get_comics() def verify_paths(): with app.app_context(): database.verify_paths() with app.app_context(): app.logger.debug("server start") database.initialize_db() thread = threading.Thread(target=get_comics, args=()) thread.daemon = True thread.start() thread2 = threading.Thread(target=verify_paths, args=()) thread2.daemon = True thread2.start() @app.teardown_appcontext def close_connection(exception): db = getattr(g, '_database', None) if db is not None: db.close() def update_comic_db(sender, **kw): try: database.add_comics(kw["meta"], kw["thumbnails"]) except Exception as e: print(e) func.comic_loaded.connect(update_comic_db) @login_manager.user_loader def load_user(username): return database.get_user(username) @app.route("/login", methods=["GET", "POST"]) def login(): try: if request.method == "POST": username = request.form.get("username") password = request.form.get("password") user = database.get_user(username) if user is None or not user.check_password(password): flash("invalid username or password") return redirect(url_for("login")) login_user(user) next_page = request.args.get("next") if not next_page: next_page = url_for("home") return redirect(next_page) return render_template("login.html", title="login") except Exception as e: return str(e) @app.route("/logout") def logout(): try: logout_user() return redirect(url_for("login")) except Exception as e: return str(e) @app.route("/") def root(): return redirect(url_for("home")) @app.route("/home") @login_required def home(): try: return render_template("home.html", title="Hello World", current_user=current_user) except Exception as e: return str(e) @app.route("/movies") @login_required def movies(): return "No Movies" @app.route("/music") @login_required def music(): return "No music" @app.route("/games") @login_required def games(): return "No Games" @app.route("/comics") @login_required def comics(): polling = request.args.get("polling") if polling: try: return render_template("publisherList.html", comics=database.get_publishers()) except Exception as e: print(e) return str(e) try: return render_template("publisherView.html", title="Comics", comics=database.get_publishers()) except Exception as e: print(e) return str(e) @app.route("/comics/") def comic_reroute(): return redirect(url_for("comics")) @app.route("/comics/") @login_required def comics_publisher(publisher): publisher = parse.unquote(publisher) series = request.args.get("series") series_year = request.args.get("seriesYear") issue = request.args.get("issue") page_number = request.args.get("pageNumber") if series: if issue: if page_number: return comic_viewer(publisher, series, series_year, issue) return comic_gallery(publisher, series, series_year, issue) return render_template("seriesView.html", title="Comics", comics=database.db_get_comics_in_series(series, publisher, series_year)) return render_template("publisherSeriesView.html", title="Comics", comics=database.db_get_series_by_publisher(publisher)) def comic_viewer(publisher, series, series_year, issue): try: publisher_parsed = parse.quote(publisher) series_parsed = parse.quote(series) page_number = int(request.args.get("pageNumber")) meta = database.db_get_comic(publisher, series, series_year, issue) page_count = int(meta["pageCount"]) prev_page = page_number - 1 next_page = page_number + 1 if next_page >= page_count: next_page = 0 if prev_page < 0: prev_page = page_count - 1 prev_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, prev_page) next_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, next_page) return render_template("comicView.html", title="Comics", prev_url=prev_url, next_url=next_url, comic=meta, page_number=page_number) except Exception as e: print(e) return str(e) def comic_gallery(publisher, series, series_year, issue): try: meta = database.db_get_comic(publisher, series, series_year, issue) return render_template("comicGallery.html", title="Comics", comic=meta) except Exception as e: print(e) return str(e) @app.route("/comics/get_comic//") @login_required def get_comic_page(comic_id, page_number): meta = database.db_get_comic_by_id(comic_id) comic = func.open_comic(meta["path"]) byteImage = BytesIO(comic.getPage(page_number)) image = Image(file=byteImage) response = make_response(image.make_blob()) response.headers["cache-control"] = "public" date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta["path"]))) response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z') response.headers["content-type"] = "image/"+image.format return response @app.route("/comics/get_comic///thumbnail") @login_required def get_comic_thumbnail(comic_id, page_number): meta = database.db_get_comic_by_id(comic_id) thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number) response = make_response(thumb["image"]) response.headers["cache-control"] = "public" date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta["path"]))) response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z') response.headers["content-type"] = thumb["type"] return response if __name__ == '__main__': app.run()