diff --git a/API.py b/API.py index ec6ea50..e37b8a9 100644 --- a/API.py +++ b/API.py @@ -1,4 +1,4 @@ -import requests +import httpx class Fetcher: @@ -11,26 +11,38 @@ class Fetcher: self.articles = {} def getUnreadCounts(self): - response = requests.get(self.URL+"/reader/api/0/unread-count?output=json", headers=self.headers) + response = httpx.get(self.URL+"/reader/api/0/unread-count?output=json", headers=self.headers) result = dict([(item["id"], (item["count"], item["newestItemTimestampUsec"])) for item in response.json()["unreadcounts"]]) self.unreadCounts = result self.categories = [{"id": item, "name": item[13:], "count": self.unreadCounts[item][0]} for item in self.unreadCounts.keys() if item[0:13] == "user/-/label/"] def getSubscriptions(self): - response = requests.get(self.URL+"/reader/api/0/subscription/list?output=json", headers=self.headers) + response = httpx.get(self.URL+"/reader/api/0/subscription/list?output=json", headers=self.headers) self.feeds = response.json()["subscriptions"] + def checkCategory(self, category): + return category in self.articles.keys() + def feedsFromCategory(self, category): return [item for item in self.feeds if item["categories"][0]["id"] == category and self.unreadCounts[item["id"]][0] != 0] def articlesFromCategory(self, category, number): if category not in self.articles: - response = requests.get(self.URL+"/reader/api/0/stream/contents?n="+number+"&s=user/-/label/"+category, headers=self.headers) + response = httpx.get(self.URL+"/reader/api/0/stream/contents?n="+number+"&s=user/-/label/"+category, headers=self.headers) + self.articles[category] = response.json()["items"] + + async def articlesFromCategoryAsync(self, category, number): + if category not in self.articles: + response = await httpx.AsyncClient().get(self.URL+"/reader/api/0/stream/contents?n="+number + + "&s=user/-/label/"+category, headers=self.headers) self.articles[category] = response.json()["items"] def articlesFromFeed(self, feed, category): - return [article for article in self.articles[category] if article["origin"]["streamId"] == feed] + try: + return [article for article in self.articles[category] if article["origin"]["streamId"] == feed] + except BaseException: + return None def fetch(self): for category in self.categories: diff --git a/App.py b/App.py index 5b58699..009204a 100644 --- a/App.py +++ b/App.py @@ -3,6 +3,7 @@ import yaml from concurrent.futures import ThreadPoolExecutor from API import Fetcher from Render import Article +import asyncio class LeftPane(urwid.ListBox): @@ -27,15 +28,21 @@ class LeftPane(urwid.ListBox): def getArticlesFromFeed(self, feed): return tui.fetcher.articlesFromFeed(feed, self.currentCategory[13:]) - def getArticles(self, attrMap): - if self.isCategoryView: - itemId = attrMap[0] - number = attrMap[1] - tui.fetcher.articlesFromCategory(itemId[13:], str(number)) - return tui.fetcher.articles[itemId[13:]] - else: - itemId = attrMap - return tui.fetcher.articlesFromFeed(itemId, self.currentCategory[13:]) + async def setCategoryArticles(self, attrMap): + itemId = attrMap[0] + number = attrMap[1] + await tui.fetcher.articlesFromCategoryAsync(itemId[13:], str(number)) + focus_widget, idx = self.get_focus() + currentCategory = focus_widget.attr_map[None][0] + if itemId == currentCategory: + tui.articles = tui.fetcher.articles[currentCategory[13:]] + tui.articleView.fill(tui.articles) + + def setFeedArticles(self, attrMap): + itemId = attrMap + tui.articles = tui.fetcher.articlesFromFeed(itemId, self.currentCategory[13:]) + if tui.articles is not None: + tui.articleView.fill(tui.articles) def keypress(self, size, key): if key in ("j", "down"): @@ -47,8 +54,9 @@ class LeftPane(urwid.ListBox): focus_widget, idx = self.get_focus() if self.isCategoryView: self.currentCategory = focus_widget.attr_map[None][0] - tui.articles = self.getArticles(focus_widget.attr_map[None]) - tui.articleView.fill(tui.articles) + asyncio.create_task(self.setCategoryArticles(focus_widget.attr_map[None])) + else: + self.setFeedArticles(focus_widget.attr_map[None]) return elif key in ("k", "up"): focus_widget, idx = self.get_focus() @@ -58,11 +66,12 @@ class LeftPane(urwid.ListBox): focus_widget, idx = self.get_focus() if self.isCategoryView: self.currentCategory = focus_widget.attr_map[None][0] - tui.articles = self.getArticles(focus_widget.attr_map[None]) - tui.articleView.fill(tui.articles) + asyncio.create_task(self.setCategoryArticles(focus_widget.attr_map[None])) + else: + self.setFeedArticles(focus_widget.attr_map[None]) return elif key in ("l", "right"): - if self.isCategoryView: + if self.isCategoryView and tui.fetcher.checkCategory(self.currentCategory[13:]): self.isCategoryView = False focus_widget, idx = self.get_focus() self.categoryPosition = idx @@ -76,8 +85,7 @@ class LeftPane(urwid.ListBox): focus_widget, idx = self.get_focus() if self.isCategoryView: self.currentCategory = focus_widget.attr_map[None][0] - tui.articles = self.getArticles(focus_widget.attr_map[None]) - tui.articleView.fill(tui.articles) + self.setFeedArticles(focus_widget.attr_map[None]) return elif key in ("h", "left"): if not self.isCategoryView: @@ -89,8 +97,7 @@ class LeftPane(urwid.ListBox): tui.leftBox.set_title("Categories") self.set_focus(self.categoryPosition) focus_widget, idx = self.get_focus() - tui.articles = self.getArticles(focus_widget.attr_map[None]) - tui.articleView.fill(tui.articles) + tui.articles = self.setCategoryArticles(focus_widget.attr_map[None]) return return super().keypress(size, key) @@ -224,9 +231,7 @@ class TUI(urwid.Frame): self.fetcher.articlesFromCategory(item, str(focus_widget.attr_map[None][1])) self.articles = tui.fetcher.articles[item] self.articleView.fill(self.articles) - self.handle = self.loop.event_loop.alarm(0, self.fetchAll) self.loop.run() - tui.loop.event_loop.remove_enter_idle(self.handle) self.executor.shutdown(wait=False) def unhandled_input(self, key): @@ -236,7 +241,7 @@ class TUI(urwid.Frame): elif key == "q": raise urwid.ExitMainLoop() elif key == "r": - self.fetchAll() + self.handle = self.loop.event_loop.alarm(0, self.fetchAll) focus_widget, idx = self.feedView.get_focus() itemId = focus_widget.attr_map[None][0] self.articles = tui.fetcher.articles[itemId[13:]]