combined the tv and movies page into a single page

This commit is contained in:
Matthew Welch 2020-04-02 19:35:32 -07:00
parent 8b2e43b41d
commit c44de9b333
15 changed files with 381 additions and 353 deletions

View File

@ -1,114 +0,0 @@
from flask import Blueprint, render_template, request, make_response, send_from_directory, current_app
from flask_login import login_required
import inspect
from scripts import database, func
Movies = Blueprint("movies", __name__, template_folder="templates")
@Movies.route("/movies")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
movies = database.db_get_all_movies()
start = (max_items*(page-1))
end = len(movies) if len(movies) < max_items*page else max_items*page
return render_template("movies/index.html", title="Movies", movies=movies, page=page, max_items=max_items, start=start, end=end, item_count=len(movies))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Movies.route("/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")
results = []
if query:
results = database.db_search_movies(query)
start = (max_items*(page-1))
end = len(results) if len(results) < max_items*page else max_items*page
return render_template("movies/search.html", title="Movies", movies=results, page=page, max_items=max_items, start=start, end=end, item_count=len(results))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>", methods=["GET", "POST"])
@login_required
def movie_view(imdb_id):
try:
if request.method == "POST":
time = int(request.args.get("time", type=float))
length = int(request.args.get("length", type=float, default=0))
database.update_user_tv_movie_data(imdb_id, None, time, 0, True if length-time <= 15 else False)
return make_response("", 201)
else:
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
user_data = database.db_get_user_tv_movie_data(movie_data.imdb_id)
if not user_data:
user_data = database.update_user_tv_movie_data(movie_data.imdb_id, None, 0, 0)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data, user_data=user_data)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>/extended")
@login_required
def movie_view_extended(imdb_id):
try:
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Movies.route("/movies/<imdb_id>/directors_cut")
@login_required
def movie_view_directors_cut(imdb_id):
try:
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
return render_template("movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@Movies.route("/movies/get_movie/<imdb_id>")
@login_required
def get_movie(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response
@Movies.route("/movies/get_movie/<imdb_id>/extended")
@login_required
def get_movie_extended(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response
@Movies.route("/movies/get_movie/<imdb_id>/directors_cut")
@login_required
def get_movie_directors_cut(imdb_id):
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
response.headers["content-type"] = "video/webm"
return response

View File

@ -1,34 +0,0 @@
{% extends "base.html" %}
{% block nav %}
<nav class="navbar navbar-expand">
<ul class="navbar-nav mr-auto"></ul>
<form class="form-inline" method="get" action="/movies/search">
<div class="form-group mx-2">
<input type="text" class="form-control" minlength="3" name="q">
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
</nav>
{% endblock %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "movies/moviesList.html" %}
</div>
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}
{% block footer_content %}
<div class="container">
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
</div>
{% endblock footer_content %}

View File

@ -1,12 +0,0 @@
{% for i in range(start, end) %}
<div class="col-4" style="padding: 10px">
<a href="/movies/{{ movies[i].imdb_id }}{% if movies[i].extended == 1 %}/extended{% endif %}{% if movies[i].directors_cut==1 %}/directors_cut{% endif %}">
<div class="card">
<img class="card-img" src="https://image.tmdb.org/t/p/original{{ movies[i].poster_path }}" alt="" onerror="this.src='/static/images/default.png'">
<div class="card-body">
{{ movies[i].title }} ({{ movies[i].year }}) {% if movies[i].extended %}Extended Edition{% endif %}{% if movies[i].directors_cut %}Director's Cut{% endif %}
</div>
</div>
</a>
</div>
{% endfor %}

View File

@ -11,13 +11,13 @@ import inspect
import datetime
import requests
import json
import os
import scripts.func as func
from scripts import database
from admin import admin
from movies import movies
from comics import comics
from tv import tv
from tv_movies import tv_movies
class NullHandler(logging.Handler):
@ -45,8 +45,7 @@ def get_google_provider_cfg():
app = Flask(__name__)
app.register_blueprint(comics.Comics)
app.register_blueprint(admin.Admin)
app.register_blueprint(movies.Movies)
app.register_blueprint(tv.TV)
app.register_blueprint(tv_movies.TV_Movies)
app.config["SECRET_KEY"] = "***REMOVED***"
app.logger.setLevel("DEBUG")
@ -59,35 +58,37 @@ MOBILE_DEVICES = ["android", "blackberry", "ipad", "iphone"]
def get_comics():
with app.app_context():
func.get_comics()
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 = path+"/"+filename
if "IN_CLOSE_WRITE" in type_names:
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)
def get_movies():
with app.app_context():
func.get_movies()
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
if "IN_CLOSE_WRITE" in type_names:
func.get_movies()
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)
def get_tv_shows():
with app.app_context():
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
func.get_tv_shows()
func.get_tv_episodes()
i = inotify.adapters.InotifyTree(func.TV_SHOWS_DIRECTORY)
for event in i.event_gen(yield_nones=False):
(header, type_names, path, filename) = event
if "IN_CLOSE_WRITE" in type_names:
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_episodes()
func.get_tv_episode(file_path)
with app.app_context():

