Merge branch 'master' into browser_osx

Conflicts:
	rtv/objects.py
This commit is contained in:
Michael Lazar
2015-12-03 21:18:40 -08:00
6 changed files with 45 additions and 57 deletions

View File

@@ -65,10 +65,9 @@ def main():
with curses_session() as stdscr: with curses_session() as stdscr:
term = Terminal(stdscr, config['ascii']) term = Terminal(stdscr, config['ascii'])
with term.loader(catch_exception=False): with term.loader(catch_exception=False):
reddit = praw.Reddit( reddit = praw.Reddit(user_agent=user_agent,
user_agent=user_agent, decode_html_entities=False,
decode_html_entities=False, disable_update_check=True)
disable_update_check=True)
# Authorize on launch if the refresh token is present # Authorize on launch if the refresh token is present
oauth = OAuthHelper(reddit, term, config) oauth = OAuthHelper(reddit, term, config)
@@ -76,13 +75,18 @@ def main():
oauth.authorize() oauth.authorize()
with term.loader(): with term.loader():
page = SubredditPage( page = SubredditPage(reddit, term, config, oauth,
reddit, term, config, oauth, config['subreddit'])
name=config['subreddit'], url=config['link'])
if term.loader.exception: if term.loader.exception:
return return
# Open the supplied submission link before opening the subreddit
if config['link']:
page.open_submission(url=config['link'])
# Launch the subreddit page
page.loop() page.loop()
except Exception as e: except Exception as e:
_logger.exception(e) _logger.exception(e)
raise raise

View File

@@ -339,7 +339,7 @@ class SubredditContent(Content):
try: try:
self.get(0) self.get(0)
except IndexError: except IndexError:
raise exceptions.SubredditError('Unable to retrieve subreddit') raise exceptions.SubredditError('No submissions')
@classmethod @classmethod
def from_name(cls, reddit, name, loader, order=None, query=None): def from_name(cls, reddit, name, loader, order=None, query=None):
@@ -361,7 +361,7 @@ class SubredditContent(Content):
if name == 'me': if name == 'me':
if not reddit.is_oauth_session(): if not reddit.is_oauth_session():
raise exceptions.AccountError('Could not access user account') raise exceptions.AccountError('Not logged in')
elif order: elif order:
submissions = reddit.user.get_submitted(sort=order) submissions = reddit.user.get_submitted(sort=order)
else: else:
@@ -443,7 +443,7 @@ class SubscriptionContent(Content):
try: try:
self.get(0) self.get(0)
except IndexError: except IndexError:
raise exceptions.SubscriptionError('Unable to load subscriptions') raise exceptions.SubscriptionError('No subscriptions')
@classmethod @classmethod
def from_user(cls, reddit, loader): def from_user(cls, reddit, loader):

View File

@@ -12,10 +12,10 @@ import threading
from contextlib import contextmanager from contextlib import contextmanager
import six import six
import praw from praw.errors import PRAWException
import requests from requests import RequestException
from . import exceptions from .exceptions import RTVError
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -111,26 +111,6 @@ class LoadScreen(object):
>>> assert isinstance(terminal.loader.exception, KeyboardInterrupt) >>> assert isinstance(terminal.loader.exception, KeyboardInterrupt)
""" """
HANDLED_EXCEPTIONS = [
(exceptions.BrowserError, 'Could not open browser'),
(exceptions.SubscriptionError, 'No Subscriptions'),
(exceptions.AccountError, 'Unable to Access Account'),
(exceptions.SubredditError, 'Invalid Subreddit'),
(praw.errors.InvalidSubreddit, 'Invalid Subreddit'),
(praw.errors.InvalidComment, 'Invalid Comment'),
(praw.errors.InvalidSubmission, 'Invalid Submission'),
(praw.errors.OAuthAppRequired, 'Invalid OAuth data'),
(praw.errors.OAuthException, 'Invalid OAuth data'),
(praw.errors.LoginOrScopeRequired, 'Not Logged In'),
(praw.errors.ClientException, 'Reddit Client Error'),
(praw.errors.NotFound, 'Not Found'),
(praw.errors.APIException, 'Reddit API Error'),
(praw.errors.HTTPException, 'Reddit HTTP Error'),
(requests.HTTPError, 'Unexpected HTTP Error'),
(requests.ConnectionError, 'Connection Error'),
(KeyboardInterrupt, None),
]
def __init__(self, terminal): def __init__(self, terminal):
self.exception = None self.exception = None
@@ -187,19 +167,27 @@ class LoadScreen(object):
self._animator.join() self._animator.join()
self._terminal.stdscr.refresh() self._terminal.stdscr.refresh()
if self.catch_exception and e is not None: if e is None or not self.catch_exception:
# Log the exception and attach it so the caller can inspect it # Skip exception handling
self.exception = e return
_logger.info('Loader caught: {0} - {1}'.format(type(e).__name__, e))
# If an error occurred, display a notification on the screen self.exception = e
for base, message in self.HANDLED_EXCEPTIONS: exc_name = type(e).__name__
if isinstance(e, base): _logger.info('Loader caught: {0} - {1}'.format(exc_name, e))
if message:
self._terminal.show_notification(message) # Some exceptions we want to swallow and display a notification
break handled_exceptions = (RTVError, PRAWException, RequestException)
else: if isinstance(e, handled_exceptions):
return # Re-raise unhandled exceptions # Pass the message straight through to the user
return True # Otherwise swallow the exception and continue message = six.text_type(e).split('/n') if str(e) else exc_name
self._terminal.show_notification(message)
return True
elif isinstance(e, KeyboardInterrupt):
# Don't need to print anything for this one
return True
else:
# Allow the exception to re-raise
return None
def animate(self, delay, interval, message, trail): def animate(self, delay, interval, message, trail):

