From a4e01da27c08e43a67b2618ad1e71c1f8f86d5cd Mon Sep 17 00:00:00 2001 From: Biswakalyan Bhuyan Date: Thu, 19 Sep 2024 15:33:11 +0530 Subject: youtube fronend --- youtube/templates/base.html | 179 +++++++++++++++++++ youtube/templates/channel.html | 133 ++++++++++++++ youtube/templates/comments.html | 65 +++++++ youtube/templates/comments_page.html | 47 +++++ youtube/templates/common_elements.html | 140 +++++++++++++++ youtube/templates/embed.html | 74 ++++++++ youtube/templates/error.html | 36 ++++ youtube/templates/home.html | 13 ++ youtube/templates/licenses.html | 64 +++++++ youtube/templates/local_playlist.html | 49 ++++++ youtube/templates/local_playlists_list.html | 14 ++ youtube/templates/playlist.html | 41 +++++ youtube/templates/search.html | 34 ++++ youtube/templates/settings.html | 47 +++++ youtube/templates/shared.css | 5 + youtube/templates/status.html | 6 + youtube/templates/subscription_manager.html | 78 +++++++++ youtube/templates/subscriptions.html | 83 +++++++++ youtube/templates/subscriptions.xml | 9 + youtube/templates/unsubscribe_verify.html | 21 +++ youtube/templates/watch.html | 263 ++++++++++++++++++++++++++++ 21 files changed, 1401 insertions(+) create mode 100644 youtube/templates/base.html create mode 100644 youtube/templates/channel.html create mode 100644 youtube/templates/comments.html create mode 100644 youtube/templates/comments_page.html create mode 100644 youtube/templates/common_elements.html create mode 100644 youtube/templates/embed.html create mode 100644 youtube/templates/error.html create mode 100644 youtube/templates/home.html create mode 100644 youtube/templates/licenses.html create mode 100644 youtube/templates/local_playlist.html create mode 100644 youtube/templates/local_playlists_list.html create mode 100644 youtube/templates/playlist.html create mode 100644 youtube/templates/search.html create mode 100644 youtube/templates/settings.html create mode 100644 youtube/templates/shared.css create mode 100644 youtube/templates/status.html create mode 100644 youtube/templates/subscription_manager.html create mode 100644 youtube/templates/subscriptions.html create mode 100644 youtube/templates/subscriptions.xml create mode 100644 youtube/templates/unsubscribe_verify.html create mode 100644 youtube/templates/watch.html (limited to 'youtube/templates') diff --git a/youtube/templates/base.html b/youtube/templates/base.html new file mode 100644 index 0000000..393cc52 --- /dev/null +++ b/youtube/templates/base.html @@ -0,0 +1,179 @@ +{% if settings.app_public %} + {% set app_url = settings.app_url|string %} +{% else %} + {% set app_url = settings.app_url|string + ':' + settings.port_number|string %} +{% endif %} + + + + + + + {{ page_title }} + + + + + + {% block style %} + {{ style }} + {% endblock %} + + {% if js_data %} + + {% endif %} + + + +
+ + + + {% if header_playlist_names is defined %} +
+ + + {% for playlist_name in header_playlist_names %} + + {% endfor %} + + +
+ +
+
+ + {% endif %} + +
+
+ + {% block main %} + {{ main }} + {% endblock %} + +
+ + + + diff --git a/youtube/templates/channel.html b/youtube/templates/channel.html new file mode 100644 index 0000000..c43f488 --- /dev/null +++ b/youtube/templates/channel.html @@ -0,0 +1,133 @@ +{% if current_tab == 'search' %} + {% set page_title = search_box_value + ' - Page ' + page_number|string %} +{% else %} + {% set page_title = channel_name|string + ' - Channel' %} +{% endif %} + +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} +{% block style %} + + +{% endblock style %} + +{% block main %} + +
+
+ {{ channel_name }} +

{{ channel_name }}

+
+
+

{{ short_description }}

+
+ +
+
+ + + {% if current_tab == 'about' %} +
+ +
+

Description

