mirror of
				https://gitea.invidious.io/iv-org/invidious.git
				synced 2024-08-15 00:53:41 +00:00 
			
		
		
		
	Refactored code and added badges to Search but many dummies because of the way components/item works
This commit is contained in:
		
							parent
							
								
									a2578ac6b4
								
							
						
					
					
						commit
						00df3e2c40
					
				
					 10 changed files with 69 additions and 30 deletions
				
			
		|  | @ -42,7 +42,7 @@ def get_about_info(ucid, locale) : AboutChannel | ||||||
|   if !initdata.has_key?("metadata") |   if !initdata.has_key?("metadata") | ||||||
|     auto_generated = true |     auto_generated = true | ||||||
|   end |   end | ||||||
|   verified = false | 
 | ||||||
|   if auto_generated |   if auto_generated | ||||||
|     author = initdata["header"]["interactiveTabbedHeaderRenderer"]["title"]["simpleText"].as_s |     author = initdata["header"]["interactiveTabbedHeaderRenderer"]["title"]["simpleText"].as_s | ||||||
|     author_url = initdata["microformat"]["microformatDataRenderer"]["urlCanonical"].as_s |     author_url = initdata["microformat"]["microformatDataRenderer"]["urlCanonical"].as_s | ||||||
|  | @ -71,10 +71,9 @@ def get_about_info(ucid, locale) : AboutChannel | ||||||
|     # if banner.includes? "channels/c4/default_banner" |     # if banner.includes? "channels/c4/default_banner" | ||||||
|     #  banner = nil |     #  banner = nil | ||||||
|     # end |     # end | ||||||
|     badges = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["badges"]? |     author_verified_badges = initdata["header"]?.try &.["c4TabbedHeaderRenderer"]?.try &.["badges"]? | ||||||
|     if !badges.nil? | 
 | ||||||
|       verified = true |     author_verified = (author_verified_badges && author_verified_badges.size > 0) | ||||||
|     end |  | ||||||
|     description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" |     description = initdata["metadata"]["channelMetadataRenderer"]?.try &.["description"]?.try &.as_s? || "" | ||||||
|     description_html = HTML.escape(description) |     description_html = HTML.escape(description) | ||||||
| 
 | 
 | ||||||
|  | @ -132,7 +131,7 @@ def get_about_info(ucid, locale) : AboutChannel | ||||||
|     is_family_friendly: is_family_friendly, |     is_family_friendly: is_family_friendly, | ||||||
|     allowed_regions: allowed_regions, |     allowed_regions: allowed_regions, | ||||||
|     tabs: tabs, |     tabs: tabs, | ||||||
|     verified: verified, |     verified: author_verified || false, | ||||||
|   ) |   ) | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -21,6 +21,7 @@ struct ChannelVideo | ||||||
|   property live_now : Bool = false |   property live_now : Bool = false | ||||||
|   property premiere_timestamp : Time? = nil |   property premiere_timestamp : Time? = nil | ||||||
|   property views : Int64? = nil |   property views : Int64? = nil | ||||||
|  |   property author_verified : Bool #TODO currently a dummy | ||||||
| 
 | 
 | ||||||
|   def to_json(locale, json : JSON::Builder) |   def to_json(locale, json : JSON::Builder) | ||||||
|     json.object do |     json.object do | ||||||
|  | @ -218,6 +219,7 @@ def fetch_channel(ucid, pull_all_videos : Bool) | ||||||
|       live_now:           live_now, |       live_now:           live_now, | ||||||
|       premiere_timestamp: premiere_timestamp, |       premiere_timestamp: premiere_timestamp, | ||||||
|       views:              views, |       views:              views, | ||||||
|  |       author_verified: false, #TODO dummy for components/item.ecr | ||||||
|     }) |     }) | ||||||
| 
 | 
 | ||||||
