Refactored page initialization, content initialization, and loading.
This commit is contained in:
@@ -135,7 +135,7 @@ class SubmissionContent(BaseContent):
|
||||
def __init__(
|
||||
self,
|
||||
submission,
|
||||
loader=default_loader(),
|
||||
loader=default_loader,
|
||||
indent_size=2,
|
||||
max_indent_level=4):
|
||||
|
||||
@@ -143,26 +143,35 @@ class SubmissionContent(BaseContent):
|
||||
self.max_indent_level = max_indent_level
|
||||
self._loader = loader
|
||||
|
||||
self._submissin = submission
|
||||
self._submission_data = self.strip_praw_submission(submission)
|
||||
self.name = self._submission_data['permalink']
|
||||
with loader:
|
||||
with self._loader():
|
||||
comments = self.flatten_comments(submission.comments)
|
||||
self._comment_data = [self.strip_praw_comment(c) for c in comments]
|
||||
|
||||
@classmethod
|
||||
def from_url(
|
||||
cls,
|
||||
r,
|
||||
reddit,
|
||||
url,
|
||||
loader=default_loader(),
|
||||
loader=default_loader,
|
||||
indent_size=2,
|
||||
max_indent_level=4):
|
||||
|
||||
with loader:
|
||||
submission = r.get_submission(url)
|
||||
with loader():
|
||||
submission = reddit.get_submission(url)
|
||||
|
||||
return cls(submission, loader, indent_size, max_indent_level)
|
||||
|
||||
def reset(self):
|
||||
|
||||
self._submissin.refresh()
|
||||
self._submission_data = self.strip_praw_submission(submission)
|
||||
self.name = self._submission_data['permalink']
|
||||
comments = self.flatten_comments(submission.comments)
|
||||
self._comment_data = [self.strip_praw_comment(c) for c in comments]
|
||||
|
||||
def get(self, index, n_cols=70):
|
||||
"""
|
||||
Grab the `i`th submission, with the title field formatted to fit inside
|
||||
@@ -227,7 +236,7 @@ class SubmissionContent(BaseContent):
|
||||
|
||||
elif data['type'] == 'MoreComments':
|
||||
|
||||
with self._loader:
|
||||
with self._loader():
|
||||
comments = data['object'].comments()
|
||||
comments = self.flatten_comments(comments, root_level=data['level'])
|
||||
comment_data = [self.strip_praw_comment(c) for c in comments]
|
||||
@@ -249,23 +258,24 @@ class SubredditContent(BaseContent):
|
||||
list for repeat access.
|
||||
"""
|
||||
|
||||
def __init__(self, name, submission_generator, loader=default_loader()):
|
||||
def __init__(self, name, submissions, loader=default_loader):
|
||||
|
||||
self.name = name
|
||||
self._loader = loader
|
||||
self._submissions = submission_generator
|
||||
self._submissions = submissions
|
||||
self._submission_data = []
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, r, name, loader=default_loader()):
|
||||
def from_name(cls, reddit, name, loader=default_loader):
|
||||
|
||||
if name == 'front':
|
||||
return cls('Front Page', r.get_front_page(limit=None), loader)
|
||||
return cls('Front Page', reddit.get_front_page(limit=None), loader)
|
||||
|
||||
if name == 'all':
|
||||
sub = r.get_subreddit(name)
|
||||
sub = reddit.get_subreddit(name)
|
||||
else:
|
||||
sub = r.get_subreddit(name, fetch=True)
|
||||
with loader():
|
||||
sub = reddit.get_subreddit(name, fetch=True)
|
||||
|
||||
return cls('/r/'+sub.display_name, sub.get_hot(limit=None), loader)
|
||||
|
||||
@@ -281,7 +291,7 @@ class SubredditContent(BaseContent):
|
||||
while index >= len(self._submission_data):
|
||||
|
||||
try:
|
||||
with self._loader:
|
||||
with self._loader():
|
||||
submission = self._submissions.next()
|
||||
except StopIteration:
|
||||
raise IndexError
|
||||
|
||||
14
rtv/main.py
14
rtv/main.py
@@ -1,7 +1,7 @@
|
||||
import argparse
|
||||
import praw
|
||||
from utils import curses_session, LoadScreen
|
||||
from content import SubredditContent
|
||||
|
||||
from utils import curses_session
|
||||
from subreddit import SubredditPage
|
||||
|
||||
parser = argparse.ArgumentParser(description='Reddit Terminal Viewer')
|
||||
@@ -13,17 +13,15 @@ group.add_argument('-p', dest='password', help='reddit password')
|
||||
|
||||
def main(args):
|
||||
|
||||
r = praw.Reddit(user_agent='reddit terminal viewer v0.0')
|
||||
r.config.decode_html_entities = True
|
||||
reddit = praw.Reddit(user_agent='reddit terminal viewer v0.0')
|
||||
reddit.config.decode_html_entities = True
|
||||
|
||||
if args.username and args.password:
|
||||
r.login(args.username, args.password)
|
||||
reddit.login(args.username, args.password)
|
||||
|
||||
with curses_session() as stdscr:
|
||||
|
||||
loader = LoadScreen(stdscr)
|
||||
content = SubredditContent(r, subreddit=args.subreddit, loader=loader)
|
||||
page = SubredditPage(stdscr, content)
|
||||
page = SubredditPage(stdscr, reddit, args.subreddit)
|
||||
page.loop()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
18
rtv/page.py
18
rtv/page.py
@@ -79,14 +79,12 @@ class BasePage(object):
|
||||
|
||||
self.stdscr = stdscr
|
||||
self.content = content
|
||||
|
||||
self.nav = Navigator(self.content.get, **kwargs)
|
||||
|
||||
self._header_window = None
|
||||
self._content_window = None
|
||||
self._subwindows = None
|
||||
|
||||
def draw(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def move_cursor_up(self):
|
||||
self._move_cursor(-1)
|
||||
|
||||
@@ -106,12 +104,22 @@ class BasePage(object):
|
||||
continue
|
||||
self.stdscr.nodelay(0)
|
||||
|
||||
def draw(self):
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
self._header_window = self.stdscr.derwin(1, n_cols, 0, 0)
|
||||
self._content_window = self.stdscr.derwin(1, 0)
|
||||
|
||||
self.draw_header()
|
||||
self.draw_content()
|
||||
self.add_cursor()
|
||||
|
||||
def draw_header(self):
|
||||
|
||||
n_rows, n_cols = self._header_window.getmaxyx()
|
||||
|
||||
self._header_window.erase()
|
||||
self._header_window.addnstr(0, 0, self.content.display_name, n_cols-1)
|
||||
self._header_window.addnstr(0, 0, self.content.name, n_cols-1)
|
||||
|
||||
def draw_content(self):
|
||||
"""
|
||||
|
||||
@@ -1,18 +1,25 @@
|
||||
import praw
|
||||
import curses
|
||||
import sys
|
||||
|
||||
from content import SubmissionContent
|
||||
from page import BasePage
|
||||
from utils import curses_session
|
||||
from utils import LoadScreen
|
||||
|
||||
class SubmissionPage(BasePage):
|
||||
|
||||
def __init__(self, stdscr, content):
|
||||
def __init__(self, stdscr, reddit, url=None, submission=None):
|
||||
|
||||
self.loader = LoadScreen(stdscr)
|
||||
|
||||
if url is not None:
|
||||
content = SubmissionContent.from_url(reddit, url, self.loader)
|
||||
elif submission is not None:
|
||||
content = SubmissionContent(submission, self.loader)
|
||||
else:
|
||||
raise ValueError('Must specify url or submission')
|
||||
|
||||
page_index, cursor_index = -1, 1
|
||||
super(SubmissionPage, self).__init__(
|
||||
stdscr, content,
|
||||
page_index=page_index, cursor_index=cursor_index)
|
||||
stdscr, content, page_index=-1, cursor_index=1)
|
||||
|
||||
def loop(self):
|
||||
|
||||
@@ -61,16 +68,6 @@ class SubmissionPage(BasePage):
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
|
||||
def draw(self):
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
self._header_window = self.stdscr.derwin(1, n_cols, 0, 0)
|
||||
self._content_window = self.stdscr.derwin(1, 0)
|
||||
|
||||
self.draw_header()
|
||||
self.draw_content()
|
||||
self.add_cursor()
|
||||
|
||||
def draw_item(self, win, data, inverted=False):
|
||||
|
||||
if data['type'] == 'MoreComments':
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
import praw
|
||||
import textwrap
|
||||
import curses
|
||||
import sys
|
||||
|
||||
from page import BasePage
|
||||
from submission import SubmissionPage
|
||||
from content import SubmissionContent
|
||||
from utils import curses_session, text_input
|
||||
from content import SubredditContent
|
||||
from utils import LoadScreen, text_input
|
||||
|
||||
class SubredditPage(BasePage):
|
||||
|
||||
def __init__(self, stdscr, reddit, name):
|
||||
|
||||
self.reddit = reddit
|
||||
self.name = name
|
||||
self.loader = LoadScreen(stdscr)
|
||||
|
||||
content = SubredditContent.from_name(reddit, name, self.loader)
|
||||
super(SubredditPage, self).__init__(stdscr, content)
|
||||
|
||||
def loop(self):
|
||||
|
||||
self.draw()
|
||||
@@ -47,11 +54,12 @@ class SubredditPage(BasePage):
|
||||
else:
|
||||
curses.beep()
|
||||
|
||||
def refresh_content(self, subreddit=None):
|
||||
def refresh_content(self, name=None):
|
||||
|
||||
self.nav.page_index, self.nav.cursor_index = 0, 0
|
||||
self.nav.inverted = False
|
||||
self.content.reset(subreddit=subreddit)
|
||||
self.name = name if name else self.name
|
||||
self.content = SubredditContent.from_name(self.reddit, self.name, self.loader)
|
||||
self.stdscr.clear()
|
||||
self.draw()
|
||||
|
||||
@@ -67,26 +75,15 @@ class SubredditPage(BasePage):
|
||||
if out is None:
|
||||
self.draw()
|
||||
else:
|
||||
self.refresh_content(subreddit=out)
|
||||
self.refresh_content(name=out)
|
||||
|
||||
def open_submission(self):
|
||||
"Select the current submission to view posts"
|
||||
|
||||
submission = self.content.get(self.nav.absolute_index)['object']
|
||||
content = SubmissionContent(submission, loader=self.content.loader)
|
||||
page = SubmissionPage(self.stdscr, content)
|
||||
page = SubmissionPage(self.stdscr, self.reddit, submission=submission)
|
||||
page.loop()
|
||||
|
||||
def draw(self):
|
||||
|
||||
n_rows, n_cols = self.stdscr.getmaxyx()
|
||||
self._header_window = self.stdscr.derwin(1, n_cols, 0, 0)
|
||||
self._content_window = self.stdscr.derwin(1, 0)
|
||||
|
||||
self.draw_header()
|
||||
self.draw_content()
|
||||
self.add_cursor()
|
||||
|
||||
@staticmethod
|
||||
def draw_item(win, data, inverted=False):
|
||||
|
||||
|
||||
37
rtv/utils.py
37
rtv/utils.py
@@ -42,26 +42,27 @@ def text_input(window):
|
||||
|
||||
class LoadScreen(object):
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
stdscr,
|
||||
message='Downloading',
|
||||
trail='...',
|
||||
delay=0.5,
|
||||
interval=0.4):
|
||||
def __init__(self, stdscr):
|
||||
|
||||
self._stdscr = stdscr
|
||||
self.message = message
|
||||
self.delay = delay
|
||||
self.interval=interval
|
||||
self.trail = trail
|
||||
|
||||
self._args = None
|
||||
self._animator = None
|
||||
self._is_running = None
|
||||
|
||||
def __call__(
|
||||
self,
|
||||
delay=0.5,
|
||||
interval=0.4,
|
||||
message='Downloading',
|
||||
trail='...'):
|
||||
|
||||
self._args = (delay, interval, message, trail)
|
||||
return self
|
||||
|
||||
def __enter__(self):
|
||||
|
||||
self._animator = threading.Thread(target=self.animate)
|
||||
self._animator = threading.Thread(target=self.animate, args=self._args)
|
||||
self._animator.daemon = True
|
||||
|
||||
self._is_running = True
|
||||
@@ -72,23 +73,23 @@ class LoadScreen(object):
|
||||
self._is_running = False
|
||||
self._animator.join()
|
||||
|
||||
def animate(self):
|
||||
def animate(self, delay, interval, message, trail):
|
||||
|
||||
# Delay before starting animation to avoid wasting resources if the
|
||||
# wait time is very short
|
||||
start = time.time()
|
||||
while (time.time() - start) < self.delay:
|
||||
while (time.time() - start) < delay:
|
||||
if not self._is_running:
|
||||
return
|
||||
|
||||
message_len = len(self.message) + len(self.trail)
|
||||
message_len = len(message) + len(trail)
|
||||
n_rows, n_cols = self._stdscr.getmaxyx()
|
||||
s_row = (n_rows - 2) / 2
|
||||
s_col = (n_cols - message_len - 1) / 2
|
||||
window = self._stdscr.derwin(3, message_len+2, s_row, s_col)
|
||||
|
||||
while True:
|
||||
for i in xrange(len(self.trail)+1):
|
||||
for i in xrange(len(trail)+1):
|
||||
|
||||
if not self._is_running:
|
||||
# TODO: figure out why this isn't removing the screen
|
||||
@@ -98,9 +99,9 @@ class LoadScreen(object):
|
||||
|
||||
window.erase()
|
||||
window.border()
|
||||
window.addstr(1, 1, self.message + self.trail[:i])
|
||||
window.addstr(1, 1, message + trail[:i])
|
||||
window.refresh()
|
||||
time.sleep(self.interval)
|
||||
time.sleep(interval)
|
||||
|
||||
|
||||
@contextmanager
|
||||
|
||||
Reference in New Issue
Block a user