From 449db3dff7cf3535009e01e64b10782b49645c4f Mon Sep 17 00:00:00 2001 From: VikingKong Date: Tue, 28 Mar 2023 21:45:25 +0300 Subject: [PATCH] - Switch to Category View when all feeds are read. - Fix error 302 on loading comments from Reddit. - Display the name of the feed when in the Category View. - Some refactoring. --- App.py | 116 +++++++++++++++++++++++----------------- Cache.py | 25 +++++---- RedditCommentsParser.py | 6 ++- 3 files changed, 86 insertions(+), 61 deletions(-) diff --git a/App.py b/App.py index cb9fce9..1d73a11 100644 --- a/App.py +++ b/App.py @@ -79,14 +79,14 @@ class LeftPane(urwid.ListBox): itemId = attrMap[0] name = attrMap[1] tui.articles = tui.cache.getArticlesFromCategory(itemId, tui.show_read) - tui.articleView.fill(tui.articles) + tui.articleView.fill(tui.articles, True) self.setArticlesPaneTitle(name) def setFeedArticles(self, attrMap): itemId = attrMap[0] tui.articles = tui.cache.getArticlesFromFeed(itemId, tui.show_read) if tui.articles is not None: - tui.articleView.fill(tui.articles) + tui.articleView.fill(tui.articles, False) self.setArticlesPaneTitle(attrMap[1]) def keypress(self, size, key): # noqa @@ -122,52 +122,63 @@ class LeftPane(urwid.ListBox): pass return elif key in ("l", "right"): - try: - if self.isCategoryView and self.currentCategory != "Favorites": - self.isCategoryView = False - focus_widget, idx = self.get_focus() - self.categoryPosition = idx - categoryId = self.processAttrMap(focus_widget.attr_map)[0] - categoryName = self.processAttrMap(focus_widget.attr_map)[1] - feeds = tui.cache.getFeeds(categoryId, tui.show_read) - self.fill(feeds, False) - focus_widget, idx = self.get_focus() - self.setFeedArticles(focus_widget.attr_map[None]) - tui.leftBox.set_title(categoryName) - except BaseException: - pass + self.stepInto() return elif key in ("h", "left"): - if not self.isCategoryView: - self.isCategoryView = True - self.fill(tui.categories, True) - tui.leftBox.set_title("Categories") - self.set_focus(self.categoryPosition) - focus_widget, idx = self.get_focus() - self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map)) + self.stepOut() return elif key in ("r"): - try: - focus_widget, idx = self.get_focus() - del self.body[idx] - if idx > 0: - idx -= 1 - self.set_focus(idx) - tui.cache.markStreamAsRead(self.processAttrMap(focus_widget.attr_map)[0]) - tui.categories = tui.cache.getCategories(tui.show_read) - focus_widget, idx = self.get_focus() - if self.isCategoryView: - self.currentCategory = self.processAttrMap(focus_widget.attr_map)[0] - self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map)) - else: - self.setFeedArticles(focus_widget.attr_map[None]) - except BaseException as e: - Utils.writeLog(e) - pass + self.markAsRead() return return super().keypress(size, key) + def stepOut(self): + if not self.isCategoryView: + self.isCategoryView = True + self.fill(tui.categories, True) + tui.leftBox.set_title("Categories") + self.set_focus(self.categoryPosition) + focus_widget, idx = self.get_focus() + self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map)) + + def stepInto(self): + try: + if self.isCategoryView and self.currentCategory != "Favorites": + self.isCategoryView = False + focus_widget, idx = self.get_focus() + self.categoryPosition = idx + categoryId = self.processAttrMap(focus_widget.attr_map)[0] + categoryName = self.processAttrMap(focus_widget.attr_map)[1] + feeds = tui.cache.getFeeds(categoryId, tui.show_read) + self.fill(feeds, False) + focus_widget, idx = self.get_focus() + self.setFeedArticles(focus_widget.attr_map[None]) + tui.leftBox.set_title(categoryName) + except BaseException: + pass + + def markAsRead(self): + try: + focus_widget, idx = self.get_focus() + del self.body[idx] + if idx > 0: + idx -= 1 + self.set_focus(idx) + tui.cache.markStreamAsRead(self.processAttrMap(focus_widget.attr_map)[0]) + tui.categories = tui.cache.getCategories(tui.show_read) + focus_widget, idx = self.get_focus() + if focus_widget is None and not self.isCategoryView: + self.stepOut() + return + if self.isCategoryView: + self.currentCategory = self.processAttrMap(focus_widget.attr_map)[0] + self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map)) + else: + self.setFeedArticles(focus_widget.attr_map[None]) + except BaseException: + pass + class RightPane(urwid.ListBox): def __init__(self, items): @@ -179,16 +190,25 @@ class RightPane(urwid.ListBox): self.article = None self.chunkNumber = 0 - def fill(self, articles): + def fill(self, articles, isCategoryView): status = "" + + def makeColumns(article): + title = article[1] + if isCategoryView: + title += " (" + article[-1] + ")" + cols = [ + (2, urwid.Text(status)), + (16, urwid.Text(article[3])), + urwid.Text(title), + ] + return cols + if tui.show_read: status = "R" items = [ urwid.AttrMap( - urwid.Columns( - [(2, urwid.Text(status)), - (16, urwid.Text(article[3])), - urwid.Text(article[1])]), + urwid.Columns(makeColumns(article)), article[0], "reveal focus") for article in articles] walker = urwid.SimpleListWalker(items) @@ -231,7 +251,6 @@ class RightPane(urwid.ListBox): pass return elif key in ("f"): - Utils.writeLog(tui.feedView.currentCategory) if self.isList is True: article_widget, article_idx = self.get_focus() articleId = article_widget.attr_map[None] @@ -240,7 +259,6 @@ class RightPane(urwid.ListBox): item_widget, item_idx = tui.feedView.get_focus() if tui.feedView.isCategoryView: tui.feedView.fill(tui.categories, tui.feedView.isCategoryView) - Utils.writeLog(tui.feedView.currentCategory) tui.feedView.set_focus(item_idx) if item_idx == 0: tui.feedView.setCategoryArticles(('Favorites', 'Favorites')) @@ -307,7 +325,7 @@ class RightPane(urwid.ListBox): try: if self.isList is False: self.isList = True - self.fill(tui.articles) + self.fill(tui.articles, tui.feedView.isCategoryView) focusFeed, idx = tui.feedView.get_focus() tui.rightBox.set_title(tui.feedView.processAttrMap(focusFeed.attr_map)[1]) self.set_focus(self.articlePosition) @@ -429,7 +447,7 @@ class TUI(urwid.Frame): item = self.feedView.processAttrMap(focus_widget.attr_map)[0] name = self.feedView.processAttrMap(focus_widget.attr_map)[1] self.articles = self.cache.getArticlesFromCategory(item, self.show_read) - self.articleView.fill(self.articles) + self.articleView.fill(self.articles, True) self.feedView.setArticlesPaneTitle(name) except BaseException: pass diff --git a/Cache.py b/Cache.py index fd1be90..201fad4 100644 --- a/Cache.py +++ b/Cache.py @@ -52,7 +52,9 @@ class Cache: timestamp integer, date text, content text, - url text + url text, + origin text, + foreign key (origin) references feeds (id) ) """ create_links = """create table if not exists links ( @@ -96,7 +98,6 @@ class Cache: def getArticle(self, id, is_fav): cur = self.conn.cursor() - Utils.writeLog(is_fav) if is_fav: cur.execute("""select title,content,url from favorites where id = ?""", (id,)) else: @@ -131,11 +132,11 @@ class Cache: inc = -1 else: inc = 1 - cur.execute("""select title, timestamp, date, content, url from articles where id = ?""", (id,)) - title, timestamp, date, content, url = cur.fetchone() - cur.execute("""insert into favorites(id, title, timestamp, date, content, url) values(:id, :title, :timestamp, :date - ,:content, :url)""", {"id": id, "title": title, "timestamp": timestamp, "date": date, "content": content, - "url": url}) + cur.execute("""select title, timestamp, date, content, url, origin from articles where id = ?""", (id,)) + title, timestamp, date, content, url, origin = cur.fetchone() + cur.execute("""insert into favorites(id, title, timestamp, date, content, url, origin) values(:id, :title, :timestamp, :date + ,:content, :url, :origin)""", {"id": id, "title": title, "timestamp": timestamp, "date": date, "content": content, + "url": url, "origin": origin}) cur.execute("""update categories set unread_count = unread_count + ? where id = ?""", (inc, "Favorites",)) if self.api.toggleArticleStarred(id, is_favorite): self.conn.commit() @@ -155,10 +156,12 @@ class Cache: def getArticlesFromCategory(self, category_id, is_read): cur = self.conn.cursor() + Utils.writeLog(category_id) if category_id == "Favorites": - cur.execute("""select * from favorites order by timestamp desc""") + cur.execute("""select *, (select name from feeds where id = origin) as origin_name from favorites order by timestamp desc""") else: - cur.execute("""select * from articles where category_id = ? and is_read = ? order by timestamp desc""", (category_id, is_read,)) + cur.execute("""select *, (select name from feeds where id = origin) as origin_name from articles where + category_id = ? and is_read = ? order by timestamp desc""", (category_id, is_read,)) return cur.fetchall() def getCategories(self, show_read): @@ -219,9 +222,9 @@ class Cache: self.conn.commit() for favorite in favorites: favObj = Article(favorite) - cur.execute("""insert or ignore into favorites(id,title,timestamp,date,content,url) values(:id,:t,:ts,:d,:c,:u)""", + cur.execute("""insert or ignore into favorites(id,title,timestamp,date,content,url,origin) values(:id,:t,:ts,:d,:c,:u,:o)""", {"id": favObj.id, "t": favObj.title, "ts": favObj.timestamp, "d": favObj.date, - "c": favObj.text, "u": favObj.url}) + "c": favObj.text, "u": favObj.url, "o": favObj.origin}) for link in favObj.links: cur.execute("""insert or ignore into links(id,url) values(?,?)""", (favObj.id, link)) self.conn.commit() diff --git a/RedditCommentsParser.py b/RedditCommentsParser.py index 5d810b6..97d52bb 100644 --- a/RedditCommentsParser.py +++ b/RedditCommentsParser.py @@ -1,12 +1,16 @@ from bs4 import BeautifulSoup import httpx +import Utils class RedditComments: def __init__(self, link): - page = httpx.get(link) + Utils.writeLog(link) + page = httpx.get(link, follow_redirects=True) + Utils.writeLog(page) content = page.text self.soup = BeautifulSoup(content) + Utils.writeLog(self.soup) self.commentObjects = self.soup.find_all("div", "Comment") self.comments = []