Added binding convention to the config file.

This commit is contained in:
Michael Lazar
2016-02-09 00:43:41 -08:00
parent 2a9bf95947
commit 2f093e47a8
3 changed files with 111 additions and 9 deletions

View File

@@ -1,10 +1,13 @@
# -*- 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
@@ -195,12 +198,12 @@ class Config(object):
return cls._parse_rtv_file(config) return cls._parse_rtv_file(config)
@staticmethod @classmethod
def _parse_rtv_file(config): def _parse_rtv_file(cls, config):
out = {} rtv = {}
if config.has_section('rtv'): if config.has_section('rtv'):
out = dict(config.items('rtv')) rtv = dict(config.items('rtv'))
params = { params = {
'ascii': partial(config.getboolean, 'rtv'), 'ascii': partial(config.getboolean, 'rtv'),
@@ -208,13 +211,41 @@ class Config(object):
'persistent': partial(config.getboolean, 'rtv'), 'persistent': partial(config.getboolean, 'rtv'),
'history_size': partial(config.getint, 'rtv'), 'history_size': partial(config.getint, 'rtv'),
'oauth_redirect_port': partial(config.getint, 'rtv'), 'oauth_redirect_port': partial(config.getint, 'rtv'),
'oauth_scope': lambda x: out[x].split(',') 'oauth_scope': lambda x: rtv[x].split(',')
} }
for key, func in params.items(): for key, func in params.items():
if key in out: if key in rtv:
out[key] = func(key) rtv[key] = func(key)
return out
bindings = {}
if config.has_section('bindings'):
bindings = dict(config.items('bindings'))
for name, keys in bindings.items():
bindings[name] = [cls._parse_key(key) for key in keys.split(',')]
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):

View File

@@ -49,4 +49,69 @@ oauth_redirect_uri = http://127.0.0.1:65000/
oauth_redirect_port = 65000 oauth_redirect_port = 65000
; Access permissions that will be requested. ; Access permissions that will be requested.
oauth_scope = edit,history,identity,mysubreddits,privatemessages,read,report,save,submit,subscribe,vote oauth_scope = edit,history,identity,mysubreddits,privatemessages,read,report,save,submit,subscribe,vote
[bindings]
##############
# Key Bindings
##############
; Multiple keys that represent the same command should be listed as a comma
; seperated list. The a mixture of the following notations should be used to
; describe keys.
;
; 1.) Plain keys can be represented by either uppercase/lowercase characters
; or the hexadecimal codes referring their ascii codes. For reference, see
; https://en.wikipedia.org/wiki/ASCII#ASCII_printable_code_chart
; e.g. Q, q, 1, ?
; e.g. 0x20 (space), 0x3c (less-than sign)
;
; 2.) Special ascii control codes should be surrounded with <>. For reference,
; see https://en.wikipedia.org/wiki/ASCII#ASCII_control_code_chart
; e.g. <LF> (enter), <ESC> (escape)
;
; 3.) Other special keys are defined by curses, they should be surrounded by <>
; and prefixed with KEY_. For reference, see
; https://docs.python.org/2/library/curses.html#constants
; e.g. <KEY_LEFT> (left arrow), <KEY_F5>, <KEY_NPAGE> (page down)
;
; Notes:
; - Curses <KEY_ENTER> is unreliable and should always be used in conjunction
; with <LF>.
; General keys
EXIT = q
FORCE_EXIT = Q
HELP = ?
SORT_HOT = 1
SORT_TOP = 2
SORT_RISING = 3
SORT_NEW = 4
SORT_CONTROVERSIAL = 5
MOVE_UP = k, <KEY_UP>
MOVE_DOWN = j, <KEY_DOWN>
PAGE_UP = m, <KEY_PPAGE>
PAGE_DOWN = n, <KEY_NPAGE>
UPVOTE = a
DOWNVOTE = z
LOGIN = u
DELETE = d
EDIT = e
INBOX = i
REFRESH = r, <KEY_F5>
; Submission page
SUBMISSION_TOGGLE_COMMENTS = l, 0x20, <KEY_RIGHT>
SUBMISSION_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>
SUBMISSION_POST = c
SUBMISSION_EXIT = h, <KEY_LEFT>
; Subreddit page
SUBREDDIT_SEARCH = f
SUBREDDIT_PROMPT = /
SUBREDDIT_POST = c
SUBREDDIT_OPEN = l, <KEY_RIGHT>
SUBREDDIT_OPEN_IN_BROWSER = o, <LF>, <KEY_ENTER>, <KEY_ENTER>
; Subscription page
SUBSCRIPTION_SELECT = l, <LF>, <KEY_ENTER>, <KEY_RIGHT>
SUBSCRIPTION_EXIT = h, s, <ESC>, <KEY_LEFT>

View File

@@ -103,6 +103,12 @@ def test_config_from_file():
assert config.config == args assert config.config == args
def test_config_keys():
config = Config()
pass
def test_config_refresh_token(): def test_config_refresh_token():
"Ensure that the refresh token can be loaded, saved, and removed" "Ensure that the refresh token can be loaded, saved, and removed"