mirror of
https://github.com/iv-org/invidious.git
synced 2026-09-26 11:35:27 -05:00
fix: read video statistics across lockup metadata rows
This commit is contained in:
parent
c88230067b
commit
6aeb1476b1
62
spec/invidious/lockup_metadata_rows_spec.cr
Normal file
62
spec/invidious/lockup_metadata_rows_spec.cr
Normal file
@ -0,0 +1,62 @@
|
||||
require "../parsers_helper.cr"
|
||||
|
||||
private def lockup_video_with_metadata(metadata : String)
|
||||
JSON.parse(<<-JSON)
|
||||
{
|
||||
"lockupViewModel": {
|
||||
"contentType": "LOCKUP_CONTENT_TYPE_VIDEO",
|
||||
"contentId": "abcdefghijk",
|
||||
"contentImage": {
|
||||
"thumbnailViewModel": {
|
||||
"image": {"sources": [{"url": "https://i.ytimg.com/vi/abcdefghijk/hqdefault.jpg"}]},
|
||||
"overlays": [{"thumbnailBottomOverlayViewModel": {
|
||||
"badges": [{"thumbnailBadgeViewModel": {"text": "12:34"}}]
|
||||
}}]
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"lockupMetadataViewModel": {
|
||||
"title": {"content": "A collaboration"},
|
||||
"metadata": {"contentMetadataViewModel": #{metadata}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
JSON
|
||||
end
|
||||
|
||||
Spectator.describe "lockup video metadata rows" do
|
||||
sample({
|
||||
"normal first row" => %({"metadataRows":[{"metadataParts":[{"text":{"content":"1.5M views"}},{"text":{"content":"3 days ago"}}]}]}),
|
||||
"collaborators before video statistics" => %({"metadataRows":[{"metadataParts":[{"text":{"content":"Channel A and Channel B"}}]},{"metadataParts":[{"text":{"content":"1.5M views"}},{"text":{"content":"3 days ago"}}]}]}),
|
||||
"collaborator names containing statistic substrings" => %({"metadataRows":[{"metadataParts":[{"text":{"content":"Chicago Reviews"}},{"text":{"content":"Tech reviews"}}]},{"metadataParts":[{"text":{"content":"1.5M views"}},{"text":{"content":"3 days ago"}}]}]}),
|
||||
"views and publication date in separate rows" => %({"metadataRows":[{"metadataParts":[{"text":{"content":"1.5M views"}}]},{"metadataParts":[{"text":{"content":"3 days ago"}}]}]}),
|
||||
"missing and null metadata parts before statistics" => %({"metadataRows":[{},{"metadataParts":null},{"metadataParts":[{"text":{"content":"1.5M views"}},{"text":{"content":"3 days ago"}}]}]}),
|
||||
"icon labels before video statistics" => %({"metadataRows":[{"metadataParts":[{"icon":{},"text":{"content":"99 views"}},{"icon":{},"text":{"content":"9 days ago"}}]},{"metadataParts":[{"text":{"content":"1.5M views"}},{"text":{"content":"3 days ago"}}]}]}),
|
||||
}) do |entry|
|
||||
it "parses the video statistics and preserves other metadata" do
|
||||
before = Time.utc - 3.days
|
||||
video = parse_item(lockup_video_with_metadata(entry[1]), "Channel A", "UCexample").as(SearchVideo)
|
||||
after = Time.utc - 3.days
|
||||
|
||||
expect(video.views).to eq(1_500_000)
|
||||
expect(video.published).to be_between(before, after)
|
||||
expect(video.title).to eq("A collaboration")
|
||||
expect(video.id).to eq("abcdefghijk")
|
||||
expect(video.author).to eq("Channel A")
|
||||
expect(video.ucid).to eq("UCexample")
|
||||
expect(video.length_seconds).to eq(754)
|
||||
end
|
||||
end
|
||||
|
||||
sample({"{}", %({"metadataRows":[]}), %({"metadataRows":null}), %({"metadataRows":[{}, {"metadataParts":null}]})}) do |metadata|
|
||||
it "keeps unknown statistics defaults" do
|
||||
before = Time.utc
|
||||
video = parse_item(lockup_video_with_metadata(metadata)).as(SearchVideo)
|
||||
after = Time.utc
|
||||
|
||||
expect(video.views).to eq(0)
|
||||
expect(video.published).to be_between(before, after)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -661,12 +661,13 @@ 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 put authors before the views and published time.
|
||||
metadata_rows = metadata.dig?("metadata", "contentMetadataViewModel", "metadataRows").try &.as_a?
|
||||
metadata_parts = metadata_rows.try &.compact_map(&.dig?("metadataParts").try &.as_a?).flatten
|
||||
|
||||
view_count_text = metadata_parts.try &.find { |item| item["icon"]?.nil? && item.dig?("text", "content").try &.as_s.includes?("views") }
|
||||
view_count_text = metadata_parts.try &.find { |item| item["icon"]?.nil? && item.dig?("text", "content").try &.as_s.matches?(/\A(?:\d+(?:[.,]\d+)*\s?[kKmMbB]?|No) views\z/) }
|
||||
.try &.dig("text", "content").as_s
|
||||
published = metadata_parts.try &.find { |item| item["icon"]?.nil? && item.dig?("text", "content").try &.as_s.includes?("ago") }
|
||||
published = metadata_parts.try &.find { |item| item["icon"]?.nil? && item.dig?("text", "content").try &.as_s.matches?(/(?:\A|\s)\d+ ?[smhdwy]\w* ago\z/) }
|
||||
.try { |item| decode_date(item.dig("text", "content").as_s) } || Time.local
|
||||
|
||||
view_count = short_text_to_number(view_count_text || "0")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user