2021-09-05 17:10:14 +00:00
|
|
|
"""
|
|
|
|
Functionality:
|
|
|
|
- all views for home app
|
2021-09-18 10:28:16 +00:00
|
|
|
- process post data received from frontend via ajax
|
2021-09-05 17:10:14 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
import json
|
2021-09-18 13:02:54 +00:00
|
|
|
import urllib.parse
|
2021-09-05 17:10:14 +00:00
|
|
|
from time import sleep
|
|
|
|
|
|
|
|
from django.http import JsonResponse
|
2021-09-18 13:02:54 +00:00
|
|
|
from django.shortcuts import redirect, render
|
2021-09-05 17:10:14 +00:00
|
|
|
from django.utils.http import urlencode
|
2021-09-18 13:02:54 +00:00
|
|
|
from django.views import View
|
2021-09-05 17:10:14 +00:00
|
|
|
from home.src.config import AppConfig
|
2021-09-18 13:02:54 +00:00
|
|
|
from home.src.download import ChannelSubscription, PendingList
|
2021-09-21 09:25:22 +00:00
|
|
|
from home.src.helper import (
|
2021-09-24 09:58:05 +00:00
|
|
|
RedisQueue,
|
2021-09-21 09:25:22 +00:00
|
|
|
get_dl_message,
|
|
|
|
get_message,
|
|
|
|
process_url_list,
|
|
|
|
set_message,
|
|
|
|
)
|
2021-09-22 04:43:38 +00:00
|
|
|
from home.src.index import WatchState
|
|
|
|
from home.src.searching import Pagination, SearchForm, SearchHandler
|
2021-09-21 09:25:22 +00:00
|
|
|
from home.tasks import (
|
|
|
|
download_pending,
|
|
|
|
download_single,
|
|
|
|
extrac_dl,
|
2021-09-24 16:37:26 +00:00
|
|
|
kill_dl,
|
2021-09-21 09:25:22 +00:00
|
|
|
run_backup,
|
|
|
|
run_manual_import,
|
|
|
|
run_restore_backup,
|
|
|
|
update_subscribed,
|
|
|
|
)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class HomeView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /
|
2021-09-09 09:45:46 +00:00
|
|
|
handle home page and video search post functionality
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
CONFIG = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
ES_URL = CONFIG["application"]["es_url"]
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def get(self, request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""return home search results"""
|
2021-09-05 17:10:14 +00:00
|
|
|
colors, sort_order, hide_watched = self.read_config()
|
|
|
|
# handle search
|
2021-09-21 09:25:22 +00:00
|
|
|
search_get = request.GET.get("search", False)
|
2021-09-05 17:10:14 +00:00
|
|
|
if search_get:
|
|
|
|
search_encoded = urllib.parse.quote(search_get)
|
|
|
|
else:
|
|
|
|
search_encoded = False
|
|
|
|
# define page size
|
2021-09-21 09:25:22 +00:00
|
|
|
page_get = int(request.GET.get("page", 0))
|
2021-09-05 17:10:14 +00:00
|
|
|
pagination_handler = Pagination(page_get, search_encoded)
|
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
url = self.ES_URL + "/ta_video/_search"
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
data = self.build_data(
|
|
|
|
pagination_handler, sort_order, search_get, hide_watched
|
|
|
|
)
|
|
|
|
|
|
|
|
search = SearchHandler(url, data)
|
|
|
|
videos_hits = search.get_data()
|
|
|
|
max_hits = search.max_hits
|
|
|
|
pagination_handler.validate(max_hits)
|
|
|
|
context = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"videos": videos_hits,
|
|
|
|
"pagination": pagination_handler.pagination,
|
|
|
|
"sortorder": sort_order,
|
|
|
|
"hide_watched": hide_watched,
|
|
|
|
"colors": colors,
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
return render(request, "home/home.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def build_data(pagination_handler, sort_order, search_get, hide_watched):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""build the data dict for the search query"""
|
|
|
|
page_size = pagination_handler.pagination["page_size"]
|
|
|
|
page_from = pagination_handler.pagination["page_from"]
|
2021-09-05 17:10:14 +00:00
|
|
|
data = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"size": page_size,
|
|
|
|
"from": page_from,
|
|
|
|
"query": {"match_all": {}},
|
2021-09-05 17:10:14 +00:00
|
|
|
"sort": [
|
|
|
|
{"published": {"order": "desc"}},
|
2021-09-21 09:25:22 +00:00
|
|
|
{"date_downloaded": {"order": "desc"}},
|
|
|
|
],
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
|
|
|
# define sort
|
2021-09-21 09:25:22 +00:00
|
|
|
if sort_order == "downloaded":
|
|
|
|
del data["sort"][0]
|
2021-09-05 17:10:14 +00:00
|
|
|
if search_get:
|
2021-09-21 09:25:22 +00:00
|
|
|
del data["sort"]
|
2021-09-05 17:10:14 +00:00
|
|
|
if hide_watched:
|
2021-09-21 09:25:22 +00:00
|
|
|
data["query"] = {"term": {"player.watched": {"value": False}}}
|
2021-09-05 17:10:14 +00:00
|
|
|
if search_get:
|
|
|
|
query = {
|
|
|
|
"multi_match": {
|
|
|
|
"query": search_get,
|
|
|
|
"fields": ["title", "channel.channel_name", "tags"],
|
|
|
|
"type": "cross_fields",
|
2021-09-21 09:25:22 +00:00
|
|
|
"operator": "and",
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
data["query"] = query
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def read_config():
|
2021-09-21 09:25:22 +00:00
|
|
|
"""read needed values from redis"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config_handler = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
colors = config_handler["application"]["colors"]
|
|
|
|
sort_order = get_message("sort_order")
|
|
|
|
hide_watched = get_message("hide_watched")
|
2021-09-05 17:10:14 +00:00
|
|
|
return colors, sort_order, hide_watched
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def post(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle post from search form"""
|
2021-09-05 17:10:14 +00:00
|
|
|
post_data = dict(request.POST)
|
2021-09-21 09:25:22 +00:00
|
|
|
search_query = post_data["videoSearch"][0]
|
|
|
|
search_url = "/?" + urlencode({"search": search_query})
|
2021-09-05 17:10:14 +00:00
|
|
|
return redirect(search_url, permanent=True)
|
|
|
|
|
|
|
|
|
|
|
|
class AboutView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /about/
|
2021-09-05 17:10:14 +00:00
|
|
|
show helpful how to information
|
|
|
|
"""
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle http get"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
colors = config["application"]["colors"]
|
|
|
|
context = {"title": "About", "colors": colors}
|
|
|
|
return render(request, "home/about.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DownloadView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /download/
|
2021-09-05 17:10:14 +00:00
|
|
|
takes POST for downloading youtube links
|
|
|
|
"""
|
|
|
|
|
2021-09-16 15:01:30 +00:00
|
|
|
def get(self, request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle get requests"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
colors = config["application"]["colors"]
|
2021-09-16 15:01:30 +00:00
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
page_get = int(request.GET.get("page", 0))
|
2021-09-16 15:01:30 +00:00
|
|
|
pagination_handler = Pagination(page_get)
|
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
url = config["application"]["es_url"] + "/ta_download/_search"
|
2021-09-16 15:01:30 +00:00
|
|
|
data = self.build_data(pagination_handler)
|
|
|
|
search = SearchHandler(url, data, cache=False)
|
|
|
|
|
|
|
|
videos_hits = search.get_data()
|
|
|
|
max_hits = search.max_hits
|
|
|
|
|
|
|
|
if videos_hits:
|
2021-09-21 09:25:22 +00:00
|
|
|
all_pending = [i["source"] for i in videos_hits]
|
2021-09-16 15:01:30 +00:00
|
|
|
pagination_handler.validate(max_hits)
|
|
|
|
pagination = pagination_handler.pagination
|
|
|
|
else:
|
|
|
|
all_pending = False
|
|
|
|
pagination = False
|
|
|
|
|
2021-09-05 17:10:14 +00:00
|
|
|
context = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"pending": all_pending,
|
|
|
|
"max_hits": max_hits,
|
|
|
|
"pagination": pagination,
|
|
|
|
"title": "Downloads",
|
|
|
|
"colors": colors,
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
return render(request, "home/downloads.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
2021-09-16 15:01:30 +00:00
|
|
|
@staticmethod
|
|
|
|
def build_data(pagination_handler):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""build data dict for search"""
|
|
|
|
page_size = pagination_handler.pagination["page_size"]
|
|
|
|
page_from = pagination_handler.pagination["page_from"]
|
2021-09-16 15:01:30 +00:00
|
|
|
data = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"size": page_size,
|
|
|
|
"from": page_from,
|
2021-09-16 15:01:30 +00:00
|
|
|
"query": {"term": {"status": {"value": "pending"}}},
|
2021-09-23 11:09:46 +00:00
|
|
|
"sort": [{"timestamp": {"order": "asc"}}],
|
2021-09-16 15:01:30 +00:00
|
|
|
}
|
|
|
|
return data
|
|
|
|
|
2021-09-05 17:10:14 +00:00
|
|
|
@staticmethod
|
|
|
|
def post(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle post requests"""
|
2021-09-05 17:10:14 +00:00
|
|
|
download_post = dict(request.POST)
|
2021-09-21 09:25:22 +00:00
|
|
|
if "vid-url" in download_post.keys():
|
|
|
|
url_str = download_post["vid-url"]
|
2021-09-23 03:50:44 +00:00
|
|
|
try:
|
|
|
|
youtube_ids = process_url_list(url_str)
|
|
|
|
except ValueError:
|
2021-09-10 08:00:10 +00:00
|
|
|
# failed to process
|
2021-09-23 03:50:44 +00:00
|
|
|
print(f"failed to parse: {url_str}")
|
2021-09-10 08:00:10 +00:00
|
|
|
mess_dict = {
|
|
|
|
"status": "downloading",
|
|
|
|
"level": "error",
|
2021-09-21 09:25:22 +00:00
|
|
|
"title": "Failed to extract links.",
|
2021-09-23 03:50:44 +00:00
|
|
|
"message": "Not a video, channel or playlist ID or URL",
|
2021-09-10 08:00:10 +00:00
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
set_message("progress:download", mess_dict)
|
|
|
|
return redirect("downloads")
|
2021-09-10 08:00:10 +00:00
|
|
|
|
2021-09-05 17:10:14 +00:00
|
|
|
print(youtube_ids)
|
|
|
|
extrac_dl.delay(youtube_ids)
|
|
|
|
|
|
|
|
sleep(2)
|
2021-09-21 09:25:22 +00:00
|
|
|
return redirect("downloads", permanent=True)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ChannelIdView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /channel/<channel-id>/
|
2021-09-09 09:45:46 +00:00
|
|
|
display single channel page from channel_id
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def get(self, request, channel_id_detail):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""get method"""
|
2021-09-05 17:10:14 +00:00
|
|
|
es_url, colors = self.read_config()
|
|
|
|
context = self.get_channel_videos(request, channel_id_detail, es_url)
|
2021-09-21 09:25:22 +00:00
|
|
|
context.update({"colors": colors})
|
|
|
|
return render(request, "home/channel_id.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def read_config():
|
2021-09-21 09:25:22 +00:00
|
|
|
"""read config file"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
es_url = config["application"]["es_url"]
|
|
|
|
colors = config["application"]["colors"]
|
2021-09-05 17:10:14 +00:00
|
|
|
return es_url, colors
|
|
|
|
|
|
|
|
def get_channel_videos(self, request, channel_id_detail, es_url):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""get channel from video index"""
|
|
|
|
page_get = int(request.GET.get("page", 0))
|
2021-09-05 17:10:14 +00:00
|
|
|
pagination_handler = Pagination(page_get)
|
|
|
|
# get data
|
2021-09-21 09:25:22 +00:00
|
|
|
url = es_url + "/ta_video/_search"
|
2021-09-05 17:10:14 +00:00
|
|
|
data = self.build_data(pagination_handler, channel_id_detail)
|
|
|
|
search = SearchHandler(url, data)
|
|
|
|
videos_hits = search.get_data()
|
|
|
|
max_hits = search.max_hits
|
|
|
|
if max_hits:
|
2021-09-21 09:25:22 +00:00
|
|
|
channel_info = videos_hits[0]["source"]["channel"]
|
|
|
|
channel_name = channel_info["channel_name"]
|
2021-09-05 17:10:14 +00:00
|
|
|
pagination_handler.validate(max_hits)
|
|
|
|
pagination = pagination_handler.pagination
|
|
|
|
else:
|
|
|
|
# get details from channel index when when no hits
|
|
|
|
channel_info, channel_name = self.get_channel_info(
|
|
|
|
channel_id_detail, es_url
|
|
|
|
)
|
|
|
|
videos_hits = False
|
|
|
|
pagination = False
|
|
|
|
|
|
|
|
context = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"channel_info": channel_info,
|
|
|
|
"videos": videos_hits,
|
|
|
|
"max_hits": max_hits,
|
|
|
|
"pagination": pagination,
|
|
|
|
"title": "Channel: " + channel_name,
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return context
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def build_data(pagination_handler, channel_id_detail):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""build data dict for search"""
|
|
|
|
page_size = pagination_handler.pagination["page_size"]
|
|
|
|
page_from = pagination_handler.pagination["page_from"]
|
2021-09-05 17:10:14 +00:00
|
|
|
data = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"size": page_size,
|
|
|
|
"from": page_from,
|
2021-09-05 17:10:14 +00:00
|
|
|
"query": {
|
|
|
|
"term": {"channel.channel_id": {"value": channel_id_detail}}
|
|
|
|
},
|
|
|
|
"sort": [
|
|
|
|
{"published": {"order": "desc"}},
|
2021-09-21 09:25:22 +00:00
|
|
|
{"date_downloaded": {"order": "desc"}},
|
|
|
|
],
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
|
|
|
return data
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get_channel_info(channel_id_detail, es_url):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""get channel info from channel index if no videos"""
|
|
|
|
url = f"{es_url}/ta_channel/_doc/{channel_id_detail}"
|
2021-09-05 17:10:14 +00:00
|
|
|
data = False
|
|
|
|
search = SearchHandler(url, data)
|
|
|
|
channel_data = search.get_data()
|
2021-09-21 09:25:22 +00:00
|
|
|
channel_info = channel_data[0]["source"]
|
|
|
|
channel_name = channel_info["channel_name"]
|
2021-09-05 17:10:14 +00:00
|
|
|
return channel_info, channel_name
|
|
|
|
|
|
|
|
|
|
|
|
class ChannelView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /channel/
|
2021-09-09 09:45:46 +00:00
|
|
|
handle functionality for channel overview page, subscribe to channel,
|
|
|
|
search as you type for channel name
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def get(self, request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle http get requests"""
|
2021-09-05 17:10:14 +00:00
|
|
|
es_url, colors = self.read_config()
|
2021-09-21 09:25:22 +00:00
|
|
|
page_get = int(request.GET.get("page", 0))
|
2021-09-05 17:10:14 +00:00
|
|
|
pagination_handler = Pagination(page_get)
|
2021-09-21 09:25:22 +00:00
|
|
|
page_size = pagination_handler.pagination["page_size"]
|
|
|
|
page_from = pagination_handler.pagination["page_from"]
|
2021-09-05 17:10:14 +00:00
|
|
|
# get
|
2021-09-21 09:25:22 +00:00
|
|
|
url = es_url + "/ta_channel/_search"
|
2021-09-05 17:10:14 +00:00
|
|
|
data = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"size": page_size,
|
|
|
|
"from": page_from,
|
|
|
|
"query": {"match_all": {}},
|
|
|
|
"sort": [{"channel_name.keyword": {"order": "asc"}}],
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
show_subed_only = get_message("show_subed_only")
|
2021-09-05 17:10:14 +00:00
|
|
|
if show_subed_only:
|
2021-09-21 09:25:22 +00:00
|
|
|
data["query"] = {"term": {"channel_subscribed": {"value": True}}}
|
2021-09-05 17:10:14 +00:00
|
|
|
search = SearchHandler(url, data)
|
|
|
|
channel_hits = search.get_data()
|
|
|
|
max_hits = search.max_hits
|
|
|
|
pagination_handler.validate(search.max_hits)
|
|
|
|
context = {
|
2021-09-21 09:25:22 +00:00
|
|
|
"channels": channel_hits,
|
|
|
|
"max_hits": max_hits,
|
|
|
|
"pagination": pagination_handler.pagination,
|
|
|
|
"show_subed_only": show_subed_only,
|
|
|
|
"title": "Channels",
|
|
|
|
"colors": colors,
|
2021-09-05 17:10:14 +00:00
|
|
|
}
|
2021-09-21 09:25:22 +00:00
|
|
|
return render(request, "home/channel.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def read_config():
|
2021-09-21 09:25:22 +00:00
|
|
|
"""read config file"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
es_url = config["application"]["es_url"]
|
|
|
|
colors = config["application"]["colors"]
|
2021-09-05 17:10:14 +00:00
|
|
|
return es_url, colors
|
|
|
|
|
2021-09-15 14:09:46 +00:00
|
|
|
def post(self, request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle http post requests"""
|
2021-09-05 17:10:14 +00:00
|
|
|
subscriptions_post = dict(request.POST)
|
|
|
|
print(subscriptions_post)
|
|
|
|
subscriptions_post = dict(request.POST)
|
2021-09-21 09:25:22 +00:00
|
|
|
if "subscribe" in subscriptions_post.keys():
|
|
|
|
sub_str = subscriptions_post["subscribe"]
|
2021-09-15 14:09:46 +00:00
|
|
|
try:
|
|
|
|
youtube_ids = process_url_list(sub_str)
|
|
|
|
self.subscribe_to(youtube_ids)
|
|
|
|
except ValueError:
|
2021-09-21 09:25:22 +00:00
|
|
|
print("parsing subscribe ids failed!")
|
2021-09-15 14:09:46 +00:00
|
|
|
print(sub_str)
|
|
|
|
|
|
|
|
sleep(1)
|
2021-09-21 09:25:22 +00:00
|
|
|
return redirect("channel", permanent=True)
|
2021-09-15 14:09:46 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def subscribe_to(youtube_ids):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""process the subscribe ids"""
|
2021-09-15 14:09:46 +00:00
|
|
|
for youtube_id in youtube_ids:
|
2021-09-21 09:25:22 +00:00
|
|
|
if youtube_id["type"] == "video":
|
|
|
|
to_sub = youtube_id["url"]
|
2021-09-15 14:09:46 +00:00
|
|
|
vid_details = PendingList().get_youtube_details(to_sub)
|
2021-09-21 09:25:22 +00:00
|
|
|
channel_id_sub = vid_details["channel_id"]
|
|
|
|
elif youtube_id["type"] == "channel":
|
|
|
|
channel_id_sub = youtube_id["url"]
|
2021-09-05 17:10:14 +00:00
|
|
|
else:
|
2021-09-21 09:25:22 +00:00
|
|
|
raise ValueError("failed to subscribe to: " + youtube_id)
|
2021-09-15 14:09:46 +00:00
|
|
|
|
2021-09-05 17:10:14 +00:00
|
|
|
ChannelSubscription().change_subscribe(
|
|
|
|
channel_id_sub, channel_subscribed=True
|
|
|
|
)
|
2021-09-21 09:25:22 +00:00
|
|
|
print("subscribed to: " + channel_id_sub)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class VideoView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /video/<video-id>/
|
2021-09-09 09:45:46 +00:00
|
|
|
display details about a single video
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def get(self, request, video_id):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""get single video"""
|
2021-09-05 17:10:14 +00:00
|
|
|
es_url, colors = self.read_config()
|
2021-09-21 09:25:22 +00:00
|
|
|
url = f"{es_url}/ta_video/_doc/{video_id}"
|
2021-09-05 17:10:14 +00:00
|
|
|
data = None
|
|
|
|
look_up = SearchHandler(url, data)
|
|
|
|
video_hit = look_up.get_data()
|
2021-09-21 09:25:22 +00:00
|
|
|
video_data = video_hit[0]["source"]
|
|
|
|
video_title = video_data["title"]
|
|
|
|
context = {"video": video_data, "title": video_title, "colors": colors}
|
|
|
|
return render(request, "home/video.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def read_config():
|
2021-09-21 09:25:22 +00:00
|
|
|
"""read config file"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
es_url = config["application"]["es_url"]
|
|
|
|
colors = config["application"]["colors"]
|
2021-09-05 17:10:14 +00:00
|
|
|
return es_url, colors
|
|
|
|
|
|
|
|
|
|
|
|
class SettingsView(View):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""resolves to /settings/
|
2021-09-09 09:45:46 +00:00
|
|
|
handle the settings page, display current settings,
|
|
|
|
take post request from the form to update settings
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def get(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""read and display current settings"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
colors = config["application"]["colors"]
|
2021-09-05 17:10:14 +00:00
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
context = {"title": "Settings", "config": config, "colors": colors}
|
2021-09-05 17:10:14 +00:00
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
return render(request, "home/settings.html", context)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def post(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle form post to update settings"""
|
2021-09-05 17:10:14 +00:00
|
|
|
form_post = dict(request.POST)
|
2021-09-21 09:25:22 +00:00
|
|
|
del form_post["csrfmiddlewaretoken"]
|
2021-09-05 17:10:14 +00:00
|
|
|
print(form_post)
|
|
|
|
config_handler = AppConfig()
|
|
|
|
config_handler.update_config(form_post)
|
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
return redirect("settings", permanent=True)
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
def progress(request):
|
|
|
|
# pylint: disable=unused-argument
|
2021-09-21 09:25:22 +00:00
|
|
|
"""endpoint for download progress ajax calls"""
|
2021-09-05 17:10:14 +00:00
|
|
|
config = AppConfig().config
|
2021-09-21 09:25:22 +00:00
|
|
|
cache_dir = config["application"]["cache_dir"]
|
2021-09-05 17:10:14 +00:00
|
|
|
json_data = get_dl_message(cache_dir)
|
|
|
|
return JsonResponse(json_data)
|
|
|
|
|
|
|
|
|
|
|
|
def process(request):
|
2021-09-21 09:25:22 +00:00
|
|
|
"""handle all the buttons calls via POST ajax"""
|
|
|
|
if request.method == "POST":
|
2021-09-05 17:10:14 +00:00
|
|
|
post_dict = json.loads(request.body.decode())
|
|
|
|
post_handler = PostData(post_dict)
|
2021-09-22 04:43:38 +00:00
|
|
|
if post_handler.to_exec:
|
2021-09-05 17:10:14 +00:00
|
|
|
task_result = post_handler.run_task()
|
|
|
|
return JsonResponse(task_result)
|
|
|
|
|
2021-09-21 09:25:22 +00:00
|
|
|
return JsonResponse({"success": False})
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
class PostData:
|
2021-09-22 04:43:38 +00:00
|
|
|
"""
|
|
|
|
map frontend http post values to backend funcs
|
|
|
|
handover long running tasks to celery
|
|
|
|
"""
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def __init__(self, post_dict):
|
|
|
|
self.post_dict = post_dict
|
2021-09-22 04:43:38 +00:00
|
|
|
self.to_exec, self.exec_val = list(post_dict.items())[0]
|
2021-09-05 17:10:14 +00:00
|
|
|
|
|
|
|
def run_task(self):
|
2021-09-22 04:43:38 +00:00
|
|
|
"""execute and return task result"""
|
|
|
|
to_exec = self.exec_map()
|
|
|
|
task_result = to_exec()
|
|
|
|
return task_result
|
|
|
|
|
|
|
|
def exec_map(self):
|
|
|
|
"""map dict key and return function to execute"""
|
|
|
|
exec_map = {
|
|
|
|
"watched": self.watched,
|
|
|
|
"rescan_pending": self.rescan_pending,
|
|
|
|
"ignore": self.ignore,
|
|
|
|
"dl_pending": self.dl_pending,
|
2021-09-24 11:03:22 +00:00
|
|
|
"queue": self.queue_handler,
|
2021-09-22 04:43:38 +00:00
|
|
|
"unsubscribe": self.unsubscribe,
|
|
|
|
"sort_order": self.sort_order,
|
|
|
|
"hide_watched": self.hide_watched,
|
|
|
|
"show_subed_only": self.show_subed_only,
|
|
|
|
"dlnow": self.dlnow,
|
|
|
|
"manual-import": self.manual_import,
|
|
|
|
"db-backup": self.db_backup,
|
|
|
|
"db-restore": self.db_restore,
|
|
|
|
"channel-search": self.channel_search,
|
|
|
|
}
|
|
|
|
|
|
|
|
return exec_map[self.to_exec]
|
|
|
|
|
|
|
|
def watched(self):
|
|
|
|
"""mark as watched"""
|
|
|
|
WatchState(self.exec_val).mark_as_watched()
|
2021-09-21 09:25:22 +00:00
|
|
|
return {"success": True}
|
2021-09-05 17:10:14 +00:00
|
|
|
|
2021-09-22 04:43:38 +00:00
|
|
|
@staticmethod
|
|
|
|
def rescan_pending():
|
|
|
|
"""look for new items in subscribed channels"""
|
|
|
|
print("rescan subscribed channels")
|
|
|
|
update_subscribed.delay()
|
|
|
|
return {"success": True}
|
2021-09-05 17:10:14 +00:00
|
|
|
|
2021-09-22 04:43:38 +00:00
|
|
|
def ignore(self):
|
|
|
|
"""ignore from download queue"""
|
2021-09-24 09:58:05 +00:00
|
|
|
id_to_ignore = self.exec_val
|
|
|
|
print("ignore video " + id_to_ignore)
|
2021-09-22 04:43:38 +00:00
|
|
|
handler = PendingList()
|
2021-09-24 09:58:05 +00:00
|
|
|
handler.ignore_from_pending([id_to_ignore])
|
|
|
|
# also clear from redis queue
|
|
|
|
RedisQueue("dl_queue").clear_item(id_to_ignore)
|
2021-09-22 04:43:38 +00:00
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def dl_pending():
|
|
|
|
"""start the download queue"""
|
|
|
|
print("download pending")
|
2021-09-24 16:37:26 +00:00
|
|
|
running = download_pending.delay()
|
|
|
|
task_id = running.id
|
|
|
|
print("set task id: " + task_id)
|
|
|
|
set_message("dl_queue_id", task_id, expire=False)
|
2021-09-22 04:43:38 +00:00
|
|
|
return {"success": True}
|
|
|
|
|
2021-09-24 11:03:22 +00:00
|
|
|
def queue_handler(self):
|
|
|
|
"""queue controls from frontend"""
|
|
|
|
to_execute = self.exec_val
|
|
|
|
if to_execute == "stop":
|
|
|
|
print("stopping download queue")
|
|
|
|
RedisQueue("dl_queue").clear()
|
2021-09-25 08:35:36 +00:00
|
|
|
elif to_execute == "kill":
|
|
|
|
task_id = get_message("dl_queue_id")
|
|
|
|
print("brutally killing " + task_id)
|
|
|
|
kill_dl(task_id)
|
2021-09-24 11:03:22 +00:00
|
|
|
|
|
|
|
return {"success": True}
|
|
|
|
|
2021-09-22 04:43:38 +00:00
|
|
|
def unsubscribe(self):
|
|
|
|
"""unsubscribe from channel"""
|
|
|
|
channel_id_unsub = self.exec_val
|
|
|
|
print("unsubscribe from " + channel_id_unsub)
|
|
|
|
ChannelSubscription().change_subscribe(
|
|
|
|
channel_id_unsub, channel_subscribed=False
|
|
|
|
)
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
def sort_order(self):
|
|
|
|
"""change the sort between published to downloaded"""
|
|
|
|
sort_order = self.exec_val
|
|
|
|
set_message("sort_order", sort_order, expire=False)
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
def hide_watched(self):
|
|
|
|
"""toggle if to show watched vids or not"""
|
|
|
|
hide_watched = bool(int(self.exec_val))
|
|
|
|
print(f"hide watched: {hide_watched}")
|
|
|
|
set_message("hide_watched", hide_watched, expire=False)
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
def show_subed_only(self):
|
|
|
|
"""show or hide subscribed channels only on channels page"""
|
|
|
|
show_subed_only = bool(int(self.exec_val))
|
|
|
|
print(f"show subed only: {show_subed_only}")
|
|
|
|
set_message("show_subed_only", show_subed_only, expire=False)
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
def dlnow(self):
|
|
|
|
"""start downloading single vid now"""
|
|
|
|
youtube_id = self.exec_val
|
|
|
|
print("downloading: " + youtube_id)
|
2021-09-25 10:40:33 +00:00
|
|
|
running = download_single.delay(youtube_id=youtube_id)
|
|
|
|
task_id = running.id
|
|
|
|
print("set task id: " + task_id)
|
|
|
|
set_message("dl_queue_id", task_id, expire=False)
|
2021-09-22 04:43:38 +00:00
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def manual_import():
|
|
|
|
"""run manual import from settings page"""
|
|
|
|
print("starting manual import")
|
|
|
|
run_manual_import.delay()
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def db_backup():
|
|
|
|
"""backup es to zip from settings page"""
|
|
|
|
print("backing up database")
|
|
|
|
run_backup.delay()
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def db_restore():
|
|
|
|
"""restore es zip from settings page"""
|
|
|
|
print("restoring index from backup zip")
|
|
|
|
run_restore_backup.delay()
|
|
|
|
return {"success": True}
|
|
|
|
|
|
|
|
def channel_search(self):
|
|
|
|
"""search for channel name as_you_type"""
|
|
|
|
search_query = self.exec_val
|
|
|
|
print("searching for: " + search_query)
|
|
|
|
search_results = SearchForm().search_channels(search_query)
|
|
|
|
return search_results
|