From d38fdc6997250a2b7b3489b67cd4a4e7c1c78711 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Wed, 28 Feb 2024 11:39:21 +0100 Subject: [PATCH] [Servers] experimental peertube support - the user can add instances in the settings menu - subscribe to channels - bookmark videos & playlists - homefeed Additional features provided by peertube instances: - hide nsfw content in search results - enable federated search results --- melon/servers/__init__.py | 6 +- melon/servers/invidious/__init__.py | 7 +- melon/servers/nebula/__init__.py | 6 +- melon/servers/peertube/__init__.py | 376 ++++++++++++++++++++++++++++ melon/servers/peertube/peertube.png | Bin 0 -> 86639 bytes 5 files changed, 386 insertions(+), 9 deletions(-) create mode 100644 melon/servers/peertube/__init__.py create mode 100644 melon/servers/peertube/peertube.png diff --git a/melon/servers/__init__.py b/melon/servers/__init__.py index 94bb56f..1b9f42e 100644 --- a/melon/servers/__init__.py +++ b/melon/servers/__init__.py @@ -175,7 +175,7 @@ class Server(ABC): """Returns a list of videos in the given feed""" return [] @abstractmethod - def search(self, query:str, mask: SearchMode, page=1) -> list[Resource]: + def search(self, query:str, mask: SearchMode, page=0) -> list[Resource]: """ Search for a given query filter for things according to mask @@ -203,7 +203,7 @@ class Server(ABC): """ pass @abstractmethod - def get_channel_feed_content(self, cid: str, feed_id: str, page=1) -> list[Resource]: + def get_channel_feed_content(self, cid: str, feed_id: str, page=0) -> list[Resource]: """ Returns list of resources in the channel feed """ @@ -216,7 +216,7 @@ class Server(ABC): """ pass @abstractmethod - def get_playlist_content(self, pid: str, page=1) -> list[Resource]: + def get_playlist_content(self, pid: str, page=0) -> list[Resource]: """ Returns a list of resources in the playlist """ diff --git a/melon/servers/invidious/__init__.py b/melon/servers/invidious/__init__.py index 9c06d0b..ac6b0c8 100644 --- a/melon/servers/invidious/__init__.py +++ b/melon/servers/invidious/__init__.py @@ -77,7 +77,7 @@ class Invidious(Server): instance = self.get_external_url() return self.request_and_parse(f"{instance}/feed/{id}") - def search(self, query, mask, page=1): + def search(self, query, mask, page=0): instance = self.get_external_url() # default to any t = "none" @@ -128,7 +128,7 @@ class Invidious(Server): def get_default_channel_feed(self, cid:str): return "" - def get_channel_feed_content(self, cid: str, feed_id: str, page=1): + def get_channel_feed_content(self, cid: str, feed_id: str, page=0): instance = self.get_external_url() return self.request_and_parse(f"{instance}/channel/{cid}/{feed_id}") @@ -148,7 +148,7 @@ class Invidious(Server): # on the playlist screen return Playlist(self.id, url, pid, title, channel, None) - def get_playlist_content(self, pid: str, page=1): + def get_playlist_content(self, pid: str, page=0): instance = self.get_external_url() return self.request_and_parse(f"{instance}/playlist?list={pid}") @@ -297,6 +297,7 @@ class Invidious(Server): for src in video.find_all("source"): try: rel = src["src"] + print(rel) stream_url = f"{instance}{rel}" results.append(Stream(stream_url, src["label"])) except: diff --git a/melon/servers/nebula/__init__.py b/melon/servers/nebula/__init__.py index f5c66ac..9c1af68 100644 --- a/melon/servers/nebula/__init__.py +++ b/melon/servers/nebula/__init__.py @@ -139,7 +139,7 @@ class Nebula(Server): return results return [] - def search(self, query, mask, page=1): + def search(self, query, mask, page=0): # nebula doesn't provide playlist search # which means that this feed will always be empty if mask == SearchMode.PLAYLISTS: @@ -200,7 +200,7 @@ class Nebula(Server): def get_default_channel_feed(self, cid:str): return "videos" - def get_channel_feed_content(self, channel_id: str, feed_id: str, page=1): + def get_channel_feed_content(self, channel_id: str, feed_id: str, page=0): if feed_id == "videos": results = [] # TODO: add pagination @@ -244,7 +244,7 @@ class Nebula(Server): # nebula doesn't support playlist thumbnails None) - def get_playlist_content(self, playlist_id: str, page=1): + def get_playlist_content(self, playlist_id: str, page=0): # TODO: add pagination # apparently this call doesn't support page numbers # and instead we have to use the provided data["next"] cursor diff --git a/melon/servers/peertube/__init__.py b/melon/servers/peertube/__init__.py new file mode 100644 index 0000000..1f5d792 --- /dev/null +++ b/melon/servers/peertube/__init__.py @@ -0,0 +1,376 @@ +from melon.servers import Server, Preference, PreferenceType +from melon.servers import Feed, Channel, Video, Playlist, Stream, SearchMode +from melon.servers import USER_AGENT +import requests +from urllib.parse import urlparse,parse_qs +from datetime import datetime +from melon.import_providers.newpipe import NewpipeImporter + +class Peertube(Server): + + id = "peertube" + name = "Peertube" + description = "Decentralized video hosting network, based on free/libre software" + + settings = { + "instances": Preference( + "instances", + "Instances", + "List of peertube instances, from which to fetch content. See https://joinpeertube.org/instances", + PreferenceType.MULTI, + ["https://tilvids.com/"], + ["https://tilvids.com/"]), + "nsfw": Preference( + "nsfw", + "Show NSFW content", + "Passes the nsfw filter to the peertube search API", + PreferenceType.TOGGLE, + False, False), + "federate": Preference( + "federate", + "Enable Federation", + "Returns content from federated instances instead of only local content", + PreferenceType.TOGGLE, + True, True) + } + + # peertube instances may contain 18+ content + # so we have to indicate that this may contain nsfw content + is_nsfw = True, + + def get_external_url(self): + # because this plugin supports multiple instances, + # we can't really get one external url + # so we redirect to the peertube info page instead + return "https://joinpeertube.org/" + + def get_instance_list(self): + return [ inst.strip("/") for inst in self.settings["instances"].value ] + + def get_public_feeds(self): + # because this plugin supports multiple instances + # we cannot set n external URL + # nor is it possible to show trending videos, + # because they cannot be merged + return [ + Feed("latest", "Latest", "dialog-information-symbolic") + ] + + def get_query_config(self) -> str: + local = not self.settings["federate"].value + nsfw = self.settings["nsfw"].value + if local: + local = "true" + else: + local = "false" + if nsfw: + nsfw = "true" + else: + nsfw = "false" + return f"isLocal={local}&nsfw={nsfw}" + + def get_public_feed_content(self,id): + if id != "latest": + return [] + conf = self.get_query_config() + videos:(Video,int) = [] + for instance in self.get_instance_list(): + url = f"{instance}/feeds/videos.json?sort=-publishedAt&{conf}" + r = requests.get(url) + if r.ok: + items = r.json()["items"] + for item in items: + url = item["url"] + vid = item["id"].split("/")[-1] + id = f"{instance}::{vid}" + title = item["title"] + desc = "" + if "summary" in item: + desc = item["summary"] + # don't know how to get the thumbnail + thumb = None + channel_name = item["author"]["name"] + channel_id = item["author"]["url"].split("/")[-1] + channel = (channel_name, channel_id) + v = Video(self.id, url, id, title, channel, desc, thumb) + date_str = item["date_modified"] + uts = datetime.fromisoformat(date_str).timestamp() + videos.append((v, uts)) + + videos.sort(key=lambda x:x[1]) + return [ v[0] for v in videos ] + + def search(self, query, mask, page=1): + vid_conf = self.get_query_config() + results = [] + for instance in self.get_instance_list(): + search_base = f"{instance}/api/v1/search" + if mask == SearchMode.CHANNELS or mask == SearchMode.ANY: + # channel search + url = f"{search_base}/video-channels?search={query}" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + item_id = item["name"] + item_host = item["host"] + channel_id = f"https://{item_host}::{item_id}" + avatar = None + if "avatar" in item and not item["avatar"] is None: + path=item["avatar"]["path"] + avatar=f"{instance}{path}" + c = Channel( + self.id, + item["url"], + channel_id, + item["displayName"], + item["description"] or "", + avatar) + results.append(c) + if mask == SearchMode.PLAYLISTS or mask == SearchMode.ANY: + # playlist search + url = f"{search_base}/video-playlists?search={query}" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + item_uuid = item["uuid"] + item_id = f"{instance}::{item_uuid}" + channel_slug = item["videoChannel"]["name"] + channel_host = item["videoChannel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + channel_name = item["videoChannel"]["displayName"] + thumb_path = item["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + p = Playlist( + self.id, + item["url"], + item_id, + item["displayName"], + (channel_name, channel_id), + thumb) + results.append(p) + if mask == SearchMode.VIDEOS or mask == SearchMode.ANY: + # video search + url = f"{search_base}/videos?search={query}&{vid_conf}" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + video_host = instance + video_slug = item["uuid"] + video_id=f"{video_host}::{video_slug}" + thumb_path = item["thumbnailPath"] + thumb = f"{instance}/{thumb_path}" + channel_name = item["channel"]["displayName"] + channel_slug = item["channel"]["name"] + channel_host = item["channel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + v = Video( + self.id, + item["url"], + video_id, + item["name"], + (channel_name, channel_id), + item["description"] or "", + thumb) + results.append(v) + return results + + def get_channel_info(self, cid: str): + instance, channel_id = cid.split("::") + url = f"{instance}/api/v1/video-channels/{channel_id}" + r = requests.get(url) + if r.ok: + data = r.json() + channel_slug = data["name"] + channel_host = data["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + avatar = None + if "avatar" in data and not data["avatar"] is None: + avatar_path = data["avatar"]["path"] + avatar = f"{instance}{avatar_path}" + return Channel( + self.id, + data["url"], + channel_id, + data["displayName"], + data["description"], + avatar) + + def get_channel_feeds(self, cid:str) : + res = self.get_channel_feed_content(cid, "playlists") + if len(res) != 0: + return [ + Feed("videos", "Videos"), + Feed("playlists", "Playlists") + ] + return [ + Feed("videos", "Videos") + ] + + def get_default_channel_feed(self, cid:str): + return "videos" + + def get_channel_feed_content(self, cid: str, feed_id: str, page=1): + instance, channel_id = cid.split("::") + results = [] + if feed_id == "videos": + url = f"{instance}/api/v1/video-channels/{channel_id}/videos" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + video_host = instance + video_slug = item["uuid"] + video_id=f"{video_host}::{video_slug}" + thumb_path = item["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + channel_name = item["channel"]["displayName"] + channel_slug = item["channel"]["name"] + channel_host = item["channel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + v = Video( + self.id, + item["url"], + video_id, + item["name"], + (channel_name, channel_id), + item["description"], + thumb) + results.append(v) + elif feed_id == "playlists": + url = f"{instance}/api/v1/video-channels/{channel_id}/video-playlists" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + item_uuid = item["uuid"] + item_id = f"{instance}::{item_uuid}" + channel_slug = item["videoChannel"]["name"] + channel_id = f"{instance}::{channel_slug}" + channel_name = item["videoChannel"]["displayName"] + thumb_path = item["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + p = Playlist( + self.id, + item["url"], + item_id, + item["displayName"], + (channel_name, channel_id), + thumb) + results.append(p) + + return results + + + def get_playlist_info(self, pid: str): + instance, playlist_id = pid.split("::") + url = f"{instance}/api/v1/video-playlists/{playlist_id}" + r = requests.get(url) + if r.ok: + data = r.json() + item_uuid = data["uuid"] + item_id = f"{instance}::{item_uuid}" + channel_name = data["videoChannel"]["displayName"] + channel_slug = data["videoChannel"]["name"] + channel_host = data["videoChannel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + thumb_path = data["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + return Playlist( + self.id, + data["url"], + item_id, + data["displayName"], + (channel_name, channel_id), + thumb) + + def get_playlist_content(self, pid: str, page=0): + instance, playlist_id = pid.split("::") + size = 15 + url = f"{instance}/api/v1/video-playlists/{playlist_id}/videos?start={page*size}&count={size}" + r = requests.get(url) + results = [] + if r.ok: + for item in r.json()["data"]: + item = item["video"] + video_host = instance + video_slug = item["uuid"] + video_id=f"{video_host}::{video_slug}" + thumb_path = item["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + channel_name = item["channel"]["displayName"] + channel_slug = item["channel"]["name"] + channel_host = item["channel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + v = Video( + self.id, + item["url"], + video_id, + item["name"], + (channel_name, channel_id), + item["description"], + thumb) + results.append(v) + return results + + def get_timeline(self, cid: str): + instance, channel_id = cid.split("::") + results = [] + url = f"{instance}/api/v1/video-channels/{channel_id}/videos" + r = requests.get(url) + if r.ok: + for item in r.json()["data"]: + video_host = instance + video_slug = item["uuid"] + video_id=f"{video_host}::{video_slug}" + thumb_path = item["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + channel_name = item["channel"]["displayName"] + channel_slug = item["channel"]["name"] + channel_host = item["channel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + v = Video( + self.id, + item["url"], + video_id, + item["name"], + (channel_name, channel_id), + item["description"], + thumb) + uts = datetime.fromisoformat(item["updatedAt"]).timestamp() + results.append((v, uts)) + return results + + def get_video_info(self, vid: str): + instance, video_id = vid.split("::") + url = f"{instance}/api/v1/videos/{video_id}" + r = requests.get(url) + if r.ok: + data = r.json() + video_host = instance + video_slug = data["uuid"] + video_id=f"{video_host}::{video_slug}" + channel_name = data["channel"]["displayName"] + channel_slug = data["channel"]["name"] + channel_host = data["channel"]["host"] + channel_id = f"https://{channel_host}::{channel_slug}" + thumb_path = data["thumbnailPath"] + thumb = f"{instance}{thumb_path}" + return Video( + self.id, + data["url"], + video_id, + data["name"], + (channel_name, channel_id), + data["description"], + thumb) + + def get_video_streams(self, vid:str): + instance, video_id = vid.split("::") + return [ + # the embed player does the quality selection + Stream(f"{instance}/videos/embed/{video_id}", "auto") + ] + + def get_import_providers(self): + return [ + # TODO: port newpipe invidious importer to peertube + # REQUIRES: figuring out what service_id peertube uses + ] diff --git a/melon/servers/peertube/peertube.png b/melon/servers/peertube/peertube.png new file mode 100644 index 0000000000000000000000000000000000000000..d4ecf69f7b7a55930e7bef6f787595ed1eb3eeac GIT binary patch literal 86639 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