introduce related videos, small fixes to invidious translation layer

This commit is contained in:
2024-12-28 04:53:37 +01:00
parent 3a524d96a0
commit dd102cb6ae

View File

@@ -5,7 +5,7 @@
# to use internal extractors.
from flask import Response, request, redirect
from markupsafe import escape
from time import strftime, localtime, time
from time import strftime, gmtime, time
import json, datetime
import invidious_formats
import ythdd_globals
@@ -47,9 +47,9 @@ def stats():
return send(200, data_to_send)
def videoIdSanityCheck(videoId: str):
if len(videId) != 11:
if len(videoId) != 11:
incrementBadRequests()
return send(400, f'error: bad request. wrong videoId: {videoId} is {len(videoId)} characters long, but should be 11.', [])
return send(400, f'error: bad request. wrong videoId: {videoId} is {len(videoId)} characters long, but should be 11.')
# elif...?
def auth(data):
@@ -67,8 +67,7 @@ def streams():
return send(200, '')
def epochToDate(epoch):
# TODO: replace with UTC time
return strftime('%Y-%m-%d %H:%M:%S', localtime(epoch))
return strftime('%Y-%m-%dT%H:%M:%SZ', gmtime(epoch))
def trending():
return send(200, [{}])
@@ -106,6 +105,7 @@ def genThumbs(videoId: str):
height = x['height']
quality = x['quality']
url = ythdd_globals.config['general']['public_facing_url'] + 'vi/' + videoId + '/' + x['url'] + '.jpg'
#url = '/vi/' + videoId + '/' + x['url'] + '.jpg'
result.append({'quality': quality, 'url': url, 'width': width, 'height': height})
return result
@@ -157,8 +157,8 @@ def rebuildFormats(data):
except:
pass
if data[x]['itag'] <= 80: # temporary solution, I promise!
formatStreams.append(result[x])
#if data[x]['itag'] <= 80: # won't be triggered for iOS player as it has no progressive streams
# formatStreams.append(result[x])
return result, formatStreams
@@ -202,7 +202,36 @@ def videos(data):
keywords = safeTraverse(video_details, ['keywords'], default=[])
# TODO: https://github.com/iv-org/invidious/blob/master/src/invidious/videos/parser.cr#L258
related = 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 = []
for x in related_raw:
y = safeTraverse(x, ['compactVideoRenderer'])
if type(y) != dict:
continue
related_video = {}
related_video['videoId'] = safeTraverse(y, ['videoId'])
related_video['title'] = safeTraverse(y, ['title', 'simpleText'])
related_video['videoThumbnails'] = genThumbs(related_video['videoId']) #safeTraverse(y, ['thumbnail', 'thumbnails'])
related_video['author'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'text'])
related_video['authorId'] = safeTraverse(y, ['longBylineText', 'runs', 0, 'navigationEndpoint', 'browseEndpoint', 'browseId'], default="UNKNOWNCHANNELID")
related_video['authorUrl'] = '/channel/' + related_video['authorId']
related_video['authorVerified'] = False
related_video['authorThumbnails'] = safeTraverse(y, ['channelThumbnail', 'thumbnails'], 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, ['lengthText', 'simpleText'], 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(y, ['viewCountText', 'simpleText'], default="0").split(" ")[0]
related_video['viewCountText'] = related_views_text
related_views = 0
if related_views_text:
related_views = int("".join([z for z in related_views_text if 48 <= ord(z) and ord(z) <= 57]))
related_views_text = related_views_text.split(" ")[0]
related_video['viewCount'] = related_views
related.append(related_video)
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
@@ -318,7 +347,7 @@ def videos(data):
# "license": String
# }
# ],
'recommendedVideos': [] # not yet implemented
"recommendedVideos": related
# "recommendedVideos": [
# {
# "videoId": String,
@@ -353,6 +382,7 @@ def videos(data):
# for debugging:
#return send(200, ythdd_extractor.WEBextractSinglePage(data[3]))
#return send(200, ythdd_extractor.IOSextract(data[3]))
#return send(200, {'idata': idata, 'wdata': wdata})
# if youtube returns not the videoId we aksed
# then it means that the instance is ratelimited