Merge branch 'master' into woorst-imgur_api
This commit is contained in:
@@ -326,6 +326,7 @@ class SubmissionContent(Content):
|
|||||||
self.max_indent_level = max_indent_level
|
self.max_indent_level = max_indent_level
|
||||||
self.name = submission_data['permalink']
|
self.name = submission_data['permalink']
|
||||||
self.order = order
|
self.order = order
|
||||||
|
self.query = None
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._submission = submission
|
self._submission = submission
|
||||||
self._submission_data = submission_data
|
self._submission_data = submission_data
|
||||||
@@ -435,10 +436,12 @@ class SubredditContent(Content):
|
|||||||
list for repeat access.
|
list for repeat access.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, submissions, loader, order=None, max_title_rows=4):
|
def __init__(self, name, submissions, loader, order=None,
|
||||||
|
max_title_rows=4, query=None):
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.order = order
|
self.order = order
|
||||||
|
self.query = query
|
||||||
self.max_title_rows = max_title_rows
|
self.max_title_rows = max_title_rows
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._submissions = submissions
|
self._submissions = submissions
|
||||||
@@ -603,7 +606,8 @@ class SubredditContent(Content):
|
|||||||
display_name = '/r/{0}'.format(subreddit.display_name)
|
display_name = '/r/{0}'.format(subreddit.display_name)
|
||||||
|
|
||||||
# We made it!
|
# We made it!
|
||||||
return cls(display_name, submissions, loader, order=display_order)
|
return cls(display_name, submissions, loader, order=display_order,
|
||||||
|
query=query)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def range(self):
|
def range(self):
|
||||||
@@ -659,6 +663,7 @@ class SubscriptionContent(Content):
|
|||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.order = None
|
self.order = None
|
||||||
|
self.query = None
|
||||||
self._loader = loader
|
self._loader = loader
|
||||||
self._subscriptions = subscriptions
|
self._subscriptions = subscriptions
|
||||||
self._subscription_data = []
|
self._subscription_data = []
|
||||||
|
|||||||
@@ -643,14 +643,16 @@ class KeyMap(object):
|
|||||||
self.set_bindings(bindings)
|
self.set_bindings(bindings)
|
||||||
|
|
||||||
def set_bindings(self, bindings):
|
def set_bindings(self, bindings):
|
||||||
# Clear the keymap before applying the bindings to avoid confusion.
|
new_keymap = {}
|
||||||
# If a user defines custom bindings in their config file, they must
|
|
||||||
# explicitly define ALL of the bindings.
|
|
||||||
self._keymap = {}
|
|
||||||
for command, keys in bindings.items():
|
for command, keys in bindings.items():
|
||||||
if not isinstance(command, Command):
|
if not isinstance(command, Command):
|
||||||
command = Command(command)
|
command = Command(command)
|
||||||
self._keymap[command] = keys
|
new_keymap[command] = keys
|
||||||
|
|
||||||
|
if not self._keymap:
|
||||||
|
self._keymap = new_keymap
|
||||||
|
else:
|
||||||
|
self._keymap.update(new_keymap)
|
||||||
|
|
||||||
def get(self, command):
|
def get(self, command):
|
||||||
if not isinstance(command, Command):
|
if not isinstance(command, Command):
|
||||||
@@ -694,4 +696,4 @@ class KeyMap(object):
|
|||||||
|
|
||||||
except (AttributeError, ValueError, TypeError):
|
except (AttributeError, ValueError, TypeError):
|
||||||
raise exceptions.ConfigError('Invalid configuration! "%s" is not a '
|
raise exceptions.ConfigError('Invalid configuration! "%s" is not a '
|
||||||
'valid key' % key)
|
'valid key' % key)
|
||||||
|
|||||||
@@ -408,6 +408,10 @@ class Page(object):
|
|||||||
sub_name = sub_name.replace('/r/front', 'Front Page')
|
sub_name = sub_name.replace('/r/front', 'Front Page')
|
||||||
sub_name = sub_name.replace('/u/me', 'My Submissions')
|
sub_name = sub_name.replace('/u/me', 'My Submissions')
|
||||||
sub_name = sub_name.replace('/u/saved', 'My Saved Submissions')
|
sub_name = sub_name.replace('/u/saved', 'My Saved Submissions')
|
||||||
|
|
||||||
|
query = self.content.query
|
||||||
|
if query:
|
||||||
|
sub_name = 'Searching {0}: {1}'.format(sub_name, query)
|
||||||
self.term.add_line(window, sub_name, 0, 0)
|
self.term.add_line(window, sub_name, 0, 0)
|
||||||
|
|
||||||
# Set the terminal title
|
# Set the terminal title
|
||||||
|
|||||||
@@ -40,6 +40,13 @@ class SubredditPage(Page):
|
|||||||
"Re-download all submissions and reset the page index"
|
"Re-download all submissions and reset the page index"
|
||||||
|
|
||||||
order = order or self.content.order
|
order = order or self.content.order
|
||||||
|
|
||||||
|
# Preserve the query if staying on the current page
|
||||||
|
if name is None:
|
||||||
|
query = self.content.query
|
||||||
|
else:
|
||||||
|
query = None
|
||||||
|
|
||||||
name = name or self.content.name
|
name = name or self.content.name
|
||||||
|
|
||||||
# Hack to allow an order specified in the name by prompt_subreddit() to
|
# Hack to allow an order specified in the name by prompt_subreddit() to
|
||||||
@@ -49,7 +56,7 @@ class SubredditPage(Page):
|
|||||||
|
|
||||||
with self.term.loader('Refreshing page'):
|
with self.term.loader('Refreshing page'):
|
||||||
self.content = SubredditContent.from_name(
|
self.content = SubredditContent.from_name(
|
||||||
self.reddit, name, self.term.loader, order=order)
|
self.reddit, name, self.term.loader, order=order, query=query)
|
||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
|
|
||||||
@@ -290,4 +297,4 @@ class SubredditPage(Page):
|
|||||||
self.term.add_line(win, text, attr=Color.YELLOW)
|
self.term.add_line(win, text, attr=Color.YELLOW)
|
||||||
if data['flair']:
|
if data['flair']:
|
||||||
text = ' {flair}'.format(**data)
|
text = ' {flair}'.format(**data)
|
||||||
self.term.add_line(win, text, attr=Color.RED)
|
self.term.add_line(win, text, attr=Color.RED)
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class Terminal(object):
|
|||||||
self.loader = LoadScreen(self)
|
self.loader = LoadScreen(self)
|
||||||
self._display = None
|
self._display = None
|
||||||
self._mailcap_dict = mailcap.getcaps()
|
self._mailcap_dict = mailcap.getcaps()
|
||||||
self._term = os.environ['TERM']
|
self._term = os.environ.get('TERM')
|
||||||
|
|
||||||
# This is a hack, the MIME parsers should be stateless
|
# This is a hack, the MIME parsers should be stateless
|
||||||
# but we need to load the imgur credentials from the config
|
# but we need to load the imgur credentials from the config
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -136,9 +136,10 @@ def test_config_from_file():
|
|||||||
|
|
||||||
fargs, fbindings = Config.get_file(filename=fp.name)
|
fargs, fbindings = Config.get_file(filename=fp.name)
|
||||||
config = Config(**fargs)
|
config = Config(**fargs)
|
||||||
|
default_keymap = config.keymap._keymap.copy()
|
||||||
config.keymap.set_bindings(fbindings)
|
config.keymap.set_bindings(fbindings)
|
||||||
assert config.config == {}
|
assert config.config == {}
|
||||||
assert config.keymap._keymap == {}
|
assert config.keymap._keymap == default_keymap
|
||||||
|
|
||||||
# [rtv]
|
# [rtv]
|
||||||
rows = ['{0}={1}'.format(key, val) for key, val in args.items()]
|
rows = ['{0}={1}'.format(key, val) for key, val in args.items()]
|
||||||
@@ -224,4 +225,4 @@ def test_config_history():
|
|||||||
|
|
||||||
config.delete_history()
|
config.delete_history()
|
||||||
assert len(config.history) == 0
|
assert len(config.history) == 0
|
||||||
assert not os.path.exists(fp.name)
|
assert not os.path.exists(fp.name)
|
||||||
|
|||||||
@@ -370,13 +370,17 @@ def test_objects_keymap():
|
|||||||
keymap.get('downvote')
|
keymap.get('downvote')
|
||||||
assert 'DOWNVOTE' in six.text_type(e)
|
assert 'DOWNVOTE' in six.text_type(e)
|
||||||
|
|
||||||
# Updating the bindings wipes out the old ones
|
|
||||||
bindings = {'refresh': ['a', 0x12, '<LF>', '<KEY_UP>']}
|
bindings = {'refresh': ['a', 0x12, '<LF>', '<KEY_UP>']}
|
||||||
|
bindings2 = {'upvote': ['b', 0x13, '<KEY_DOWN>']}
|
||||||
|
keymap._keymap = {}
|
||||||
keymap.set_bindings(bindings)
|
keymap.set_bindings(bindings)
|
||||||
assert keymap.get('refresh')
|
assert keymap.get('refresh')
|
||||||
with pytest.raises(exceptions.ConfigError) as e:
|
with pytest.raises(exceptions.ConfigError) as e:
|
||||||
keymap.get('upvote')
|
keymap.get('upvote')
|
||||||
assert 'UPVOTE' in six.text_type(e)
|
assert 'UPVOTE' in six.text_type(e)
|
||||||
|
keymap.set_bindings(bindings2)
|
||||||
|
assert keymap.get('refresh')
|
||||||
|
assert keymap.get('upvote')
|
||||||
|
|
||||||
# Strings should be parsed correctly into keys
|
# Strings should be parsed correctly into keys
|
||||||
assert KeyMap.parse('a') == 97
|
assert KeyMap.parse('a') == 97
|
||||||
@@ -589,4 +593,4 @@ def test_objects_navigator_flip():
|
|||||||
nav.flip(3)
|
nav.flip(3)
|
||||||
assert nav.page_index == 2
|
assert nav.page_index == 2
|
||||||
assert nav.cursor_index == 3
|
assert nav.cursor_index == 3
|
||||||
assert not nav.inverted
|
assert not nav.inverted
|
||||||
|
|||||||
@@ -119,4 +119,4 @@ def test_page_authenticated(reddit, terminal, config, oauth, refresh_token):
|
|||||||
# Logout
|
# Logout
|
||||||
terminal.stdscr.getch.return_value = ord('y')
|
terminal.stdscr.getch.return_value = ord('y')
|
||||||
page.controller.trigger('u')
|
page.controller.trigger('u')
|
||||||
assert not reddit.is_oauth_session()
|
assert not reddit.is_oauth_session()
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ def test_subreddit_title(subreddit_page, terminal, capsys):
|
|||||||
|
|
||||||
|
|
||||||
def test_subreddit_search(subreddit_page, terminal):
|
def test_subreddit_search(subreddit_page, terminal):
|
||||||
|
window = terminal.stdscr.subwin
|
||||||
|
|
||||||
# Search the current subreddit
|
# Search the current subreddit
|
||||||
with mock.patch.object(terminal, 'prompt_input'):
|
with mock.patch.object(terminal, 'prompt_input'):
|
||||||
@@ -96,12 +97,31 @@ def test_subreddit_search(subreddit_page, terminal):
|
|||||||
assert terminal.prompt_input.called
|
assert terminal.prompt_input.called
|
||||||
assert not terminal.loader.exception
|
assert not terminal.loader.exception
|
||||||
|
|
||||||
|
# The page title should display the query
|
||||||
|
subreddit_page.draw()
|
||||||
|
title = 'Searching /r/python: search term'.encode('utf-8')
|
||||||
|
window.addstr.assert_any_call(0, 0, title)
|
||||||
|
|
||||||
|
# Ordering the results should preserve the query
|
||||||
|
window.addstr.reset_mock()
|
||||||
|
subreddit_page.refresh_content(order='hot')
|
||||||
|
subreddit_page.refresh_content(order='top-all')
|
||||||
|
subreddit_page.refresh_content(order='new')
|
||||||
|
assert subreddit_page.content.name == '/r/python'
|
||||||
|
assert subreddit_page.content.query == 'search term'
|
||||||
|
assert not terminal.loader.exception
|
||||||
|
|
||||||
# Searching with an empty query shouldn't crash
|
# Searching with an empty query shouldn't crash
|
||||||
with mock.patch.object(terminal, 'prompt_input'):
|
with mock.patch.object(terminal, 'prompt_input'):
|
||||||
terminal.prompt_input.return_value = None
|
terminal.prompt_input.return_value = None
|
||||||
subreddit_page.controller.trigger('f')
|
subreddit_page.controller.trigger('f')
|
||||||
assert not terminal.loader.exception
|
assert not terminal.loader.exception
|
||||||
|
|
||||||
|
# Changing to a new subreddit should clear the query
|
||||||
|
window.addstr.reset_mock()
|
||||||
|
subreddit_page.refresh_content(name='/r/learnpython')
|
||||||
|
assert subreddit_page.content.query is None
|
||||||
|
|
||||||
|
|
||||||
def test_subreddit_prompt(subreddit_page, terminal):
|
def test_subreddit_prompt(subreddit_page, terminal):
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user