From df67eb6c2608c5b2f909ed7c42b0a4bd3823f78f Mon Sep 17 00:00:00 2001 From: Austin-Olacsi <138650713+Austin-Olacsi@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:40:47 -0600 Subject: [PATCH] [fix] rewrite vimeo engine --- searx/engines/vimeo.py | 119 ++++++++++++++++++++++++++--------------- 1 file changed, 75 insertions(+), 44 deletions(-) diff --git a/searx/engines/vimeo.py b/searx/engines/vimeo.py index 6d1420679..da6f36571 100644 --- a/searx/engines/vimeo.py +++ b/searx/engines/vimeo.py @@ -1,67 +1,98 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -""" -Wikipedia (Web -""" +"""Vimeo (videos)""" -from urllib.parse import urlencode -from json import loads -from dateutil import parser +import typing as t +from datetime import datetime, timedelta +from urllib.parse import urlencode, urlparse +from searx.result_types import EngineResults +from searx.network import get +from searx.enginelib import EngineCache -from searx.utils import extr - -# about +# Engine metadata about = { "website": 'https://vimeo.com/', "wikidata_id": 'Q156376', "official_api_documentation": 'http://developer.vimeo.com/api', "use_official_api": False, "require_api_key": False, - "results": 'HTML', + "results": 'JSON', } -# engine dependent config -categories = ['videos'] + +# Engine configuration paging = True +categories = ['videos'] +results_per_page = 20 -# search-url -base_url = 'https://vimeo.com/' -search_url = base_url + 'search/page:{pageno}?{query}' +# Search URL +base_url = "https://api.vimeo.com" + +# Cache keys & expiration +JWT_CACHE_KEY = "jwt" +JWT_CACHE_EXPIRATION_SECONDS = 300 + +CACHE: EngineCache -# do search-request -def request(query, params): - params['url'] = search_url.format(pageno=params['pageno'], query=urlencode({'q': query})) - - return params +def setup(engine_settings: dict[str, t.Any]) -> bool: + global CACHE # pylint: disable=global-statement + CACHE = EngineCache(engine_settings["name"]) -# get response from search-request -def response(resp): - results = [] +def fetch_json_web_token(): - data = loads(extr(resp.text, 'var data = ', ';\n')) + if json_web_token := CACHE.get(JWT_CACHE_KEY): + return json_web_token - # parse results - for result in data['filtered']['data']: - result = result[result['type']] - videoid = result['uri'].split('/')[-1] - url = base_url + videoid - title = result['name'] - thumbnail = result['pictures']['sizes'][-1]['link'] - publishedDate = parser.parse(result['created_time']) + jwt_url = "https://vimeo.com/_next/jwt" - # append result - results.append( - { - 'url': url, - 'title': title, - 'content': '', - 'template': 'videos.html', - 'publishedDate': publishedDate, - 'iframe_src': "https://player.vimeo.com/video/" + videoid, - 'thumbnail': thumbnail, - } + jwt_headers = { + 'x-requested-with': "XMLHttpRequest", + } + + resp = get(url=jwt_url, headers=jwt_headers, timeout=5) + json_web_token = resp.json()["token"] + + CACHE.set(key=JWT_CACHE_KEY, value=json_web_token, expire=JWT_CACHE_EXPIRATION_SECONDS) + + return json_web_token + + +def request(query: str, params: "OnlineParams"): + + json_web_token = fetch_json_web_token() + + query_params = { + "filter_type": "clip", + "query": query, + "page": params["pageno"], + "per_page": results_per_page, + } + + params["url"] = f"{base_url}/search?{urlencode(query_params)}" + params["headers"]["content-type"] = "application/json" + params["headers"]["authorization"] = "jwt " + json_web_token + params["headers"]["Accept"] = "application/vnd.vimeo.*+json;version=3.3" + + +def response(resp: "SXNG_Response") -> EngineResults: + results = EngineResults() + search_res = resp.json() + + for item in search_res["data"]: + video_id = urlparse(item["clip"]["link"]).path.strip('/') + + results.add( + results.types.LegacyResult( + template="videos.html", + title=item["clip"]["name"], + url=item["clip"]["link"], + author=item["clip"]["user"]["name"], + thumbnail=item["clip"]["pictures"]["base_link"], + length=timedelta(seconds=item["clip"]["duration"]), + publishedDate=datetime.fromisoformat(item["clip"]["created_time"]), + iframe_src="https://player.vimeo.com/video/" + video_id, + ) ) - # return results return results