diff --git a/tubearchivist/home/apps.py b/tubearchivist/home/apps.py index 3957f5e..8911e3b 100644 --- a/tubearchivist/home/apps.py +++ b/tubearchivist/home/apps.py @@ -1,7 +1,6 @@ """handle custom startup functions""" import os -import sys from django.apps import AppConfig from home.src.es.connect import ElasticWrap @@ -105,7 +104,7 @@ class StartupCheck: "required elasticsearch version: " + f"{self.MIN_MAJOR}.{self.MIN_MINOR}" ) - sys.exit(1) + # sys.exit(1) print("elasticsearch version check passed") diff --git a/tubearchivist/home/templates/home/channel_id.html b/tubearchivist/home/templates/home/channel_id.html index 5aefcba..1e5b1b4 100644 --- a/tubearchivist/home/templates/home/channel_id.html +++ b/tubearchivist/home/templates/home/channel_id.html @@ -6,8 +6,13 @@
channel_banner
+
+

Videos

+

Playlists

+

About

+
-
+
-

Last refreshed: {{ channel_info.channel_last_refresh }}

- {% if channel_info.channel_active %} -

Youtube: Active

- {% else %} -

Youtube: Deactivated

- {% endif %} - -
- Delete {{ channel_info.channel_name }} including all videos? -
-
-
-
-
- {% if channel_info.channel_views >= 1000000 %} -

Channel views: {{ channel_info.channel_views|intword }}

- {% elif channel_info.channel_views > 0 %} -

Channel views: {{ channel_info.channel_views|intcomma }}

- {% endif %} {% if max_hits %} -

Total Videos archived: {{ max_hits }}

-

Watched:

+

Total Videos: {{ max_hits }}

+ {% endif %} - -
-
-
-
- {% csrf_token %} -
-

Download format: - {% if channel_info.channel_overwrites.download_format %} - {{ channel_info.channel_overwrites.download_format }} - {% else %} - False - {% endif %}

- {{ channel_overwrite_form.download_format }}
-
-
-

Auto delete watched videos after x days: - {% if channel_info.channel_overwrites.autodelete_days %} - {{ channel_info.channel_overwrites.autodelete_days }} - {% else %} - False - {% endif %}

- {{ channel_overwrite_form.autodelete_days }}
-
-
-

Index playlists: - {% if channel_info.channel_overwrites.index_playlists %} - {{ channel_info.channel_overwrites.index_playlists }} - {% else %} - False - {% endif %}

- {{ channel_overwrite_form.index_playlists }}
-
-
-

Enable SponsorBlock: - {% if channel_info.channel_overwrites.integrate_sponsorblock %} - {{ channel_info.channel_overwrites.integrate_sponsorblock }} - {% elif channel_info.channel_overwrites.integrate_sponsorblock == False %} - Disabled - {% else %} - False - {% endif %}

- {{ channel_overwrite_form.integrate_sponsorblock }}
-
- -
-
-
- {% if channel_info.channel_description %} -
-

Description:

-
- {{ channel_info.channel_description|linebreaks }} -
-
- {% endif %}
diff --git a/tubearchivist/home/templates/home/channel_id_about.html b/tubearchivist/home/templates/home/channel_id_about.html new file mode 100644 index 0000000..2b7a439 --- /dev/null +++ b/tubearchivist/home/templates/home/channel_id_about.html @@ -0,0 +1,114 @@ +{% extends "home/base.html" %} +{% block content %} +{% load static %} +{% load humanize %} +
+
+ channel_banner +
+ +
+
+
+ + channel-thumb + +
+
+

{{ channel_info.channel_name }}

+ {% if channel_info.channel_subs >= 1000000 %} +

Subscribers: {{ channel_info.channel_subs|intword }}

+ {% else %} +

Subscribers: {{ channel_info.channel_subs|intcomma }}

+ {% endif %} +
+
+
+
+

Last refreshed: {{ channel_info.channel_last_refresh }}

+ {% if channel_info.channel_active %} +

Youtube: Active

+ {% else %} +

Youtube: Deactivated

+ {% endif %} +
+
+
+
+ {% if channel_info.channel_views >= 1000000 %} +

Channel views: {{ channel_info.channel_views|intword }}

+ {% elif channel_info.channel_views > 0 %} +

