Amazing-Python-Scripts
88 строк · 3.0 Кб
1import shlex
2
3from cecmap.commands import Command
4from cecmap.keycodes import KEYCODES
5
6
7class Config:
8
9def __init__(self, keycodes=KEYCODES):
10self.keycodes = keycodes.copy()
11self.bindings = {'*': {}}
12self.mode = None
13self.modes = []
14
15def bind(self, keybindings):
16"""Set keybindings according to mode."""
17for mode, bindings in keybindings.items():
18if mode != '*':
19if self.mode is None:
20self.mode = mode
21if mode not in self.modes:
22self.modes.append(mode)
23self.bindings[mode] = {}
24self.bindings[mode].update(bindings)
25
26def keybinding(self, mode, keycode):
27"""Get command associated to keycode in current mode."""
28default = self.bindings['*'].get(keycode)
29handler = self.bindings[mode].get(keycode, default)
30return handler
31
32def load(self, parser, client):
33"""
34Load keycodes and keybindings from config parser.
35
36Returns a new ``Config`` object that is a copy of this config merged
37with the loaded settings.
38
39See the ``cecmap/config/default.cfg`` file for example.
40"""
41keycodes = self.keycodes.copy()
42modes = {}
43
44if parser.has_section('keycode'):
45section = parser['keycode']
46for name, value in section.items():
47if not value.isnumeric():
48raise ValueError(
49"Invalid key code for {}: {!r}".format(name, value))
50keycodes[name] = int(value)
51
52for section in parser.sections():
53if section.lower().startswith('mode.'):
54mode_name = section[len('mode.'):]
55modes[mode_name] = parser.items(section)
56elif section != 'keycode':
57print("Warning: Unused section in config file:", section)
58
59all_modes = set(self.modes) | set(modes)
60keybindings = {mode: {} for mode in modes}
61
62for mode, items in modes.items():
63for key, binding in items:
64command, *args = shlex.split(binding)
65
66if key.isnumeric():
67keycode = int(key)
68elif key in keycodes:
69keycode = keycodes[key]
70else:
71raise ValueError("Undefined key: {!r}".format(key))
72
73if command == 'switch' and args and args[0] not in all_modes:
74raise ValueError("Unknown mode: {!r}".format(args[0]))
75
76if command in Command.commands:
77command = Command.commands[command](client, *args)
78else:
79raise ValueError(
80"Invalid command: {!r} = {!r}".format(key, binding))
81
82keybindings[mode][keycode] = command
83
84config = Config()
85config.keycodes = keycodes
86config.bind(self.bindings)
87config.bind(keybindings)
88return config
89