rpiwebapp-public/comics/comics.py
Matthew Welch 8b2e43b41d bug fixes and navigation improvement
fixed bugs with postgresql group by statement replacing it with the over statement
added buttons to go to the next and previous episodes in the episode viewer
improved pagination so that it will only show a few previous and next pages instead of all of them
and added a next and previous page button
2020-03-28 12:37:11 -07:00

171 lines
7.3 KiB
Python

from flask import Blueprint, render_template, request, make_response, current_app
from flask_login import login_required
from urllib import parse
from io import BytesIO
from wand.image import Image
import os, pytz, datetime
import inspect
from scripts import database, func
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.info(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.info(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:
if page_number:
return comic_viewer(publisher, series, series_year, issue)
return comic_gallery(publisher, series, series_year, issue)
return render_template("comics/seriesView.html", title="Comics", comics=comics,
start=start, end=end, page=page, max_items=max_items, item_count=len(comics))
return render_template("comics/publisherSeriesView.html", title="Comics", publisher_series=publisher_series,
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
def comic_viewer(publisher, series, series_year, issue):
try:
on_mobile = False
if request.user_agent.platform in MOBILE_DEVICES:
on_mobile = True
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)
title = "Comics: "+meta.series+": #"+meta.issuetext+" "+(meta.title or "")
return render_template("comics/comicView.html", title=title, on_mobile=on_mobile, prev_url=prev_url, next_url=next_url, comic=meta, page_number=page_number)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
def comic_gallery(publisher, series, series_year, issue):
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
meta = database.db_get_comic(publisher, series, series_year, issue)
start = (max_items*(page-1))
end = meta.pagecount if meta.pagecount < max_items*page else max_items*page
return render_template("comics/comicGallery.html", title="Comics", comic=meta, start=start, end=end, page=page, max_items=max_items, item_count=meta.pagecount)
except Exception as e:
current_app.logger.info(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)
comic = func.open_comic(meta.path)
byte_image = BytesIO(comic.getPage(page_number))
image = Image(file=byte_image)
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
@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"
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