Move more routes to new pattern
parent
2ae074a9a4
commit
d755d05f88
@ -0,0 +1,78 @@
|
|||||||
|
module Invidious::Routes::Notifications
|
||||||
|
# /modify_notifications
|
||||||
|
# will "ding" all subscriptions.
|
||||||
|
# /modify_notifications?receive_all_updates=false&receive_no_updates=false
|
||||||
|
# will "unding" all subscriptions.
|
||||||
|
def self.modify(env)
|
||||||
|
locale = env.get("preferences").as(Preferences).locale
|
||||||
|
|
||||||
|
user = env.get? "user"
|
||||||
|
sid = env.get? "sid"
|
||||||
|
referer = get_referer(env, "/")
|
||||||
|
|
||||||
|
redirect = env.params.query["redirect"]?
|
||||||
|
redirect ||= "false"
|
||||||
|
redirect = redirect == "true"
|
||||||
|
|
||||||
|
if !user
|
||||||
|
if redirect
|
||||||
|
return env.redirect referer
|
||||||
|
else
|
||||||
|
return error_json(403, "No such user")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user = user.as(User)
|
||||||
|
|
||||||
|
if !user.password
|
||||||
|
channel_req = {} of String => String
|
||||||
|
|
||||||
|
channel_req["receive_all_updates"] = env.params.query["receive_all_updates"]? || "true"
|
||||||
|
channel_req["receive_no_updates"] = env.params.query["receive_no_updates"]? || ""
|
||||||
|
channel_req["receive_post_updates"] = env.params.query["receive_post_updates"]? || "true"
|
||||||
|
|
||||||
|
channel_req.reject! { |k, v| v != "true" && v != "false" }
|
||||||
|
|
||||||
|
headers = HTTP::Headers.new
|
||||||
|
headers["Cookie"] = env.request.headers["Cookie"]
|
||||||
|
|
||||||
|
html = YT_POOL.client &.get("/subscription_manager?disable_polymer=1", headers)
|
||||||
|
|
||||||
|
cookies = HTTP::Cookies.from_client_headers(headers)
|
||||||
|
html.cookies.each do |cookie|
|
||||||
|
if {"VISITOR_INFO1_LIVE", "YSC", "SIDCC"}.includes? cookie.name
|
||||||
|
if cookies[cookie.name]?
|
||||||
|
cookies[cookie.name] = cookie
|
||||||
|
else
|
||||||
|
cookies << cookie
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
headers = cookies.add_request_headers(headers)
|
||||||
|
|
||||||
|
if match = html.body.match(/'XSRF_TOKEN': "(?<session_token>[^"]+)"/)
|
||||||
|
session_token = match["session_token"]
|
||||||
|
else
|
||||||
|
return env.redirect referer
|
||||||
|
end
|
||||||
|
|
||||||
|
headers["content-type"] = "application/x-www-form-urlencoded"
|
||||||
|
channel_req["session_token"] = session_token
|
||||||
|
|
||||||
|
subs = XML.parse_html(html.body)
|
||||||
|
subs.xpath_nodes(%q(//a[@class="subscription-title yt-uix-sessionlink"]/@href)).each do |channel|
|
||||||
|
channel_id = channel.content.lstrip("/channel/").not_nil!
|
||||||
|
channel_req["channel_id"] = channel_id
|
||||||
|
|
||||||
|
YT_POOL.client &.post("/subscription_ajax?action_update_subscription_preferences=1", headers, form: channel_req)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if redirect
|
||||||
|
env.redirect referer
|
||||||
|
else
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
"{}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,168 @@
|
|||||||
|
module Invidious::Routes::Subscriptions
|
||||||
|
def self.toggle_subscription(env)
|
||||||
|
locale = env.get("preferences").as(Preferences).locale
|
||||||
|
|
||||||
|
user = env.get? "user"
|
||||||
|
sid = env.get? "sid"
|
||||||
|
referer = get_referer(env, "/")
|
||||||
|
|
||||||
|
redirect = env.params.query["redirect"]?
|
||||||
|
redirect ||= "true"
|
||||||
|
redirect = redirect == "true"
|
||||||
|
|
||||||
|
if !user
|
||||||
|
if redirect
|
||||||
|
return env.redirect referer
|
||||||
|
else
|
||||||
|
return error_json(403, "No such user")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
user = user.as(User)
|
||||||
|
sid = sid.as(String)
|
||||||
|
token = env.params.body["csrf_token"]?
|
||||||
|
|
||||||
|
begin
|
||||||
|
validate_request(token, sid, env.request, HMAC_KEY, locale)
|
||||||
|
rescue ex
|
||||||
|
if redirect
|
||||||
|
return error_template(400, ex)
|
||||||
|
else
|
||||||
|
return error_json(400, ex)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if env.params.query["action_create_subscription_to_channel"]?.try &.to_i?.try &.== 1
|
||||||
|
action = "action_create_subscription_to_channel"
|
||||||
|
elsif env.params.query["action_remove_subscriptions"]?.try &.to_i?.try &.== 1
|
||||||
|
action = "action_remove_subscriptions"
|
||||||
|
else
|
||||||
|
return env.redirect referer
|
||||||
|
end
|
||||||
|
|
||||||
|
channel_id = env.params.query["c"]?
|
||||||
|
channel_id ||= ""
|
||||||
|
|
||||||
|
if !user.password
|
||||||
|
# Sync subscriptions with YouTube
|
||||||
|
subscribe_ajax(channel_id, action, env.request.headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
case action
|
||||||
|
when "action_create_subscription_to_channel"
|
||||||
|
if !user.subscriptions.includes? channel_id
|
||||||
|
get_channel(channel_id, false, false)
|
||||||
|
Invidious::Database::Users.subscribe_channel(user, channel_id)
|
||||||
|
end
|
||||||
|
when "action_remove_subscriptions"
|
||||||
|
Invidious::Database::Users.unsubscribe_channel(user, channel_id)
|
||||||
|
else
|
||||||
|
return error_json(400, "Unsupported action #{action}")
|
||||||
|
end
|
||||||
|
|
||||||
|
if redirect
|
||||||
|
env.redirect referer
|
||||||
|
else
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
"{}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.subscription_manager(env)
|
||||||
|
locale = env.get("preferences").as(Preferences).locale
|
||||||
|
|
||||||
|
user = env.get? "user"
|
||||||
|
sid = env.get? "sid"
|
||||||
|
referer = get_referer(env)
|
||||||
|
|
||||||
|
if !user
|
||||||
|
return env.redirect referer
|
||||||
|
end
|
||||||
|
|
||||||
|
user = user.as(User)
|
||||||
|
sid = sid.as(String)
|
||||||
|
|
||||||
|
if !user.password
|
||||||
|
# Refresh account
|
||||||
|
headers = HTTP::Headers.new
|
||||||
|
headers["Cookie"] = env.request.headers["Cookie"]
|
||||||
|
|
||||||
|
user, sid = get_user(sid, headers)
|
||||||
|
end
|
||||||
|
|
||||||
|
action_takeout = env.params.query["action_takeout"]?.try &.to_i?
|
||||||
|
action_takeout ||= 0
|
||||||
|
action_takeout = action_takeout == 1
|
||||||
|
|
||||||
|
format = env.params.query["format"]?
|
||||||
|
format ||= "rss"
|
||||||
|
|
||||||
|
subscriptions = Invidious::Database::Channels.select(user.subscriptions)
|
||||||
|
subscriptions.sort_by!(&.author.downcase)
|
||||||
|
|
||||||
|
if action_takeout
|
||||||
|
if format == "json"
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
env.response.headers["content-disposition"] = "attachment"
|
||||||
|
playlists = Invidious::Database::Playlists.select_like_iv(user.email)
|
||||||
|
|
||||||
|
return JSON.build do |json|
|
||||||
|
json.object do
|
||||||
|
json.field "subscriptions", user.subscriptions
|
||||||
|
json.field "watch_history", user.watched
|
||||||
|
json.field "preferences", user.preferences
|
||||||
|
json.field "playlists" do
|
||||||
|
json.array do
|
||||||
|
playlists.each do |playlist|
|
||||||
|
json.object do
|
||||||
|
json.field "title", playlist.title
|
||||||
|
json.field "description", html_to_content(playlist.description_html)
|
||||||
|
json.field "privacy", playlist.privacy.to_s
|
||||||
|
json.field "videos" do
|
||||||
|
json.array do
|
||||||
|
Invidious::Database::PlaylistVideos.select_ids(playlist.id, playlist.index, limit: 500).each do |video_id|
|
||||||
|
json.string video_id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
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
|
||||||
|
if format == "newpipe"
|
||||||
|
title = "YouTube Subscriptions"
|
||||||
|
else
|
||||||
|
title = "Invidious Subscriptions"
|
||||||
|
end
|
||||||
|
|
||||||
|
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.element("outline", text: channel.author, title: channel.author,
|
||||||
|
"type": "rss", xmlUrl: xml_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return export.gsub(%(<?xml version="1.0"?>\n), "")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
templated "subscription_manager"
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue