Added urlview keybinding

1.  A shortcut of 'b' was used as the default binding for passing
comment body text to urlview (this is similar to the default of C-b in
the 'mutt' text email client)
2.  The `comment_urlview` SubmissionController function was added to
recieve the SUBMISSION_OPEN_IN_URLVIEWER keypress request.
3.  The `open_urlview` terminal function was added to handle the urlview
request.  It passes the comment body data to urlview via a Popen
process.
4.  A test case was added to ensure this new code path is executed
5.  Small formatting changes, mostly line length
This commit is contained in:
Matt Smith
2016-07-04 22:42:30 -07:00
committed by Matt Smith
parent fb837bafc7
commit 749ad11171
9 changed files with 343 additions and 9 deletions

View File

@@ -60,3 +60,4 @@ In submission mode you can view the self text for a submission and browse commen
:``l`` or ``►``: Open the selected comment in a new window :``l`` or ``►``: Open the selected comment in a new window
:``o`` or ``ENTER``: Open the comment permalink with your web browser :``o`` or ``ENTER``: Open the comment permalink with your web browser
:``SPACE``: Fold the selected comment, or load additional comments :``SPACE``: Fold the selected comment, or load additional comments
:``b``: Displays URLs with urlview

View File

@@ -136,6 +136,34 @@ If you prefer the complete terminal experience, set ``$BROWSER`` to a console-ba
`w3m <http://w3m.sourceforge.net/>`_, `lynx <http://lynx.isc.org/>`_, and `elinks <http://elinks.or.cz/>`_ are all good choices. `w3m <http://w3m.sourceforge.net/>`_, `lynx <http://lynx.isc.org/>`_, and `elinks <http://elinks.or.cz/>`_ are all good choices.
----------
Url Viewer
----------
You can open comment links using a url extraction binary.
The ``$RTV_URLVIEWER`` environment variable can be used to set the url viewer.
.. code-block:: bash
$ export RTV_URLVIEWER=urlview
The default program is ``urlview``, but most systems do not come with it installed by default.
Ubuntu
------
.. code-block:: bash
$ sudo apt-get install urlview
Mac with Homebrew
-----------------
.. code-block:: bash
$ brew install urlview
`urlview <https://github.com/sigpipe/urlview>`_, `urlscan <https://github.com/firecat53/urlscan>`_, are known to be compatible, but any program that accepts text via a stdin pipe will do
=== ===
FAQ FAQ
=== ===

View File

