diff --git a/docs/dev/engines/online/odysee.rst b/docs/dev/engines/online/odysee.rst new file mode 100644 index 000000000..75be1ad11 --- /dev/null +++ b/docs/dev/engines/online/odysee.rst @@ -0,0 +1,13 @@ +.. _odysee engine: + +====== +Odysee +====== + +.. contents:: Contents + :depth: 2 + :local: + :backlinks: entry + +.. automodule:: searx.engines.odysee + :members: diff --git a/searx/engines/odysee.py b/searx/engines/odysee.py new file mode 100644 index 000000000..3450c30da --- /dev/null +++ b/searx/engines/odysee.py @@ -0,0 +1,92 @@ +# SPDX-License-Identifier: AGPL-3.0-or-later +# lint: pylint +"""Odysee_ is a decentralised video hosting platform. + +.. _Odysee: https://github.com/OdyseeTeam/odysee-frontend +""" + +import time +from datetime import datetime + +# Engine metadata +about = { + "website": "https://odysee.com/", + "wikidata_id": "Q102046570", + "official_api_documentation": None, + "use_official_api": False, + "require_api_key": False, + "results": "JSON", +} + +# Engine configuration +paging = True +results_per_page = 20 +categories = ['images'] + +# Search URL (Note: lighthouse.lbry.com/search works too, and may be faster at times) +base_url = "https://lighthouse.odysee.tv/search" + +# Request function +def request(query, params): + page = params.get("pageno", 1) - 1 + start_index = page * results_per_page + + query_params = { + "s": query, + "size": results_per_page, + "from": start_index, + "include": "channel,thumbnail_url,title,description,duration,release_time", + "mediaType": "video", + } + + query_str = "&".join([f"{key}={value}" for key, value in query_params.items()]) + params["url"] = f"{base_url}?{query_str}" + return params + + +# Format the video duration +def format_duration(duration): + seconds = int(duration) + length = time.gmtime(seconds) + if length.tm_hour: + return time.strftime("%H:%M:%S", length) + return time.strftime("%M:%S", length) + + +def response(resp): + data = resp.json() + results = [] + + for item in data: + name = item["name"] + claim_id = item["claimId"] + title = item["title"] + thumbnail_url = item["thumbnail_url"] + description = item["description"] or "" + channel = item["channel"] + release_time = item["release_time"] + duration = item["duration"] + + release_date = datetime.strptime(release_time.split("T")[0], "%Y-%m-%d") + formatted_date = datetime.utcfromtimestamp(release_date.timestamp()) + + url = f"https://odysee.com/{name}:{claim_id}" + iframe_url = f"https://odysee.com/$/embed/{name}:{claim_id}" + odysee_thumbnail = f"https://thumbnails.odycdn.com/optimize/s:390:0/quality:85/plain/{thumbnail_url}" + formatted_duration = format_duration(duration) + + results.append( + { + "title": title, + "url": url, + "content": description, + "author": channel, + "publishedDate": formatted_date, + "length": formatted_duration, + "thumbnail": odysee_thumbnail, + "iframe_src": iframe_url, + "template": "videos.html", + } + ) + + return results diff --git a/searx/settings.yml b/searx/settings.yml index 85434370d..b70a44b96 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -1057,6 +1057,11 @@ engines: require_api_key: false results: JSON + - name: odysee + engine: odysee + shortcut: od + disabled: true + - name: openairedatasets engine: json_engine paging: true