View File

@ -23,15 +23,12 @@ from comicapi.issuestring import IssueString
from scripts import tmdb
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/imdb.db"
RPI_USER_DATABASE = "/var/lib/rpiWebApp/users.db"
MC_DATABASE = "***REMOVED***database.db"
MC_IMDB_DATABASE = "***REMOVED***imdb.db"
MC_USER_DATABASE = "***REMOVED***users.db"
MC_IMDB_DATABASE = "/mnt/c/Users/Matthew/Documents/MyPrograms/Websites/rpi_web_interface/imdb.db"
MC_USER_DATABASE = "/mnt/c/Users/Matthew/Documents/MyPrograms/Websites/rpi_web_interface/users.db"
DATABASE = RPI_DATABASE if os.path.exists(RPI_DATABASE) else MC_DATABASE
IMDB_DATABASE = RPI_IMDB_DATABASE if os.path.exists(RPI_IMDB_DATABASE) else MC_IMDB_DATABASE
USER_DATABASE = RPI_USER_DATABASE if os.path.exists(RPI_USER_DATABASE) else MC_USER_DATABASE
@ -190,7 +187,7 @@ class TvEpisode(Base):
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
class DupComic(Comic):
class DupComic(Base):
__tablename__ = "duplicate_comics"
path = Column(String, unique=True)
@ -229,18 +226,13 @@ class DupComic(Comic):
characters = Column(String)
teams = Column(String)
locations = Column(String)
id = Column(Integer)
pk = Column(Integer, primary_key=True, autoincrement=True)
__mapper_args__ = {
"concrete": True
}
id = Column(Integer, primary_key=True, autoincrement=True)
def __init__(self, data):
i = 0
try:
for column in self.__table__.columns:
if column.name == "id" or column.name == "pk":
if column.name == "id":
continue
setattr(self, column.name, data[i])
i += 1
@ -288,6 +280,8 @@ class UserTvMovieData(Base):
length = Column(Integer)
finished = Column(Boolean, default=False)
time_stamp = Column(DateTime)
extended = Column(Boolean, default=False)
directors_cut = Column(Boolean, default=False)
def __init__(self, data):
i = 0
@ -337,10 +331,10 @@ def get_imdb():
return db
def update_user_tv_movie_data(imdb_id, parent_id, time, length, finished=False):
def update_user_tv_movie_data(imdb_id, parent_id, time, length, finished=False, extended=False, directors_cut=False):
session = Session()
email = current_user.email
user_data = session.query(UserTvMovieData).filter(UserTvMovieData.imdb_id == imdb_id, UserTvMovieData.user == email).one_or_none()
user_data = session.query(UserTvMovieData).filter(UserTvMovieData.imdb_id == imdb_id, UserTvMovieData.user == email, UserTvMovieData.extended == extended, UserTvMovieData.directors_cut == directors_cut).one_or_none()
if user_data:
user_data.time = time
user_data.finished = finished
@ -350,7 +344,7 @@ def update_user_tv_movie_data(imdb_id, parent_id, time, length, finished=False):
session.commit()
return user_data
else:
data = UserTvMovieData((email, imdb_id, parent_id, time, length, finished, datetime.datetime.now()))
data = UserTvMovieData((email, imdb_id, parent_id, time, length, finished, datetime.datetime.now(), extended, directors_cut))
session.add(data)
session.commit()
return data
@ -414,6 +408,9 @@ def add_comics(meta, thumbnails):
for comic_data, images in zip(data, thumbnails):
try:
comic = Comic(comic_data)
if comic.publisher is None:
dup_comics.append(comic_data)
continue
session.add(comic)
session.commit()
comic_id = session.query(Comic.id).order_by(Comic.id.desc()).first()[0]
@ -443,15 +440,15 @@ def db_get_all_comics():
def db_get_series_by_publisher(publisher):
session = Session()
result = [i[0] for i in session.query(Comic, over(func.rank(), partition_by=[Comic.publisher, Comic.series, Comic.seriesyear], order_by=[Comic.series, Comic.seriesyear])).filter(Comic.publisher == publisher).all()]
result = session.query(Comic).filter(Comic.publisher == publisher).order_by(Comic.series, Comic.seriesyear, Comic.issue).distinct(Comic.series).all()
series = result
return series
def db_get_comics_in_series(series, publisher, series_year):
session = Session()
result = session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesyear == series_year)\
.order_by(Comic.issue).all()
current_app.logger.info(str(session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesyear == series_year).order_by(Comic.issue)))
result = session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesyear == series_year).order_by(Comic.issue).all()
comics = result
return comics
@ -535,10 +532,15 @@ def imdb_get_movie(title, year):
return row
def imdb_get_tv_show(title, year):
row = get_imdb().execute(
"SELECT tconst FROM title_basics WHERE (originalTitle LIKE ? OR primaryTitle LIKE ?) AND (titleType LIKE 'tvSeries' OR titleType LIKE 'tvMiniSeries') AND startYear=?",
(title, title, year)).fetchone()
def imdb_get_tv_show(title, year, info={}):
if not info:
row = get_imdb().execute(
"SELECT tconst FROM title_basics WHERE (originalTitle LIKE ? OR primaryTitle LIKE ?) AND (titleType LIKE 'tvSeries' OR titleType LIKE 'tvMiniSeries') AND startYear=?",
(title, title, year)).fetchone()
else:
row = get_imdb().execute(
"SELECT tconst FROM title_basics WHERE originalTitle=? AND primaryTitle=? AND titleType=? AND startYear=? AND endYear=? AND runtimeMinutes=? AND genres=?",
(info["originalTitle"], info["primaryTitle"], info["titleType"], info["startYear"], info["endYear"], info["runtimeMinutes"], info["genres"])).fetchone()
return row
@ -567,6 +569,9 @@ def tmdb_get_tv_episode_by_imdb_id(imdb_id):
def db_get_all_movies():
session = Session()
movies = session.query(Movie).order_by(Movie.title, Movie.year).all()
if current_user:
email = current_user.email
movies = [(i, session.execute("SELECT rpiwebapp.is_movie_finished('{}', '{}')".format(i.imdb_id, email)).first()[0]) for i in movies]
return movies
@ -577,14 +582,56 @@ def db_get_movie_by_imdb_id(imdb_id, extended=False, directors_cut=False):
return result
def tv_movie_sort(a):
if type(a) is tuple:
return a[0].title
return a.title
def get_all_tv_movies():
session = Session()
movies = session.query(Movie).order_by(Movie.title, Movie.year).all()
shows = session.query(TvShow).order_by(TvShow.title, TvShow.year).all()
tv_movies = movies + shows
if current_user:
email = current_user.email
shows = [
(i, session.execute("SELECT rpiwebapp.is_tv_show_finished('{}', '{}')".format(i.imdb_id, email)).first()[0])
for i in shows]
movies = [
(i, session.execute("SELECT rpiwebapp.is_movie_finished('{}', '{}')".format(i.imdb_id, email)).first()[0])
for i in movies]
tv_movies = movies + shows
tv_movies = sorted(tv_movies, key=tv_movie_sort)
return tv_movies
def get_tv_movie_by_imdb_id(imdb_id, extended=False, directors_cut=False):
session = Session()
result = session.query(Movie).filter(Movie.imdb_id == imdb_id, Movie.extended == extended,
Movie.directors_cut == directors_cut).one_or_none()
if not result:
result = session.query(TvShow).filter(TvShow.imdb_id == imdb_id).one_or_none()
return result
def get_all_tv_shows():
session = Session()
result = session.query(TvShow).order_by(TvShow.title, TvShow.year).all()
email = current_user.email
shows = [(i, session.execute("SELECT rpiwebapp.is_tv_show_finished('{}', '{}')".format(i.imdb_id, email)).first()[0]) for i in result]
if current_user:
email = current_user.email
shows = [(i, session.execute("SELECT rpiwebapp.is_tv_show_finished('{}', '{}')".format(i.imdb_id, email)).first()[0]) for i in result]
else:
shows = result
return shows
def get_tv_show(imdb_id):
session = Session()
result = session.query(TvShow).filter(TvShow.imdb_id == imdb_id).one_or_none()
return result
def get_tv_show_episodes_by_imdb_id(imdb_id):
session = Session()
result = session.query(TvEpisode).filter(TvEpisode.parent_imdb_id == imdb_id).order_by(TvEpisode.season, TvEpisode.episode).all()
@ -597,10 +644,10 @@ def db_get_episode_by_imdb_id(imdb_id):
return result
def db_get_user_tv_movie_data(imdb_id):
def db_get_user_tv_movie_data(imdb_id, extended=False, directors_cut=False):
session = Session()
email = current_user.email
result = session.query(UserTvMovieData).filter(UserTvMovieData.user == email, UserTvMovieData.imdb_id == imdb_id).one_or_none()
result = session.query(UserTvMovieData).filter(UserTvMovieData.user == email, UserTvMovieData.imdb_id == imdb_id, UserTvMovieData.extended == extended, UserTvMovieData.directors_cut == directors_cut).one_or_none()
return result
@ -690,6 +737,10 @@ def db_search_movies(query):
for movie in results["year"]:
if movie not in movies:
movies.append(movie)
session = Session()
email = current_user.email
movies = [(i, session.execute("SELECT rpiwebapp.is_movie_finished('{}', '{}')".format(i.imdb_id, email)).first()[0]) for i in movies]
return movies
@ -705,7 +756,19 @@ def db_search_tv_shows(query):
for show in results["year"]:
if show not in tv_shows:
tv_shows.append(show)
return tv_shows
session = Session()
email = current_user.email
shows = [
(i, session.execute("SELECT rpiwebapp.is_tv_show_finished('{}', '{}')".format(i.imdb_id, email)).first()[0]) for
i in tv_shows]
return shows
def db_search_tv_movie(query):
movies = db_search_movies(query)
shows = db_search_tv_shows(query)
tv_movies = sorted(movies + shows, key=tv_movie_sort)
return tv_movies
def resize_image(image, new_width=256, new_height=256):