|     LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updating or inserting video") |     LOGGER.trace("fetch_channel: #{ucid} : video #{video_id} : Updating or inserting video") | ||||||
|  | @ -255,6 +257,7 @@ def fetch_channel(ucid, pull_all_videos : Bool) | ||||||
|         live_now:           video.live_now, |         live_now:           video.live_now, | ||||||
|         premiere_timestamp: video.premiere_timestamp, |         premiere_timestamp: video.premiere_timestamp, | ||||||
|         views:              video.views, |         views:              video.views, | ||||||
|  |         author_verified: false, #TODO dummy for components/item.ecr | ||||||
|       }) } |       }) } | ||||||
| 
 | 
 | ||||||
|       videos.each do |video| |       videos.each do |video| | ||||||
|  |  | ||||||
|  | @ -144,8 +144,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b | ||||||
| 
 | 
 | ||||||
|               content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" |               content_html = node_comment["contentText"]?.try { |t| parse_content(t) } || "" | ||||||
|               author = node_comment["authorText"]?.try &.["simpleText"]? || "" |               author = node_comment["authorText"]?.try &.["simpleText"]? || "" | ||||||
|               verified = node_comment["authorCommentBadge"]? != nil |               verified = (node_comment["authorCommentBadge"]? != nil) | ||||||
|               json.field "verified", verified |               json.field "verified", (verified || false) | ||||||
|               json.field "author", author |               json.field "author", author | ||||||
|               json.field "authorThumbnails" do |               json.field "authorThumbnails" do | ||||||
|                 json.array do |                 json.array do | ||||||
|  | @ -329,7 +329,7 @@ def template_youtube_comments(comments, locale, thin_mode, is_replies = false) | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       author_name = HTML.escape(child["author"].as_s) |       author_name = HTML.escape(child["author"].as_s) | ||||||
|       if child["verified"].as_bool |       if child["verified"]?.try &.as_bool | ||||||
|         author_name += "<i class=\"icon ion ion-md-checkmark-circle\"></i>" |         author_name += "<i class=\"icon ion ion-md-checkmark-circle\"></i>" | ||||||
|       end |       end | ||||||
|       html << <<-END_HTML |       html << <<-END_HTML | ||||||
|  |  | ||||||
|  | @ -12,6 +12,7 @@ struct SearchVideo | ||||||
|   property live_now : Bool |   property live_now : Bool | ||||||
|   property premium : Bool |   property premium : Bool | ||||||
|   property premiere_timestamp : Time? |   property premiere_timestamp : Time? | ||||||
|  |   property author_verified : Bool | ||||||
| 
 | 
 | ||||||
|   def to_xml(auto_generated, query_params, xml : XML::Builder) |   def to_xml(auto_generated, query_params, xml : XML::Builder) | ||||||
|     query_params["v"] = self.id |     query_params["v"] = self.id | ||||||
|  | @ -129,6 +130,7 @@ struct SearchPlaylist | ||||||
|   property video_count : Int32 |   property video_count : Int32 | ||||||
|   property videos : Array(SearchPlaylistVideo) |   property videos : Array(SearchPlaylistVideo) | ||||||
|   property thumbnail : String? |   property thumbnail : String? | ||||||
|  |   property author_verified : Bool | ||||||
| 
 | 
 | ||||||
|   def to_json(locale : String?, json : JSON::Builder) |   def to_json(locale : String?, json : JSON::Builder) | ||||||
|     json.object do |     json.object do | ||||||
|  | @ -140,7 +142,7 @@ struct SearchPlaylist | ||||||
|       json.field "author", self.author |       json.field "author", self.author | ||||||
|       json.field "authorId", self.ucid |       json.field "authorId", self.ucid | ||||||
|       json.field "authorUrl", "/channel/#{self.ucid}" |       json.field "authorUrl", "/channel/#{self.ucid}" | ||||||
| 
 |       json.field "authorVerified", self.author_verified | ||||||
