summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/invidious/comments.cr12
-rw-r--r--src/invidious/helpers/utils.cr2
-rw-r--r--src/invidious/routes/playlists.cr2
-rw-r--r--src/invidious/search.cr51
-rw-r--r--src/invidious/trending.cr24
-rw-r--r--src/invidious/views/components/item.ecr5
-rw-r--r--src/invidious/views/trending.ecr2
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 %>&amp;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 %>&amp;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>