View File

@ -6,6 +6,7 @@ from io import BytesIO
from wand.image import Image
import os, re
import inspect
import json
from scripts import database
@ -26,11 +27,13 @@ RPI_VIDEOS_DIRECTORY = "/usb/storage/media/Videos/Videos/"
RPI_GAMES_DIRECTORY = "/usb/storage/media/games/"
RPI_MUSIC_DIRECTORY = "/usb/storage/media/Music/"
MC_COMICS_DIRECTORY = "C:\\Users\\Matthew\\Documents\\Comics"
MC_COMICS_DIRECTORY = "/mnt/c/Users/Matthew/Documents/Comics"
MC_MOVIES_DIRECTORY = "/mnt/c/Users/Matthew/Documents/Movies"
MC_TV_SHOWS_DIRECTORY = "/mnt/c/Users/Matthew/Documents/TV"
COMICS_DIRECTORY = RPI_COMICS_DIRECTORY if os.path.exists(RPI_COMICS_DIRECTORY) else MC_COMICS_DIRECTORY
MOVIES_DIRECTORY = RPI_MOVIES_DIRECTORY
TV_SHOWS_DIRECTORY = RPI_TV_SHOWS_DIRECTORY
MOVIES_DIRECTORY = RPI_MOVIES_DIRECTORY if os.path.exists(RPI_MOVIES_DIRECTORY) else MC_MOVIES_DIRECTORY
TV_SHOWS_DIRECTORY = RPI_TV_SHOWS_DIRECTORY if os.path.exists(RPI_TV_SHOWS_DIRECTORY) else MC_TV_SHOWS_DIRECTORY
#############
@ -193,16 +196,67 @@ def get_movies():
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"]
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]
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))
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+"/"
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)
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)
@ -232,7 +286,7 @@ def get_tv_episodes():
for video in sorted(os.listdir(tv_show.path)):
video_match = re.match(video_pattern, video)
if video_match:
path = tv_show.path + video
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"))
@ -256,7 +310,46 @@ def get_tv_episodes():
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.")
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))
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")

