Changed file formatting and fixed comic viewer.

This commit is contained in:
Matthew Welch 2020-08-05 18:47:29 -07:00
parent 51c6b5e572
commit f8aa5ff2d7
19 changed files with 2180 additions and 1745 deletions

View File

@ -1,5 +1,5 @@
from flask import Blueprint, flash, redirect, url_for, render_template
from flask_login import login_required, current_user
from flask import Blueprint, flash, redirect, render_template, url_for
from flask_login import current_user, login_required
Admin = Blueprint("admin", __name__, template_folder="templates")
@ -7,7 +7,7 @@ Admin = Blueprint("admin", __name__, template_folder="templates")
@Admin.route("/admin")
@login_required
def index():
if not current_user.is_admin:
flash("you must be an admin to access this page, login with an admin account.")
return redirect(url_for("login"))
return render_template("admin/index.html", title="Admin")
if not current_user.is_admin:
flash("you must be an admin to access this page, login with an admin account.")
return redirect(url_for("login"))
return render_template("admin/index.html", title="Admin")

View File

@ -1,10 +1,12 @@
from flask import Blueprint, render_template, request, make_response, current_app
from flask_login import login_required
from urllib import parse
import filetype
import os, pytz, datetime
import datetime
import inspect
import os
from urllib import parse
import filetype
import pytz
from flask import Blueprint, current_app, make_response, render_template, request
from flask_login import login_required
from scripts import database, func
@ -16,145 +18,195 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
@Comics.route("/comics")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publishers = database.get_publishers()
start = (max_items*(page-1))
end = len(publishers) if len(publishers) < max_items*page else max_items*page
return render_template("comics/index.html", title="Comics", publishers=publishers, page=page, max_items=max_items, start=start, end=end, item_count=len(publishers))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publishers = database.get_publishers()
start = max_items * (page - 1)
end = len(publishers) if len(publishers) < max_items * page else max_items * page
return render_template(
"comics/index.html",
title="Comics",
publishers=publishers,
page=page,
max_items=max_items,
start=start,
end=end,
item_count=len(publishers),
)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/search")
@login_required
def search():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_end = 0
series_end = 0
comics_end = 0
publisher_start = 0
series_start = 0
comics_start = 0
item_count = 0
query = request.args.get("q")
results = {
"publisher": [],
"series": [],
"comics": []
}
if query:
results = database.db_search_comics(query)
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
for temp_page in range(1, page+1):
publisher_start = publisher_end
series_start = series_end
comics_start = comics_end
items = 0
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items*temp_page else max_items*temp_page
items += publisher_end - publisher_start
if items < max_items:
series_end = len(results["series"]) if len(results["series"]) < (max_items*temp_page)-items else (max_items*temp_page)-items
items += series_end-series_start
if items < max_items:
comics_end = len(results["comics"]) if len(results["comics"]) < (max_items*temp_page)-series_end-publisher_end else (max_items*temp_page)-series_end-publisher_end
return render_template("comics/search.html", title="Comics: Search", publishers=results["publisher"], publisher_series=results["series"],
comics=results["comics"], page=page, max_items=max_items, item_count=item_count,
publisher_start=publisher_start, series_start=series_start, comics_start=comics_start,
publisher_end=publisher_end, series_end=series_end, comics_end=comics_end)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e))+" "+str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_end = 0
series_end = 0
comics_end = 0
publisher_start = 0
series_start = 0
comics_start = 0
item_count = 0
query = request.args.get("q")
results = {"publisher": [], "series": [], "comics": []}
if query:
results = database.db_search_comics(query)
item_count = len(results["publisher"]) + len(results["series"]) + len(results["comics"])
for temp_page in range(1, page + 1):
publisher_start = publisher_end
series_start = series_end
comics_start = comics_end
items = 0
publisher_end = len(results["publisher"]) if len(results["publisher"]) < max_items * temp_page else max_items * temp_page
items += publisher_end - publisher_start
if items < max_items:
series_end = (
len(results["series"]) if len(results["series"]) < (max_items * temp_page) - items else (max_items * temp_page) - items
)
items += series_end - series_start
if items < max_items:
comics_end = (
len(results["comics"])
if len(results["comics"]) < (max_items * temp_page) - series_end - publisher_end
else (max_items * temp_page) - series_end - publisher_end
)
return render_template(
"comics/search.html",
title="Comics: Search",
publishers=results["publisher"],
publisher_series=results["series"],
comics=results["comics"],
page=page,
max_items=max_items,
item_count=item_count,
publisher_start=publisher_start,
series_start=series_start,
comics_start=comics_start,
publisher_end=publisher_end,
series_end=series_end,
comics_end=comics_end,
)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/<publisher>")
@login_required
def comics_publisher(publisher):
try:
publisher = parse.unquote(publisher)
series = request.args.get("series")
series_year = request.args.get("seriesYear")
issue = request.args.get("issue")
page_number = request.args.get("pageNumber")
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_series = database.db_get_series_by_publisher(publisher)
start = (max_items*(page-1))
end = len(publisher_series) if len(publisher_series) < max_items*page else max_items*page
if series:
comics = database.db_get_comics_in_series(series, publisher, series_year)
start = (max_items * (page - 1))
end = len(comics) if len(comics) < max_items * page else max_items * page
if issue:
return comic_gallery(publisher, series, series_year, issue)
comics_dict = []
for i in comics:
item = i.__dict__
item.pop('_sa_instance_state', None)
item.pop('path', None)
comics_dict.append(item)
return render_template("comics/seriesView.html", title="Comics", comics=comics_dict,
start=start, end=end, page=page, max_items=max_items, item_count=len(comics))
pub_series_dict = []
for i in publisher_series:
item = i.__dict__
item.pop('_sa_instance_state', None)
item.pop('path', None)
pub_series_dict.append(item)
return render_template("comics/publisherSeriesView.html", title="Comics", publisher_series=pub_series_dict,
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
try:
publisher = parse.unquote(publisher)
series = request.args.get("series")
series_year = request.args.get("seriesYear")
issue = request.args.get("issue")
page_number = request.args.get("pageNumber")
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
publisher_series = database.db_get_series_by_publisher(publisher)
start = max_items * (page - 1)
end = len(publisher_series) if len(publisher_series) < max_items * page else max_items * page
if series:
comics = database.db_get_comics_in_series(series, publisher, series_year)
start = max_items * (page - 1)
end = len(comics) if len(comics) < max_items * page else max_items * page
if issue:
return comic_gallery(publisher, series, series_year, issue)
comics_dict = []
for i in comics:
item = i.__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
comics_dict.append(item)
return render_template(
"comics/seriesView.html",
title="Comics",
comics=comics_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=len(comics),
)
pub_series_dict = []
for i in publisher_series:
item = i.__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
pub_series_dict.append(item)
return render_template(
"comics/publisherSeriesView.html",
title="Comics",
publisher_series=pub_series_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=len(publisher_series),
)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/<int:comic_id>")
@login_required
def comic_gallery(comic_id):
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
meta = database.db_get_comic(comic_id)
start = (max_items*(page-1))
end = meta.pagecount if meta.pagecount < max_items*page else max_items*page
comic_dict = meta.__dict__
comic_dict.pop('_sa_instance_state', None)
comic_dict.pop('path', None)
return render_template("comics/comicGallery.html", title="Comics", comic=comic_dict, start=start, end=end, page=page, max_items=max_items, item_count=meta.pagecount)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
meta = database.db_get_comic(comic_id)
start = max_items * (page - 1)
end = meta.pagecount if meta.pagecount < max_items * page else max_items * page
comic_dict = meta.__dict__
comic_dict.pop("_sa_instance_state", None)
comic_dict.pop("path", None)
return render_template(
"comics/comicGallery.html",
title="Comics",
comic=comic_dict,
start=start,
end=end,
page=page,
max_items=max_items,
item_count=meta.pagecount,
)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>")
@login_required
def get_comic_page(comic_id, page_number):
meta = database.db_get_comic_by_id(comic_id)
comic = func.open_comic(meta.path)
byte_image = comic.getPage(page_number)
type = filetype.guess(byte_image).mime
response = make_response(byte_image)
response.headers["content-type"] = type
response.headers["cache-control"] = "public"
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
response.headers["Content-Disposition"] = "attachment; filename=\"{} {}_{}{}\"".format(str(meta.series), meta.issuetext, str(page_number), filetype.guess(byte_image).extension)
return response
meta = database.db_get_comic_by_id(comic_id)
comic = func.open_comic(meta.path)
byte_image = comic.getPage(page_number)
type = filetype.guess(byte_image).mime
response = make_response(byte_image)
response.headers["content-type"] = type
response.headers["cache-control"] = "public"
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
response.headers["last-modified"] = date.strftime("%a, %d %b %Y %H:%M:%S %Z")
response.headers["Content-Disposition"] = 'attachment; filename="{} {}_{}{}"'.format(
str(meta.series), meta.issuetext, str(page_number), filetype.guess(byte_image).extension
)
return response
@Comics.route("/comics/get_comic/<int:comic_id>/<int:page_number>/thumbnail")
@login_required
def get_comic_thumbnail(comic_id, page_number):
meta = database.db_get_comic_by_id(comic_id)
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
response = make_response(thumb.image)
response.headers["cache-control"] = "public"
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
response.headers["content-type"] = thumb.type
response.headers["Content-Disposition"] = "attachment; filename=\"{} {}_{}_thumbnail\"".format(str(meta.series), meta.issuetext, str(page_number))
return response
meta = database.db_get_comic_by_id(comic_id)
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
response = make_response(thumb.image)
response.headers["cache-control"] = "public"
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
response.headers["last-modified"] = date.strftime("%a, %d %b %Y %H:%M:%S %Z")
response.headers["content-type"] = thumb.type
response.headers["Content-Disposition"] = 'attachment; filename="{} {}_{}_thumbnail"'.format(str(meta.series), meta.issuetext, str(page_number))
return response

View File

@ -117,7 +117,7 @@
page_container.innerHTML = "";
for (i = start;i < end; i++) {
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>
</div>`;
page_container.innerHTML += list_element;
@ -134,15 +134,24 @@
let next_image = document.getElementById("next");
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) {
if (document.getElementById(page_number.toString())) {return;}
if (page_number >= page_count) {return;}
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 += `<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>';
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
@ -202,4 +211,6 @@
});
load_next_image(0);
</script>
<script type="text/python">
</script>
{% endblock %}