Channel views: {{ channel_info.channel_views|intcomma }}

+ {% endif %} + +
+ Delete {{ channel_info.channel_name }} including all videos? +
+
+
+
+ {% if channel_info.channel_description %} +
+

Description

+
+
+
+ {{ channel_info.channel_description|linebreaks }} +
+
+ {% endif %} +
+

Costomize {{ channel_info.channel_name }}

+
+
+
+
+ {% csrf_token %} +
+

Download format: + {% if channel_info.channel_overwrites.download_format %} + {{ channel_info.channel_overwrites.download_format }} + {% else %} + False + {% endif %}

+ {{ channel_overwrite_form.download_format }}
+
+
+

Auto delete watched videos after x days: + {% if channel_info.channel_overwrites.autodelete_days %} + {{ channel_info.channel_overwrites.autodelete_days }} + {% else %} + False + {% endif %}

+ {{ channel_overwrite_form.autodelete_days }}
+
+
+

Index playlists: + {% if channel_info.channel_overwrites.index_playlists %} + {{ channel_info.channel_overwrites.index_playlists }} + {% else %} + False + {% endif %}

+ {{ channel_overwrite_form.index_playlists }}
+
+
+

Enable SponsorBlock: + {% if channel_info.channel_overwrites.integrate_sponsorblock %} + {{ channel_info.channel_overwrites.integrate_sponsorblock }} + {% elif channel_info.channel_overwrites.integrate_sponsorblock == False %} + Disabled + {% else %} + False + {% endif %}

+ {{ channel_overwrite_form.integrate_sponsorblock }}
+
+ +
+
+
+
+{% endblock content %} \ No newline at end of file diff --git a/tubearchivist/home/templates/home/channel_id_playlist.html b/tubearchivist/home/templates/home/channel_id_playlist.html new file mode 100644 index 0000000..b7f5891 --- /dev/null +++ b/tubearchivist/home/templates/home/channel_id_playlist.html @@ -0,0 +1,57 @@ +{% extends "home/base.html" %} +{% block content %} +{% load static %} +{% load humanize %} +
+
+ channel_banner +
+ +
+
+ Show subscribed only: +
+ + {% if not show_subed_only %} + + {% else %} + + {% endif %} +
+
+
+ grid view + list view +
+
+
+ {% if results %} + {% for playlist in results %} +
+
+ + {{ playlist.source.playlist_id }}-thumbnail + +
+
+

{{ playlist.source.playlist_channel }}

+

{{ playlist.source.playlist_name }}

+

Last refreshed: {{ playlist.source.playlist_last_refresh }}

+ {% if playlist.source.playlist_subscribed %} + + {% else %} + + {% endif %} +
+
+ {% endfor %} + {% else %} +

No playlists found...