View File

@ -33,10 +33,7 @@
<a class="nav-link" href="{{ url_for("comics.index") }}">Comics</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for("movies.index") }}">Movies</a>
</li>
<li class="nav-item">
<a class="nav-link" href="{{ url_for("tv.index") }}">Tv</a>
<a class="nav-link" href="{{ url_for("tv_movies.index") }}">Tv & Movies</a>
</li>
</ul>
<ul class="navbar-nav">

View File

@ -1,38 +0,0 @@
{% extends "base.html" %}
{% block nav %}
<nav class="navbar navbar-expand">
<ul class="navbar-nav mr-auto"></ul>
<form class="form-inline" method="get" action="">
<div class="form-group mx-2">
<input type="text" class="form-control" minlength="3" name="q">
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
</nav>
{% endblock %}
{% block content %}
<div style="text-align: center">
{% include "pagination.html" %}
</div>
<div class="container col-7">
{% if movies != [] %}
<div class="row justify-content-start">
{% include "tv/tvShowList.html" %}
</div>
{% else %}
<h1>No results.</h1>
{% endif %}
</div>
<div style="text-align: center">
{% include "pagination.html" %}
</div>
{% endblock %}
{% block footer_content %}
<div class="container">
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
</div>
{% endblock footer_content %}

View File