+
{{ common_elements.text_runs(description) }}
+
+ +
+ {% else %} + + + + +
+ {% for item_info in items %} + {{ common_elements.item(item_info, include_author=false) }} + {% endfor %} +
+
+ + + + {% endif %} + +{% endblock main %} diff --git a/youtube/templates/comments.html b/youtube/templates/comments.html new file mode 100644 index 0000000..7bd75e5 --- /dev/null +++ b/youtube/templates/comments.html @@ -0,0 +1,65 @@ +{% import "common_elements.html" as common_elements %} + +{% macro render_comment(comment, include_avatar, timestamp_links=False) %} +
+
+ + {% if include_avatar %} + {{ comment['author'] }} + {% endif %} + +
+ {{ comment['author'] }} +
+ + + {% if timestamp_links %} + {{ common_elements.text_runs(comment['text'])|timestamps|safe }} + {% else %} + {{ common_elements.text_runs(comment['text']) }} + {% endif %} + + {{ comment['likes_text'] if comment['approx_like_count'] else ''}} +
+ {% if comment['reply_count'] %} + {% if settings.use_comments_js and comment['replies_url'] %} +
+ {{ comment['view_replies_text'] }} + Open in new tab +
loading...
+
+ {% elif comment['replies_url'] %} + {{ comment['view_replies_text'] }} + {% else %} + {{ comment['view_replies_text'] }} (error constructing url) + {% endif %} + {% endif %} +
+
+
+{% endmacro %} + +{% macro video_comments(comments_info) %} + + {% if comments_info['error'] %} +
+
{{ comments_info['error'] }}
+
+ {% else %} +
+ {% for comment in comments_info['comments'] %} + {{ render_comment(comment, comments_info['include_avatars'], True) }} + {% endfor %} +
+ {% if 'more_comments_url' is in comments_info %} + More comments + {% endif %} + {% endif %} + +{% endmacro %} diff --git a/youtube/templates/comments_page.html b/youtube/templates/comments_page.html new file mode 100644 index 0000000..3764b10 --- /dev/null +++ b/youtube/templates/comments_page.html @@ -0,0 +1,47 @@ +{% set page_title = ('Replies' if comments_info['is_replies'] else 'Comments page ' + comments_info['page_number']|string) %} +{% import "comments.html" as comments with context %} + +{% if not slim %} + {% extends "base.html" %} + {% block style %} + + {% endblock style %} +{% endif %} + +{% block main %} +
+ {% if not comments_info['is_replies'] %} + + {% endif %} + + {% if not comments_info['is_replies'] %} + + {% endif %} + +
+ {% for comment in comments_info['comments'] %} + {{ comments.render_comment(comment, comments_info['include_avatars'], slim) }} + {% endfor %} +
+ {% if 'more_comments_url' is in comments_info %} + More comments + {% endif %} +
+ + {% if settings.use_comments_js %} + + + {% endif %} +{% endblock main %} diff --git a/youtube/templates/common_elements.html b/youtube/templates/common_elements.html new file mode 100644 index 0000000..bacc513 --- /dev/null +++ b/youtube/templates/common_elements.html @@ -0,0 +1,140 @@ +{% macro text_runs(runs) %} + {%- if runs[0] is mapping -%} + {%- for text_run in runs -%} + {%- if text_run.get("bold", false) -%} + {{ text_run["text"] }} + {%- elif text_run.get('italics', false) -%} + {{ text_run["text"] }} + {%- else -%} + {{ text_run["text"] }} + {%- endif -%} + {%- endfor -%} + {%- elif runs -%} + {{ runs }} + {%- endif -%} +{% endmacro %} + +{% macro item(info, description=false, horizontal=true, include_author=true, include_badges=true, lazy_load=false) %} +
+ {% if info['error'] %} + {{ info['error'] }} + {% else %} +
+ +
+ {% if lazy_load %} +  + {% elif info['type'] == 'channel' %} +  + {% else %} +  + {% endif %} + + {% if info['type'] != 'channel' %} +

{{ (info['video_count']|commatize + ' videos') if info['type'] == 'playlist' else info['duration'] }}

+ {% endif %} +
+
+

{{ info['title'] }}

