diff --git a/.gitignore b/.gitignore index 5b334d1..16c17bf 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ venv/ .env config.yml __pycache__ +debug.log diff --git a/API.py b/API.py index 82f1133..5a2e198 100644 --- a/API.py +++ b/API.py @@ -49,4 +49,4 @@ class Fetcher: def fetch(self): for category in self.categories: yield "Fetching category " + category["name"] - self.articlesFromCategory(category["name"], str(self.unreadCounts[category["id"]][0])) + self.articlesFromCategory(category["id"], str(self.unreadCounts[category["id"]][0])) diff --git a/App.py b/App.py index 390521f..1231b38 100644 --- a/App.py +++ b/App.py @@ -2,6 +2,7 @@ import urwid import yaml import asyncio import warnings +import os from concurrent.futures import ThreadPoolExecutor from API import Fetcher from Render import Article @@ -154,7 +155,7 @@ class RightPane(urwid.ListBox): tui.rightBox.set_title(self.article.title + " (" + str(self.article.currentPageNumber) + "/" + str(self.article.numberOfPages) + ")") - def keypress(self, size, key): + def keypress(self, size, key): #noqa if key in ("j", "down"): if not self.isList: walker = urwid.SimpleListWalker([urwid.Text(self.article.scrollDown())]) @@ -196,10 +197,52 @@ class RightPane(urwid.ListBox): tui.rightBox.set_title(focusFeed.attr_map[None][1]) self.set_focus(self.articlePosition) return + elif key == "m": + if self.isList is False and len(self.article.links) > 0: + top = Links(self.article.links) + tui.createOverlay(urwid.LineBox(top), len(self.article.links)+2) + return return super().keypress(size, key) +class Links(urwid.ListBox): + def __init__(self, links): + super().__init__(self) + items = [urwid.AttrMap(urwid.Columns([urwid.Text(link)]), (link), "reveal focus") for link in links] + walker = urwid.SimpleFocusListWalker(items) + self.body = walker + + def parseLink(self, link): + ext = link.split(".")[-1] + if ext.lower() in ("jpg", "jpeg", "gif", "png", "tif", "tiff"): + os.popen('feh {link}'.format(link=link)) + else: + os.popen('firefox -new-tab {link}'.format(link=link)) + + def keypress(self, size, key): + if key in ("j", "down"): + focus_widget, idx = self.get_focus() + item_size = len(self.body) + if idx < item_size - 1: + idx = idx + 1 + self.set_focus(idx) + return + elif key in ("k", "up"): + focus_widget, idx = self.get_focus() + if idx > 0: + idx = idx - 1 + self.set_focus(idx) + return + elif key in ("l", "right"): + focus_widget, idx = self.get_focus() + link = focus_widget.attr_map[None] + self.parseLink(link) + elif key == "q": + tui.destroyOverlay() + return + + class TUI(urwid.Frame): @classmethod @@ -225,6 +268,7 @@ class TUI(urwid.Frame): URL = config["server"]["URL"] token = config["server"]["token"] + self.overlay = None self.fetcher = Fetcher(URL, token) self.leftPaneItems = {} @@ -237,22 +281,12 @@ class TUI(urwid.Frame): self.rightBox = urwid.LineBox(self.articleView, title="Articles") self.views = urwid.Columns( [(56, self.leftBox), self.rightBox]) - self.status = urwid.Text("") - self.footer = urwid.ListBox([self.status]) - self.container = urwid.Pile([self.views, (1, self.footer)]) + self.container = urwid.Pile([self.views]) self.body = self.container self.articles = [] super().__init__(self.body) - def fetchAll(self): - articles = tui.fetcher.fetch() - for text in articles: - self.status.set_text(text) - tui.loop.entering_idle() - self.status.set_text("") - self.loop.event_loop.remove_alarm(self.handle) - def run(self): focus_widget, idx = self.feedView.get_focus() item = focus_widget.attr_map[None][0] @@ -264,6 +298,16 @@ class TUI(urwid.Frame): self.loop.run() self.executor.shutdown(wait=False) + def createOverlay(self, element, h): + self.overlay = urwid.Overlay( + element, + self.body, align="center", width=("relative", 50), valign="middle", height=h) + self.body = self.overlay + + def destroyOverlay(self): + self.body = self.overlay.bottom_w + del(self.overlay) + def unhandled_input(self, key): if key == "tab": self.activePane = not self.activePane @@ -273,11 +317,16 @@ class TUI(urwid.Frame): elif key == "q": raise urwid.ExitMainLoop() elif key == "r": - 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] - self.articleView.fill(self.articles) + olb = urwid.ListBox(urwid.SimpleListWalker([urwid.Text("")])) + overlay = urwid.Overlay( + urwid.LineBox(olb), + self.body, align="center", width=("relative", 50), valign="middle", height=3) + self.body = overlay + articles = tui.fetcher.fetch() + for text in articles: + olb.body = urwid.SimpleListWalker([urwid.Text(text)]) + tui.loop.entering_idle() + self.body = overlay.bottom_w tui = TUI.create() diff --git a/Render.py b/Render.py index 51e5c9d..4000df3 100644 --- a/Render.py +++ b/Render.py @@ -1,17 +1,35 @@ from inscriptis import get_text import os import Utils +import html.parser + + +class LinkParser(html.parser.HTMLParser): + def reset(self): + super().reset() + self.links = [] + + def handle_starttag(self, tag, attrs): + if tag == 'a': + for (name, value) in attrs: + if name == 'href': + self.links.append(value) class Article: def __init__(self, articleObj): - self.text = get_text(articleObj["summary"]["content"]) + content = articleObj["summary"]["content"] + parser = LinkParser() + for line in content: + parser.feed(line) + self.links = parser.links + Utils.writeLog(self.links) + self.text = get_text(content) self.title = articleObj["title"] self.date = Utils.timestampToDate(articleObj["timestampUsec"]) self.currentPageNumber = 1 terminal_width, terminal_height = os.get_terminal_size() terminal_width -= 76 - terminal_height -= 1 start_of_chunk = 0 end_of_chunk = 0 rows_passed = 0