diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index aaec19c5..ca7c9ebc 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -400,6 +400,22 @@ def extract_items(initial_data : Hash(String, JSON::Any), author_fallback : Stri
description_html: description_html,
auto_generated: auto_generated,
)
+ elsif i = item["gridPlaylistRenderer"]?
+ title = i["title"]["runs"].as_a[0]?.try &.["text"].as_s || ""
+ plid = i["playlistId"]?.try &.as_s || ""
+
+ video_count = i["videoCountText"]["runs"].as_a[0]?.try &.["text"].as_s.gsub(/\D/, "").to_i || 0
+ playlist_thumbnail = i["thumbnail"]["thumbnails"][0]?.try &.["url"]?.try &.as_s || ""
+
+ items << SearchPlaylist.new(
+ title: title,
+ id: plid,
+ author: author_fallback || "",
+ ucid: author_id_fallback || "",
+ video_count: video_count,
+ videos: [] of SearchPlaylistVideo,
+ thumbnail: playlist_thumbnail
+ )
elsif i = item["playlistRenderer"]?
title = i["title"]["simpleText"]?.try &.as_s || ""
plid = i["playlistId"]?.try &.as_s || ""
diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr
index fcf73dad..a1b7715d 100644
--- a/src/invidious/playlists.cr
+++ b/src/invidious/playlists.cr
@@ -118,7 +118,7 @@ struct Playlist
end
end
- json.field "description", html_to_content(self.description_html)
+ json.field "description", self.description
json.field "descriptionHtml", self.description_html
json.field "videoCount", self.video_count
@@ -153,7 +153,7 @@ struct Playlist
author: String,
author_thumbnail: String,
ucid: String,
- description_html: String,
+ description: String,
video_count: Int32,
views: Int64,
updated: Time,
@@ -163,6 +163,10 @@ struct Playlist
def privacy
PlaylistPrivacy::Public
end
+
+ def description_html
+ HTML.escape(self.description).gsub("\n", "
")
+ end
end
enum PlaylistPrivacy
@@ -298,52 +302,6 @@ def subscribe_playlist(db, user, playlist)
return playlist
end
-def extract_playlist(plid, nodeset, index)
- videos = [] of PlaylistVideo
-
- nodeset.each_with_index do |video, offset|
- anchor = video.xpath_node(%q(.//td[@class="pl-video-title"]))
- if !anchor
- next
- end
-
- title = anchor.xpath_node(%q(.//a)).not_nil!.content.strip(" \n")
- id = anchor.xpath_node(%q(.//a)).not_nil!["href"].lchop("/watch?v=")[0, 11]
-
- anchor = anchor.xpath_node(%q(.//div[@class="pl-video-owner"]/a))
- if anchor
- author = anchor.content
- ucid = anchor["href"].split("/")[2]
- else
- author = ""
- ucid = ""
- end
-
- anchor = video.xpath_node(%q(.//td[@class="pl-video-time"]/div/div[1]))
- if anchor && !anchor.content.empty?
- length_seconds = decode_length_seconds(anchor.content)
- live_now = false
- else
- length_seconds = 0
- live_now = true
- end
-
- videos << PlaylistVideo.new(
- title: title,
- id: id,
- author: author,
- ucid: ucid,
- length_seconds: length_seconds,
- published: Time.utc,
- plid: plid,
- index: (index + offset).to_i64,
- live_now: live_now
- )
- end
-
- return videos
-end
-
def produce_playlist_url(id, index)
if id.starts_with? "UC"
id = "UU" + id.lchop("UC")
@@ -389,58 +347,64 @@ def fetch_playlist(plid, locale)
plid = "UU#{plid.lchop("UC")}"
end
- response = YT_POOL.client &.get("/playlist?list=#{plid}&hl=en&disable_polymer=1")
+ response = YT_POOL.client &.get("/playlist?list=#{plid}&hl=en")
if response.status_code != 200
- raise translate(locale, "Not a playlist.")
+ if response.headers["location"]?.try &.includes? "/sorry/index"
+ raise "Could not extract playlist info. Instance is likely blocked."
+ else
+ raise translate(locale, "Not a playlist.")
+ end
end
- body = response.body.gsub(/