Implement fetching and displaying Favorites.

sqlite
VikingKong 3 years ago
parent bc0beb12c9
commit b1e382ad89

@ -34,6 +34,11 @@ class Fetcher:
+ category, headers=self.headers) + category, headers=self.headers)
return response.json()["items"] return response.json()["items"]
def getFavorites(self):
response = httpx.get(self.URL+"/reader/api/0/stream/contents?s=user/-/state/com.google/starred&n=1000", headers=self.headers)
json = response.json()
return (json["updated"], Utils.timestampToDate(json["updated"]*1000000), json["items"])
def markStreamAsRead(self, streamId, ts): def markStreamAsRead(self, streamId, ts):
try: try:
response = httpx.post(self.URL+"/reader/api/0/mark-all-as-read", data={"s": streamId, "ts": ts}, headers=self.headers) response = httpx.post(self.URL+"/reader/api/0/mark-all-as-read", data={"s": streamId, "ts": ts}, headers=self.headers)

@ -22,12 +22,13 @@ class LeftPane(urwid.ListBox):
self.categoryPosition = 0 self.categoryPosition = 0
self.isCategoryView = True self.isCategoryView = True
self.currentCategory = "" self.currentCategory = ""
focus_widget, idx = self.get_focus()
if self.isCategoryView: def processAttrMap(self, attrMap):
try: res = attrMap[None]
self.currentCategory = focus_widget.attr_map[None][0] if res == "favorite":
except BaseException: return attrMap["attrs"]
self.currentCategory = None else:
return res
def fill(self, items, is_category_view): def fill(self, items, is_category_view):
def getAttrs(item): def getAttrs(item):
@ -35,11 +36,34 @@ class LeftPane(urwid.ListBox):
return (item[0], item[1], item[2]) return (item[0], item[1], item[2])
else: else:
return (item[0], item[1]) return (item[0], item[1])
items = [urwid.AttrMap(urwid.Columns([ if is_category_view is True:
(16, urwid.Text(item[4])), urwid.Text(item[1]), (5, urwid.Text(str(item[2])))]), items = [
getAttrs(item), "reveal focus") for item in items] urwid.AttrMap(
urwid.Columns(
[(16, urwid.Text(items[0][4])),
urwid.Text(items[0][1]),
(5, urwid.Text(str(items[0][2])))]),
{None: "favorite", "attrs": getAttrs(items[0])},
"reveal focus"),
*
[urwid.AttrMap(
urwid.Columns([(16, urwid.Text(item[4])),
urwid.Text(item[1]),
(5, urwid.Text(str(item[2])))]),
getAttrs(item),
"reveal focus") for item in items[1:]]]
else:
items = [urwid.AttrMap(urwid.Columns([
(16, urwid.Text(item[4])), urwid.Text(item[1]), (5, urwid.Text(str(item[2])))]),
getAttrs(item), "reveal focus") for item in items]
walker = urwid.SimpleListWalker(items) walker = urwid.SimpleListWalker(items)
self.body = walker self.body = walker
focus_widget, idx = self.get_focus()
if self.isCategoryView:
try:
self.currentCategory = focus_widget.attr_map[None][0]
except BaseException:
self.currentCategory = None
def findById(self, id): def findById(self, id):
idx = 0 idx = 0
@ -75,8 +99,8 @@ class LeftPane(urwid.ListBox):
self.set_focus(idx) self.set_focus(idx)
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 = self.processAttrMap(focus_widget.attr_map)[0]
self.setCategoryArticles(focus_widget.attr_map[None]) self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map))
else: else:
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
except BaseException: except BaseException:
@ -90,8 +114,8 @@ class LeftPane(urwid.ListBox):
self.set_focus(idx) self.set_focus(idx)
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 = self.processAttrMap(focus_widget.attr_map)[0]
self.setCategoryArticles(focus_widget.attr_map[None]) self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map))
else: else:
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
except BaseException: except BaseException:
@ -103,8 +127,8 @@ class LeftPane(urwid.ListBox):
self.isCategoryView = False self.isCategoryView = False
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
self.categoryPosition = idx self.categoryPosition = idx
categoryId = focus_widget.attr_map[None][0] categoryId = self.processAttrMap(focus_widget.attr_map)[0]
categoryName = focus_widget.attr_map[None][1] categoryName = self.processAttrMap(focus_widget.attr_map)[1]
feeds = tui.cache.getFeeds(categoryId, tui.show_read) 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()
@ -120,7 +144,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()
self.setCategoryArticles(focus_widget.attr_map[None]) self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map))
return return
elif key in ("r"): elif key in ("r"):
try: try:
@ -129,12 +153,12 @@ class LeftPane(urwid.ListBox):
if idx > 0: if idx > 0:
idx -= 1 idx -= 1
self.set_focus(idx) self.set_focus(idx)
tui.cache.markStreamAsRead(focus_widget.attr_map[None][0]) tui.cache.markStreamAsRead(self.processAttrMap(focus_widget.attr_map)[0])
tui.categories = tui.cache.getCategories(tui.show_read) tui.categories = tui.cache.getCategories(tui.show_read)
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 = self.processAttrMap(focus_widget.attr_map)[0]
self.setCategoryArticles(focus_widget.attr_map[None]) self.setCategoryArticles(self.processAttrMap(focus_widget.attr_map))
else: else:
self.setFeedArticles(focus_widget.attr_map[None]) self.setFeedArticles(focus_widget.attr_map[None])
except BaseException as e: except BaseException as e:
@ -231,8 +255,8 @@ class RightPane(urwid.ListBox):
tui.feedView.set_focus(new_idx) tui.feedView.set_focus(new_idx)
focus_widget, idx = tui.feedView.get_focus() focus_widget, idx = tui.feedView.get_focus()
if tui.feedView.isCategoryView: if tui.feedView.isCategoryView:
tui.feedView.currentCategory = focus_widget.attr_map[None][0] tui.feedView.currentCategory = tui.feedView.processAttrMap(focus_widget.attr_map)[0]
tui.feedView.setCategoryArticles(focus_widget.attr_map[None]) tui.feedView.setCategoryArticles(tui.feedView.processAttrMap(focus_widget.attr_map))
else: else:
tui.feedView.setFeedArticles(focus_widget.attr_map[None]) tui.feedView.setFeedArticles(focus_widget.attr_map[None])
try: try:
@ -250,7 +274,9 @@ class RightPane(urwid.ListBox):
focus_widget, idx = self.get_focus() focus_widget, idx = self.get_focus()
self.articlePosition = idx self.articlePosition = idx
articleId = focus_widget.attr_map[None] articleId = focus_widget.attr_map[None]
self.article = Render(*tui.cache.getArticle(articleId), tui.cache.getArticleLinks(articleId)) Utils.writeLog(tui.feedView.currentCategory)
self.article = Render(*tui.cache.getArticle(articleId, tui.feedView.currentCategory == "Favorites"),
tui.cache.getArticleLinks(articleId))
walker = urwid.SimpleListWalker([urwid.Text(self.article.firstPage)]) walker = urwid.SimpleListWalker([urwid.Text(self.article.firstPage)])
self.body = walker self.body = walker
self.setArticleTitle() self.setArticleTitle()
@ -269,7 +295,7 @@ class RightPane(urwid.ListBox):
self.isList = True self.isList = True
self.fill(tui.articles) self.fill(tui.articles)
focusFeed, idx = tui.feedView.get_focus() focusFeed, idx = tui.feedView.get_focus()
tui.rightBox.set_title(focusFeed.attr_map[None][1]) tui.rightBox.set_title(tui.feedView.processAttrMap(focusFeed.attr_map)[1])
self.set_focus(self.articlePosition) self.set_focus(self.articlePosition)
except BaseException: except BaseException:
pass pass
@ -336,7 +362,8 @@ class TUI(urwid.Frame):
def create(cls): def create(cls):
tui = cls() tui = cls()
palette = [("linebox", "dark blue", "black"), ("text", "dark cyan", "dark cyan"), palette = [("linebox", "bold", "dark cyan", "standout"), ("text", "dark cyan", "dark cyan"),
("favorite", "dark green", "black"),
('header', 'white', 'black'), ('reveal focus', 'black', 'dark cyan', 'standout')] ('header', 'white', 'black'), ('reveal focus', 'black', 'dark cyan', 'standout')]
loop = urwid.MainLoop( loop = urwid.MainLoop(
tui, tui,
@ -380,9 +407,13 @@ class TUI(urwid.Frame):
def initialize_panes(self): def initialize_panes(self):
try: try:
self.feedView.fill(self.cache.getCategories(self.show_read), True) self.feedView.fill(self.cache.getCategories(self.show_read), True)
try:
self.feedView.set_focus(1)
except BaseException:
pass
focus_widget, idx = self.feedView.get_focus() focus_widget, idx = self.feedView.get_focus()
item = focus_widget.attr_map[None][0] item = self.feedView.processAttrMap(focus_widget.attr_map)[0]
name = focus_widget.attr_map[None][1] name = self.feedView.processAttrMap(focus_widget.attr_map)[1]
self.articles = self.cache.getArticlesFromCategory(item, self.show_read) 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)
@ -412,7 +443,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 == "f": elif key == "S":
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),