+ + {% if include_author %} + {% set author_description = info['author'] %} + {% set AUTHOR_DESC_LENGTH = 35 %} + {% if author_description != None %} + {% if author_description|length >= AUTHOR_DESC_LENGTH %} + {% set author_description = author_description[:AUTHOR_DESC_LENGTH].split(' ')[:-1]|join(' ') %} + {% if not author_description[-1] in ['.', '?', ':', '!'] %} + {% set author_more = author_description + '…' %} + {% set author_description = author_more|replace('"','') %} + {% endif %} + {% endif %} + {% endif %} + {% if info.get('author_url') %} +
{{ author_description }}
+ {% else %} +
{{ author_description }}
+ {% endif %} + {% endif %} + +
+ {% if info['type'] == 'channel' %} +
{{ info['approx_subscriber_count'] }} subscribers
+
{{ info['video_count']|commatize }} videos
+ {% else %} + {% if info.get('time_published') %} + {{ info['time_published'] }} + {% endif %} + {% if info.get('approx_view_count') %} +
{{ info['approx_view_count'] }} views
+ {% endif %} + {% endif %} +
+
+ {% if info['type'] == 'video' %} + + {% endif %} + {% endif %} +
+{% endmacro %} + +{% macro page_buttons(estimated_pages, url, parameters_dictionary, include_ends=false) %} + {% set current_page = parameters_dictionary.get('page', 1)|int %} + {% set parameters_dictionary = parameters_dictionary.to_dict() %} + {% if current_page is le(5) %} + {% set page_start = 1 %} + {% set page_end = [9, estimated_pages]|min %} + {% else %} + {% set page_start = current_page - 4 %} + {% set page_end = [current_page + 4, estimated_pages]|min %} + {% endif %} + + {% if include_ends and page_start is gt(1) %} + {% set _ = parameters_dictionary.__setitem__('page', 1) %} + {{ 1 }} + {% endif %} + + {% for page in range(page_start, page_end+1) %} + {% if page == current_page %} + {{ page }} + {% else %} + {# https://stackoverflow.com/questions/36886650/how-to-add-a-new-entry-into-a-dictionary-object-while-using-jinja2 #} + {% set _ = parameters_dictionary.__setitem__('page', page) %} + {{ page }} + {% endif %} + {% endfor %} + + {% if include_ends and page_end is lt(estimated_pages) %} + {% set _ = parameters_dictionary.__setitem__('page', estimated_pages) %} + {{ estimated_pages }} + {% endif %} + +{% endmacro %} + +{% macro next_previous_buttons(is_last_page, url, parameters_dictionary) %} + {% set current_page = parameters_dictionary.get('page', 1)|int %} + {% set parameters_dictionary = parameters_dictionary.to_dict() %} + + {% if current_page != 1 %} + {% set _ = parameters_dictionary.__setitem__('page', current_page - 1) %} + Previous page + {% endif %} + + {% if not is_last_page %} + {% set _ = parameters_dictionary.__setitem__('page', current_page + 1) %} + Next page + {% endif %} +{% endmacro %} + +{% macro next_previous_ctoken_buttons(prev_ctoken, next_ctoken, url, parameters_dictionary) %} + {% set parameters_dictionary = parameters_dictionary.to_dict() %} + + {% if prev_ctoken %} + {% set _ = parameters_dictionary.__setitem__('ctoken', prev_ctoken) %} + Previous page + {% endif %} + + {% if next_ctoken %} + {% set _ = parameters_dictionary.__setitem__('ctoken', next_ctoken) %} + Next page + {% endif %} +{% endmacro %} diff --git a/youtube/templates/embed.html b/youtube/templates/embed.html new file mode 100644 index 0000000..85d2d78 --- /dev/null +++ b/youtube/templates/embed.html @@ -0,0 +1,74 @@ + + + + + + + {{ title }} + + {% if settings.use_video_player == 2 %} + + + + {% endif %} + + {% if js_data %} + + {% endif %} + + + + {% if js_data %} + + {% endif %} + + {% if settings.use_video_player == 2 %} + + + + + {% elif settings.use_video_player == 1 %} + + {% endif %} + + diff --git a/youtube/templates/error.html b/youtube/templates/error.html new file mode 100644 index 0000000..97f8ca9 --- /dev/null +++ b/youtube/templates/error.html @@ -0,0 +1,36 @@ +{% if error_code %} + {% set page_title = 'Error: ' ~ error_code %} +{% else %} + {% set page_title = 'Error' %} +{% endif %} + +{% if not slim %} + {% extends "base.html" %} +{% endif %} + +{% if traceback %} + {% block style %} + + {% endblock style %} +{% endif %} + +{% block main %} + {% if traceback %} +
+

500 Uncaught exception:

+
{{ traceback }}
+

Please report this issue at https://todo.sr.ht/~heckyel/yt-local

+

Remember to include the traceback in your issue and redact any information in it you do not want to share

+
+ {% else %} +
+
+
+
+ {{ error_message }} +
+
+
+
+ {% endif %} +{% endblock %} diff --git a/youtube/templates/home.html b/youtube/templates/home.html new file mode 100644 index 0000000..0adac56 --- /dev/null +++ b/youtube/templates/home.html @@ -0,0 +1,13 @@ +{% set page_title = title %} +{% extends "base.html" %} +{% block style %} + +{% endblock style %} +{% block main %} + +{% endblock main %} diff --git a/youtube/templates/licenses.html b/youtube/templates/licenses.html new file mode 100644 index 0000000..dc73bfb --- /dev/null +++ b/youtube/templates/licenses.html @@ -0,0 +1,64 @@ +{% set page_title = title %} +{% extends "base.html" %} +{% block style %} + +{% endblock style %} +{% block main %} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
JavaScript Licensing Table
FileLicenseSource
av-merge.jsAGPL-3.0 or laterav-merge.js
comments.jsAGPL-3.0 or latercomments.js
common.jsAGPL-3.0 or latercommon.js
hotkeys.jsAGPL-3.0 or laterhotkeys.js
playlistadd.jsAGPL-3.0 or laterplaylistadd.js
plyr-start.jsAGPL-3.0 or laterplyr-start.js
plyr.min.jsExpatplyr.js
transcript-table.jsAGPL-3.0 or latertranscript-table.js
watch.jsAGPL-3.0 or laterwatch.js
+{% endblock main %} diff --git a/youtube/templates/local_playlist.html b/youtube/templates/local_playlist.html new file mode 100644 index 0000000..3286f67 --- /dev/null +++ b/youtube/templates/local_playlist.html @@ -0,0 +1,49 @@ +{% set page_title = playlist_name + ' - Local playlist' %} +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} +{% block style %} + + +{% endblock style %} + +{% block main %} +
+

