diff --git a/ythdd_extractor.py b/ythdd_extractor.py index ba0ed63..db35dc4 100644 --- a/ythdd_extractor.py +++ b/ythdd_extractor.py @@ -348,29 +348,59 @@ def WEBgetSearchSuggestions(query: str, previous_query: str = '') -> list: # Takes in a search query and returns relevant suggestions. # Can optionally take the previous query but that's rather novel and # not supported across players nor invidious API itself. - params = { - 'ds': 'yt', - 'hl': 'en', # host language - 'gl': 'us', # geolocation - 'client': 'youtube', - 'gs_ri': 'youtube', - 'q': str(query), # query - 'pq': str(previous_query) if previous_query is not None else '' # previous query - } - - response = requests.get( - 'https://suggestqueries-clients6.youtube.com/complete/search', - params=params, - headers=stage2_headers - ) - # can break anytime but hopefully the tiny speed gain will make up for it - results = response.text[23 + len(query):] - results = results[:results.rfind("{") - 1] - results = json.loads(results) - + suggestions = [] - for result in results: - suggestions.append(result[0]) + + if not isinstance(query, str): + print("WEBgetSearchSuggestions: query is not a string (as it should)") + return {} + if not isinstance(previous_query, str): + previous_query = '' + + if ythdd_globals.config["general"]["cache"]: + # look for cached suggestions + for cached_search in ythdd_globals.general_cache["search"]: + if cached_search["q"] == query.lower() and cached_search["pq"] == previous_query.lower(): + # found it? skip ahead + suggestions = cached_search["resp"] + break + + # request wasn't cached? query the API + if suggestions == []: + + params = { + 'ds': 'yt', + 'hl': 'en', # host language + 'gl': 'us', # geolocation + 'client': 'youtube', + 'gs_ri': 'youtube', + 'q': query, # query + 'pq': previous_query # previous query + } + + response = requests.get( + 'https://suggestqueries-clients6.youtube.com/complete/search', + params=params, + headers=stage2_headers + ) + + # can break anytime but hopefully the tiny speed gain will make up for it + results = response.text[23 + len(query):] + results = results[:results.rfind("{") - 1] + results = json.loads(results) + + for result in results: + suggestions.append(result[0]) + + # cache response + if ythdd_globals.config["general"]["cache"]: + ythdd_globals.general_cache["search"].append( + { + "q": query.lower(), + "pq": previous_query.lower(), + "resp": suggestions + } + ) return { "query": query, diff --git a/ythdd_globals.py b/ythdd_globals.py index da090f6..efe29d2 100644 --- a/ythdd_globals.py +++ b/ythdd_globals.py @@ -23,6 +23,7 @@ version = "0.0.1" apiVersion = "1" randomly_generated_passcode = 0 video_cache = {} +general_cache = {"search": []} def getConfig(configfile): diff --git a/ythdd_inv_tl.py b/ythdd_inv_tl.py index 0a36b3b..f13b7e9 100644 --- a/ythdd_inv_tl.py +++ b/ythdd_inv_tl.py @@ -633,7 +633,6 @@ def parseViewsFromViewText(viewcounttext: str) -> int: def search(data, req): search_query = req.args.get('q') - print(f"search query: {search_query}") # ignore paginated requests as we do nothing with the continuation token page = req.args.get('page') @@ -641,7 +640,6 @@ def search(data, req): return send(404, []) if (data[-2].lower() != "search" or data[-1].lower() != "") and data[-1].lower() != "search": - print(f"'{data[-2]}', '{data[-1]}'") previous_query = req.args.get('pq') suggestions = ythdd_extractor.WEBgetSearchSuggestions(search_query, previous_query) return send(200, suggestions)