View File

@@ -19,7 +19,7 @@ class SubredditController(PageController):
class SubredditPage(Page): class SubredditPage(Page):
def __init__(self, reddit, term, config, oauth, name, url=None): def __init__(self, reddit, term, config, oauth, name):
""" """
Params: Params:
name (string): Name of subreddit to open name (string): Name of subreddit to open
@@ -31,9 +31,6 @@ class SubredditPage(Page):
self.controller = SubredditController(self) self.controller = SubredditController(self)
self.nav = Navigator(self.content.get) self.nav = Navigator(self.content.get)
if url:
self.open_submission(url=url)
@SubredditController.register(curses.KEY_F5, 'r') @SubredditController.register(curses.KEY_F5, 'r')
def refresh_content(self, name=None, order=None): def refresh_content(self, name=None, order=None):
"Re-download all submissions and reset the page index" "Re-download all submissions and reset the page index"
@@ -127,7 +124,8 @@ class SubredditPage(Page):
title, content = text.split('\n', 1) title, content = text.split('\n', 1)
with self.term.loader(message='Posting', delay=0): with self.term.loader(message='Posting', delay=0):
submission = self.reddit.submit(name, title, text=content) submission = self.reddit.submit(name, title, text=content,
raise_captcha_exception=True)
# Give reddit time to process the submission # Give reddit time to process the submission
time.sleep(2.0) time.sleep(2.0)
if self.term.loader.exception: if self.term.loader.exception:

View File

@@ -77,8 +77,7 @@ def test_oauth_authorize_with_refresh_token(oauth, stdscr, refresh_token):
exception = OAuthException('', '') exception = OAuthException('', '')
oauth.reddit.refresh_access_information.side_effect = exception oauth.reddit.refresh_access_information.side_effect = exception
oauth.authorize() oauth.authorize()
message = 'Invalid OAuth data'.encode('utf-8') assert isinstance(oauth.term.loader.exception, OAuthException)
stdscr.derwin().addstr.assert_called_with(1, 1, message)
assert oauth.http_server is None assert oauth.http_server is None
@@ -149,8 +148,7 @@ def test_oauth_authorize(oauth, reddit, stdscr, refresh_token):
exception = OAuthException('', '') exception = OAuthException('', '')
oauth.reddit.get_access_information.side_effect = exception oauth.reddit.get_access_information.side_effect = exception
oauth.authorize() oauth.authorize()
message = 'Invalid OAuth data'.encode('utf-8') assert isinstance(oauth.term.loader.exception, OAuthException)
stdscr.derwin().addstr.assert_called_with(1, 1, message)
assert not oauth.config.save_refresh_token.called assert not oauth.config.save_refresh_token.called

View File

@@ -53,7 +53,7 @@ def test_objects_load_screen_exception_handled(terminal, stdscr, ascii):
assert not terminal.loader._is_running assert not terminal.loader._is_running
assert not terminal.loader._animator.is_alive() assert not terminal.loader._animator.is_alive()
assert isinstance(terminal.loader.exception, requests.ConnectionError) assert isinstance(terminal.loader.exception, requests.ConnectionError)
error_message = 'Connection Error'.encode('ascii' if ascii else 'utf-8') error_message = 'ConnectionError'.encode('ascii' if ascii else 'utf-8')
stdscr.subwin.addstr.assert_called_with(1, 1, error_message) stdscr.subwin.addstr.assert_called_with(1, 1, error_message)
@@ -152,7 +152,7 @@ def test_objects_load_screen_nested_complex(terminal, stdscr, ascii):
assert terminal.loader.depth == 0 assert terminal.loader.depth == 0
assert not terminal.loader._is_running assert not terminal.loader._is_running
assert not terminal.loader._animator.is_alive() assert not terminal.loader._animator.is_alive()
error_message = 'Connection Error'.encode('ascii' if ascii else 'utf-8') error_message = 'ConnectionError'.encode('ascii' if ascii else 'utf-8')
stdscr.subwin.addstr.assert_called_once_with(1, 1, error_message) stdscr.subwin.addstr.assert_called_once_with(1, 1, error_message)