rpiwebapp-public/comics/comics.py
Matthew Welch c4e6824a8a Move some files out of scripts folder
Change error logging to log messages as error rather than info
Add 404 error when video or comic not found
Change paths to use pathlib
2021-07-10 13:17:28 -07:00

217 lines
8.3 KiB
Python

import datetime
import inspect
import os
from urllib import parse
import filetype
import pytz
from flask import Blueprint, current_app, make_response, render_template, request
from flask_login import login_required
import func
import database
Comics = Blueprint("comics", __name__, template_folder="templates")
MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
@Comics.route("/comics")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publishers = database.get_publishers()
start = max_items * (page - 1)
end = len(publishers) if len(publishers) < max_items * page else max_items * page
return render_template(
"comics/index.html",
title="Comics",
publishers=publishers,
page=page,
max_items=max_items,
start=start,
end=end,
item_count=len(publishers),
)
except Exception as e:
current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/search")
@login_required
def search():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_end = 0
series_end = 0
comics_end = 0
publisher_start = 0
series_start = 0
comics_start = 0
item_count = 0
query = request.args.get("q")
results = {"publisher": [], "series": [], "comics": []}
if query:
results = database.db_search_comics(query)
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
for temp_page in range(1, page + 1):
publisher_start = publisher_end
series_start = series_end
comics_start = comics_end
items = 0
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items * temp_page else max_items * temp_page
items += publisher_end - publisher_start
if items < max_items:
series_end = (
len(results["series"]) if len(results["series"]) < (max_items * temp_page) - items else (max_items * temp_page) - items
)
items += series_end - series_start
if items < max_items:
comics_end = (
len(results["comics"])
if len(results["comics"]) < (max_items * temp_page) - series_end - publisher_end
else (max_items * temp_page) - series_end - publisher_end
)
return render_template(
"comics/search.html",
title="Comics: Search",
publishers=results["publisher"],
publisher_series=results["series"],
comics=results["comics"],
page=page,
max_items=max_items,
item_count=item_count,
publisher_start=publisher_start,
series_start=series_start,
comics_start=comics_start,
publisher_end=publisher_end,
series_end=series_end,
comics_end=comics_end,
)
except Exception as e:
current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/<publisher>")
@login_required
def comics_publisher(publisher):
try:
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")
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_series = database.db_get_series_by_publisher(publisher)
start = max_items * (page - 1)
end = len(publisher_series) if len(publisher_series) < max_items * page else max_items * page
if series:
comics = database.db_get_comics_in_series(series, publisher, series_year)
start = max_items * (page - 1)
end = len(comics) if len(comics) < max_items * page else max_items * page
if issue:
return comic_gallery(publisher, series, series_year, issue)
comics_dict = []
for i in comics:
item = i.__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
comics_dict.append(item)
return render_template(
"comics/seriesView.html",
title="Comics",
comics=comics_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=len(comics),
)
pub_series_dict = []
for i in publisher_series:
item = i.__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
pub_series_dict.append(item)
return render_template(
"comics/publisherSeriesView.html",
title="Comics",
publisher_series=pub_series_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=len(publisher_series),
)
except Exception as e:
current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/<int:comic_id>")
@login_required
def comic_gallery(comic_id):
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
meta = database.db_get_comic(comic_id)
start = max_items * (page - 1)
end = meta.pagecount if meta.pagecount < max_items * page else max_items * page
comic_dict = meta.__dict__
comic_dict.pop("_sa_instance_state", None)
comic_dict.pop("path", None)
return render_template(
"comics/comicGallery.html",
title="Comics",
comic=comic_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=meta.pagecount,
)
except Exception as e:
current_app.logger.error(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>")
@login_required
def get_comic_page(comic_id, page_number):
meta = database.db_get_comic_by_id(comic_id)
if not os.path.exists(meta.path):
return "File not found", 404
comic = func.open_comic(meta.path)
byte_image = comic.getPage(page_number)
type = filetype.guess(byte_image).mime
response = make_response(byte_image)
response.headers["content-type"] = type
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-Disposition"] = 'attachment; filename="{} {}_{}{}"'.format(
str(meta.series), meta.issuetext, str(page_number), filetype.guess(byte_image).extension
)
return response
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>/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"
if os.path.exists(meta.path):
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
response.headers["Content-Disposition"] = 'filename="{} {}_{}_thumbnail"'.format(str(meta.series), meta.issuetext, str(page_number))
return response