mirror of
https://github.com/iv-org/invidious.git
synced 2026-09-26 11:35:27 -05:00
fix(parser): handle collab lockup metadata rows
This commit is contained in:
parent
c88230067b
commit
636e64ed3e
99
spec/invidious/yt_backend/lockup_view_model_parser_spec.cr
Normal file
99
spec/invidious/yt_backend/lockup_view_model_parser_spec.cr
Normal file
@ -0,0 +1,99 @@
|
||||
require "../../parsers_helper.cr"
|
||||
|
||||
Spectator.describe "LockupViewModelParser channel videos" do
|
||||
def lockup_video(metadata_rows : Array(JSON::Any)) : JSON::Any
|
||||
JSON.parse({
|
||||
"lockupViewModel" => {
|
||||
"contentType" => "LOCKUP_CONTENT_TYPE_VIDEO",
|
||||
"contentId" => "video123",
|
||||
"contentImage" => {
|
||||
"thumbnailViewModel" => {
|
||||
"image" => {
|
||||
"sources" => [{"url" => "https://example.invalid/thumb.jpg"}],
|
||||
},
|
||||
"overlays" => [{
|
||||
"thumbnailBottomOverlayViewModel" => {
|
||||
"badges" => [{
|
||||
"thumbnailBadgeViewModel" => {"text" => "12:34"},
|
||||
}],
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
"metadata" => {
|
||||
"lockupMetadataViewModel" => {
|
||||
"title" => {"content" => "Collaboration video"},
|
||||
"metadata" => {
|
||||
"contentMetadataViewModel" => {
|
||||
"metadataRows" => metadata_rows.map(&.raw),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}.to_json)
|
||||
end
|
||||
|
||||
it "parses a normal first-row metadata layout" do
|
||||
rows = [
|
||||
JSON.parse({
|
||||
"metadataParts" => [
|
||||
{"text" => {"content" => "1.5M views"}},
|
||||
{"text" => {"content" => "3 days ago"}},
|
||||
],
|
||||
}.to_json),
|
||||
]
|
||||
|
||||
result = parse_item(lockup_video(rows), "Example", "UC123")
|
||||
expect(result).to be_a(SearchVideo)
|
||||
|
||||
video = result.as(SearchVideo)
|
||||
expect(video.views).to eq(1_500_000)
|
||||
expect(video.published).to be_close(Time.utc - 3.days, 2.seconds)
|
||||
expect(video.length_seconds).to eq(754)
|
||||
end
|
||||
|
||||
it "parses metadata after a collaboration author row" do
|
||||
rows = [
|
||||
JSON.parse({
|
||||
"metadataParts" => [
|
||||
{"text" => {"content" => "Example and Collaborator"}},
|
||||
],
|
||||
}.to_json),
|
||||
JSON.parse({
|
||||
"metadataParts" => [
|
||||
{"text" => {"content" => "1.5M views"}},
|
||||
{"text" => {"content" => "3 days ago"}},
|
||||
],
|
||||
}.to_json),
|
||||
]
|
||||
|
||||
result = parse_item(lockup_video(rows), "Example", "UC123")
|
||||
expect(result).to be_a(SearchVideo)
|
||||
|
||||
video = result.as(SearchVideo)
|
||||
expect(video.views).to eq(1_500_000)
|
||||
expect(video.published).to be_close(Time.utc - 3.days, 2.seconds)
|
||||
expect(video.author).to eq("Example")
|
||||
expect(video.ucid).to eq("UC123")
|
||||
end
|
||||
|
||||
it "skips metadata rows that do not contain metadataParts" do
|
||||
rows = [
|
||||
JSON.parse("{}"),
|
||||
JSON.parse({
|
||||
"metadataParts" => [
|
||||
{"text" => {"content" => "1.5M views"}},
|
||||
{"text" => {"content" => "3 days ago"}},
|
||||
],
|
||||
}.to_json),
|
||||
]
|
||||
|
||||
result = parse_item(lockup_video(rows), "Example", "UC123")
|
||||
expect(result).to be_a(SearchVideo)
|
||||
|
||||
video = result.as(SearchVideo)
|
||||
expect(video.views).to eq(1_500_000)
|
||||
expect(video.published).to be_close(Time.utc - 3.days, 2.seconds)
|
||||
end
|
||||
end
|
||||
@ -662,7 +662,12 @@ private module Parsers
|
||||
metadata = item_contents.dig("metadata", "lockupMetadataViewModel")
|
||||
title = metadata.dig("title", "content").as_s
|
||||
# Contains the views of the video and the published time of the video.
|
||||
metadata_parts = metadata.dig("metadata", "contentMetadataViewModel", "metadataRows", 0, "metadataParts").try &.as_a
|
||||
# Collaboration videos can prepend author rows before the actual video metadata,
|
||||
# so collect metadata parts from every row and skip rows without metadataParts.
|
||||
metadata_rows = metadata.dig?("metadata", "contentMetadataViewModel", "metadataRows").try &.as_a
|
||||
metadata_parts = metadata_rows.try &.compact_map { |row|
|
||||
row["metadataParts"]?.try &.as_a
|
||||
}.try &.flatten
|
||||
|
||||
view_count_text = metadata_parts.try &.find { |item| item["icon"]?.nil? && item.dig?("text", "content").try &.as_s.includes?("views") }
|
||||
.try &.dig("text", "content").as_s
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user