@@ -44,6 +44,7 @@ HELP = """
`h` or `LEFT` : Return to subreddit mode `h` or `LEFT` : Return to subreddit mode
`l` or `RIGHT` : Open the selected comment in a new window `l` or `RIGHT` : Open the selected comment in a new window
`SPACE` : Fold the selected comment, or load additional comments `SPACE` : Fold the selected comment, or load additional comments
`b` : Display URLs with urlview
""" """
COMMENT_FILE = """ COMMENT_FILE = """

View File

@@ -112,6 +112,7 @@ 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> SUBMISSION_OPEN_IN_PAGER = l, <KEY_RIGHT>
SUBMISSION_OPEN_IN_URLVIEWER = b
; Subreddit page ; Subreddit page
SUBREDDIT_SEARCH = f SUBREDDIT_SEARCH = f

View File

@@ -35,11 +35,11 @@ class SubmissionPage(Page):
current_index = self.nav.absolute_index current_index = self.nav.absolute_index
self.content.toggle(current_index) self.content.toggle(current_index)
# This logic handles a display edge case after a comment toggle. We want # This logic handles a display edge case after a comment toggle. We
# to make sure that when we re-draw the page, the cursor stays at its # want to make sure that when we re-draw the page, the cursor stays at
# current absolute position on the screen. In order to do this, apply # its current absolute position on the screen. In order to do this,
# a fixed offset if, while inverted, we either try to hide the bottom # apply a fixed offset if, while inverted, we either try to hide the
# comment or toggle any of the middle comments. # bottom comment or toggle any of the middle comments.
if self.nav.inverted: if self.nav.inverted:
data = self.content.get(current_index) data = self.content.get(current_index)
if data['hidden'] or self.nav.cursor_index != 0: if data['hidden'] or self.nav.cursor_index != 0:
@@ -147,6 +147,15 @@ class SubmissionPage(Page):
else: else:
self.term.flash() self.term.flash()
@SubmissionController.register(Command('SUBMISSION_OPEN_IN_URLVIEWER'))
def comment_urlview(self):
data = self.content.get(self.nav.absolute_index)
comment = data.get('body', '')
if comment:
self.term.open_urlview(comment)
else:
self.term.flash()
def _draw_item(self, win, data, inverted): def _draw_item(self, win, data, inverted):
if data['type'] == 'MoreComments': if data['type'] == 'MoreComments':
@@ -219,7 +228,8 @@ class SubmissionPage(Page):
n_cols -= 1 n_cols -= 1
self.term.add_line(win, '{body}'.format(**data), 0, 1) self.term.add_line(win, '{body}'.format(**data), 0, 1)
self.term.add_line(win, ' [{count}]'.format(**data), attr=curses.A_BOLD) self.term.add_line(
win, ' [{count}]'.format(**data), attr=curses.A_BOLD)
attr = Color.get_level(data['level']) attr = Color.get_level(data['level'])
self.term.addch(win, 0, 0, self.term.vline, attr) self.term.addch(win, 0, 0, self.term.vline, attr)

View File

@@ -349,7 +349,8 @@ class Terminal(object):
'Browser exited with status=%s' % code) 'Browser exited with status=%s' % code)
time.sleep(0.01) time.sleep(0.01)
else: else:
raise exceptions.BrowserError('Timeout opening browser') raise exceptions.BrowserError(
'Timeout opening browser')
finally: finally:
# Can't check the loader exception because the oauth module # Can't check the loader exception because the oauth module
# supersedes this loader and we need to always kill the # supersedes this loader and we need to always kill the
@@ -438,6 +439,20 @@ class Terminal(object):
else: else:
_logger.info('File deleted: %s', filepath) _logger.info('File deleted: %s', filepath)
def open_urlview(self, data):
urlview = os.getenv('RTV_URLVIEWER') or 'urlview'
try:
with self.suspend():
p = subprocess.Popen([urlview],
stdin=subprocess.PIPE)
try:
p.communicate(input=six.b(data))
except KeyboardInterrupt:
p.terminate()
except OSError:
self.show_notification(
'Could not open urls with {}'.format(urlview))
def text_input(self, window, allow_resize=False): def text_input(self, window, allow_resize=False):
""" """
Transform a window into a text box that will accept user input and loop Transform a window into a text box that will accept user input and loop

View File

@@ -28,6 +28,10 @@ for future sessions. You can disable this behavior by setting the option
Text editor to use when editing comments and submissions. Will fallback to Text editor to use when editing comments and submissions. Will fallback to
\fI$EDITOR\fR. \fI$EDITOR\fR.
.TP .TP
.BR RTV_URLVIEWER
Url Viewer to use to extract links from comments. Requires a compatible
Url Viewer to be installed
.TP
.BR BROWSER .BR BROWSER
Web browser to use when opening links. Web browser to use when opening links.
.TP .TP

View File

@@ -0,0 +1,249 @@
interactions:
- request:
body: !!binary |
cmVkaXJlY3RfdXJpPWh0dHAlM0ElMkYlMkYxMjcuMC4wLjElM0E2NTAwMCUyRiZncmFudF90eXBl
PXJlZnJlc2hfdG9rZW4mcmVmcmVzaF90b2tlbj0qKioqKioqKioq
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Authorization: ['**********']
Connection: [keep-alive]
Content-Length: ['122']
Content-Type: [application/x-www-form-urlencoded]
Cookie: [__cfduid=d963647719488322ce24aaf79235c3d6e1449042300]
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
method: POST
uri: https://api.reddit.com/api/v1/access_token/
response:
body:
string: !!binary |
H4sIAAAAAAAAAyWMsQrCQBAFf2W5WiFqDGqb0lYQq3DJPXSReMfuJvEU/12i1YNh5r2d7zqoNhbv
eLgDubKsdsVqtV0iDedjf/GvNJzzaR/qqeZ1XW72084tyP2CxnLCXLXwApk5nokF2vD8tqmKYkFO
u/jXENjoxmpRMnHAw9gy9VmHVhACm1ISHr2hh6q/QkngAwlSFCP1I0iHtmebRzvhFjRGg/t8AYx9
Bq7KAAAA
headers:
CF-RAY: [24e569649f492816-SJC]
Connection: [keep-alive]
Content-Encoding: [gzip]
Content-Type: [application/json; charset=UTF-8]
Date: ['Wed, 02 Dec 2015 07:45:20 GMT']
Server: [cloudflare-nginx]
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
X-Moose: [majestic]
cache-control: ['max-age=0, must-revalidate']
x-content-type-options: [nosniff]
x-frame-options: [SAMEORIGIN]
x-xss-protection: [1; mode=block]
status: {code: 200, message: OK}
- request:
body: null
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Authorization: ['**********']
Connection: [keep-alive]
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
method: GET
uri: https://oauth.reddit.com/api/v1/me.json
response:
body:
string: !!binary |
H4sIAAAAAAAAA12QwWrDMBBEf0Xs2YTYuLTxZ5TSq5CtdbNE2k1XUhoI/fei1C5xjxp23ozmBkeX
bHQUYDCzCwkbA+wiwmDgFb2n/IYaiV14J/xChcbApOgyehhM2/fd89O+Oxx2+8bAkTzaWSValVFy
emBSsqmkM7K/G1d5QdmSpxXXtf2Kq9XE/68XiE/25DS6aqkQiRE5/2nVKxdU275sG3xI8Fslykao
D/gMjGP9Zz23eD2TukzCMBguIdQ7HuVqJymcl7ha9YJKM6G3uBTOWnDFTHofMy33v1skEn4IWFao
Id8/dZfx5JkBAAA=
headers:
CF-RAY: [24e56971a0f811a7-SJC]
Connection: [keep-alive]
Content-Encoding: [gzip]
Content-Type: [application/json; charset=UTF-8]
Date: ['Wed, 02 Dec 2015 07:45:22 GMT']
Server: [cloudflare-nginx]
Set-Cookie: ['__cfduid=d667511ab17e019fb769e680b9cab23071449042322; expires=Thu,
01-Dec-16 07:45:22 GMT; path=/; domain=.reddit.com; HttpOnly']
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
X-Moose: [majestic]
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
must-revalidate']
expires: ['-1']
x-content-type-options: [nosniff]
x-frame-options: [SAMEORIGIN]
x-ratelimit-remaining: ['586.0']
x-ratelimit-reset: ['278']
x-ratelimit-used: ['14']
x-xss-protection: [1; mode=block]
status: {code: 200, message: OK}
- request:
body: null
headers:
Accept: ['*/*']
Accept-Encoding: ['gzip, deflate']
Authorization: ['**********']
Connection: [keep-alive]
Cookie: [__cfduid=d667511ab17e019fb769e680b9cab23071449042322]
User-Agent: [rtv test suite PRAW/3.3.0 Python/3.4.0 b'Linux-3.13.0-24-generic-x86_64-with-Ubuntu-14.04-trusty']
method: GET
uri: https://oauth.reddit.com/r/Python/comments/2xmo63/a_python_terminal_viewer_for_browsing_reddit/.json
response:
body:
string: !!binary |
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
AA==
headers:
CF-RAY: [24e56974010611a7-SJC]
Connection: [keep-alive]
Content-Encoding: [gzip]
Content-Length: ['7639']
Content-Type: [application/json; charset=UTF-8]
Date: ['Wed, 02 Dec 2015 07:45:22 GMT']
Server: [cloudflare-nginx]
Strict-Transport-Security: [max-age=15552000; includeSubDomains; preload]
Vary: [accept-encoding]
X-Moose: [majestic]
cache-control: ['private, s-maxage=0, max-age=0, must-revalidate', 'max-age=0,
must-revalidate']
expires: ['-1']
x-content-type-options: [nosniff]
x-frame-options: [SAMEORIGIN]
x-ratelimit-remaining: ['585.0']
x-ratelimit-reset: ['278']
x-ratelimit-used: ['15']
x-reddit-tracking: ['https://pixel.redditmedia.com/pixel/of_destiny.png?v=x7Hgtcci0o4lZvWWI68HSCYaPfSu8AoLGJymDPfSvXaVLHrXHOY314V%2FS7aiBGPeCNk%2FdOqa1ik%3D']
x-ua-compatible: [IE=edge]
x-xss-protection: [1; mode=block]
status: {code: 200, message: OK}
version: 1

View File

@@ -254,3 +254,28 @@ def test_submission_edit(submission_page, terminal, refresh_token):
submission_page.controller.trigger('e') submission_page.controller.trigger('e')
assert open_editor.called assert open_editor.called
edit.assert_called_with('comment text') edit.assert_called_with('comment text')
def test_submission_urlview(submission_page, terminal, refresh_token):
# Log in
submission_page.config.refresh_token = refresh_token
submission_page.oauth.authorize()
# Positive Case
data = submission_page.content.get(submission_page.nav.absolute_index)
TEST_BODY = 'test comment body'
data['body'] = TEST_BODY
with mock.patch.object(terminal, 'open_urlview') as open_urlview, \
mock.patch('subprocess.Popen'):
submission_page.controller.trigger('b')
open_urlview.assert_called_with(TEST_BODY)
# Negative Case
data = submission_page.content.get(submission_page.nav.absolute_index)
TEST_NO_BODY = ''
data['body'] = TEST_NO_BODY
with mock.patch.object(terminal, 'open_urlview') as open_urlview, \
mock.patch('subprocess.Popen'):
submission_page.controller.trigger('b')
assert not open_urlview.called