|       json.field "videoCount", self.video_count |       json.field "videoCount", self.video_count | ||||||
|       json.field "videos" do |       json.field "videos" do | ||||||
|         json.array do |         json.array do | ||||||
|  | @ -182,6 +184,7 @@ struct SearchChannel | ||||||
|   property video_count : Int32 |   property video_count : Int32 | ||||||
|   property description_html : String |   property description_html : String | ||||||
|   property auto_generated : Bool |   property auto_generated : Bool | ||||||
|  |   property author_verified : Bool | ||||||
| 
 | 
 | ||||||
|   def to_json(locale : String?, json : JSON::Builder) |   def to_json(locale : String?, json : JSON::Builder) | ||||||
|     json.object do |     json.object do | ||||||
|  | @ -189,7 +192,7 @@ struct SearchChannel | ||||||
|       json.field "author", self.author |       json.field "author", self.author | ||||||
|       json.field "authorId", self.ucid |       json.field "authorId", self.ucid | ||||||
|       json.field "authorUrl", "/channel/#{self.ucid}" |       json.field "authorUrl", "/channel/#{self.ucid}" | ||||||
| 
 |       json.field "authorVerified", self.author_verified | ||||||
|       json.field "authorThumbnails" do |       json.field "authorThumbnails" do | ||||||
|         json.array do |         json.array do | ||||||
|           qualities = {32, 48, 76, 100, 176, 512} |           qualities = {32, 48, 76, 100, 176, 512} | ||||||
|  |  | ||||||
|  | @ -8,6 +8,10 @@ struct MixVideo | ||||||
|   property length_seconds : Int32 |   property length_seconds : Int32 | ||||||
|   property index : Int32 |   property index : Int32 | ||||||
|   property rdid : String |   property rdid : String | ||||||
|  | 
 | ||||||
|  |   def author_verified | ||||||
|  |     false #TODO dummy | ||||||
|  |   end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
| struct Mix | struct Mix | ||||||
|  |  | ||||||
|  | @ -234,6 +234,10 @@ struct InvidiousPlaylist | ||||||
|     0_i64 |     0_i64 | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   def author_verified | ||||||
|  |     false # TODO dummy for components/item.ecr | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   def description_html |   def description_html | ||||||
|     HTML.escape(self.description) |     HTML.escape(self.description) | ||||||
|   end |   end | ||||||
|  | @ -252,6 +256,7 @@ def create_playlist(title, privacy, user) | ||||||
|     updated:     Time.utc, |     updated:     Time.utc, | ||||||
|     privacy:     privacy, |     privacy:     privacy, | ||||||
|     index:       [] of Int64, |     index:       [] of Int64, | ||||||
|  |     author_verified: false, # TODO dummy for components/item.ecr | ||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|   Invidious::Database::Playlists.insert(playlist) |   Invidious::Database::Playlists.insert(playlist) | ||||||
|  | @ -270,6 +275,7 @@ def subscribe_playlist(user, playlist) | ||||||
|     updated:     playlist.updated, |     updated:     playlist.updated, | ||||||
|     privacy:     PlaylistPrivacy::Private, |     privacy:     PlaylistPrivacy::Private, | ||||||
|     index:       [] of Int64, |     index:       [] of Int64, | ||||||
|  |     author_verified: false, # TODO dummy for components/item.ecr | ||||||
|   }) |   }) | ||||||
| 
 | 
 | ||||||
|   Invidious::Database::Playlists.insert(playlist) |   Invidious::Database::Playlists.insert(playlist) | ||||||
|  |  | ||||||
|  | @ -182,6 +182,7 @@ module Invidious::Routes::Feeds | ||||||
|         paid:               false, |         paid:               false, | ||||||
|         premium:            false, |         premium:            false, | ||||||
|         premiere_timestamp: nil, |         premiere_timestamp: nil, | ||||||
|  |         author_verified: false, #TODO real value | ||||||
|       }) |       }) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -414,6 +415,7 @@ module Invidious::Routes::Feeds | ||||||
|           live_now:           video.live_now, |           live_now:           video.live_now, | ||||||
|           premiere_timestamp: video.premiere_timestamp, |           premiere_timestamp: video.premiere_timestamp, | ||||||
|           views:              video.views, |           views:              video.views, | ||||||
|  |           author_verified: false, #TODO dummy for components/item.ecr | ||||||
|         }) |         }) | ||||||
| 
 | 
 | ||||||
