- Implement displaying read articles.

- Implement toggling a single article read/unread.
sqlite
VikingKong 3 years ago
parent c5a2c45c9a
commit 6bea11da2b

@ -33,3 +33,18 @@ class Fetcher:
response = httpx.get(self.URL+"/reader/api/0/stream/contents?ot="+timestamp+"&s=" response = httpx.get(self.URL+"/reader/api/0/stream/contents?ot="+timestamp+"&s="
+ category, headers=self.headers) + category, headers=self.headers)
return response.json()["items"] return response.json()["items"]
def toggleArticleStatus(self, articleId, is_read):
if is_read == 0:
tag_op = 'r'
else:
tag_op = 'a'
try:
response = httpx.post(self.URL+"/reader/api/0/edit-tag", data={"i": articleId, tag_op: "user/-/state/com.google/read"},
headers=self.headers)
if response.status_code == 200:
return True
else:
return False
except BaseException:
return False

@ -1,6 +1,5 @@
import urwid import urwid
import yaml import yaml
import asyncio
import warnings import warnings
import subprocess import subprocess
import os import os
@ -42,27 +41,26 @@ class LeftPane(urwid.ListBox):
walker = urwid.SimpleListWalker(items) walker = urwid.SimpleListWalker(items)
self.body = walker self.body = walker
def findById(self, id):
idx = 0
for idx, item in zip(range(len(self.body)), self.body):
if item.attr_map[None][0] == id:
break
return idx
def setArticlesPaneTitle(self, text): def setArticlesPaneTitle(self, text):
tui.rightBox.set_title(text) tui.rightBox.set_title(text)
def getArticlesFromCategory(self, category, number=0): def setCategoryArticles(self, attrMap):
tui.fetcher.articlesFromCategory(category, str(number))
articles = tui.fetcher.articles[category]
return articles
def getArticlesFromFeed(self, feed):
return tui.fetcher.articlesFromFeed(feed, self.currentCategory)
async def setCategoryArticles(self, attrMap):
itemId = attrMap[0] itemId = attrMap[0]
name = attrMap[1] name = attrMap[1]
tui.articles = tui.cache.getArticlesFromCategory(itemId) tui.articles = tui.cache.getArticlesFromCategory(itemId, tui.show_read)
tui.articleView.fill(tui.articles) tui.articleView.fill(tui.articles)
self.setArticlesPaneTitle(name) self.setArticlesPaneTitle(name)
def setFeedArticles(self, attrMap): def setFeedArticles(self, attrMap):
itemId = attrMap[0] itemId = attrMap[0]
tui.articles = tui.cache.getArticlesFromFeed(itemId) tui.articles = tui.cache.getArticlesFromFeed(itemId, tui.show_read)
if tui.articles is not None: if tui.articles is not None:
tui.articleView.fill(tui.articles) tui.articleView.fill(tui.articles)
self.setArticlesPaneTitle(attrMap[1]) self.setArticlesPaneTitle(attrMap[1])
@ -77,7 +75,7 @@ class LeftPane(urwid.ListBox):
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
if self.isCategoryView: if self.isCategoryView:
self.currentCategory = focus_widget.attr_map[None][0] self.currentCategory = focus_widget.attr_map[None][0]
asyncio.create_task(self.setCategoryArticles(focus_widget.attr_map[None])) self.setCategoryArticles(focus_widget.attr_map[None])
else: else:
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
return return
@ -89,7 +87,7 @@ class LeftPane(urwid.ListBox):
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
if self.isCategoryView: if self.isCategoryView:
self.currentCategory = focus_widget.attr_map[None][0] self.currentCategory = focus_widget.attr_map[None][0]
asyncio.create_task(self.setCategoryArticles(focus_widget.attr_map[None])) self.setCategoryArticles(focus_widget.attr_map[None])
else: else:
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
return return
@ -100,7 +98,7 @@ class LeftPane(urwid.ListBox):
self.categoryPosition = idx self.categoryPosition = idx
categoryId = focus_widget.attr_map[None][0] categoryId = focus_widget.attr_map[None][0]
categoryName = focus_widget.attr_map[None][1] categoryName = focus_widget.attr_map[None][1]
feeds = tui.cache.getFeeds(categoryId) feeds = tui.cache.getFeeds(categoryId, tui.show_read)
self.fill(feeds, False) self.fill(feeds, False)
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
@ -113,7 +111,7 @@ class LeftPane(urwid.ListBox):
tui.leftBox.set_title("Categories") tui.leftBox.set_title("Categories")
self.set_focus(self.categoryPosition) self.set_focus(self.categoryPosition)
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
asyncio.create_task(self.setCategoryArticles(focus_widget.attr_map[None])) self.setCategoryArticles(focus_widget.attr_map[None])
return return
return super().keypress(size, key) return super().keypress(size, key)
@ -130,10 +128,13 @@ class RightPane(urwid.ListBox):
self.chunkNumber = 0 self.chunkNumber = 0
def fill(self, articles): def fill(self, articles):
status = ""
if tui.show_read:
status = "R"
items = [ items = [
urwid.AttrMap( urwid.AttrMap(
urwid.Columns( urwid.Columns(
[(2, urwid.Text("")), [(2, urwid.Text(status)),
(16, urwid.Text(article[3])), (16, urwid.Text(article[3])),
urwid.Text(article[1])]), urwid.Text(article[1])]),
article[0], article[0],
@ -171,6 +172,33 @@ class RightPane(urwid.ListBox):
idx = idx - 1 idx = idx - 1
self.set_focus(idx) self.set_focus(idx)
return return
elif key in ("r"):
if self.isList is True:
feeds = []
article_widget, article_idx = self.get_focus()
articleId = article_widget.attr_map[None]
tui.cache.toggleArticleStatus(articleId)
item_widget, item_idx = tui.feedView.get_focus()
itemAttrMap = item_widget.attr_map[None]
if tui.feedView.isCategoryView:
tui.feedView.setCategoryArticles(itemAttrMap)
else:
tui.feedView.setFeedArticles(itemAttrMap)
if article_idx > 0:
article_idx -= 1
try:
self.set_focus(article_idx)
except BaseException:
pass
if tui.feedView.isCategoryView:
feeds = tui.cache.getCategories(tui.show_read)
tui.categories = feeds
else:
feeds = tui.cache.getFeeds(tui.feedView.currentCategory, tui.show_read)
tui.feedView.fill(feeds, tui.feedView.isCategoryView)
new_idx = tui.feedView.findById(itemAttrMap[0])
tui.feedView.set_focus(new_idx)
return
elif key in ("l", "right"): elif key in ("l", "right"):
if self.isList is True: if self.isList is True:
self.isList = False self.isList = False
@ -278,10 +306,11 @@ class TUI(urwid.Frame):
URL = config["server"]["URL"] URL = config["server"]["URL"]
token = config["server"]["token"] token = config["server"]["token"]
self.show_read = 0
self.overlay = None self.overlay = None
self.fetcher = Fetcher(URL, token) self.fetcher = Fetcher(URL, token)
self.cache = Cache(self.fetcher) self.cache = Cache(self.fetcher)
self.categories = self.cache.getCategories() self.categories = self.cache.getCategories(self.show_read)
self.leftPaneItems = {} self.leftPaneItems = {}
self.activePane = False self.activePane = False
@ -301,11 +330,11 @@ class TUI(urwid.Frame):
def initialize_panes(self): def initialize_panes(self):
try: try:
self.feedView.fill(self.cache.getCategories(), True) self.feedView.fill(self.cache.getCategories(self.show_read), True)
focus_widget, idx = self.feedView.get_focus() focus_widget, idx = self.feedView.get_focus()
item = focus_widget.attr_map[None][0] item = focus_widget.attr_map[None][0]
name = focus_widget.attr_map[None][1] name = focus_widget.attr_map[None][1]
self.articles = self.cache.getArticlesFromCategory(item) self.articles = self.cache.getArticlesFromCategory(item, self.show_read)
self.articleView.fill(self.articles) self.articleView.fill(self.articles)
self.feedView.setArticlesPaneTitle(name) self.feedView.setArticlesPaneTitle(name)
except BaseException: except BaseException:
@ -334,7 +363,7 @@ class TUI(urwid.Frame):
tui.articleView.isList = True tui.articleView.isList = True
elif key == "q": elif key == "q":
raise urwid.ExitMainLoop() raise urwid.ExitMainLoop()
elif key == "r": elif key == "f":
olb = urwid.ListBox(urwid.SimpleListWalker([urwid.Text("")])) olb = urwid.ListBox(urwid.SimpleListWalker([urwid.Text("")]))
overlay = urwid.Overlay( overlay = urwid.Overlay(
urwid.LineBox(olb), urwid.LineBox(olb),
@ -346,6 +375,16 @@ class TUI(urwid.Frame):
tui.loop.entering_idle() tui.loop.entering_idle()
self.body = overlay.bottom_w self.body = overlay.bottom_w
self.initialize_panes() self.initialize_panes()
elif key == "R":
self.show_read = int(not self.show_read)
focus_widget, idx = self.feedView.get_focus()
if self.feedView.isCategoryView:
self.feedView.setCategoryArticles(focus_widget.attr_map[None])
else:
self.feedView.setFeedArticles(focus_widget.attr_map[None])
self.categories = tui.cache.getCategories(self.show_read)
self.feedView.fill(self.categories, True)
return
tui = TUI.create() tui = TUI.create()

@ -64,30 +64,53 @@ class Cache:
cur.execute("""select title,content,url from articles where id = ?""", (id,)) cur.execute("""select title,content,url from articles where id = ?""", (id,))
return cur.fetchone() return cur.fetchone()
def toggleArticleStatus(self, id):
inc = 0
cur = self.conn.cursor()
cur.execute("""update articles set is_read = not is_read where id = ?""", (id,))
cur.execute("""select origin, category_id, is_read from articles where id = ?""", (id,))
feed_id, category_id, is_read = cur.fetchone()
if is_read == 0:
inc = 1
else:
inc = -1
cur.execute("""update categories set unread_count = unread_count + ? where id = ?""", (inc, category_id,))
cur.execute("""update feeds set unread_count = unread_count + ? where id = ?""", (inc, feed_id,))
if self.api.toggleArticleStatus(id, is_read):
self.conn.commit()
else:
self.conn.rollback()
def getArticleLinks(self, id): def getArticleLinks(self, id):
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select url from links where id = ?""", (id,)) cur.execute("""select url from links where id = ?""", (id,))
links = functools.reduce(operator.iconcat, cur.fetchall(), []) links = functools.reduce(operator.iconcat, cur.fetchall(), [])
return links return links
def getArticlesFromFeed(self, feed_id): def getArticlesFromFeed(self, feed_id, is_read):
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select * from articles where origin = ? order by timestamp desc""", (feed_id,)) cur.execute("""select * from articles where origin = ? and is_read = ? order by timestamp desc""", (feed_id, is_read,))
return cur.fetchall() return cur.fetchall()
def getArticlesFromCategory(self, category_id): def getArticlesFromCategory(self, category_id, is_read):
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select * from articles where category_id = ? order by timestamp desc""", (category_id,)) cur.execute("""select * from articles where category_id = ? and is_read = ? order by timestamp desc""", (category_id, is_read,))
return cur.fetchall() return cur.fetchall()
def getCategories(self): def getCategories(self, show_read):
statement = """select * from categories where unread_count != 0 order by timestamp desc"""
if show_read == 1:
statement = """select * from categories order by timestamp desc"""
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select * from categories where unread_count != 0 order by timestamp desc""") cur.execute(statement)
return cur.fetchall() return cur.fetchall()
def getFeeds(self, category_id): def getFeeds(self, category_id, show_read):
statement = """select * from feeds where category_id = ? and unread_count != 0 order by timestamp desc"""
if show_read == 1:
statement = """select * from feeds where category_id = ? order by timestamp desc"""
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select * from feeds where category_id = ? and unread_count != 0 order by timestamp desc""", (category_id,)) cur.execute(statement, (category_id,))
return cur.fetchall() return cur.fetchall()
def refresh(self): def refresh(self):

@ -36,4 +36,4 @@ def checkRedditComments(links):
def writeLog(text): def writeLog(text):
with open("debug.log", "a") as f: with open("debug.log", "a") as f:
f.write(str(text)) f.write(str(text)+"\n")

Loading…
Cancel
Save