From ac4c597aa72f349c12ceee62d99a2621034650c3 Mon Sep 17 00:00:00 2001 From: unrealtournament <111871385+unrealtournament@users.noreply.github.com> Date: Fri, 24 Jul 2026 22:02:19 +0200 Subject: [PATCH 1/2] add subscription json export for NewPipe --- src/invidious/routes/subscriptions.cr | 9 +++++---- src/invidious/user/exports.cr | 20 ++++++++++++++++++++ src/invidious/views/user/data_control.ecr | 4 ++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 1de655d20..06cb1469d 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -80,14 +80,15 @@ module Invidious::Routes::Subscriptions subscriptions.sort_by!(&.author.downcase) if action_takeout - if format == "json" - env.response.content_type = "application/json" - env.response.headers["content-disposition"] = "attachment" + env.response.content_type = "application/json" + env.response.headers["content-disposition"] = "attachment" + if format == "json" return Invidious::User::Export.to_invidious(user) + elsif format == "newpipe_json" + return Invidious::User::Export.to_newpipe(subscriptions) else env.response.content_type = "application/xml" - env.response.headers["content-disposition"] = "attachment" export = XML.build do |xml| xml.element("opml", version: "1.1") do xml.element("body") do diff --git a/src/invidious/user/exports.cr b/src/invidious/user/exports.cr index 3fa468bad..db4de441d 100644 --- a/src/invidious/user/exports.cr +++ b/src/invidious/user/exports.cr @@ -2,6 +2,26 @@ struct Invidious::User module Export extend self + def to_newpipe(subscriptions) + return JSON.build do |json| + json.object do + json.field "subscriptions" do + json.array do + subscriptions.each do |channel| + json.object do + json.field "service_id", 0 + json.field "url", "https://www.youtube.com/channel/" + channel.id + json.field "name", channel.author + end + end + end + end + json.field "app_version", "0.29.0" + json.field "app_version_int", 1014 + end + end + end + def to_invidious(user : User) playlists = Invidious::Database::Playlists.select_like_iv(user.email) diff --git a/src/invidious/views/user/data_control.ecr b/src/invidious/views/user/data_control.ecr index 1ada97122..f12cff6e5 100644 --- a/src/invidious/views/user/data_control.ecr +++ b/src/invidious/views/user/data_control.ecr @@ -60,6 +60,10 @@ <%= I18n.translate(locale, "Export subscriptions as OPML (for NewPipe & FreeTube)") %> +
+ From 33cf701333ac9cf8f4b4756bb187b8e405a2fe0a Mon Sep 17 00:00:00 2001 From: unrealtournament <111871385+unrealtournament@users.noreply.github.com> Date: Fri, 24 Jul 2026 22:31:02 +0200 Subject: [PATCH 2/2] remove old newpipe export format --- src/invidious/routes/subscriptions.cr | 12 ++---------- src/invidious/views/user/data_control.ecr | 2 +- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/invidious/routes/subscriptions.cr b/src/invidious/routes/subscriptions.cr index 06cb1469d..46c48f65f 100644 --- a/src/invidious/routes/subscriptions.cr +++ b/src/invidious/routes/subscriptions.cr @@ -92,19 +92,11 @@ module Invidious::Routes::Subscriptions export = XML.build do |xml| xml.element("opml", version: "1.1") do xml.element("body") do - if format == "newpipe" - title = "YouTube Subscriptions" - else - title = "Invidious Subscriptions" - end + title = "Invidious Subscriptions" xml.element("outline", text: title, title: title) do subscriptions.each do |channel| - if format == "newpipe" - xml_url = "https://www.youtube.com/feeds/videos.xml?channel_id=#{channel.id}" - else - xml_url = "#{HOST_URL}/feed/channel/#{channel.id}" - end + xml_url = "#{HOST_URL}/feed/channel/#{channel.id}" xml.element("outline", text: channel.author, title: channel.author, "type": "rss", xmlUrl: xml_url) diff --git a/src/invidious/views/user/data_control.ecr b/src/invidious/views/user/data_control.ecr index f12cff6e5..222cd3755 100644 --- a/src/invidious/views/user/data_control.ecr +++ b/src/invidious/views/user/data_control.ecr @@ -57,7 +57,7 @@