Added color! Added setup.py

This commit is contained in:
Michael Lazar
2015-02-02 21:43:06 -08:00
parent d01393e4b4
commit c9c38dc264
14 changed files with 108 additions and 1739 deletions

View File

@@ -0,0 +1 @@
from main import main

View File

@@ -103,7 +103,7 @@ class BaseContent(object):
if isinstance(comment, praw.objects.MoreComments):
data['type'] = 'MoreComments'
data['count'] = comment.count
data['body'] = 'More comments [{}]'.format(comment.count)
data['body'] = 'More comments'.format(comment.count)
else:
data['type'] = 'Comment'
data['body'] = clean(comment.body)
@@ -112,6 +112,10 @@ class BaseContent(object):
data['author'] = (clean(comment.author.name) if
getattr(comment, 'author') else '[deleted]')
sub_author = (clean(comment.submission.author.name) if
getattr(comment.submission, 'author') else '[deleted]')
data['is_author'] = (data['author'] == sub_author)
return data
@staticmethod
@@ -157,7 +161,7 @@ class SubmissionContent(BaseContent):
self.max_indent_level = max_indent_level
self._loader = loader
self._submissin = submission
self._submission = submission
self._submission_data = self.strip_praw_submission(submission)
self.name = self._submission_data['permalink']
with self._loader():
@@ -184,7 +188,7 @@ class SubmissionContent(BaseContent):
def reset(self):
self._submissin.refresh()
self._submission.refresh()
self._submission_data = self.strip_praw_submission(submission)
self.name = self._submission_data['permalink']
comments = self.flatten_comments(submission.comments)

View File

@@ -10,12 +10,14 @@ from submission import SubmissionPage
parser = argparse.ArgumentParser(description='Reddit Terminal Viewer')
parser.add_argument('-s', dest='subreddit', default='front', help='subreddit name')
parser.add_argument('-l', dest='link', help='full link to a submission')
group = parser.add_argument_group('authentication (optional)')
group.add_argument('-u', dest='username', help='reddit username')
group.add_argument('-p', dest='password', help='reddit password')
group.add_argument('--debug', action='store_true')
def main(args):
def main():
args = parser.parse_args()
try:
reddit = praw.Reddit(user_agent='reddit terminal viewer v0.0')
@@ -46,13 +48,6 @@ def main(args):
except SubredditNameError as e:
print 'Could not reach subreddit: {}'.format(e.name)
# except Exception:
# if not args.debug:
# print 'Unhandled exception'
# else:
# raise
if __name__ == '__main__':
args = parser.parse_args()
main(args)
main()

View File

@@ -1,5 +1,7 @@
import curses
from utils import Color
class Navigator(object):
"""
Handles math behind cursor movement and screen paging.
@@ -139,7 +141,9 @@ class BasePage(object):
n_rows, n_cols = self._header_window.getmaxyx()
self._header_window.erase()
self._header_window.addnstr(0, 0, self.content.name, n_cols-1)
attr = curses.A_REVERSE | curses.A_BOLD | Color.RED
self._header_window.addnstr(0, 0, self.content.name, n_cols-1, attr)
self._header_window.refresh()
def _draw_content(self):
"""
@@ -164,8 +168,8 @@ class BasePage(object):
start = current_row - window_rows if inverted else current_row
subwindow = self._content_window.derwin(
window_rows, window_cols, start, data['offset'])
self.draw_item(subwindow, data, inverted)
self._subwindows.append(subwindow)
attr = self.draw_item(subwindow, data, inverted)
self._subwindows.append((subwindow, attr))
available_rows -= (window_rows + 1) # Add one for the blank line
current_row += step * (window_rows + 1)
if available_rows <= 0:
@@ -188,13 +192,16 @@ class BasePage(object):
self.add_cursor()
def _edit_cursor(self, attribute):
def _edit_cursor(self, attribute=None):
# Don't allow the cursor to go below page index 0
if self.nav.absolute_index < 0:
return
window = self._subwindows[self.nav.cursor_index]
# TODO: attach attr to data[attr] or something
window, attr = self._subwindows[self.nav.cursor_index]
if attr is not None:
attribute |= attr
n_rows, _ = window.getmaxyx()
for row in xrange(n_rows):

View File