@ -1,91 +0,0 @@
from flask import Blueprint, render_template, request, make_response, send_from_directory, current_app
from flask_login import login_required
from scripts import database
import inspect
import datetime
TV = Blueprint("tv", __name__, template_folder="templates")
@TV.route("/tv")
@login_required
def index():
try:
page = request.args.get("page", 1, type=int)
max_items = request.args.get("max_items", 30, type=int)
tv_shows = database.get_all_tv_shows()
start = (max_items * (page - 1))
end = len(tv_shows) if len(tv_shows) < max_items * page else max_items * page
return render_template("tv/index.html", title="Tv", tv_shows=tv_shows, page=page, max_items=max_items, start=start, end=end, item_count=len(tv_shows))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e))+" "+str(e)
@TV.route("/tv/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_shows = []
if query:
tv_shows = database.db_search_tv_shows(query)
start = (max_items * (page - 1))
end = len(tv_shows) if len(tv_shows) < max_items * page else max_items * page
return render_template("tv/search.html", title="Tv", tv_shows=tv_shows, page=page, max_items=max_items,
start=start, end=end, item_count=len(tv_shows))
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e))+" "+str(e)
@TV.route("/tv/<imdb_id>", methods=["GET", "POST"])
@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))
database.update_user_tv_movie_data(imdb_id, parent_id, time, length, True if length-time <= 15 else False)
return make_response("", 201)
else:
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
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.now()))
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)
return render_template("tv/episodeViewer.html", title="Tv", 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)
except Exception as e:
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
return str(type(e)) + " " + str(e)
@TV.route("/tv/get_episode/<imdb_id>")
@login_required
def get_episode(imdb_id):
episode_data = database.db_get_episode_by_imdb_id(imdb_id)
filename = "S{:02d}E{:02d} - {}.mkv".format(episode_data.season, episode_data.episode, episode_data.title)
dir = episode_data.path.replace(filename, "")
response = make_response(send_from_directory(dir, filename))
response.headers["content-type"] = "video/webm"
return response

View File

@ -5,7 +5,7 @@
<video id="player" class="video-js vjs-big-play-centered" style="display: inline-block" controls preload="auto" width="1100"
poster="https://image.tmdb.org/t/p/original{{ episode.still_path }}" data-setup="{}">
<source src="{{ url_for("tv.index") }}/get_episode/{{ episode.imdb_id }}" type="video/webm">
<source src="{{ url_for("tv_movies.index") }}/get_episode/{{ episode.imdb_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>
@ -31,7 +31,7 @@
{% endif %}
{% endfor %}
<p style="text-align: left">{{ episode.description }}</p>
<a class="btn btn-primary" href="{{ url_for("tv.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.imdb_id }}" download="{{ episode.title }}">Download</a>
{% with %}
{% set seasons = [] %}
@ -110,7 +110,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("POST", "https://rpi.narnian.us/tv/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length);
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length);
oReq.send();
time = myPlayer.currentTime();
}
@ -119,7 +119,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("POST", "https://rpi.narnian.us/tv/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length);
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ episode.imdb_id }}?time="+(time+5)+"&parent={{ episode.parent_imdb_id }}&length="+length);
oReq.send();
time = myPlayer.currentTime();
});

View File

