feat: search pagination
adds support for getting past the first page of search results
This commit is contained in:
@@ -357,14 +357,19 @@ def browseChannel(ucid: str, params: str = None, ctoken: str = None):
|
||||
|
||||
return response_json
|
||||
|
||||
def WEBextractSearchResults(search_query: str) -> list:
|
||||
def WEBextractSearchResults(search_query: str, page: int) -> 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})
|
||||
additional_context = {"query": search_query}
|
||||
if page is not None:
|
||||
params = ythdd_proto.produceSearchParams(page)
|
||||
additional_context["params"] = params
|
||||
|
||||
web_context = makeWebContext(additional_context)
|
||||
response = requests.post('https://www.youtube.com/youtubei/v1/search',
|
||||
params={"prettyPrint": False},
|
||||
headers=stage2_headers,
|
||||
|
||||
@@ -23,7 +23,7 @@ import ythdd_struct_parser
|
||||
# [✓] /api/v1/stats (stats())
|
||||
# [✓] /streams/dQw4w9WgXcQ (does nothing)
|
||||
# [✓] /vi/:videoIdXXXX/maxresdefault.jpg
|
||||
# [✓] /api/v1/search?q=... (videos and playlists)
|
||||
# [✓] /api/v1/search?q=... (videos and playlists), pagination
|
||||
# [✓] /api/v1/search/suggestions?q=...&pq=...
|
||||
# [✓] /api/v1/channel/:ucid
|
||||
# [✓] /api/v1/channel/:ucid/videos, shorts, playlists, streams
|
||||
@@ -38,6 +38,7 @@ import ythdd_struct_parser
|
||||
# [X] /api/v1/videos/:videoIdXXXX does not depend on yt-dlp and offloads stream retrieval elsewhere (making initial response fast)
|
||||
# [X] /api/v1/manifest/:videoIdXXXX (above is prerequisite)
|
||||
# [X] rewrite the awful lookup logic
|
||||
# [X] /api/v1/search?q=... complex filtering options (https://gitea.invidious.io/iv-org/invidious/src/branch/master/src/invidious/search/filters.cr)
|
||||
# ----------
|
||||
# IDEAS:
|
||||
# [*] /api/v1/popular returns last requested videos by the IP (serving as multi-device history?)
|
||||
@@ -579,14 +580,19 @@ def search(data, req):
|
||||
# ignore paginated requests as we do nothing with the continuation token
|
||||
page = req.args.get('page')
|
||||
if page is not None and page != '1':
|
||||
return send(404, [])
|
||||
try:
|
||||
page = int(page)
|
||||
except:
|
||||
return send(400, {"error": "Wrong page."})
|
||||
else:
|
||||
page = None # when page is "1"
|
||||
|
||||
if (data[-2].lower() != "search" or data[-1].lower() != "") and data[-1].lower() != "search":
|
||||
previous_query = req.args.get('pq')
|
||||
suggestions = ythdd_extractor.WEBgetSearchSuggestions(search_query, previous_query)
|
||||
return send(200, suggestions)
|
||||
|
||||
results = ythdd_extractor.WEBextractSearchResults(search_query)
|
||||
results = ythdd_extractor.WEBextractSearchResults(search_query, page)
|
||||
results_list = []
|
||||
|
||||
for entry in results:
|
||||
|
||||
@@ -83,3 +83,14 @@ def producePlaylistContinuation(plid: str, offset: int = 0) -> str:
|
||||
b64_ctoken = bbpbToB64(bbpb_dicts, urlsafe=True, padding=True)
|
||||
|
||||
return b64_ctoken
|
||||
|
||||
def produceSearchParams(page: int = 1) -> str:
|
||||
msge = {
|
||||
"9:int": 20 * (page - 1), # pagination
|
||||
"30:int": 1 # no self-harm censorship
|
||||
}
|
||||
|
||||
bbpb_dicts = fdictToBbpb(msge)
|
||||
b64_params = bbpbToB64(bbpb_dicts, urlsafe=True, padding=True)
|
||||
|
||||
return b64_params
|
||||
Reference in New Issue
Block a user