+ {% endif %} +
+
+{% endblock content %} \ No newline at end of file diff --git a/tubearchivist/home/urls.py b/tubearchivist/home/urls.py index 972e4a5..521ed3b 100644 --- a/tubearchivist/home/urls.py +++ b/tubearchivist/home/urls.py @@ -6,6 +6,8 @@ from django.contrib.auth.views import LogoutView from django.urls import path from home.views import ( AboutView, + ChannelIdAboutView, + ChannelIdPlaylistView, ChannelIdView, ChannelView, DownloadView, @@ -42,6 +44,16 @@ urlpatterns = [ login_required(ChannelIdView.as_view()), name="channel_id", ), + path( + "channel//about/", + login_required(ChannelIdAboutView.as_view()), + name="channel_id_about", + ), + path( + "channel//playlist/", + login_required(ChannelIdPlaylistView.as_view()), + name="channel_id_playlist", + ), path( "video//", login_required(VideoView.as_view()), diff --git a/tubearchivist/home/views.py b/tubearchivist/home/views.py index bb30e8d..85fe41e 100644 --- a/tubearchivist/home/views.py +++ b/tubearchivist/home/views.py @@ -8,6 +8,7 @@ import json import urllib.parse from time import sleep +from api.src.search_processor import SearchProcess from django.conf import settings from django.contrib.auth import login from django.contrib.auth.forms import AuthenticationForm @@ -15,6 +16,7 @@ from django.http import JsonResponse from django.shortcuts import redirect, render from django.views import View from home.src.download.yt_dlp_base import CookieHandler +from home.src.es.connect import ElasticWrap from home.src.es.index_setup import get_available_backups from home.src.frontend.api_calls import PostData from home.src.frontend.forms import ( @@ -440,7 +442,6 @@ class ChannelIdView(ArchivistResultsView): { "title": "Channel: " + channel_name, "channel_info": channel_info, - "channel_overwrite_form": ChannelOverwriteForm, } ) @@ -477,6 +478,93 @@ class ChannelIdView(ArchivistResultsView): return redirect("channel_id", channel_id, permanent=True) +class ChannelIdAboutView(ArchivistResultsView): + """resolves to /channel//about/ + show metadata, handle per channel conf + """ + + view_origin = "channel" + + def get(self, request, channel_id): + """handle get request""" + self.initiate_vars(request) + + path = f"ta_channel/_doc/{channel_id}" + response, _ = ElasticWrap(path).get() + + channel_info = SearchProcess(response).process() + channel_name = channel_info["channel_name"] + + self.context.update( + { + "title": "Channel: About " + channel_name, + "channel_info": channel_info, + "channel_overwrite_form": ChannelOverwriteForm, + } + ) + + return render(request, "home/channel_id_about.html", self.context) + + @staticmethod + def post(request, channel_id): + """handle post request""" + print(f"handle post from {channel_id}") + channel_overwrite_form = ChannelOverwriteForm(request.POST) + if channel_overwrite_form.is_valid(): + overwrites = channel_overwrite_form.cleaned_data + print(f"{channel_id}: set overwrites {overwrites}") + channel_overwrites(channel_id, overwrites=overwrites) + if overwrites.get("index_playlists") == "1": + index_channel_playlists.delay(channel_id) + + sleep(1) + return redirect("channel_id_about", channel_id, permanent=True) + + +class ChannelIdPlaylistView(ArchivistResultsView): + """resolves to /channel//playlist/ + show all playlists of channel + """ + + view_origin = "playlist" + es_search = "ta_playlist/_search" + + def get(self, request, channel_id): + """handle get request""" + self.initiate_vars(request) + self._update_view_data(channel_id) + self.find_results() + + channel_info = self._get_channel_meta(channel_id) + channel_name = channel_info["channel_name"] + self.context.update( + { + "title": "Channel: Playlists " + channel_name, + "channel_info": channel_info, + } + ) + + return render(request, "home/channel_id_playlist.html", self.context) + + def _update_view_data(self, channel_id): + """update view specific data dict""" + self.data["sort"] = [{"playlist_name.keyword": {"order": "asc"}}] + must_list = [{"match": {"playlist_channel_id": channel_id}}] + + if self.context["show_subed_only"]: + must_list.append({"match": {"playlist_subscribed": True}}) + + self.data["query"] = {"bool": {"must": must_list}} + + def _get_channel_meta(self, channel_id): + """get metadata for channel""" + path = f"ta_channel/_doc/{channel_id}" + response, _ = ElasticWrap(path).get() + channel_info = SearchProcess(response).process() + + return channel_info + + class ChannelView(ArchivistResultsView): """resolves to /channel/ handle functionality for channel overview page, subscribe to channel, diff --git a/tubearchivist/requirements.txt b/tubearchivist/requirements.txt index 59b8f7e..be126c9 100644 --- a/tubearchivist/requirements.txt +++ b/tubearchivist/requirements.txt @@ -1,6 +1,6 @@ beautifulsoup4==4.11.1 celery==5.2.7 -Django==4.0.5 +Django==4.0.6 django-cors-headers==3.13.0 djangorestframework==3.13.1 Pillow==9.2.0 diff --git a/tubearchivist/static/css/style.css b/tubearchivist/static/css/style.css index 45a7c0a..e34f74a 100644 --- a/tubearchivist/static/css/style.css +++ b/tubearchivist/static/css/style.css @@ -817,6 +817,18 @@ button:hover { transform: translateX(-30%); } +.info-box-item.channel-nav { + justify-content: center; +} + +.info-box-item.channel-nav a { + padding: 0 1rem; +} + +.info-box-item.channel-nav a:hover { + text-decoration: underline; +} + /* playlist overview page */ .playlist-list.list { display: grid;