feat: basic support for search queries

currently returns videos and playlists - the latter don't yet have
an API endpoint
This commit is contained in:
2025-09-05 06:23:45 +02:00
parent 89f8f2a786
commit a814797363
3 changed files with 188 additions and 24 deletions

View File

@@ -229,6 +229,7 @@ def IOSextract(uri: str):
def makeWebContext(secondaryContextDict: dict):
# Uses web_context_dict to create a context, returns a dict.
# Essentially, expands the web_context_dict with a secondary one.
current_web_context_dict = web_context_dict
@@ -264,10 +265,37 @@ def getChannelAvatar(response_json: dict):
if avatar['width'] * avatar['height'] > best_avatar['width'] * best_avatar['height']:
best_avatar = avatar
# or use regex substitution and set the size to something like 512x512
# e.g.: =s128 -> =s512
best_avatar['url'] = ythdd_globals.translateLinks(best_avatar['url'])
return best_avatar
def generateChannelAvatarsFromUrl(url: str, proxied: bool = True) -> list:
# Generates channel avatars at default sizes.
avatars = []
if not url.startswith("https://yt3.ggpht.com/"):
return []
url = ythdd_globals.translateLinks(url)
url_size_start = url.rfind("=s") + 2
url_size_end = url. find("-", url_size_start) - 1
default_sizes = [32, 48, 76, 100, 176, 512]
for size in default_sizes:
avatars.append(
{
"url": url[:url_size_start] + str(size) + url[url_size_end:],
"width": size,
"height": size
}
)
return avatars
def isVerified(response_json: dict):
# Returns True if any user badge has been found (verified/artist).
badges = safeTraverse(response_json, [], default=False)
@@ -291,4 +319,27 @@ def browseAbout(ucid: str):
response_json = json.loads(response.text)
return response_json
return response_json
def WEBextractSearchResults(search_query: str) -> list:
# Posts a search request to innertube API
# and processes only the relevant part (the actual results)
if search_query is None:
return []
web_context = makeWebContext({"query": search_query})
response = requests.post('https://www.youtube.com/youtubei/v1/search',
params={"prettyPrint": False},
headers=stage2_headers,
data=json.dumps(web_context)
)
results = []
try:
results = json.loads(response.text)
except:
pass
results = safeTraverse(results, ["contents", "twoColumnSearchResultsRenderer", "primaryContents", "sectionListRenderer", "contents", 0, "itemSectionRenderer", "contents"], default=[])
return results