Merge branch 'master' into browser_osx
Conflicts: rtv/objects.py
This commit is contained in:
@@ -65,10 +65,9 @@ def main():
|
||||
with curses_session() as stdscr:
|
||||
term = Terminal(stdscr, config['ascii'])
|
||||
with term.loader(catch_exception=False):
|
||||
reddit = praw.Reddit(
|
||||
user_agent=user_agent,
|
||||
decode_html_entities=False,
|
||||
disable_update_check=True)
|
||||
reddit = praw.Reddit(user_agent=user_agent,
|
||||
decode_html_entities=False,
|
||||
disable_update_check=True)
|
||||
|
||||
# Authorize on launch if the refresh token is present
|
||||
oauth = OAuthHelper(reddit, term, config)
|
||||
@@ -76,13 +75,18 @@ def main():
|
||||
oauth.authorize()
|
||||
|
||||
with term.loader():
|
||||
page = SubredditPage(
|
||||
reddit, term, config, oauth,
|
||||
name=config['subreddit'], url=config['link'])
|
||||
page = SubredditPage(reddit, term, config, oauth,
|
||||
config['subreddit'])
|
||||
if term.loader.exception:
|
||||
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()
|
||||
|
||||
except Exception as e:
|
||||
_logger.exception(e)
|
||||
raise
|
||||
|
||||
@@ -339,7 +339,7 @@ class SubredditContent(Content):
|
||||
try:
|
||||
self.get(0)
|
||||
except IndexError:
|
||||
raise exceptions.SubredditError('Unable to retrieve subreddit')
|
||||
raise exceptions.SubredditError('No submissions')
|
||||
|
||||
@classmethod
|
||||
def from_name(cls, reddit, name, loader, order=None, query=None):
|
||||
@@ -361,7 +361,7 @@ class SubredditContent(Content):
|
||||
|
||||
if name == 'me':
|
||||
if not reddit.is_oauth_session():
|
||||
raise exceptions.AccountError('Could not access user account')
|
||||
raise exceptions.AccountError('Not logged in')
|
||||
elif order:
|
||||
submissions = reddit.user.get_submitted(sort=order)
|
||||
else:
|
||||
@@ -443,7 +443,7 @@ class SubscriptionContent(Content):
|
||||
try:
|
||||
self.get(0)
|
||||
except IndexError:
|
||||
raise exceptions.SubscriptionError('Unable to load subscriptions')
|
||||
raise exceptions.SubscriptionError('No subscriptions')
|
||||
|
||||
@classmethod
|
||||
def from_user(cls, reddit, loader):
|
||||
|
||||
@@ -12,10 +12,10 @@ import threading
|
||||
from contextlib import contextmanager
|
||||
|
||||
import six
|
||||
import praw
|
||||
import requests
|
||||
from praw.errors import PRAWException
|
||||
from requests import RequestException
|
||||
|
||||
from . import exceptions
|
||||
from .exceptions import RTVError
|
||||
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -111,26 +111,6 @@ class LoadScreen(object):
|
||||
>>> 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):
|
||||
|
||||
self.exception = None
|
||||
@@ -187,19 +167,27 @@ class LoadScreen(object):
|
||||
self._animator.join()
|
||||
self._terminal.stdscr.refresh()
|
||||
|
||||
if self.catch_exception and e is not None:
|
||||
# Log the exception and attach it so the caller can inspect it
|
||||
self.exception = e
|
||||
_logger.info('Loader caught: {0} - {1}'.format(type(e).__name__, e))
|
||||
# If an error occurred, display a notification on the screen
|
||||
for base, message in self.HANDLED_EXCEPTIONS:
|
||||
if isinstance(e, base):
|
||||
if message:
|
||||
self._terminal.show_notification(message)
|
||||
break
|
||||
else:
|
||||
return # Re-raise unhandled exceptions
|
||||
return True # Otherwise swallow the exception and continue
|
||||
if e is None or not self.catch_exception:
|
||||
# Skip exception handling
|
||||
return
|
||||
|
||||
self.exception = e
|
||||
exc_name = type(e).__name__
|
||||
_logger.info('Loader caught: {0} - {1}'.format(exc_name, e))
|
||||
|
||||
# Some exceptions we want to swallow and display a notification
|
||||
handled_exceptions = (RTVError, PRAWException, RequestException)
|
||||
if isinstance(e, handled_exceptions):
|
||||
# Pass the message straight through to the user
|
||||
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):
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class SubredditController(PageController):
|
||||
|
||||
class SubredditPage(Page):
|
||||
|
||||
def __init__(self, reddit, term, config, oauth, name, url=None):
|
||||
def __init__(self, reddit, term, config, oauth, name):
|
||||
"""
|
||||
Params:
|
||||
name (string): Name of subreddit to open
|
||||
@@ -31,9 +31,6 @@ class SubredditPage(Page):
|
||||
self.controller = SubredditController(self)
|
||||
self.nav = Navigator(self.content.get)
|
||||
|
||||
if url:
|
||||
self.open_submission(url=url)
|
||||
|
||||
@SubredditController.register(curses.KEY_F5, 'r')
|
||||
def refresh_content(self, name=None, order=None):
|
||||
"Re-download all submissions and reset the page index"
|
||||
@@ -127,7 +124,8 @@ class SubredditPage(Page):
|
||||
|
||||
title, content = text.split('\n', 1)
|
||||
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
|
||||
time.sleep(2.0)
|
||||
if self.term.loader.exception:
|
||||
|
||||
@@ -77,8 +77,7 @@ def test_oauth_authorize_with_refresh_token(oauth, stdscr, refresh_token):
|
||||
exception = OAuthException('', '')
|
||||
oauth.reddit.refresh_access_information.side_effect = exception
|
||||
oauth.authorize()
|
||||
message = 'Invalid OAuth data'.encode('utf-8')
|
||||
stdscr.derwin().addstr.assert_called_with(1, 1, message)
|
||||
assert isinstance(oauth.term.loader.exception, OAuthException)
|
||||
assert oauth.http_server is None
|
||||
|
||||
|
||||
@@ -149,8 +148,7 @@ def test_oauth_authorize(oauth, reddit, stdscr, refresh_token):
|
||||
exception = OAuthException('', '')
|
||||
oauth.reddit.get_access_information.side_effect = exception
|
||||
oauth.authorize()
|
||||
message = 'Invalid OAuth data'.encode('utf-8')
|
||||
stdscr.derwin().addstr.assert_called_with(1, 1, message)
|
||||
assert isinstance(oauth.term.loader.exception, OAuthException)
|
||||
assert not oauth.config.save_refresh_token.called
|
||||
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ def test_objects_load_screen_exception_handled(terminal, stdscr, ascii):
|
||||
assert not terminal.loader._is_running
|
||||
assert not terminal.loader._animator.is_alive()
|
||||
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)
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ def test_objects_load_screen_nested_complex(terminal, stdscr, ascii):
|
||||
assert terminal.loader.depth == 0
|
||||
assert not terminal.loader._is_running
|
||||
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)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user