@ -3,7 +3,7 @@
{% block nav %}
<nav class="navbar navbar-expand">
<ul class="navbar-nav mr-auto"></ul>
<form class="form-inline" method="get" action="/tv/search">
<form class="form-inline" method="get" action="/tv_movies/search">
<div class="form-group mx-2">
<input type="text" class="form-control" minlength="3" name="q">
</div>
@ -18,7 +18,7 @@
</div>
<div class="container col-7">
<div class="row justify-content-start">
{% include "tv/tvShowList.html" %}
{% include "tv_movies/tvMovieList.html" %}
</div>
</div>
<div style="text-align: center">

View File

@ -4,7 +4,15 @@
<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"
poster="https://image.tmdb.org/t/p/original{{ movie.backdrop_path }}" data-setup="{}">
<source src="{{ url_for("movies.index") }}/get_movie/{{ movie.imdb_id }}{% if movie.extended == 1 %}/extended{% endif %}{% if movie.directors_cut==1 %}/directors_cut{% endif %}" type="video/webm">
{% 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">
{% elif movie.extended %}
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_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">
{% else %}
<source src="{{ url_for("tv_movies.index") }}/get_movie/{{ movie.imdb_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
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
@ -12,7 +20,7 @@
</video>
<h1>{{ movie.title }}</h1>
<p style="text-align: left">{{ movie.description }}</p>
<a class="btn btn-primary" href="{{ url_for("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.imdb_id }}{% if movie.extended == 1 %}/extended{% endif %}{% if movie.directors_cut==1 %}/directors_cut{% endif %}" download="{{ movie.title }}">Download</a>
</div>
{% endblock %}
@ -41,7 +49,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("POST", "https://rpi.narnian.us/movies/{{ movie.imdb_id }}?time="+(time+5)+"&length="+length);
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.imdb_id }}?time="+(time+5)+"&length="+length{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
oReq.send();
time = myPlayer.currentTime();
}
@ -50,7 +58,7 @@
length = myPlayer.duration();
let oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("POST", "https://rpi.narnian.us/movies/{{ movie.imdb_id }}?time="+(time+5)+"&length="+length);
oReq.open("POST", "https://rpi.narnian.us/tv_movies/{{ movie.imdb_id }}?time="+(time+5)+"&length="+length{% if movie.extended %}+"&extended=True"{% endif %}{% if movie.directors_cut %}+"&directors_cut=True"{% endif %});
oReq.send();
time = myPlayer.currentTime();
});

View File

@ -19,7 +19,7 @@
<div class="container col-7">
{% if movies != [] %}
<div class="row justify-content-start">
{% include "movies/moviesList.html" %}
{% include "tv_movies/tvMovieList.html" %}
</div>
{% else %}
<h1>No results.</h1>

View File

@ -1,6 +1,14 @@
{% for i in range(start, end) %}
<div class="col-4" style="padding: 10px">
<a href="/tv/{{ tv_shows[i][0].imdb_id }}">
{% if tv_shows[i][0].extended and tv_shows[i][0].directors_cut %}
<a href="/tv_movies/{{ tv_shows[i][0].imdb_id }}?extended=True&directors_cut=True">
{% elif tv_shows[i][0].extended %}
<a href="/tv_movies/{{ tv_shows[i][0].imdb_id }}?extended=True">
{% elif tv_shows[i][0].directors_cut %}
<a href="/tv_movies/{{ tv_shows[i][0].imdb_id }}?directors_cut=True">
{% else %}
<a href="/tv_movies/{{ tv_shows[i][0].imdb_id }}">
{% endif %}
<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">

147
tv_movies/tv_movies.py Normal file
View File

@ -0,0 +1,147 @@
from flask import Blueprint, render_template, request, make_response, send_from_directory, current_app
from flask_login import login_required
from scripts import database, func
import inspect
import datetime
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
return render_template("tv_movies/index.html", title="tv_movies", tv_shows=tv, 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_shows = []
if query:
tv_shows = database.db_search_tv_movie(query)
start = (max_items * (page - 1))
end = len(tv_shows) if len(tv_shows) < max_items * page else max_items * page
return render_template("tv_movies/search.html", title="tv_movies", tv_shows=tv_shows, page=page, max_items=max_items,
start=start, end=end, item_count=len(tv_shows))
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"])
@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)
@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))
database.update_user_tv_movie_data(imdb_id, None, time, 0, True if length-time <= 15 else False, 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)
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)
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))
database.update_user_tv_movie_data(imdb_id, parent_id, time, length, True if length-time <= 15 else False)
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
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.now()))
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
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)
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>")
@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
@TV_Movies.route("/tv_movies/get_episode/<imdb_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