|
|
|
@ -20,6 +20,7 @@ private ITEM_PARSERS = {
|
|
|
|
|
Parsers::ReelItemRendererParser,
|
|
|
|
|
Parsers::ItemSectionRendererParser,
|
|
|
|
|
Parsers::ContinuationItemRendererParser,
|
|
|
|
|
Parsers::HashtagHeaderRenderer,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private alias InitialData = Hash(String, JSON::Any)
|
|
|
|
@ -550,6 +551,39 @@ private module Parsers
|
|
|
|
|
return {{@type.name}}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# Parses an InnerTube hashtagHeaderRender into a HashtagHeaderRender.
|
|
|
|
|
# Returns nil when the given object isn't a hashtagHeaderRender.
|
|
|
|
|
#
|
|
|
|
|
# hashtagHeaderRender contains metadate of the hashtag page such as video count and channel count
|
|
|
|
|
#
|
|
|
|
|
module HashtagHeaderRenderer
|
|
|
|
|
def self.process(item : JSON::Any, author_fallback : AuthorFallback)
|
|
|
|
|
if item_contents = item["hashtagHeaderRenderer"]?
|
|
|
|
|
return self.parse(item_contents)
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
private def self.parse(item_contents)
|
|
|
|
|
info = extract_text(item_contents.dig?("hashtagInfoText")) || ""
|
|
|
|
|
|
|
|
|
|
regex_match = /(?<videos>\d+\S)\D+(?<channels>\d+\S)/.match(info)
|
|
|
|
|
|
|
|
|
|
hashtag = extract_text(item_contents.dig?("hashtag")) || ""
|
|
|
|
|
videos = short_text_to_number(regex_match.try &.["videos"]?.try &.to_s || "0")
|
|
|
|
|
channels = short_text_to_number(regex_match.try &.["channels"]?.try &.to_s || "0")
|
|
|
|
|
|
|
|
|
|
return HashtagHeader.new({
|
|
|
|
|
tag: hashtag,
|
|
|
|
|
channel_count: channels,
|
|
|
|
|
video_count: videos,
|
|
|
|
|
})
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
def self.parser_name
|
|
|
|
|
return {{@type.name}}
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
# The following are the extractors for extracting an array of items from
|
|
|
|
|