{{ playlist_name }}

+ +
+
+ + +
+
+
+ +
+
+ + + +
+
+ {% for video_info in videos %} + {{ common_elements.item(video_info) }} + {% endfor %} +
+ + +{% endblock main %} diff --git a/youtube/templates/local_playlists_list.html b/youtube/templates/local_playlists_list.html new file mode 100644 index 0000000..61a6888 --- /dev/null +++ b/youtube/templates/local_playlists_list.html @@ -0,0 +1,14 @@ +{% set page_title = 'Local playlists' %} +{% extends "base.html" %} + +{% block style %} + +{% endblock style %} + +{% block main %} + +{% endblock main %} diff --git a/youtube/templates/playlist.html b/youtube/templates/playlist.html new file mode 100644 index 0000000..994523e --- /dev/null +++ b/youtube/templates/playlist.html @@ -0,0 +1,41 @@ +{% set page_title = title|string + ' - Page ' + parameters_dictionary.get('page', '1') %} +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} +{% block style %} + + +{% endblock style %} + +{% block main %} + +
+
+ {{ title }} +

{{ title }}

+
+ +
+
{{ video_count|commatize }} videos
+
{{ view_count|commatize }} views
+
Last updated {{ time_published }}
+
+
+
+ + +
+ {% for info in video_list %} + {{ common_elements.item(info) }} + {% endfor %} +
+
+ + + +{% endblock main %} diff --git a/youtube/templates/search.html b/youtube/templates/search.html new file mode 100644 index 0000000..af87c90 --- /dev/null +++ b/youtube/templates/search.html @@ -0,0 +1,34 @@ +{% set search_box_value = query %} +{% set page_title = query + ' - Search' %} +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} +{% block style %} + + +{% endblock style %} + +{% block main %} +
+
Approximately {{ '{:,}'.format(estimated_results) }} results ({{ '{:,}'.format(estimated_pages) }} pages)
+ {% if corrections['type'] == 'showing_results_for' %} +
Showing results for {{ common_elements.text_runs(corrections['corrected_query_text']) }}
+
Search instead for {{ corrections['original_query_text'] }}
+ {% elif corrections['type'] == 'did_you_mean' %} +
Did you mean {{ common_elements.text_runs(corrections['corrected_query_text']) }}
+ {% endif %} +
+ + +
+ {% for info in results %} + {{ common_elements.item(info, description=true) }} + {% endfor %} +
+
+ + +{% endblock main %} diff --git a/youtube/templates/settings.html b/youtube/templates/settings.html new file mode 100644 index 0000000..a4ebabf --- /dev/null +++ b/youtube/templates/settings.html @@ -0,0 +1,47 @@ +{% set page_title = 'Settings' %} +{% extends "base.html" %} +{% block style %} + +{% endblock style %} + +{% block main %} +
+ {% for categ in categories %} +

{{ categ|capitalize }}

+ + {% endfor %} + +
+{% endblock main %} diff --git a/youtube/templates/shared.css b/youtube/templates/shared.css new file mode 100644 index 0000000..8f12651 --- /dev/null +++ b/youtube/templates/shared.css @@ -0,0 +1,5 @@ +html { + font-family: {{ font_family }}; + background: var(--background); + color: var(--text); +} diff --git a/youtube/templates/status.html b/youtube/templates/status.html new file mode 100644 index 0000000..97e2ed4 --- /dev/null +++ b/youtube/templates/status.html @@ -0,0 +1,6 @@ +{% set page_title = (title if (title is defined) else 'Status') %} +{% extends "base.html" %} + +{% block main %} + {{ message }} +{% endblock %} diff --git a/youtube/templates/subscription_manager.html b/youtube/templates/subscription_manager.html new file mode 100644 index 0000000..96082c3 --- /dev/null +++ b/youtube/templates/subscription_manager.html @@ -0,0 +1,78 @@ +{% set page_title = 'Subscription Manager' %} +{% extends "base.html" %} +{% block style %} + +{% endblock style %} + + +{% macro subscription_list(sub_list) %} + {% for subscription in sub_list %} +
  • + + {{ subscription['channel_name'] }} + {{ ', '.join(subscription['tags']) }} +
  • + {% endfor %} +{% endmacro %} + +{% block main %} +
    +
    +

    Import subscriptions

    +
    + + +
    +
    + +
    +

    Export subscriptions

    +
    + + + + +
    +
    +
    + +
    + +
    + {% if group_by_tags %} + Don't group + {% else %} + Group by tags + {% endif %} + + + + + + + +
    + + + {% if group_by_tags %} + + {% else %} +
      + {{ subscription_list(sub_list) }} +
    + {% endif %} + +{% endblock main %} diff --git a/youtube/templates/subscriptions.html b/youtube/templates/subscriptions.html new file mode 100644 index 0000000..2823e8d --- /dev/null +++ b/youtube/templates/subscriptions.html @@ -0,0 +1,83 @@ +{% if current_tag %} + {% set page_title = 'Subscriptions - ' + current_tag %} +{% else %} + {% set page_title = 'Subscriptions' %} +{% endif %} +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} + +{% block style %} + + +{% endblock style %} + +{% block main %} + +
    + + + + +
    + +
    + + {% if current_tag %} +

    {{ current_tag }}

    + {% endif %} + +
    + {% for video_info in videos %} + {{ common_elements.item(video_info) }} + {% endfor %} +
    +
    + + + +{% endblock main %} diff --git a/youtube/templates/subscriptions.xml b/youtube/templates/subscriptions.xml new file mode 100644 index 0000000..5365da1 --- /dev/null +++ b/youtube/templates/subscriptions.xml @@ -0,0 +1,9 @@ + + + + {% for sub in sub_list %} + + {%- endfor %} + + + diff --git a/youtube/templates/unsubscribe_verify.html b/youtube/templates/unsubscribe_verify.html new file mode 100644 index 0000000..e899783 --- /dev/null +++ b/youtube/templates/unsubscribe_verify.html @@ -0,0 +1,21 @@ +{% set page_title = 'Unsubscribe?' %} +{% extends "base.html" %} +{% block style %} + +{% endblock style %} + +{% block main %} +

    Are you sure you want to unsubscribe from these channels?

    +
    + {% for channel_id, channel_name in unsubscribe_list %} + + {% endfor %} + + +
    + +{% endblock main %} diff --git a/youtube/templates/watch.html b/youtube/templates/watch.html new file mode 100644 index 0000000..0991457 --- /dev/null +++ b/youtube/templates/watch.html @@ -0,0 +1,263 @@ +{% set page_title = title %} +{% extends "base.html" %} +{% import "common_elements.html" as common_elements %} +{% import "comments.html" as comments with context %} +{% block style %} + + + {% if settings.use_video_player == 2 %} + + + + + {% endif %} +{% endblock style %} + +{% block main %} + {% if playability_error %} +
    + {{ 'Error: ' + playability_error }} + {% if invidious_reload_button %} +
    + Reload without invidious (for usage of new identity button).
    + {% endif %} +
    +
    + {% elif (uni_sources.__len__() == 0 or live) and hls_formats.__len__() != 0 %} +
    + Copy a url into your video player: +
      + {% for fmt in hls_formats %} +
    1. {{ fmt['video_quality'] }}:
    2. + {% endfor %} +
    +
    + {% else %} +
    + +
    + {% endif %} + +
    +
    +

    {{ title }}

    + +
      + {%- if unlisted -%} +
    • Unlisted
    • + {%- endif -%} + {%- if age_restricted -%} +
    • Age-restricted
    • + {%- endif -%} + {%- if limited_state -%} +
    • Limited state
    • + {%- endif -%} + {%- if live -%} +
    • Live
    • + {%- endif -%} +
    + +
    Uploaded by {{ uploader }}
    + {{ view_count }} views + + {{ like_count }} likes + +
    + + {% if settings.use_video_player != 2 %} + + {% endif %} +
    + + + Direct Link + + {% if settings.use_video_download != 0 %} +
    + Download + +
    + {% else %} + + {% endif %} + {{ common_elements.text_runs(description)|escape|urlize|timestamps|safe }} + +
    + {% if music_list.__len__() != 0 %} +
    + + + + {% for attribute in music_attributes %} + + {% endfor %} + + {% for track in music_list %} + + {% for attribute in music_attributes %} + {% if attribute.lower() == 'title' and track['url'] is not none %} + + {% else %} + + {% endif %} + {% endfor %} + + {% endfor %} +
    Music
    {{ attribute }}
    {{ track.get(attribute.lower(), '') }}{{ track.get(attribute.lower(), '') }}
    + {% endif %} +
    +
    + More info +
    +

    Tor exit node: {{ ip_address }}

    + {% if invidious_used %} +

    Used Invidious as fallback.

    + {% endif %} +

    Allowed countries: {{ allowed_countries|join(', ') }}

    + {% if settings.use_sponsorblock_js %} +
      +
    • +
    + {% endif %} +
    +
    +
    + +
    + + + {% if playlist %} +
    +
    +

    {{ playlist['title'] }}

    + +
    + +
    + {% elif settings.related_videos_mode != 0 %} + + {% endif %} + + {% if subtitle_sources %} +
    + Transcript +
    + + + +
    +
    +
    + {% endif %} + + + {% if settings.related_videos_mode != 0 %} + + {% endif %} + +
    + + + {% if settings.comments_mode != 0 %} + {% if comments_disabled %} +
    Comments disabled
    + {% else %} +
    + {{ comment_count|commatize }} comment{{'s' if comment_count != '1' else ''}} +
    + {% if comments_info %} + {{ comments.video_comments(comments_info) }} + {% endif %} +
    +
    + {% endif %} + {% endif %} + +
    + + + + + + + {% if settings.use_video_player == 2 %} + + + + + {% elif settings.use_video_player == 1 %} + + {% endif %} + {% if settings.use_comments_js %} {% endif %} + {% if settings.use_sponsorblock_js %} {% endif %} +{% endblock main %} -- cgit v1.2.3-59-g8ed1b