@@ -3,7 +3,7 @@ import sys
from content import SubmissionContent
from page import BasePage
from utils import LoadScreen
from utils import LoadScreen, Color
class SubmissionPage(BasePage):
@@ -70,51 +70,64 @@ class SubmissionPage(BasePage):
def draw_item(self, win, data, inverted=False):
if data['type'] == 'MoreComments':
self.draw_more_comments(win, data)
return self.draw_more_comments(win, data)
elif data['type'] == 'HiddenComment':
self.draw_more_comments(win, data)
return self.draw_more_comments(win, data)
elif data['type'] == 'Comment':
self.draw_comment(win, data, inverted=inverted)
return self.draw_comment(win, data, inverted=inverted)
else:
self.draw_submission(win, data)
return self.draw_submission(win, data)
@staticmethod
def draw_comment(win, data, inverted=False):
n_rows, n_cols = win.getmaxyx()
n_cols -= 2
n_cols -= 1
# Handle the case where the window is not large enough to fit the data.
valid_rows = range(0, n_rows)
offset = 0 if not inverted else -(data['n_rows'] - n_rows)
row = offset
text = '{} {} {}'.format(data['author'], data['score'], data['created'])
if row in valid_rows:
win.addnstr(row, 1, text, n_cols)
text = '{author}'.format(**data)
attr = curses.A_BOLD
attr |= (Color.BLUE if not data['is_author'] else Color.GREEN)
win.addnstr(row, 1, text, n_cols-1, attr)
text = ' {score} {created}'.format(**data)
win.addnstr(text, n_cols - win.getyx()[1])
n_body = len(data['split_body'])
for row, text in enumerate(data['split_body'], start=offset+1):
if row in valid_rows:
win.addnstr(row, 1, text, n_cols)
win.addnstr(row, 1, text, n_cols-1)
# Vertical line, unfortunately vline() doesn't support custom color so
# we have to build it one chr at a time.
attr = Color.get_level(data['level'])
for y in xrange(n_rows):
win.addch(y, 0, curses.ACS_VLINE)
win.addch(y, 0, curses.ACS_VLINE, attr)
return attr | curses.ACS_VLINE
@staticmethod
def draw_more_comments(win, data):
n_rows, n_cols = win.getmaxyx()
n_cols -= 2
win.addnstr(0, 1, data['body'], n_cols)
n_cols -= 1
win.addnstr(0, 1, data['body'], n_cols-1)
text = ' [{count}]'.format(**data)
attr = curses.A_BOLD
win.addnstr(text, n_cols - win.getyx()[1], attr)
attr = Color.get_level(data['level'])
for y in xrange(n_rows):
win.addch(y, 0, curses.ACS_VLINE)
win.addch(y, 0, curses.ACS_VLINE, attr)
return attr | curses.ACS_VLINE
@staticmethod
def draw_submission(win, data):

View File

@@ -5,7 +5,7 @@ from errors import SubredditNameError
from page import BasePage
from submission import SubmissionPage
from content import SubredditContent
from utils import LoadScreen, text_input, display_message
from utils import LoadScreen, text_input, display_message, Color
class SubredditPage(BasePage):
@@ -108,11 +108,13 @@ class SubredditPage(BasePage):
n_title = len(data['split_title'])
for row, text in enumerate(data['split_title'], start=offset):
if row in valid_rows:
win.addstr(row, 1, text)
attr = curses.A_BOLD
win.addstr(row, 1, text, attr)
row = n_title + offset
if row in valid_rows:
win.addnstr(row, 1, '{url}'.format(**data), n_cols)
attr = curses.A_UNDERLINE | Color.BLUE
win.addnstr(row, 1, '{url}'.format(**data), n_cols, attr)
row = n_title + offset + 1
if row in valid_rows:

View File

@@ -7,6 +7,39 @@ from contextlib import contextmanager
from errors import EscapePressed
class Color(object):
COLORS = {
'RED': (curses.COLOR_RED, -1),
'GREEN': (curses.COLOR_GREEN, -1),
'YELLOW': (curses.COLOR_YELLOW, -1),
'BLUE': (curses.COLOR_BLUE, -1),
'MAGENTA': (curses.COLOR_MAGENTA, -1),
'CYAN': (curses.COLOR_CYAN, -1),
}
@classmethod
def get_level(cls, level):
levels = [cls.MAGENTA, cls.CYAN, cls.GREEN, cls.YELLOW]
return levels[level % len(levels)]
@classmethod
def init(cls):
"""
Initialize color pairs inside of curses using the default background.
This should be called once during the curses initial setup. Afterwards,
curses color pairs can be accessed directly through class attributes.
"""
# Assign the terminal's default (background) color to code -1
curses.use_default_colors()
for index, (attr, code) in enumerate(cls.COLORS.items(), start=1):
curses.init_pair(index, code[0], code[1])
setattr(cls, attr, curses.color_pair(index))
def text_input(window):
"""
Transform a window into a text box that will accept user input and loop
@@ -156,23 +189,14 @@ def curses_session():
# module -- the error return from C start_color() is ignorable.
try:
curses.start_color()
# Assign the terminal's default (background) color to code -1
curses.use_default_colors()
except:
pass
else:
Color.init()
# Hide blinking cursor
curses.curs_set(0)
# Initialize color pairs - colored text on the default background
curses.init_pair(1, curses.COLOR_RED, -1)
curses.init_pair(2, curses.COLOR_GREEN, -1)
curses.init_pair(3, curses.COLOR_YELLOW, -1)
curses.init_pair(4, curses.COLOR_BLUE, -1)
curses.init_pair(5, curses.COLOR_MAGENTA, -1)
curses.init_pair(6, curses.COLOR_CYAN, -1)
yield stdscr
finally: