Added text input for subreddit prompt, added escape key support.

This commit is contained in:
Michael Lazar
2015-01-29 19:53:14 -08:00
parent bc40cf4fc7
commit a6ab60514c
5 changed files with 84 additions and 14 deletions

View File

@@ -16,7 +16,6 @@ class BaseContent(object):
data['object'] = comment data['object'] = comment
data['level'] = comment.nested_level data['level'] = comment.nested_level
if isinstance(comment, praw.objects.MoreComments): if isinstance(comment, praw.objects.MoreComments):
data['type'] = 'MoreComments' data['type'] = 'MoreComments'
data['body'] = 'More comments [{}]'.format(comment.count) data['body'] = 'More comments [{}]'.format(comment.count)
@@ -147,8 +146,9 @@ class SubredditContent(BaseContent):
self._submissions = self.r.get_front_page(limit=None) self._submissions = self.r.get_front_page(limit=None)
self.display_name = 'Front Page' self.display_name = 'Front Page'
else: else:
self._submissions = self.r.get_subreddit(self.subreddit, limit=None) sub = self.r.get_subreddit(self.subreddit)
self.display_name = self._submissions.display_name self._submissions = sub.get_hot()
self.display_name = '/r/' + self.subreddit
class SubmissionContent(BaseContent): class SubmissionContent(BaseContent):

View File

@@ -37,7 +37,7 @@ class SubmissionViewer(BaseViewer):
self.draw() self.draw()
# Go back # Go back
elif cmd in (ord('b'), curses.KEY_LEFT): elif cmd in (ord('b'), 27, curses.KEY_LEFT):
break break
# Quit # Quit
@@ -47,6 +47,13 @@ class SubmissionViewer(BaseViewer):
else: else:
curses.beep() curses.beep()
def refresh_content(self):
self.add_loading()
self.content.reset()
self.stdscr.clear()
self.draw()
def draw(self): def draw(self):
n_rows, n_cols = self.stdscr.getmaxyx() n_rows, n_cols = self.stdscr.getmaxyx()

View File

@@ -6,7 +6,7 @@ import sys
from content_generators import SubredditContent, SubmissionContent from content_generators import SubredditContent, SubmissionContent
from submission_viewer import SubmissionViewer from submission_viewer import SubmissionViewer
from viewer import BaseViewer from viewer import BaseViewer
from utils import curses_session from utils import curses_session, text_input
class SubredditViewer(BaseViewer): class SubredditViewer(BaseViewer):
@@ -31,7 +31,7 @@ class SubredditViewer(BaseViewer):
# Enter edit mode to change subreddit # Enter edit mode to change subreddit
elif cmd == ord('/'): elif cmd == ord('/'):
pass self.prompt_subreddit()
# Refresh page # Refresh page
elif cmd in (curses.KEY_F5, ord('r')): elif cmd in (curses.KEY_F5, ord('r')):
@@ -47,6 +47,29 @@ class SubredditViewer(BaseViewer):
else: else:
curses.beep() curses.beep()
def refresh_content(self, subreddit=None):
self.add_loading()
self.nav.page_index, self.nav.cursor_index = 0, 0
self.nav.inverted = False
self.content.reset(subreddit=subreddit)
self.stdscr.clear()
self.draw()
def prompt_subreddit(self):
prompt = 'Enter Subreddit: /r/'
n_rows, n_cols = self.stdscr.getmaxyx()
self.stdscr.addstr(n_rows-1, 0, prompt)
self.stdscr.refresh()
window = self.stdscr.derwin(n_rows-1, len(prompt))
out = text_input(window)
if out is None:
self.draw()
else:
self.refresh_content(subreddit=out)
def open_submission(self): def open_submission(self):
"Select the current submission to view posts" "Select the current submission to view posts"

View File

@@ -1,7 +1,12 @@
from datetime import datetime, timedelta from datetime import datetime, timedelta
from contextlib import contextmanager from contextlib import contextmanager
import os
import curses import curses
from curses import textpad
class EscapePressed(Exception):
pass
def clean(unicode_string): def clean(unicode_string):
""" """
@@ -46,10 +51,51 @@ def humanize_timestamp(utc_timestamp, verbose=False):
years = months / 12 years = months / 12
return ('%d years ago' % years) if verbose else ('%dyr' % years) return ('%d years ago' % years) if verbose else ('%dyr' % years)
def validate(ch):
"Filters characters for special key sequences"
if ch == 27:
raise EscapePressed
return ch
def text_input(window):
"""
Transform a window into a text box that will accept user input and loop
until an escape sequence is entered.
If enter is pressed, return the input text as a string.
If escape is pressed, return None.
"""
window.clear()
curses.curs_set(2)
textbox = textpad.Textbox(window, insert_mode=True)
# Wrapping in an exception block so that we can distinguish when the user
# hits the return character from when the user tries to back out of the
# input.
try:
out = textbox.edit(validate=validate)
out = out.strip()
except EscapePressed:
out = None
curses.curs_set(0)
return out
@contextmanager @contextmanager
def curses_session(): def curses_session():
try: try:
# Curses must wait for some time after the Escape key is pressed to see
# check if it is the beginning of an escape sequence indicating a
# special key. The default wait time is 1 second, which means that
# getch() will not return the escape key (ord(27)), until a full second
# after it has been pressed. Turn this down to 25 ms, which is close to
# what VIM uses.
# http://stackoverflow.com/questions/27372068
os.environ['ESCDELAY'] = '25'
# Initialize curses # Initialize curses
stdscr = curses.initscr() stdscr = curses.initscr()

View File

@@ -83,6 +83,7 @@ class BaseViewer(object):
self.nav = Navigator(self.content.get, **kwargs) self.nav = Navigator(self.content.get, **kwargs)
self._subwindows = None self._subwindows = None
self.add_loading()
def draw(self): def draw(self):
raise NotImplementedError raise NotImplementedError
@@ -106,12 +107,6 @@ class BaseViewer(object):
continue continue
self.stdscr.nodelay(0) self.stdscr.nodelay(0)
def refresh_content(self):
self.add_loading()
self.content.reset()
self.stdscr.clear()
self.draw()
def add_loading(self): def add_loading(self):
"Draw a `loading` popup dialog in the center of the screen" "Draw a `loading` popup dialog in the center of the screen"
@@ -132,7 +127,6 @@ class BaseViewer(object):
self._header_window.erase() 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.display_name, n_cols-1)
self._header_window.refresh()
def draw_content(self): def draw_content(self):
""" """