Added user data and Google OAuth
Added initial implementation of user data for tv shows and movies as well as OAuth for Google sign in.
@ -1,9 +1,7 @@
|
|||||||
from flask import Blueprint, flash, redirect, url_for, render_template
|
from flask import Blueprint, flash, redirect, url_for, render_template
|
||||||
from flask_login import login_required, current_user
|
from flask_login import login_required, current_user
|
||||||
from sqlite_web import sqlite_web
|
|
||||||
|
|
||||||
Admin = Blueprint("admin", __name__, template_folder="templates")
|
Admin = Blueprint("admin", __name__, template_folder="templates")
|
||||||
login_required(sqlite_web.index)
|
|
||||||
|
|
||||||
|
|
||||||
@Admin.route("/admin")
|
@Admin.route("/admin")
|
||||||
|
@ -26,7 +26,6 @@ def index():
|
|||||||
return render_template("comics/index.html", title="Comics", publishers=publishers, page=page, max_items=max_items, start=start, end=end, item_count=len(publishers))
|
return render_template("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:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -70,7 +69,6 @@ def search():
|
|||||||
publisher_end=publisher_end, series_end=series_end, comics_end=comics_end)
|
publisher_end=publisher_end, series_end=series_end, comics_end=comics_end)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return str(type(e))+" "+str(e)
|
return str(type(e))+" "+str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -102,7 +100,6 @@ def comics_publisher(publisher):
|
|||||||
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
|
start=start, end=end, page=page, max_items=max_items, item_count=len(publisher_series))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -115,7 +112,7 @@ def comic_viewer(publisher, series, series_year, issue):
|
|||||||
series_parsed = parse.quote(series)
|
series_parsed = parse.quote(series)
|
||||||
page_number = int(request.args.get("pageNumber"))
|
page_number = int(request.args.get("pageNumber"))
|
||||||
meta = database.db_get_comic(publisher, series, series_year, issue)
|
meta = database.db_get_comic(publisher, series, series_year, issue)
|
||||||
page_count = int(meta["pageCount"])
|
page_count = int(meta.pageCount)
|
||||||
|
|
||||||
prev_page = page_number - 1
|
prev_page = page_number - 1
|
||||||
next_page = page_number + 1
|
next_page = page_number + 1
|
||||||
@ -125,11 +122,10 @@ def comic_viewer(publisher, series, series_year, issue):
|
|||||||
prev_page = page_count - 1
|
prev_page = page_count - 1
|
||||||
prev_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, prev_page)
|
prev_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, prev_page)
|
||||||
next_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, next_page)
|
next_url = "/comics/{}?series={}&seriesYear={}&issue={}&pageNumber={}".format(publisher_parsed, series_parsed, series_year, issue, next_page)
|
||||||
title = "Comics: "+meta["series"]+": #"+meta["issueText"]+" "+(meta["title"] or "")
|
title = "Comics: "+meta.series+": #"+meta.issueText+" "+(meta.title or "")
|
||||||
return render_template("comics/comicView.html", title=title, on_mobile=on_mobile, prev_url=prev_url, next_url=next_url, comic=meta, page_number=page_number)
|
return render_template("comics/comicView.html", title=title, on_mobile=on_mobile, prev_url=prev_url, next_url=next_url, comic=meta, page_number=page_number)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -139,11 +135,10 @@ def comic_gallery(publisher, series, series_year, issue):
|
|||||||
max_items = request.args.get("max_items", 30, type=int)
|
max_items = request.args.get("max_items", 30, type=int)
|
||||||
meta = database.db_get_comic(publisher, series, series_year, issue)
|
meta = database.db_get_comic(publisher, series, series_year, issue)
|
||||||
start = (max_items*(page-1))
|
start = (max_items*(page-1))
|
||||||
end = meta["pageCount"] if meta["pageCount"] < max_items*page else max_items*page
|
end = meta.pageCount if meta.pageCount < max_items*page else max_items*page
|
||||||
return render_template("comics/comicGallery.html", title="Comics", comic=meta, start=start, end=end, page=page, max_items=max_items, item_count=meta["pageCount"])
|
return render_template("comics/comicGallery.html", title="Comics", comic=meta, start=start, end=end, page=page, max_items=max_items, item_count=meta.pageCount)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -151,12 +146,12 @@ def comic_gallery(publisher, series, series_year, issue):
|
|||||||
@login_required
|
@login_required
|
||||||
def get_comic_page(comic_id, page_number):
|
def get_comic_page(comic_id, page_number):
|
||||||
meta = database.db_get_comic_by_id(comic_id)
|
meta = database.db_get_comic_by_id(comic_id)
|
||||||
comic = func.open_comic(meta["path"])
|
comic = func.open_comic(meta.path)
|
||||||
byte_image = BytesIO(comic.getPage(page_number))
|
byte_image = BytesIO(comic.getPage(page_number))
|
||||||
image = Image(file=byte_image)
|
image = Image(file=byte_image)
|
||||||
response = make_response(image.make_blob())
|
response = make_response(image.make_blob())
|
||||||
response.headers["cache-control"] = "public"
|
response.headers["cache-control"] = "public"
|
||||||
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta["path"])))
|
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
|
||||||
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
|
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
|
||||||
response.headers["content-type"] = "image/" + image.format
|
response.headers["content-type"] = "image/" + image.format
|
||||||
return response
|
return response
|
||||||
@ -167,9 +162,9 @@ def get_comic_page(comic_id, page_number):
|
|||||||
def get_comic_thumbnail(comic_id, page_number):
|
def get_comic_thumbnail(comic_id, page_number):
|
||||||
meta = database.db_get_comic_by_id(comic_id)
|
meta = database.db_get_comic_by_id(comic_id)
|
||||||
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
|
thumb = database.db_get_thumbnail_by_id_page(comic_id, page_number)
|
||||||
response = make_response(thumb["image"])
|
response = make_response(thumb.image)
|
||||||
response.headers["cache-control"] = "public"
|
response.headers["cache-control"] = "public"
|
||||||
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta["path"])))
|
date = pytz.utc.localize(datetime.datetime.utcfromtimestamp(os.path.getmtime(meta.path)))
|
||||||
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
|
response.headers["last-modified"] = date.strftime('%a, %d %b %Y %H:%M:%S %Z')
|
||||||
response.headers["content-type"] = thumb["type"]
|
response.headers["content-type"] = thumb.type
|
||||||
return response
|
return response
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{% for i in range(start, end) %}
|
{% for i in range(start, end) %}
|
||||||
<div class="col-3" style="padding: 10px">
|
<div class="col-3" style="padding: 10px">
|
||||||
<a href="/comics/{{ publisher_series[i]["publisher"]|urlencode }}?series={{ publisher_series[i]["series"]|urlencode }}&seriesYear={{ publisher_series[i]["seriesYear"] }}">
|
<a href="/comics/{{ publisher_series[i].publisher|urlencode }}?series={{ publisher_series[i].series|urlencode }}&seriesYear={{ publisher_series[i].seriesYear }}">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img class="card-img" src="/comics/get_comic/{{ publisher_series[i]['id'] }}/0/thumbnail" onerror="this.src='/static/images/default.png'">
|
<img class="card-img" src="/comics/get_comic/{{ publisher_series[i]['id'] }}/0/thumbnail" onerror="this.src='/static/images/default.png'">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{{ publisher_series[i]["series"] }} {{ publisher_series[i]["seriesYear"] }}
|
{{ publisher_series[i].series }} {{ publisher_series[i].seriesYear }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -8,9 +8,9 @@
|
|||||||
<div class="comic-grid">
|
<div class="comic-grid">
|
||||||
{% for page_number in range(start, end) %}
|
{% for page_number in range(start, end) %}
|
||||||
<div style="margin: auto" class="comic-thumbnail card bg-dark text-white">
|
<div style="margin: auto" class="comic-thumbnail card bg-dark text-white">
|
||||||
<a href="/comics/{{ comic["publisher"]|urlencode }}?series={{ comic["series"]|urlencode }}&seriesYear={{ comic["seriesYear"] }}&issue={{ comic["issue"]|urlencode }}&pageNumber={{ page_number }}">
|
<a href="/comics/{{ comic.publisher|urlencode }}?series={{ comic.series|urlencode }}&seriesYear={{ comic.seriesYear }}&issue={{ comic.issue|urlencode }}&pageNumber={{ page_number }}">
|
||||||
<img src="/comics/get_comic/{{ comic["id"] }}/{{ page_number }}/thumbnail" alt="" style="display: inline" onerror="this.src='/static/images/default.png'">
|
<img src="/comics/get_comic/{{ comic.id }}/{{ page_number }}/thumbnail" alt="" style="display: inline" onerror="this.src='/static/images/default.png'">
|
||||||
<p class="card-text">{{ 1+page_number }}/{{ comic["pageCount"] }}</p>
|
<p class="card-text">{{ 1+page_number }}/{{ comic.pageCount }}</p>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</a>
|
</a>
|
||||||
<a href="{{ next_url }}" ondragstart="return false">
|
<a href="{{ next_url }}" ondragstart="return false">
|
||||||
<img class="comic-page" ondragstart="return false" id="image" src="/comics/get_comic/{{ comic["id"] }}/{{ page_number }}" alt="">
|
<img class="comic-page" ondragstart="return false" id="image" src="/comics/get_comic/{{ comic.id }}/{{ page_number }}" alt="">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{% for i in range(start, end) %}
|
{% for i in range(start, end) %}
|
||||||
<div class="col-3" style="padding: 10px">
|
<div class="col-3" style="padding: 10px">
|
||||||
<a href="/comics/{{ comics[i]["publisher"]|urlencode }}?series={{ comics[i]["series"]|urlencode }}&seriesYear={{ comics[i]["seriesYear"] }}&issue={{ comics[i]["issue"]|urlencode }}">
|
<a href="/comics/{{ comics[i].publisher|urlencode }}?series={{ comics[i].series|urlencode }}&seriesYear={{ comics[i].seriesYear }}&issue={{ comics[i].issue|urlencode }}">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<img class="card-img" src="/comics/get_comic/{{ comics[i]['id'] }}/0/thumbnail" onerror="this.src='/static/images/default.png'">
|
<img class="card-img" src="/comics/get_comic/{{ comics[i]['id'] }}/0/thumbnail" onerror="this.src='/static/images/default.png'">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{{ comics[i]["series"] }} {% if comics[i]["issue"] > 0 %}{{ "#{0:g}".format(comics[i]["issue"]) }}{% endif %} {% if comics[i]["title"] != None %}{{ comics[i]["title"] }} {% endif %}
|
{{ comics[i].series }} {% if comics[i].issue > 0 %}{{ "#{0:g}".format(comics[i].issue) }}{% endif %} {% if comics[i].title != None %}{{ comics[i].title }} {% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from flask import Blueprint, render_template, request, make_response, send_file, send_from_directory, current_app
|
from flask import Blueprint, render_template, request, make_response, send_from_directory, current_app
|
||||||
from flask_login import login_required
|
from flask_login import login_required
|
||||||
import inspect
|
import inspect
|
||||||
|
|
||||||
@ -19,7 +19,6 @@ def index():
|
|||||||
return render_template("movies/index.html", title="Movies", movies=movies, page=page, max_items=max_items, start=start, end=end, item_count=len(movies))
|
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:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -40,19 +39,26 @@ def search():
|
|||||||
return render_template("movies/search.html", title="Movies", movies=results, page=page, max_items=max_items, start=start, end=end, item_count=len(results))
|
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:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@Movies.route("/movies/<imdb_id>")
|
@Movies.route("/movies/<imdb_id>", methods=["GET", "POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def movie_view(imdb_id):
|
def movie_view(imdb_id):
|
||||||
try:
|
try:
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
|
if request.method == "POST":
|
||||||
return render_template("movies/movieViewer.html", title="Movies: " + movie_data["title"], movie=movie_data)
|
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:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -61,10 +67,9 @@ def movie_view(imdb_id):
|
|||||||
def movie_view_extended(imdb_id):
|
def movie_view_extended(imdb_id):
|
||||||
try:
|
try:
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
|
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)
|
return render_template("movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -73,10 +78,9 @@ def movie_view_extended(imdb_id):
|
|||||||
def movie_view_directors_cut(imdb_id):
|
def movie_view_directors_cut(imdb_id):
|
||||||
try:
|
try:
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
|
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)
|
return render_template("movies/movieViewer.html", title="Movies: " + movie_data.title, movie=movie_data)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(type(e), e)
|
|
||||||
return str(type(e)) + " " + str(e)
|
return str(type(e)) + " " + str(e)
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +88,7 @@ def movie_view_directors_cut(imdb_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def get_movie(imdb_id):
|
def get_movie(imdb_id):
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
|
movie_data = database.db_get_movie_by_imdb_id(imdb_id)
|
||||||
filename = movie_data["title"]+" ("+str(movie_data["year"])+").mkv"
|
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
|
||||||
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
||||||
response.headers["content-type"] = "video/webm"
|
response.headers["content-type"] = "video/webm"
|
||||||
return response
|
return response
|
||||||
@ -94,7 +98,7 @@ def get_movie(imdb_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def get_movie_extended(imdb_id):
|
def get_movie_extended(imdb_id):
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
|
movie_data = database.db_get_movie_by_imdb_id(imdb_id, extended=1)
|
||||||
filename = movie_data["title"]+" ("+str(movie_data["year"])+").mkv"
|
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
|
||||||
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
||||||
response.headers["content-type"] = "video/webm"
|
response.headers["content-type"] = "video/webm"
|
||||||
return response
|
return response
|
||||||
@ -104,7 +108,7 @@ def get_movie_extended(imdb_id):
|
|||||||
@login_required
|
@login_required
|
||||||
def get_movie_directors_cut(imdb_id):
|
def get_movie_directors_cut(imdb_id):
|
||||||
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
|
movie_data = database.db_get_movie_by_imdb_id(imdb_id, directors_cut=1)
|
||||||
filename = movie_data["title"]+" ("+str(movie_data["year"])+").mkv"
|
filename = movie_data.title+" ("+str(movie_data.year)+").mkv"
|
||||||
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
response = make_response(send_from_directory(func.MOVIES_DIRECTORY, filename))
|
||||||
response.headers["content-type"] = "video/webm"
|
response.headers["content-type"] = "video/webm"
|
||||||
return response
|
return response
|
||||||
|
@ -2,16 +2,17 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container" style="text-align: center">
|
<div class="container" style="text-align: center">
|
||||||
<video 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" style="display: inline-block" controls preload="auto" width="1100"
|
||||||
poster="https://image.tmdb.org/t/p/original{{ movie["backdrop_path"] }}" data-setup="{}">
|
poster="https://image.tmdb.org/t/p/original{{ movie.backdrop_path }}" data-setup="{}">
|
||||||
<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">
|
<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">
|
||||||
<p class='vjs-no-js'>
|
<p class='vjs-no-js'>
|
||||||
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
To view this video please enable JavaScript, and consider upgrading to a web browser that
|
||||||
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
|
<a href='https://videojs.com/html5-video-support/' target='_blank'>supports HTML5 video</a>
|
||||||
</p>
|
</p>
|
||||||
</video>
|
</video>
|
||||||
<h1>{{ movie["title"] }}</h1>
|
<h1>{{ movie.title }}</h1>
|
||||||
<p style="text-align: left">{{ movie["description"] }}</p>
|
<p style="text-align: left">{{ movie.description }}</p>
|
||||||
|
<a class="btn btn-primary" href="{{ url_for("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>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -20,4 +21,40 @@
|
|||||||
<img src="/static/svg/tmdb.svg" alt="" style="height: 40px;">
|
<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>
|
<p>This product uses the TMDb API but is not endorsed or certified by TMDb.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<script>
|
||||||
|
videojs("player").ready(function(){
|
||||||
|
let myPlayer = videojs.getPlayer("player");
|
||||||
|
let saved_time = {{ user_data.time }};
|
||||||
|
let length = 0;
|
||||||
|
if (saved_time > 5) {
|
||||||
|
myPlayer.currentTime(saved_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reqListener() {
|
||||||
|
console.log(this.responseText);
|
||||||
|
}
|
||||||
|
|
||||||
|
let time = myPlayer.currentTime();
|
||||||
|
let timestamp = document.getElementById("timestamp");
|
||||||
|
myPlayer.on("timeupdate", function () {
|
||||||
|
if (myPlayer.currentTime()-time >= 10) {
|
||||||
|
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.send();
|
||||||
|
time = myPlayer.currentTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
myPlayer.on("pause", function () {
|
||||||
|
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.send();
|
||||||
|
time = myPlayer.currentTime();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
{% endblock footer_content %}
|
{% endblock footer_content %}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{% for i in range(start, end) %}
|
{% for i in range(start, end) %}
|
||||||
<div class="col-4" style="padding: 10px">
|
<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 %}">
|
<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">
|
<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'">
|
<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">
|
<div class="card-body">
|
||||||
{{ movies[i]["title"] }} ({{ movies[i]["year"] }})
|
{{ movies[i].title }} ({{ movies[i].year }})
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
|
@ -7,5 +7,5 @@ location / {
|
|||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||||
fastcgi_param SCRIPT_NAME "";
|
fastcgi_param SCRIPT_NAME "";
|
||||||
fastcgi_pass unix:/run/matt/rpiWebApp/fcgi.sock;
|
fastcgi_pass unix:/run/rpiWebApp/fcgi.sock;
|
||||||
}
|
}
|
||||||
|
112
rpiWebApp.py
@ -1,12 +1,16 @@
|
|||||||
from flask import Flask
|
from flask import Flask
|
||||||
from flask import render_template, request, g, redirect, url_for, flash, current_app
|
from flask import render_template, request, g, redirect, url_for, flash, current_app
|
||||||
from flask_login import LoginManager, current_user, login_user, logout_user, login_required
|
from flask_login import LoginManager, current_user, login_user, logout_user, login_required
|
||||||
from flask_log import Logging
|
|
||||||
|
from oauthlib.oauth2 import WebApplicationClient
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
import logging
|
import logging
|
||||||
import inotify.adapters, inotify.constants
|
import inotify.adapters, inotify.constants
|
||||||
import inspect
|
import inspect
|
||||||
|
import datetime
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
|
||||||
import scripts.func as func
|
import scripts.func as func
|
||||||
from scripts import database
|
from scripts import database
|
||||||
@ -26,15 +30,25 @@ nullLog = NullHandler()
|
|||||||
inotify.adapters._LOGGER = nullLog
|
inotify.adapters._LOGGER = nullLog
|
||||||
|
|
||||||
|
|
||||||
|
GOOGLE_CLIENT_ID = "***REMOVED***"
|
||||||
|
GOOGLE_CLIENT_SECRET = "***REMOVED***"
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.register_blueprint(comics.Comics)
|
app.register_blueprint(comics.Comics)
|
||||||
app.register_blueprint(admin.Admin)
|
app.register_blueprint(admin.Admin)
|
||||||
app.register_blueprint(movies.Movies)
|
app.register_blueprint(movies.Movies)
|
||||||
app.register_blueprint(tv.TV)
|
app.register_blueprint(tv.TV)
|
||||||
app.config["SECRET_KEY"] = "***REMOVED***"
|
app.config["SECRET_KEY"] = "***REMOVED***"
|
||||||
app.config["FLASK_LOG_LEVEL"] = "DEBUG"
|
app.logger.setLevel("DEBUG")
|
||||||
app.config["FLASK_LOG_FACILITY"] = "daemon"
|
|
||||||
flask_log = Logging(app)
|
|
||||||
|
|
||||||
login_manager = LoginManager(app)
|
login_manager = LoginManager(app)
|
||||||
login_manager.login_view = "login"
|
login_manager.login_view = "login"
|
||||||
@ -99,7 +113,6 @@ def update_comic_db(sender, **kw):
|
|||||||
database.add_comics(kw["meta"], kw["thumbnails"])
|
database.add_comics(kw["meta"], kw["thumbnails"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def update_movie_db(sender, **kw):
|
def update_movie_db(sender, **kw):
|
||||||
@ -107,17 +120,13 @@ def update_movie_db(sender, **kw):
|
|||||||
database.add_movies(kw["movies"])
|
database.add_movies(kw["movies"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def update_tv_show_db(sender, **kw):
|
def update_tv_show_db(sender, **kw):
|
||||||
try:
|
try:
|
||||||
database.add_tv_shows(kw["tv_show"])
|
database.add_tv_shows(kw["tv_show"])
|
||||||
if kw["tv_episodes"]:
|
|
||||||
database.add_tv_episodes(kw["tv_episodes"])
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def update_tv_episodes_db(sender, **kw):
|
def update_tv_episodes_db(sender, **kw):
|
||||||
@ -125,7 +134,6 @@ def update_tv_episodes_db(sender, **kw):
|
|||||||
database.add_tv_episodes(kw["tv_episodes"])
|
database.add_tv_episodes(kw["tv_episodes"])
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
func.comic_loaded.connect(update_comic_db)
|
func.comic_loaded.connect(update_comic_db)
|
||||||
@ -135,26 +143,96 @@ func.tv_episodes_loaded.connect(update_tv_episodes_db)
|
|||||||
|
|
||||||
|
|
||||||
@login_manager.user_loader
|
@login_manager.user_loader
|
||||||
def load_user(username):
|
def load_user(email):
|
||||||
return database.get_user(username)
|
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))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/login", methods=["GET", "POST"])
|
@app.route("/login", methods=["GET", "POST"])
|
||||||
def login():
|
def login():
|
||||||
try:
|
try:
|
||||||
|
google_provider_cfg = get_google_provider_cfg()
|
||||||
|
authorization_endpoint = google_provider_cfg["authorization_endpoint"]
|
||||||
|
|
||||||
|
request_uri = client.prepare_request_uri(
|
||||||
|
authorization_endpoint,
|
||||||
|
redirect_uri=request.base_url + "/callback",
|
||||||
|
scope=["openid", "email", "profile"],
|
||||||
|
)
|
||||||
|
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
username = request.form.get("username")
|
email = request.form.get("email")
|
||||||
password = request.form.get("password")
|
password = request.form.get("password")
|
||||||
user = database.get_user(username)
|
user = database.get_user(email)
|
||||||
if user is None or not user.check_password(password):
|
if user is None or not user.check_password(password):
|
||||||
flash("invalid username or password")
|
flash("invalid email or password")
|
||||||
return redirect(url_for("login"))
|
return redirect(url_for("login"))
|
||||||
login_user(user)
|
login_user(user, remember=True, duration=datetime.timedelta(days=7))
|
||||||
next_page = request.args.get("next")
|
next_page = request.args.get("next")
|
||||||
if not next_page:
|
if not next_page:
|
||||||
next_page = url_for("home")
|
next_page = url_for("home")
|
||||||
return redirect(next_page)
|
return redirect(next_page)
|
||||||
return render_template("login.html", title="login")
|
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")
|
||||||
|
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
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))
|
||||||
|
|
||||||
|
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:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
return str(e)
|
return str(e)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
import click
|
|
@ -1,5 +1,5 @@
|
|||||||
from flask import g, current_app
|
from flask import g, current_app
|
||||||
from flask_login import UserMixin
|
from flask_login import UserMixin, current_user
|
||||||
|
|
||||||
from werkzeug.security import check_password_hash
|
from werkzeug.security import check_password_hash
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
@ -8,17 +8,19 @@ from sqlalchemy.ext.declarative import declarative_base
|
|||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
from sqlalchemy import Column, Integer, String, BLOB, Boolean, Table, MetaData, DateTime
|
from sqlalchemy import Column, Integer, String, BLOB, Boolean, Table, MetaData, DateTime
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker, scoped_session
|
||||||
|
from sqlalchemy.pool import QueuePool, NullPool
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import os
|
import os
|
||||||
import inspect
|
import inspect
|
||||||
|
import logging
|
||||||
|
|
||||||
from comicapi.issuestring import IssueString
|
from comicapi.issuestring import IssueString
|
||||||
|
|
||||||
from scripts import tmdb
|
from scripts import tmdb
|
||||||
|
|
||||||
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
|
RPI_DATABASE = "/usb/storage/rpiWebApp/database.db"
|
||||||
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/imdb.db"
|
RPI_IMDB_DATABASE = "/usb/storage/rpiWebApp/imdb.db"
|
||||||
|
|
||||||
MC_DATABASE = "***REMOVED***"
|
MC_DATABASE = "***REMOVED***"
|
||||||
MC_IMDB_DATABASE = "C:\\Users\\Matthew\\Documents\\MyPrograms\\Websites\\rpi_web_interface\\imdb.db"
|
MC_IMDB_DATABASE = "C:\\Users\\Matthew\\Documents\\MyPrograms\\Websites\\rpi_web_interface\\imdb.db"
|
||||||
@ -27,9 +29,11 @@ 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
|
IMDB_DATABASE = RPI_IMDB_DATABASE if os.path.exists(RPI_IMDB_DATABASE) else MC_IMDB_DATABASE
|
||||||
|
|
||||||
|
|
||||||
engine = create_engine("sqlite:///"+DATABASE+"?check_same_thread=False")
|
engine = create_engine("sqlite:///"+DATABASE+"?check_same_thread=False", poolclass=NullPool)
|
||||||
Session = sessionmaker(bind=engine)
|
logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
|
||||||
session = Session()
|
session_factory = sessionmaker(bind=engine)
|
||||||
|
Session = scoped_session(session_factory)
|
||||||
|
|
||||||
Base = declarative_base()
|
Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
@ -84,7 +88,6 @@ class Comic(Base):
|
|||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
||||||
#print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Comic: {series} {issue}>".format(series=self.series, issue=self.issueText)
|
return "<Comic: {series} {issue}>".format(series=self.series, issue=self.issueText)
|
||||||
@ -109,7 +112,6 @@ class ComicThumbnail(Base):
|
|||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
||||||
#print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
class Movie(Base):
|
class Movie(Base):
|
||||||
@ -135,7 +137,6 @@ class Movie(Base):
|
|||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) +" "+ str(e))
|
||||||
#print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
class TvShow(Base):
|
class TvShow(Base):
|
||||||
@ -157,7 +158,6 @@ class TvShow(Base):
|
|||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
class TvEpisode(Base):
|
class TvEpisode(Base):
|
||||||
@ -181,104 +181,78 @@ class TvEpisode(Base):
|
|||||||
i += 1
|
i += 1
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
class User(Base, UserMixin):
|
class User(Base, UserMixin):
|
||||||
__tablename__ = "users"
|
__tablename__ = "users"
|
||||||
|
|
||||||
username = Column(String, unique=True, primary_key=True)
|
id = Column(String, primary_key=True)
|
||||||
|
username = Column(String)
|
||||||
|
email = Column(String, unique=True)
|
||||||
passwordHash = Column(String(128))
|
passwordHash = Column(String(128))
|
||||||
isAdmin = Column(Boolean, default=False)
|
isAdmin = Column(Boolean, default=False)
|
||||||
|
|
||||||
def __init__(self, data):
|
def __init__(self, data):
|
||||||
i = 0
|
i = 0
|
||||||
for column in self.__table__.columns:
|
try:
|
||||||
setattr(self, column.name, data[i])
|
for column in self.__table__.columns:
|
||||||
i += 1
|
setattr(self, column.name, data[i])
|
||||||
self.init_user_data()
|
i += 1
|
||||||
|
pass
|
||||||
@orm.reconstructor
|
except Exception as e:
|
||||||
def init_user_data(self):
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
meta = MetaData()
|
|
||||||
|
|
||||||
self.comics = Table(
|
|
||||||
"comics", meta,
|
|
||||||
Column("comic_id", Integer, primary_key=True),
|
|
||||||
Column("viewed", Boolean, default=False),
|
|
||||||
Column("date", DateTime)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.movies = Table(
|
|
||||||
"movies", meta,
|
|
||||||
Column("imdb_id", Integer, primary_key=True),
|
|
||||||
Column("viewed", Boolean, default=False),
|
|
||||||
Column("date", DateTime)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tv_episodes = Table(
|
|
||||||
"tv_episodes", meta,
|
|
||||||
Column("imdb_id", Integer, primary_key=True),
|
|
||||||
Column("viewed", Boolean, default=False),
|
|
||||||
Column("date", DateTime)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tv_shows = Table(
|
|
||||||
"tv_shows", meta,
|
|
||||||
Column("imdb_id", Integer, primary_key=True),
|
|
||||||
Column("viewed", Boolean, default=False),
|
|
||||||
Column("date", DateTime)
|
|
||||||
)
|
|
||||||
|
|
||||||
user_engine = create_engine("sqlite:///" + "user_" + self.username + ".db" + "?check_same_thread=False")
|
|
||||||
self.conn = engine.connect()
|
|
||||||
|
|
||||||
meta.create_all(user_engine)
|
|
||||||
|
|
||||||
def set_comic_viewed(self, comic_id, val=True):
|
|
||||||
self.conn.execute(self.comics.insert().values(comic_id=comic_id, viewed=val))
|
|
||||||
|
|
||||||
def is_comic_viewed(self, comic_id):
|
|
||||||
q = self.comics.select().where(self.comics.c.comic_id == comic_id)
|
|
||||||
result = self.conn.execute(q).fetchone()
|
|
||||||
if result:
|
|
||||||
return result["viewed"]
|
|
||||||
|
|
||||||
def set_movie_viewed(self, imdb_id, val=True):
|
|
||||||
self.conn.execute(self.movies.insert().values(comic_id=imdb_id, viewed=val))
|
|
||||||
|
|
||||||
def is_movie_viewed(self, imdb_id):
|
|
||||||
q = self.movies.select().where(self.movies.c.imdb_id == imdb_id)
|
|
||||||
result = self.conn.execute(q).fetchone()
|
|
||||||
if result:
|
|
||||||
return result["viewed"]
|
|
||||||
|
|
||||||
def set_tv_episode_viewed(self, imdb_id, val=True):
|
|
||||||
self.conn.execute(self.tv_episodes.insert().values(comic_id=imdb_id, viewed=val))
|
|
||||||
|
|
||||||
def is_tv_episode_viewed(self, imdb_id):
|
|
||||||
q = self.tv_episodes.select().where(self.tv_episodes.c.imdb_id == imdb_id)
|
|
||||||
result = self.conn.execute(q).fetchone()
|
|
||||||
if result:
|
|
||||||
return result["viewed"]
|
|
||||||
|
|
||||||
def set_tv_show_viewed(self, imdb_id, val=True):
|
|
||||||
self.conn.execute(self.tv_shows.insert().values(comic_id=imdb_id, viewed=val))
|
|
||||||
|
|
||||||
def is_tv_show_viewed(self, imdb_id):
|
|
||||||
q = self.tv_shows.select().where(self.tv_shows.c.imdb_id == imdb_id)
|
|
||||||
result = self.conn.execute(q).fetchone()
|
|
||||||
if result:
|
|
||||||
return result["viewed"]
|
|
||||||
|
|
||||||
def get_id(self):
|
def get_id(self):
|
||||||
return self.username
|
return self.email
|
||||||
|
|
||||||
def check_password(self, password):
|
def check_password(self, password):
|
||||||
|
if not self.passwordHash:
|
||||||
|
return
|
||||||
result = check_password_hash(self.passwordHash, password)
|
result = check_password_hash(self.passwordHash, password)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
class UserTvMovieData(Base):
|
||||||
|
__tablename__ = "user_tv_movie_data"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
|
user = Column(String)
|
||||||
|
imdb_id = Column(String)
|
||||||
|
parent_imdb_id = Column(String)
|
||||||
|
time = Column(Integer)
|
||||||
|
length = Column(Integer)
|
||||||
|
finished = Column(Boolean, default=False)
|
||||||
|
|
||||||
|
def __init__(self, data):
|
||||||
|
i = 0
|
||||||
|
try:
|
||||||
|
for column in self.__table__.columns:
|
||||||
|
if column.name == "id":
|
||||||
|
continue
|
||||||
|
setattr(self, column.name, data[i])
|
||||||
|
i += 1
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
|
||||||
|
"""class UserComicData(Base):
|
||||||
|
__tablename__ = "user_comic_data"
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
|
user = Column(String)
|
||||||
|
comic_id = Column(Integer)
|
||||||
|
viewed = Column(Boolean, default=False)
|
||||||
|
|
||||||
|
def __init__(self, data):
|
||||||
|
i = 0
|
||||||
|
try:
|
||||||
|
for column in self.__table__.columns:
|
||||||
|
setattr(self, column.name, data[i])
|
||||||
|
i += 1
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))"""
|
||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
db = getattr(g, '_database', None)
|
db = getattr(g, '_database', None)
|
||||||
if db is None:
|
if db is None:
|
||||||
@ -336,22 +310,24 @@ def initialize_db():
|
|||||||
"teams" TEXT,
|
"teams" TEXT,
|
||||||
"locations" TEXT,
|
"locations" TEXT,
|
||||||
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE
|
||||||
)""")
|
)""")
|
||||||
get_db().execute("""CREATE TABLE IF NOT EXISTS "credits" (
|
get_db().execute("""CREATE TABLE IF NOT EXISTS "credits" (
|
||||||
"id" INTEGER NOT NULL,
|
"id" INTEGER NOT NULL,
|
||||||
"role" TEXT,
|
"role" TEXT,
|
||||||
"name" TEXT,
|
"name" TEXT,
|
||||||
"primary" INTEGER NOT NULL
|
"primary" INTEGER NOT NULL
|
||||||
)""")
|
)""")
|
||||||
get_db().execute("""CREATE TABLE IF NOT EXISTS "comic_thumbnails" (
|
get_db().execute("""CREATE TABLE IF NOT EXISTS "comic_thumbnails" (
|
||||||
"comic_id" INTEGER,
|
"comic_id" INTEGER,
|
||||||
"pageNumber" INTEGER,
|
"pageNumber" INTEGER,
|
||||||
"image" BLOB,
|
"image" BLOB,
|
||||||
"type" TEXT,
|
"type" TEXT,
|
||||||
"id" INTEGER PRIMARY KEY AUTOINCREMENT
|
"id" INTEGER PRIMARY KEY AUTOINCREMENT
|
||||||
)""")
|
)""")
|
||||||
get_db().execute("""CREATE TABLE IF NOT EXISTS "users" (
|
get_db().execute("""CREATE TABLE IF NOT EXISTS "users" (
|
||||||
"username" TEXT UNIQUE PRIMARY KEY,
|
"id" TEXT PRIMARY KEY,
|
||||||
|
"username" TEXT,
|
||||||
|
"email" TEXT UNIQUE,
|
||||||
"passwordHash" VARCHAR(128),
|
"passwordHash" VARCHAR(128),
|
||||||
"isAdmin" INTEGER NOT NULL DEFAULT 0
|
"isAdmin" INTEGER NOT NULL DEFAULT 0
|
||||||
)""")
|
)""")
|
||||||
@ -367,7 +343,7 @@ def initialize_db():
|
|||||||
"directors_cut" INTEGER,
|
"directors_cut" INTEGER,
|
||||||
"poster_path" TEXT,
|
"poster_path" TEXT,
|
||||||
"backdrop_path" TEXT
|
"backdrop_path" TEXT
|
||||||
)""")
|
)""")
|
||||||
get_db().execute("""CREATE TABLE IF NOT EXISTS "tv_shows" (
|
get_db().execute("""CREATE TABLE IF NOT EXISTS "tv_shows" (
|
||||||
"imdb_id" TEXT PRIMARY KEY ,
|
"imdb_id" TEXT PRIMARY KEY ,
|
||||||
"tmdb_id" INTEGER UNIQUE,
|
"tmdb_id" INTEGER UNIQUE,
|
||||||
@ -387,7 +363,16 @@ def initialize_db():
|
|||||||
"description" TEXT,
|
"description" TEXT,
|
||||||
"still_path" TEXT,
|
"still_path" TEXT,
|
||||||
"path" TEXT
|
"path" TEXT
|
||||||
)""")
|
)""")
|
||||||
|
get_db().execute("""CREATE TABLE IF NOT EXISTS "user_tv_movie_data" (
|
||||||
|
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
|
||||||
|
"user" TEXT,
|
||||||
|
"imdb_id" TEXT,
|
||||||
|
"parent_imdb_id" TEXT,
|
||||||
|
"time" INTEGER,
|
||||||
|
"length" INTEGER,
|
||||||
|
"finished" INTEGER DEFAULT 0
|
||||||
|
)""")
|
||||||
get_db().execute("CREATE INDEX IF NOT EXISTS path_index ON comics(path);")
|
get_db().execute("CREATE INDEX IF NOT EXISTS path_index ON comics(path);")
|
||||||
get_db().execute("CREATE INDEX IF NOT EXISTS comic_id_index ON comic_thumbnails(comic_id);")
|
get_db().execute("CREATE INDEX IF NOT EXISTS comic_id_index ON comic_thumbnails(comic_id);")
|
||||||
get_db().commit()
|
get_db().commit()
|
||||||
@ -398,7 +383,34 @@ def initialize_db():
|
|||||||
get_imdb().commit()
|
get_imdb().commit()
|
||||||
|
|
||||||
|
|
||||||
|
def update_user_tv_movie_data(imdb_id, parent_id, time, length, finished=False):
|
||||||
|
session = Session()
|
||||||
|
email = current_user.email
|
||||||
|
user_data = session.query(UserTvMovieData).filter(UserTvMovieData.imdb_id == imdb_id, UserTvMovieData.user == email).one_or_none()
|
||||||
|
if user_data:
|
||||||
|
user_data.time = time
|
||||||
|
user_data.finished = finished
|
||||||
|
if not user_data.length > 0 and length > 0:
|
||||||
|
user_data.length = length
|
||||||
|
session.commit()
|
||||||
|
return user_data
|
||||||
|
else:
|
||||||
|
data = UserTvMovieData((email, imdb_id, parent_id, time, length, finished))
|
||||||
|
session.add(data)
|
||||||
|
session.commit()
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def add_user(data):
|
||||||
|
session = Session()
|
||||||
|
user = User(data)
|
||||||
|
session.add(user)
|
||||||
|
session.commit()
|
||||||
|
return user
|
||||||
|
|
||||||
|
|
||||||
def add_movies(movies):
|
def add_movies(movies):
|
||||||
|
session = Session()
|
||||||
for movie_data in movies:
|
for movie_data in movies:
|
||||||
movie = Movie(movie_data)
|
movie = Movie(movie_data)
|
||||||
session.add(movie)
|
session.add(movie)
|
||||||
@ -407,15 +419,16 @@ def add_movies(movies):
|
|||||||
|
|
||||||
def add_tv_shows(tv_show_data):
|
def add_tv_shows(tv_show_data):
|
||||||
try:
|
try:
|
||||||
|
session = Session()
|
||||||
tv_show = TvShow(tv_show_data)
|
tv_show = TvShow(tv_show_data)
|
||||||
session.add(tv_show)
|
session.add(tv_show)
|
||||||
session.commit()
|
session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def add_tv_episodes(episodes):
|
def add_tv_episodes(episodes):
|
||||||
|
session = Session()
|
||||||
for episode_data in episodes:
|
for episode_data in episodes:
|
||||||
try:
|
try:
|
||||||
episode = TvEpisode(episode_data)
|
episode = TvEpisode(episode_data)
|
||||||
@ -424,10 +437,10 @@ def add_tv_episodes(episodes):
|
|||||||
session.commit()
|
session.commit()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def add_comics(meta, thumbnails):
|
def add_comics(meta, thumbnails):
|
||||||
|
session = Session()
|
||||||
data = []
|
data = []
|
||||||
for info in meta:
|
for info in meta:
|
||||||
issue = IssueString(info[1].issue).asFloat()
|
issue = IssueString(info[1].issue).asFloat()
|
||||||
@ -458,93 +471,96 @@ def add_comics(meta, thumbnails):
|
|||||||
|
|
||||||
|
|
||||||
def db_get_all_comics():
|
def db_get_all_comics():
|
||||||
|
session = Session()
|
||||||
result = session.query(Comic).all()
|
result = session.query(Comic).all()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def db_get_series_by_publisher(publisher):
|
def db_get_series_by_publisher(publisher):
|
||||||
|
session = Session()
|
||||||
result = session.query(Comic).filter(Comic.publisher == publisher).group_by(Comic.publisher, Comic.series, Comic.seriesYear).order_by(Comic.series, Comic.seriesYear).all()
|
result = session.query(Comic).filter(Comic.publisher == publisher).group_by(Comic.publisher, Comic.series, Comic.seriesYear).order_by(Comic.series, Comic.seriesYear).all()
|
||||||
series = [comic.__dict__ for comic in result]
|
series = result
|
||||||
return series
|
return series
|
||||||
|
|
||||||
|
|
||||||
def db_get_comics_in_series(series, publisher, series_year):
|
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)\
|
result = session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesYear == series_year)\
|
||||||
.order_by(Comic.issue).all()
|
.order_by(Comic.issue).all()
|
||||||
comics = [comic.__dict__ for comic in result]
|
comics = result
|
||||||
return comics
|
return comics
|
||||||
|
|
||||||
|
|
||||||
def get_publishers():
|
def get_publishers():
|
||||||
|
session = Session()
|
||||||
result = session.query(Comic.publisher).distinct(Comic.publisher).order_by(Comic.publisher).all()
|
result = session.query(Comic.publisher).distinct(Comic.publisher).order_by(Comic.publisher).all()
|
||||||
publishers = [r for (r,) in result]
|
publishers = [r for (r,) in result]
|
||||||
return publishers
|
return publishers
|
||||||
|
|
||||||
|
|
||||||
def db_get_comic_by_id(comic_id):
|
def db_get_comic_by_id(comic_id):
|
||||||
comic = session.query(Comic).filter(Comic.id == comic_id).one().__dict__
|
session = Session()
|
||||||
|
comic = session.query(Comic).filter(Comic.id == comic_id).one_or_none()
|
||||||
return comic
|
return comic
|
||||||
|
|
||||||
|
|
||||||
def db_get_thumbnail_by_id_page(comic_id, pageNumber):
|
def db_get_thumbnail_by_id_page(comic_id, pageNumber):
|
||||||
thumbnail = session.query(ComicThumbnail).filter(ComicThumbnail.comic_id == comic_id, ComicThumbnail.pageNumber == pageNumber).one().__dict__
|
session = Session()
|
||||||
|
thumbnail = session.query(ComicThumbnail).filter(ComicThumbnail.comic_id == comic_id, ComicThumbnail.pageNumber == pageNumber).one_or_none()
|
||||||
return thumbnail
|
return thumbnail
|
||||||
|
|
||||||
|
|
||||||
def db_get_comic(publisher, series, series_year, issue):
|
def db_get_comic(publisher, series, series_year, issue):
|
||||||
comic = session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesYear == series_year, Comic.issue == issue).one().__dict__
|
session = Session()
|
||||||
|
comic = session.query(Comic).filter(Comic.publisher == publisher, Comic.series == series, Comic.seriesYear == series_year, Comic.issue == issue).one_or_none()
|
||||||
return comic
|
return comic
|
||||||
|
|
||||||
|
|
||||||
def comic_path_in_db(path):
|
def comic_path_in_db(path):
|
||||||
try:
|
try:
|
||||||
|
session = Session()
|
||||||
result = session.query(Comic).filter(Comic.path == path).one_or_none()
|
result = session.query(Comic).filter(Comic.path == path).one_or_none()
|
||||||
if result:
|
if result:
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# print(path)
|
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def movie_path_in_db(path):
|
def movie_path_in_db(path):
|
||||||
try:
|
try:
|
||||||
|
session = Session()
|
||||||
result = session.query(Movie).filter(Movie.path == path).one_or_none()
|
result = session.query(Movie).filter(Movie.path == path).one_or_none()
|
||||||
if result:
|
if result:
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# print(path)
|
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def tv_show_path_in_db(path):
|
def tv_show_path_in_db(path):
|
||||||
try:
|
try:
|
||||||
|
session = Session()
|
||||||
result = session.query(TvShow).filter(TvShow.path == path).one_or_none()
|
result = session.query(TvShow).filter(TvShow.path == path).one_or_none()
|
||||||
if result:
|
if result:
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# print(path)
|
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def tv_episode_path_in_db(path):
|
def tv_episode_path_in_db(path):
|
||||||
try:
|
try:
|
||||||
|
session = Session()
|
||||||
result = session.query(TvEpisode).filter(TvEpisode.path == path).one_or_none()
|
result = session.query(TvEpisode).filter(TvEpisode.path == path).one_or_none()
|
||||||
if result:
|
if result:
|
||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# print(path)
|
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@ -603,32 +619,53 @@ def tmdb_get_tv_episode_by_imdb_id(imdb_id):
|
|||||||
|
|
||||||
|
|
||||||
def db_get_all_movies():
|
def db_get_all_movies():
|
||||||
|
session = Session()
|
||||||
movies = session.query(Movie).order_by(Movie.title, Movie.year).all()
|
movies = session.query(Movie).order_by(Movie.title, Movie.year).all()
|
||||||
return movies
|
return movies
|
||||||
|
|
||||||
|
|
||||||
def db_get_movie_by_imdb_id(imdb_id, extended=False, directors_cut=False):
|
def db_get_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,
|
result = session.query(Movie).filter(Movie.imdb_id == imdb_id, Movie.extended == extended,
|
||||||
Movie.directors_cut == directors_cut).one()
|
Movie.directors_cut == directors_cut).one_or_none()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_all_tv_shows():
|
def get_all_tv_shows():
|
||||||
|
session = Session()
|
||||||
result = session.query(TvShow).order_by(TvShow.title, TvShow.year).all()
|
result = session.query(TvShow).order_by(TvShow.title, TvShow.year).all()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def get_tv_show_episodes_by_imdb_id(imdb_id):
|
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()
|
result = session.query(TvEpisode).filter(TvEpisode.parent_imdb_id == imdb_id).order_by(TvEpisode.season, TvEpisode.episode).all()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def db_get_episode_by_imdb_id(imdb_id):
|
def db_get_episode_by_imdb_id(imdb_id):
|
||||||
result = session.query(TvEpisode).filter(TvEpisode.imdb_id == imdb_id).one()
|
session = Session()
|
||||||
|
result = session.query(TvEpisode).filter(TvEpisode.imdb_id == imdb_id).one_or_none()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def db_get_user_tv_movie_data(imdb_id):
|
||||||
|
session = Session()
|
||||||
|
email = current_user.email
|
||||||
|
result = session.query(UserTvMovieData).filter(UserTvMovieData.user == email, UserTvMovieData.imdb_id == imdb_id).one_or_none()
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def db_get_user_tv_show_episodes_data(parent_imdb_id) -> list:
|
||||||
|
session = Session()
|
||||||
|
email = current_user.email
|
||||||
|
result = session.query(UserTvMovieData).filter(UserTvMovieData.user == email,
|
||||||
|
UserTvMovieData.parent_imdb_id == parent_imdb_id).all()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def db_search_table_columns_by_query(query, table, columns, group=[], order=[]):
|
def db_search_table_columns_by_query(query, table, columns, group=[], order=[]):
|
||||||
|
session = Session()
|
||||||
results = {}
|
results = {}
|
||||||
final_query = "%" + query.replace(" ", "%") + "%"
|
final_query = "%" + query.replace(" ", "%") + "%"
|
||||||
for column in columns:
|
for column in columns:
|
||||||
@ -644,22 +681,18 @@ def db_search_comics(query):
|
|||||||
results = db_search_table_columns_by_query(query, Comic, [Comic.publisher, Comic.title, Comic.series, Comic.year])
|
results = db_search_table_columns_by_query(query, Comic, [Comic.publisher, Comic.title, Comic.series, Comic.year])
|
||||||
series_results = db_search_table_columns_by_query(query, Comic, [Comic.publisher, Comic.title, Comic.series, Comic.year],
|
series_results = db_search_table_columns_by_query(query, Comic, [Comic.publisher, Comic.title, Comic.series, Comic.year],
|
||||||
group=[Comic.series, Comic.seriesYear], order=[Comic.issue])
|
group=[Comic.series, Comic.seriesYear], order=[Comic.issue])
|
||||||
|
|
||||||
for row in results["publisher"]:
|
for row in results["publisher"]:
|
||||||
if row["publisher"] not in publishers:
|
if row["publisher"] not in publishers:
|
||||||
publishers.append(row.publisher)
|
publishers.append(row.publisher)
|
||||||
for row in series_results["series"]:
|
for row in series_results["series"]:
|
||||||
dict = row.__dict__
|
if row not in series:
|
||||||
if dict not in series:
|
series.append(row)
|
||||||
series.append(dict)
|
|
||||||
for row in results["title"]:
|
for row in results["title"]:
|
||||||
dict = row.__dict__
|
if row not in comics:
|
||||||
if dict not in comics:
|
comics.append(row)
|
||||||
comics.append(dict)
|
|
||||||
for row in results["year"]:
|
for row in results["year"]:
|
||||||
dict = row.__dict__
|
if row not in comics:
|
||||||
if dict not in comics:
|
comics.append(row)
|
||||||
comics.append(dict)
|
|
||||||
|
|
||||||
return {"publisher": publishers, "series": series, "comics": comics}
|
return {"publisher": publishers, "series": series, "comics": comics}
|
||||||
|
|
||||||
@ -668,14 +701,14 @@ def db_search_movies(query):
|
|||||||
results = db_search_table_columns_by_query(query, Movie, [Movie.title, Movie.year, Movie.description], order=[Movie.title])
|
results = db_search_table_columns_by_query(query, Movie, [Movie.title, Movie.year, Movie.description], order=[Movie.title])
|
||||||
movies = []
|
movies = []
|
||||||
for movie in results["title"]:
|
for movie in results["title"]:
|
||||||
if movie.__dict__ not in movies:
|
if movie not in movies:
|
||||||
movies.append(movie.__dict__)
|
movies.append(movie)
|
||||||
for movie in results["description"]:
|
for movie in results["description"]:
|
||||||
if movie.__dict__ not in movies:
|
if movie not in movies:
|
||||||
movies.append(movie.__dict__)
|
movies.append(movie)
|
||||||
for movie in results["year"]:
|
for movie in results["year"]:
|
||||||
if movie.__dict__ not in movies:
|
if movie not in movies:
|
||||||
movies.append(movie.__dict__)
|
movies.append(movie)
|
||||||
return movies
|
return movies
|
||||||
|
|
||||||
|
|
||||||
@ -683,14 +716,14 @@ def db_search_tv_shows(query):
|
|||||||
results = db_search_table_columns_by_query(query, TvShow, [TvShow.title, TvShow.year, TvShow.description], order=[TvShow.title])
|
results = db_search_table_columns_by_query(query, TvShow, [TvShow.title, TvShow.year, TvShow.description], order=[TvShow.title])
|
||||||
tv_shows = []
|
tv_shows = []
|
||||||
for show in results["title"]:
|
for show in results["title"]:
|
||||||
if show.__dict__ not in tv_shows:
|
if show not in tv_shows:
|
||||||
tv_shows.append(show.__dict__)
|
tv_shows.append(show)
|
||||||
for show in results["description"]:
|
for show in results["description"]:
|
||||||
if show.__dict__ not in tv_shows:
|
if show not in tv_shows:
|
||||||
tv_shows.append(show.__dict__)
|
tv_shows.append(show)
|
||||||
for show in results["year"]:
|
for show in results["year"]:
|
||||||
if show.__dict__ not in tv_shows:
|
if show not in tv_shows:
|
||||||
tv_shows.append(show.__dict__)
|
tv_shows.append(show)
|
||||||
return tv_shows
|
return tv_shows
|
||||||
|
|
||||||
|
|
||||||
@ -725,8 +758,12 @@ def fix_thumbnails():
|
|||||||
print("Finished fix thumbnail size")
|
print("Finished fix thumbnail size")
|
||||||
|
|
||||||
|
|
||||||
def get_user(username):
|
def get_user(email):
|
||||||
result = session.query(User).filter(User.username == username).one()
|
try:
|
||||||
if result:
|
session = Session()
|
||||||
return result
|
result = session.query(User).filter(User.email == email).one_or_none()
|
||||||
return None
|
if result:
|
||||||
|
return result
|
||||||
|
return None
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
@ -3,7 +3,7 @@ from wand.image import Image
|
|||||||
import sqlite3, os
|
import sqlite3, os
|
||||||
|
|
||||||
|
|
||||||
RPI_DATABASE = "/var/lib/rpiWebApp/database.db"
|
RPI_DATABASE = "/usb/storage/rpiWebApp/database.db"
|
||||||
|
|
||||||
MC_DATABASE = "***REMOVED***"
|
MC_DATABASE = "***REMOVED***"
|
||||||
|
|
||||||
|
109
scripts/func.py
@ -1,4 +1,5 @@
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
|
from flask import g
|
||||||
from comicapi import comicarchive
|
from comicapi import comicarchive
|
||||||
from blinker import Namespace
|
from blinker import Namespace
|
||||||
|
|
||||||
@ -54,18 +55,20 @@ def get_comics():
|
|||||||
test_path = path.encode("utf8")
|
test_path = path.encode("utf8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info("encoding failed on: "+path)
|
current_app.logger.info("encoding failed on: "+path)
|
||||||
# print("encoding failed on:", path)
|
|
||||||
continue
|
continue
|
||||||
archive = open_comic(path)
|
archive = open_comic(path)
|
||||||
md = archive.readCIX()
|
md = archive.readCIX()
|
||||||
if md.publisher in publishers_to_ignore:
|
if md.publisher in publishers_to_ignore:
|
||||||
continue
|
continue
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
# print(path)
|
try:
|
||||||
meta.append((path, md))
|
meta.append((path, md))
|
||||||
thumbnails.append(get_comic_thumbnails(archive))
|
thumbnails.append(get_comic_thumbnails(archive))
|
||||||
comics_added += 1
|
comics_added += 1
|
||||||
i += 1
|
i += 1
|
||||||
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
continue
|
||||||
if i >= 2:
|
if i >= 2:
|
||||||
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
|
comic_loaded.send("anonymous", meta=meta.copy(), thumbnails=thumbnails.copy())
|
||||||
meta.clear()
|
meta.clear()
|
||||||
@ -75,9 +78,6 @@ def get_comics():
|
|||||||
current_app.logger.info("total number of comics: "+str(total_comics))
|
current_app.logger.info("total number of comics: "+str(total_comics))
|
||||||
current_app.logger.info("comics in database: "+str(comics_in_db))
|
current_app.logger.info("comics in database: "+str(comics_in_db))
|
||||||
current_app.logger.info("number of comics added: "+str(comics_added))
|
current_app.logger.info("number of comics added: "+str(comics_added))
|
||||||
# print("total number of comics:", total_comics)
|
|
||||||
# print("comics in database:", comics_in_db)
|
|
||||||
# print("number of comics added:", comics_added)
|
|
||||||
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
||||||
|
|
||||||
|
|
||||||
@ -90,16 +90,18 @@ def get_comic(path):
|
|||||||
test_path = path.encode("utf8")
|
test_path = path.encode("utf8")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info("encoding failed on: "+path)
|
current_app.logger.info("encoding failed on: "+path)
|
||||||
# print("encoding failed on:", path)
|
|
||||||
return
|
return
|
||||||
archive = open_comic(path)
|
archive = open_comic(path)
|
||||||
md = archive.readCIX()
|
md = archive.readCIX()
|
||||||
if md.publisher in publishers_to_ignore:
|
if md.publisher in publishers_to_ignore:
|
||||||
return
|
return
|
||||||
current_app.logger.info(path)
|
current_app.logger.info(path)
|
||||||
# print(path)
|
|
||||||
meta.append((path, md))
|
meta.append((path, md))
|
||||||
thumbnails.append(get_comic_thumbnails(archive))
|
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)
|
comic_loaded.send("anonymous", meta=meta, thumbnails=thumbnails)
|
||||||
|
|
||||||
|
|
||||||
@ -131,7 +133,6 @@ def open_comic(path):
|
|||||||
|
|
||||||
def get_movies():
|
def get_movies():
|
||||||
current_app.logger.info("start load movies")
|
current_app.logger.info("start load movies")
|
||||||
# print("start load movies")
|
|
||||||
pattern = r"(.+) \((....)\)(\(extended\))?( Director's Cut)?(\.mkv)"
|
pattern = r"(.+) \((....)\)(\(extended\))?( Director's Cut)?(\.mkv)"
|
||||||
movies = []
|
movies = []
|
||||||
total_movies = 0
|
total_movies = 0
|
||||||
@ -147,13 +148,10 @@ def get_movies():
|
|||||||
match = re.fullmatch(pattern, f)
|
match = re.fullmatch(pattern, f)
|
||||||
if not match:
|
if not match:
|
||||||
current_app.logger.info(f+" did not match regex.")
|
current_app.logger.info(f+" did not match regex.")
|
||||||
# print(f, "did not match regex.")
|
|
||||||
continue
|
continue
|
||||||
current_app.logger.info("movie path: "+path)
|
current_app.logger.info("movie path: "+path)
|
||||||
# print("movie path:", path)
|
|
||||||
title = match.group(1)
|
title = match.group(1)
|
||||||
current_app.logger.info("movie title: "+title)
|
current_app.logger.info("movie title: "+title)
|
||||||
# print("movie title:", title)
|
|
||||||
year = int(match.group(2))
|
year = int(match.group(2))
|
||||||
extended = False
|
extended = False
|
||||||
directors_cut = False
|
directors_cut = False
|
||||||
@ -167,7 +165,6 @@ def get_movies():
|
|||||||
imdb_data = database.imdb_get_movie(title, year)
|
imdb_data = database.imdb_get_movie(title, year)
|
||||||
if not imdb_data:
|
if not imdb_data:
|
||||||
current_app.logger.info("could not get imdb data for: "+title+" "+str(year))
|
current_app.logger.info("could not get imdb data for: "+title+" "+str(year))
|
||||||
# print("could not get imdb data for:", title, year)
|
|
||||||
continue
|
continue
|
||||||
imdb_id = imdb_data["tconst"]
|
imdb_id = imdb_data["tconst"]
|
||||||
length = imdb_data["runtimeMinutes"]
|
length = imdb_data["runtimeMinutes"]
|
||||||
@ -175,7 +172,6 @@ def get_movies():
|
|||||||
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
|
tmdb_data = database.tmdb_get_movie_by_imdb_id(imdb_id)
|
||||||
if not tmdb_data:
|
if not tmdb_data:
|
||||||
current_app.logger.info("could not get tmdb data")
|
current_app.logger.info("could not get tmdb data")
|
||||||
# print("could not get tmdb data")
|
|
||||||
continue
|
continue
|
||||||
tmdb_id = tmdb_data[0]
|
tmdb_id = tmdb_data[0]
|
||||||
description = tmdb_data[1]
|
description = tmdb_data[1]
|
||||||
@ -196,10 +192,6 @@ def get_movies():
|
|||||||
current_app.logger.info("total movies: "+str(total_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 in database: "+str(movies_in_db))
|
||||||
current_app.logger.info("movies added: "+str(movies_added))
|
current_app.logger.info("movies added: "+str(movies_added))
|
||||||
# print("finish load movies")
|
|
||||||
# print("total movies:", total_movies)
|
|
||||||
# print("movies in database:", movies_in_db)
|
|
||||||
# print("movies added:", movies_added)
|
|
||||||
|
|
||||||
|
|
||||||
def get_tv_shows():
|
def get_tv_shows():
|
||||||
@ -221,7 +213,7 @@ def get_tv_shows():
|
|||||||
if not tmdb_data:
|
if not tmdb_data:
|
||||||
current_app.logger.info("could not get tmdb data for:" + series_name + " " + str(series_year))
|
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)
|
# print("could not get tmdb data for:", series_name, series_year)
|
||||||
with open("/var/lib/rpiWebApp/log.txt", "a") as f:
|
with open("/usb/storage/rpiWebApp/log.txt", "a") as f:
|
||||||
f.write("could not get tmdb data for: " + imdb_id + " " + series_name + " " + str(series_year)+"\n")
|
f.write("could not get tmdb data for: " + imdb_id + " " + series_name + " " + str(series_year)+"\n")
|
||||||
continue
|
continue
|
||||||
tmdb_id = tmdb_data[0]
|
tmdb_id = tmdb_data[0]
|
||||||
@ -230,41 +222,42 @@ def get_tv_shows():
|
|||||||
tv_show_data = (imdb_id, tmdb_id, series_name, series_year, description, poster_path, path)
|
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)
|
tv_show_loaded.send("anonymous", tv_show=tv_show_data)
|
||||||
current_app.logger.info("finished load tv shows.")
|
current_app.logger.info("finished load tv shows.")
|
||||||
# print("finished load tv shows.")
|
|
||||||
|
|
||||||
|
|
||||||
def get_tv_episodes():
|
def get_tv_episodes():
|
||||||
video_pattern = r"S(..)E(..) - (.+)(.mp4|.mkv)"
|
try:
|
||||||
rows = database.get_all_tv_shows()
|
video_pattern = r"S(\d+)E(\d+) - (.+)(.mp4|.mkv)"
|
||||||
for tv_show in rows:
|
rows = database.get_all_tv_shows()
|
||||||
episodes = []
|
for tv_show in rows:
|
||||||
for video in sorted(os.listdir(tv_show.path)):
|
episodes = []
|
||||||
video_match = re.fullmatch(video_pattern, video)
|
for video in sorted(os.listdir(tv_show.path)):
|
||||||
if video_match:
|
video_match = re.fullmatch(video_pattern, video)
|
||||||
path = tv_show.path + video
|
if video_match:
|
||||||
if not database.tv_episode_path_in_db(path):
|
path = tv_show.path + video
|
||||||
season = int(video_match.group(1))
|
if not database.tv_episode_path_in_db(path):
|
||||||
episode = int(video_match.group(2))
|
season = int(video_match.group(1))
|
||||||
episode_name = video_match.group(3)
|
episode = int(video_match.group(2))
|
||||||
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
|
episode_name = video_match.group(3)
|
||||||
if not episode_imdb_data:
|
episode_imdb_data = database.imdb_get_tv_episode(tv_show.imdb_id, season, episode)
|
||||||
current_app.logger.info("could not get imdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
|
if not episode_imdb_data:
|
||||||
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
|
current_app.logger.info("could not get imdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
|
||||||
continue
|
print("could not get imdb data for:", tv_show.title, tv_show.year, season, episode)
|
||||||
episode_imdb_id = episode_imdb_data["tconst"]
|
continue
|
||||||
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
|
episode_imdb_id = episode_imdb_data["tconst"]
|
||||||
if not episode_tmdb_data:
|
episode_tmdb_data = database.tmdb_get_tv_episode_by_imdb_id(episode_imdb_id)
|
||||||
current_app.logger.info("could not get tmdb data for: "+tv_show.title+" "+str(tv_show.year)+" "+str(season)+" "+str(episode))
|
if not episode_tmdb_data:
|
||||||
# print("could not get tmdb data for:", tv_show.title, tv_show.year, season, episode)
|
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", "a") as f:
|
with open("/usb/storage/rpiWebApp/log.txt", "w") as f:
|
||||||
f.write("could not get tmdb data for: " + episode_imdb_id + " " + tv_show.title + " " + str(
|
f.write("could not get tmdb data for: " + episode_imdb_id + " " + tv_show.title + " " + str(
|
||||||
tv_show.year) + " " + str(season) + " " + str(episode) + "\n")
|
tv_show.year) + " " + str(season) + " " + str(episode) + "\n")
|
||||||
continue
|
continue
|
||||||
episode_tmdb_id = episode_tmdb_data[0]
|
episode_tmdb_id = episode_tmdb_data[0]
|
||||||
episode_description = episode_tmdb_data[1]
|
episode_description = episode_tmdb_data[1]
|
||||||
episode_still_path = episode_tmdb_data[2]
|
episode_still_path = episode_tmdb_data[2]
|
||||||
episodes.append((episode_imdb_id, tv_show.imdb_id, episode_tmdb_id, episode_name, season, episode,
|
episodes.append((episode_imdb_id, tv_show.imdb_id, episode_tmdb_id, episode_name, season, episode,
|
||||||
episode_description, episode_still_path, path))
|
episode_description, episode_still_path, path))
|
||||||
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
tv_episodes_loaded.send("anonymous", tv_episodes=episodes)
|
||||||
current_app.logger.info("finished load tv episodes.")
|
current_app.logger.info("finished load tv episodes.")
|
||||||
# print("finish load tv episodes.")
|
except Exception as e:
|
||||||
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import sqlite3, subprocess, os
|
import sqlite3, subprocess, os
|
||||||
|
|
||||||
RPI_IMDB_DATABASE = "/var/lib/rpiWebApp/"
|
RPI_IMDB_DATABASE = "/usb/storage/rpiWebApp/"
|
||||||
RPI_TSV_DIRECTORY = "/usb/storage/imdb-rename/"
|
RPI_TSV_DIRECTORY = "/usb/storage/imdb-rename/"
|
||||||
RPI_CSV_DIRECTORY = "/home/matt/"
|
RPI_CSV_DIRECTORY = "/home/matt/"
|
||||||
|
|
||||||
MC_IMDB_DATABASE = "C:\\Users\\Matthew\\Documents\\MyPrograms\\Websites\\rpi_web_interface\\"
|
MC_IMDB_DATABASE = "***REMOVED***"
|
||||||
MC_TSV_DIRECTORY = "C:\\\\Users\\\\Matthew\\\\Documents\\\\IMDB\\\\"
|
MC_TSV_DIRECTORY = "***REMOVED***"
|
||||||
MC_CSV_DIRECTORY = "C:\\\\Users\\\\Matthew\\\\Documents\\\\IMDB\\\\"
|
MC_CSV_DIRECTORY = "***REMOVED***"
|
||||||
|
|
||||||
|
|
||||||
IMDB_DATABASE = RPI_IMDB_DATABASE if os.path.exists(RPI_IMDB_DATABASE) else MC_IMDB_DATABASE
|
IMDB_DATABASE = RPI_IMDB_DATABASE if os.path.exists(RPI_IMDB_DATABASE) else MC_IMDB_DATABASE
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
from flask import current_app
|
from flask import current_app
|
||||||
import requests
|
import requests
|
||||||
import logging
|
|
||||||
import inspect
|
import inspect
|
||||||
logging.getLogger("requests").setLevel(logging.WARNING)
|
|
||||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
||||||
|
|
||||||
API_KEY = "***REMOVED***"
|
API_KEY = "***REMOVED***"
|
||||||
TMDB_FIND_URL = "https://api.themoviedb.org/3/find/"
|
TMDB_FIND_URL = "https://api.themoviedb.org/3/find/"
|
||||||
@ -18,18 +15,15 @@ def get_movie_data(imdb_id):
|
|||||||
"language": "en-US",
|
"language": "en-US",
|
||||||
"external_source": "imdb_id"
|
"external_source": "imdb_id"
|
||||||
}
|
}
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, data=data)
|
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
||||||
info = dict(r.json())
|
info = dict(r.json())
|
||||||
if "status_code" in info.keys():
|
if "status_code" in info.keys():
|
||||||
current_app.logger.info("error getting tmdb data, status code: "+str(info["status_code"]))
|
current_app.logger.info("error getting tmdb movie data, status code: "+str(info["status_code"])+" "+str(info["status_message"]))
|
||||||
# print("error getting tmdb data, status code:", info["status_code"])
|
|
||||||
return None
|
return None
|
||||||
if info["movie_results"] == []:
|
if info["movie_results"] == []:
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
# print("no tmdb results for:", imdb_id)
|
|
||||||
return None
|
return None
|
||||||
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
|
current_app.logger.info("tmdb movie title: " + str(info["movie_results"][0]["title"]))
|
||||||
# print("tmdb movie title:", info["movie_results"][0]["title"])
|
|
||||||
movie_id = info["movie_results"][0]["id"]
|
movie_id = info["movie_results"][0]["id"]
|
||||||
overview = info["movie_results"][0]["overview"]
|
overview = info["movie_results"][0]["overview"]
|
||||||
poster_path = info["movie_results"][0]["poster_path"]
|
poster_path = info["movie_results"][0]["poster_path"]
|
||||||
@ -38,7 +32,6 @@ def get_movie_data(imdb_id):
|
|||||||
return movie_id, overview, poster_path, backdrop_path
|
return movie_id, overview, poster_path, backdrop_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def get_tv_show_data(imdb_id):
|
def get_tv_show_data(imdb_id):
|
||||||
@ -48,18 +41,15 @@ def get_tv_show_data(imdb_id):
|
|||||||
"language": "en-US",
|
"language": "en-US",
|
||||||
"external_source": "imdb_id"
|
"external_source": "imdb_id"
|
||||||
}
|
}
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, data=data)
|
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
||||||
info = dict(r.json())
|
info = dict(r.json())
|
||||||
if "status_code" in info.keys():
|
if "status_code" in info.keys():
|
||||||
current_app.logger.info("error getting tmdb data, status code: " + str(info["status_code"]))
|
current_app.logger.info("error getting tmdb tv show data, status code: " + str(info["status_code"])+" "+str(info["status_message"]))
|
||||||
# print("error getting tmdb data, status code:", info["status_code"])
|
|
||||||
return None
|
return None
|
||||||
if info["tv_results"] == []:
|
if info["tv_results"] == []:
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
# print("no tmdb results for:", imdb_id)
|
|
||||||
return None
|
return None
|
||||||
current_app.logger.info("tmdb tv show title: " + str(info["tv_results"][0]["name"]))
|
current_app.logger.info("tmdb tv show title: " + str(info["tv_results"][0]["name"]))
|
||||||
# print("tmdb tv show title:", info["tv_results"][0]["name"])
|
|
||||||
tv_show_id = info["tv_results"][0]["id"]
|
tv_show_id = info["tv_results"][0]["id"]
|
||||||
overview = info["tv_results"][0]["overview"]
|
overview = info["tv_results"][0]["overview"]
|
||||||
poster_path = info["tv_results"][0]["poster_path"]
|
poster_path = info["tv_results"][0]["poster_path"]
|
||||||
@ -67,7 +57,6 @@ def get_tv_show_data(imdb_id):
|
|||||||
return tv_show_id, overview, poster_path
|
return tv_show_id, overview, poster_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
|
||||||
|
|
||||||
def get_tv_episode_data(imdb_id):
|
def get_tv_episode_data(imdb_id):
|
||||||
@ -77,18 +66,15 @@ def get_tv_episode_data(imdb_id):
|
|||||||
"language": "en-US",
|
"language": "en-US",
|
||||||
"external_source": "imdb_id"
|
"external_source": "imdb_id"
|
||||||
}
|
}
|
||||||
r = requests.get(TMDB_FIND_URL+imdb_id, data=data)
|
r = requests.get(TMDB_FIND_URL+imdb_id, params=data)
|
||||||
info = dict(r.json())
|
info = dict(r.json())
|
||||||
if "status_code" in info.keys():
|
if "status_code" in info.keys():
|
||||||
current_app.logger.info("error getting tmdb data, status code: " + str(info["status_code"]))
|
current_app.logger.info("error getting tmdb tv episode data, status code: " + str(info["status_code"])+" "+str(info["status_message"]))
|
||||||
# print("error getting tmdb data, status code:", info["status_code"])
|
|
||||||
return None
|
return None
|
||||||
if info["tv_episode_results"] == []:
|
if info["tv_episode_results"] == []:
|
||||||
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
current_app.logger.info("no tmdb results for: " + str(imdb_id))
|
||||||
# print("no tmdb results for:", imdb_id)
|
|
||||||
return None
|
return None
|
||||||
current_app.logger.info("tmdb tv_episode title: " + str(info["tv_episode_results"][0]["name"]))
|
current_app.logger.info("tmdb tv_episode title: " + str(info["tv_episode_results"][0]["name"]))
|
||||||
# print("tmdb tv episode title:", info["tv_episode_results"][0]["name"])
|
|
||||||
tv_episode_id = info["tv_episode_results"][0]["id"]
|
tv_episode_id = info["tv_episode_results"][0]["id"]
|
||||||
name = info["tv_episode_results"][0]["name"]
|
name = info["tv_episode_results"][0]["name"]
|
||||||
overview = info["tv_episode_results"][0]["overview"]
|
overview = info["tv_episode_results"][0]["overview"]
|
||||||
@ -97,4 +83,3 @@ def get_tv_episode_data(imdb_id):
|
|||||||
return tv_episode_id, overview, still_path
|
return tv_episode_id, overview, still_path
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
current_app.logger.info(inspect.stack()[0][3] + " " + str(type(e)) + " " + str(e))
|
||||||
# print(inspect.stack()[0][3], type(e), e)
|
|
||||||
|
BIN
static/images/Ajax-Farrell.png
Normal file
After Width: | Height: | Size: 35 KiB |
BIN
static/images/Caliber Comics.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
static/images/DC.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
static/images/Dark Horse Manga.png
Normal file
After Width: | Height: | Size: 39 KiB |
BIN
static/images/Epic.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
static/images/Fantagraphics.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
static/images/Fox Comics (US).png
Normal file
After Width: | Height: | Size: 40 KiB |
BIN
static/images/Gold Key.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
static/images/Image.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
static/images/Marvel Digital Comics Unlimited.png
Normal file
After Width: | Height: | Size: 8.2 KiB |
BIN
static/images/Marvel Knights.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
static/images/Marvel UK.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
static/images/Panini Comics.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
static/images/Sablevision.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
static/images/Storm King Comics.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
static/images/T-Publications.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
static/images/Tangent Comics.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
static/images/Yen Press.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
BIN
static/images/btn_google_signin_dark_disabled_web.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/images/btn_google_signin_dark_focus_web.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
static/images/btn_google_signin_dark_normal_web.png
Normal file
After Width: | Height: | Size: 3.9 KiB |
BIN
static/images/btn_google_signin_dark_pressed_web.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
static/images/btn_google_signin_light_disabled_web.png
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/images/btn_google_signin_light_focus_web.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
static/images/btn_google_signin_light_normal_web.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
BIN
static/images/btn_google_signin_light_pressed_web.png
Normal file
After Width: | Height: | Size: 4.0 KiB |
12
static/video-js-7.6.0/alt/video.core.min.js
vendored
20
static/video-js-7.6.0/alt/video.novtt.min.js
vendored
@ -1,34 +0,0 @@
|
|||||||
videojs.addLanguage('ar', {
|
|
||||||
"Play": "تشغيل",
|
|
||||||
"Pause": "إيقاف",
|
|
||||||
"Current Time": "الوقت الحالي",
|
|
||||||
"Duration": "مدة",
|
|
||||||
"Remaining Time": "الوقت المتبقي",
|
|
||||||
"Stream Type": "نوع التيار",
|
|
||||||
"LIVE": "مباشر",
|
|
||||||
"Loaded": "تم التحميل",
|
|
||||||
"Progress": "التقدم",
|
|
||||||
"Fullscreen": "ملء الشاشة",
|
|
||||||
"Non-Fullscreen": "تعطيل ملء الشاشة",
|
|
||||||
"Mute": "صامت",
|
|
||||||
"Unmute": "غير الصامت",
|
|
||||||
"Playback Rate": "معدل التشغيل",
|
|
||||||
"Subtitles": "الترجمة",
|
|
||||||
"subtitles off": "إيقاف الترجمة",
|
|
||||||
"Captions": "التعليقات",
|
|
||||||
"captions off": "إيقاف التعليقات",
|
|
||||||
"Chapters": "فصول",
|
|
||||||
"You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
|
|
||||||
"A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
|
|
||||||
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
|
|
||||||
"Play Video": "تشغيل الفيديو",
|
|
||||||
"Close": "أغلق",
|
|
||||||
"Modal Window": "نافذة مشروطة",
|
|
||||||
"This is a modal window": "هذه نافذة مشروطة",
|
|
||||||
"This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
|
|
||||||
", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
|
|
||||||
", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
|
|
||||||
", selected": ", مختار"
|
|
||||||
});
|
|
@ -1,34 +0,0 @@
|
|||||||
{
|
|
||||||
"Play": "تشغيل",
|
|
||||||
"Pause": "إيقاف",
|
|
||||||
"Current Time": "الوقت الحالي",
|
|
||||||
"Duration": "مدة",
|
|
||||||
"Remaining Time": "الوقت المتبقي",
|
|
||||||
"Stream Type": "نوع التيار",
|
|
||||||
"LIVE": "مباشر",
|
|
||||||
"Loaded": "تم التحميل",
|
|
||||||
"Progress": "التقدم",
|
|
||||||
"Fullscreen": "ملء الشاشة",
|
|
||||||
"Non-Fullscreen": "تعطيل ملء الشاشة",
|
|
||||||
"Mute": "صامت",
|
|
||||||
"Unmute": "غير الصامت",
|
|
||||||
"Playback Rate": "معدل التشغيل",
|
|
||||||
"Subtitles": "الترجمة",
|
|
||||||
"subtitles off": "إيقاف الترجمة",
|
|
||||||
"Captions": "التعليقات",
|
|
||||||
"captions off": "إيقاف التعليقات",
|
|
||||||
"Chapters": "فصول",
|
|
||||||
"You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
|
|
||||||
"A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
|
|
||||||
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
|
|
||||||
"Play Video": "تشغيل الفيديو",
|
|
||||||
"Close": "أغلق",
|
|
||||||
"Modal Window": "نافذة مشروطة",
|
|
||||||
"This is a modal window": "هذه نافذة مشروطة",
|
|
||||||
"This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
|
|
||||||
", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
|
|
||||||
", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
|
|
||||||
", selected": ", مختار"
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
videojs.addLanguage('es', {
|
|
||||||
"Play": "Reproducción",
|
|
||||||
"Play Video": "Reproducción Vídeo",
|
|
||||||
"Pause": "Pausa",
|
|
||||||
"Current Time": "Tiempo reproducido",
|
|
||||||
"Duration": "Duración total",
|
|
||||||
"Remaining Time": "Tiempo restante",
|
|
||||||
"Stream Type": "Tipo de secuencia",
|
|
||||||
"LIVE": "DIRECTO",
|
|
||||||
"Loaded": "Cargado",
|
|
||||||
"Progress": "Progreso",
|
|
||||||
"Fullscreen": "Pantalla completa",
|
|
||||||
"Non-Fullscreen": "Pantalla no completa",
|
|
||||||
"Mute": "Silenciar",
|
|
||||||
"Unmute": "No silenciado",
|
|
||||||
"Playback Rate": "Velocidad de reproducción",
|
|
||||||
"Subtitles": "Subtítulos",
|
|
||||||
"subtitles off": "Subtítulos desactivados",
|
|
||||||
"Captions": "Subtítulos especiales",
|
|
||||||
"captions off": "Subtítulos especiales desactivados",
|
|
||||||
"Chapters": "Capítulos",
|
|
||||||
"You aborted the media playback": "Ha interrumpido la reproducción del vídeo.",
|
|
||||||
"A network error caused the media download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
|
|
||||||
"No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo."
|
|
||||||
});
|
|
@ -1,27 +0,0 @@
|
|||||||
{
|
|
||||||
"Play": "Reproducción",
|
|
||||||
"Play Video": "Reproducción Vídeo",
|
|
||||||
"Pause": "Pausa",
|
|
||||||
"Current Time": "Tiempo reproducido",
|
|
||||||
"Duration": "Duración total",
|
|
||||||
"Remaining Time": "Tiempo restante",
|
|
||||||
"Stream Type": "Tipo de secuencia",
|
|
||||||
"LIVE": "DIRECTO",
|
|
||||||
"Loaded": "Cargado",
|
|
||||||
"Progress": "Progreso",
|
|
||||||
"Fullscreen": "Pantalla completa",
|
|
||||||
"Non-Fullscreen": "Pantalla no completa",
|
|
||||||
"Mute": "Silenciar",
|
|
||||||
"Unmute": "No silenciado",
|
|
||||||
"Playback Rate": "Velocidad de reproducción",
|
|
||||||
"Subtitles": "Subtítulos",
|
|
||||||
"subtitles off": "Subtítulos desactivados",
|
|
||||||
"Captions": "Subtítulos especiales",
|
|
||||||
"captions off": "Subtítulos especiales desactivados",
|
|
||||||
"Chapters": "Capítulos",
|
|
||||||
"You aborted the media playback": "Ha interrumpido la reproducción del vídeo.",
|
|
||||||
"A network error caused the media download to fail part-way.": "Un error de red ha interrumpido la descarga del vídeo.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "No se ha podido cargar el vídeo debido a un fallo de red o del servidor o porque el formato es incompatible.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "La reproducción de vídeo se ha interrumpido por un problema de corrupción de datos o porque el vídeo precisa funciones que su navegador no ofrece.",
|
|
||||||
"No compatible source was found for this media.": "No se ha encontrado ninguna fuente compatible con este vídeo."
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
videojs.addLanguage('nb', {
|
|
||||||
"Play": "Spill",
|
|
||||||
"Pause": "Pause",
|
|
||||||
"Current Time": "Aktuell tid",
|
|
||||||
"Duration": "Varighet",
|
|
||||||
"Remaining Time": "Gjenstående tid",
|
|
||||||
"Stream Type": "Type strøm",
|
|
||||||
"LIVE": "DIREKTE",
|
|
||||||
"Loaded": "Lastet inn",
|
|
||||||
"Progress": "Status",
|
|
||||||
"Fullscreen": "Fullskjerm",
|
|
||||||
"Non-Fullscreen": "Lukk fullskjerm",
|
|
||||||
"Mute": "Lyd av",
|
|
||||||
"Unmute": "Lyd på",
|
|
||||||
"Playback Rate": "Avspillingsrate",
|
|
||||||
"Subtitles": "Undertekst på",
|
|
||||||
"subtitles off": "Undertekst av",
|
|
||||||
"Captions": "Undertekst for hørselshemmede på",
|
|
||||||
"captions off": "Undertekst for hørselshemmede av",
|
|
||||||
"Chapters": "Kapitler",
|
|
||||||
"You aborted the media playback": "Du avbrøt avspillingen.",
|
|
||||||
"A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
|
|
||||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"Play": "Spill",
|
|
||||||
"Pause": "Pause",
|
|
||||||
"Current Time": "Aktuell tid",
|
|
||||||
"Duration": "Varighet",
|
|
||||||
"Remaining Time": "Gjenstående tid",
|
|
||||||
"Stream Type": "Type strøm",
|
|
||||||
"LIVE": "DIREKTE",
|
|
||||||
"Loaded": "Lastet inn",
|
|
||||||
"Progress": "Status",
|
|
||||||
"Fullscreen": "Fullskjerm",
|
|
||||||
"Non-Fullscreen": "Lukk fullskjerm",
|
|
||||||
"Mute": "Lyd av",
|
|
||||||
"Unmute": "Lyd på",
|
|
||||||
"Playback Rate": "Avspillingsrate",
|
|
||||||
"Subtitles": "Undertekst på",
|
|
||||||
"subtitles off": "Undertekst av",
|
|
||||||
"Captions": "Undertekst for hørselshemmede på",
|
|
||||||
"captions off": "Undertekst for hørselshemmede av",
|
|
||||||
"Chapters": "Kapitler",
|
|
||||||
"You aborted the media playback": "Du avbrøt avspillingen.",
|
|
||||||
"A network error caused the media download to fail part-way.": "En nettverksfeil avbrøt nedlasting av videoen.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikke lastes ned, på grunn av nettverksfeil eller serverfeil, eller fordi formatet ikke er støttet.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspillingen ble avbrudt på grunn av ødelagte data eller fordi videoen ville gjøre noe som nettleseren din ikke har støtte for.",
|
|
||||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
videojs.addLanguage('nn', {
|
|
||||||
"Play": "Spel",
|
|
||||||
"Pause": "Pause",
|
|
||||||
"Current Time": "Aktuell tid",
|
|
||||||
"Duration": "Varigheit",
|
|
||||||
"Remaining Time": "Tid attende",
|
|
||||||
"Stream Type": "Type straum",
|
|
||||||
"LIVE": "DIREKTE",
|
|
||||||
"Loaded": "Lasta inn",
|
|
||||||
"Progress": "Status",
|
|
||||||
"Fullscreen": "Fullskjerm",
|
|
||||||
"Non-Fullscreen": "Stenga fullskjerm",
|
|
||||||
"Mute": "Ljod av",
|
|
||||||
"Unmute": "Ljod på",
|
|
||||||
"Playback Rate": "Avspelingsrate",
|
|
||||||
"Subtitles": "Teksting på",
|
|
||||||
"subtitles off": "Teksting av",
|
|
||||||
"Captions": "Teksting for høyrselshemma på",
|
|
||||||
"captions off": "Teksting for høyrselshemma av",
|
|
||||||
"Chapters": "Kapitel",
|
|
||||||
"You aborted the media playback": "Du avbraut avspelinga.",
|
|
||||||
"A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
|
|
||||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
|
||||||
});
|
|
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"Play": "Spel",
|
|
||||||
"Pause": "Pause",
|
|
||||||
"Current Time": "Aktuell tid",
|
|
||||||
"Duration": "Varigheit",
|
|
||||||
"Remaining Time": "Tid attende",
|
|
||||||
"Stream Type": "Type straum",
|
|
||||||
"LIVE": "DIREKTE",
|
|
||||||
"Loaded": "Lasta inn",
|
|
||||||
"Progress": "Status",
|
|
||||||
"Fullscreen": "Fullskjerm",
|
|
||||||
"Non-Fullscreen": "Stenga fullskjerm",
|
|
||||||
"Mute": "Ljod av",
|
|
||||||
"Unmute": "Ljod på",
|
|
||||||
"Playback Rate": "Avspelingsrate",
|
|
||||||
"Subtitles": "Teksting på",
|
|
||||||
"subtitles off": "Teksting av",
|
|
||||||
"Captions": "Teksting for høyrselshemma på",
|
|
||||||
"captions off": "Teksting for høyrselshemma av",
|
|
||||||
"Chapters": "Kapitel",
|
|
||||||
"You aborted the media playback": "Du avbraut avspelinga.",
|
|
||||||
"A network error caused the media download to fail part-way.": "Ein nettverksfeil avbraut nedlasting av videoen.",
|
|
||||||
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "Videoen kunne ikkje lastas ned, på grunn av ein nettverksfeil eller serverfeil, eller av di formatet ikkje er stoda.",
|
|
||||||
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "Videoavspelinga blei broten på grunn av øydelagde data eller av di videoen ville gjera noe som nettlesaren din ikkje stodar.",
|
|
||||||
"No compatible source was found for this media.": "Fant ikke en kompatibel kilde for dette mediainnholdet."
|
|
||||||
}
|
|
1
static/video-js-7.6.0/video-js.min.css
vendored
20
static/video-js-7.6.0/video.min.js
vendored
@ -664,7 +664,7 @@ body.vjs-full-window {
|
|||||||
max-height: 25em;
|
max-height: 25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vjs-workinghover .vjs-menu-button-popup:hover .vjs-menu,
|
.vjs-workinghover .vjs-menu-button-popup.vjs-hover .vjs-menu,
|
||||||
.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
|
.vjs-menu-button-popup .vjs-menu.vjs-lock-showing {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -996,21 +996,23 @@ body.vjs-full-window {
|
|||||||
.video-js .vjs-volume-panel {
|
.video-js .vjs-volume-panel {
|
||||||
transition: width 1s;
|
transition: width 1s;
|
||||||
}
|
}
|
||||||
.video-js .vjs-volume-panel:hover .vjs-volume-control, .video-js .vjs-volume-panel:active .vjs-volume-control, .video-js .vjs-volume-panel:focus .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control:hover, .video-js .vjs-volume-panel .vjs-volume-control:active, .video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active {
|
.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control, .video-js .vjs-volume-panel:active .vjs-volume-control, .video-js .vjs-volume-panel:focus .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control:active, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
|
transition: visibility 0.1s, opacity 0.1s, height 0.1s, width 0.1s, left 0s, top 0s;
|
||||||
}
|
}
|
||||||
.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal {
|
.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-horizontal, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control.vjs-volume-horizontal, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-horizontal {
|
||||||
width: 5em;
|
width: 5em;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
.video-js .vjs-volume-panel:hover .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control:hover.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-mute-control:hover ~ .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical {
|
.video-js .vjs-volume-panel.vjs-hover .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:active .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel:focus .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control:active.vjs-volume-vertical, .video-js .vjs-volume-panel.vjs-hover .vjs-mute-control ~ .vjs-volume-control.vjs-volume-vertical, .video-js .vjs-volume-panel .vjs-volume-control.vjs-slider-active.vjs-volume-vertical {
|
||||||
left: -3.5em;
|
left: -3.5em;
|
||||||
|
transition: left 0s;
|
||||||
}
|
}
|
||||||
.video-js .vjs-volume-panel.vjs-volume-panel-horizontal:hover, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active {
|
.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-hover, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal:active, .video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-slider-active {
|
||||||
width: 9em;
|
width: 10em;
|
||||||
transition: width 0.1s;
|
transition: width 0.1s;
|
||||||
}
|
}
|
||||||
.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only {
|
.video-js .vjs-volume-panel.vjs-volume-panel-horizontal.vjs-mute-toggle-only {
|
1
static/video-js-7.7.5/alt/video-js-cdn.min.css
vendored
Normal file
19
static/video-js-7.7.5/alt/video.core.min.js
vendored
Normal file
19
static/video-js-7.7.5/alt/video.core.novtt.min.js
vendored
Normal file
28
static/video-js-7.7.5/alt/video.novtt.min.js
vendored
Normal file
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
86
static/video-js-7.7.5/lang/ar.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
videojs.addLanguage('ar', {
|
||||||
|
"Play": "تشغيل",
|
||||||
|
"Pause": "إيقاف",
|
||||||
|
"Current Time": "الوقت الحالي",
|
||||||
|
"Duration": "مدة",
|
||||||
|
"Remaining Time": "الوقت المتبقي",
|
||||||
|
"Stream Type": "نوع التيار",
|
||||||
|
"LIVE": "مباشر",
|
||||||
|
"Loaded": "تم التحميل",
|
||||||
|
"Progress": "التقدم",
|
||||||
|
"Fullscreen": "ملء الشاشة",
|
||||||
|
"Non-Fullscreen": "تعطيل ملء الشاشة",
|
||||||
|
"Mute": "صامت",
|
||||||
|
"Unmute": "غير الصامت",
|
||||||
|
"Playback Rate": "معدل التشغيل",
|
||||||
|
"Subtitles": "الترجمة",
|
||||||
|
"subtitles off": "إيقاف الترجمة",
|
||||||
|
"Captions": "التعليقات",
|
||||||
|
"captions off": "إيقاف التعليقات",
|
||||||
|
"Chapters": "فصول",
|
||||||
|
"You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
|
||||||
|
"A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
|
||||||
|
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
|
||||||
|
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
|
||||||
|
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
|
||||||
|
"Play Video": "تشغيل الفيديو",
|
||||||
|
"Close": "أغلق",
|
||||||
|
"Modal Window": "نافذة مشروطة",
|
||||||
|
"This is a modal window": "هذه نافذة مشروطة",
|
||||||
|
"This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
|
||||||
|
", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
|
||||||
|
", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
|
||||||
|
", selected": ", مختار",
|
||||||
|
"Audio Player": "مشغل الصوت",
|
||||||
|
"Video Player": "مشغل الفيديو",
|
||||||
|
"Replay": "إعادة التشغيل",
|
||||||
|
"Seek to live, currently behind live": "ذهاب إلى نقطة البث المباشر، متأخر عن البث المباشر حاليًا",
|
||||||
|
"Seek to live, currently playing live": "ذهاب إلى نقطة البث المباشر، البث المباشر قيد التشغيل حاليًا",
|
||||||
|
"Progress Bar": "شريط التقدم",
|
||||||
|
"Descriptions": "الأوصاف",
|
||||||
|
"descriptions off": "إخفاء الأوصاف",
|
||||||
|
"Audio Track": "المسار الصوتي",
|
||||||
|
"Volume Level": "مستوى الصوت",
|
||||||
|
"The media is encrypted and we do not have the keys to decrypt it.": "الوسائط مشفرة وليس لدينا الرموز اللازمة لفك شفرتها.",
|
||||||
|
"Close Modal Dialog": "إغلاق مربع الحوار المشروط",
|
||||||
|
", opens descriptions settings dialog": "، يفتح مربع حوار إعدادات الأوصاف",
|
||||||
|
"captions settings": "إعدادات التعليقات التوضيحية",
|
||||||
|
"subtitles settings": "إعدادات الترجمات",
|
||||||
|
"descriptions settings": "إعدادات الأوصاف",
|
||||||
|
"Text": "النص",
|
||||||
|
"White": "أبيض",
|
||||||
|
"Black": "أسود",
|
||||||
|
"Red": "أحمر",
|
||||||
|
"Green": "أخضر",
|
||||||
|
"Blue": "أزرق",
|
||||||
|
"Yellow": "أصفر",
|
||||||
|
"Magenta": "أرجواني",
|
||||||
|
"Cyan": "أزرق سماوي",
|
||||||
|
"Background": "الخلفية",
|
||||||
|
"Window": "نافذة",
|
||||||
|
"Transparent": "شفاف",
|
||||||
|
"Semi-Transparent": "نصف شفاف",
|
||||||
|
"Opaque": "معتم",
|
||||||
|
"Font Size": "حجم الخط",
|
||||||
|
"Text Edge Style": "نمط حواف النص",
|
||||||
|
"None": "لا شيء",
|
||||||
|
"Raised": "بارز",
|
||||||
|
"Depressed": "منخفض",
|
||||||
|
"Uniform": "منتظم",
|
||||||
|
"Dropshadow": "ظل خلفي",
|
||||||
|
"Font Family": "عائلة الخطوط",
|
||||||
|
"Proportional Sans-Serif": "Proportional Sans-Serif",
|
||||||
|
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
||||||
|
"Proportional Serif": "Proportional Serif",
|
||||||
|
"Monospace Serif": "Monospace Serif",
|
||||||
|
"Casual": "Casual",
|
||||||
|
"Script": "Script",
|
||||||
|
"Small Caps": "Small Caps",
|
||||||
|
"Reset": "إعادة الضبط",
|
||||||
|
"restore all settings to the default values": "استعادة كل الإعدادات إلى القيم الافتراضية",
|
||||||
|
"Done": "تم",
|
||||||
|
"Caption Settings Dialog": "مربع حوار إعدادات التعليقات التوضيحية",
|
||||||
|
"Beginning of dialog window. Escape will cancel and close the window.": "بداية نافذة مربع حوار. الضغط على زر \"Escape\" سيؤدي إلى الإلغاء وإغلاق النافذة.",
|
||||||
|
"End of dialog window.": "نهاية نافذة مربع حوار.",
|
||||||
|
"{1} is loading.": "{1} قيد التحميل."
|
||||||
|
});
|
86
static/video-js-7.7.5/lang/ar.json
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"Play": "تشغيل",
|
||||||
|
"Pause": "إيقاف",
|
||||||
|
"Current Time": "الوقت الحالي",
|
||||||
|
"Duration": "مدة",
|
||||||
|
"Remaining Time": "الوقت المتبقي",
|
||||||
|
"Stream Type": "نوع التيار",
|
||||||
|
"LIVE": "مباشر",
|
||||||
|
"Loaded": "تم التحميل",
|
||||||
|
"Progress": "التقدم",
|
||||||
|
"Fullscreen": "ملء الشاشة",
|
||||||
|
"Non-Fullscreen": "تعطيل ملء الشاشة",
|
||||||
|
"Mute": "صامت",
|
||||||
|
"Unmute": "غير الصامت",
|
||||||
|
"Playback Rate": "معدل التشغيل",
|
||||||
|
"Subtitles": "الترجمة",
|
||||||
|
"subtitles off": "إيقاف الترجمة",
|
||||||
|
"Captions": "التعليقات",
|
||||||
|
"captions off": "إيقاف التعليقات",
|
||||||
|
"Chapters": "فصول",
|
||||||
|
"You aborted the media playback": "لقد ألغيت تشغيل الفيديو",
|
||||||
|
"A network error caused the media download to fail part-way.": "تسبب خطأ في الشبكة بفشل تحميل الفيديو بالكامل.",
|
||||||
|
"The media could not be loaded, either because the server or network failed or because the format is not supported.": "لا يمكن تحميل الفيديو بسبب فشل في الخادوم أو الشبكة ، أو فشل بسبب عدم إمكانية قراءة تنسيق الفيديو.",
|
||||||
|
"The media playback was aborted due to a corruption problem or because the media used features your browser did not support.": "تم إيقاف تشغيل الفيديو بسبب مشكلة فساد أو لأن الفيديو المستخدم يستخدم ميزات غير مدعومة من متصفحك.",
|
||||||
|
"No compatible source was found for this media.": "فشل العثور على أي مصدر متوافق مع هذا الفيديو.",
|
||||||
|
"Play Video": "تشغيل الفيديو",
|
||||||
|
"Close": "أغلق",
|
||||||
|
"Modal Window": "نافذة مشروطة",
|
||||||
|
"This is a modal window": "هذه نافذة مشروطة",
|
||||||
|
"This modal can be closed by pressing the Escape key or activating the close button.": "يمكن غلق هذه النافذة المشروطة عن طريق الضغط على زر الخروج أو تفعيل زر الإغلاق",
|
||||||
|
", opens captions settings dialog": ", تفتح نافذة خيارات التعليقات",
|
||||||
|
", opens subtitles settings dialog": ", تفتح نافذة خيارات الترجمة",
|
||||||
|
", selected": ", مختار",
|
||||||
|
"Audio Player": "مشغل الصوت",
|
||||||
|
"Video Player": "مشغل الفيديو",
|
||||||
|
"Replay": "إعادة التشغيل",
|
||||||
|
"Seek to live, currently behind live": "ذهاب إلى نقطة البث المباشر، متأخر عن البث المباشر حاليًا",
|
||||||
|
"Seek to live, currently playing live": "ذهاب إلى نقطة البث المباشر، البث المباشر قيد التشغيل حاليًا",
|
||||||
|
"Progress Bar": "شريط التقدم",
|
||||||
|
"Descriptions": "الأوصاف",
|
||||||
|
"descriptions off": "إخفاء الأوصاف",
|
||||||
|
"Audio Track": "المسار الصوتي",
|
||||||
|
"Volume Level": "مستوى الصوت",
|
||||||
|
"The media is encrypted and we do not have the keys to decrypt it.": "الوسائط مشفرة وليس لدينا الرموز اللازمة لفك شفرتها.",
|
||||||
|
"Close Modal Dialog": "إغلاق مربع الحوار المشروط",
|
||||||
|
", opens descriptions settings dialog": "، يفتح مربع حوار إعدادات الأوصاف",
|
||||||
|
"captions settings": "إعدادات التعليقات التوضيحية",
|
||||||
|
"subtitles settings": "إعدادات الترجمات",
|
||||||
|
"descriptions settings": "إعدادات الأوصاف",
|
||||||
|
"Text": "النص",
|
||||||
|
"White": "أبيض",
|
||||||
|
"Black": "أسود",
|
||||||
|
"Red": "أحمر",
|
||||||
|
"Green": "أخضر",
|
||||||
|
"Blue": "أزرق",
|
||||||
|
"Yellow": "أصفر",
|
||||||
|
"Magenta": "أرجواني",
|
||||||
|
"Cyan": "أزرق سماوي",
|
||||||
|
"Background": "الخلفية",
|
||||||
|
"Window": "نافذة",
|
||||||
|
"Transparent": "شفاف",
|
||||||
|
"Semi-Transparent": "نصف شفاف",
|
||||||
|
"Opaque": "معتم",
|
||||||
|
"Font Size": "حجم الخط",
|
||||||
|
"Text Edge Style": "نمط حواف النص",
|
||||||
|
"None": "لا شيء",
|
||||||
|
"Raised": "بارز",
|
||||||
|
"Depressed": "منخفض",
|
||||||
|
"Uniform": "منتظم",
|
||||||
|
"Dropshadow": "ظل خلفي",
|
||||||
|
"Font Family": "عائلة الخطوط",
|
||||||
|
"Proportional Sans-Serif": "Proportional Sans-Serif",
|
||||||
|
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
||||||
|
"Proportional Serif": "Proportional Serif",
|
||||||
|
"Monospace Serif": "Monospace Serif",
|
||||||
|
"Casual": "Casual",
|
||||||
|
"Script": "Script",
|
||||||
|
"Small Caps": "Small Caps",
|
||||||
|
"Reset": "إعادة الضبط",
|
||||||
|
"restore all settings to the default values": "استعادة كل الإعدادات إلى القيم الافتراضية",
|
||||||
|
"Done": "تم",
|
||||||
|
"Caption Settings Dialog": "مربع حوار إعدادات التعليقات التوضيحية",
|
||||||
|
"Beginning of dialog window. Escape will cancel and close the window.": "بداية نافذة مربع حوار. الضغط على زر \"Escape\" سيؤدي إلى الإلغاء وإغلاق النافذة.",
|
||||||
|
"End of dialog window.": "نهاية نافذة مربع حوار.",
|
||||||
|
"{1} is loading.": "{1} قيد التحميل."
|
||||||
|
}
|
@ -62,13 +62,13 @@ videojs.addLanguage('de', {
|
|||||||
"Depressed": "Gedrückt",
|
"Depressed": "Gedrückt",
|
||||||
"Uniform": "Uniform",
|
"Uniform": "Uniform",
|
||||||
"Dropshadow": "Schlagschatten",
|
"Dropshadow": "Schlagschatten",
|
||||||
"Font Family": "Schristfamilie",
|
"Font Family": "Schriftfamilie",
|
||||||
"Proportional Sans-Serif": "Proportionale Sans-Serif",
|
"Proportional Sans-Serif": "Proportionale Sans-Serif",
|
||||||
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
||||||
"Proportional Serif": "Proportionale Serif",
|
"Proportional Serif": "Proportionale Serif",
|
||||||
"Monospace Serif": "Monospace Serif",
|
"Monospace Serif": "Monospace Serif",
|
||||||
"Casual": "Zwanglos",
|
"Casual": "Zwanglos",
|
||||||
"Script": "Schreibeschrift",
|
"Script": "Schreibschrift",
|
||||||
"Small Caps": "Small-Caps",
|
"Small Caps": "Small-Caps",
|
||||||
"Reset": "Zurücksetzen",
|
"Reset": "Zurücksetzen",
|
||||||
"restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
|
"restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
|
||||||
@ -80,7 +80,7 @@ videojs.addLanguage('de', {
|
|||||||
"Video Player": "Video-Player",
|
"Video Player": "Video-Player",
|
||||||
"Progress Bar": "Forschrittsbalken",
|
"Progress Bar": "Forschrittsbalken",
|
||||||
"progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
|
"progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
|
||||||
"Volume Level": "Lautstärkestufe",
|
"Volume Level": "Lautstärke",
|
||||||
"{1} is loading.": "{1} wird geladen.",
|
"{1} is loading.": "{1} wird geladen.",
|
||||||
"Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
|
"Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
|
||||||
"Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt."
|
"Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt."
|
@ -62,13 +62,13 @@
|
|||||||
"Depressed": "Gedrückt",
|
"Depressed": "Gedrückt",
|
||||||
"Uniform": "Uniform",
|
"Uniform": "Uniform",
|
||||||
"Dropshadow": "Schlagschatten",
|
"Dropshadow": "Schlagschatten",
|
||||||
"Font Family": "Schristfamilie",
|
"Font Family": "Schriftfamilie",
|
||||||
"Proportional Sans-Serif": "Proportionale Sans-Serif",
|
"Proportional Sans-Serif": "Proportionale Sans-Serif",
|
||||||
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
"Monospace Sans-Serif": "Monospace Sans-Serif",
|
||||||
"Proportional Serif": "Proportionale Serif",
|
"Proportional Serif": "Proportionale Serif",
|
||||||
"Monospace Serif": "Monospace Serif",
|
"Monospace Serif": "Monospace Serif",
|
||||||
"Casual": "Zwanglos",
|
"Casual": "Zwanglos",
|
||||||
"Script": "Schreibeschrift",
|
"Script": "Schreibschrift",
|
||||||
"Small Caps": "Small-Caps",
|
"Small Caps": "Small-Caps",
|
||||||
"Reset": "Zurücksetzen",
|
"Reset": "Zurücksetzen",
|
||||||
"restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
|
"restore all settings to the default values": "Alle Einstellungen auf die Standardwerte zurücksetzen",
|
||||||
@ -80,7 +80,7 @@
|
|||||||
"Video Player": "Video-Player",
|
"Video Player": "Video-Player",
|
||||||
"Progress Bar": "Forschrittsbalken",
|
"Progress Bar": "Forschrittsbalken",
|
||||||
"progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
|
"progress bar timing: currentTime={1} duration={2}": "{1} von {2}",
|
||||||
"Volume Level": "Lautstärkestufe",
|
"Volume Level": "Lautstärke",
|
||||||
"{1} is loading.": "{1} wird geladen.",
|
"{1} is loading.": "{1} wird geladen.",
|
||||||
"Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
|
"Seek to live, currently behind live": "Zur Live-Übertragung wechseln. Aktuell wird es nicht live abgespielt.",
|
||||||
"Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt."
|
"Seek to live, currently playing live": "Zur Live-Übertragung wechseln. Es wird aktuell live abgespielt."
|