diff --git a/main.py b/main.py index bc4e06b..50c118a 100644 --- a/main.py +++ b/main.py @@ -191,22 +191,19 @@ class Context(): # appended to the "failures" context entry, otherwise a single request would crash the whole homepage. def subscriptions(self, page=1, lang=None): # Let's follow subscriptions from the current working dir - # TODO: make it configurable, maybe by "playlist" or by language? + # TODO: make it configurable, maybe by "playlist" defined in config? subscriptions = Subscriptions('.', self.api, cache) info = subscriptions.info() - # TODO: limit does nothing here?! - videos = subscriptions.videos(limit=12) + # Lang-filtering is done deeper in the API, so if a channel has 3 differents videos per publication for different languages, + # we can still get the expected number of recent videos from there instead of only considering the eg. 5 latest videos in said lang + # TODO: Is it working well? Should write some tests + videos = subscriptions.videos(page=page, lang=lang) failures = info.failures failures.extend(videos.failures) filtered_videos = videos.successes - if lang != None: - # TODO: What to do when language is not defined on video? Should we have "default language" for account/channel? - # Currently it's displayed in all languages - filtered_videos = list(filter(lambda vid: vid["language"]["id"] == lang or vid["language"]["id"] == None, filtered_videos)) - self.insert("subscriptions", info.successes) self.insert("videos", filtered_videos) # Sanitize errors for HTML so we can have newlines in errors but not risk content injection @@ -214,16 +211,20 @@ class Context(): return self # --- INDEX ROUTE --- -@app.route("/") -async def main(): - context = Context(api).subscriptions() +@app.route("/", defaults = {"page": 1}) +@app.route("/") +async def main(page): + # TODO: Pagination + context = Context(api).subscriptions(page=page) # Inside subscriptions variable in templates, you may find either an account info structure, or a channel info structure. Channels may be recognized due to `ownerAccount` property. # Failed requests do not fail the index.html rendering, instead they are stored in "failures" context key return await render("index.html", context.failed(), context.build) -@app.route("/") -async def main_lang(lang): - context = Context(api).subscriptions(lang=lang) +@app.route("/", defaults = {"page": 1}) +@app.route("//") +async def main_lang(lang, page): + # TODO: Pagination + context = Context(api).subscriptions(page=page, lang=lang) return await render("index.html", context.failed(), context.build) # --- END INDEX ROUTE --- diff --git a/peertube.py b/peertube.py index c9a68a2..4db720a 100644 --- a/peertube.py +++ b/peertube.py @@ -343,9 +343,10 @@ class API: # Fetch latest videos from multiple accounts, returned as MultipleResults # NOTE: This new API method enforces usage of Account class as channel. DO NOT USE WITH (account, domain) tuple. def accounts_videos(self, accounts, limit=None, sort=True, ttl=None): + api_limit = 10 if limit == None else limit results = MultipleResults() for account in accounts: - results.insert_paginated(self.account_videos(account.domain, account.name)) + results.insert_paginated(self.account_videos(account.domain, account.name, count=api_limit)) if limit or sort: # We also sort when limit is set, because otherwise limit will discard useful information results.successes.sort(key = lambda vid: dateutil.isoparse(vid["createdAt"]), reverse=True) @@ -386,9 +387,10 @@ class API: # Fetch latest videos from multiple channels, returned as MultipleResults # NOTE: This new API method enforces usage of Account class as channel. DO NOT USE WITH (account, domain) tuple. def channels_videos(self, channels, limit=None, sort=True, ttl=None): + api_limit = 10 if limit == None else limit results = MultipleResults() for channel in channels: - results.insert_paginated(self.channel_videos(channel.domain, channel.name)) + results.insert_paginated(self.channel_videos(channel.domain, channel.name, count=api_limit)) if limit or sort: # We also sort when limit is set, because otherwise limit will discard useful information results.successes.sort(key = lambda vid: dateutil.isoparse(vid["createdAt"]), reverse=True) diff --git a/utils.py b/utils.py index 62f7fc6..9852dcd 100644 --- a/utils.py +++ b/utils.py @@ -153,11 +153,14 @@ class Subscriptions: # Get the latest `limit` videos from accounts and channels subscriptions combined. Returns a list of successes and failures # NOTE: duplicates are not handled, why would you add both an account and the corresponding channel? - def videos(self, limit=12, sort=True, ttl=None): - results = MultipleResults().merge_with(self.api.accounts_videos(self.accounts(), limit=limit, ttl=ttl, sort=False)) \ - .merge_with(self.api.channels_videos(self.channels(), limit=limit, ttl=ttl, sort=False)) - if sort: + def videos(self, page=None, sort=True, lang=None, ttl=None): + results = MultipleResults().merge_with(self.api.accounts_videos(self.accounts(), ttl=ttl, sort=False)) \ + .merge_with(self.api.channels_videos(self.channels(), ttl=ttl, sort=False)) + if lang != None: + results.successes = list(filter(lambda vid: vid["language"]["id"] == lang or vid["language"]["id"] == None, results.successes)) + if page or sort: results.successes.sort(key = lambda vid: dateutil.isoparse(vid["createdAt"]), reverse=True) + if page: results.successes = results.successes[15*(page-1):15*page] return results # List of locally-subscribed accounts (accounts.list)