fix: support new lockupViewModel for recommended videos

This commit is contained in:
2025-07-02 23:17:16 +02:00
parent 32c563a45a
commit 3253447c72

View File

@@ -385,38 +385,74 @@ def videos(data):
related_raw = safeTraverse(wdata, ['ec2', 'contents', 'twoColumnWatchNextResults', 'secondaryResults', 'secondaryResults', 'results'], default=[]) # can possibly change in the future related_raw = safeTraverse(wdata, ['ec2', 'contents', 'twoColumnWatchNextResults', 'secondaryResults', 'secondaryResults', 'results'], default=[]) # can possibly change in the future
related = [] related = []
for x in related_raw: for x in related_raw[:-1]:
y = safeTraverse(x, ['compactVideoRenderer']) if safeTraverse(x, ['compactVideoRenderer'], default=[]):
if type(y) != dict: y = safeTraverse(x, ['compactVideoRenderer'])
continue if type(y) != dict:
related_video = {} continue
related_video['videoId'] = safeTraverse(y, ['videoId']) related_video = {}
related_video['title'] = safeTraverse(y, ['title', 'simpleText']) related_video['videoId'] = safeTraverse(y, ['videoId'])
related_video['videoThumbnails'] = genThumbs(related_video['videoId']) #safeTraverse(y, ['thumbnail', 'thumbnails']) related_video['title'] = safeTraverse(y, ['title', 'simpleText'])
related_video['author'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'text']) related_video['videoThumbnails'] = genThumbs(related_video['videoId']) #safeTraverse(y, ['thumbnail', 'thumbnails'])
related_video['authorId'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'navigationEndpoint', 'browseEndpoint', 'browseId'], default="UNKNOWNCHANNELID") related_video['author'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'text'])
related_video['authorUrl'] = '/channel/' + related_video['authorId'] related_video['authorId'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'navigationEndpoint', 'browseEndpoint', 'browseId'], default="UNKNOWNCHANNELID")
related_video['authorVerified'] = False related_video['authorUrl'] = '/channel/' + related_video['authorId']
if "ownerBadges" in y: related_video['authorVerified'] = False
related_video['authorVerified'] = True # hopefully this won't break things, as invidious API doesn't distinguish music and normal verified badges if "ownerBadges" in y:
related_video['authorThumbnails'] = safeTraverse(y, ['channelThumbnail', 'thumbnails'], default=[]) related_video['authorVerified'] = True # hopefully this won't break things, as invidious API doesn't distinguish music and normal verified badges
for z in related_video['authorThumbnails']: related_video['authorThumbnails'] = safeTraverse(y, ['channelThumbnail', 'thumbnails'], default=[])
z['url'] = ythdd_globals.translateLinks(z['url']) for z in related_video['authorThumbnails']:
related_video['lengthSeconds'] = 0 z['url'] = ythdd_globals.translateLinks(z['url'])
time_lookup_list = [1, 60, 3_600, 86_400] related_video['lengthSeconds'] = 0
time_list = safeTraverse(y, ['lengthText', 'simpleText'], default="0:0").split(":") time_lookup_list = [1, 60, 3_600, 86_400]
for z in range(len(time_list)): time_list = safeTraverse(y, ['lengthText', 'simpleText'], default="0:0").split(":")
related_video['lengthSeconds'] += time_lookup_list[z] * int(time_list[len(time_list) - 1 - z]) for z in range(len(time_list)):
related_views_text = safeTraverse(y, ['viewCountText', 'simpleText'], default="0").split(" ")[0] related_video['lengthSeconds'] += time_lookup_list[z] * int(time_list[len(time_list) - 1 - z])
related_video['viewCountText'] = safeTraverse(y, ['shortViewCountText', 'simpleText'], default="0").split(" ")[0] related_views_text = safeTraverse(y, ['viewCountText', 'simpleText'], default="0").split(" ")[0]
related_views = 0 related_video['viewCountText'] = safeTraverse(y, ['shortViewCountText', 'simpleText'], default="0").split(" ")[0]
if related_views_text: related_views = 0
if related_views_text.lower() == "no": if related_views_text:
related_views_text = "0" if related_views_text.lower() == "no":
related_views = int("0" + "".join([z for z in related_views_text if 48 <= ord(z) and ord(z) <= 57])) related_views_text = "0"
related_views_text = related_views_text.split(" ")[0] related_views = int("0" + "".join([z for z in related_views_text if 48 <= ord(z) and ord(z) <= 57]))
related_video['viewCount'] = related_views related_views_text = related_views_text.split(" ")[0]
related.append(related_video) related_video['viewCount'] = related_views
related.append(related_video)
else:
y = safeTraverse(x, ['lockupViewModel'])
if type(y) != dict:
continue
lmvm = safeTraverse(y, ['metadata', 'lockupMetadataViewModel'], default=[])
related_video = {}
related_video['videoId'] = safeTraverse(y, ['contentId'])
related_video['title'] = safeTraverse(lmvm, ['title', 'content'])
related_video['videoThumbnails'] = genThumbs(related_video['videoId']) #safeTraverse(y, ['thumbnail', 'thumbnails'])
related_video['author'] = safeTraverse(lmvm, ['metadata', 'contentMetadataViewModel', 'metadataRows', 0, 'metadataParts', 0, 'text', 'content'])
related_video['authorId'] = safeTraverse(lmvm, ['image', 'decoratedAvatarViewModel', 'rendererContext', 'commandContext', 'onTap', 'innertubeCommand', 'browseEndpoint', 'browseId'], default="UNKNOWNCHANNELID")
related_video['authorUrl'] = '/channel/' + related_video['authorId']
related_video['authorVerified'] = False if safeTraverse(lmvm, ['metadata', 'contentMetadataViewModel', 'metadataRows', 0, 'metadataParts', 0, 'text', 'attachmentRuns']) is None else True # seens to do the job
related_video['authorThumbnails'] = safeTraverse(lmvm, ['image', 'decoratedAvatarViewModel', 'avatar', 'avatarViewModel', 'image', 'sources'], default=[])
for z in related_video['authorThumbnails']:
z['url'] = ythdd_globals.translateLinks(z['url'])
related_video['lengthSeconds'] = 0
time_lookup_list = [1, 60, 3_600, 86_400]
time_list = safeTraverse(y, ['contentImage', 'thumbnailViewModel', 'overlays', 0, 'thumbnailOverlayBadgeViewModel', 'thumbnailBadges', 0, 'thumbnailBadgeViewModel', 'text'], default="0:0").split(":")
for z in range(len(time_list)):
related_video['lengthSeconds'] += time_lookup_list[z] * int(time_list[len(time_list) - 1 - z])
related_views_text = safeTraverse(lmvm, ['metadata', 'contentMetadataViewModel', 'metadataRows', 1, 'metadataParts', 0, 'text', 'content'], default="0").split(" ")[0]
related_video['viewCountText'] = safeTraverse(lmvm, ['metadata', 'contentMetadataViewModel', 'metadataRows', 1, 'metadataParts', 0, 'text', 'content'], default="0").split(" ")[0]
related_views = 0
magnitude = {'K': 1_000, 'M': 1_000_000, 'B': 1_000_000_000}
if related_views_text:
if related_views_text.lower() == "no":
related_views_text = "0"
related_views = int("0" + "".join([z for z in related_views_text if 48 <= ord(z) and ord(z) <= 57]))
related_views_text = related_views_text.split(" ")[0]
for x in magnitude.keys():
if x == related_views_text[-1]:
related_views *= magnitude[x]
related_video['viewCount'] = related_views
related.append(related_video)
# magnitude = {'K': 1_000, 'M': 1_000_000, 'B': 1_000_000_000} # magnitude = {'K': 1_000, 'M': 1_000_000, 'B': 1_000_000_000}
# toplevel_buttons = safeTraverse(video_primary_renderer, ['videoActions', 'menuRenderer', 'topLevelButtons'], default={}) # hacky solution # toplevel_buttons = safeTraverse(video_primary_renderer, ['videoActions', 'menuRenderer', 'topLevelButtons'], default={}) # hacky solution
@@ -549,6 +585,7 @@ def videos(data):
if ythdd_globals.config['general']['debug']: if ythdd_globals.config['general']['debug']:
response["ydata"] = ydata response["ydata"] = ydata
response["wdata"] = wdata
# for debugging: # for debugging:
#return send(200, ythdd_extractor.WEBextractSinglePage(data[3])) #return send(200, ythdd_extractor.WEBextractSinglePage(data[3]))