Working on adding pager.

This commit is contained in:
Michael Lazar
2016-03-03 18:28:14 -08:00
parent 201ef8e6df
commit ffbd6c1dfd
5 changed files with 83 additions and 6 deletions

View File

@@ -104,10 +104,11 @@ INBOX = i
REFRESH = r, <KEY_F5> REFRESH = r, <KEY_F5>
; Submission page ; Submission page
SUBMISSION_TOGGLE_COMMENT = l, 0x20, <KEY_RIGHT> SUBMISSION_TOGGLE_COMMENT = 0x20
SUBMISSION_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER> SUBMISSION_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>
SUBMISSION_POST = c SUBMISSION_POST = c
SUBMISSION_EXIT = h, <KEY_LEFT> SUBMISSION_EXIT = h, <KEY_LEFT>
SUBMISSION_OPEN_IN_PAGER = l, <KEY_RIGHT>
; Subreddit page ; Subreddit page
SUBREDDIT_SEARCH = f SUBREDDIT_SEARCH = f

View File

@@ -69,6 +69,19 @@ class SubmissionPage(Page):
else: else:
self.term.flash() self.term.flash()
@SubmissionController.register(Command('SUBMISSION_OPEN_IN_PAGER'))
def open_pager(self):
"Open the selected item with the system's pager"
data = self.content.get(self.nav.absolute_index)
if data['type'] == 'Submission':
text = '\n\n'.join((data['permalink'], data['text']))
self.term.open_pager(text)
elif data['type'] == 'Comment':
text = '\n\n'.join((data['permalink'], data['body']))
self.term.open_pager(text)
else:
self.term.flash()
@SubmissionController.register(Command('SUBMISSION_POST')) @SubmissionController.register(Command('SUBMISSION_POST'))
@logged_in @logged_in
def add_comment(self): def add_comment(self):

View File

@@ -35,6 +35,7 @@ class Terminal(object):
# ASCII code # ASCII code
ESCAPE = 27 ESCAPE = 27
RETURN = 10 RETURN = 10
SPACE = 32
def __init__(self, stdscr, ascii=False): def __init__(self, stdscr, ascii=False):
@@ -356,6 +357,26 @@ class Terminal(object):
with self.suspend(): with self.suspend():
webbrowser.open_new_tab(url) webbrowser.open_new_tab(url)
def open_pager(self, data):
"""
View a long block of text using the system's default pager.
The data string will be piped directly to the pager.
"""
pager = os.getenv('PAGER') or 'less'
try:
with self.suspend():
p = subprocess.Popen([pager], stdin=subprocess.PIPE)
p.stdin.write(self.clean(data))
p.stdin.close()
try:
p.wait()
except KeyboardInterrupt:
p.terminate()
except OSError:
self.show_notification('Could not open pager %s' % pager)
def open_editor(self, data=''): def open_editor(self, data=''):
""" """
Open a temporary file using the system's default editor. Open a temporary file using the system's default editor.
@@ -366,16 +387,19 @@ class Terminal(object):
""" """
with NamedTemporaryFile(prefix='rtv-', suffix='.txt', mode='wb') as fp: with NamedTemporaryFile(prefix='rtv-', suffix='.txt', mode='wb') as fp:
fp.write(codecs.encode(data, 'utf-8')) fp.write(self.clean(data))
fp.flush() fp.flush()
editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano' editor = os.getenv('RTV_EDITOR') or os.getenv('EDITOR') or 'nano'
try: try:
with self.suspend(): with self.suspend():
subprocess.Popen([editor, fp.name]).wait() p = subprocess.Popen([editor, fp.name])
try:
p.wait()
except KeyboardInterrupt:
p.terminate()
except OSError: except OSError:
raise exceptions.ProgramError( self.show_notification('Could not open file with %s' % editor)
'Could not open file with %s' % editor)
# Open a second file object to read. This appears to be necessary # Open a second file object to read. This appears to be necessary
# in order to read the changes made by some editors (gedit). w+ # in order to read the changes made by some editors (gedit). w+

View File

@@ -94,6 +94,23 @@ def test_submission_open(submission_page, terminal):
assert terminal.open_browser.called assert terminal.open_browser.called
def test_submission_pager(submission_page, terminal):
# View a submission with the pager
with mock.patch.object(terminal, 'open_pager'):
submission_page.controller.trigger(terminal.RETURN)
assert terminal.open_browser.called
# Move down to the first comment
with mock.patch.object(submission_page, 'clear_input_queue'):
submission_page.controller.trigger('j')
# View a comment with the pager
with mock.patch.object(terminal, 'open_pager'):
submission_page.controller.trigger(terminal.RETURN)
assert terminal.open_browser.called
def test_submission_vote(submission_page, refresh_token): def test_submission_vote(submission_page, refresh_token):
# Log in # Log in

View File

@@ -308,4 +308,26 @@ def test_open_browser(terminal):
terminal.open_browser(url) terminal.open_browser(url)
open_new_tab.assert_called_with(url) open_new_tab.assert_called_with(url)
assert curses.endwin.called assert curses.endwin.called
assert curses.doupdate.called assert curses.doupdate.called
def test_open_pager(terminal, stdscr):
data = "Hello World!"
def side_effect(*_, stdin=None):
assert stdin is not None
raise OSError
with mock.patch('subprocess.Popen', autospec=True) as Popen, \
mock.patch.dict('os.environ', {'PAGER': 'fake'}):
terminal.open_pager(data)
assert Popen.called
assert not stdscr.addstr.called
# Raise an OS error
Popen.side_effect = side_effect
terminal.open_pager(data)
message = 'Could not open pager fake'.encode('ascii')
assert stdscr.addstr.called_with(0, 0, message)