View File

@ -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 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
@ -14,78 +13,157 @@ Games = Blueprint("games", __name__, template_folder="templates")
@Games.route("/games")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
games = database.get_all_games()
start = (max_items*(page-1))
end = len(games) if len(games) < max_items*page else max_items*page
return render_template("games/index.html", title="Games", games=games)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
games = database.get_all_games()
start = max_items * (page - 1)
end = len(games) if len(games) < max_items * page else max_items * page
return render_template("games/index.html", title="Games", games=games)
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')
@Games.route("/games/get_games")
@login_required
def get_games():
try:
games = database.get_all_games()
games_json = {}
for game in games:
games_json[game.game_id] = {
"id": game.game_id,
"title": game.title,
"windows": game.windows,
"mac": game.mac,
"linux": game.linux,
"description": game.description,
"poster_path": game.poster_path
}
return jsonify(games_json)
# return jsonify({game["id"]: game for game in games})
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
try:
games = database.get_all_games()
games_json = {}
for game in games:
games_json[game.game_id] = {
"id": game.game_id,
"title": game.title,
"description": game.description,
"poster_path": game.poster_path,
"windows": game.windows,
"mac": game.mac,
"linux": game.linux,
"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_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
def get_game(game_id):
try:
game = database.get_game(game_id)
if game:
game_json = {
"title": game.title,
"game_id": game.game_id,
"description": game.description,
"poster_path": game.poster_path,
"windows": game.windows,
"mac": game.mac,
"linux": game.linux
}
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)
try:
game = database.get_game(game_id)
if game:
with open(os.path.join(game.path, "info.json")) as f:
info = json.load(f)
windows = None
mac = None
linux = None
if "windows" in info.keys():
windows = info["windows"]
if "mac" in info.keys():
mac = info["mac"]
if "linux" in info.keys():
linux = info["linux"]
game_json = {
"title": game.title,
"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
def download_game(game_id):
try:
game = database.get_game(game_id)
if game:
files = game.windows["files"]
filename = sanitize_filename(files[0])
folder = re.match(r"(.+)_setup_win.(exe|msi)", filename).group(1)
if len(files) > 1:
filename = sanitize_filename(game.title+".zip")
path = os.path.join(func.GAMES_DIRECTORY, folder, filename)
return send_file(path, as_attachment=True, attachment_filename=filename)
else:
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)
def download_game_hash(game_id, file_hash):
try:
game = database.get_game(game_id)
if game:
folder = game.path
path = os.path.join(folder, file_hash[:2], file_hash)
return send_file(path, as_attachment=True, attachment_filename=file_hash)
else:
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)

View File

