--- /dev/null
+#!/bin/sh
+# Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
+# License: GPL-3.0 or later.
+#
+# Clicking on the "Download" button on entry's page sends a POST request to
+# /entry/download/<entry_id>. This script resolves the <entry_id> to an <url>
+# and redirects the client to /ydlpd?url=<url> with HTTP 303 See Other [1]. This
+# causes the client to automatically send a GET request to that address.
+#
+# [1] https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/303
+
+. /etc/environment
+
+VIDEO=$(/usr/bin/psql --user=miniflux \
+ --dbname=${RSS_DB} \
+ --tuples-only \
+ --no-align \
+ --command="
+SELECT url
+FROM entries
+WHERE id = ${ENTRY_ID}")
+
+echo "HTTP/1.1 303 See Other"
+echo "Location: /ydlpd?url=${VIDEO}"
+echo "Content-Type: text/html; charset=UTF-8"
+echo "Content-Length: 0"
+echo ""
root ${prod_dir}/${rss};
+ location ~ ^/entry/download/(\d+)$ {
+ include fastcgi_params;
+ fastcgi_pass unix:/var/run/fcgiwrap.socket;
+
+ fastcgi_read_timeout 30;
+
+ fastcgi_param ENTRY_ID ${dollar}1;
+ fastcgi_param SCRIPT_FILENAME ${dollar}document_root/download.sh;
+ }
+
+ location ~ ^/ydlpd(.*)$ {
+ include fastcgi_params;
+ fastcgi_pass unix:/var/run/fcgiwrap.socket;
+
+ fastcgi_read_timeout 30;
+
+ fastcgi_param URL ${dollar}arg_url;
+ fastcgi_param SCRIPT_FILENAME ${dollar}document_root/ydlpd.sh;
+ }
+
location / {
proxy_pass http://127.0.0.1:4080;
proxy_redirect off;
--- /dev/null
+#!/bin/sh
+# Copyright (c) 2024 Jakub Czajka <jakub@ekhem.eu.org>
+# License: GPL-3.0 or later.
+#
+# If user downloads entry's page, miniflux embeds the HTML. The response needs to
+# have the following format [1]:
+#
+# {
+# "content": "<page's HTML>",
+# "reading_time": "<integer>"
+# }
+#
+# Moreover, the HTML embeded in JSON needs to have '\n' instead of new lines.
+# This script returns a HTML form to select the format for download and passes
+# it alongside video's URL to ydlpd for download.
+#
+# [1] https://github.com/miniflux/v2/blob/main/internal/ui/static/js/app.js#L355
+
+. /etc/environment
+
+PAGE=$(echo "\
+<form id='ydlpd' action='https://yt.${private_domain}/download'>
+ <fieldset>
+ <input type='text' id='url' name='url' value='${URL}' required />
+ <div class='container'>
+ <select id='format' name='format'>
+ <option value=''>--Select format--</option>
+ <option value='video'>video</option>
+ <option value='audio'>audio</option>
+ </select>
+ <button type='submit'>Download</button>
+ </div>
+ </fieldset>
+</form>" | sed 's/^[ \t]*//g')
+
+echo "HTTP/1.1 200 OK"
+echo "Content-type: text/json"
+echo ""
+echo -n "{\"content\": \"${PAGE}\"" | sed --null-data 's/\n/\\n/g'
+echo -n ", \"reading_time\": \"1\"}"