@ -6,6 +6,7 @@ import operator
import math import math
import re import re
from Render import Article from Render import Article
import Utils
class Cache: class Cache:
@ -44,6 +45,15 @@ class Cache:
foreign key (origin) references feeds (id) foreign key (origin) references feeds (id)
) )
""" """
create_favorites = """create table if not exists favorites (
id text primary key,
title text not null,
timestamp integer,
date text,
content text,
url text
)
"""
create_links = """create table if not exists links ( create_links = """create table if not exists links (
id text, id text,
url text not null, url text not null,
@ -56,9 +66,10 @@ class Cache:
self.conn.cursor().execute(create_feeds) self.conn.cursor().execute(create_feeds)
self.conn.cursor().execute(create_articles) self.conn.cursor().execute(create_articles)
self.conn.cursor().execute(create_links) self.conn.cursor().execute(create_links)
self.conn.cursor().execute(create_favorites)
except Error as e: except Error as e:
print(e) Utils.writeLog(e)
def markStreamAsRead(self, streamId): def markStreamAsRead(self, streamId):
cur = self.conn.cursor() cur = self.conn.cursor()
@ -82,9 +93,13 @@ class Cache:
cur.execute("""update articles set is_read = 1 where category_id = ?""", (streamId,)) cur.execute("""update articles set is_read = 1 where category_id = ?""", (streamId,))
self.conn.commit() self.conn.commit()
def getArticle(self, id): def getArticle(self, id, is_fav):
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select title,content,url from articles where id = ?""", (id,)) Utils.writeLog(is_fav)
if is_fav:
cur.execute("""select title,content,url from favorites where id = ?""", (id,))
else:
cur.execute("""select title,content,url from articles where id = ?""", (id,))
return cur.fetchone() return cur.fetchone()
def toggleArticleStatus(self, id): def toggleArticleStatus(self, id):
@ -117,16 +132,22 @@ class Cache:
def getArticlesFromCategory(self, category_id, is_read): def getArticlesFromCategory(self, category_id, is_read):
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select * from articles where category_id = ? and is_read = ? order by timestamp desc""", (category_id, is_read,)) if category_id == "Favorites":
cur.execute("""select * 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,))
return cur.fetchall() return cur.fetchall()
def getCategories(self, show_read): 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()
statement = """select * from categories where id = 'Favorites'"""
cur.execute(statement) cur.execute(statement)
return cur.fetchall() favorites = cur.fetchone()
statement = """select * from categories where unread_count != 0 and id != 'Favorites' order by timestamp desc"""
if show_read == 1:
statement = """select * from categories where id != 'Favorites' order by timestamp desc"""
cur.execute(statement)
return [favorites, *cur.fetchall()]
def getFeeds(self, category_id, show_read): def getFeeds(self, category_id, show_read):
statement = """select * from feeds where category_id = ? and unread_count != 0 order by timestamp desc""" statement = """select * from feeds where category_id = ? and unread_count != 0 order by timestamp desc"""
@ -136,12 +157,13 @@ class Cache:
cur.execute(statement, (category_id,)) cur.execute(statement, (category_id,))
return cur.fetchall() return cur.fetchall()
def refresh(self): def refresh(self): # noqa
timestamps = {} timestamps = {}
cur = self.conn.cursor() cur = self.conn.cursor()
cur.execute("""select id, timestamp from categories""") cur.execute("""select id, timestamp from categories""")
for row in cur.fetchall(): for row in cur.fetchall():
timestamps[row[0]] = row[1] timestamps[row[0]] = row[1]
Utils.writeLog(timestamps)
self.api.refresh() self.api.refresh()
for item in self.api.unreadCounts.keys(): for item in self.api.unreadCounts.keys():
@ -161,14 +183,39 @@ class Cache:
{"id": item["id"], "name": item["title"], "count": data[0], "ts": data[1], "d": data[2], {"id": item["id"], "name": item["title"], "count": data[0], "ts": data[1], "d": data[2],
"c_id": item["categories"][0]["id"]}) "c_id": item["categories"][0]["id"]})
self.conn.commit() self.conn.commit()
yield "Fetching Favorites"
cur.execute("""select timestamp from categories where id = 'Favorites'""")
favoritesTimestampTuple = cur.fetchone()
if favoritesTimestampTuple is None:
cur.execute("""insert into categories(id,name,unread_count,timestamp,date) values('Favorites','Favorites',0,0,'')""")
self.conn.commit()
last_updated, last_updated_date, favorites = self.api.getFavorites()
cur.execute("""update categories set unread_count = :count, timestamp = :ts, date = :d where id = 'Favorites'""",
{"count": len(favorites), "ts": last_updated, "d": last_updated_date})
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)""",
{"id": favObj.id, "t": favObj.title, "ts": favObj.timestamp, "d": favObj.date,
"c": favObj.text, "u": favObj.url})
for link in favObj.links:
cur.execute("""insert or ignore into links(id,url) values(?,?)""", (favObj.id, link))
self.conn.commit()
cur.execute("""select c.id, c.name, c.unread_count, cur.execute("""select c.id, c.name, c.unread_count,
(select count(*) from articles a where a.category_id = c.id) as articles_num from categories c""") (select count(*) from articles a where a.category_id = c.id) as articles_num from categories c
where c.id != 'Favorites'""")
for row in cur.fetchall(): for row in cur.fetchall():
yield "Fetching category " + row[1] yield "Fetching category " + row[1]
try:
timestamp = str(math.floor(timestamps[row[0]] / 1000000))
except BaseException:
timestamp = 0
articles = self.api.articlesFromCategory( articles = self.api.articlesFromCategory(
row[0], row[0],
count=str(row[2]), count=str(row[2]),
timestamp=str(math.floor(timestamps[row[0]] / 1000000)), timestamp=timestamp,
number=row[3]) number=row[3])
for article in articles: for article in articles:
articleObj = Article(article) articleObj = Article(article)

Loading…
Cancel
Save