diff --git a/CONTROLS.rst b/CONTROLS.rst index f5075f4..c3cfa63 100644 --- a/CONTROLS.rst +++ b/CONTROLS.rst @@ -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 :``o`` or ``ENTER``: Open the comment permalink with your web browser :``SPACE``: Fold the selected comment, or load additional comments +:``b``: Displays URLs with urlview diff --git a/README.rst b/README.rst index 32309e2..b9230d5 100644 --- a/README.rst +++ b/README.rst @@ -136,6 +136,34 @@ If you prefer the complete terminal experience, set ``$BROWSER`` to a console-ba `w3m `_, `lynx `_, and `elinks `_ 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 `_, `urlscan `_, are known to be compatible, but any program that accepts text via a stdin pipe will do + === FAQ === diff --git a/rtv/docs.py b/rtv/docs.py index bb9eab8..c1542a8 100644 --- a/rtv/docs.py +++ b/rtv/docs.py @@ -44,6 +44,7 @@ HELP = """ `h` or `LEFT` : Return to subreddit mode `l` or `RIGHT` : Open the selected comment in a new window `SPACE` : Fold the selected comment, or load additional comments + `b` : Display URLs with urlview """ COMMENT_FILE = """ diff --git a/rtv/rtv.cfg b/rtv/rtv.cfg index b7ad320..cb15877 100644 --- a/rtv/rtv.cfg +++ b/rtv/rtv.cfg @@ -112,6 +112,7 @@ SUBMISSION_OPEN_IN_BROWSER = o, , SUBMISSION_POST = c SUBMISSION_EXIT = h, SUBMISSION_OPEN_IN_PAGER = l, +SUBMISSION_OPEN_IN_URLVIEWER = b ; Subreddit page SUBREDDIT_SEARCH = f diff --git a/rtv/submission.py b/rtv/submission.py index a70dd3a..39fa3a7 100644 --- a/rtv/submission.py +++ b/rtv/submission.py @@ -35,11 +35,11 @@ class SubmissionPage(Page): current_index = self.nav.absolute_index self.content.toggle(current_index) - # This logic handles a display edge case after a comment toggle. We want - # to make sure that when we re-draw the page, the cursor stays at its - # current absolute position on the screen. In order to do this, apply - # a fixed offset if, while inverted, we either try to hide the bottom - # comment or toggle any of the middle comments. + # This logic handles a display edge case after a comment toggle. We + # want to make sure that when we re-draw the page, the cursor stays at + # its current absolute position on the screen. In order to do this, + # apply a fixed offset if, while inverted, we either try to hide the + # bottom comment or toggle any of the middle comments. if self.nav.inverted: data = self.content.get(current_index) if data['hidden'] or self.nav.cursor_index != 0: @@ -147,6 +147,15 @@ class SubmissionPage(Page): else: 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): if data['type'] == 'MoreComments': @@ -219,7 +228,8 @@ class SubmissionPage(Page): n_cols -= 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']) self.term.addch(win, 0, 0, self.term.vline, attr) diff --git a/rtv/terminal.py b/rtv/terminal.py index d7fa38e..90dc698 100644 --- a/rtv/terminal.py +++ b/rtv/terminal.py @@ -349,7 +349,8 @@ class Terminal(object): 'Browser exited with status=%s' % code) time.sleep(0.01) else: - raise exceptions.BrowserError('Timeout opening browser') + raise exceptions.BrowserError( + 'Timeout opening browser') finally: # Can't check the loader exception because the oauth module # supersedes this loader and we need to always kill the @@ -438,6 +439,20 @@ class Terminal(object): else: _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): """ Transform a window into a text box that will accept user input and loop @@ -574,4 +589,4 @@ class Terminal(object): break out = '\n'.join(stack) - return out \ No newline at end of file + return out diff --git a/scripts/rtv.1.template b/scripts/rtv.1.template index 02831dd..6ca82a8 100644 --- a/scripts/rtv.1.template +++ b/scripts/rtv.1.template @@ -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 \fI$EDITOR\fR. .TP +.BR RTV_URLVIEWER +Url Viewer to use to extract links from comments. Requires a compatible +Url Viewer to be installed +.TP .BR BROWSER Web browser to use when opening links. .TP diff --git a/tests/cassettes/test_submission_urlview.yaml b/tests/cassettes/test_submission_urlview.yaml new file mode 100644 index 0000000..23af475 --- /dev/null +++ b/tests/cassettes/test_submission_urlview.yaml @@ -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 diff --git a/tests/test_submission.py b/tests/test_submission.py index e224bd7..77825a1 100644 --- a/tests/test_submission.py +++ b/tests/test_submission.py @@ -253,4 +253,29 @@ def test_submission_edit(submission_page, terminal, refresh_token): submission_page.controller.trigger('e') assert open_editor.called - edit.assert_called_with('comment text') \ No newline at end of file + 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