@ -2,7 +2,7 @@
{% block content %}
{% 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>
{% endfor %}
{% endblock %}

View File

@ -1,47 +1,48 @@
from flask import Flask
from flask import render_template, request, g, redirect, url_for, flash, current_app, Response
from flask_login import LoginManager, current_user, login_user, logout_user, login_required
import base64
import datetime
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
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
from scripts import database
from admin import admin
from comics import comics
from tv_movies import tv_movies
from games import games
from scripts import database
from tv_movies import tv_movies
class NullHandler(logging.Handler):
def emit(self, record=None):
pass
def emit(self, record=None):
pass
def debug(self, *arg):
pass
def debug(self, *arg):
pass
nullLog = NullHandler()
inotify.adapters._LOGGER = nullLog
GOOGLE_CLIENT_ID = "***REMOVED***"
GOOGLE_CLIENT_SECRET = "***REMOVED***"
GOOGLE_DISCOVERY_URL = (
"https://accounts.google.com/.well-known/openid-configuration"
)
GOOGLE_DISCOVERY_URL = "https://accounts.google.com/.well-known/openid-configuration"
client = WebApplicationClient(GOOGLE_CLIENT_ID)
def get_google_provider_cfg():
return requests.get(GOOGLE_DISCOVERY_URL).json()
return requests.get(GOOGLE_DISCOVERY_URL).json()
app = Flask(__name__)
@ -54,7 +55,7 @@ app.logger.setLevel("DEBUG")
# app.use_x_sendfile = True
login_manager = LoginManager(app)
login_manager.login_view = "login"
# login_manager.login_view = "login"
app.config["REMEMBER_COOKIE_DOMAIN"] = "narnian.us"
@ -62,101 +63,135 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
def get_comics():
with app.app_context():
i = inotify.adapters.InotifyTree(func.COMICS_DIRECTORY)
func.get_comics()
for event in i.event_gen(yield_nones=False):
(header, type_names, path, filename) = event
file_path = os.path.join(path, filename)
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
func.get_comic(file_path)
with app.app_context():
i = inotify.adapters.InotifyTree(func.COMICS_DIRECTORY)
new_dirs = []
func.get_comics()
while True:
for event in i.event_gen(timeout_s=5*60, 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_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():
with app.app_context():
i = inotify.adapters.InotifyTree(func.MOVIES_DIRECTORY)
func.get_movies()
for event in i.event_gen(yield_nones=False):
(header, type_names, path, filename) = event
file_path = os.path.join(path, filename)
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
func.get_movie(file_path)
with app.app_context():
i = inotify.adapters.InotifyTree(func.MOVIES_DIRECTORY)
func.get_movies()
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_movie(file_path)
def get_tv_shows():
with app.app_context():
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
func.get_tv_shows()
func.get_tv_episodes()
for event in i.event_gen(yield_nones=False):
(header, type_names, path, filename) = event
file_path = os.path.join(path, filename)
if "IN_CLOSE_WRITE" in type_names or "IN_MOVED_TO" in type_names:
func.get_tv_shows()
func.get_tv_episode(file_path)
with app.app_context():
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
func.get_tv_shows()
func.get_tv_episodes()
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:
if file_path.is_dir():
func.get_tv_shows()
else:
func.get_tv_episode(file_path)
def get_games():
with app.app_context():
func.get_games()
with app.app_context():
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():
current_app.logger.info("server start")
thread = threading.Thread(target=get_comics, args=())
thread.daemon = True
thread.start()
thread2 = threading.Thread(target=get_movies, args=())
thread2.daemon = True
thread2.start()
thread3 = threading.Thread(target=get_tv_shows, args=())
thread3.daemon = True
thread3.start()
thread4 = threading.Thread(target=get_games, args=())
thread4.daemon = True
thread4.start()
current_app.logger.info("server start")
thread = threading.Thread(target=get_comics, args=())
thread.daemon = True
thread.start()
thread2 = threading.Thread(target=get_movies, args=())
thread2.daemon = True
thread2.start()
thread3 = threading.Thread(target=get_tv_shows, args=())
thread3.daemon = True
thread3.start()
thread4 = threading.Thread(target=get_games, args=())
thread4.daemon = True
thread4.start()
@app.teardown_appcontext
def close_connection(exception):
db = getattr(g, '_database', None)
if db is not None:
db.close()
db = getattr(g, "_database", None)
if db is not None:
db.close()
def update_comic_db(sender, **kw):
try:
database.add_comics(kw["meta"], kw["thumbnails"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
try:
database.add_comics(kw["meta"], kw["thumbnails"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def update_movie_db(sender, **kw):
try:
database.add_movies(kw["movies"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
try:
database.add_movies(kw["movies"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def update_tv_show_db(sender, **kw):
try:
database.add_tv_shows(kw["tv_show"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
try:
database.add_tv_shows(kw["tv_show"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def update_tv_episodes_db(sender, **kw):
try:
database.add_tv_episodes(kw["tv_episodes"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
try:
database.add_tv_episodes(kw["tv_episodes"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def update_games_db(sender, **kw):
try:
database.add_games(kw["games"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
try:
database.add_games(kw["games"])
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
func.comic_loaded.connect(update_comic_db)
@ -168,177 +203,183 @@ func.games_loaded.connect(update_games_db)
@login_manager.user_loader
def load_user(email):
try:
return database.get_user(email)
except Exception as 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))
try:
return database.get_user(email)
except Exception as 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))
@login_manager.request_loader
def load_user_from_request(request):
try:
api_key = request.headers.get('Authorization')
if api_key:
api_key = api_key.replace('Basic ', '', 1)
try:
api_key = base64.b64decode(api_key).decode("utf-8")
except TypeError:
pass
email = api_key.split(":")[0]
password = api_key.split(":")[1]
user = load_user(email)
if user and user.check_password(password):
return user
return None
except Exception as 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))
try:
api_key = request.headers.get("Authorization")
if api_key:
api_key = api_key.replace("Basic ", "", 1)
try:
api_key = base64.b64decode(api_key).decode("utf-8")
except TypeError:
pass
email = api_key.split(":")[0]
password = api_key.split(":")[1]
user = load_user(email)
if user and user.check_password(password):
return user
return None
except Exception as 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))
@app.route("/login", methods=["GET", "POST"])
def login():
try:
google_provider_cfg = get_google_provider_cfg()
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
try:
url = urlsplit(request.url)
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(
authorization_endpoint,
redirect_uri=request.base_url + "/callback",
scope=["openid", "email", "profile"],
)
google_provider_cfg = get_google_provider_cfg()
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
if request.method == "POST":
email = request.form.get("email")
password = request.form.get("password")
user = database.get_user(email)
if user is None or not user.check_password(password):
flash("invalid email or password")
return redirect(url_for("login"))
login_user(user, remember=True, duration=datetime.timedelta(days=7))
next_page = request.args.get("next")
if not next_page:
next_page = url_for("home")
return redirect(next_page)
return render_template("login.html", title="login", auth_url=request_uri)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
request_uri = client.prepare_request_uri(
authorization_endpoint,
redirect_uri=urljoin(request.host_url, url_for("callback")),
scope=["openid", "email", "profile"],
state=next_page,
hd="narnian.us",
)
if request.method == "POST":
email = request.form.get("email")
password = request.form.get("password")
user = database.get_user(email)
if user is None or not user.check_password(password):
flash("invalid email or password")
return redirect(url_for("login"))
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")
def callback():
try:
# Get authorization code Google sent back to you
code = request.args.get("code")
try:
# Get authorization code Google sent back to you
code = request.args.get("code")
google_provider_cfg = get_google_provider_cfg()
token_endpoint = google_provider_cfg["token_endpoint"]
google_provider_cfg = get_google_provider_cfg()
token_endpoint = google_provider_cfg["token_endpoint"]
token_url, headers, body = client.prepare_token_request(
token_endpoint,
authorization_response=request.url,
redirect_url=request.base_url,
code=code
)
token_response = requests.post(
token_url,
headers=headers,
data=body,
auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
)
token_url, headers, body = client.prepare_token_request(
token_endpoint, authorization_response=request.url, redirect_url=request.base_url, 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"]
uri, headers, body = client.add_token(userinfo_endpoint)
userinfo_response = requests.get(uri, headers=headers, data=body)
userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
uri, headers, body = client.add_token(userinfo_endpoint)
userinfo_response = requests.get(uri, headers=headers, data=body)
if userinfo_response.json().get("email_verified"):
unique_id = userinfo_response.json()["sub"]
users_email = userinfo_response.json()["email"]
users_name = userinfo_response.json()["given_name"]
else:
return "User email not available or not verified by Google.", 400
if userinfo_response.json().get("email_verified"):
unique_id = userinfo_response.json()["sub"]
users_email = userinfo_response.json()["email"]
users_name = userinfo_response.json()["given_name"]
else:
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))
user = database.get_user(users_email)
current_app.logger.info("user data from google: " + str(data))
user = database.get_user(users_email)
if not user:
user = database.add_user(data)
current_app.logger.info("new user: {} created".format(users_email))
if not user:
user = database.add_user(data)
current_app.logger.info("new user: {} created".format(users_email))
current_app.logger.info("email: "+str(user.email))
current_app.logger.info("username: "+str(user.username))
current_app.logger.info("authenticated: "+str(user.is_authenticated))
current_app.logger.info("active: "+str(user.is_active))
current_app.logger.info("id: "+str(user.get_id()))
login_user(user, remember=True, duration=datetime.timedelta(days=7), force=True)
current_app.logger.info("email: " + str(user.email))
current_app.logger.info("username: " + str(user.username))
current_app.logger.info("authenticated: " + str(user.is_authenticated))
current_app.logger.info("active: " + str(user.is_active))
current_app.logger.info("id: " + str(user.get_id()))
login_user(user, remember=True, duration=datetime.timedelta(days=7), force=True)
return redirect(url_for("home"))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
return redirect(request.args.get("state"))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
@app.route("/logout")
def logout():
try:
logout_user()
return redirect(url_for("login"))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
try:
logout_user()
return redirect(url_for("login"))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
@app.route("/")
def root():
return redirect(url_for("home"))
return redirect(url_for("home"))
@app.route("/home")
@login_required
def home():
try:
return render_template("home.html", title="Home", current_user=current_user)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
try:
return render_template("home.html", title="Home", current_user=current_user)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
@app.after_request
def apply_headers(response: Response):
try:
user_name = "anonymous"
if current_user:
user_name = getattr(current_user, "email", "anonymous")
response.set_cookie("rpi_name", user_name)
return response
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
try:
user_name = "anonymous"
if current_user:
user_name = getattr(current_user, "email", "anonymous")
response.set_cookie("rpi_name", user_name)
response.headers.set("email", user_name)
return response
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
@app.route("/music")
@login_required
def music():
return "No music"
return "No music"
@app.errorhandler(404)
def resource_not_found(e):
try:
return render_template("404.html"), 404
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
try:
return render_template("404.html"), 404
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(e)
@login_manager.unauthorized_handler
def handle_unauthorized():
temp = login()
return temp, 401
@app.errorhandler(Exception)
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)
@ -351,5 +392,5 @@ comics.Comics.register_error_handler(Exception, handle_exception)
admin.Admin.register_error_handler(Exception, handle_exception)
if __name__ == '__main__':
app.run()
if __name__ == "__main__":
app.run()

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,8 @@
import os
import sqlite3
from io import BytesIO
from wand.image import Image
import sqlite3, os
from wand.image import Image
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):
new_image = image
orig_height = new_image.height
orig_width = new_image.width
if orig_height >= orig_width:
width = int((orig_width/orig_height) * new_height)
height = new_height
else:
height = int((orig_height/orig_width) * new_width)
width = new_width
new_image.thumbnail(width, height)
return new_image
new_image = image
orig_height = new_image.height
orig_width = new_image.width
if orig_height >= orig_width:
width = int((orig_width / orig_height) * new_height)
height = new_height
else:
height = int((orig_height / orig_width) * new_width)
width = new_width
new_image.thumbnail(width, height)
return new_image
def fix_thumbnails():
new_height = 256
new_width = 256
print("Start fix thumbnail size")
rows = db.execute("SELECT * FROM comic_thumbnails")
print("got list of all thumbnails\n")
new_height = 256
new_width = 256
print("Start fix thumbnail size")
rows = db.execute("SELECT * FROM comic_thumbnails")
print("got list of all thumbnails\n")
for row in rows:
image = Image(file=BytesIO(row["image"]))
if image.width > new_width or image.height > new_height:
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.commit()
for row in rows:
image = Image(file=BytesIO(row["image"]))
if image.width > new_width or image.height > new_height:
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.commit()
fix_thumbnails()

View File

@ -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 json
import os
import pathlib
import re
from datetime import timedelta
from io import BytesIO
import enzyme
import requests
from blinker import Namespace
from comicapi import comicarchive
from flask import current_app
from wand.image import Image
from scripts import database
@ -22,6 +24,8 @@ games_loaded = rpi_signals.signal("games_loaded")
publishers_to_ignore = ["***REMOVED***"]
API_KEY = "***REMOVED***"
# Directories
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():
total_comics = 0
comics_in_db = 0
comics_added = 0
meta = []
thumbnails = []
i = 0
for root, dirs, files in os.walk(COMICS_DIRECTORY):
for f in files:
if "temp" in root:
continue
if f.endswith(".cbr"):
total_comics += 1
path = os.path.join(root, f)
if not database.comic_path_in_db(path):
try:
test_path = path.encode("utf8")
except Exception as e:
current_app.logger.info("encoding failed on: "+path)
continue
archive = open_comic(path)
md = archive.readCIX()
if md.publisher in publishers_to_ignore:
continue
current_app.logger.info(path)
try:
meta.append((path, md))
thumbnails.append(get_comic_thumbnails(archive))
comics_added += 1
i += 1
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
continue
if i >= 2:
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
meta.clear()
thumbnails.clear()
i = 0
comics_in_db += 1
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("number of comics added: "+str(comics_added))
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
total_comics = 0
comics_in_db = 0
comics_added = 0
meta = []
thumbnails = []
i = 0
for root, dirs, files in os.walk(COMICS_DIRECTORY):
for f in files:
if "temp" in root:
continue
if f.endswith(".cbr"):
total_comics += 1
path = os.path.join(root, f)
if not database.comic_path_in_db(path):
try:
test_path = path.encode("utf8")
except Exception as e:
current_app.logger.info("encoding failed on: " + path)
continue
archive = open_comic(path)
md = archive.readCIX()
if md.publisher in publishers_to_ignore:
continue
current_app.logger.info(path)
try:
meta.append((path, md))
thumbnails.append(get_comic_thumbnails(archive))
comics_added += 1
i += 1
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
continue
if i >= 2:
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
meta.clear()
thumbnails.clear()
i = 0
comics_in_db += 1
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("number of comics added: " + str(comics_added))
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
def get_comic(path):
meta = []
thumbnails = []
if path.endswith(".cbr"):
if not database.comic_path_in_db(path):
try:
test_path = path.encode("utf8")
except Exception as e:
current_app.logger.info("encoding failed on: "+path)
return
archive = open_comic(path)
md = archive.readCIX()
if md.publisher in publishers_to_ignore:
return
current_app.logger.info(path)
meta.append((path, md))
try:
thumbnails.append(get_comic_thumbnails(archive))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
def get_comic(path: pathlib.Path):
meta = []
thumbnails = []
if path.suffix == ".cbr":
if not database.comic_path_in_db(str(path)):
try:
test_path = str(path).encode("utf8")
except Exception as e:
current_app.logger.info(f"encoding failed on: {path}")
return
archive = open_comic(str(path))
md = archive.readCIX()
if md.publisher in publishers_to_ignore:
return
current_app.logger.info(path)
meta.append((str(path), md))
try:
thumbnails.append(get_comic_thumbnails(archive))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
def get_comic_thumbnails(comic):
thumbnails = []
size = "256x256"
new_height = 256
new_width = 256
for page in range(comic.getNumberOfPages()):
image_bytes = BytesIO(comic.getPage(page))
image = Image(file=image_bytes)
orig_height = image.height
orig_width = image.width
if orig_height >= orig_width:
width = int((orig_width/orig_height) * new_height)
height = new_height
else:
height = int((orig_height/orig_width) * new_width)
width = new_width
image.thumbnail(width, height)
thumbnails.append((image.make_blob(), "image/"+image.format))
return thumbnails
thumbnails = []
size = "256x256"
new_height = 256
new_width = 256
for page in range(comic.getNumberOfPages()):
image_bytes = BytesIO(comic.getPage(page))
image = Image(file=image_bytes)
orig_height = image.height
orig_width = image.width
if orig_height >= orig_width:
width = int((orig_width / orig_height) * new_height)
height = new_height
else:
height = int((orig_height / orig_width) * new_width)
width = new_width
image.thumbnail(width, height)
thumbnails.append((image.make_blob(), "image/" + image.format))
return thumbnails
def open_comic(path):
archive = comicarchive.ComicArchive(path, default_image_path="static/images/icon.png")
return archive
archive = comicarchive.ComicArchive(path, default_image_path="static/images/icon.png")
return archive
def get_movies():
current_app.logger.info("start load movies")
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
movies = []
total_movies = 0
movies_in_db = 0
movies_added = 0
for root, dirs, files in os.walk(MOVIES_DIRECTORY):
for f in files:
if f.endswith(".mkv"):
total_movies += 1
path = os.path.join(root, f)
if not database.movie_path_in_db(path):
try:
match = re.match(pattern, f)
if not match:
current_app.logger.info(f+" did not match regex.")
continue
current_app.logger.info("movie path: "+path)
title = match.group("title")
current_app.logger.info("movie title: "+title)
year = int(match.group("year"))
extended = False
directors_cut = False
if match.group("extended"):
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"]
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)"
url = "https://api.themoviedb.org/3/search/movie"
movies = []
total_movies = 0
movies_in_db = 0
movies_added = 0
for root, dirs, files in os.walk(MOVIES_DIRECTORY):
for f in files:
if f.endswith(".mkv"):
total_movies += 1
path = os.path.join(root, f)
if not database.movie_path_in_db(path):
try:
match = re.match(pattern, f)
if not match:
current_app.logger.info(f + " did not match regex.")
continue
current_app.logger.info("movie path: " + path)
title = match.group("title")
current_app.logger.info("movie title: " + title)
year = int(match.group("year"))
extended = True if match.group("extended") else False
directors_cut = True if match.group("directors_cut") else False
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
if not tmdb_data:
current_app.logger.info("could not get tmdb data")
continue
tmdb_id = tmdb_data[0]
description = tmdb_data[1]
poster_path = tmdb_data[2]
backdrop_path = tmdb_data[3]
movies_added += 1
data = {
"api_key": API_KEY,
"query": title,
"primary_release_year": year,
"language": "en-US",
}
r = requests.get(url, params=data)
if len(r.json()["results"]) == 0:
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))
if len(movies) >= 20:
movie_loaded.send("anonymous", movies=movies.copy())
movies.clear()
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
# print(e)
movies_in_db += 1
movie_loaded.send("anonymous", movies=movies)
current_app.logger.info("finish load 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))
tmdb_id = info["id"]
description = info["overview"]
poster_path = info["poster_path"]
backdrop_path = info["backdrop_path"]
movies_added += 1
movies.append((path, tmdb_id, title, year, description, extended, directors_cut, poster_path, backdrop_path,))
if len(movies) >= 20:
movie_loaded.send("anonymous", movies=movies.copy())
movies.clear()
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
# 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):
pattern = r"(?P<title>.+) \((?P<year>\d+)\)(?P<extended>\(extended\))?(?P<directors_cut> Director's Cut)?(?P<extension>\.mkv)"
movies = []
if not database.movie_path_in_db(path):
try:
match = re.match(pattern, path)
if not match:
current_app.logger.info(path + " did not match regex.")
return
current_app.logger.info("movie path: " + path)
title = match.group("title")
current_app.logger.info("movie title: " + title)
year = int(match.group("year"))
extended = False
directors_cut = False
if match.group("extended"):
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"]
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)"
url = "https://api.themoviedb.org/3/search/movie"
movies = []
if not database.movie_path_in_db(str(path)):
try:
match = re.match(pattern, path.name)
if not match:
current_app.logger.info(f"{path.name} did not match regex.")
return
current_app.logger.info(f"movie path: {path}")
title = match.group("title")
current_app.logger.info("movie title: " + title)
year = int(match.group("year"))
extended = match.group("extended") is True
directors_cut = match.group("directors_cut") is True
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
if not tmdb_data:
current_app.logger.info("could not get tmdb data")
return
tmdb_id = tmdb_data[0]
description = tmdb_data[1]
poster_path = tmdb_data[2]
backdrop_path = tmdb_data[3]
data = {
"api_key": API_KEY,
"query": title,
"primary_release_year": year,
"language": "en-US",
}
r = requests.get(url, params=data)
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,
poster_path, backdrop_path))
movie_loaded.send("anonymous", movies=movies.copy())
movies.clear()
current_app.logger.info("finish load movie")
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
tmdb_id = info["id"]
description = info["overview"]
poster_path = info["poster_path"]
backdrop_path = info["backdrop_path"]
movies.append((str(path), tmdb_id, title, year, description, extended, directors_cut, poster_path, backdrop_path,))
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():
dir_pattern = r"(?P<title>.+) \((?P<year>\d+)\)"
for dir in sorted(os.listdir(TV_SHOWS_DIRECTORY)):
dir_match = re.match(dir_pattern, dir)
if dir_match:
path = TV_SHOWS_DIRECTORY+dir
if not database.tv_show_path_in_db(path):
info = {}
if os.path.exists(path+"/info.json"):
with open(path+"/info.json") as f:
info = json.load(f)
series_name = dir_match.group("title")
series_year = int(dir_match.group("year"))
imdb_data = database.imdb_get_tv_show(series_name, series_year, info)
if not imdb_data:
current_app.logger.info("could not get imdb data for:"+series_name+" "+str(series_year))
# print("could not get imdb data for:", series_name, series_year)
continue
imdb_id = imdb_data["tconst"]
tmdb_data = database.tmdb_get_tv_show_by_imdb_id(imdb_id)
if not tmdb_data:
current_app.logger.info("could not get tmdb data for:" + series_name + " " + str(series_year))
# print("could not get tmdb data for:", series_name, series_year)
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")
continue
tmdb_id = tmdb_data[0]
description = tmdb_data[1]
poster_path = tmdb_data[2]
tv_show_data = (imdb_id, 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 load tv shows.")
dir_pattern = r"(?P<title>.+) \((?P<year>\d+)\)"
search_url = "https://api.themoviedb.org/3/search/tv"
tv_url = "https://api.themoviedb.org/3/tv/"
current_app.logger.info("start loading tv shows")
for dir in sorted(os.listdir(TV_SHOWS_DIRECTORY)):
dir_match = re.match(dir_pattern, dir)
if dir_match:
path = TV_SHOWS_DIRECTORY + dir
if not database.tv_show_path_in_db(path):
json_info = {}
if os.path.exists(path + "/info.json"):
with open(path + "/info.json") as f:
json_info = json.load(f)
series_name = dir_match.group("title")
series_year = int(dir_match.group("year"))
if not json_info:
data = {
"api_key": API_KEY,
"query": series_name,
"first_air_date_year": series_year,
"language": "en-US",
}
r = requests.get(search_url, params=data)
if len(r.json()["results"]) == 0:
current_app.logger.info(f"no tv show results for {series_name} - ({series_year})")
continue
info = r.json()["results"][0]
else:
data = {"api_key": API_KEY, "language": "en-US"}
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():
try:
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mp4|.mkv)"
rows = database.get_all_tv_shows()
for tv_show in rows:
episodes = []
for video in sorted(os.listdir(tv_show.path)):
video_match = re.match(video_pattern, video)
if video_match:
path = os.path.join(tv_show.path, video)
if not database.tv_episode_path_in_db(path):
season = int(video_match.group("season"))
episode = int(video_match.group("episode"))
episode_name = video_match.group("title")
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
if not episode_imdb_data:
current_app.logger.info("could not get imdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
continue
episode_imdb_id = episode_imdb_data["tconst"]
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
if not episode_tmdb_data:
current_app.logger.info("could not get tmdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
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_show.year) + " " + str(season) + " " + str(episode) + "\n")
continue
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 episodes")
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mkv)"
rows = database.get_all_tv_shows()
current_app.logger.info("start loading tv episodes")
for tv_show in rows:
try:
episodes = []
for video in sorted(os.listdir(tv_show.path)):
video_match = re.match(video_pattern, video)
if video_match:
path = os.path.join(tv_show.path, video)
if not database.tv_episode_path_in_db(path):
season = int(video_match.group("season"))
episode = int(video_match.group("episode"))
episode_name = video_match.group("title")
current_app.logger.info(f"S{season} E{episode} - {tv_show.title}: {episode_name}")
url = f"https://api.themoviedb.org/3/tv/{tv_show.tmdb_id}/season/{season}/episode/{episode}"
data = {"api_key": API_KEY, "language": "en-US"}
r = requests.get(url, params=data)
if "status_code" in r.json().keys():
current_app.logger.info(f"no tv episode results for S{season} E{episode} - {tv_show.title}: {episode_name}")
continue
info = r.json()
episode_tmdb_id = info["id"]
episode_description = info["overview"]
episode_still_path = info["still_path"]
episodes.append(
(episode_tmdb_id, tv_show.tmdb_id, episode_name, season, episode, episode_description, episode_still_path, path,)
)
if len(episodes) >= 10:
tv_episodes_loaded.send("anonymous", tv_episodes=episodes.copy())
episodes.clear()
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
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):
folder, name = os.path.split(path)
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mp4|.mkv)"
video_match = re.match(video_pattern, name)
if video_match:
rows = database.get_all_tv_shows()
for tv_show in rows:
if folder == tv_show.path:
if not database.tv_episode_path_in_db(path):
episodes = []
season = int(video_match.group("season"))
episode = int(video_match.group("episode"))
episode_name = video_match.group("title")
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
if not episode_imdb_data:
current_app.logger.info(
"could not get imdb data for: " + tv_show.title + " " + str(tv_show.year) + " " + str(
season) + " " + str(episode))
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
return
episode_imdb_id = episode_imdb_data["tconst"]
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
if not episode_tmdb_data:
current_app.logger.info(
"could not get tmdb data for: " + tv_show.title + " " + str(tv_show.year) + " " + str(
season) + " " + str(episode))
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_show.year) + " " + str(season) + " " + str(episode) + "\n")
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_tv_episode(path: pathlib.Path):
video_pattern = r"S(?P<season>\d+)E(?P<episode>\d+) - (?P<title>.+)(?P<extension>.mkv)"
video_match = re.match(video_pattern, path.name)
if video_match:
rows = database.get_all_tv_shows()
for tv_show in rows:
if path.parent == tv_show.path:
if not database.tv_episode_path_in_db(str(path)):
episodes = []
season = int(video_match.group("season"))
episode = int(video_match.group("episode"))
episode_name = video_match.group("title")
url = f"https://api.themoviedb.org/3/tv/{tv_show.tmdb_id}/season/{season}/episode/{episode}"
data = {"api_key": API_KEY, "language": "en-US"}
r = requests.get(url, params=data)
if "status_code" in r.json().keys():
current_app.logger.info(f"no tv episode results for S{season} E{episode} - {tv_show.title}: {episode_name}")
continue
info = r.json()
episode_tmdb_id = info["id"]
episode_description = info["overview"]
episode_still_path = info["still_path"]
episodes.append(
(episode_tmdb_id, tv_show.tmdb_id, episode_name, season, episode, episode_description, episode_still_path, str(path),)
)
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
current_app.logger.info("finished loading tv episode")
def get_chapters(path):
try:
with open(path, 'rb') as f:
mkv = enzyme.MKV(f)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
mkv_info = {}
for chapter in mkv.chapters:
if chapter.string == "Intro":
mkv_info["intro"] = {
"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 == "end-credit scene":
if "end-credit scene" not in mkv_info.keys():
mkv_info["end-credit scene"] = []
end_credit = {"start": chapter.start.seconds}
if chapter.end:
end_credit["end"] = timedelta(microseconds=chapter.end//1000).seconds
mkv_info["end-credit scene"].append(end_credit)
return mkv_info
try:
with open(path, "rb") as f:
mkv = enzyme.MKV(f)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return {}
mkv_info = {}
for chapter in mkv.chapters:
if chapter.string == "Intro":
mkv_info["intro"] = {
"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 == "end-credit scene":
if "end-credit scene" not in mkv_info.keys():
mkv_info["end-credit scene"] = []
end_credit = {"start": chapter.start.seconds}
if chapter.end:
end_credit["end"] = timedelta(microseconds=chapter.end // 1000).seconds
mkv_info["end-credit scene"].append(end_credit)
return mkv_info
def get_tags(path):
try:
with open(path, 'rb') as f:
mkv = enzyme.MKV(f)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
mkv_info = {}
for tag in mkv.tags:
if tag.targets.data[0].data == 70:
mkv_info["collection"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["collection"]["title"] = simple.string
if simple.name == "TOTAL_PARTS":
mkv_info["collection"]["episodes"] = int(simple.string)
if simple.name == "KEYWORDS":
mkv_info["collection"]["key_words"] = simple.string.split(",")
if simple.name == "DATE_RELEASED":
mkv_info["collection"]["year"] = int(simple.string)
if simple.name == "SUMMARY":
mkv_info["collection"]["summary"] = simple.string
if tag.targets.data[0].data == 60:
mkv_info["season"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["season"]["title"] = simple.string
if simple.name == "TOTAL_PARTS":
mkv_info["season"]["episodes"] = int(simple.string)
if tag.targets.data[0].data == 50:
mkv_info["movie"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["movie"]["title"] = simple.string
if simple.name == "DATE_RELEASED":
mkv_info["movie"]["year"] = int(simple.string)
if simple.name == "PART_NUMBER":
mkv_info["movie"]["episode"] = int(simple.string)
if simple.name == "KEYWORDS":
mkv_info["movie"]["key_words"] = simple.string.split(",")
if simple.name == "SUMMARY":
mkv_info["movie"]["summary"] = simple.string
return mkv_info
try:
with open(path, "rb") as f:
mkv = enzyme.MKV(f)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
mkv_info = {}
for tag in mkv.tags:
if tag.targets.data[0].data == 70:
mkv_info["collection"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["collection"]["title"] = simple.string
if simple.name == "TOTAL_PARTS":
mkv_info["collection"]["episodes"] = int(simple.string)
if simple.name == "KEYWORDS":
mkv_info["collection"]["key_words"] = simple.string.split(",")
if simple.name == "DATE_RELEASED":
mkv_info["collection"]["year"] = int(simple.string)
if simple.name == "SUMMARY":
mkv_info["collection"]["summary"] = simple.string
if tag.targets.data[0].data == 60:
mkv_info["season"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["season"]["title"] = simple.string
if simple.name == "TOTAL_PARTS":
mkv_info["season"]["episodes"] = int(simple.string)
if tag.targets.data[0].data == 50:
mkv_info["movie"] = {}
for simple in tag.simpletags:
if simple.name == "TITLE":
mkv_info["movie"]["title"] = simple.string
if simple.name == "DATE_RELEASED":
mkv_info["movie"]["year"] = int(simple.string)
if simple.name == "PART_NUMBER":
mkv_info["movie"]["episode"] = int(simple.string)
if simple.name == "KEYWORDS":
mkv_info["movie"]["key_words"] = simple.string.split(",")
if simple.name == "SUMMARY":
mkv_info["movie"]["summary"] = simple.string
return mkv_info
def get_games():
games = []
cover_url = "https://api-v3.igdb.com/covers"
games_url = "https://api-v3.igdb.com/games"
headers = {
"accept": "application/json",
"user-key": "641f7f0e3af5273dcc1105ce851ea804"
}
i = 0
for folder in sorted(os.listdir(GAMES_DIRECTORY), key=str.casefold):
root = os.path.join(GAMES_DIRECTORY, folder)
if os.path.isdir(os.path.join(root)):
path = os.path.join(root, "info.json")
with open(path, "r") as f:
info = json.load(f)
game_id = info["id"]
if not database.game_in_db(game_id):
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 = None
mac = None
linux = None
if "windows" in info.keys():
windows = info["windows"]
if "mac" in info.keys():
mac = info["mac"]
if "linux" in info.keys():
linux = info["linux"]
game = (info["name"], game_id, description, poster_path, windows, mac, linux)
games.append(game)
i += 1
if i >= 5:
games_loaded.send("anonymous", games=games.copy())
games.clear()
i = 0
games_loaded.send("anonymous", games=games)
current_app.logger.info("finished loading games")
games = []
cover_url = "https://api-v3.igdb.com/covers"
games_url = "https://api-v3.igdb.com/games"
headers = {
"accept": "application/json",
"user-key": "641f7f0e3af5273dcc1105ce851ea804",
}
i = 0
current_app.logger.info("start loading games")
for folder in sorted(os.listdir(GAMES_DIRECTORY), key=str.casefold):
root = os.path.join(GAMES_DIRECTORY, folder)
if os.path.isdir(os.path.join(root)):
try:
path = os.path.join(root, "info.json")
with open(path, "r") as f:
info = json.load(f)
game_id = info["id"]
if not database.game_in_db(game_id):
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,
root,
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))

View File

@ -1,4 +1,6 @@
import sqlite3, subprocess, os
import os
import sqlite3
import subprocess
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/"
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():
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(["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")
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(
["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():
print("start import csv")
f = open("import_csv.sql").read()
sql_script = f.format(CSV_DIRECTORY)
subprocess.run(["sudo", "-u", "http", "sqlite3", IMDB_DATABASE+"imdb.db"], input=sql_script.encode("utf8"))
print("end import csv")
print("start import csv")
f = open("import_csv.sql").read()
sql_script = f.format(CSV_DIRECTORY)
subprocess.run(["sudo", "-u", "http", "sqlite3", IMDB_DATABASE + "imdb.db"], input=sql_script.encode("utf8"))
print("end import csv")
create_csv_files()

View File

@ -1,7 +1,8 @@
from flask import current_app
import requests
import inspect
import requests
from flask import current_app
API_KEY = "***REMOVED***"
TMDB_FIND_URL = "https://api.themoviedb.org/3/find/"
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):
try:
data = {
"api_key": API_KEY,
"language": "en-US",
"external_source": "imdb_id"
}
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
info = dict(r.json())
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"]))
return None
if info["movie_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
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"]
try:
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
info = dict(r.json())
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"]))
return None
if info["movie_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
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
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return movie_id, overview, poster_path, backdrop_path
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def get_tv_show_data(imdb_id):
try:
data = {
"api_key": API_KEY,
"language": "en-US",
"external_source": "imdb_id"
}
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
info = dict(r.json())
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"]))
return None
if info["tv_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
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"]
try:
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
info = dict(r.json())
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"]))
return None
if info["tv_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
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
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return tv_show_id, overview, poster_path
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
def get_tv_episode_data(imdb_id):
try:
data = {
"api_key": API_KEY,
"language": "en-US",
"external_source": "imdb_id"
}
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
episode_info = dict(r.json())
if "status_code" in episode_info.keys():
current_app.logger.info("error getting tmdb tv episode data, status code: " + str(episode_info["status_code"])+" "+str(episode_info["status_message"]))
return None
if episode_info["tv_episode_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
data = {
"api_key": API_KEY,
"language": "en-US"
}
r = requests.get(TMDB_GET_TV_URL+str(episode_info["tv_episode_results"][0]["show_id"]), params=data)
show_name = dict(r.json())["name"]
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"]
try:
data = {"api_key": API_KEY, "language": "en-US", "external_source": "imdb_id"}
r = requests.get(TMDB_FIND_URL + imdb_id, params=data)
episode_info = dict(r.json())
if "status_code" in episode_info.keys():
current_app.logger.info(
"error getting tmdb tv episode data, status code: " + str(episode_info["status_code"]) + " " + str(episode_info["status_message"])
)
return None
if episode_info["tv_episode_results"] == []:
current_app.logger.info("no tmdb results for: " + str(imdb_id))
return None
data = {"api_key": API_KEY, "language": "en-US"}
r = requests.get(TMDB_GET_TV_URL + str(episode_info["tv_episode_results"][0]["show_id"]), params=data)
show_name = dict(r.json())["name"]
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
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return tv_episode_id, overview, still_path
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))

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

View File

@ -61,7 +61,7 @@
</div>
<script>
var page_num = {{ page }};
var page_num = {% if page %}{{ page }}{% else %}1{% endif %};
var max_items = {{ max_items }};
var item_count = {{ item_count }};
var start = max_items*(page_num-1);
@ -74,6 +74,10 @@
var page_container = document.getElementById("page-container");
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;
start = max_items*(page_num-1);
if (item_count < max_items*page_num) {
@ -126,6 +130,7 @@
}
}
}
window.scrollTo(0, 0)
}
function offset_page(i) {

View File

@ -1,11 +1,13 @@
{% extends "base.html" %}
{% 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="{}">
<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'>
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>
@ -32,7 +34,7 @@
{% endif %}
{% endfor %}
<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 %}
{% 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-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 %}
{% 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">
<img src="/static/svg/verified.svg" >
</div>
@ -71,7 +73,7 @@
{% endfor %}
</div>
{% 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-red" style="height: 5px; width: {{ (data.time/data.length)*100 }}%"></div>
</div>
@ -83,6 +85,8 @@
</form>
</div>
</div>
<div class="w3-col s1 w3-hide-small m1 l2"><p></p></div>
</div>
{% endblock %}
@ -133,7 +137,7 @@
//length = myPlayer.duration();
let oReq = new XMLHttpRequest();
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();
time = myPlayer.currentTime();
}
@ -143,7 +147,7 @@
//length = myPlayer.duration();
let oReq = new XMLHttpRequest();
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();
time = myPlayer.currentTime();
});

View File

@ -16,8 +16,8 @@
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-10">
<div id="page-container" class="row justify-content-start"></div>
<div class="w3-container">
<div id="page-container" style="display: flow-root; text-align: center"></div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
@ -34,28 +34,42 @@
function populate_page() {
page_container.innerHTML = "";
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) {
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) {
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) {
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 = ``;
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">
<img src="/static/svg/verified.svg" >
</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}
<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'">
<div class="card-body">
${tv_shows[i][0].title} (${tv_shows[i][0].year})
</div>
<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'">
${text}
${finished}
${badge}
</div>
</a>
</div>`;

View File

@ -1,17 +1,19 @@
{% extends "base.html" %}
{% block content %}
<div class="container" 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-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 vjs-16-9" style="display: inline-block" controls preload="auto"
poster="https://image.tmdb.org/t/p/original{{ movie.backdrop_path }}" data-setup="{}">
{% 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 %}
<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 %}
<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 %}
<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 %}
<p class='vjs-no-js'>
To view this video please enable JavaScript, and consider upgrading to a web browser that
@ -20,7 +22,9 @@
</video>
<h1>{{ movie.title }}</h1>
<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>
{% endblock %}
@ -60,7 +64,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
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();
time = myPlayer.currentTime();
}
@ -70,7 +74,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
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();
time = myPlayer.currentTime();
});

View File

@ -16,9 +16,9 @@
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-10">
<div class="w3-container">
{% 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 %}
<h1>No results.</h1>
{% endif %}
@ -38,28 +38,42 @@
function populate_page() {
page_container.innerHTML = "";
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) {
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) {
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) {
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 = ``;
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">
<img src="/static/svg/verified.svg" >
</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}
<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'">
<div class="card-body">
${tv_shows[i][0].title} (${tv_shows[i][0].year})
</div>
<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'">
${text}
${finished}
${badge}
</div>
</a>
</div>`;

View File

@ -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 scripts import database, func
import inspect
import datetime
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")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
tv = database.get_all_tv_movies()
start = (max_items * (page - 1))
end = len(tv) if len(tv) < max_items * page else max_items * page
tv_dict = []
for tv_item in tv:
item = tv_item[0].__dict__
item.pop('_sa_instance_state', None)
item.pop('path', None)
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))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e))+" "+str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
tv = database.get_all_tv_movies()
start = max_items * (page - 1)
end = len(tv) if len(tv) < max_items * page else max_items * page
tv_dict = []
for tv_item in tv:
item = tv_item[0].__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
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)
)
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")
@login_required
def search():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
start = 0
end = 0
query = request.args.get("q")
tv = []
if query:
tv = database.db_search_tv_movie(query)
start = (max_items * (page - 1))
end = len(tv) if len(tv) < max_items * page else max_items * page
tv_dict = []
for tv_item in tv:
item = tv_item[0].__dict__
item.pop('_sa_instance_state', None)
item.pop('path', None)
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,
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))
return str(type(e))+" "+str(e)
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
start = 0
end = 0
query = request.args.get("q")
tv = []
if query:
tv = database.db_search_tv_movie(query)
start = max_items * (page - 1)
end = len(tv) if len(tv) < max_items * page else max_items * page
tv_dict = []
for tv_item in tv:
item = tv_item[0].__dict__
item.pop("_sa_instance_state", None)
item.pop("path", None)
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, 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))
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
def tv_movie_viewer(imdb_id):
try:
tv_movie = database.get_tv_movie_by_imdb_id(imdb_id)
if type(tv_movie) is database.Movie:
extended = request.args.get("extended", 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)
else:
return episode_viewer(imdb_id)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e))+" "+str(e)
def tv_movie_viewer(tmdb_id):
try:
tv_movie = database.get_tv_movie_by_tmdb_id(tmdb_id)
if type(tv_movie) is database.Movie:
extended = request.args.get("extended", default=False, type=bool)
directors_cut = request.args.get("directors_cut", default=False, type=bool)
return movie_view(tmdb_id, extended=extended, directors_cut=directors_cut)
else:
return episode_viewer(tmdb_id)
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
def movie_view(imdb_id, extended=False, directors_cut=False):
try:
if request.method == "POST":
time = int(request.args.get("time", type=float))
length = int(request.args.get("length", type=float, default=0))
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)
return make_response("", 201)
else:
movie_data = database.db_get_movie_by_imdb_id(imdb_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)
chapters = func.get_chapters(movie_data.path)
if not user_data:
user_data = database.update_user_tv_movie_data(movie_data.imdb_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)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
def movie_view(tmdb_id, extended=False, directors_cut=False):
try:
if request.method == "POST":
time = int(request.args.get("time", type=float))
length = int(request.args.get("length", type=float, default=0))
finished = True if request.args.get("finished", default="false") == "true" else False
database.update_user_tv_movie_data(tmdb_id, None, time, length, finished, extended, directors_cut)
return make_response("", 201)
else:
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.tmdb_id, extended=extended, directors_cut=directors_cut)
chapters = func.get_chapters(movie_data.path)
if not user_data:
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
)
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
def episode_viewer(imdb_id):
try:
if request.method == "POST":
time = int(request.args.get("time", type=float))
parent_id = request.args.get("parent", type=str)
length = int(request.args.get("length", type=float, default=0))
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)
return make_response("", 201)
else:
tv_show = database.get_tv_show(imdb_id)
episodes = database.get_tv_show_episodes_by_imdb_id(imdb_id)
season_num = request.args.get("season", 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)
if not season_num and not episode_num:
(current_episode, user_data) = database.db_get_current_tv_show_episode_and_data(imdb_id, episodes)
season_num = current_episode.season
episode_num = current_episode.episode
chapters = func.get_chapters(current_episode.path)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
else:
current_episode = episodes[0]
user_data = database.UserTvMovieData(("", "", "", 0, 0, False, datetime.datetime.min))
for episode in episodes:
if episode.season == season_num and episode.episode == episode_num:
current_episode = episode
user_data = database.db_get_user_tv_movie_data(current_episode.imdb_id)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
break
else:
for episode in episodes:
if episode.season == season_num:
current_episode = episode
episode_num = episode.episode
user_data = database.db_get_user_tv_movie_data(current_episode.imdb_id)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.imdb_id, imdb_id, 0, 0)
break
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)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
def episode_viewer(tmdb_id):
try:
if request.method == "POST":
time = int(request.args.get("time", type=float))
parent_id = request.args.get("parent", type=str)
length = int(request.args.get("length", type=float, default=0))
finished = True if request.args.get("finished", default="false") == "true" else False
database.update_user_tv_movie_data(tmdb_id, parent_id, time, length, finished)
return make_response("", 201)
else:
tv_show = database.get_tv_show(tmdb_id)
episodes = database.get_tv_show_episodes_by_tmdb_id(tmdb_id)
season_num = request.args.get("season", 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(tmdb_id)
if not season_num and not episode_num:
(current_episode, user_data) = database.db_get_current_tv_show_episode_and_data(tmdb_id, episodes)
season_num = current_episode.season
episode_num = current_episode.episode
chapters = func.get_chapters(current_episode.path)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
else:
current_episode = episodes[0]
user_data = database.UserTvMovieData(("", "", "", 0, 0, False, datetime.datetime.min, False, False))
for episode in episodes:
if episode.season == season_num and episode.episode == episode_num:
current_episode = episode
user_data = database.db_get_user_tv_movie_data(current_episode.tmdb_id)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
break
else:
for episode in episodes:
if episode.season == season_num:
current_episode = episode
episode_num = episode.episode
user_data = database.db_get_user_tv_movie_data(current_episode.tmdb_id)
if not user_data:
user_data = database.update_user_tv_movie_data(current_episode.tmdb_id, tmdb_id, 0, 0)
break
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,
)
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
def get_movie(imdb_id):
extended = request.args.get("extended", 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)
filename = movie_data.path.replace(func.MOVIES_DIRECTORY, "")
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response
def get_movie(tmdb_id):
extended = request.args.get("extended", default=False, type=bool)
directors_cut = request.args.get("directors_cut", default=False, type=bool)
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, "")
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response
@TV_Movies.route("/tv_movies/get_episode/<imdb_id>")
@TV_Movies.route("/tv_movies/get_episode/<tmdb_id>")
@login_required
def get_episode(imdb_id):
episode_data = database.db_get_episode_by_imdb_id(imdb_id)
filename = episode_data.path.replace(func.TV_SHOWS_DIRECTORY, "")
response = make_response(send_from_directory(func.TV_SHOWS_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response
def get_episode(tmdb_id):
episode_data = database.db_get_episode_by_tmdb_id(tmdb_id)
filename = episode_data.path.replace(func.TV_SHOWS_DIRECTORY, "")
response = make_response(send_from_directory(func.TV_SHOWS_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response