mirror of
https://github.com/iv-org/invidious.git
synced 2024-12-19 04:34:23 -05:00
Make feat. chan page URL to compatible with yt
This commit is contained in:
parent
8000d538db
commit
c91ff8506a
@ -313,7 +313,6 @@ Invidious::Routing.get "/channel/:ucid/videos", Invidious::Routes::Channels, :vi
|
|||||||
Invidious::Routing.get "/channel/:ucid/playlists", Invidious::Routes::Channels, :playlists
|
Invidious::Routing.get "/channel/:ucid/playlists", Invidious::Routes::Channels, :playlists
|
||||||
Invidious::Routing.get "/channel/:ucid/community", Invidious::Routes::Channels, :community
|
Invidious::Routing.get "/channel/:ucid/community", Invidious::Routes::Channels, :community
|
||||||
Invidious::Routing.get "/channel/:ucid/channels", Invidious::Routes::Channels, :channels
|
Invidious::Routing.get "/channel/:ucid/channels", Invidious::Routes::Channels, :channels
|
||||||
Invidious::Routing.get "/channel/:ucid/channels/:param", Invidious::Routes::Channels, :featured_channel_category
|
|
||||||
Invidious::Routing.get "/channel/:ucid/about", Invidious::Routes::Channels, :about
|
Invidious::Routing.get "/channel/:ucid/about", Invidious::Routes::Channels, :about
|
||||||
|
|
||||||
Invidious::Routing.get "/watch", Invidious::Routes::Watch, :handle
|
Invidious::Routing.get "/watch", Invidious::Routes::Watch, :handle
|
||||||
|
@ -380,7 +380,9 @@ def fetch_channel_playlists(ucid, author, continuation, sort_by)
|
|||||||
return items, continuation
|
return items, continuation
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_channel_featured_channels(ucid, tab_data, params = nil, continuation = nil, query_title = nil)
|
def fetch_channel_featured_channels(ucid, tab_data, view=nil, shelf_id=nil, continuation = nil, query_title = nil)
|
||||||
|
auxiliary_data = {} of String => String
|
||||||
|
|
||||||
if continuation.is_a?(String)
|
if continuation.is_a?(String)
|
||||||
initial_data = request_youtube_api_browse(continuation)
|
initial_data = request_youtube_api_browse(continuation)
|
||||||
items = extract_items(initial_data)
|
items = extract_items(initial_data)
|
||||||
@ -392,9 +394,14 @@ def fetch_channel_featured_channels(ucid, tab_data, params = nil, continuation =
|
|||||||
browse_endpoint_data: nil,
|
browse_endpoint_data: nil,
|
||||||
continuation_token: continuation_token,
|
continuation_token: continuation_token,
|
||||||
badges: nil,
|
badges: nil,
|
||||||
|
auxiliary_data: auxiliary_data,
|
||||||
})]
|
})]
|
||||||
else
|
else
|
||||||
if params.is_a?(String)
|
if view && shelf_id
|
||||||
|
auxiliary_data["view"] = view
|
||||||
|
auxiliary_data["shelf_id"] = shelf_id
|
||||||
|
|
||||||
|
params = produce_featured_channel_browse_param(view.to_i64, shelf_id.to_i64)
|
||||||
initial_data = request_youtube_api_browse(ucid, params)
|
initial_data = request_youtube_api_browse(ucid, params)
|
||||||
continuation_token = fetch_continuation_token(initial_data)
|
continuation_token = fetch_continuation_token(initial_data)
|
||||||
else
|
else
|
||||||
@ -432,17 +439,19 @@ def fetch_channel_featured_channels(ucid, tab_data, params = nil, continuation =
|
|||||||
browse_endpoint_data: category.browse_endpoint_data,
|
browse_endpoint_data: category.browse_endpoint_data,
|
||||||
continuation_token: continuation_token,
|
continuation_token: continuation_token,
|
||||||
badges: nil,
|
badges: nil,
|
||||||
|
auxiliary_data: category.auxiliary_data,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
# If we don't have any categories we'll create one.
|
# If we don't have any categories we'll create one.
|
||||||
if category_array.empty?
|
if category_array.empty?
|
||||||
return [Category.new({
|
return [Category.new({
|
||||||
title: fallback_title, # If continuation contents is requested then the query_title has to be passed along.
|
title: fallback_title,
|
||||||
contents: items,
|
contents: items,
|
||||||
browse_endpoint_data: nil,
|
browse_endpoint_data: nil,
|
||||||
continuation_token: continuation_token,
|
continuation_token: continuation_token,
|
||||||
badges: nil,
|
badges: nil,
|
||||||
|
auxiliary_data: auxiliary_data,
|
||||||
})]
|
})]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -450,6 +459,21 @@ def fetch_channel_featured_channels(ucid, tab_data, params = nil, continuation =
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def produce_featured_channel_browse_param(view : Int64, shelf_id : Int64)
|
||||||
|
object = {
|
||||||
|
"2:string" => "channels",
|
||||||
|
"4:varint" => view,
|
||||||
|
"14:varint" => shelf_id
|
||||||
|
}
|
||||||
|
|
||||||
|
browse_params = object.try { |i| Protodec::Any.cast_json(object) }
|
||||||
|
.try { |i| Protodec::Any.from_json(i) }
|
||||||
|
.try { |i| Base64.urlsafe_encode(i) }
|
||||||
|
.try { |i| URI.encode_www_form(i) }
|
||||||
|
|
||||||
|
return browse_params
|
||||||
|
end
|
||||||
|
|
||||||
def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, sort_by = "newest", v2 = false)
|
def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, sort_by = "newest", v2 = false)
|
||||||
object = {
|
object = {
|
||||||
"80226972:embedded" => {
|
"80226972:embedded" => {
|
||||||
|
@ -208,7 +208,6 @@ private class CategoryParser < ItemParser
|
|||||||
def parse(item_contents, author_fallback)
|
def parse(item_contents, author_fallback)
|
||||||
# Title extraction is a bit complicated. There are two possible routes for it
|
# Title extraction is a bit complicated. There are two possible routes for it
|
||||||
# as well as times when the title attribute just isn't sent by YT.
|
# as well as times when the title attribute just isn't sent by YT.
|
||||||
|
|
||||||
title_container = item_contents["title"]? || ""
|
title_container = item_contents["title"]? || ""
|
||||||
if !title_container.is_a? String
|
if !title_container.is_a? String
|
||||||
if title = title_container["simpleText"]?
|
if title = title_container["simpleText"]?
|
||||||
@ -220,6 +219,7 @@ private class CategoryParser < ItemParser
|
|||||||
title = ""
|
title = ""
|
||||||
end
|
end
|
||||||
|
|
||||||
|
auxiliary_data = {} of String => String
|
||||||
browse_endpoint = item_contents["endpoint"]?.try &.["browseEndpoint"] || nil
|
browse_endpoint = item_contents["endpoint"]?.try &.["browseEndpoint"] || nil
|
||||||
browse_endpoint_data = ""
|
browse_endpoint_data = ""
|
||||||
category_type = 0 # 0: Video, 1: Channels, 2: Playlist/feed, 3: trending
|
category_type = 0 # 0: Video, 1: Channels, 2: Playlist/feed, 3: trending
|
||||||
@ -236,7 +236,14 @@ private class CategoryParser < ItemParser
|
|||||||
# instead it uses the browseId parameter. So if there isn't a params value we can assume the
|
# instead it uses the browseId parameter. So if there isn't a params value we can assume the
|
||||||
# category is a playlist/feed
|
# category is a playlist/feed
|
||||||
if browse_endpoint["params"]?
|
if browse_endpoint["params"]?
|
||||||
browse_endpoint_data = browse_endpoint["params"].as_s
|
# However, even though the channel category type returns the browse endpoint param
|
||||||
|
# we're not going to be using it in order to preserve compatablity with Youtube.
|
||||||
|
# and for an URL that looks cleaner
|
||||||
|
url = item_contents["endpoint"]["commandMetadata"]["webCommandMetadata"]["url"]
|
||||||
|
url = URI.parse(url.as_s)
|
||||||
|
auxiliary_data["view"] = url.query_params["view"]
|
||||||
|
auxiliary_data["shelf_id"] = url.query_params["shelf_id"]
|
||||||
|
|
||||||
category_type = 1
|
category_type = 1
|
||||||
else
|
else
|
||||||
browse_endpoint_data = browse_endpoint["browseId"].as_s
|
browse_endpoint_data = browse_endpoint["browseId"].as_s
|
||||||
@ -276,6 +283,7 @@ private class CategoryParser < ItemParser
|
|||||||
browse_endpoint_data: browse_endpoint_data,
|
browse_endpoint_data: browse_endpoint_data,
|
||||||
continuation_token: nil,
|
continuation_token: nil,
|
||||||
badges: badges,
|
badges: badges,
|
||||||
|
auxiliary_data: auxiliary_data,
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -237,6 +237,9 @@ class Category
|
|||||||
property continuation_token : String?
|
property continuation_token : String?
|
||||||
property badges : Array(Tuple(String, String))?
|
property badges : Array(Tuple(String, String))?
|
||||||
|
|
||||||
|
# Data unique to only specific types of categories.
|
||||||
|
property auxiliary_data : Hash(String, String)
|
||||||
|
|
||||||
def to_json(locale, json : JSON::Builder)
|
def to_json(locale, json : JSON::Builder)
|
||||||
json.object do
|
json.object do
|
||||||
json.field "title", self.title
|
json.field "title", self.title
|
||||||
|
@ -102,6 +102,12 @@ class Invidious::Routes::Channels < Invidious::Routes::BaseRoute
|
|||||||
return env.redirect "/channel/#{channel.ucid}"
|
return env.redirect "/channel/#{channel.ucid}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
view = env.params.query["view"]?
|
||||||
|
shelf_id = env.params.query["shelf_id"]?
|
||||||
|
# Category title isn't returned when requesting a specific category or continuation data
|
||||||
|
# so we have it in through a url param
|
||||||
|
current_category_title = env.params.query["title"]?
|
||||||
|
|
||||||
if continuation
|
if continuation
|
||||||
offset = env.params.query["offset"]?
|
offset = env.params.query["offset"]?
|
||||||
if offset
|
if offset
|
||||||
@ -112,47 +118,27 @@ class Invidious::Routes::Channels < Invidious::Routes::BaseRoute
|
|||||||
|
|
||||||
# Previous continuation
|
# Previous continuation
|
||||||
previous_continuation = env.params.query["previous"]?
|
previous_continuation = env.params.query["previous"]?
|
||||||
# Category title is not returned when using a continuation token.
|
|
||||||
title = env.params.query["title"]?
|
|
||||||
|
|
||||||
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], nil, continuation, title).not_nil!
|
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], nil, nil, continuation, current_category_title).not_nil!
|
||||||
|
elsif view && shelf_id
|
||||||
|
offset = env.params.query["offset"]?
|
||||||
|
if offset
|
||||||
|
offset = offset.to_i
|
||||||
|
else
|
||||||
|
offset = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], view, shelf_id, continuation, current_category_title).not_nil!
|
||||||
else
|
else
|
||||||
previous_continuation = nil
|
previous_continuation = nil
|
||||||
category_param = nil
|
|
||||||
offset = 0
|
offset = 0
|
||||||
title = nil
|
|
||||||
|
|
||||||
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], nil, nil).not_nil!
|
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], nil, nil, current_category_title).not_nil!
|
||||||
end
|
end
|
||||||
|
|
||||||
templated "channel/featured_channels", buffer_footer: true
|
templated "channel/featured_channels", buffer_footer: true
|
||||||
end
|
end
|
||||||
|
|
||||||
def featured_channel_category(env)
|
|
||||||
# Used to check when the initial page is reached and redirect to /channel/:ucid/channels/:param when zero
|
|
||||||
offset = env.params.query["offset"]?
|
|
||||||
category_param = env.params.url["param"]
|
|
||||||
if offset
|
|
||||||
offset = offset.to_i
|
|
||||||
else
|
|
||||||
offset = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
data = self.fetch_basic_information(env)
|
|
||||||
if !data.is_a?(Tuple)
|
|
||||||
return data
|
|
||||||
end
|
|
||||||
locale, user, subscriptions, continuation, ucid, channel = data
|
|
||||||
|
|
||||||
# Previous continuation
|
|
||||||
previous_continuation = env.params.query["previous"]?
|
|
||||||
# Category title is not returned when using a continuation token.
|
|
||||||
title = env.params.query["title"]?
|
|
||||||
|
|
||||||
featured_channel_categories = fetch_channel_featured_channels(ucid, channel.tabs["channels"], category_param, continuation, title).not_nil!
|
|
||||||
templated "channel/featured_channels"
|
|
||||||
end
|
|
||||||
|
|
||||||
def about(env)
|
def about(env)
|
||||||
data = self.fetch_basic_information(env)
|
data = self.fetch_basic_information(env)
|
||||||
if !data.is_a?(Tuple)
|
if !data.is_a?(Tuple)
|
||||||
|
@ -14,8 +14,9 @@
|
|||||||
<details open="">
|
<details open="">
|
||||||
<summary style="display: revert;">
|
<summary style="display: revert;">
|
||||||
<h3 class="category-heading">
|
<h3 class="category-heading">
|
||||||
<% if (category_request_param = category.browse_endpoint_data).is_a?(String) %>
|
<% if category.auxiliary_data.has_key?("view") %>
|
||||||
<a href="/channel/<%=channel.ucid%>/channels/<%=HTML.escape(category_request_param)%>">
|
<% category_url_param = "?view=#{category.auxiliary_data["view"]}&shelf_id=#{category.auxiliary_data["shelf_id"]}" %>
|
||||||
|
<a href="/channel/<%=channel.ucid%>/channels<%=HTML.escape(category_url_param)%>">
|
||||||
<%= category.title %>
|
<%= category.title %>
|
||||||
</a>
|
</a>
|
||||||
<%else%>
|
<%else%>
|
||||||
@ -90,14 +91,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<% if !featured_channel_categories.empty? %>
|
<% if !featured_channel_categories.empty? %>
|
||||||
|
<% base_url = "/channel/#{channel.ucid}/channels?view=#{view}&shelf_id=#{shelf_id}" %>
|
||||||
<div class="pure-g h-box">
|
<div class="pure-g h-box">
|
||||||
<div class="pure-u-1 pure-u-lg-1-5">
|
<div class="pure-u-1 pure-u-lg-1-5">
|
||||||
<% if previous_continuation %>
|
<% if previous_continuation %>
|
||||||
<a href="/channel/<%=channel.ucid%>/channels/<%=category_param%>?continuation=<%=HTML.escape(previous_continuation)%>&offset=<%=offset.not_nil!-1%>&title=<%=HTML.escape(title.not_nil!)%>">
|
<a href="<%= base_url %>&continuation=<%=HTML.escape(previous_continuation)%>&offset=<%=offset.not_nil!-1%>&title=<%=HTML.escape(current_category_title.not_nil!)%>">
|
||||||
<%= translate(locale, "Previous page") %>
|
<%= translate(locale, "Previous page") %>
|
||||||
</a>
|
</a>
|
||||||
<% elsif (offset - 1) == 0 %>
|
<% elsif (offset - 1) == 0 %>
|
||||||
<a href="/channel/<%=channel.ucid%>/channels/<%=category_param%>">
|
<a href="<%= base_url %>">
|
||||||
<%= translate(locale, "Previous page") %>
|
<%= translate(locale, "Previous page") %>
|
||||||
</a>
|
</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
@ -105,15 +107,15 @@
|
|||||||
<div class="pure-u-1 pure-u-lg-3-5"></div>
|
<div class="pure-u-1 pure-u-lg-3-5"></div>
|
||||||
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
|
<div class="pure-u-1 pure-u-lg-1-5" style="text-align:right">
|
||||||
<% if (next_cont_token = featured_channel_categories[0].continuation_token) %>
|
<% if (next_cont_token = featured_channel_categories[0].continuation_token) %>
|
||||||
<% additional_url_param = ""%>
|
<% previous = ""%>
|
||||||
<% if continuation %>
|
<% if continuation %>
|
||||||
<% additional_url_param = "&previous=#{HTML.escape(continuation)}"%>
|
<% previous = "&previous=#{HTML.escape(continuation)}"%>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if !title %>
|
<% if !current_category_title %>
|
||||||
<% title = featured_channel_categories[0].title %>
|
<% current_category_title = featured_channel_categories[0].title %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<a href="/channel/<%=channel.ucid%>/channels/<%=category_param%>?continuation=<%=HTML.escape(next_cont_token)%>&offset=<%=offset.not_nil!+1%>&title=<%=HTML.escape(title)%><%=additional_url_param%>">
|
<a href="<%= base_url %>&continuation=<%=HTML.escape(next_cont_token)%>&offset=<%=offset.not_nil!+1%>&title=<%=HTML.escape(current_category_title)%><%=previous%>">
|
||||||
<%= translate(locale, "Next page") %>
|
<%= translate(locale, "Next page") %>
|
||||||
</a>
|
</a>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
Loading…
Reference in New Issue
Block a user