aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJesús <heckyel@hyperbola.info>2021-04-16 11:49:09 -0500
committerJesús <heckyel@hyperbola.info>2021-04-16 11:49:09 -0500
commit5a8e7e30d2a3f806520749b60c85077dbc1f5d3e (patch)
tree7d62bcecc6de15d79781a0ffd989bba4cfd97adb /core
downloadyt-local-docker-5a8e7e30d2a3f806520749b60c85077dbc1f5d3e.tar.lz
yt-local-docker-5a8e7e30d2a3f806520749b60c85077dbc1f5d3e.tar.xz
yt-local-docker-5a8e7e30d2a3f806520749b60c85077dbc1f5d3e.zip
initial commit
Diffstat (limited to 'core')
-rw-r--r--core/0001.patch403
-rw-r--r--core/Dockerfile29
-rw-r--r--core/entrypoint.sh80
3 files changed, 512 insertions, 0 deletions
diff --git a/core/0001.patch b/core/0001.patch
new file mode 100644
index 0000000..e4b19fc
--- /dev/null
+++ b/core/0001.patch
@@ -0,0 +1,403 @@
+diff --git a/settings.py b/settings.py
+index 1482db0..065954e 100644
+--- a/settings.py
++++ b/settings.py
+@@ -452,6 +452,6 @@ def settings_page():
+
+ globals().update(current_settings_dict)
+ save_settings(current_settings_dict)
+- return flask.redirect(util.URL_ORIGIN + '/settings', 303)
++ return flask.redirect(util.URL_ORIGIN)
+ else:
+ flask.abort(400)
+diff --git a/youtube/__init__.py b/youtube/__init__.py
+index 3c85d47..05fa3a5 100644
+--- a/youtube/__init__.py
++++ b/youtube/__init__.py
+@@ -13,9 +13,6 @@ yt_app.url_map.strict_slashes = False
+ # yt_app.jinja_env.lstrip_blocks = True
+
+
+-yt_app.add_url_rule('/settings', 'settings_page', settings.settings_page, methods=['POST', 'GET'])
+-
+-
+ @yt_app.route('/')
+ def homepage():
+ return flask.render_template('home.html', title="Youtube local")
+diff --git a/youtube/static/channel.css b/youtube/static/channel.css
+index ada086d..3d2d36a 100644
+--- a/youtube/static/channel.css
++++ b/youtube/static/channel.css
+@@ -270,11 +270,9 @@ hr {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/static/local_playlist.css b/youtube/static/local_playlist.css
+index 33771f4..1689b31 100644
+--- a/youtube/static/local_playlist.css
++++ b/youtube/static/local_playlist.css
+@@ -246,11 +246,9 @@ hr {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/static/playlist.css b/youtube/static/playlist.css
+index 8438ceb..a614056 100644
+--- a/youtube/static/playlist.css
++++ b/youtube/static/playlist.css
+@@ -256,11 +256,9 @@ hr {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/static/search.css b/youtube/static/search.css
+index ff1fbda..b9b7952 100644
+--- a/youtube/static/search.css
++++ b/youtube/static/search.css
+@@ -274,11 +274,9 @@ hr {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/static/subscription.css b/youtube/static/subscription.css
+index 2004bd6..9a963ba 100644
+--- a/youtube/static/subscription.css
++++ b/youtube/static/subscription.css
+@@ -250,11 +250,9 @@ hr {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/static/watch.css b/youtube/static/watch.css
+index 8d23017..dd83da3 100644
+--- a/youtube/static/watch.css
++++ b/youtube/static/watch.css
+@@ -385,11 +385,9 @@ label[for=options-toggle-cbox] {
+
+ .item-box {
+ display: grid;
+- grid-template-columns: 1.9fr 0.1fr;
++ grid-template-columns: 1fr;
+ grid-template-rows: 1fr;
+- grid-gap: 1px;
+- grid-template-areas:
+- "item-video item-checkbox";
++ grid-template-areas: "item-video";
+ }
+
+ .item-video {
+diff --git a/youtube/templates/base.html b/youtube/templates/base.html
+index 7b32d76..5f60b40 100644
+--- a/youtube/templates/base.html
++++ b/youtube/templates/base.html
+@@ -117,22 +117,6 @@
+ </div>
+ </form>
+
+- {% if header_playlist_names is defined %}
+- <form class="playlist" id="playlist-edit" action="/youtube.com/edit_playlist" method="post" target="_self">
+- <input class="play-box" name="playlist_name" id="playlist-name-selection" list="playlist-options" type="search" placeholder="I added your playlist...">
+- <datalist class="play-hidden" id="playlist-options">
+- {% for playlist_name in header_playlist_names %}
+- <option value="{{ playlist_name }}">{{ playlist_name }}</option>
+- {% endfor %}
+- </datalist>
+- <button class="play-add" type="submit" id="playlist-add-button" name="action" value="add">+List</button>
+- <div class="play-clean">
+- <button type="reset" id="item-selection-reset">Clear selection</button>
+- </div>
+- </form>
+- <script src="/youtube.com/static/js/playlistadd.js"></script>
+- {% endif %}
+-
+ </header>
+ <main class="main">
+
+diff --git a/youtube/templates/channel.html b/youtube/templates/channel.html
+index 294f1df..a4361c3 100644
+--- a/youtube/templates/channel.html
++++ b/youtube/templates/channel.html
+@@ -21,14 +21,6 @@
+ <div class="summary">
+ <p>{{ short_description }}</p>
+ </div>
+- <div class="subscribe">
+- <form method="POST" action="/youtube.com/subscriptions" class="subscribe-unsubscribe">
+- <input class="btn-subscribe" type="submit" value="{{ 'Unsubscribe' if subscribed else 'Subscribe' }}">
+- <input type="hidden" name="channel_id" value="{{ channel_id }}">
+- <input type="hidden" name="channel_name" value="{{ channel_name }}">
+- <input type="hidden" name="action" value="{{ 'unsubscribe' if subscribed else 'subscribe' }}">
+- </form>
+- </div>
+ </div>
+ <hr/>
+
+diff --git a/youtube/templates/common_elements.html b/youtube/templates/common_elements.html
+index 94554d4..7ba904a 100644
+--- a/youtube/templates/common_elements.html
++++ b/youtube/templates/common_elements.html
+@@ -59,9 +59,6 @@
+ {% endif %}
+ </div>
+ </div>
+- {% if info['type'] == 'video' %}
+- <input class="item-checkbox" type="checkbox" name="video_info_list" value="{{ info['video_info'] }}" form="playlist-edit">
+- {% endif %}
+ {% endif %}
+ </article>
+ {% endmacro %}
+diff --git a/youtube/templates/home.html b/youtube/templates/home.html
+index ef1f029..b537cca 100644
+--- a/youtube/templates/home.html
++++ b/youtube/templates/home.html
+@@ -4,10 +4,4 @@
+ <link href="/youtube.com/static/home.css" rel="stylesheet"/>
+ {% endblock style %}
+ {% block main %}
+- <ul>
+- <li><a href="/youtube.com/playlists">Local playlists</a></li>
+- <li><a href="/youtube.com/subscriptions">Subscriptions</a></li>
+- <li><a href="/youtube.com/subscription_manager">Subscription Manager</a></li>
+- <li><a href="/youtube.com/settings">Settings</a></li>
+- </ul>
+ {% endblock main %}
+diff --git a/youtube/templates/settings.html b/youtube/templates/settings.html
+index 7a7ce9e..4749d4c 100644
+--- a/youtube/templates/settings.html
++++ b/youtube/templates/settings.html
+@@ -5,43 +5,5 @@
+ {% endblock style %}
+
+ {% block main %}
+- <form method="POST" class="settings-form">
+- {% for categ in categories %}
+- <h2>{{ categ|capitalize }}</h2>
+- <ul class="settings-list">
+- {% for setting_name, setting_info, value in settings_by_category[categ] %}
+- {% if not setting_info.get('hidden', false) %}
+- <li class="setting-item">
+- {% if 'label' is in(setting_info) %}
+- <label for="{{ 'setting_' + setting_name }}">{{ setting_info['label'] }}</label>
+- {% else %}
+- <label for="{{ 'setting_' + setting_name }}">{{ setting_name.replace('_', ' ')|capitalize }}</label>
+- {% endif %}
+
+- {% if setting_info['type'].__name__ == 'bool' %}
+- <input type="checkbox" id="{{ 'setting_' + setting_name }}" name="{{ setting_name }}" {{ 'checked' if value else '' }}>
+- {% elif setting_info['type'].__name__ == 'int' %}
+- {% if 'options' is in(setting_info) %}
+- <select id="{{ 'setting_' + setting_name }}" name="{{ setting_name }}">
+- {% for option in setting_info['options'] %}
+- <option value="{{ option[0] }}" {{ 'selected' if option[0] == value else '' }}>{{ option[1] }}</option>
+- {% endfor %}
+- </select>
+- {% else %}
+- <input type="number" id="{{ 'setting_' + setting_name }}" name="{{ setting_name }}" value="{{ value }}" step="1">
+- {% endif %}
+- {% elif setting_info['type'].__name__ == 'float' %}
+-
+- {% elif setting_info['type'].__name__ == 'str' %}
+- <input type="text" id="{{ 'setting_' + setting_name }}" name="{{ setting_name }}" value="{{ value }}">
+- {% else %}
+- <span>Error: Unknown setting type: setting_info['type'].__name__</span>
+- {% endif %}
+- </li>
+- {% endif %}
+- {% endfor %}
+- </ul>
+- {% endfor %}
+- <input type="submit" value="Save settings">
+- </form>
+ {% endblock main %}
+diff --git a/youtube/templates/subscription_manager.html b/youtube/templates/subscription_manager.html
+index 92cd024..c8eb603 100644
+--- a/youtube/templates/subscription_manager.html
++++ b/youtube/templates/subscription_manager.html
+@@ -16,52 +16,5 @@
+ {% endmacro %}
+
+ {% block main %}
+- <div class="import-export">
+- <form class="subscriptions-import-form" enctype="multipart/form-data" action="/youtube.com/import_subscriptions" method="POST">
+- <h2>Import subscriptions</h2>
+- <input type="file" id="subscriptions-import" accept="application/json, application/xml, text/x-opml" name="subscriptions_file">
+- <input type="submit" value="Import" class="import-submit-button">
+- </form>
+-
+- <!--<ul class="subscriptions-export-links">
+- <li><a href="/youtube.com/subscriptions.opml">Export subscriptions (OPML)</a></li>
+- <li><a href="/youtube.com/subscriptions.xml">Export subscriptions (RSS)</a></li>
+- </ul>-->
+- </div>
+-
+- <hr>
+-
+- <form id="subscription-manager-form" class="sub-list-controls" method="POST">
+- {% if group_by_tags %}
+- <a class="sort-button" href="/https://www.youtube.com/subscription_manager?group_by_tags=0">Don't group</a>
+- {% else %}
+- <a class="sort-button" href="/https://www.youtube.com/subscription_manager?group_by_tags=1">Group by tags</a>
+- {% endif %}
+- <input type="text" name="tags">
+- <button type="submit" name="action" value="add_tags">Add tags</button>
+- <button type="submit" name="action" value="remove_tags">Remove tags</button>
+- <button type="submit" name="action" value="unsubscribe_verify">Unsubscribe</button>
+- <button type="submit" name="action" value="mute">Mute</button>
+- <button type="submit" name="action" value="unmute">Unmute</button>
+- <input type="reset" value="Clear Selection">
+- </form>
+-
+-
+- {% if group_by_tags %}
+- <ul class="tag-group-list">
+- {% for tag_name, sub_list in tag_groups %}
+- <li class="tag-group">
+- <h2 class="tag-group-name">{{ tag_name }}</h2>
+- <ol class="sub-list">
+- {{ subscription_list(sub_list) }}
+- </ol>
+- </li>
+- {% endfor %}
+- </ul>
+- {% else %}
+- <ol class="sub-list">
+- {{ subscription_list(sub_list) }}
+- </ol>
+- {% endif %}
+
+ {% endblock main %}
+diff --git a/youtube/templates/subscriptions.html b/youtube/templates/subscriptions.html
+index b528e5c..6302fcc 100644
+--- a/youtube/templates/subscriptions.html
++++ b/youtube/templates/subscriptions.html
+@@ -13,71 +13,5 @@
+
+ {% block main %}
+
+- <div class="subscriptions-sidebar">
+- <div class="sidebar-links">
+- <a class="sidebar-title" href="/youtube.com/subscription_manager" class="sub-manager-link">Subscription Manager</a>
+- <form class="sidebar-action" method="POST" class="refresh-all">
+- <input type="submit" value="Check All">
+- <input type="hidden" name="action" value="refresh">
+- <input type="hidden" name="type" value="all">
+- </form>
+- </div>
+-
+- <ol class="sidebar-list tags">
+- {% if current_tag %}
+- <li class="sidebar-list-item">
+- <a href="/youtube.com/subscriptions" class="sidebar-item-name">Any tag</a>
+- </li>
+- {% endif %}
+-
+- {% for tag in tags %}
+- <li class="sidebar-list-item">
+- {% if tag == current_tag %}
+- <span class="sidebar-item-name">{{ tag }}</span>
+- {% else %}
+- <a href="?tag={{ tag|urlencode }}" class="sidebar-item-name">{{ tag }}</a>
+- {% endif %}
+- <form method="POST" class="sidebar-item-refresh">
+- <input type="submit" value="Check">
+- <input type="hidden" name="action" value="refresh">
+- <input type="hidden" name="type" value="tag">
+- <input type="hidden" name="tag_name" value="{{ tag }}">
+- </form>
+- </li>
+- {% endfor %}
+- </ol>
+-
+- <hr>
+- <ol class="sidebar-list sub-refresh-list">
+- {% for subscription in subscription_list %}
+- <li class="sidebar-list-item {{ 'muted' if subscription['muted'] else '' }}">
+- <a href="{{ subscription['channel_url'] }}" class="sidebar-item-name" title="{{ subscription['channel_name'] }}">{{ subscription['channel_name'] }}</a>
+- <form method="POST" class="sidebar-item-refresh">
+- <input type="submit" value="Check">
+- <input type="hidden" name="action" value="refresh">
+- <input type="hidden" name="type" value="channel">
+- <input type="hidden" name="channel_id" value="{{ subscription['channel_id'] }}">
+- </form>
+- </li>
+- {% endfor %}
+- </ol>
+- </div>
+-
+- {% if current_tag %}
+- <h2 class="current-tag">{{ current_tag }}</h2>
+- {% endif %}
+-
+- <div class="video-container">
+- {% for video_info in videos %}
+- {{ common_elements.item(video_info) }}
+- {% endfor %}
+- </div>
+- <hr/>
+-
+- <footer class="pagination-container">
+- <nav class="pagination-list">
+- {{ common_elements.page_buttons(num_pages, '/youtube.com/subscriptions', parameters_dictionary) }}
+- </nav>
+- </footer>
+
+ {% endblock main %}
+diff --git a/youtube/templates/watch.html b/youtube/templates/watch.html
+index 70f5692..9b55493 100644
+--- a/youtube/templates/watch.html
++++ b/youtube/templates/watch.html
+@@ -79,8 +79,6 @@
+ <script src="/youtube.com/static/js/speedyplay.js"></script>
+ </div>
+
+- <input class="v-checkbox" name="video_info_list" value="{{ video_info }}" form="playlist-edit" type="checkbox">
+-
+ <details class="v-download">
+ <summary class="download-dropdown-label">Download</summary>
+ <ul class="download-dropdown-content">
diff --git a/core/Dockerfile b/core/Dockerfile
new file mode 100644
index 0000000..9bbd2e6
--- /dev/null
+++ b/core/Dockerfile
@@ -0,0 +1,29 @@
+FROM alpine:latest
+LABEL MAINTAINER="heckyel@riseup.net"
+
+ENV LANG C.UTF-8
+ENV LC_ALL C.UTF-8
+
+RUN apk add musl-dev build-base gcc libffi-dev python3-dev patch git py3-pip
+
+ARG APP_DIR="/srv/app"
+ARG YT_REPO="https://git.sr.ht/~heckyel/yt-local"
+ARG YT_BRANCH="master"
+
+RUN mkdir --parents "$APP_DIR"
+
+WORKDIR "$APP_DIR"
+
+RUN git clone --depth=1 "$YT_REPO" --branch "$YT_BRANCH" "$APP_DIR"
+RUN git show --oneline --no-patch
+RUN pip3 install -r requirements.txt
+
+COPY 0001.patch "$APP_DIR/0001.patch"
+RUN patch -Np1 -i "$APP_DIR/0001.patch"
+
+EXPOSE 8080
+
+COPY entrypoint.sh /
+RUN chmod u+x /entrypoint.sh
+
+ENTRYPOINT ["/entrypoint.sh"]
diff --git a/core/entrypoint.sh b/core/entrypoint.sh
new file mode 100644
index 0000000..ba37c18
--- /dev/null
+++ b/core/entrypoint.sh
@@ -0,0 +1,80 @@
+#!/usr/bin/env sh
+
+## Config
+if [ ! -d "/root/.youtube-local" ]; then
+ # make dir
+ install -d /root/.youtube-local
+
+ # generate config
+ cat > /root/.youtube-local/settings.txt <<- EOF
+# 0 - Off
+# 1 - On, except video
+# 2 - On, including video (see warnings)
+route_tor = $ROUTE_TOR
+
+tor_port = $TOR_PORT
+
+tor_control_port = TOR_CONTROL_PORT
+
+port_number = 8080
+
+# This will allow others to connect to your Youtube Local instance as a website.
+# For security reasons, enabling this is not recommended.
+allow_foreign_addresses = $ALLOW_FOREIGN_ADDRESSES
+
+# 0 - off by default
+# 1 - only manually created subtitles on by default
+# 2 - enable even if automatically generated is all that's available
+subtitles_mode = $SUBTITLES_MODE
+
+# ISO 639 language code: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+subtitles_language = $SUBTITLES_LANG
+
+# 0 - Related videos disabled
+# 1 - Related videos always shown
+# 2 - Related videos hidden; shown by clicking a button
+related_videos_mode = $RELATED_VIDEOS_MODE
+
+# 0 - Video comments disabled
+# 1 - Video comments always shown
+# 2 - Video comments hidden; shown by clicking a button
+comments_mode = $COMMENTS_MODE
+
+enable_comment_avatars = $ENABLE_COMMENTS_AVATARS
+
+# 0 to sort by top
+# 1 to sort by newest
+default_comment_sorting = $DEFAULT_COMMENT_SORTING
+
+theater_mode = $THEATER_MODE
+
+default_resolution = $DEFAULT_RESOLUTION
+
+use_video_hotkeys = $USE_VIDEO_HOTKEYS
+
+proxy_images = $PROXY_IMAGES
+
+use_comments_js = $USE_COMMENTS_JS
+
+use_sponsorblock_js = $USE_SPONSORBLOCK_JS
+
+theme = $THEME
+
+font = $FONT
+
+embed_page_mode = $EMBED_PAGE_MODE
+
+autocheck_subscriptions = $AUTOCHECK_SUBSCRIPTIONS
+
+# Developer use to debug 403s
+gather_googlevideo_domains = $GATHER_GOOGLEVIDEO_DOMAINS
+
+# Save all responses from youtube for debugging
+debugging_save_responses = $DEBUGGING_SAVE_RESPONSES
+
+# Do not change, remove, or comment out this value, or else your settings may be lost or corrupted
+settings_version = 3
+EOF
+fi
+
+exec /usr/bin/python3 /srv/app/server.py