Changed file formatting and fixed comic viewer.
This commit is contained in:
parent
51c6b5e572
commit
f8aa5ff2d7
@ -1,5 +1,5 @@
|
|||||||
from flask import Blueprint, flash, redirect, url_for, render_template
|
from flask import Blueprint, flash, redirect, render_template, url_for
|
||||||
from flask_login import login_required, current_user
|
from flask_login import current_user, login_required
|
||||||
|
|
||||||
Admin = Blueprint("admin", __name__, template_folder="templates")
|
Admin = Blueprint("admin", __name__, template_folder="templates")
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ Admin = Blueprint("admin", __name__, template_folder="templates")
|
|||||||
@Admin.route("/admin")
|
@Admin.route("/admin")
|
||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
if not current_user.is_admin:
|
if not current_user.is_admin:
|
||||||
flash("you must be an admin to access this page, login with an admin account.")
|
flash("you must be an admin to access this page, login with an admin account.")
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
return render_template("admin/index.html", title="Admin")
|
return render_template("admin/index.html", title="Admin")
|
||||||
|
298
comics/comics.py
298
comics/comics.py
@ -1,10 +1,12 @@
|
|||||||
from flask import Blueprint, render_template, request, make_response, current_app
|
import datetime
|
||||||
from flask_login import login_required
|
|
||||||
|
|
||||||
from urllib import parse
|
|
||||||
import filetype
|
|
||||||
import os, pytz, datetime
|
|
||||||
import inspect
|
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
|
||||||
|
|
||||||
from scripts import database, func
|
from scripts import database, func
|
||||||
|
|
||||||
@ -16,145 +18,195 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
|
|||||||
@Comics.route("/comics")
|
@Comics.route("/comics")
|
||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
publishers = database.get_publishers()
|
publishers = database.get_publishers()
|
||||||
start = (max_items*(page-1))
|
start = max_items * (page - 1)
|
||||||
end = len(publishers) if len(publishers) < max_items*page else max_items*page
|
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))
|
return render_template(
|
||||||
except Exception as e:
|
"comics/index.html",
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
title="Comics",
|
||||||
return str(type(e)) + " " + str(e)
|
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")
|
@Comics.route("/comics/search")
|
||||||
@login_required
|
@login_required
|
||||||
def search():
|
def search():
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
publisher_end = 0
|
publisher_end = 0
|
||||||
series_end = 0
|
series_end = 0
|
||||||
comics_end = 0
|
comics_end = 0
|
||||||
publisher_start = 0
|
publisher_start = 0
|
||||||
series_start = 0
|
series_start = 0
|
||||||
comics_start = 0
|
comics_start = 0
|
||||||
item_count = 0
|
item_count = 0
|
||||||
query = request.args.get("q")
|
query = request.args.get("q")
|
||||||
results = {
|
results = {"publisher": [], "series": [], "comics": []}
|
||||||
"publisher": [],
|
if query:
|
||||||
"series": [],
|
results = database.db_search_comics(query)
|
||||||
"comics": []
|
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
|
||||||
}
|
for temp_page in range(1, page + 1):
|
||||||
if query:
|
publisher_start = publisher_end
|
||||||
results = database.db_search_comics(query)
|
series_start = series_end
|
||||||
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
|
comics_start = comics_end
|
||||||
for temp_page in range(1, page+1):
|
items = 0
|
||||||
publisher_start = publisher_end
|
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items * temp_page else max_items * temp_page
|
||||||
series_start = series_end
|
items += publisher_end - publisher_start
|
||||||
comics_start = comics_end
|
if items < max_items:
|
||||||
items = 0
|
series_end = (
|
||||||
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items*temp_page else max_items*temp_page
|
len(results["series"]) if len(results["series"]) < (max_items * temp_page) - items else (max_items * temp_page) - items
|
||||||
items += publisher_end - publisher_start
|
)
|
||||||
if items < max_items:
|
items += series_end - series_start
|
||||||
series_end = len(results["series"]) if len(results["series"]) < (max_items*temp_page)-items else (max_items*temp_page)-items
|
if items < max_items:
|
||||||
items += series_end-series_start
|
comics_end = (
|
||||||
if items < max_items:
|
len(results["comics"])
|
||||||
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
|
if len(results["comics"]) < (max_items * temp_page) - series_end - publisher_end
|
||||||
return render_template("comics/search.html", title="Comics: Search", publishers=results["publisher"], publisher_series=results["series"],
|
else (max_items * temp_page) - series_end - publisher_end
|
||||||
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,
|
return render_template(
|
||||||
publisher_end=publisher_end, series_end=series_end, comics_end=comics_end)
|
"comics/search.html",
|
||||||
except Exception as e:
|
title="Comics: Search",
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
publishers=results["publisher"],
|
||||||
return str(type(e))+" "+str(e)
|
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>")
|
@Comics.route("/comics/<publisher>")
|
||||||
@login_required
|
@login_required
|
||||||
def comics_publisher(publisher):
|
def comics_publisher(publisher):
|
||||||
try:
|
try:
|
||||||
publisher = parse.unquote(publisher)
|
publisher = parse.unquote(publisher)
|
||||||
series = request.args.get("series")
|
series = request.args.get("series")
|
||||||
series_year = request.args.get("seriesYear")
|
series_year = request.args.get("seriesYear")
|
||||||
issue = request.args.get("issue")
|
issue = request.args.get("issue")
|
||||||
page_number = request.args.get("pageNumber")
|
page_number = request.args.get("pageNumber")
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
publisher_series = database.db_get_series_by_publisher(publisher)
|
publisher_series = database.db_get_series_by_publisher(publisher)
|
||||||
start = (max_items*(page-1))
|
start = max_items * (page - 1)
|
||||||
end = len(publisher_series) if len(publisher_series) < max_items*page else max_items*page
|
end = len(publisher_series) if len(publisher_series) < max_items * page else max_items * page
|
||||||
if series:
|
if series:
|
||||||
comics = database.db_get_comics_in_series(series, publisher, series_year)
|
comics = database.db_get_comics_in_series(series, publisher, series_year)
|
||||||
start = (max_items * (page - 1))
|
start = max_items * (page - 1)
|
||||||
end = len(comics) if len(comics) < max_items * page else max_items * page
|
end = len(comics) if len(comics) < max_items * page else max_items * page
|
||||||
if issue:
|
if issue:
|
||||||
return comic_gallery(publisher, series, series_year, issue)
|
return comic_gallery(publisher, series, series_year, issue)
|
||||||
comics_dict = []
|
comics_dict = []
|
||||||
for i in comics:
|
for i in comics:
|
||||||
item = i.__dict__
|
item = i.__dict__
|
||||||
item.pop('_sa_instance_state', None)
|
item.pop("_sa_instance_state", None)
|
||||||
item.pop('path', None)
|
item.pop("path", None)
|
||||||
comics_dict.append(item)
|
comics_dict.append(item)
|
||||||
return render_template("comics/seriesView.html", title="Comics", comics=comics_dict,
|
return render_template(
|
||||||
start=start, end=end, page=page, max_items=max_items, item_count=len(comics))
|
"comics/seriesView.html",
|
||||||
pub_series_dict = []
|
title="Comics",
|
||||||
for i in publisher_series:
|
comics=comics_dict,
|
||||||
item = i.__dict__
|
start=start,
|
||||||
item.pop('_sa_instance_state', None)
|
end=end,
|
||||||
item.pop('path', None)
|
page=page,
|
||||||
pub_series_dict.append(item)
|
max_items=max_items,
|
||||||
return render_template("comics/publisherSeriesView.html", title="Comics", publisher_series=pub_series_dict,
|
item_count=len(comics),
|
||||||
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
|
)
|
||||||
except Exception as e:
|
pub_series_dict = []
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
for i in publisher_series:
|
||||||
return str(type(e)) + " " + str(e)
|
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.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@Comics.route("/comics/<int:comic_id>")
|
@Comics.route("/comics/<int:comic_id>")
|
||||||
@login_required
|
@login_required
|
||||||
def comic_gallery(comic_id):
|
def comic_gallery(comic_id):
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
meta = database.db_get_comic(comic_id)
|
meta = database.db_get_comic(comic_id)
|
||||||
start = (max_items*(page-1))
|
start = max_items * (page - 1)
|
||||||
end = meta.pagecount if meta.pagecount < max_items*page else max_items*page
|
end = meta.pagecount if meta.pagecount < max_items * page else max_items * page
|
||||||
comic_dict = meta.__dict__
|
comic_dict = meta.__dict__
|
||||||
comic_dict.pop('_sa_instance_state', None)
|
comic_dict.pop("_sa_instance_state", None)
|
||||||
comic_dict.pop('path', 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)
|
return render_template(
|
||||||
except Exception as e:
|
"comics/comicGallery.html",
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
title="Comics",
|
||||||
return str(type(e)) + " " + str(e)
|
comic=comic_dict,
|
||||||
|
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>")
|
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>")
|
||||||
@login_required
|
@login_required
|
||||||
def get_comic_page(comic_id, page_number):
|
def get_comic_page(comic_id, page_number):
|
||||||
meta = database.db_get_comic_by_id(comic_id)
|
meta = database.db_get_comic_by_id(comic_id)
|
||||||
comic = func.open_comic(meta.path)
|
comic = func.open_comic(meta.path)
|
||||||
byte_image = comic.getPage(page_number)
|
byte_image = comic.getPage(page_number)
|
||||||
type = filetype.guess(byte_image).mime
|
type = filetype.guess(byte_image).mime
|
||||||
response = make_response(byte_image)
|
response = make_response(byte_image)
|
||||||
response.headers["content-type"] = type
|
response.headers["content-type"] = type
|
||||||
response.headers["cache-control"] = "public"
|
response.headers["cache-control"] = "public"
|
||||||
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(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["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)
|
response.headers["Content-Disposition"] = 'attachment; filename="{} {}_{}{}"'.format(
|
||||||
return response
|
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")
|
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>/thumbnail")
|
||||||
@login_required
|
@login_required
|
||||||
def get_comic_thumbnail(comic_id, page_number):
|
def get_comic_thumbnail(comic_id, page_number):
|
||||||
meta = database.db_get_comic_by_id(comic_id)
|
meta = database.db_get_comic_by_id(comic_id)
|
||||||
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
|
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
|
||||||
response = make_response(thumb.image)
|
response = make_response(thumb.image)
|
||||||
response.headers["cache-control"] = "public"
|
response.headers["cache-control"] = "public"
|
||||||
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(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["last-modified"] = date.strftime("%a, %d %b %Y %H:%M:%S %Z")
|
||||||
response.headers["content-type"] = thumb.type
|
response.headers["content-type"] = thumb.type
|
||||||
response.headers["Content-Disposition"] = "attachment; filename=\"{} {}_{}_thumbnail\"".format(str(meta.series), meta.issuetext, str(page_number))
|
response.headers["Content-Disposition"] = 'attachment; filename="{} {}_{}_thumbnail"'.format(str(meta.series), meta.issuetext, str(page_number))
|
||||||
return response
|
return response
|
||||||
|
@ -117,7 +117,7 @@
|
|||||||
page_container.innerHTML = "";
|
page_container.innerHTML = "";
|
||||||
for (i = start;i < end; i++) {
|
for (i = start;i < end; i++) {
|
||||||
var list_element = `<div style="margin: auto" class="comic-thumbnail card bg-dark text-white">
|
var list_element = `<div style="margin: auto" class="comic-thumbnail card bg-dark text-white">
|
||||||
<img src="/comics/get_comic/${comic.id}/${i}/thumbnail" alt="" style="display: inline" onerror="this.src='/static/images/default.png';this.height='256'" onclick="openLightBox();currentImage(${1+i})">
|
<img src="/comics/get_comic/${comic.id}/${i}/thumbnail" alt="" style="display: inline" onerror="this.src='/static/images/default.png';this.height='256'" onclick="openLightBox();currentImage(${1+i});load_next_image(${i});">
|
||||||
<p class="card-text">${1+i}/${comic.pagecount}</p>
|
<p class="card-text">${1+i}/${comic.pagecount}</p>
|
||||||
</div>`;
|
</div>`;
|
||||||
page_container.innerHTML += list_element;
|
page_container.innerHTML += list_element;
|
||||||
@ -134,15 +134,24 @@
|
|||||||
let next_image = document.getElementById("next");
|
let next_image = document.getElementById("next");
|
||||||
let prev_image = document.getElementById("prev");
|
let prev_image = document.getElementById("prev");
|
||||||
|
|
||||||
|
for (let i=0; i<{{ item_count }};i++) {
|
||||||
|
light_box_content.innerHTML += `<div class="images" style="display: none"></div>`
|
||||||
|
}
|
||||||
|
|
||||||
function load_next_image(page_number) {
|
function load_next_image(page_number) {
|
||||||
if (document.getElementById(page_number.toString())) {return;}
|
if (document.getElementById(page_number.toString())) {return;}
|
||||||
if (page_number >= page_count) {return;}
|
if (page_number >= page_count) {return;}
|
||||||
console.log("start loading: page "+(page_number+1).toString());
|
console.log("start loading: page "+(page_number+1).toString());
|
||||||
let image = '<div class="images">';
|
let image = '<div class="images" style="display: none">';
|
||||||
image += `<div class="numbertext">${1 + page_number} / ${page_count}</div>`;
|
image += `<div class="numbertext">${1 + page_number} / ${page_count}</div>`;
|
||||||
image += `<img id="${page_number}" style="width: 100%" src="/comics/get_comic/${comic_id}/${page_number}" alt="" onerror="this.src=\'/static/images/default.png\';load_next_image(${page_number + 1})" ondragstart="return false" onload="load_next_image(${page_number + 1})">`;
|
image += `<img id="${page_number}" style="width: 100%" src="/comics/get_comic/${comic_id}/${page_number}" alt="" onerror="this.src=\'/static/images/default.png\';load_next_image(${page_number + 1})" ondragstart="return false" onload="load_next_image(${page_number + 1})">`;
|
||||||
image += '</div>';
|
image += '</div>';
|
||||||
light_box_content.innerHTML += image;
|
{#light_box_content.innerHTML += image;#}
|
||||||
|
var slides = document.getElementsByClassName("images");
|
||||||
|
slides[page_number].outerHTML = image
|
||||||
|
if (imageIndex == page_number+1) {
|
||||||
|
currentImage(page_number+1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the Modal
|
// Open the Modal
|
||||||
@ -202,4 +211,6 @@
|
|||||||
});
|
});
|
||||||
load_next_image(0);
|
load_next_image(0);
|
||||||
</script>
|
</script>
|
||||||
|
<script type="text/python">
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
218
games/games.py
218
games/games.py
@ -1,10 +1,9 @@
|
|||||||
from flask import Blueprint, render_template, request, send_file, current_app, jsonify, abort
|
|
||||||
from flask_login import login_required
|
|
||||||
|
|
||||||
from pathvalidate import sanitize_filename
|
|
||||||
import os
|
|
||||||
import inspect
|
import inspect
|
||||||
import re
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
from flask import Blueprint, abort, current_app, jsonify, render_template, request, send_file
|
||||||
|
from flask_login import login_required
|
||||||
|
|
||||||
from scripts import database, func
|
from scripts import database, func
|
||||||
|
|
||||||
@ -14,78 +13,157 @@ Games = Blueprint("games", __name__, template_folder="templates")
|
|||||||
@Games.route("/games")
|
@Games.route("/games")
|
||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
games = database.get_all_games()
|
games = database.get_all_games()
|
||||||
start = (max_items*(page-1))
|
start = max_items * (page - 1)
|
||||||
end = len(games) if len(games) < max_items*page else max_items*page
|
end = len(games) if len(games) < max_items * page else max_items * page
|
||||||
return render_template("games/index.html", title="Games", games=games)
|
return render_template("games/index.html", title="Games", games=games)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@Games.route('/games/get_games')
|
@Games.route("/games/get_games")
|
||||||
@login_required
|
@login_required
|
||||||
def get_games():
|
def get_games():
|
||||||
try:
|
try:
|
||||||
games = database.get_all_games()
|
games = database.get_all_games()
|
||||||
games_json = {}
|
games_json = {}
|
||||||
for game in games:
|
for game in games:
|
||||||
games_json[game.game_id] = {
|
games_json[game.game_id] = {
|
||||||
"id": game.game_id,
|
"id": game.game_id,
|
||||||
"title": game.title,
|
"title": game.title,
|
||||||
"windows": game.windows,
|
"description": game.description,
|
||||||
"mac": game.mac,
|
"poster_path": game.poster_path,
|
||||||
"linux": game.linux,
|
"windows": game.windows,
|
||||||
"description": game.description,
|
"mac": game.mac,
|
||||||
"poster_path": game.poster_path
|
"linux": game.linux,
|
||||||
}
|
"title_sanitized": game.title_sanitized,
|
||||||
return jsonify(games_json)
|
}
|
||||||
# return jsonify({game["id"]: game for game in games})
|
return jsonify(games_json)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@Games.route('/games/get_game/<int:game_id>')
|
@Games.route("/games/get_games/windows")
|
||||||
|
@login_required
|
||||||
|
def get_games_windows():
|
||||||
|
try:
|
||||||
|
games = database.get_windows_games()
|
||||||
|
games_json = {}
|
||||||
|
for game in games:
|
||||||
|
with open(os.path.join(game.path, "info.json")) as f:
|
||||||
|
info = json.load(f)
|
||||||
|
games_json[game.game_id] = {
|
||||||
|
"id": game.game_id,
|
||||||
|
"title": game.title,
|
||||||
|
"description": game.description,
|
||||||
|
"poster_path": game.poster_path,
|
||||||
|
"windows": {"executable": info["windows"]["executable"]},
|
||||||
|
"title_sanitized": game.title_sanitized,
|
||||||
|
}
|
||||||
|
return jsonify(games_json)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@Games.route("/games/get_games/mac")
|
||||||
|
@login_required
|
||||||
|
def get_games_mac():
|
||||||
|
try:
|
||||||
|
games = database.get_mac_games()
|
||||||
|
games_json = {}
|
||||||
|
for game in games:
|
||||||
|
with open(os.path.join(game.path, "info.json")) as f:
|
||||||
|
info = json.load(f)
|
||||||
|
games_json[game.game_id] = {
|
||||||
|
"id": game.game_id,
|
||||||
|
"title": game.title,
|
||||||
|
"description": game.description,
|
||||||
|
"poster_path": game.poster_path,
|
||||||
|
"title_sanitized": game.title_sanitized,
|
||||||
|
"mac": {},
|
||||||
|
}
|
||||||
|
if "executable" in info["mac"].keys():
|
||||||
|
games_json[game.game_id]["mac"] = {"executable": info["mac"]["executable"]}
|
||||||
|
return jsonify(games_json)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@Games.route("/games/get_games/linux")
|
||||||
|
@login_required
|
||||||
|
def get_games_linux():
|
||||||
|
try:
|
||||||
|
games = database.get_linux_games()
|
||||||
|
games_json = {}
|
||||||
|
for game in games:
|
||||||
|
with open(os.path.join(game.path, "info.json")) as f:
|
||||||
|
info = json.load(f)
|
||||||
|
games_json[game.game_id] = {
|
||||||
|
"id": game.game_id,
|
||||||
|
"title": game.title,
|
||||||
|
"description": game.description,
|
||||||
|
"poster_path": game.poster_path,
|
||||||
|
"title_sanitized": game.title_sanitized,
|
||||||
|
"linux": {"executable": info["linux"]["executable"]},
|
||||||
|
}
|
||||||
|
return jsonify(games_json)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@Games.route("/games/get_game/<int:game_id>")
|
||||||
@login_required
|
@login_required
|
||||||
def get_game(game_id):
|
def get_game(game_id):
|
||||||
try:
|
try:
|
||||||
game = database.get_game(game_id)
|
game = database.get_game(game_id)
|
||||||
if game:
|
if game:
|
||||||
game_json = {
|
with open(os.path.join(game.path, "info.json")) as f:
|
||||||
"title": game.title,
|
info = json.load(f)
|
||||||
"game_id": game.game_id,
|
windows = None
|
||||||
"description": game.description,
|
mac = None
|
||||||
"poster_path": game.poster_path,
|
linux = None
|
||||||
"windows": game.windows,
|
if "windows" in info.keys():
|
||||||
"mac": game.mac,
|
windows = info["windows"]
|
||||||
"linux": game.linux
|
if "mac" in info.keys():
|
||||||
}
|
mac = info["mac"]
|
||||||
return jsonify(game_json)
|
if "linux" in info.keys():
|
||||||
abort(404)
|
linux = info["linux"]
|
||||||
except Exception as e:
|
game_json = {
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
"title": game.title,
|
||||||
return str(type(e)) + " " + str(e)
|
"game_id": game.game_id,
|
||||||
|
"description": game.description,
|
||||||
|
"poster_path": game.poster_path,
|
||||||
|
"windows": windows,
|
||||||
|
"mac": mac,
|
||||||
|
"linux": linux,
|
||||||
|
"title_sanitized": game.title_sanitized,
|
||||||
|
}
|
||||||
|
return jsonify(game_json)
|
||||||
|
abort(404)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@Games.route("/games/download/<int:game_id>")
|
@Games.route("/games/download_hash/<int:game_id>/<file_hash>")
|
||||||
@login_required
|
@login_required
|
||||||
def download_game(game_id):
|
def download_game_hash(game_id, file_hash):
|
||||||
try:
|
try:
|
||||||
game = database.get_game(game_id)
|
game = database.get_game(game_id)
|
||||||
if game:
|
if game:
|
||||||
files = game.windows["files"]
|
folder = game.path
|
||||||
filename = sanitize_filename(files[0])
|
path = os.path.join(folder, file_hash[:2], file_hash)
|
||||||
folder = re.match(r"(.+)_setup_win.(exe|msi)", filename).group(1)
|
return send_file(path, as_attachment=True, attachment_filename=file_hash)
|
||||||
if len(files) > 1:
|
else:
|
||||||
filename = sanitize_filename(game.title+".zip")
|
abort(404)
|
||||||
path = os.path.join(func.GAMES_DIRECTORY, folder, filename)
|
except Exception as e:
|
||||||
return send_file(path, as_attachment=True, attachment_filename=filename)
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
else:
|
return str(type(e)) + " " + str(e)
|
||||||
abort(404)
|
|
||||||
except Exception as e:
|
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
|
||||||
return str(type(e)) + " " + str(e)
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% for game in games %}
|
{% for game in games %}
|
||||||
<a class="btn btn-primary" href="{{ url_for("games.index") }}/download/{{ game.game_id }}">Download</a>
|
<a class="btn btn-primary" href="{{ url_for("games.index") }}/download/windows/{{ game.game_id }}" download>Download</a>
|
||||||
<p>{{ game.title }} - {{ game.game_id }}</p>
|
<p>{{ game.title }} - {{ game.game_id }}</p>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
455
rpiWebApp.py
455
rpiWebApp.py
@ -1,47 +1,48 @@
|
|||||||
from flask import Flask
|
import base64
|
||||||
from flask import render_template, request, g, redirect, url_for, flash, current_app, Response
|
import datetime
|
||||||
from flask_login import LoginManager, current_user, login_user, logout_user, login_required
|
import inspect
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import threading
|
||||||
|
from urllib.parse import urljoin, urlsplit, urlunsplit
|
||||||
|
|
||||||
|
import inotify.adapters
|
||||||
|
import inotify.constants
|
||||||
|
import requests
|
||||||
|
from flask import Flask, Response, current_app, flash, g, redirect, render_template, request, url_for
|
||||||
|
from flask_login import LoginManager, current_user, login_required, login_user, logout_user
|
||||||
from oauthlib.oauth2 import WebApplicationClient
|
from oauthlib.oauth2 import WebApplicationClient
|
||||||
|
|
||||||
import threading
|
|
||||||
import logging
|
|
||||||
import inotify.adapters, inotify.constants
|
|
||||||
import inspect
|
|
||||||
import datetime
|
|
||||||
import requests
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
import base64
|
|
||||||
|
|
||||||
import scripts.func as func
|
import scripts.func as func
|
||||||
from scripts import database
|
|
||||||
from admin import admin
|
from admin import admin
|
||||||
from comics import comics
|
from comics import comics
|
||||||
from tv_movies import tv_movies
|
|
||||||
from games import games
|
from games import games
|
||||||
|
from scripts import database
|
||||||
|
from tv_movies import tv_movies
|
||||||
|
|
||||||
|
|
||||||
class NullHandler(logging.Handler):
|
class NullHandler(logging.Handler):
|
||||||
def emit(self, record=None):
|
def emit(self, record=None):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def debug(self, *arg):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def debug(self, *arg):
|
|
||||||
pass
|
|
||||||
nullLog = NullHandler()
|
nullLog = NullHandler()
|
||||||
inotify.adapters._LOGGER = nullLog
|
inotify.adapters._LOGGER = nullLog
|
||||||
|
|
||||||
|
|
||||||
GOOGLE_CLIENT_ID = "***REMOVED***"
|
GOOGLE_CLIENT_ID = "***REMOVED***"
|
||||||
GOOGLE_CLIENT_SECRET = "***REMOVED***"
|
GOOGLE_CLIENT_SECRET = "***REMOVED***"
|
||||||
GOOGLE_DISCOVERY_URL = (
|
GOOGLE_DISCOVERY_URL = "https://accounts.google.com/.well-known/openid-configuration"
|
||||||
"https://accounts.google.com/.well-known/openid-configuration"
|
|
||||||
)
|
|
||||||
client = WebApplicationClient(GOOGLE_CLIENT_ID)
|
client = WebApplicationClient(GOOGLE_CLIENT_ID)
|
||||||
|
|
||||||
|
|
||||||
def get_google_provider_cfg():
|
def get_google_provider_cfg():
|
||||||
return requests.get(GOOGLE_DISCOVERY_URL).json()
|
return requests.get(GOOGLE_DISCOVERY_URL).json()
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
@ -54,7 +55,7 @@ app.logger.setLevel("DEBUG")
|
|||||||
# app.use_x_sendfile = True
|
# app.use_x_sendfile = True
|
||||||
|
|
||||||
login_manager = LoginManager(app)
|
login_manager = LoginManager(app)
|
||||||
login_manager.login_view = "login"
|
# login_manager.login_view = "login"
|
||||||
app.config["REMEMBER_COOKIE_DOMAIN"] = "narnian.us"
|
app.config["REMEMBER_COOKIE_DOMAIN"] = "narnian.us"
|
||||||
|
|
||||||
|
|
||||||
@ -62,101 +63,135 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
|
|||||||
|
|
||||||
|
|
||||||
def get_comics():
|
def get_comics():
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
i = inotify.adapters.InotifyTree(func.COMICS_DIRECTORY)
|
i = inotify.adapters.InotifyTree(func.COMICS_DIRECTORY)
|
||||||
func.get_comics()
|
new_dirs = []
|
||||||
for event in i.event_gen(yield_nones=False):
|
func.get_comics()
|
||||||
(header, type_names, path, filename) = event
|
while True:
|
||||||
file_path = os.path.join(path, filename)
|
for event in i.event_gen(timeout_s=5*60, yield_nones=False):
|
||||||
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
(header, type_names, path, filename) = event
|
||||||
func.get_comic(file_path)
|
file_path = pathlib.Path(path, filename)
|
||||||
|
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
||||||
|
func.get_comic(file_path)
|
||||||
|
elif "IN_CREATE" in type_names:
|
||||||
|
if file_path.is_dir():
|
||||||
|
new_dirs.append(file_path)
|
||||||
|
for new_dir in new_dirs:
|
||||||
|
for file in new_dir.glob("*"):
|
||||||
|
func.get_comic(file)
|
||||||
|
new_dirs.clear()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_movies():
|
def get_movies():
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
i = inotify.adapters.InotifyTree(func.MOVIES_DIRECTORY)
|
i = inotify.adapters.InotifyTree(func.MOVIES_DIRECTORY)
|
||||||
func.get_movies()
|
|
||||||
for event in i.event_gen(yield_nones=False):
|
func.get_movies()
|
||||||
(header, type_names, path, filename) = event
|
|
||||||
file_path = os.path.join(path, filename)
|
for event in i.event_gen(yield_nones=False):
|
||||||
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
(header, type_names, path, filename) = event
|
||||||
func.get_movie(file_path)
|
file_path = pathlib.Path(path, filename)
|
||||||
|
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
||||||
|
func.get_movie(file_path)
|
||||||
|
|
||||||
|
|
||||||
def get_tv_shows():
|
def get_tv_shows():
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
|
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
|
||||||
func.get_tv_shows()
|
func.get_tv_shows()
|
||||||
func.get_tv_episodes()
|
func.get_tv_episodes()
|
||||||
for event in i.event_gen(yield_nones=False):
|
for event in i.event_gen(yield_nones=False):
|
||||||
(header, type_names, path, filename) = event
|
(header, type_names, path, filename) = event
|
||||||
file_path = os.path.join(path, filename)
|
file_path = pathlib.Path(path, filename)
|
||||||
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
||||||
func.get_tv_shows()
|
if file_path.is_dir():
|
||||||
func.get_tv_episode(file_path)
|
func.get_tv_shows()
|
||||||
|
else:
|
||||||
|
func.get_tv_episode(file_path)
|
||||||
|
|
||||||
|
|
||||||
def get_games():
|
def get_games():
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
func.get_games()
|
i = inotify.adapters.Inotify()
|
||||||
|
i.add_watch(func.GAMES_DIRECTORY)
|
||||||
|
for directory in os.listdir(func.GAMES_DIRECTORY):
|
||||||
|
path = pathlib.Path(func.GAMES_DIRECTORY, directory)
|
||||||
|
if path.is_dir():
|
||||||
|
i.add_watch(str(path))
|
||||||
|
|
||||||
|
func.get_games()
|
||||||
|
func.update_games()
|
||||||
|
|
||||||
|
for event in i.event_gen(yield_nones=False):
|
||||||
|
(header, type_names, path, filename) = event
|
||||||
|
file_path = pathlib.Path(path, filename)
|
||||||
|
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
|
||||||
|
func.get_game(file_path)
|
||||||
|
elif "IN_CREATE" in type_names:
|
||||||
|
if file_path.is_dir() and len(file_path.name) > 2:
|
||||||
|
i.add_watch(str(file_path))
|
||||||
|
elif "IN_DELETE_SELF" in type_names:
|
||||||
|
if file_path.is_dir():
|
||||||
|
i.remove_watch(file_path)
|
||||||
|
|
||||||
|
|
||||||
with app.app_context():
|
with app.app_context():
|
||||||
current_app.logger.info("server start")
|
current_app.logger.info("server start")
|
||||||
thread = threading.Thread(target=get_comics, args=())
|
thread = threading.Thread(target=get_comics, args=())
|
||||||
thread.daemon = True
|
thread.daemon = True
|
||||||
thread.start()
|
thread.start()
|
||||||
thread2 = threading.Thread(target=get_movies, args=())
|
thread2 = threading.Thread(target=get_movies, args=())
|
||||||
thread2.daemon = True
|
thread2.daemon = True
|
||||||
thread2.start()
|
thread2.start()
|
||||||
thread3 = threading.Thread(target=get_tv_shows, args=())
|
thread3 = threading.Thread(target=get_tv_shows, args=())
|
||||||
thread3.daemon = True
|
thread3.daemon = True
|
||||||
thread3.start()
|
thread3.start()
|
||||||
thread4 = threading.Thread(target=get_games, args=())
|
thread4 = threading.Thread(target=get_games, args=())
|
||||||
thread4.daemon = True
|
thread4.daemon = True
|
||||||
thread4.start()
|
thread4.start()
|
||||||
|
|
||||||
|
|
||||||
@app.teardown_appcontext
|
@app.teardown_appcontext
|
||||||
def close_connection(exception):
|
def close_connection(exception):
|
||||||
db = getattr(g, '_database', None)
|
db = getattr(g, "_database", None)
|
||||||
if db is not None:
|
if db is not None:
|
||||||
db.close()
|
db.close()
|
||||||
|
|
||||||
|
|
||||||
def update_comic_db(sender, **kw):
|
def update_comic_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_comics(kw["meta"], kw["thumbnails"])
|
database.add_comics(kw["meta"], kw["thumbnails"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def update_movie_db(sender, **kw):
|
def update_movie_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_movies(kw["movies"])
|
database.add_movies(kw["movies"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def update_tv_show_db(sender, **kw):
|
def update_tv_show_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_tv_shows(kw["tv_show"])
|
database.add_tv_shows(kw["tv_show"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def update_tv_episodes_db(sender, **kw):
|
def update_tv_episodes_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_tv_episodes(kw["tv_episodes"])
|
database.add_tv_episodes(kw["tv_episodes"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def update_games_db(sender, **kw):
|
def update_games_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_games(kw["games"])
|
database.add_games(kw["games"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
func.comic_loaded.connect(update_comic_db)
|
func.comic_loaded.connect(update_comic_db)
|
||||||
@ -168,177 +203,183 @@ func.games_loaded.connect(update_games_db)
|
|||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(email):
|
def load_user(email):
|
||||||
try:
|
try:
|
||||||
return database.get_user(email)
|
return database.get_user(email)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
return str(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
@login_manager.request_loader
|
@login_manager.request_loader
|
||||||
def load_user_from_request(request):
|
def load_user_from_request(request):
|
||||||
try:
|
try:
|
||||||
api_key = request.headers.get('Authorization')
|
api_key = request.headers.get("Authorization")
|
||||||
if api_key:
|
if api_key:
|
||||||
api_key = api_key.replace('Basic ', '', 1)
|
api_key = api_key.replace("Basic ", "", 1)
|
||||||
try:
|
try:
|
||||||
api_key = base64.b64decode(api_key).decode("utf-8")
|
api_key = base64.b64decode(api_key).decode("utf-8")
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
email = api_key.split(":")[0]
|
email = api_key.split(":")[0]
|
||||||
password = api_key.split(":")[1]
|
password = api_key.split(":")[1]
|
||||||
user = load_user(email)
|
user = load_user(email)
|
||||||
if user and user.check_password(password):
|
if user and user.check_password(password):
|
||||||
return user
|
return user
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
return str(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
try:
|
try:
|
||||||
google_provider_cfg = get_google_provider_cfg()
|
url = urlsplit(request.url)
|
||||||
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
|
google_redirect = urlunsplit(("", "", url.path, url.query, ""))
|
||||||
|
next_page = google_redirect
|
||||||
|
if "login" in url.path:
|
||||||
|
next_page = url_for("home")
|
||||||
|
if request.args.get("url", default=None):
|
||||||
|
next_page = request.args.get("url", default=None)
|
||||||
|
|
||||||
request_uri = client.prepare_request_uri(
|
google_provider_cfg = get_google_provider_cfg()
|
||||||
authorization_endpoint,
|
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
|
||||||
redirect_uri=request.base_url + "/callback",
|
|
||||||
scope=["openid", "email", "profile"],
|
|
||||||
)
|
|
||||||
|
|
||||||
if request.method == "POST":
|
request_uri = client.prepare_request_uri(
|
||||||
email = request.form.get("email")
|
authorization_endpoint,
|
||||||
password = request.form.get("password")
|
redirect_uri=urljoin(request.host_url, url_for("callback")),
|
||||||
user = database.get_user(email)
|
scope=["openid", "email", "profile"],
|
||||||
if user is None or not user.check_password(password):
|
state=next_page,
|
||||||
flash("invalid email or password")
|
hd="narnian.us",
|
||||||
return redirect(url_for("login"))
|
)
|
||||||
login_user(user, remember=True, duration=datetime.timedelta(days=7))
|
|
||||||
next_page = request.args.get("next")
|
if request.method == "POST":
|
||||||
if not next_page:
|
email = request.form.get("email")
|
||||||
next_page = url_for("home")
|
password = request.form.get("password")
|
||||||
return redirect(next_page)
|
user = database.get_user(email)
|
||||||
return render_template("login.html", title="login", auth_url=request_uri)
|
if user is None or not user.check_password(password):
|
||||||
except Exception as e:
|
flash("invalid email or password")
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
return redirect(url_for("login"))
|
||||||
return str(e)
|
login_user(user, remember=True, duration=datetime.timedelta(days=7))
|
||||||
|
return redirect(next_page)
|
||||||
|
return render_template("login.html", title="login", auth_url=request_uri)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/login/callback")
|
@app.route("/login/callback")
|
||||||
def callback():
|
def callback():
|
||||||
try:
|
try:
|
||||||
# Get authorization code Google sent back to you
|
# Get authorization code Google sent back to you
|
||||||
code = request.args.get("code")
|
code = request.args.get("code")
|
||||||
|
|
||||||
google_provider_cfg = get_google_provider_cfg()
|
google_provider_cfg = get_google_provider_cfg()
|
||||||
token_endpoint = google_provider_cfg["token_endpoint"]
|
token_endpoint = google_provider_cfg["token_endpoint"]
|
||||||
|
|
||||||
token_url, headers, body = client.prepare_token_request(
|
token_url, headers, body = client.prepare_token_request(
|
||||||
token_endpoint,
|
token_endpoint, authorization_response=request.url, redirect_url=request.base_url, code=code
|
||||||
authorization_response=request.url,
|
)
|
||||||
redirect_url=request.base_url,
|
token_response = requests.post(token_url, headers=headers, data=body, auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET))
|
||||||
code=code
|
|
||||||
)
|
|
||||||
token_response = requests.post(
|
|
||||||
token_url,
|
|
||||||
headers=headers,
|
|
||||||
data=body,
|
|
||||||
auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
|
|
||||||
)
|
|
||||||
|
|
||||||
client.parse_request_body_response(json.dumps(token_response.json()))
|
client.parse_request_body_response(json.dumps(token_response.json()))
|
||||||
|
|
||||||
userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
|
userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
|
||||||
uri, headers, body = client.add_token(userinfo_endpoint)
|
uri, headers, body = client.add_token(userinfo_endpoint)
|
||||||
userinfo_response = requests.get(uri, headers=headers, data=body)
|
userinfo_response = requests.get(uri, headers=headers, data=body)
|
||||||
|
|
||||||
if userinfo_response.json().get("email_verified"):
|
if userinfo_response.json().get("email_verified"):
|
||||||
unique_id = userinfo_response.json()["sub"]
|
unique_id = userinfo_response.json()["sub"]
|
||||||
users_email = userinfo_response.json()["email"]
|
users_email = userinfo_response.json()["email"]
|
||||||
users_name = userinfo_response.json()["given_name"]
|
users_name = userinfo_response.json()["given_name"]
|
||||||
else:
|
else:
|
||||||
return "User email not available or not verified by Google.", 400
|
return "User email not available or not verified by Google.", 400
|
||||||
|
|
||||||
data = (unique_id, users_name, users_email, None, False)
|
data = (unique_id, users_name, users_email, None, False)
|
||||||
|
|
||||||
current_app.logger.info("user data from google: " + str(data))
|
current_app.logger.info("user data from google: " + str(data))
|
||||||
user = database.get_user(users_email)
|
user = database.get_user(users_email)
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
user = database.add_user(data)
|
user = database.add_user(data)
|
||||||
current_app.logger.info("new user: {} created".format(users_email))
|
current_app.logger.info("new user: {} created".format(users_email))
|
||||||
|
|
||||||
current_app.logger.info("email: "+str(user.email))
|
current_app.logger.info("email: " + str(user.email))
|
||||||
current_app.logger.info("username: "+str(user.username))
|
current_app.logger.info("username: " + str(user.username))
|
||||||
current_app.logger.info("authenticated: "+str(user.is_authenticated))
|
current_app.logger.info("authenticated: " + str(user.is_authenticated))
|
||||||
current_app.logger.info("active: "+str(user.is_active))
|
current_app.logger.info("active: " + str(user.is_active))
|
||||||
current_app.logger.info("id: "+str(user.get_id()))
|
current_app.logger.info("id: " + str(user.get_id()))
|
||||||
login_user(user, remember=True, duration=datetime.timedelta(days=7), force=True)
|
login_user(user, remember=True, duration=datetime.timedelta(days=7), force=True)
|
||||||
|
|
||||||
return redirect(url_for("home"))
|
return redirect(request.args.get("state"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/logout")
|
@app.route("/logout")
|
||||||
def logout():
|
def logout():
|
||||||
try:
|
try:
|
||||||
logout_user()
|
logout_user()
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def root():
|
def root():
|
||||||
return redirect(url_for("home"))
|
return redirect(url_for("home"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/home")
|
@app.route("/home")
|
||||||
@login_required
|
@login_required
|
||||||
def home():
|
def home():
|
||||||
try:
|
try:
|
||||||
return render_template("home.html", title="Home", current_user=current_user)
|
return render_template("home.html", title="Home", current_user=current_user)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.after_request
|
@app.after_request
|
||||||
def apply_headers(response: Response):
|
def apply_headers(response: Response):
|
||||||
try:
|
try:
|
||||||
user_name = "anonymous"
|
user_name = "anonymous"
|
||||||
if current_user:
|
if current_user:
|
||||||
user_name = getattr(current_user, "email", "anonymous")
|
user_name = getattr(current_user, "email", "anonymous")
|
||||||
response.set_cookie("rpi_name", user_name)
|
response.set_cookie("rpi_name", user_name)
|
||||||
return response
|
response.headers.set("email", user_name)
|
||||||
except Exception as e:
|
return response
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
except Exception as e:
|
||||||
return str(e)
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/music")
|
@app.route("/music")
|
||||||
@login_required
|
@login_required
|
||||||
def music():
|
def music():
|
||||||
return "No music"
|
return "No music"
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.errorhandler(404)
|
||||||
def resource_not_found(e):
|
def resource_not_found(e):
|
||||||
try:
|
try:
|
||||||
return render_template("404.html"), 404
|
return render_template("404.html"), 404
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(e)
|
return str(e)
|
||||||
|
|
||||||
|
|
||||||
|
@login_manager.unauthorized_handler
|
||||||
|
def handle_unauthorized():
|
||||||
|
temp = login()
|
||||||
|
return temp, 401
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(Exception)
|
@app.errorhandler(Exception)
|
||||||
def handle_exception(e):
|
def handle_exception(e):
|
||||||
return render_template("error.html", e=e), 500
|
return render_template("error.html", e=e), 500
|
||||||
|
|
||||||
|
|
||||||
games.Games.register_error_handler(404, resource_not_found)
|
games.Games.register_error_handler(404, resource_not_found)
|
||||||
@ -351,5 +392,5 @@ comics.Comics.register_error_handler(Exception, handle_exception)
|
|||||||
admin.Admin.register_error_handler(Exception, handle_exception)
|
admin.Admin.register_error_handler(Exception, handle_exception)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == "__main__":
|
||||||
app.run()
|
app.run()
|
||||||
|
1367
scripts/database.py
1367
scripts/database.py
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,8 @@
|
|||||||
|
import os
|
||||||
|
import sqlite3
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from wand.image import Image
|
|
||||||
import sqlite3, os
|
|
||||||
|
|
||||||
|
from wand.image import Image
|
||||||
|
|
||||||
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
|
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
|
||||||
|
|
||||||
@ -15,32 +16,35 @@ db.row_factory = sqlite3.Row
|
|||||||
|
|
||||||
|
|
||||||
def resize_image(image, new_width=256, new_height=256):
|
def resize_image(image, new_width=256, new_height=256):
|
||||||
new_image = image
|
new_image = image
|
||||||
orig_height = new_image.height
|
orig_height = new_image.height
|
||||||
orig_width = new_image.width
|
orig_width = new_image.width
|
||||||
if orig_height >= orig_width:
|
if orig_height >= orig_width:
|
||||||
width = int((orig_width/orig_height) * new_height)
|
width = int((orig_width / orig_height) * new_height)
|
||||||
height = new_height
|
height = new_height
|
||||||
else:
|
else:
|
||||||
height = int((orig_height/orig_width) * new_width)
|
height = int((orig_height / orig_width) * new_width)
|
||||||
width = new_width
|
width = new_width
|
||||||
new_image.thumbnail(width, height)
|
new_image.thumbnail(width, height)
|
||||||
return new_image
|
return new_image
|
||||||
|
|
||||||
|
|
||||||
def fix_thumbnails():
|
def fix_thumbnails():
|
||||||
new_height = 256
|
new_height = 256
|
||||||
new_width = 256
|
new_width = 256
|
||||||
print("Start fix thumbnail size")
|
print("Start fix thumbnail size")
|
||||||
rows = db.execute("SELECT * FROM comic_thumbnails")
|
rows = db.execute("SELECT * FROM comic_thumbnails")
|
||||||
print("got list of all thumbnails\n")
|
print("got list of all thumbnails\n")
|
||||||
|
|
||||||
for row in rows:
|
for row in rows:
|
||||||
image = Image(file=BytesIO(row["image"]))
|
image = Image(file=BytesIO(row["image"]))
|
||||||
if image.width > new_width or image.height > new_height:
|
if image.width > new_width or image.height > new_height:
|
||||||
print("id:", row["id"], "pageNumber:", row["pageNumber"])
|
print("id:", row["id"], "pageNumber:", row["pageNumber"])
|
||||||
db.execute("UPDATE comic_thumbnails SET image=? WHERE id=? AND pageNumber=?", [resize_image(image, new_width, new_height).make_blob(), row["id"], row["pageNumber"]])
|
db.execute(
|
||||||
db.commit()
|
"UPDATE comic_thumbnails SET image=? WHERE id=? AND pageNumber=?",
|
||||||
|
[resize_image(image, new_width, new_height).make_blob(), row["id"], row["pageNumber"]],
|
||||||
|
)
|
||||||
|
db.commit()
|
||||||
|
|
||||||
|
|
||||||
fix_thumbnails()
|
fix_thumbnails()
|
||||||
|
935
scripts/func.py
935
scripts/func.py
@ -1,15 +1,17 @@
|
|||||||
from flask import current_app
|
|
||||||
from comicapi import comicarchive
|
|
||||||
from blinker import Namespace
|
|
||||||
from datetime import timedelta
|
|
||||||
|
|
||||||
from io import BytesIO
|
|
||||||
from wand.image import Image
|
|
||||||
import os, re
|
|
||||||
import inspect
|
import inspect
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
|
import pathlib
|
||||||
|
import re
|
||||||
|
from datetime import timedelta
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
import enzyme
|
import enzyme
|
||||||
import requests
|
import requests
|
||||||
|
from blinker import Namespace
|
||||||
|
from comicapi import comicarchive
|
||||||
|
from flask import current_app
|
||||||
|
from wand.image import Image
|
||||||
|
|
||||||
from scripts import database
|
from scripts import database
|
||||||
|
|
||||||
@ -22,6 +24,8 @@ games_loaded = rpi_signals.signal("games_loaded")
|
|||||||
|
|
||||||
publishers_to_ignore = ["***REMOVED***"]
|
publishers_to_ignore = ["***REMOVED***"]
|
||||||
|
|
||||||
|
API_KEY = "***REMOVED***"
|
||||||
|
|
||||||
# Directories
|
# Directories
|
||||||
|
|
||||||
RPI_COMICS_DIRECTORY = "/usb/storage/media/Comics/"
|
RPI_COMICS_DIRECTORY = "/usb/storage/media/Comics/"
|
||||||
@ -45,434 +49,555 @@ GAMES_DIRECTORY = RPI_GAMES_DIRECTORY if os.path.exists(RPI_GAMES_DIRECTORY) els
|
|||||||
|
|
||||||
|
|
||||||
def get_comics():
|
def get_comics():
|
||||||
total_comics = 0
|
total_comics = 0
|
||||||
comics_in_db = 0
|
comics_in_db = 0
|
||||||
comics_added = 0
|
comics_added = 0
|
||||||
meta = []
|
meta = []
|
||||||
thumbnails = []
|
thumbnails = []
|
||||||
i = 0
|
i = 0
|
||||||
for root, dirs, files in os.walk(COMICS_DIRECTORY):
|
for root, dirs, files in os.walk(COMICS_DIRECTORY):
|
||||||
for f in files:
|
for f in files:
|
||||||
if "temp" in root:
|
if "temp" in root:
|
||||||
continue
|
continue
|
||||||
if f.endswith(".cbr"):
|
if f.endswith(".cbr"):
|
||||||
total_comics += 1
|
total_comics += 1
|
||||||
path = os.path.join(root, f)
|
path = os.path.join(root, f)
|
||||||
if not database.comic_path_in_db(path):
|
if not database.comic_path_in_db(path):
|
||||||
try:
|
try:
|
||||||
test_path = path.encode("utf8")
|
test_path = path.encode("utf8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info("encoding failed on: "+path)
|
current_app.logger.info("encoding failed on: " + path)
|
||||||
continue
|
continue
|
||||||
archive = open_comic(path)
|
archive = open_comic(path)
|
||||||
md = archive.readCIX()
|
md = archive.readCIX()
|
||||||
if md.publisher in publishers_to_ignore:
|
if md.publisher in publishers_to_ignore:
|
||||||
continue
|
continue
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
try:
|
try:
|
||||||
meta.append((path, md))
|
meta.append((path, md))
|
||||||
thumbnails.append(get_comic_thumbnails(archive))
|
thumbnails.append(get_comic_thumbnails(archive))
|
||||||
comics_added += 1
|
comics_added += 1
|
||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
continue
|
continue
|
||||||
if i >= 2:
|
if i >= 2:
|
||||||
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
|
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
|
||||||
meta.clear()
|
meta.clear()
|
||||||
thumbnails.clear()
|
thumbnails.clear()
|
||||||
i = 0
|
i = 0
|
||||||
comics_in_db += 1
|
comics_in_db += 1
|
||||||
current_app.logger.info("total number of comics: "+str(total_comics))
|
current_app.logger.info("total number of comics: " + str(total_comics))
|
||||||
current_app.logger.info("comics in database: "+str(comics_in_db))
|
current_app.logger.info("comics in database: " + str(comics_in_db))
|
||||||
current_app.logger.info("number of comics added: "+str(comics_added))
|
current_app.logger.info("number of comics added: " + str(comics_added))
|
||||||
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
||||||
|
|
||||||
|
|
||||||
def get_comic(path):
|
def get_comic(path: pathlib.Path):
|
||||||
meta = []
|
meta = []
|
||||||
thumbnails = []
|
thumbnails = []
|
||||||
if path.endswith(".cbr"):
|
if path.suffix == ".cbr":
|
||||||
if not database.comic_path_in_db(path):
|
if not database.comic_path_in_db(str(path)):
|
||||||
try:
|
try:
|
||||||
test_path = path.encode("utf8")
|
test_path = str(path).encode("utf8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info("encoding failed on: "+path)
|
current_app.logger.info(f"encoding failed on: {path}")
|
||||||
return
|
return
|
||||||
archive = open_comic(path)
|
archive = open_comic(str(path))
|
||||||
md = archive.readCIX()
|
md = archive.readCIX()
|
||||||
if md.publisher in publishers_to_ignore:
|
if md.publisher in publishers_to_ignore:
|
||||||
return
|
return
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
meta.append((path, md))
|
meta.append((str(path), md))
|
||||||
try:
|
try:
|
||||||
thumbnails.append(get_comic_thumbnails(archive))
|
thumbnails.append(get_comic_thumbnails(archive))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return
|
return
|
||||||
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
||||||
|
|
||||||
|
|
||||||
def get_comic_thumbnails(comic):
|
def get_comic_thumbnails(comic):
|
||||||
thumbnails = []
|
thumbnails = []
|
||||||
size = "256x256"
|
size = "256x256"
|
||||||
new_height = 256
|
new_height = 256
|
||||||
new_width = 256
|
new_width = 256
|
||||||
for page in range(comic.getNumberOfPages()):
|
for page in range(comic.getNumberOfPages()):
|
||||||
image_bytes = BytesIO(comic.getPage(page))
|
image_bytes = BytesIO(comic.getPage(page))
|
||||||
image = Image(file=image_bytes)
|
image = Image(file=image_bytes)
|
||||||
orig_height = image.height
|
orig_height = image.height
|
||||||
orig_width = image.width
|
orig_width = image.width
|
||||||
if orig_height >= orig_width:
|
if orig_height >= orig_width:
|
||||||
width = int((orig_width/orig_height) * new_height)
|
width = int((orig_width / orig_height) * new_height)
|
||||||
height = new_height
|
height = new_height
|
||||||
else:
|
else:
|
||||||
height = int((orig_height/orig_width) * new_width)
|
height = int((orig_height / orig_width) * new_width)
|
||||||
width = new_width
|
width = new_width
|
||||||
image.thumbnail(width, height)
|
image.thumbnail(width, height)
|
||||||
thumbnails.append((image.make_blob(), "image/"+image.format))
|
thumbnails.append((image.make_blob(), "image/" + image.format))
|
||||||
return thumbnails
|
return thumbnails
|
||||||
|
|
||||||
|
|
||||||
def open_comic(path):
|
def open_comic(path):
|
||||||
archive = comicarchive.ComicArchive(path, default_image_path="static/images/icon.png")
|
archive = comicarchive.ComicArchive(path, default_image_path="static/images/icon.png")
|
||||||
return archive
|
return archive
|
||||||
|
|
||||||
|
|
||||||
def get_movies():
|
def get_movies():
|
||||||
current_app.logger.info("start load movies")
|
current_app.logger.info("start loading movies")
|
||||||
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
|
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
|
||||||
movies = []
|
url = "https://api.themoviedb.org/3/search/movie"
|
||||||
total_movies = 0
|
movies = []
|
||||||
movies_in_db = 0
|
total_movies = 0
|
||||||
movies_added = 0
|
movies_in_db = 0
|
||||||
for root, dirs, files in os.walk(MOVIES_DIRECTORY):
|
movies_added = 0
|
||||||
for f in files:
|
for root, dirs, files in os.walk(MOVIES_DIRECTORY):
|
||||||
if f.endswith(".mkv"):
|
for f in files:
|
||||||
total_movies += 1
|
if f.endswith(".mkv"):
|
||||||
path = os.path.join(root, f)
|
total_movies += 1
|
||||||
if not database.movie_path_in_db(path):
|
path = os.path.join(root, f)
|
||||||
try:
|
if not database.movie_path_in_db(path):
|
||||||
match = re.match(pattern, f)
|
try:
|
||||||
if not match:
|
match = re.match(pattern, f)
|
||||||
current_app.logger.info(f+" did not match regex.")
|
if not match:
|
||||||
continue
|
current_app.logger.info(f + " did not match regex.")
|
||||||
current_app.logger.info("movie path: "+path)
|
continue
|
||||||
title = match.group("title")
|
current_app.logger.info("movie path: " + path)
|
||||||
current_app.logger.info("movie title: "+title)
|
title = match.group("title")
|
||||||
year = int(match.group("year"))
|
current_app.logger.info("movie title: " + title)
|
||||||
extended = False
|
year = int(match.group("year"))
|
||||||
directors_cut = False
|
extended = True if match.group("extended") else False
|
||||||
if match.group("extended"):
|
directors_cut = True if match.group("directors_cut") else False
|
||||||
extended = True
|
|
||||||
imdb_data = database.imdb_get_movie(title.replace(match.group("extended"), ""), year)
|
|
||||||
elif match.group("directors_cut"):
|
|
||||||
imdb_data = database.imdb_get_movie(title.replace(match.group("directors_cut"), ""), year)
|
|
||||||
directors_cut = True
|
|
||||||
else:
|
|
||||||
imdb_data = database.imdb_get_movie(title, year)
|
|
||||||
if not imdb_data:
|
|
||||||
current_app.logger.info("could not get imdb data for: "+title+" "+str(year))
|
|
||||||
continue
|
|
||||||
imdb_id = imdb_data["tconst"]
|
|
||||||
length = imdb_data["runtimeMinutes"]
|
|
||||||
|
|
||||||
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
|
data = {
|
||||||
if not tmdb_data:
|
"api_key": API_KEY,
|
||||||
current_app.logger.info("could not get tmdb data")
|
"query": title,
|
||||||
continue
|
"primary_release_year": year,
|
||||||
tmdb_id = tmdb_data[0]
|
"language": "en-US",
|
||||||
description = tmdb_data[1]
|
}
|
||||||
poster_path = tmdb_data[2]
|
r = requests.get(url, params=data)
|
||||||
backdrop_path = tmdb_data[3]
|
if len(r.json()["results"]) == 0:
|
||||||
movies_added += 1
|
data = {
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"query": title,
|
||||||
|
"year": year,
|
||||||
|
"language": "en-US",
|
||||||
|
}
|
||||||
|
r = requests.get(url, params=data)
|
||||||
|
if len(r.json()["results"]) == 0:
|
||||||
|
current_app.logger.info(f"no movie results for {title} - ({year})")
|
||||||
|
continue
|
||||||
|
info = r.json()["results"][0]
|
||||||
|
|
||||||
movies.append((path, imdb_id, tmdb_id, title, year, length, description, extended, directors_cut, poster_path, backdrop_path))
|
tmdb_id = info["id"]
|
||||||
if len(movies) >= 20:
|
description = info["overview"]
|
||||||
movie_loaded.send("anonymous", movies=movies.copy())
|
poster_path = info["poster_path"]
|
||||||
movies.clear()
|
backdrop_path = info["backdrop_path"]
|
||||||
except Exception as e:
|
movies_added += 1
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
|
||||||
# print(e)
|
movies.append((path, tmdb_id, title, year, description, extended, directors_cut, poster_path, backdrop_path,))
|
||||||
movies_in_db += 1
|
if len(movies) >= 20:
|
||||||
movie_loaded.send("anonymous", movies=movies)
|
movie_loaded.send("anonymous", movies=movies.copy())
|
||||||
current_app.logger.info("finish load movies")
|
movies.clear()
|
||||||
current_app.logger.info("total movies: "+str(total_movies))
|
except Exception as e:
|
||||||
current_app.logger.info("movies in database: "+str(movies_in_db))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
current_app.logger.info("movies added: "+str(movies_added))
|
# print(e)
|
||||||
|
movies_in_db += 1
|
||||||
|
movie_loaded.send("anonymous", movies=movies)
|
||||||
|
current_app.logger.info("finish loading movies")
|
||||||
|
current_app.logger.info("total movies: " + str(total_movies))
|
||||||
|
current_app.logger.info("movies in database: " + str(movies_in_db))
|
||||||
|
current_app.logger.info("movies added: " + str(movies_added))
|
||||||
|
|
||||||
|
|
||||||
def get_movie(path):
|
def get_movie(path: pathlib.Path):
|
||||||
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
|
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
|
||||||
movies = []
|
url = "https://api.themoviedb.org/3/search/movie"
|
||||||
if not database.movie_path_in_db(path):
|
movies = []
|
||||||
try:
|
if not database.movie_path_in_db(str(path)):
|
||||||
match = re.match(pattern, path)
|
try:
|
||||||
if not match:
|
match = re.match(pattern, path.name)
|
||||||
current_app.logger.info(path + " did not match regex.")
|
if not match:
|
||||||
return
|
current_app.logger.info(f"{path.name} did not match regex.")
|
||||||
current_app.logger.info("movie path: " + path)
|
return
|
||||||
title = match.group("title")
|
current_app.logger.info(f"movie path: {path}")
|
||||||
current_app.logger.info("movie title: " + title)
|
title = match.group("title")
|
||||||
year = int(match.group("year"))
|
current_app.logger.info("movie title: " + title)
|
||||||
extended = False
|
year = int(match.group("year"))
|
||||||
directors_cut = False
|
extended = match.group("extended") is True
|
||||||
if match.group("extended"):
|
directors_cut = match.group("directors_cut") is True
|
||||||
extended = True
|
|
||||||
imdb_data = database.imdb_get_movie(title.replace(match.group("extended"), ""), year)
|
|
||||||
elif match.group("directors_cut"):
|
|
||||||
imdb_data = database.imdb_get_movie(title.replace(match.group("directors_cut"), ""), year)
|
|
||||||
directors_cut = True
|
|
||||||
else:
|
|
||||||
imdb_data = database.imdb_get_movie(title, year)
|
|
||||||
if not imdb_data:
|
|
||||||
current_app.logger.info("could not get imdb data for: " + title + " " + str(year))
|
|
||||||
return
|
|
||||||
imdb_id = imdb_data["tconst"]
|
|
||||||
length = imdb_data["runtimeMinutes"]
|
|
||||||
|
|
||||||
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
|
data = {
|
||||||
if not tmdb_data:
|
"api_key": API_KEY,
|
||||||
current_app.logger.info("could not get tmdb data")
|
"query": title,
|
||||||
return
|
"primary_release_year": year,
|
||||||
tmdb_id = tmdb_data[0]
|
"language": "en-US",
|
||||||
description = tmdb_data[1]
|
}
|
||||||
poster_path = tmdb_data[2]
|
r = requests.get(url, params=data)
|
||||||
backdrop_path = tmdb_data[3]
|
if len(r.json()["results"]) == 0:
|
||||||
|
data = {
|
||||||
|
"api_key": API_KEY,
|
||||||
|
"query": title,
|
||||||
|
"year": year,
|
||||||
|
"language": "en-US",
|
||||||
|
}
|
||||||
|
r = requests.get(url, params=data)
|
||||||
|
info = r.json()["results"][0]
|
||||||
|
if len(r.json()["results"]) == 0:
|
||||||
|
current_app.logger.info(f"no movie results for {title} - ({year})")
|
||||||
|
return
|
||||||
|
|
||||||
movies.append((path, imdb_id, tmdb_id, title, year, length, description, extended, directors_cut,
|
tmdb_id = info["id"]
|
||||||
poster_path, backdrop_path))
|
description = info["overview"]
|
||||||
movie_loaded.send("anonymous", movies=movies.copy())
|
poster_path = info["poster_path"]
|
||||||
movies.clear()
|
backdrop_path = info["backdrop_path"]
|
||||||
current_app.logger.info("finish load movie")
|
|
||||||
except Exception as e:
|
movies.append((str(path), tmdb_id, title, year, description, extended, directors_cut, poster_path, backdrop_path,))
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
movie_loaded.send("anonymous", movies=movies.copy())
|
||||||
|
movies.clear()
|
||||||
|
current_app.logger.info("finish loading movie")
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def get_tv_shows():
|
def get_tv_shows():
|
||||||
dir_pattern = r"(?P<title>.+) \((?P<year>\d+)\)"
|
dir_pattern = r"(?P<title>.+) \((?P<year>\d+)\)"
|
||||||
for dir in sorted(os.listdir(TV_SHOWS_DIRECTORY)):
|
search_url = "https://api.themoviedb.org/3/search/tv"
|
||||||
dir_match = re.match(dir_pattern, dir)
|
tv_url = "https://api.themoviedb.org/3/tv/"
|
||||||
if dir_match:
|
current_app.logger.info("start loading tv shows")
|
||||||
path = TV_SHOWS_DIRECTORY+dir
|
for dir in sorted(os.listdir(TV_SHOWS_DIRECTORY)):
|
||||||
if not database.tv_show_path_in_db(path):
|
dir_match = re.match(dir_pattern, dir)
|
||||||
info = {}
|
if dir_match:
|
||||||
if os.path.exists(path+"/info.json"):
|
path = TV_SHOWS_DIRECTORY + dir
|
||||||
with open(path+"/info.json") as f:
|
if not database.tv_show_path_in_db(path):
|
||||||
info = json.load(f)
|
json_info = {}
|
||||||
series_name = dir_match.group("title")
|
if os.path.exists(path + "/info.json"):
|
||||||
series_year = int(dir_match.group("year"))
|
with open(path + "/info.json") as f:
|
||||||
imdb_data = database.imdb_get_tv_show(series_name, series_year, info)
|
json_info = json.load(f)
|
||||||
if not imdb_data:
|
series_name = dir_match.group("title")
|
||||||
current_app.logger.info("could not get imdb data for:"+series_name+" "+str(series_year))
|
series_year = int(dir_match.group("year"))
|
||||||
# print("could not get imdb data for:", series_name, series_year)
|
|
||||||
continue
|
if not json_info:
|
||||||
imdb_id = imdb_data["tconst"]
|
data = {
|
||||||
tmdb_data = database.tmdb_get_tv_show_by_imdb_id(imdb_id)
|
"api_key": API_KEY,
|
||||||
if not tmdb_data:
|
"query": series_name,
|
||||||
current_app.logger.info("could not get tmdb data for:" + series_name + " " + str(series_year))
|
"first_air_date_year": series_year,
|
||||||
# print("could not get tmdb data for:", series_name, series_year)
|
"language": "en-US",
|
||||||
with open("/var/lib/rpiWebApp/log.txt", "a") as f:
|
}
|
||||||
f.write("could not get tmdb data for: " + imdb_id + " " + series_name + " " + str(series_year)+"\n")
|
r = requests.get(search_url, params=data)
|
||||||
continue
|
if len(r.json()["results"]) == 0:
|
||||||
tmdb_id = tmdb_data[0]
|
current_app.logger.info(f"no tv show results for {series_name} - ({series_year})")
|
||||||
description = tmdb_data[1]
|
continue
|
||||||
poster_path = tmdb_data[2]
|
info = r.json()["results"][0]
|
||||||
tv_show_data = (imdb_id, tmdb_id, series_name, series_year, description, poster_path, path)
|
else:
|
||||||
tv_show_loaded.send("anonymous", tv_show=tv_show_data)
|
data = {"api_key": API_KEY, "language": "en-US"}
|
||||||
current_app.logger.info("finished load tv shows.")
|
r = requests.get(tv_url + str(json_info["tmdb_id"]), params=data)
|
||||||
|
if "status_code" in r.json().keys():
|
||||||
|
current_app.logger.info(f"no tv show results for {series_name} - ({series_year})")
|
||||||
|
continue
|
||||||
|
info = r.json()
|
||||||
|
|
||||||
|
tmdb_id = info["id"]
|
||||||
|
description = info["overview"]
|
||||||
|
poster_path = info["poster_path"]
|
||||||
|
tv_show_data = (
|
||||||
|
tmdb_id,
|
||||||
|
series_name,
|
||||||
|
series_year,
|
||||||
|
description,
|
||||||
|
poster_path,
|
||||||
|
path,
|
||||||
|
)
|
||||||
|
tv_show_loaded.send("anonymous", tv_show=tv_show_data)
|
||||||
|
current_app.logger.info("finished loading tv shows.")
|
||||||
|
|
||||||
|
|
||||||
def get_tv_episodes():
|
def get_tv_episodes():
|
||||||
try:
|
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mkv)"
|
||||||
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mp4|.mkv)"
|
rows = database.get_all_tv_shows()
|
||||||
rows = database.get_all_tv_shows()
|
current_app.logger.info("start loading tv episodes")
|
||||||
for tv_show in rows:
|
for tv_show in rows:
|
||||||
episodes = []
|
try:
|
||||||
for video in sorted(os.listdir(tv_show.path)):
|
episodes = []
|
||||||
video_match = re.match(video_pattern, video)
|
for video in sorted(os.listdir(tv_show.path)):
|
||||||
if video_match:
|
video_match = re.match(video_pattern, video)
|
||||||
path = os.path.join(tv_show.path, video)
|
if video_match:
|
||||||
if not database.tv_episode_path_in_db(path):
|
path = os.path.join(tv_show.path, video)
|
||||||
season = int(video_match.group("season"))
|
if not database.tv_episode_path_in_db(path):
|
||||||
episode = int(video_match.group("episode"))
|
season = int(video_match.group("season"))
|
||||||
episode_name = video_match.group("title")
|
episode = int(video_match.group("episode"))
|
||||||
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
|
episode_name = video_match.group("title")
|
||||||
if not episode_imdb_data:
|
current_app.logger.info(f"S{season} E{episode} - {tv_show.title}: {episode_name}")
|
||||||
current_app.logger.info("could not get imdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
|
url = f"https://api.themoviedb.org/3/tv/{tv_show.tmdb_id}/season/{season}/episode/{episode}"
|
||||||
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
|
|
||||||
continue
|
data = {"api_key": API_KEY, "language": "en-US"}
|
||||||
episode_imdb_id = episode_imdb_data["tconst"]
|
r = requests.get(url, params=data)
|
||||||
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
|
if "status_code" in r.json().keys():
|
||||||
if not episode_tmdb_data:
|
current_app.logger.info(f"no tv episode results for S{season} E{episode} - {tv_show.title}: {episode_name}")
|
||||||
current_app.logger.info("could not get tmdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
|
continue
|
||||||
with open("/var/lib/rpiWebApp/log.txt", "w") as f:
|
info = r.json()
|
||||||
f.write("could not get tmdb data for: " + episode_imdb_id + " " + tv_show.title + " " + str(
|
|
||||||
tv_show.year) + " " + str(season) + " " + str(episode) + "\n")
|
episode_tmdb_id = info["id"]
|
||||||
continue
|
episode_description = info["overview"]
|
||||||
episode_tmdb_id = episode_tmdb_data[0]
|
episode_still_path = info["still_path"]
|
||||||
episode_description = episode_tmdb_data[1]
|
episodes.append(
|
||||||
episode_still_path = episode_tmdb_data[2]
|
(episode_tmdb_id, tv_show.tmdb_id, episode_name, season, episode, episode_description, episode_still_path, path,)
|
||||||
episodes.append((episode_imdb_id, tv_show.imdb_id, episode_tmdb_id, episode_name, season, episode,
|
)
|
||||||
episode_description, episode_still_path, path))
|
if len(episodes) >= 10:
|
||||||
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
tv_episodes_loaded.send("anonymous", tv_episodes=episodes.copy())
|
||||||
current_app.logger.info("finished load tv episodes")
|
episodes.clear()
|
||||||
except Exception as e:
|
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
current_app.logger.info("finished loading tv episodes")
|
||||||
|
|
||||||
|
|
||||||
def get_tv_episode(path):
|
def get_tv_episode(path: pathlib.Path):
|
||||||
folder, name = os.path.split(path)
|
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mkv)"
|
||||||
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mp4|.mkv)"
|
video_match = re.match(video_pattern, path.name)
|
||||||
video_match = re.match(video_pattern, name)
|
if video_match:
|
||||||
if video_match:
|
rows = database.get_all_tv_shows()
|
||||||
rows = database.get_all_tv_shows()
|
for tv_show in rows:
|
||||||
for tv_show in rows:
|
if path.parent == tv_show.path:
|
||||||
if folder == tv_show.path:
|
if not database.tv_episode_path_in_db(str(path)):
|
||||||
if not database.tv_episode_path_in_db(path):
|
episodes = []
|
||||||
episodes = []
|
season = int(video_match.group("season"))
|
||||||
season = int(video_match.group("season"))
|
episode = int(video_match.group("episode"))
|
||||||
episode = int(video_match.group("episode"))
|
episode_name = video_match.group("title")
|
||||||
episode_name = video_match.group("title")
|
url = f"https://api.themoviedb.org/3/tv/{tv_show.tmdb_id}/season/{season}/episode/{episode}"
|
||||||
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
|
|
||||||
if not episode_imdb_data:
|
data = {"api_key": API_KEY, "language": "en-US"}
|
||||||
current_app.logger.info(
|
r = requests.get(url, params=data)
|
||||||
"could not get imdb data for: " + tv_show.title + " " + str(tv_show.year) + " " + str(
|
if "status_code" in r.json().keys():
|
||||||
season) + " " + str(episode))
|
current_app.logger.info(f"no tv episode results for S{season} E{episode} - {tv_show.title}: {episode_name}")
|
||||||
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
|
continue
|
||||||
return
|
info = r.json()
|
||||||
episode_imdb_id = episode_imdb_data["tconst"]
|
|
||||||
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
|
episode_tmdb_id = info["id"]
|
||||||
if not episode_tmdb_data:
|
episode_description = info["overview"]
|
||||||
current_app.logger.info(
|
episode_still_path = info["still_path"]
|
||||||
"could not get tmdb data for: " + tv_show.title + " " + str(tv_show.year) + " " + str(
|
episodes.append(
|
||||||
season) + " " + str(episode))
|
(episode_tmdb_id, tv_show.tmdb_id, episode_name, season, episode, episode_description, episode_still_path, str(path),)
|
||||||
with open("/var/lib/rpiWebApp/log.txt", "w") as f:
|
)
|
||||||
f.write("could not get tmdb data for: " + episode_imdb_id + " " + tv_show.title + " " + str(
|
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
||||||
tv_show.year) + " " + str(season) + " " + str(episode) + "\n")
|
current_app.logger.info("finished loading tv episode")
|
||||||
return
|
|
||||||
episode_tmdb_id = episode_tmdb_data[0]
|
|
||||||
episode_description = episode_tmdb_data[1]
|
|
||||||
episode_still_path = episode_tmdb_data[2]
|
|
||||||
episodes.append((episode_imdb_id, tv_show.imdb_id, episode_tmdb_id, episode_name, season, episode,
|
|
||||||
episode_description, episode_still_path, path))
|
|
||||||
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
|
||||||
current_app.logger.info("finished load tv episode")
|
|
||||||
|
|
||||||
|
|
||||||
def get_chapters(path):
|
def get_chapters(path):
|
||||||
try:
|
try:
|
||||||
with open(path, 'rb') as f:
|
with open(path, "rb") as f:
|
||||||
mkv = enzyme.MKV(f)
|
mkv = enzyme.MKV(f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
mkv_info = {}
|
return {}
|
||||||
for chapter in mkv.chapters:
|
mkv_info = {}
|
||||||
if chapter.string == "Intro":
|
for chapter in mkv.chapters:
|
||||||
mkv_info["intro"] = {
|
if chapter.string == "Intro":
|
||||||
"start": chapter.start.seconds,
|
mkv_info["intro"] = {
|
||||||
"end": timedelta(microseconds=chapter.end//1000).seconds
|
"start": chapter.start.seconds,
|
||||||
}
|
"end": timedelta(microseconds=chapter.end // 1000).seconds,
|
||||||
if chapter.string == "Credits":
|
}
|
||||||
mkv_info["credits"] = {"start": chapter.start.seconds}
|
if chapter.string == "Credits":
|
||||||
if chapter.string == "end-credit scene":
|
mkv_info["credits"] = {"start": chapter.start.seconds}
|
||||||
if "end-credit scene" not in mkv_info.keys():
|
if chapter.string == "end-credit scene":
|
||||||
mkv_info["end-credit scene"] = []
|
if "end-credit scene" not in mkv_info.keys():
|
||||||
end_credit = {"start": chapter.start.seconds}
|
mkv_info["end-credit scene"] = []
|
||||||
if chapter.end:
|
end_credit = {"start": chapter.start.seconds}
|
||||||
end_credit["end"] = timedelta(microseconds=chapter.end//1000).seconds
|
if chapter.end:
|
||||||
mkv_info["end-credit scene"].append(end_credit)
|
end_credit["end"] = timedelta(microseconds=chapter.end // 1000).seconds
|
||||||
return mkv_info
|
mkv_info["end-credit scene"].append(end_credit)
|
||||||
|
return mkv_info
|
||||||
|
|
||||||
|
|
||||||
def get_tags(path):
|
def get_tags(path):
|
||||||
try:
|
try:
|
||||||
with open(path, 'rb') as f:
|
with open(path, "rb") as f:
|
||||||
mkv = enzyme.MKV(f)
|
mkv = enzyme.MKV(f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
mkv_info = {}
|
mkv_info = {}
|
||||||
for tag in mkv.tags:
|
for tag in mkv.tags:
|
||||||
if tag.targets.data[0].data == 70:
|
if tag.targets.data[0].data == 70:
|
||||||
mkv_info["collection"] = {}
|
mkv_info["collection"] = {}
|
||||||
for simple in tag.simpletags:
|
for simple in tag.simpletags:
|
||||||
if simple.name == "TITLE":
|
if simple.name == "TITLE":
|
||||||
mkv_info["collection"]["title"] = simple.string
|
mkv_info["collection"]["title"] = simple.string
|
||||||
if simple.name == "TOTAL_PARTS":
|
if simple.name == "TOTAL_PARTS":
|
||||||
mkv_info["collection"]["episodes"] = int(simple.string)
|
mkv_info["collection"]["episodes"] = int(simple.string)
|
||||||
if simple.name == "KEYWORDS":
|
if simple.name == "KEYWORDS":
|
||||||
mkv_info["collection"]["key_words"] = simple.string.split(",")
|
mkv_info["collection"]["key_words"] = simple.string.split(",")
|
||||||
if simple.name == "DATE_RELEASED":
|
if simple.name == "DATE_RELEASED":
|
||||||
mkv_info["collection"]["year"] = int(simple.string)
|
mkv_info["collection"]["year"] = int(simple.string)
|
||||||
if simple.name == "SUMMARY":
|
if simple.name == "SUMMARY":
|
||||||
mkv_info["collection"]["summary"] = simple.string
|
mkv_info["collection"]["summary"] = simple.string
|
||||||
if tag.targets.data[0].data == 60:
|
if tag.targets.data[0].data == 60:
|
||||||
mkv_info["season"] = {}
|
mkv_info["season"] = {}
|
||||||
for simple in tag.simpletags:
|
for simple in tag.simpletags:
|
||||||
if simple.name == "TITLE":
|
if simple.name == "TITLE":
|
||||||
mkv_info["season"]["title"] = simple.string
|
mkv_info["season"]["title"] = simple.string
|
||||||
if simple.name == "TOTAL_PARTS":
|
if simple.name == "TOTAL_PARTS":
|
||||||
mkv_info["season"]["episodes"] = int(simple.string)
|
mkv_info["season"]["episodes"] = int(simple.string)
|
||||||
if tag.targets.data[0].data == 50:
|
if tag.targets.data[0].data == 50:
|
||||||
mkv_info["movie"] = {}
|
mkv_info["movie"] = {}
|
||||||
for simple in tag.simpletags:
|
for simple in tag.simpletags:
|
||||||
if simple.name == "TITLE":
|
if simple.name == "TITLE":
|
||||||
mkv_info["movie"]["title"] = simple.string
|
mkv_info["movie"]["title"] = simple.string
|
||||||
if simple.name == "DATE_RELEASED":
|
if simple.name == "DATE_RELEASED":
|
||||||
mkv_info["movie"]["year"] = int(simple.string)
|
mkv_info["movie"]["year"] = int(simple.string)
|
||||||
if simple.name == "PART_NUMBER":
|
if simple.name == "PART_NUMBER":
|
||||||
mkv_info["movie"]["episode"] = int(simple.string)
|
mkv_info["movie"]["episode"] = int(simple.string)
|
||||||
if simple.name == "KEYWORDS":
|
if simple.name == "KEYWORDS":
|
||||||
mkv_info["movie"]["key_words"] = simple.string.split(",")
|
mkv_info["movie"]["key_words"] = simple.string.split(",")
|
||||||
if simple.name == "SUMMARY":
|
if simple.name == "SUMMARY":
|
||||||
mkv_info["movie"]["summary"] = simple.string
|
mkv_info["movie"]["summary"] = simple.string
|
||||||
return mkv_info
|
return mkv_info
|
||||||
|
|
||||||
|
|
||||||
def get_games():
|
def get_games():
|
||||||
games = []
|
games = []
|
||||||
cover_url = "https://api-v3.igdb.com/covers"
|
cover_url = "https://api-v3.igdb.com/covers"
|
||||||
games_url = "https://api-v3.igdb.com/games"
|
games_url = "https://api-v3.igdb.com/games"
|
||||||
headers = {
|
headers = {
|
||||||
"accept": "application/json",
|
"accept": "application/json",
|
||||||
"user-key": "641f7f0e3af5273dcc1105ce851ea804"
|
"user-key": "641f7f0e3af5273dcc1105ce851ea804",
|
||||||
}
|
}
|
||||||
i = 0
|
i = 0
|
||||||
for folder in sorted(os.listdir(GAMES_DIRECTORY), key=str.casefold):
|
current_app.logger.info("start loading games")
|
||||||
root = os.path.join(GAMES_DIRECTORY, folder)
|
for folder in sorted(os.listdir(GAMES_DIRECTORY), key=str.casefold):
|
||||||
if os.path.isdir(os.path.join(root)):
|
root = os.path.join(GAMES_DIRECTORY, folder)
|
||||||
path = os.path.join(root, "info.json")
|
if os.path.isdir(os.path.join(root)):
|
||||||
with open(path, "r") as f:
|
try:
|
||||||
info = json.load(f)
|
path = os.path.join(root, "info.json")
|
||||||
game_id = info["id"]
|
with open(path, "r") as f:
|
||||||
if not database.game_in_db(game_id):
|
info = json.load(f)
|
||||||
current_app.logger.info(f"start loading game: {info['name']}:{info['id']}")
|
game_id = info["id"]
|
||||||
data = f"fields summary;limit 1;where id={game_id};"
|
if not database.game_in_db(game_id):
|
||||||
r = requests.get(games_url, headers=headers, data=data).json()[0]
|
current_app.logger.info(f"start loading game: {info['name']}:{info['id']}")
|
||||||
description = ""
|
data = f"fields summary;limit 1;where id={game_id};"
|
||||||
if "summary" in r.keys():
|
r = requests.get(games_url, headers=headers, data=data).json()[0]
|
||||||
description = r["summary"]
|
description = ""
|
||||||
data = f"fields image_id;limit 1;where game={game_id};"
|
if "summary" in r.keys():
|
||||||
r = requests.get(cover_url, headers=headers, data=data).json()
|
description = r["summary"]
|
||||||
poster_path = None
|
data = f"fields image_id;limit 1;where game={game_id};"
|
||||||
if r:
|
r = requests.get(cover_url, headers=headers, data=data).json()
|
||||||
if "image_id" in r[0].keys():
|
poster_path = None
|
||||||
poster_path = "https://images.igdb.com/igdb/image/upload/t_cover_big/" + r[0]["image_id"] + ".jpg"
|
if r:
|
||||||
windows = None
|
if "image_id" in r[0].keys():
|
||||||
mac = None
|
poster_path = "https://images.igdb.com/igdb/image/upload/t_cover_big/" + r[0]["image_id"] + ".jpg"
|
||||||
linux = None
|
windows = False
|
||||||
if "windows" in info.keys():
|
mac = False
|
||||||
windows = info["windows"]
|
linux = False
|
||||||
if "mac" in info.keys():
|
if "windows" in info.keys():
|
||||||
mac = info["mac"]
|
windows = True
|
||||||
if "linux" in info.keys():
|
if "mac" in info.keys():
|
||||||
linux = info["linux"]
|
mac = True
|
||||||
game = (info["name"], game_id, description, poster_path, windows, mac, linux)
|
if "linux" in info.keys():
|
||||||
games.append(game)
|
linux = True
|
||||||
i += 1
|
game = (
|
||||||
if i >= 5:
|
info["name"],
|
||||||
games_loaded.send("anonymous", games=games.copy())
|
game_id,
|
||||||
games.clear()
|
description,
|
||||||
i = 0
|
poster_path,
|
||||||
games_loaded.send("anonymous", games=games)
|
root,
|
||||||
current_app.logger.info("finished loading games")
|
windows,
|
||||||
|
mac,
|
||||||
|
linux,
|
||||||
|
folder,
|
||||||
|
)
|
||||||
|
games.append(game)
|
||||||
|
i += 1
|
||||||
|
if i >= 5:
|
||||||
|
games_loaded.send("anonymous", games=games.copy())
|
||||||
|
games.clear()
|
||||||
|
i = 0
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
games_loaded.send("anonymous", games=games)
|
||||||
|
current_app.logger.info("finished loading games")
|
||||||
|
|
||||||
|
|
||||||
|
def get_game(path: pathlib.Path):
|
||||||
|
try:
|
||||||
|
games = []
|
||||||
|
cover_url = "https://api-v3.igdb.com/covers"
|
||||||
|
games_url = "https://api-v3.igdb.com/games"
|
||||||
|
headers = {
|
||||||
|
"accept": "application/json",
|
||||||
|
"user-key": "***REMOVED***",
|
||||||
|
}
|
||||||
|
if not path.name == "info.json":
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
with path.open("r") as f:
|
||||||
|
info = json.load(f)
|
||||||
|
game_id = info["id"]
|
||||||
|
if database.game_in_db(game_id):
|
||||||
|
update_game(path)
|
||||||
|
else:
|
||||||
|
dir = path.parent
|
||||||
|
folder = path.parts[-2]
|
||||||
|
current_app.logger.info(f"start loading game: {info['name']}:{info['id']}")
|
||||||
|
data = f"fields summary;limit 1;where id={game_id};"
|
||||||
|
r = requests.get(games_url, headers=headers, data=data).json()[0]
|
||||||
|
description = ""
|
||||||
|
if "summary" in r.keys():
|
||||||
|
description = r["summary"]
|
||||||
|
data = f"fields image_id;limit 1;where game={game_id};"
|
||||||
|
r = requests.get(cover_url, headers=headers, data=data).json()
|
||||||
|
poster_path = None
|
||||||
|
if r:
|
||||||
|
if "image_id" in r[0].keys():
|
||||||
|
poster_path = "https://images.igdb.com/igdb/image/upload/t_cover_big/" + r[0]["image_id"] + ".jpg"
|
||||||
|
windows = False
|
||||||
|
mac = False
|
||||||
|
linux = False
|
||||||
|
if "windows" in info.keys():
|
||||||
|
windows = True
|
||||||
|
if "mac" in info.keys():
|
||||||
|
mac = True
|
||||||
|
if "linux" in info.keys():
|
||||||
|
linux = True
|
||||||
|
game = (
|
||||||
|
info["name"],
|
||||||
|
game_id,
|
||||||
|
description,
|
||||||
|
poster_path,
|
||||||
|
str(dir),
|
||||||
|
windows,
|
||||||
|
mac,
|
||||||
|
linux,
|
||||||
|
folder,
|
||||||
|
)
|
||||||
|
games.append(game)
|
||||||
|
games_loaded.send("anonymous", games=games)
|
||||||
|
current_app.logger.info("finished loading game")
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
|
def update_games():
|
||||||
|
current_app.logger.info("start updating game data")
|
||||||
|
for folder in sorted(os.listdir(GAMES_DIRECTORY), key=str.casefold):
|
||||||
|
root = pathlib.Path(GAMES_DIRECTORY, folder, "info.json")
|
||||||
|
update_game(root)
|
||||||
|
current_app.logger.info("finished updating game data")
|
||||||
|
|
||||||
|
|
||||||
|
def update_game(path: pathlib.Path):
|
||||||
|
try:
|
||||||
|
if path.name == "info.json" and path.exists():
|
||||||
|
with path.open("r") as f:
|
||||||
|
info = json.load(f)
|
||||||
|
game_id = info["id"]
|
||||||
|
windows = False
|
||||||
|
mac = False
|
||||||
|
linux = False
|
||||||
|
if "windows" in info.keys():
|
||||||
|
windows = True
|
||||||
|
if "mac" in info.keys():
|
||||||
|
mac = True
|
||||||
|
if "linux" in info.keys():
|
||||||
|
linux = True
|
||||||
|
database.update_game((game_id, windows, mac, linux))
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
import sqlite3, subprocess, os
|
import os
|
||||||
|
import sqlite3
|
||||||
|
import subprocess
|
||||||
|
|
||||||
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/"
|
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/"
|
||||||
RPI_TSV_DIRECTORY = "/var/lib/imdb-rename/"
|
RPI_TSV_DIRECTORY = "/var/lib/imdb-rename/"
|
||||||
@ -15,19 +17,25 @@ CSV_DIRECTORY = RPI_CSV_DIRECTORY if os.path.exists(RPI_CSV_DIRECTORY) else MC_C
|
|||||||
|
|
||||||
|
|
||||||
def create_csv_files():
|
def create_csv_files():
|
||||||
print("start create csv")
|
print("start create csv")
|
||||||
subprocess.run(["xsv", "input", "-d", "\t", "--no-quoting", "{}title.akas.tsv".format(TSV_DIRECTORY), "-o", "{}title_akas.csv".format(CSV_DIRECTORY)])
|
subprocess.run(
|
||||||
subprocess.run(["xsv", "input", "-d", "\t", "--no-quoting", "{}title.basics.tsv".format(TSV_DIRECTORY), "-o", "{}title_basics.csv".format(CSV_DIRECTORY)])
|
["xsv", "input", "-d", "\t", "--no-quoting", "{}title.akas.tsv".format(TSV_DIRECTORY), "-o", "{}title_akas.csv".format(CSV_DIRECTORY)]
|
||||||
subprocess.run(["xsv", "input", "-d", "\t", "--no-quoting", "{}title.episode.tsv".format(TSV_DIRECTORY), "-o", "{}title_episode.csv".format(CSV_DIRECTORY)])
|
)
|
||||||
print("end create csv")
|
subprocess.run(
|
||||||
|
["xsv", "input", "-d", "\t", "--no-quoting", "{}title.basics.tsv".format(TSV_DIRECTORY), "-o", "{}title_basics.csv".format(CSV_DIRECTORY)]
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["xsv", "input", "-d", "\t", "--no-quoting", "{}title.episode.tsv".format(TSV_DIRECTORY), "-o", "{}title_episode.csv".format(CSV_DIRECTORY)]
|
||||||
|
)
|
||||||
|
print("end create csv")
|
||||||
|
|
||||||
|
|
||||||
def import_csv_files():
|
def import_csv_files():
|
||||||
print("start import csv")
|
print("start import csv")
|
||||||
f = open("import_csv.sql").read()
|
f = open("import_csv.sql").read()
|
||||||
sql_script = f.format(CSV_DIRECTORY)
|
sql_script = f.format(CSV_DIRECTORY)
|
||||||
subprocess.run(["sudo", "-u", "http", "sqlite3", IMDB_DATABASE+"imdb.db"], input=sql_script.encode("utf8"))
|
subprocess.run(["sudo", "-u", "http", "sqlite3", IMDB_DATABASE + "imdb.db"], input=sql_script.encode("utf8"))
|
||||||
print("end import csv")
|
print("end import csv")
|
||||||
|
|
||||||
|
|
||||||
create_csv_files()
|
create_csv_files()
|
||||||
|
134
scripts/tmdb.py
134
scripts/tmdb.py
@ -1,7 +1,8 @@
|
|||||||
from flask import current_app
|
|
||||||
import requests
|
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from flask import current_app
|
||||||
|
|
||||||
API_KEY = "***REMOVED***"
|
API_KEY = "***REMOVED***"
|
||||||
TMDB_FIND_URL = "https://api.themoviedb.org/3/find/"
|
TMDB_FIND_URL = "https://api.themoviedb.org/3/find/"
|
||||||
TMDB_GET_TV_URL = "https://api.themoviedb.org/3/tv/"
|
TMDB_GET_TV_URL = "https://api.themoviedb.org/3/tv/"
|
||||||
@ -10,83 +11,70 @@ TMDB_IMG_URL = "https://image.tmdb.org/t/p/original"
|
|||||||
|
|
||||||
|
|
||||||
def get_movie_data(imdb_id):
|
def get_movie_data(imdb_id):
|
||||||
try:
|
try:
|
||||||
data = {
|
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
|
||||||
"api_key": API_KEY,
|
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
|
||||||
"language": "en-US",
|
info = dict(r.json())
|
||||||
"external_source": "imdb_id"
|
if "status_code" in info.keys():
|
||||||
}
|
current_app.logger.info("error getting tmdb movie data, status code: " + str(info["status_code"]) + " " + str(info["status_message"]))
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
return None
|
||||||
info = dict(r.json())
|
if info["movie_results"] == []:
|
||||||
if "status_code" in info.keys():
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
current_app.logger.info("error getting tmdb movie data, status code: "+str(info["status_code"])+" "+str(info["status_message"]))
|
return None
|
||||||
return None
|
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
|
||||||
if info["movie_results"] == []:
|
movie_id = info["movie_results"][0]["id"]
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
overview = info["movie_results"][0]["overview"]
|
||||||
return None
|
poster_path = info["movie_results"][0]["poster_path"]
|
||||||
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
|
backdrop_path = info["movie_results"][0]["backdrop_path"]
|
||||||
movie_id = info["movie_results"][0]["id"]
|
|
||||||
overview = info["movie_results"][0]["overview"]
|
|
||||||
poster_path = info["movie_results"][0]["poster_path"]
|
|
||||||
backdrop_path = info["movie_results"][0]["backdrop_path"]
|
|
||||||
|
|
||||||
return movie_id, overview, poster_path, backdrop_path
|
return movie_id, overview, poster_path, backdrop_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def get_tv_show_data(imdb_id):
|
def get_tv_show_data(imdb_id):
|
||||||
try:
|
try:
|
||||||
data = {
|
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
|
||||||
"api_key": API_KEY,
|
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
|
||||||
"language": "en-US",
|
info = dict(r.json())
|
||||||
"external_source": "imdb_id"
|
if "status_code" in info.keys():
|
||||||
}
|
current_app.logger.info("error getting tmdb tv show data, status code: " + str(info["status_code"]) + " " + str(info["status_message"]))
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
return None
|
||||||
info = dict(r.json())
|
if info["tv_results"] == []:
|
||||||
if "status_code" in info.keys():
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
current_app.logger.info("error getting tmdb tv show data, status code: " + str(info["status_code"])+" "+str(info["status_message"]))
|
return None
|
||||||
return None
|
current_app.logger.info("tmdb tv show title: " + str(info["tv_results"][0]["name"]))
|
||||||
if info["tv_results"] == []:
|
tv_show_id = info["tv_results"][0]["id"]
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
overview = info["tv_results"][0]["overview"]
|
||||||
return None
|
poster_path = info["tv_results"][0]["poster_path"]
|
||||||
current_app.logger.info("tmdb tv show title: " + str(info["tv_results"][0]["name"]))
|
|
||||||
tv_show_id = info["tv_results"][0]["id"]
|
|
||||||
overview = info["tv_results"][0]["overview"]
|
|
||||||
poster_path = info["tv_results"][0]["poster_path"]
|
|
||||||
|
|
||||||
return tv_show_id, overview, poster_path
|
return tv_show_id, overview, poster_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
def get_tv_episode_data(imdb_id):
|
def get_tv_episode_data(imdb_id):
|
||||||
try:
|
try:
|
||||||
data = {
|
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
|
||||||
"api_key": API_KEY,
|
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
|
||||||
"language": "en-US",
|
episode_info = dict(r.json())
|
||||||
"external_source": "imdb_id"
|
if "status_code" in episode_info.keys():
|
||||||
}
|
current_app.logger.info(
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
"error getting tmdb tv episode data, status code: " + str(episode_info["status_code"]) + " " + str(episode_info["status_message"])
|
||||||
episode_info = dict(r.json())
|
)
|
||||||
if "status_code" in episode_info.keys():
|
return None
|
||||||
current_app.logger.info("error getting tmdb tv episode data, status code: " + str(episode_info["status_code"])+" "+str(episode_info["status_message"]))
|
if episode_info["tv_episode_results"] == []:
|
||||||
return None
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
if episode_info["tv_episode_results"] == []:
|
return None
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
data = {"api_key": API_KEY, "language": "en-US"}
|
||||||
return None
|
r = requests.get(TMDB_GET_TV_URL + str(episode_info["tv_episode_results"][0]["show_id"]), params=data)
|
||||||
data = {
|
show_name = dict(r.json())["name"]
|
||||||
"api_key": API_KEY,
|
current_app.logger.info("tmdb tv_episode title: " + show_name + ": " + str(episode_info["tv_episode_results"][0]["name"]))
|
||||||
"language": "en-US"
|
tv_episode_id = episode_info["tv_episode_results"][0]["id"]
|
||||||
}
|
name = episode_info["tv_episode_results"][0]["name"]
|
||||||
r = requests.get(TMDB_GET_TV_URL+str(episode_info["tv_episode_results"][0]["show_id"]), params=data)
|
overview = episode_info["tv_episode_results"][0]["overview"]
|
||||||
show_name = dict(r.json())["name"]
|
still_path = episode_info["tv_episode_results"][0]["still_path"]
|
||||||
current_app.logger.info("tmdb tv_episode title: " + show_name + ": " + str(episode_info["tv_episode_results"][0]["name"]))
|
|
||||||
tv_episode_id = episode_info["tv_episode_results"][0]["id"]
|
|
||||||
name = episode_info["tv_episode_results"][0]["name"]
|
|
||||||
overview = episode_info["tv_episode_results"][0]["overview"]
|
|
||||||
still_path = episode_info["tv_episode_results"][0]["still_path"]
|
|
||||||
|
|
||||||
return tv_episode_id, overview, still_path
|
return tv_episode_id, overview, still_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
BIN
static/images/Seven Seas Entertainment.png
Normal file
BIN
static/images/Seven Seas Entertainment.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 6.9 KiB |
@ -61,7 +61,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
var page_num = {{ page }};
|
var page_num = {% if page %}{{ page }}{% else %}1{% endif %};
|
||||||
var max_items = {{ max_items }};
|
var max_items = {{ max_items }};
|
||||||
var item_count = {{ item_count }};
|
var item_count = {{ item_count }};
|
||||||
var start = max_items*(page_num-1);
|
var start = max_items*(page_num-1);
|
||||||
@ -74,6 +74,10 @@
|
|||||||
var page_container = document.getElementById("page-container");
|
var page_container = document.getElementById("page-container");
|
||||||
|
|
||||||
function go_to_page(pagenumber) {
|
function go_to_page(pagenumber) {
|
||||||
|
let url = new URL(document.location)
|
||||||
|
url.searchParams.set("page", pagenumber)
|
||||||
|
window.history.replaceState(null, null, url.toString())
|
||||||
|
{#document.location.search = search#}
|
||||||
page_num = pagenumber;
|
page_num = pagenumber;
|
||||||
start = max_items*(page_num-1);
|
start = max_items*(page_num-1);
|
||||||
if (item_count < max_items*page_num) {
|
if (item_count < max_items*page_num) {
|
||||||
@ -126,6 +130,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
window.scrollTo(0, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
function offset_page(i) {
|
function offset_page(i) {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container" style="text-align: center">
|
<div class="w3-row" style="text-align: center">
|
||||||
|
<div class="w3-col s1 w3-hide-small m1 l2"><p></p></div>
|
||||||
|
<div class="w3-col s12 m10 l8">
|
||||||
|
|
||||||
<video id="player" class="video-js vjs-big-play-centered" style="display: inline-block" controls preload="auto" width="1100"
|
<video id="player" class="video-js vjs-big-play-centered vjs-16-9" style="display: inline-block; width:100%" controls preload="auto"
|
||||||
poster="https://image.tmdb.org/t/p/original{{ episode.still_path }}" data-setup="{}">
|
poster="https://image.tmdb.org/t/p/original{{ episode.still_path }}" data-setup="{}">
|
||||||
<source src="{{ url_for("tv_movies.index") }}/get_episode/{{ episode.imdb_id }}" type="video/webm">
|
<source src="{{ url_for("tv_movies.index") }}/get_episode/{{ episode.tmdb_id }}" type="video/webm">
|
||||||
<p class='vjs-no-js'>
|
<p class='vjs-no-js'>
|
||||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
||||||
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
|
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
|
||||||
@ -32,7 +34,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<p style="text-align: left">{{ episode.description }}</p>
|
<p style="text-align: left">{{ episode.description }}</p>
|
||||||
<a class="btn btn-primary" href="{{ url_for("tv_movies.index") }}/get_episode/{{ episode.imdb_id }}" download="{{ episode.title }}">Download</a>
|
<a class="btn btn-primary" href="{{ url_for("tv_movies.index") }}/get_episode/{{ episode.tmdb_id }}" download="{{ episode.title }}">Download</a>
|
||||||
|
|
||||||
{% with %}
|
{% with %}
|
||||||
{% set seasons = [] %}
|
{% set seasons = [] %}
|
||||||
@ -63,7 +65,7 @@
|
|||||||
<div class="w3-display-topleft w3-container w3-round" style="background: rgba(105,105,105,0.61);color: white">Episode {{ episode.episode }}</div>
|
<div class="w3-display-topleft w3-container w3-round" style="background: rgba(105,105,105,0.61);color: white">Episode {{ episode.episode }}</div>
|
||||||
<div class="w3-display-bottommiddle w3-container w3-round" style="background: rgba(105,105,105,0.61);color: white">{{ episode.title }}</div>
|
<div class="w3-display-bottommiddle w3-container w3-round" style="background: rgba(105,105,105,0.61);color: white">{{ episode.title }}</div>
|
||||||
{% for data in user_tv_show_data %}
|
{% for data in user_tv_show_data %}
|
||||||
{% if data.imdb_id == episode.imdb_id and data.finished %}
|
{% if data.tmdb_id == episode.tmdb_id and data.finished %}
|
||||||
<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
||||||
<img src="/static/svg/verified.svg" >
|
<img src="/static/svg/verified.svg" >
|
||||||
</div>
|
</div>
|
||||||
@ -71,7 +73,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% for data in user_tv_show_data %}
|
{% for data in user_tv_show_data %}
|
||||||
{% if data.imdb_id == episode.imdb_id and data.time != 0 and data.length != 0 %}
|
{% if data.tmdb_id == episode.tmdb_id and data.time != 0 and data.length != 0 %}
|
||||||
<div class="w3-light-gray">
|
<div class="w3-light-gray">
|
||||||
<div class="w3-red" style="height: 5px; width: {{ (data.time/data.length)*100 }}%"></div>
|
<div class="w3-red" style="height: 5px; width: {{ (data.time/data.length)*100 }}%"></div>
|
||||||
</div>
|
</div>
|
||||||
@ -83,6 +85,8 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="w3-col s1 w3-hide-small m1 l2"><p></p></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -133,7 +137,7 @@
|
|||||||
//length = myPlayer.duration();
|
//length = myPlayer.duration();
|
||||||
let oReq = new XMLHttpRequest();
|
let oReq = new XMLHttpRequest();
|
||||||
oReq.addEventListener("load", reqListener);
|
oReq.addEventListener("load", reqListener);
|
||||||
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length+"&finished="+finished);
|
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.tmdb_id }}?time="+(time+5)+"&parent={{ episode.parent_tmdb_id }}&length="+length+"&finished="+finished);
|
||||||
oReq.send();
|
oReq.send();
|
||||||
time = myPlayer.currentTime();
|
time = myPlayer.currentTime();
|
||||||
}
|
}
|
||||||
@ -143,7 +147,7 @@
|
|||||||
//length = myPlayer.duration();
|
//length = myPlayer.duration();
|
||||||
let oReq = new XMLHttpRequest();
|
let oReq = new XMLHttpRequest();
|
||||||
oReq.addEventListener("load", reqListener);
|
oReq.addEventListener("load", reqListener);
|
||||||
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length+"&finished="+finished);
|
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.tmdb_id }}?time="+(time+5)+"&parent={{ episode.parent_tmdb_id }}&length="+length+"&finished="+finished);
|
||||||
oReq.send();
|
oReq.send();
|
||||||
time = myPlayer.currentTime();
|
time = myPlayer.currentTime();
|
||||||
});
|
});
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
{% include "pagination.html" %}
|
{% include "pagination.html" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="container col-10">
|
<div class="w3-container">
|
||||||
<div id="page-container" class="row justify-content-start"></div>
|
<div id="page-container" style="display: flow-root; text-align: center"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
{% include "pagination.html" %}
|
{% include "pagination.html" %}
|
||||||
@ -34,28 +34,42 @@
|
|||||||
function populate_page() {
|
function populate_page() {
|
||||||
page_container.innerHTML = "";
|
page_container.innerHTML = "";
|
||||||
for (i = start;i < end; i++) {
|
for (i = start;i < end; i++) {
|
||||||
var anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}">`;
|
let badge = ""
|
||||||
|
var anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}">`;
|
||||||
if (tv_shows[i][0].extended && tv_shows[i][0].directors_cut) {
|
if (tv_shows[i][0].extended && tv_shows[i][0].directors_cut) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?extended=True&directors_cut=True">`;
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?extended=True&directors_cut=True">`;
|
||||||
} else if (tv_shows[i][0].extended) {
|
} else if (tv_shows[i][0].extended) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?extended=True">`;
|
badge = `<div class="w3-display-topleft w3-container" style="color: white; background: rgba(105,105,105,0.61); border-radius: 0 5px 5px 0">
|
||||||
|
extended
|
||||||
|
</div>`
|
||||||
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?extended=True">`;
|
||||||
} else if (tv_shows[i][0].directors_cut) {
|
} else if (tv_shows[i][0].directors_cut) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?directors_cut=True">`;
|
badge = `<div class="w3-display-topleft w3-container" style="color: white; background: rgba(105,105,105,0.61); border-radius: 0 5px 5px 0">
|
||||||
|
director's cut
|
||||||
|
</div>`
|
||||||
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?directors_cut=True">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
var finished = ``;
|
var finished = ``;
|
||||||
if (tv_shows[i][1]) {
|
if (tv_shows[i][1]) {
|
||||||
finished = `<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
finished = `<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
||||||
<img src="/static/svg/verified.svg" >
|
<img src="/static/svg/verified.svg" >
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
var list_element = `<div class="col-3" style="padding: 10px">
|
|
||||||
|
var text = ""
|
||||||
|
if (!tv_shows[i][0].poster_path) {
|
||||||
|
text = `<div class='w3-display-middle w3-container' style="color: white; text-align: center;font-size: 20px; width: 100%">
|
||||||
|
${tv_shows[i][0].title} (${tv_shows[i][0].year})</div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
var list_element = `<div class="w3-display-container w3-round" style="width: 350px; display: inline-block; padding: 10px">
|
||||||
${anchor}
|
${anchor}
|
||||||
<div class="card w3-display-container">
|
<div class="card w3-display-container">
|
||||||
<img class="card-img" src="https://image.tmdb.org/t/p/original${tv_shows[i][0].poster_path}" alt="" onerror="this.src='/static/images/default.png'">
|
<img class="card-img" src="https://image.tmdb.org/t/p/original${tv_shows[i][0].poster_path}" alt="${tv_shows[i][0].title} (${tv_shows[i][0].year})" title="${tv_shows[i][0].title} (${tv_shows[i][0].year})" onerror="this.src='/static/images/default.png'">
|
||||||
<div class="card-body">
|
${text}
|
||||||
${tv_shows[i][0].title} (${tv_shows[i][0].year})
|
|
||||||
</div>
|
|
||||||
${finished}
|
${finished}
|
||||||
|
${badge}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container" style="text-align: center">
|
<div class="w3-row" style="text-align: center">
|
||||||
<video id="player" class="video-js vjs-big-play-centered" style="display: inline-block" controls preload="auto" width="1100"
|
<div class="w3-col s1 w3-hide-small m1 l2"><p></p></div>
|
||||||
|
<div class="w3-col s12 m10 l8">
|
||||||
|
<video id="player" class="video-js vjs-big-play-centered vjs-16-9" style="display: inline-block" controls preload="auto"
|
||||||
poster="https://image.tmdb.org/t/p/original{{ movie.backdrop_path }}" data-setup="{}">
|
poster="https://image.tmdb.org/t/p/original{{ movie.backdrop_path }}" data-setup="{}">
|
||||||
{% if movie.extended and movie.directors_cut %}
|
{% if movie.extended and movie.directors_cut %}
|
||||||
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_id }}?extended=True&directors_cut=True" type="video/webm">
|
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.tmdb_id }}?extended=True&directors_cut=True" type="video/webm">
|
||||||
{% elif movie.extended %}
|
{% elif movie.extended %}
|
||||||
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_id }}?extended=True" type="video/webm">
|
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.tmdb_id }}?extended=True" type="video/webm">
|
||||||
{% elif movie.directors_cut %}
|
{% elif movie.directors_cut %}
|
||||||
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_id }}?directors_cut=True" type="video/webm">
|
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.tmdb_id }}?directors_cut=True" type="video/webm">
|
||||||
{% else %}
|
{% else %}
|
||||||
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_id }}" type="video/webm">
|
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.tmdb_id }}" type="video/webm">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p class='vjs-no-js'>
|
<p class='vjs-no-js'>
|
||||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
||||||
@ -20,7 +22,9 @@
|
|||||||
</video>
|
</video>
|
||||||
<h1>{{ movie.title }}</h1>
|
<h1>{{ movie.title }}</h1>
|
||||||
<p style="text-align: left">{{ movie.description }}</p>
|
<p style="text-align: left">{{ movie.description }}</p>
|
||||||
<a class="btn btn-primary" href="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_id }}{% if movie.extended == 1 %}/extended{% endif %}{% if movie.directors_cut==1 %}/directors_cut{% endif %}" download="{{ movie.title }}">Download</a>
|
<a class="btn btn-primary" href="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.tmdb_id }}{% if movie.extended == 1 %}/extended{% endif %}{% if movie.directors_cut==1 %}/directors_cut{% endif %}" download="{{ movie.title }}">Download</a>
|
||||||
|
</div>
|
||||||
|
<div class="w3-col s1 w3-hide-small m1 l2"><p></p></div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -60,7 +64,7 @@
|
|||||||
length = myPlayer.duration();
|
length = myPlayer.duration();
|
||||||
let oReq = new XMLHttpRequest();
|
let oReq = new XMLHttpRequest();
|
||||||
oReq.addEventListener("load", reqListener);
|
oReq.addEventListener("load", reqListener);
|
||||||
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.imdb_id }}?time="+(time)+"&length="+length+"&finished="+finished{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
|
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.tmdb_id }}?time="+(time)+"&length="+length+"&finished="+finished{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
|
||||||
oReq.send();
|
oReq.send();
|
||||||
time = myPlayer.currentTime();
|
time = myPlayer.currentTime();
|
||||||
}
|
}
|
||||||
@ -70,7 +74,7 @@
|
|||||||
length = myPlayer.duration();
|
length = myPlayer.duration();
|
||||||
let oReq = new XMLHttpRequest();
|
let oReq = new XMLHttpRequest();
|
||||||
oReq.addEventListener("load", reqListener);
|
oReq.addEventListener("load", reqListener);
|
||||||
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.imdb_id }}?time="+(time)+"&length="+length+"&finished="+finished{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
|
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.tmdb_id }}?time="+(time)+"&length="+length+"&finished="+finished{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
|
||||||
oReq.send();
|
oReq.send();
|
||||||
time = myPlayer.currentTime();
|
time = myPlayer.currentTime();
|
||||||
});
|
});
|
||||||
|
@ -16,9 +16,9 @@
|
|||||||
<div style="text-align: center">
|
<div style="text-align: center">
|
||||||
{% include "pagination.html" %}
|
{% include "pagination.html" %}
|
||||||
</div>
|
</div>
|
||||||
<div class="container col-10">
|
<div class="w3-container">
|
||||||
{% if movies != [] %}
|
{% if movies != [] %}
|
||||||
<div id="page-container" class="row justify-content-start"></div>
|
<div id="page-container" style="display: flow-root; text-align: center"></div>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1>No results.</h1>
|
<h1>No results.</h1>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -38,28 +38,42 @@
|
|||||||
function populate_page() {
|
function populate_page() {
|
||||||
page_container.innerHTML = "";
|
page_container.innerHTML = "";
|
||||||
for (i = start;i < end; i++) {
|
for (i = start;i < end; i++) {
|
||||||
var anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}">`;
|
let badge = ""
|
||||||
|
var anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}">`;
|
||||||
if (tv_shows[i][0].extended && tv_shows[i][0].directors_cut) {
|
if (tv_shows[i][0].extended && tv_shows[i][0].directors_cut) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?extended=True&directors_cut=True">`;
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?extended=True&directors_cut=True">`;
|
||||||
} else if (tv_shows[i][0].extended) {
|
} else if (tv_shows[i][0].extended) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?extended=True">`;
|
badge = `<div class="w3-display-topleft w3-container" style="color: white; background: rgba(105,105,105,0.61); border-radius: 0 5px 5px 0">
|
||||||
|
extended
|
||||||
|
</div>`
|
||||||
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?extended=True">`;
|
||||||
} else if (tv_shows[i][0].directors_cut) {
|
} else if (tv_shows[i][0].directors_cut) {
|
||||||
anchor = `<a href="/tv_movies/${tv_shows[i][0].imdb_id}?directors_cut=True">`;
|
badge = `<div class="w3-display-topleft w3-container" style="color: white; background: rgba(105,105,105,0.61); border-radius: 0 5px 5px 0">
|
||||||
|
director's cut
|
||||||
|
</div>`
|
||||||
|
anchor = `<a href="/tv_movies/${tv_shows[i][0].tmdb_id}?directors_cut=True">`;
|
||||||
}
|
}
|
||||||
|
|
||||||
var finished = ``;
|
var finished = ``;
|
||||||
if (tv_shows[i][1]) {
|
if (tv_shows[i][1]) {
|
||||||
finished = `<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
finished = `<div class="w3-display-topright w3-container" style="background: rgba(105,105,105,0.61); border-radius: 5px 0 0 5px">
|
||||||
<img src="/static/svg/verified.svg" >
|
<img src="/static/svg/verified.svg" >
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
var list_element = `<div class="col-3" style="padding: 10px">
|
|
||||||
|
var text = ""
|
||||||
|
if (!tv_shows[i][0].poster_path) {
|
||||||
|
text = `<div class='w3-display-middle w3-container' style="color: white; text-align: center;font-size: 20px; width: 100%">
|
||||||
|
${tv_shows[i][0].title} (${tv_shows[i][0].year})</div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
var list_element = `<div class="w3-display-container w3-round" style="width: 350px; display: inline-block; padding: 10px">
|
||||||
${anchor}
|
${anchor}
|
||||||
<div class="card w3-display-container">
|
<div class="card w3-display-container">
|
||||||
<img class="card-img" src="https://image.tmdb.org/t/p/original${tv_shows[i][0].poster_path}" alt="" onerror="this.src='/static/images/default.png'">
|
<img class="card-img" src="https://image.tmdb.org/t/p/original${tv_shows[i][0].poster_path}" alt="${tv_shows[i][0].title} (${tv_shows[i][0].year})" title="${tv_shows[i][0].title} (${tv_shows[i][0].year})" onerror="this.src='/static/images/default.png'">
|
||||||
<div class="card-body">
|
${text}
|
||||||
${tv_shows[i][0].title} (${tv_shows[i][0].year})
|
|
||||||
</div>
|
|
||||||
${finished}
|
${finished}
|
||||||
|
${badge}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>`;
|
</div>`;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
from flask import Blueprint, render_template, request, make_response, send_from_directory, current_app
|
import datetime
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
from flask import Blueprint, current_app, make_response, render_template, request, send_from_directory
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
|
|
||||||
from scripts import database, func
|
from scripts import database, func
|
||||||
import inspect
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
TV_Movies = Blueprint("tv_movies", __name__, template_folder="templates")
|
TV_Movies = Blueprint("tv_movies", __name__, template_folder="templates")
|
||||||
|
|
||||||
@ -11,154 +12,169 @@ TV_Movies = Blueprint("tv_movies", __name__, template_folder="templates")
|
|||||||
@TV_Movies.route("/tv_movies")
|
@TV_Movies.route("/tv_movies")
|
||||||
@login_required
|
@login_required
|
||||||
def index():
|
def index():
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
tv = database.get_all_tv_movies()
|
tv = database.get_all_tv_movies()
|
||||||
start = (max_items * (page - 1))
|
start = max_items * (page - 1)
|
||||||
end = len(tv) if len(tv) < max_items * page else max_items * page
|
end = len(tv) if len(tv) < max_items * page else max_items * page
|
||||||
tv_dict = []
|
tv_dict = []
|
||||||
for tv_item in tv:
|
for tv_item in tv:
|
||||||
item = tv_item[0].__dict__
|
item = tv_item[0].__dict__
|
||||||
item.pop('_sa_instance_state', None)
|
item.pop("_sa_instance_state", None)
|
||||||
item.pop('path', None)
|
item.pop("path", None)
|
||||||
tv_dict.append((item, tv_item[1]))
|
tv_dict.append((item, tv_item[1]))
|
||||||
return render_template("tv_movies/index.html", title="tv & movies", tv_shows=tv_dict, page=page, max_items=max_items, start=start, end=end, item_count=len(tv))
|
return render_template(
|
||||||
except Exception as e:
|
"tv_movies/index.html", title="tv & movies", tv_shows=tv_dict, page=page, max_items=max_items, start=start, end=end, item_count=len(tv)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
)
|
||||||
return str(type(e))+" "+str(e)
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@TV_Movies.route("/tv_movies/search")
|
@TV_Movies.route("/tv_movies/search")
|
||||||
@login_required
|
@login_required
|
||||||
def search():
|
def search():
|
||||||
try:
|
try:
|
||||||
page = request.args.get("page", 1, type=int)
|
page = request.args.get("page", 1, type=int)
|
||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
start = 0
|
start = 0
|
||||||
end = 0
|
end = 0
|
||||||
query = request.args.get("q")
|
query = request.args.get("q")
|
||||||
tv = []
|
tv = []
|
||||||
if query:
|
if query:
|
||||||
tv = database.db_search_tv_movie(query)
|
tv = database.db_search_tv_movie(query)
|
||||||
start = (max_items * (page - 1))
|
start = max_items * (page - 1)
|
||||||
end = len(tv) if len(tv) < max_items * page else max_items * page
|
end = len(tv) if len(tv) < max_items * page else max_items * page
|
||||||
tv_dict = []
|
tv_dict = []
|
||||||
for tv_item in tv:
|
for tv_item in tv:
|
||||||
item = tv_item[0].__dict__
|
item = tv_item[0].__dict__
|
||||||
item.pop('_sa_instance_state', None)
|
item.pop("_sa_instance_state", None)
|
||||||
item.pop('path', None)
|
item.pop("path", None)
|
||||||
tv_dict.append((item, tv_item[1]))
|
tv_dict.append((item, tv_item[1]))
|
||||||
return render_template("tv_movies/search.html", title="tv_movies", tv_shows=tv_dict, page=page, max_items=max_items,
|
return render_template(
|
||||||
start=start, end=end, item_count=len(tv))
|
"tv_movies/search.html", title="tv_movies", tv_shows=tv_dict, page=page, max_items=max_items, start=start, end=end, item_count=len(tv)
|
||||||
except Exception as e:
|
)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
except Exception as e:
|
||||||
return str(type(e))+" "+str(e)
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@TV_Movies.route("/tv_movies/<imdb_id>", methods=["GET", "POST"])
|
@TV_Movies.route("/tv_movies/<tmdb_id>", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def tv_movie_viewer(imdb_id):
|
def tv_movie_viewer(tmdb_id):
|
||||||
try:
|
try:
|
||||||
tv_movie = database.get_tv_movie_by_imdb_id(imdb_id)
|
tv_movie = database.get_tv_movie_by_tmdb_id(tmdb_id)
|
||||||
if type(tv_movie) is database.Movie:
|
if type(tv_movie) is database.Movie:
|
||||||
extended = request.args.get("extended", default=False, type=bool)
|
extended = request.args.get("extended", default=False, type=bool)
|
||||||
directors_cut = request.args.get("directors_cut", default=False, type=bool)
|
directors_cut = request.args.get("directors_cut", default=False, type=bool)
|
||||||
return movie_view(imdb_id, extended=extended, directors_cut=directors_cut)
|
return movie_view(tmdb_id, extended=extended, directors_cut=directors_cut)
|
||||||
else:
|
else:
|
||||||
return episode_viewer(imdb_id)
|
return episode_viewer(tmdb_id)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(type(e))+" "+str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def movie_view(imdb_id, extended=False, directors_cut=False):
|
def movie_view(tmdb_id, extended=False, directors_cut=False):
|
||||||
try:
|
try:
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
time = int(request.args.get("time", type=float))
|
time = int(request.args.get("time", type=float))
|
||||||
length = int(request.args.get("length", type=float, default=0))
|
length = int(request.args.get("length", type=float, default=0))
|
||||||
finished = True if request.args.get("finished", default="false") == "true" else False
|
finished = True if request.args.get("finished", default="false") == "true" else False
|
||||||
database.update_user_tv_movie_data(imdb_id, None, time, length, finished, extended, directors_cut)
|
database.update_user_tv_movie_data(tmdb_id, None, time, length, finished, extended, directors_cut)
|
||||||
return make_response("", 201)
|
return make_response("", 201)
|
||||||
else:
|
else:
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=extended, directors_cut=directors_cut)
|
movie_data = database.db_get_movie_by_tmdb_id(tmdb_id, extended=extended, directors_cut=directors_cut)
|
||||||
user_data = database.db_get_user_tv_movie_data(movie_data.imdb_id, extended=extended, directors_cut=directors_cut)
|
user_data = database.db_get_user_tv_movie_data(movie_data.tmdb_id, extended=extended, directors_cut=directors_cut)
|
||||||
chapters = func.get_chapters(movie_data.path)
|
chapters = func.get_chapters(movie_data.path)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
user_data = database.update_user_tv_movie_data(movie_data.imdb_id, None, 0, 0)
|
user_data = database.update_user_tv_movie_data(movie_data.tmdb_id, None, 0, 0)
|
||||||
return render_template("tv_movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data, user_data=user_data, chapters=chapters)
|
return render_template(
|
||||||
except Exception as e:
|
"tv_movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data, user_data=user_data, chapters=chapters
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
)
|
||||||
return str(type(e)) + " " + str(e)
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def episode_viewer(imdb_id):
|
def episode_viewer(tmdb_id):
|
||||||
try:
|
try:
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
time = int(request.args.get("time", type=float))
|
time = int(request.args.get("time", type=float))
|
||||||
parent_id = request.args.get("parent", type=str)
|
parent_id = request.args.get("parent", type=str)
|
||||||
length = int(request.args.get("length", type=float, default=0))
|
length = int(request.args.get("length", type=float, default=0))
|
||||||
finished = True if request.args.get("finished", default="false") == "true" else False
|
finished = True if request.args.get("finished", default="false") == "true" else False
|
||||||
database.update_user_tv_movie_data(imdb_id, parent_id, time, length, finished)
|
database.update_user_tv_movie_data(tmdb_id, parent_id, time, length, finished)
|
||||||
return make_response("", 201)
|
return make_response("", 201)
|
||||||
else:
|
else:
|
||||||
tv_show = database.get_tv_show(imdb_id)
|
tv_show = database.get_tv_show(tmdb_id)
|
||||||
episodes = database.get_tv_show_episodes_by_imdb_id(imdb_id)
|
episodes = database.get_tv_show_episodes_by_tmdb_id(tmdb_id)
|
||||||
season_num = request.args.get("season", type=int, default=None)
|
season_num = request.args.get("season", type=int, default=None)
|
||||||
episode_num = request.args.get("episode", type=int, default=None)
|
episode_num = request.args.get("episode", type=int, default=None)
|
||||||
user_tv_show_data = database.db_get_user_tv_show_episodes_data(imdb_id)
|
user_tv_show_data = database.db_get_user_tv_show_episodes_data(tmdb_id)
|
||||||
if not season_num and not episode_num:
|
if not season_num and not episode_num:
|
||||||
(current_episode, user_data) = database.db_get_current_tv_show_episode_and_data(imdb_id, episodes)
|
(current_episode, user_data) = database.db_get_current_tv_show_episode_and_data(tmdb_id, episodes)
|
||||||
season_num = current_episode.season
|
season_num = current_episode.season
|
||||||
episode_num = current_episode.episode
|
episode_num = current_episode.episode
|
||||||
chapters = func.get_chapters(current_episode.path)
|
chapters = func.get_chapters(current_episode.path)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
|
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
|
||||||
else:
|
else:
|
||||||
current_episode = episodes[0]
|
current_episode = episodes[0]
|
||||||
user_data = database.UserTvMovieData(("", "", "", 0, 0, False, datetime.datetime.min))
|
user_data = database.UserTvMovieData(("", "", "", 0, 0, False, datetime.datetime.min, False, False))
|
||||||
for episode in episodes:
|
for episode in episodes:
|
||||||
if episode.season == season_num and episode.episode == episode_num:
|
if episode.season == season_num and episode.episode == episode_num:
|
||||||
current_episode = episode
|
current_episode = episode
|
||||||
user_data = database.db_get_user_tv_movie_data(current_episode.imdb_id)
|
user_data = database.db_get_user_tv_movie_data(current_episode.tmdb_id)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
|
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
for episode in episodes:
|
for episode in episodes:
|
||||||
if episode.season == season_num:
|
if episode.season == season_num:
|
||||||
current_episode = episode
|
current_episode = episode
|
||||||
episode_num = episode.episode
|
episode_num = episode.episode
|
||||||
user_data = database.db_get_user_tv_movie_data(current_episode.imdb_id)
|
user_data = database.db_get_user_tv_movie_data(current_episode.tmdb_id)
|
||||||
if not user_data:
|
if not user_data:
|
||||||
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
|
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
|
||||||
break
|
break
|
||||||
chapters = func.get_chapters(current_episode.path)
|
chapters = func.get_chapters(current_episode.path)
|
||||||
return render_template("tv_movies/episodeViewer.html", title="Tv: " + tv_show.title, episodes=episodes, season_num=season_num, episode_num=episode_num, episode=current_episode, user_data=user_data, user_tv_show_data=user_tv_show_data, chapters=chapters)
|
return render_template(
|
||||||
except Exception as e:
|
"tv_movies/episodeViewer.html",
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
title="Tv: " + tv_show.title,
|
||||||
return str(type(e)) + " " + str(e)
|
episodes=episodes,
|
||||||
|
season_num=season_num,
|
||||||
|
episode_num=episode_num,
|
||||||
|
episode=current_episode,
|
||||||
|
user_data=user_data,
|
||||||
|
user_tv_show_data=user_tv_show_data,
|
||||||
|
chapters=chapters,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@TV_Movies.route("/tv_movies/get_movie/<imdb_id>")
|
@TV_Movies.route("/tv_movies/get_movie/<tmdb_id>")
|
||||||
@login_required
|
@login_required
|
||||||
def get_movie(imdb_id):
|
def get_movie(tmdb_id):
|
||||||
extended = request.args.get("extended", default=False, type=bool)
|
extended = request.args.get("extended", default=False, type=bool)
|
||||||
directors_cut = request.args.get("directors_cut", default=False, type=bool)
|
directors_cut = request.args.get("directors_cut", default=False, type=bool)
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=extended, directors_cut=directors_cut)
|
movie_data = database.db_get_movie_by_tmdb_id(tmdb_id, extended=extended, directors_cut=directors_cut)
|
||||||
filename = movie_data.path.replace(func.MOVIES_DIRECTORY, "")
|
filename = movie_data.path.replace(func.MOVIES_DIRECTORY, "")
|
||||||
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
||||||
response.headers["content-type"] = "video/webm"
|
response.headers["content-type"] = "video/webm"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@TV_Movies.route("/tv_movies/get_episode/<imdb_id>")
|
@TV_Movies.route("/tv_movies/get_episode/<tmdb_id>")
|
||||||
@login_required
|
@login_required
|
||||||
def get_episode(imdb_id):
|
def get_episode(tmdb_id):
|
||||||
episode_data = database.db_get_episode_by_imdb_id(imdb_id)
|
episode_data = database.db_get_episode_by_tmdb_id(tmdb_id)
|
||||||
filename = episode_data.path.replace(func.TV_SHOWS_DIRECTORY, "")
|
filename = episode_data.path.replace(func.TV_SHOWS_DIRECTORY, "")
|
||||||
response = make_response(send_from_directory(func.TV_SHOWS_DIRECTORY, filename))
|
response = make_response(send_from_directory(func.TV_SHOWS_DIRECTORY, filename))
|
||||||
response.headers["content-type"] = "video/webm"
|
response.headers["content-type"] = "video/webm"
|
||||||
return response
|
return response
|
||||||
|
Loading…
Reference in New Issue
Block a user