|         was_insert = Invidious::Database::ChannelVideos.insert(video, with_premiere_timestamp: true) |         was_insert = Invidious::Database::ChannelVideos.insert(video, with_premiere_timestamp: true) | ||||||
|  |  | ||||||
|  | @ -1047,7 +1047,9 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ | ||||||
| 
 | 
 | ||||||
|   author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") |   author_info = video_secondary_renderer.try &.dig?("owner", "videoOwnerRenderer") | ||||||
|   author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") |   author_thumbnail = author_info.try &.dig?("thumbnail", "thumbnails", 0, "url") | ||||||
|   params["authorVerified"] = JSON::Any.new(author_info.try &.["badges"]? != nil) |   author_verified_badge = author_info.try &.["badges"]? | ||||||
|  | 
 | ||||||
|  |   params["authorVerified"] = JSON::Any.new((author_verified_badge && author_verified_badge.size > 0) || false) | ||||||
|   params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") |   params["authorThumbnail"] = JSON::Any.new(author_thumbnail.try &.as_s || "") | ||||||
| 
 | 
 | ||||||
|   params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? |   params["subCountText"] = JSON::Any.new(author_info.try &.["subscriberCountText"]? | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
|                         <img loading="lazy" style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).request_target.gsub(/=s\d+/, "=s176") %>"/> |                         <img loading="lazy" style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).request_target.gsub(/=s\d+/, "=s176") %>"/> | ||||||
|                     </center> |                     </center> | ||||||
|                 <% end %> |                 <% end %> | ||||||
|                 <p dir="auto"><%= HTML.escape(item.author) %></p> |                 <p dir="auto"><%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><i class="icon ion ion-md-checkmark-circle"></i><% end %></p> | ||||||
|             </a> |             </a> | ||||||
|             <p><%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %></p> |             <p><%= translate_count(locale, "generic_subscribers_count", item.subscriber_count, NumberFormatting::Separator) %></p> | ||||||
|             <% if !item.auto_generated %><p><%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %></p><% end %> |             <% if !item.auto_generated %><p><%= translate_count(locale, "generic_videos_count", item.video_count, NumberFormatting::Separator) %></p><% end %> | ||||||
|  | @ -30,7 +30,7 @@ | ||||||
|                 <p dir="auto"><%= HTML.escape(item.title) %></p> |                 <p dir="auto"><%= HTML.escape(item.title) %></p> | ||||||
|             </a> |             </a> | ||||||
|             <a href="/channel/<%= item.ucid %>"> |             <a href="/channel/<%= item.ucid %>"> | ||||||
|                 <p dir="auto"><b><%= HTML.escape(item.author) %></b></p> |                 <p dir="auto"><b><%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><i class="icon ion ion-md-checkmark-circle"></i><% end %></b></p> | ||||||
|             </a> |             </a> | ||||||
|         <% when MixVideo %> |         <% when MixVideo %> | ||||||
|             <a href="/watch?v=<%= item.id %>&list=<%= item.rdid %>"> |             <a href="/watch?v=<%= item.id %>&list=<%= item.rdid %>"> | ||||||
|  | @ -45,7 +45,7 @@ | ||||||
|                 <p dir="auto"><%= HTML.escape(item.title) %></p> |                 <p dir="auto"><%= HTML.escape(item.title) %></p> | ||||||
|             </a> |             </a> | ||||||
|             <a href="/channel/<%= item.ucid %>"> |             <a href="/channel/<%= item.ucid %>"> | ||||||
|                 <p dir="auto"><b><%= HTML.escape(item.author) %></b></p> |                 <p dir="auto"><b><%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><i class="icon ion ion-md-checkmark-circle"></i><% end %></b></p> | ||||||
|             </a> |             </a> | ||||||
|         <% when PlaylistVideo %> |         <% when PlaylistVideo %> | ||||||
|             <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.plid %>&index=<%= item.index %>"> |             <a style="width:100%" href="/watch?v=<%= item.id %>&list=<%= item.plid %>&index=<%= item.index %>"> | ||||||
|  | @ -142,7 +142,7 @@ | ||||||
| 
 | 
 | ||||||
