diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/invidious/comments.cr | 12 | ||||
| -rw-r--r-- | src/invidious/helpers/utils.cr | 2 | ||||
| -rw-r--r-- | src/invidious/routes/playlists.cr | 2 | ||||
| -rw-r--r-- | src/invidious/search.cr | 51 | ||||
| -rw-r--r-- | src/invidious/trending.cr | 24 | ||||
| -rw-r--r-- | src/invidious/views/components/item.ecr | 5 | ||||
| -rw-r--r-- | src/invidious/views/trending.ecr | 2 |
7 files changed, 57 insertions, 41 deletions
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index e7e87203..5d72503e 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -226,7 +226,7 @@ def fetch_youtube_comments(id, db, cursor, format, locale, thin_mode, region, so if body["continuations"]? continuation = body["continuations"][0]["nextContinuationData"]["continuation"].as_s - json.field "continuation", cursor.try &.starts_with?("E") ? continuation : extract_comment_cursor(continuation) + json.field "continuation", continuation end end end @@ -580,16 +580,6 @@ def content_to_comment_html(content) return comment_html end -def extract_comment_cursor(continuation) - cursor = URI.decode_www_form(continuation) - .try { |i| Base64.decode(i) } - .try { |i| IO::Memory.new(i) } - .try { |i| Protodec::Any.parse(i) } - .try { |i| i["6:2:embedded"]["1:0:string"].as_s } - - return cursor -end - def produce_comment_continuation(video_id, cursor = "", sort_by = "top") object = { "2:embedded" => { diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr index 2c95a373..67f496df 100644 --- a/src/invidious/helpers/utils.cr +++ b/src/invidious/helpers/utils.cr @@ -9,6 +9,8 @@ def add_yt_headers(request) return if request.resource.starts_with? "/sorry/index" request.headers["x-youtube-client-name"] ||= "1" request.headers["x-youtube-client-version"] ||= "2.20200609" + # Preserve original cookies and add new YT consent cookie for EU servers + request.headers["cookie"] = "#{request.headers["cookie"]?}; CONSENT=YES+" if !CONFIG.cookies.empty? request.headers["cookie"] = "#{(CONFIG.cookies.map { |c| "#{c.name}=#{c.value}" }).join("; ")}; #{request.headers["cookie"]?}" end diff --git a/src/invidious/routes/playlists.cr b/src/invidious/routes/playlists.cr index 73c14155..1f7fa27d 100644 --- a/src/invidious/routes/playlists.cr +++ b/src/invidious/routes/playlists.cr @@ -434,7 +434,7 @@ class Invidious::Routes::Playlists < Invidious::Routes::BaseRoute end page_count = (playlist.video_count / 100).to_i - page_count = 1 if page_count == 0 + page_count += 1 if (playlist.video_count % 100) > 0 if page > page_count return env.redirect "/playlist?list=#{plid}&page=#{page_count}" diff --git a/src/invidious/search.cr b/src/invidious/search.cr index cf8fd790..4b216613 100644 --- a/src/invidious/search.cr +++ b/src/invidious/search.cr @@ -231,20 +231,32 @@ end alias SearchItem = SearchVideo | SearchChannel | SearchPlaylist def channel_search(query, page, channel) - response = YT_POOL.client &.get("/channel/#{channel}?hl=en&gl=US") - response = YT_POOL.client &.get("/user/#{channel}?hl=en&gl=US") if response.headers["location"]? - response = YT_POOL.client &.get("/c/#{channel}?hl=en&gl=US") if response.headers["location"]? + response = YT_POOL.client &.get("/channel/#{channel}") + + if response.status_code == 404 + response = YT_POOL.client &.get("/user/#{channel}") + response = YT_POOL.client &.get("/c/#{channel}") if response.status_code == 404 + initial_data = extract_initial_data(response.body) + ucid = initial_data["header"]["c4TabbedHeaderRenderer"]?.try &.["channelId"].as_s? + raise InfoException.new("Impossible to extract channel ID from page") if !ucid + else + ucid = channel + end - ucid = response.body.match(/\\"channelId\\":\\"(?<ucid>[^\\]+)\\"/).try &.["ucid"]? + continuation = produce_channel_search_continuation(ucid, query, page) + response_json = request_youtube_api_browse(continuation) - return 0, [] of SearchItem if !ucid + result = JSON.parse(response_json) + continuationItems = result["onResponseReceivedActions"]? + .try &.[0]["appendContinuationItemsAction"]["continuationItems"] - url = produce_channel_search_url(ucid, query, page) - response = YT_POOL.client &.get(url) - initial_data = JSON.parse(response.body).as_a.find &.["response"]? - return 0, [] of SearchItem if !initial_data - author = initial_data["response"]?.try &.["metadata"]?.try &.["channelMetadataRenderer"]?.try &.["title"]?.try &.as_s - items = extract_items(initial_data.as_h, author, ucid) + return 0, [] of SearchItem if !continuationItems + + items = [] of SearchItem + continuationItems.as_a.select(&.as_h.has_key?("itemSectionRenderer")).each { |item| + extract_item(item["itemSectionRenderer"]["contents"].as_a[0]) + .try { |t| items << t } + } return items.size, items end @@ -361,17 +373,28 @@ def produce_search_params(page = 1, sort : String = "relevance", date : String = return params end -def produce_channel_search_url(ucid, query, page) +def produce_channel_search_continuation(ucid, query, page) + if page <= 1 + idx = 0_i64 + else + idx = 30_i64 * (page - 1) + end + object = { "80226972:embedded" => { "2:string" => ucid, "3:base64" => { "2:string" => "search", + "6:varint" => 1_i64, "7:varint" => 1_i64, - "15:string" => "#{page}", + "12:varint" => 1_i64, + "15:base64" => { + "3:varint" => idx, + }, "23:varint" => 0_i64, }, "11:string" => query, + "35:string" => "browse-feed#{ucid}search", }, } @@ -380,7 +403,7 @@ def produce_channel_search_url(ucid, query, page) .try { |i| Base64.urlsafe_encode(i) } .try { |i| URI.encode_www_form(i) } - return "/browse_ajax?continuation=#{continuation}&gl=US&hl=en" + return continuation end def process_search_query(query, page, user, region) diff --git a/src/invidious/trending.cr b/src/invidious/trending.cr index 8d078387..910a99d8 100644 --- a/src/invidious/trending.cr +++ b/src/invidious/trending.cr @@ -6,24 +6,22 @@ def fetch_trending(trending_type, region, locale) plid = nil if trending_type && trending_type != "Default" - trending_type = trending_type.downcase.capitalize + if trending_type == "Music" + trending_type = 1 + elsif trending_type == "Gaming" + trending_type = 2 + elsif trending_type == "Movies" + trending_type = 3 + end response = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body initial_data = extract_initial_data(response) + url = initial_data["contents"]["twoColumnBrowseResultsRenderer"]["tabs"][trending_type]["tabRenderer"]["endpoint"]["commandMetadata"]["webCommandMetadata"]["url"] + url = "#{url}&gl=#{region}&hl=en" - tabs = initial_data["contents"]["twoColumnBrowseResultsRenderer"]["tabs"][0]["tabRenderer"]["content"]["sectionListRenderer"]["subMenu"]["channelListSubMenuRenderer"]["contents"].as_a - url = tabs.select { |tab| tab["channelListSubMenuAvatarRenderer"]["title"]["simpleText"] == trending_type }[0]? - - if url - url["channelListSubMenuAvatarRenderer"]["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"] - url = url["channelListSubMenuAvatarRenderer"]["navigationEndpoint"]["commandMetadata"]["webCommandMetadata"]["url"].as_s - url = "#{url}&gl=#{region}&hl=en" - trending = YT_POOL.client &.get(url).body - plid = extract_plid(url) - else - trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body - end + trending = YT_POOL.client &.get(url).body + plid = extract_plid(url) else trending = YT_POOL.client &.get("/feed/trending?gl=#{region}&hl=en").body end diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr index ea7d356c..9dfa047e 100644 --- a/src/invidious/views/components/item.ecr +++ b/src/invidious/views/components/item.ecr @@ -141,7 +141,10 @@ <b style="flex: 1;"> <a style="width:100%" href="/channel/<%= item.ucid %>"><%= item.author %></a> </b> - <a title="Audio mode" href="/watch?v=<%= item.id %>&listen=1"> + <a title="<%=translate(locale, "Watch on YouTube")%>" href="https://www.youtube.com/watch?v=<%= item.id %>" style="margin-right: 5px;"> + <i class="icon ion-logo-youtube"></i> + </a> + <a title="<%=translate(locale, "Audio mode")%>" href="/watch?v=<%= item.id %>&listen=1"> <i class="icon ion-md-headset"></i> </a> </p> diff --git a/src/invidious/views/trending.ecr b/src/invidious/views/trending.ecr index 42acb15c..3ec62555 100644 --- a/src/invidious/views/trending.ecr +++ b/src/invidious/views/trending.ecr @@ -21,7 +21,7 @@ </div> <div class="pure-u-1-3"> <div class="pure-g" style="text-align:right"> - <% {"Default", "Music", "Gaming", "News", "Movies"}.each do |option| %> + <% {"Default", "Music", "Gaming", "Movies"}.each do |option| %> <div class="pure-u-1 pure-md-1-3"> <% if trending_type == option %> <b><%= translate(locale, option) %></b> |
