First attempt at multiple pages of homepage subscriptions
This commit is contained in:
parent
90c054e258
commit
fe0b83bd0e
29
main.py
29
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("/<int:page>")
|
||||
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("/<lang:lang>")
|
||||
async def main_lang(lang):
|
||||
context = Context(api).subscriptions(lang=lang)
|
||||
@app.route("/<lang:lang>", defaults = {"page": 1})
|
||||
@app.route("/<lang:lang>/<int:page>")
|
||||
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 ---
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
11
utils.py
11
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)
|
||||
|
|
Loading…
Reference in New Issue