|             <div class="video-card-row flexible"> |             <div class="video-card-row flexible"> | ||||||
|                 <div class="flex-left"><a href="/channel/<%= item.ucid %>"> |                 <div class="flex-left"><a href="/channel/<%= item.ucid %>"> | ||||||
|                     <p class="channel-name" dir="auto"><%= HTML.escape(item.author) %></p> |                     <p class="channel-name" dir="auto"><%= HTML.escape(item.author) %><% if !item.author_verified.nil? && item.author_verified %><i class="icon ion ion-md-checkmark-circle"></i><% end %></p> | ||||||
|                 </a></div> |                 </a></div> | ||||||
| 
 | 
 | ||||||
|                 <% endpoint_params = "?v=#{item.id}" %> |                 <% endpoint_params = "?v=#{item.id}" %> | ||||||
|  |  | ||||||
|  | @ -102,7 +102,11 @@ private module Parsers | ||||||
|       premium = false |       premium = false | ||||||
| 
 | 
 | ||||||
|       premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) } |       premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) } | ||||||
|  |       author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| | ||||||
|  |         badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") | ||||||
|  |       end | ||||||
| 
 | 
 | ||||||
|  |       author_verified = (author_verified_badge && author_verified_badge.size > 0) | ||||||
|       item_contents["badges"]?.try &.as_a.each do |badge| |       item_contents["badges"]?.try &.as_a.each do |badge| | ||||||
|         b = badge["metadataBadgeRenderer"] |         b = badge["metadataBadgeRenderer"] | ||||||
|         case b["label"].as_s |         case b["label"].as_s | ||||||
|  | @ -129,6 +133,7 @@ private module Parsers | ||||||
|         live_now:           live_now, |         live_now:           live_now, | ||||||
|         premium:            premium, |         premium:            premium, | ||||||
|         premiere_timestamp: premiere_timestamp, |         premiere_timestamp: premiere_timestamp, | ||||||
|  |         author_verified:    author_verified || false, | ||||||
|       }) |       }) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -156,7 +161,11 @@ private module Parsers | ||||||
|     private def self.parse(item_contents, author_fallback) |     private def self.parse(item_contents, author_fallback) | ||||||
|       author = extract_text(item_contents["title"]) || author_fallback.name |       author = extract_text(item_contents["title"]) || author_fallback.name | ||||||
|       author_id = item_contents["channelId"]?.try &.as_s || author_fallback.id |       author_id = item_contents["channelId"]?.try &.as_s || author_fallback.id | ||||||
|  |       author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| | ||||||
|  |         badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") | ||||||
|  |       end | ||||||
| 
 | 
 | ||||||
|  |       author_verified = (author_verified_badge && author_verified_badge.size > 0) | ||||||
|       author_thumbnail = HelperExtractors.get_thumbnails(item_contents) |       author_thumbnail = HelperExtractors.get_thumbnails(item_contents) | ||||||
|       # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. |       # When public subscriber count is disabled, the subscriberCountText isn't sent by InnerTube. | ||||||
|       # Always simpleText |       # Always simpleText | ||||||
|  | @ -179,6 +188,7 @@ private module Parsers | ||||||
|         video_count:      video_count, |         video_count:      video_count, | ||||||
|         description_html: description_html, |         description_html: description_html, | ||||||
|         auto_generated:   auto_generated, |         auto_generated:   auto_generated, | ||||||
|  |         author_verified:  author_verified || false, | ||||||
|       }) |       }) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -206,18 +216,23 @@ private module Parsers | ||||||
|     private def self.parse(item_contents, author_fallback) |     private def self.parse(item_contents, author_fallback) | ||||||
|       title = extract_text(item_contents["title"]) || "" |       title = extract_text(item_contents["title"]) || "" | ||||||
|       plid = item_contents["playlistId"]?.try &.as_s || "" |       plid = item_contents["playlistId"]?.try &.as_s || "" | ||||||
|  |       author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| | ||||||
|  |         badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") | ||||||
|  |       end | ||||||
| 
 | 
 | ||||||
