From 03c49f9a0fada8dc71ef9502fe054d0f4cd82de4 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Fri, 15 Mar 2024 11:10:02 +0100 Subject: [PATCH] fetch all playlist videos at once --- melon/servers/__init__.py | 2 +- melon/servers/invidious/__init__.py | 38 ++++++++++++++++++++++++++--- melon/servers/nebula/__init__.py | 3 +-- melon/servers/peertube/__init__.py | 5 ++-- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/melon/servers/__init__.py b/melon/servers/__init__.py index c457140..4bf7bc8 100644 --- a/melon/servers/__init__.py +++ b/melon/servers/__init__.py @@ -224,7 +224,7 @@ class Server(ABC): """ pass @abstractmethod - def get_playlist_content(self, pid: str, page=0) -> list[Resource]: + def get_playlist_content(self, pid: str) -> 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 b1aecac..cef1d22 100644 --- a/melon/servers/invidious/__init__.py +++ b/melon/servers/invidious/__init__.py @@ -7,7 +7,6 @@ import gi gi.require_version("WebKit", "6.0") from gi.repository import GLib, WebKit - from melon.import_providers.newpipe import NewpipeImporter from melon.servers import Server, Preference, PreferenceType from melon.servers import Feed, Channel, Video, Playlist, Stream, SearchMode @@ -155,9 +154,9 @@ class Invidious(Server): # on the playlist screen return Playlist(self.id, url, pid, title, channel, None) - def get_playlist_content(self, pid: str, page=0): + def get_playlist_content(self, pid: str): instance = self.get_external_url() - return self.request_and_parse(f"{instance}/playlist?list={pid}") + return self.request_and_parse(f"{instance}/playlist?list={pid}", recurse=True) def get_timeline(self, cid: str): instance = self.get_external_url() @@ -198,7 +197,7 @@ class Invidious(Server): return feed return [] - def request_and_parse(self,url): + def request_and_parse(self,url, recurse = False): """Fetches the URL and returns a list of Resources""" r = requests.get(url, headers={ "User-Agent": USER_AGENT }) if r.ok: @@ -268,6 +267,37 @@ class Invidious(Server): else: continue results.append(res) + if recurse: + current_page = 1 + urlres = urlparse(url) + query = parse_qs(urlres.query) + if "page" in query: + current_page = query["page"][0] + try: + current_page = int(current_page) + except Exception as e: + current_page = 1 + instance = self.get_external_url() + listings = soup.find_all("a", {"class":"pure-button"}) + for lis in listings: + iurl = lis["href"] + iurlres = urlparse(iurl) + iquery = parse_qs(iurlres.query) + if iurlres.path != urlres.path: + continue + if not "page" in iquery: + continue + ipage = 1 + try: + ipage = int(iquery["page"][0]) + except Exception as e: + ipage = 1 + if ipage <= current_page: + continue + iurl = f"{instance}/{iurl}" + results += self.request_and_parse(iurl, recurse) + break + return results # simply return empty array if request failed return [] diff --git a/melon/servers/nebula/__init__.py b/melon/servers/nebula/__init__.py index 3c341cf..9e9d109 100644 --- a/melon/servers/nebula/__init__.py +++ b/melon/servers/nebula/__init__.py @@ -246,8 +246,7 @@ class Nebula(Server): # nebula doesn't support playlist thumbnails None) - def get_playlist_content(self, playlist_id: str, page=0): - # TODO: add pagination + def get_playlist_content(self, playlist_id: str): # apparently this call doesn't support page numbers # and instead we have to use the provided data["next"] cursor url = f"https://content.api.nebula.app/video_playlists/{playlist_id}/video_episodes/" diff --git a/melon/servers/peertube/__init__.py b/melon/servers/peertube/__init__.py index b814a50..9fc6a7c 100644 --- a/melon/servers/peertube/__init__.py +++ b/melon/servers/peertube/__init__.py @@ -283,10 +283,9 @@ class Peertube(Server): (channel_name, channel_id), thumb) - def get_playlist_content(self, pid: str, page=0): + def get_playlist_content(self, pid: str): instance, playlist_id = pid.split("::") - size = 15 - url = f"{instance}/api/v1/video-playlists/{playlist_id}/videos?start={page*size}&count={size}" + url = f"{instance}/api/v1/video-playlists/{playlist_id}/videos" r = requests.get(url) results = [] if r.ok: -- 2.38.5