Almost functional.
This commit is contained in:
@@ -26,6 +26,7 @@ _logger = logging.getLogger(__name__)
|
|||||||
# ptrace_scope to 0 in /etc/sysctl.d/10-ptrace.conf.
|
# ptrace_scope to 0 in /etc/sysctl.d/10-ptrace.conf.
|
||||||
# http://blog.mellenthin.de/archives/2010/10/18/gdb-attach-fails
|
# http://blog.mellenthin.de/archives/2010/10/18/gdb-attach-fails
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"Main entry point"
|
"Main entry point"
|
||||||
|
|
||||||
@@ -38,12 +39,13 @@ def main():
|
|||||||
sys.stdout.write('\x1b]2;{0}\x07'.format(title))
|
sys.stdout.write('\x1b]2;{0}\x07'.format(title))
|
||||||
|
|
||||||
args = Config.get_args()
|
args = Config.get_args()
|
||||||
fargs = Config.get_file(args.get('config'))
|
fargs, bindings = Config.get_file(args.get('config'))
|
||||||
|
|
||||||
# Apply the file config first, then overwrite with any command line args
|
# Apply the file config first, then overwrite with any command line args
|
||||||
config = Config()
|
config = Config()
|
||||||
config.update(**fargs)
|
config.update(**fargs)
|
||||||
config.update(**args)
|
config.update(**args)
|
||||||
|
config.keymap.update(**bindings)
|
||||||
|
|
||||||
# Copy the default config file and quit
|
# Copy the default config file and quit
|
||||||
if config['copy_config']:
|
if config['copy_config']:
|
||||||
|
|||||||
@@ -1,19 +1,17 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import curses
|
|
||||||
import codecs
|
import codecs
|
||||||
import shutil
|
import shutil
|
||||||
import argparse
|
import argparse
|
||||||
from curses import ascii
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from six.moves import configparser
|
from six.moves import configparser
|
||||||
|
|
||||||
from . import docs, __version__
|
from . import docs, __version__
|
||||||
|
from .objects import KeyMap
|
||||||
|
|
||||||
PACKAGE = os.path.dirname(__file__)
|
PACKAGE = os.path.dirname(__file__)
|
||||||
HOME = os.path.expanduser('~')
|
HOME = os.path.expanduser('~')
|
||||||
@@ -115,7 +113,10 @@ class Config(object):
|
|||||||
self.history_file = history_file
|
self.history_file = history_file
|
||||||
self.token_file = token_file
|
self.token_file = token_file
|
||||||
self.config = kwargs
|
self.config = kwargs
|
||||||
self.default = self.get_file(DEFAULT_CONFIG)
|
|
||||||
|
default, bindings = self.get_file(DEFAULT_CONFIG)
|
||||||
|
self.default = default
|
||||||
|
self.keymap = KeyMap(bindings)
|
||||||
|
|
||||||
# `refresh_token` and `history` are saved/loaded at separate locations,
|
# `refresh_token` and `history` are saved/loaded at separate locations,
|
||||||
# so they are treated differently from the rest of the config options.
|
# so they are treated differently from the rest of the config options.
|
||||||
@@ -198,8 +199,8 @@ class Config(object):
|
|||||||
|
|
||||||
return cls._parse_rtv_file(config)
|
return cls._parse_rtv_file(config)
|
||||||
|
|
||||||
@classmethod
|
@staticmethod
|
||||||
def _parse_rtv_file(cls, config):
|
def _parse_rtv_file(config):
|
||||||
|
|
||||||
rtv = {}
|
rtv = {}
|
||||||
if config.has_section('rtv'):
|
if config.has_section('rtv'):
|
||||||
@@ -213,7 +214,6 @@ class Config(object):
|
|||||||
'oauth_redirect_port': partial(config.getint, 'rtv'),
|
'oauth_redirect_port': partial(config.getint, 'rtv'),
|
||||||
'oauth_scope': lambda x: rtv[x].split(',')
|
'oauth_scope': lambda x: rtv[x].split(',')
|
||||||
}
|
}
|
||||||
|
|
||||||
for key, func in params.items():
|
for key, func in params.items():
|
||||||
if key in rtv:
|
if key in rtv:
|
||||||
rtv[key] = func(key)
|
rtv[key] = func(key)
|
||||||
@@ -223,30 +223,10 @@ class Config(object):
|
|||||||
bindings = dict(config.items('bindings'))
|
bindings = dict(config.items('bindings'))
|
||||||
|
|
||||||
for name, keys in bindings.items():
|
for name, keys in bindings.items():
|
||||||
bindings[name] = [cls._parse_key(key) for key in keys.split(',')]
|
bindings[name] = [key.strip() for key in keys.split(',')]
|
||||||
|
|
||||||
return rtv, bindings
|
return rtv, bindings
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _parse_key(key):
|
|
||||||
"""
|
|
||||||
Parse a key represented by a string return its character code.
|
|
||||||
"""
|
|
||||||
|
|
||||||
key = key.strip()
|
|
||||||
if re.match('[<]KEY_.*[>]', key):
|
|
||||||
# Curses control character
|
|
||||||
return getattr(curses, key[1:-1])
|
|
||||||
elif re.match('[<].*[>]', key):
|
|
||||||
# Ascii control character
|
|
||||||
return getattr(ascii, key[1:-1])
|
|
||||||
elif key.startswith('0x'):
|
|
||||||
# Ascii hex code
|
|
||||||
return int(key, 16)
|
|
||||||
else:
|
|
||||||
# Ascii character
|
|
||||||
return ord(key)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _ensure_filepath(filename):
|
def _ensure_filepath(filename):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import re
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import curses
|
import curses
|
||||||
@@ -9,7 +10,9 @@ import inspect
|
|||||||
import weakref
|
import weakref
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
|
from curses import ascii
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
from collections import defaultdict
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import praw
|
import praw
|
||||||
@@ -502,6 +505,11 @@ class Controller(object):
|
|||||||
>>> def func(self, *args)
|
>>> def func(self, *args)
|
||||||
>>> ...
|
>>> ...
|
||||||
|
|
||||||
|
Register a KeyBinding that can be defined later by the config file
|
||||||
|
>>> @Controller.register(KeyMap.UPVOTE)
|
||||||
|
>>> def upvote(self, *args)
|
||||||
|
>> ...
|
||||||
|
|
||||||
Register a default behavior by using `None`.
|
Register a default behavior by using `None`.
|
||||||
>>> @Controller.register(None)
|
>>> @Controller.register(None)
|
||||||
>>> def default_func(self, *args)
|
>>> def default_func(self, *args)
|
||||||
@@ -515,13 +523,22 @@ class Controller(object):
|
|||||||
|
|
||||||
character_map = {}
|
character_map = {}
|
||||||
|
|
||||||
def __init__(self, instance):
|
def __init__(self, instance, keymap=None):
|
||||||
|
|
||||||
self.instance = instance
|
self.instance = instance
|
||||||
# Build a list of parent controllers that follow the object's MRO to
|
# Build a list of parent controllers that follow the object's MRO
|
||||||
# check if any parent controllers have registered the keypress
|
# to check if any parent controllers have registered the keypress
|
||||||
self.parents = inspect.getmro(type(self))[:-1]
|
self.parents = inspect.getmro(type(self))[:-1]
|
||||||
|
|
||||||
|
# Update the character map with the bindings defined in the keymap
|
||||||
|
if not keymap:
|
||||||
|
for controller in [self] + self.parents:
|
||||||
|
for binding, func in controller.character_map.items():
|
||||||
|
if isinstance(binding, KeyBinding):
|
||||||
|
# TODO: Raise error if trying to overwrite a char
|
||||||
|
mappings = {char: func for char in keymap.get(binding)}
|
||||||
|
self.character_map.update(mappings)
|
||||||
|
|
||||||
def trigger(self, char, *args, **kwargs):
|
def trigger(self, char, *args, **kwargs):
|
||||||
|
|
||||||
if isinstance(char, six.string_types) and len(char) == 1:
|
if isinstance(char, six.string_types) and len(char) == 1:
|
||||||
@@ -551,4 +568,53 @@ class Controller(object):
|
|||||||
else:
|
else:
|
||||||
cls.character_map[char] = f
|
cls.character_map[char] = f
|
||||||
return f
|
return f
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
|
||||||
|
class KeyBinding(object):
|
||||||
|
|
||||||
|
def __init__(self, val):
|
||||||
|
self.val = val.upper()
|
||||||
|
|
||||||
|
|
||||||
|
class KeyMapMeta(type):
|
||||||
|
|
||||||
|
def __getattr__(cls, key):
|
||||||
|
return KeyBinding(key)
|
||||||
|
|
||||||
|
|
||||||
|
@six.add_metaclass(KeyMapMeta)
|
||||||
|
class KeyMap(object):
|
||||||
|
|
||||||
|
def __init__(self, bindings):
|
||||||
|
self._bindings = defaultdict(list)
|
||||||
|
self.update(bindings)
|
||||||
|
|
||||||
|
def update(self, **bindings):
|
||||||
|
for command, keys in bindings:
|
||||||
|
binding = KeyBinding(command)
|
||||||
|
self._bindings[binding] = [self._parse_key(key) for key in keys]
|
||||||
|
|
||||||
|
def get(self, binding):
|
||||||
|
return self._bindings[binding]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _parse_key(key):
|
||||||
|
"""
|
||||||
|
Parse a key represented by a string and return its character code.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if isinstance(key, int):
|
||||||
|
return key
|
||||||
|
elif re.match('[<]KEY_.*[>]', key):
|
||||||
|
# Curses control character
|
||||||
|
return getattr(curses, key[1:-1])
|
||||||
|
elif re.match('[<].*[>]', key):
|
||||||
|
# Ascii control character
|
||||||
|
return getattr(ascii, key[1:-1])
|
||||||
|
elif key.startswith('0x'):
|
||||||
|
# Ascii hex code
|
||||||
|
return int(key, 16)
|
||||||
|
else:
|
||||||
|
# Ascii character
|
||||||
|
return ord(key)
|
||||||
38
rtv/page.py
38
rtv/page.py
@@ -9,7 +9,7 @@ from functools import wraps
|
|||||||
from kitchen.text.display import textual_width
|
from kitchen.text.display import textual_width
|
||||||
|
|
||||||
from . import docs
|
from . import docs
|
||||||
from .objects import Controller, Color
|
from .objects import Controller, Color, KeyMap
|
||||||
|
|
||||||
|
|
||||||
def logged_in(f):
|
def logged_in(f):
|
||||||
@@ -68,60 +68,60 @@ class Page(object):
|
|||||||
ch = self.term.stdscr.getch()
|
ch = self.term.stdscr.getch()
|
||||||
self.controller.trigger(ch)
|
self.controller.trigger(ch)
|
||||||
|
|
||||||
@PageController.register('q')
|
@PageController.register(KeyMap.EXIT)
|
||||||
def exit(self):
|
def exit(self):
|
||||||
if self.term.prompt_y_or_n('Do you really want to quit? (y/n): '):
|
if self.term.prompt_y_or_n('Do you really want to quit? (y/n): '):
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
@PageController.register('Q')
|
@PageController.register(KeyMap.FORCE_EXIT)
|
||||||
def force_exit(self):
|
def force_exit(self):
|
||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
@PageController.register('?')
|
@PageController.register(KeyMap.HELP)
|
||||||
def show_help(self):
|
def show_help(self):
|
||||||
self.term.show_notification(docs.HELP.strip().splitlines())
|
self.term.show_notification(docs.HELP.strip().splitlines())
|
||||||
|
|
||||||
@PageController.register('1')
|
@PageController.register(KeyMap.SORT_HOT)
|
||||||
def sort_content_hot(self):
|
def sort_content_hot(self):
|
||||||
self.refresh_content(order='hot')
|
self.refresh_content(order='hot')
|
||||||
|
|
||||||
@PageController.register('2')
|
@PageController.register(KeyMap.SORT_TOP)
|
||||||
def sort_content_top(self):
|
def sort_content_top(self):
|
||||||
self.refresh_content(order='top')
|
self.refresh_content(order='top')
|
||||||
|
|
||||||
@PageController.register('3')
|
@PageController.register(KeyMap.SORT_RISING)
|
||||||
def sort_content_rising(self):
|
def sort_content_rising(self):
|
||||||
self.refresh_content(order='rising')
|
self.refresh_content(order='rising')
|
||||||
|
|
||||||
@PageController.register('4')
|
@PageController.register(KeyMap.SORT_NEW)
|
||||||
def sort_content_new(self):
|
def sort_content_new(self):
|
||||||
self.refresh_content(order='new')
|
self.refresh_content(order='new')
|
||||||
|
|
||||||
@PageController.register('5')
|
@PageController.register(KeyMap.SORT_CONTROVERSIAL)
|
||||||
def sort_content_controversial(self):
|
def sort_content_controversial(self):
|
||||||
self.refresh_content(order='controversial')
|
self.refresh_content(order='controversial')
|
||||||
|
|
||||||
@PageController.register(curses.KEY_UP, 'k')
|
@PageController.register(KeyMap.MOVE_UP)
|
||||||
def move_cursor_up(self):
|
def move_cursor_up(self):
|
||||||
self._move_cursor(-1)
|
self._move_cursor(-1)
|
||||||
self.clear_input_queue()
|
self.clear_input_queue()
|
||||||
|
|
||||||
@PageController.register(curses.KEY_DOWN, 'j')
|
@PageController.register(KeyMap.MOVE_DOWN)
|
||||||
def move_cursor_down(self):
|
def move_cursor_down(self):
|
||||||
self._move_cursor(1)
|
self._move_cursor(1)
|
||||||
self.clear_input_queue()
|
self.clear_input_queue()
|
||||||
|
|
||||||
@PageController.register('m', curses.KEY_PPAGE)
|
@PageController.register(KeyMap.PAGE_UP)
|
||||||
def move_page_up(self):
|
def move_page_up(self):
|
||||||
self._move_page(-1)
|
self._move_page(-1)
|
||||||
self.clear_input_queue()
|
self.clear_input_queue()
|
||||||
|
|
||||||
@PageController.register('n', curses.KEY_NPAGE)
|
@PageController.register(KeyMap.PAGE_DOWN)
|
||||||
def move_page_down(self):
|
def move_page_down(self):
|
||||||
self._move_page(1)
|
self._move_page(1)
|
||||||
self.clear_input_queue()
|
self.clear_input_queue()
|
||||||
|
|
||||||
@PageController.register('a')
|
@PageController.register(KeyMap.UPVOTE)
|
||||||
@logged_in
|
@logged_in
|
||||||
def upvote(self):
|
def upvote(self):
|
||||||
data = self.content.get(self.nav.absolute_index)
|
data = self.content.get(self.nav.absolute_index)
|
||||||
@@ -138,7 +138,7 @@ class Page(object):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
data['likes'] = True
|
data['likes'] = True
|
||||||
|
|
||||||
@PageController.register('z')
|
@PageController.register(KeyMap.DOWNVOTE)
|
||||||
@logged_in
|
@logged_in
|
||||||
def downvote(self):
|
def downvote(self):
|
||||||
data = self.content.get(self.nav.absolute_index)
|
data = self.content.get(self.nav.absolute_index)
|
||||||
@@ -155,7 +155,7 @@ class Page(object):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
data['likes'] = None
|
data['likes'] = None
|
||||||
|
|
||||||
@PageController.register('u')
|
@PageController.register(KeyMap.LOGIN)
|
||||||
def login(self):
|
def login(self):
|
||||||
"""
|
"""
|
||||||
Prompt to log into the user's account, or log out of the current
|
Prompt to log into the user's account, or log out of the current
|
||||||
@@ -169,7 +169,7 @@ class Page(object):
|
|||||||
else:
|
else:
|
||||||
self.oauth.authorize()
|
self.oauth.authorize()
|
||||||
|
|
||||||
@PageController.register('d')
|
@PageController.register(KeyMap.DELETE)
|
||||||
@logged_in
|
@logged_in
|
||||||
def delete_item(self):
|
def delete_item(self):
|
||||||
"""
|
"""
|
||||||
@@ -193,7 +193,7 @@ class Page(object):
|
|||||||
if self.term.loader.exception is None:
|
if self.term.loader.exception is None:
|
||||||
self.refresh_content()
|
self.refresh_content()
|
||||||
|
|
||||||
@PageController.register('e')
|
@PageController.register(KeyMap.EDIT)
|
||||||
@logged_in
|
@logged_in
|
||||||
def edit(self):
|
def edit(self):
|
||||||
"""
|
"""
|
||||||
@@ -228,7 +228,7 @@ class Page(object):
|
|||||||
if self.term.loader.exception is None:
|
if self.term.loader.exception is None:
|
||||||
self.refresh_content()
|
self.refresh_content()
|
||||||
|
|
||||||
@PageController.register('i')
|
@PageController.register(KeyMap.INBOX)
|
||||||
@logged_in
|
@logged_in
|
||||||
def get_inbox(self):
|
def get_inbox(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ INBOX = i
|
|||||||
REFRESH = r, <KEY_F5>
|
REFRESH = r, <KEY_F5>
|
||||||
|
|
||||||
; Submission page
|
; Submission page
|
||||||
SUBMISSION_TOGGLE_COMMENTS = l, 0x20, <KEY_RIGHT>
|
SUBMISSION_TOGGLE_COMMENT = l, 0x20, <KEY_RIGHT>
|
||||||
SUBMISSION_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>
|
SUBMISSION_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>
|
||||||
SUBMISSION_POST = c
|
SUBMISSION_POST = c
|
||||||
SUBMISSION_EXIT = h, <KEY_LEFT>
|
SUBMISSION_EXIT = h, <KEY_LEFT>
|
||||||
@@ -111,6 +111,7 @@ SUBREDDIT_PROMPT = /
|
|||||||
SUBREDDIT_POST = c
|
SUBREDDIT_POST = c
|
||||||
SUBREDDIT_OPEN = l, <KEY_RIGHT>
|
SUBREDDIT_OPEN = l, <KEY_RIGHT>
|
||||||
SUBREDDIT_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>, <KEY_ENTER>
|
SUBREDDIT_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>, <KEY_ENTER>
|
||||||
|
SUBREDDIT_OPEN_SUBSCRIPTIONS = s
|
||||||
|
|
||||||
; Subscription page
|
; Subscription page
|
||||||
SUBSCRIPTION_SELECT = l, <LF>, <KEY_ENTER>, <KEY_RIGHT>
|
SUBSCRIPTION_SELECT = l, <LF>, <KEY_ENTER>, <KEY_RIGHT>
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import curses
|
|||||||
from . import docs
|
from . import docs
|
||||||
from .content import SubmissionContent
|
from .content import SubmissionContent
|
||||||
from .page import Page, PageController, logged_in
|
from .page import Page, PageController, logged_in
|
||||||
from .objects import Navigator, Color
|
from .objects import Navigator, Color, KeyMap
|
||||||
from .terminal import Terminal
|
|
||||||
|
|
||||||
|
|
||||||
class SubmissionController(PageController):
|
class SubmissionController(PageController):
|
||||||
@@ -29,7 +28,7 @@ class SubmissionPage(Page):
|
|||||||
# Start at the submission post, which is indexed as -1
|
# Start at the submission post, which is indexed as -1
|
||||||
self.nav = Navigator(self.content.get, page_index=-1)
|
self.nav = Navigator(self.content.get, page_index=-1)
|
||||||
|
|
||||||
@SubmissionController.register(curses.KEY_RIGHT, 'l', ' ')
|
@SubmissionController.register(KeyMap.SUBMISSION_TOGGLE_COMMENT)
|
||||||
def toggle_comment(self):
|
def toggle_comment(self):
|
||||||
"Toggle the selected comment tree between visible and hidden"
|
"Toggle the selected comment tree between visible and hidden"
|
||||||
|
|
||||||
@@ -41,13 +40,13 @@ class SubmissionPage(Page):
|
|||||||
# causes the cursor index to go out of bounds.
|
# causes the cursor index to go out of bounds.
|
||||||
self.nav.page_index, self.nav.cursor_index = current_index, 0
|
self.nav.page_index, self.nav.cursor_index = current_index, 0
|
||||||
|
|
||||||
@SubmissionController.register(curses.KEY_LEFT, 'h')
|
@SubmissionController.register(KeyMap.SUBMISSION_EXIT)
|
||||||
def exit_submission(self):
|
def exit_submission(self):
|
||||||
"Close the submission and return to the subreddit page"
|
"Close the submission and return to the subreddit page"
|
||||||
|
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
@SubmissionController.register(curses.KEY_F5, 'r')
|
@SubmissionController.register(KeyMap.REFRESH)
|
||||||
def refresh_content(self, order=None, name=None):
|
def refresh_content(self, order=None, name=None):
|
||||||
"Re-download comments and reset the page index"
|
"Re-download comments and reset the page index"
|
||||||
|
|
||||||
@@ -60,7 +59,7 @@ class SubmissionPage(Page):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.nav = Navigator(self.content.get, page_index=-1)
|
self.nav = Navigator(self.content.get, page_index=-1)
|
||||||
|
|
||||||
@SubmissionController.register(curses.KEY_ENTER, Terminal.RETURN, 'o')
|
@SubmissionController.register(KeyMap.SUBMISSION_OPEN_IN_BROWSER)
|
||||||
def open_link(self):
|
def open_link(self):
|
||||||
"Open the selected item with the webbrowser"
|
"Open the selected item with the webbrowser"
|
||||||
|
|
||||||
@@ -71,7 +70,7 @@ class SubmissionPage(Page):
|
|||||||
else:
|
else:
|
||||||
self.term.flash()
|
self.term.flash()
|
||||||
|
|
||||||
@SubmissionController.register('c')
|
@SubmissionController.register(KeyMap.SUBMISSION_POST)
|
||||||
@logged_in
|
@logged_in
|
||||||
def add_comment(self):
|
def add_comment(self):
|
||||||
"""
|
"""
|
||||||
@@ -114,7 +113,7 @@ class SubmissionPage(Page):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.refresh_content()
|
self.refresh_content()
|
||||||
|
|
||||||
@SubmissionController.register('d')
|
@SubmissionController.register(KeyMap.DELETE)
|
||||||
@logged_in
|
@logged_in
|
||||||
def delete_comment(self):
|
def delete_comment(self):
|
||||||
"Delete a comment as long as it is not the current submission"
|
"Delete a comment as long as it is not the current submission"
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import curses
|
|||||||
from . import docs
|
from . import docs
|
||||||
from .content import SubredditContent
|
from .content import SubredditContent
|
||||||
from .page import Page, PageController, logged_in
|
from .page import Page, PageController, logged_in
|
||||||
from .objects import Navigator, Color
|
from .objects import Navigator, Color, KeyMap
|
||||||
from .submission import SubmissionPage
|
from .submission import SubmissionPage
|
||||||
from .subscription import SubscriptionPage
|
from .subscription import SubscriptionPage
|
||||||
from .terminal import Terminal
|
from .terminal import Terminal
|
||||||
@@ -31,7 +31,7 @@ class SubredditPage(Page):
|
|||||||
self.controller = SubredditController(self)
|
self.controller = SubredditController(self)
|
||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
|
|
||||||
@SubredditController.register(curses.KEY_F5, 'r')
|
@SubredditController.register(KeyMap.REFRESH)
|
||||||
def refresh_content(self, order=None, name=None):
|
def refresh_content(self, order=None, name=None):
|
||||||
"Re-download all submissions and reset the page index"
|
"Re-download all submissions and reset the page index"
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ class SubredditPage(Page):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
|
|
||||||
@SubredditController.register('f')
|
@SubredditController.register(KeyMap.SUBREDDIT_SEARCH)
|
||||||
def search_subreddit(self, name=None):
|
def search_subreddit(self, name=None):
|
||||||
"Open a prompt to search the given subreddit"
|
"Open a prompt to search the given subreddit"
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ class SubredditPage(Page):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
|
|
||||||
@SubredditController.register('/')
|
@SubredditController.register(KeyMap.SUBREDDIT_PROMPT)
|
||||||
def prompt_subreddit(self):
|
def prompt_subreddit(self):
|
||||||
"Open a prompt to navigate to a different subreddit"
|
"Open a prompt to navigate to a different subreddit"
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ class SubredditPage(Page):
|
|||||||
if name is not None:
|
if name is not None:
|
||||||
self.refresh_content(order='ignore', name=name)
|
self.refresh_content(order='ignore', name=name)
|
||||||
|
|
||||||
@SubredditController.register(curses.KEY_RIGHT, 'l')
|
@SubredditController.register(KeyMap.SUBREDDIT_OPEN)
|
||||||
def open_submission(self, url=None):
|
def open_submission(self, url=None):
|
||||||
"Select the current submission to view posts"
|
"Select the current submission to view posts"
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ class SubredditPage(Page):
|
|||||||
if data.get('url_type') == 'selfpost':
|
if data.get('url_type') == 'selfpost':
|
||||||
self.config.history.add(data['url_full'])
|
self.config.history.add(data['url_full'])
|
||||||
|
|
||||||
@SubredditController.register(curses.KEY_ENTER, Terminal.RETURN, 'o')
|
@SubredditController.register(KeyMap.SUBREDDIT_OPEN_IN_BROWSER)
|
||||||
def open_link(self):
|
def open_link(self):
|
||||||
"Open a link with the webbrowser"
|
"Open a link with the webbrowser"
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ class SubredditPage(Page):
|
|||||||
self.term.open_browser(data['url_full'])
|
self.term.open_browser(data['url_full'])
|
||||||
self.config.history.add(data['url_full'])
|
self.config.history.add(data['url_full'])
|
||||||
|
|
||||||
@SubredditController.register('c')
|
@SubredditController.register(KeyMap.SUBREDDIT_POST)
|
||||||
@logged_in
|
@logged_in
|
||||||
def post_submission(self):
|
def post_submission(self):
|
||||||
"Post a new submission to the given subreddit"
|
"Post a new submission to the given subreddit"
|
||||||
@@ -145,7 +145,7 @@ class SubredditPage(Page):
|
|||||||
|
|
||||||
self.refresh_content()
|
self.refresh_content()
|
||||||
|
|
||||||
@SubredditController.register('s')
|
@SubredditController.register(KeyMap.SUBREDDIT_OPEN_SUBSCRIPTIONS)
|
||||||
@logged_in
|
@logged_in
|
||||||
def open_subscriptions(self):
|
def open_subscriptions(self):
|
||||||
"Open user subscriptions page"
|
"Open user subscriptions page"
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import curses
|
|||||||
|
|
||||||
from .page import Page, PageController
|
from .page import Page, PageController
|
||||||
from .content import SubscriptionContent
|
from .content import SubscriptionContent
|
||||||
from .objects import Color, Navigator
|
from .objects import Color, Navigator, KeyMap
|
||||||
from .terminal import Terminal
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionController(PageController):
|
class SubscriptionController(PageController):
|
||||||
@@ -23,7 +22,7 @@ class SubscriptionPage(Page):
|
|||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
self.subreddit_data = None
|
self.subreddit_data = None
|
||||||
|
|
||||||
@SubscriptionController.register(curses.KEY_F5, 'r')
|
@SubscriptionController.register(KeyMap.REFRESH)
|
||||||
def refresh_content(self, order=None, name=None):
|
def refresh_content(self, order=None, name=None):
|
||||||
"Re-download all subscriptions and reset the page index"
|
"Re-download all subscriptions and reset the page index"
|
||||||
|
|
||||||
@@ -38,15 +37,14 @@ class SubscriptionPage(Page):
|
|||||||
if not self.term.loader.exception:
|
if not self.term.loader.exception:
|
||||||
self.nav = Navigator(self.content.get)
|
self.nav = Navigator(self.content.get)
|
||||||
|
|
||||||
@SubscriptionController.register(curses.KEY_ENTER, Terminal.RETURN,
|
@SubscriptionController.register(KeyMap.SUBSCRIPTION_SELECT)
|
||||||
curses.KEY_RIGHT, 'l')
|
|
||||||
def select_subreddit(self):
|
def select_subreddit(self):
|
||||||
"Store the selected subreddit and return to the subreddit page"
|
"Store the selected subreddit and return to the subreddit page"
|
||||||
|
|
||||||
self.subreddit_data = self.content.get(self.nav.absolute_index)
|
self.subreddit_data = self.content.get(self.nav.absolute_index)
|
||||||
self.active = False
|
self.active = False
|
||||||
|
|
||||||
@SubscriptionController.register(curses.KEY_LEFT, Terminal.ESCAPE, 'h', 's')
|
@SubscriptionController.register(KeyMap.SUBSCRIPTION_CLOSE)
|
||||||
def close_subscriptions(self):
|
def close_subscriptions(self):
|
||||||
"Close subscriptions and return to the subreddit page"
|
"Close subscriptions and return to the subreddit page"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user