|  |       author_verified = (author_verified_badge && author_verified_badge.size > 0) | ||||||
|       video_count = HelperExtractors.get_video_count(item_contents) |       video_count = HelperExtractors.get_video_count(item_contents) | ||||||
|       playlist_thumbnail = HelperExtractors.get_thumbnails(item_contents) |       playlist_thumbnail = HelperExtractors.get_thumbnails(item_contents) | ||||||
| 
 | 
 | ||||||
|       SearchPlaylist.new({ |       SearchPlaylist.new({ | ||||||
|         title:       title, |         title:           title, | ||||||
|         id:          plid, |         id:              plid, | ||||||
|         author:      author_fallback.name, |         author:          author_fallback.name, | ||||||
|         ucid:        author_fallback.id, |         ucid:            author_fallback.id, | ||||||
|         video_count: video_count, |         video_count:     video_count, | ||||||
|         videos:      [] of SearchPlaylistVideo, |         videos:          [] of SearchPlaylistVideo, | ||||||
|         thumbnail:   playlist_thumbnail, |         thumbnail:       playlist_thumbnail, | ||||||
|  |         author_verified: author_verified || false, | ||||||
|       }) |       }) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -251,7 +266,11 @@ private module Parsers | ||||||
|       author_info = item_contents.dig?("shortBylineText", "runs", 0) |       author_info = item_contents.dig?("shortBylineText", "runs", 0) | ||||||
|       author = author_info.try &.["text"].as_s || author_fallback.name |       author = author_info.try &.["text"].as_s || author_fallback.name | ||||||
|       author_id = author_info.try { |x| HelperExtractors.get_browse_id(x) } || author_fallback.id |       author_id = author_info.try { |x| HelperExtractors.get_browse_id(x) } || author_fallback.id | ||||||
|  |       author_verified_badge = item_contents["ownerBadges"]?.try do |badges_array| | ||||||
|  |         badges_array.as_a.find(&.dig("metadataBadgeRenderer", "tooltip").as_s.== "Verified") | ||||||
|  |       end | ||||||
| 
 | 
 | ||||||
|  |       author_verified = (author_verified_badge && author_verified_badge.size > 0) | ||||||
|       videos = item_contents["videos"]?.try &.as_a.map do |v| |       videos = item_contents["videos"]?.try &.as_a.map do |v| | ||||||
|         v = v["childVideoRenderer"] |         v = v["childVideoRenderer"] | ||||||
|         v_title = v.dig?("title", "simpleText").try &.as_s || "" |         v_title = v.dig?("title", "simpleText").try &.as_s || "" | ||||||
|  | @ -267,13 +286,14 @@ private module Parsers | ||||||
|       # TODO: item_contents["publishedTimeText"]? |       # TODO: item_contents["publishedTimeText"]? | ||||||
| 
 | 
 | ||||||
|       SearchPlaylist.new({ |       SearchPlaylist.new({ | ||||||
|         title:       title, |         title:           title, | ||||||
|         id:          plid, |         id:              plid, | ||||||
|         author:      author, |         author:          author, | ||||||
|         ucid:        author_id, |         ucid:            author_id, | ||||||
|         video_count: video_count, |         video_count:     video_count, | ||||||
|         videos:      videos, |         videos:          videos, | ||||||
|         thumbnail:   playlist_thumbnail, |         thumbnail:       playlist_thumbnail, | ||||||
|  |         author_verified: author_verified || false, | ||||||
|       }) |       }) | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue