| LIRC libraries LinuxInfraredRemoteControl

database.py
Go to the documentation of this file.
1 ''' Read-only configuration database. '''
2
7
8
34
35
37
38
39 import glob
40 import os
41 import os.path
42 import subprocess
43 import sys
44
45 try:
46 import yaml
47 except ImportError:
48 _YAML_MSG = '''
49 "Cannot import the yaml library. Please install the python3
50 yaml package, on many distributions known as python3-PyYAML. It is also
51 available as a pypi package at https://pypi.python.org/pypi/PyYAML.'''
52 print(_YAML_MSG)
53 sys.exit(1)
54
55 import config
56
57
58 def _here(path):
59 ''' Return path added to current dir for __file__. '''
60 return os.path.join(os.path.dirname(os.path.abspath(__file__)), path)
61
62
63 def _load_kerneldrivers(configdir):
64 ''' Parse the kerneldrivers.yaml file, discard unavailable
65 drivers.
66 '''
67
68 with open(os.path.join(configdir, "kernel-drivers.yaml")) as f:
69 cf = yaml.load(f.read())
70 drivers = cf['drivers'].copy()
71 for driver in cf['drivers']:
72 if driver == 'default':
73 continue
74 with open('/dev/null', 'w') as f:
75 try:
76 subprocess.check_output([config.MODINFO, driver],
77 stderr=f)
78 except subprocess.CalledProcessError:
79 del drivers[driver]
80 return drivers
81
82
83 class ItemLookupError(Exception):
84 """A lookup failed, either too namy or no matches found. """
85 pass
86
87
88 class Config(object):
89 ''' The configuration selected, and it's sources. '''
90 # pylint: disable=too-many-instance-attributes
91
92 def __init__(self, cf=None):
93 self.device = None
94 self.driver = {}
95 self.config = {}
96 self.modinit = ""
97 self.modprobe = ""
98 self.lircd_conf = ""
99 self.lircmd_conf = ""
100 self.label = ""
101 if cf:
102 for key, value in cf.items():
103 setattr(self, key, value)
104
105 @property
106 def note(self):
107 ''' The possible note to display when selected. '''
108 if 'note' in self.config:
109 return self.config['note']
110 else:
111 return None
112
113
114 class Database(object):
115 ''' Reflects the *.yaml files in the configs/ directory. '''
116
117 def __init__(self, path=None, yamlpath=None):
118
119 if path and os.path.exists(path):
120 configdir = path
121 elif path:
122 raise FileNotFoundError(path)
123 elif os.path.exists(_here('configs')):
124 configdir = _here('configs')
125 elif os.path.exists(_here('../configs')):
126 configdir = _here('../configs')
127 elif os.path.exists(_here('../../configs')):
128 configdir = _here('../../configs')
129 else:
130 where = 'configs:../configs'
131 if path:
132 where += ':' + path
133 raise FileNotFoundError(where)
134 if not yamlpath:
135 yamlpath = configdir
136 db = {}
137 with open(os.path.join(yamlpath, "confs_by_driver.yaml")) as f:
138 cf = yaml.load(f.read())
139 db['lircd_by_driver'] = cf['lircd_by_driver'].copy()
140 db['lircmd_by_driver'] = cf['lircmd_by_driver'].copy()
141
142 db['kernel-drivers'] = _load_kerneldrivers(configdir)
143 db['drivers'] = db['kernel-drivers'].copy()
144 with open(os.path.join(yamlpath, "drivers.yaml")) as f:
145 cf = yaml.load(f.read())
146 db['drivers'].update(cf['drivers'].copy())
147 for key, d in db['drivers'].items():
148 d['id'] = key
149 hint = d['device_hint']
150 if not hint:
151 continue
152 hint = hint.strip()
153 if hint.startswith('"') and hint.endswith('"'):
154 hint = hint[1:-1]
155 hint = hint.replace(r'\"', "@$#!")
156 hint = hint.replace('"', '')
157 hint = hint.replace("@$#!", '"')
158 hint = hint.replace("\\\\", "\\")
159 d['device_hint'] = hint
160
161 configs = {}
162 for path in glob.glob(configdir + '/*.conf'):
163 with open(path) as f:
164 cf = yaml.load(f.read())
165 configs[cf['config']['id']] = cf['config']
166 db['configs'] = configs
167 self.db = db
168
169 @property
170 def kernel_drivers(self):
171 ''' The kernel-drivers dictionary, drivers.yaml + kernel-drivers.yaml.
172 '''
173 return self.db['kernel-drivers']
174
175 @property
176 def drivers(self):
177 ''' The drivers dictionary, drivers.yaml + kernel-drivers.yaml. '''
178 return self.db['drivers']
179
180 @property
181 def configs(self):
182 ''' Return dict of parsed config/*.conf files, keyd by id. '''
183 return self.db['configs']
184
185 def remotes_by_driver(self, driver):
186 ''' Return the list of remotes suggested for a given driver. '''
187 if isinstance(driver, dict):
188 driver = driver['id']
189 try:
190 return self.db['lircd_by_driver'][driver]
191 except KeyError:
192 return []
193
194 def lircmd_by_driver(self, driver):
195 ''' Return list of lircmd.conf file for given driver or None. '''
196 if isinstance(driver, dict):
197 driver = driver['id']
198 try:
199 return self.db['lircmd_by_driver'][driver]
200 except KeyError:
201 return []
202
203 def driver_by_remote(self, remote):
204 ''' Return the driver (possibly None) suggested for a remote. '''
205 for driver, files in self.db['lircd_by_driver'].items():
206 if remote in files:
207 return self.db['drivers'][driver]
208 return None
209
210 def find_config(self, key, value):
211 ''' Return item (a config) in configs where config[key] == value. '''
212 found = [c for c in self.db['configs'].values()
213 if key in c and c[key] == value]
214 if len(found) > 1:
215 raise ItemLookupError(
216 "find_config: Too many matches for %s, %s): " % (key, value)
217 + ', '.join([c['id'] for c in found]))
218 elif not found:
219 raise ItemLookupError(
220 "find_config: Nothing found for %s, %s): " % (key, value))
221 found = dict(found[0])
222 if 'device_hint' not in found:
223 try:
224 found['device_hint'] = \
225 self.db['drivers'][found['driver']]['device_hint']
226 except KeyError:
227 found['device_hint'] = \
228 self.db['kernel-drivers'][found['driver']]['device_hint']
229 return found
230
231
233
234 # vim: set expandtab ts=4 sw=4:
lirc.database.Config.lircd_conf
lircd_conf
Substituted data from driver.
Definition: database.py:105
lirc.database.Database.driver_by_remote
def driver_by_remote(self, remote)
Return the driver (possibly None) suggested for a remote.
Definition: database.py:211
lirc.database.Database.kernel_drivers
def kernel_drivers(self)
The kernel-drivers dictionary, drivers.yaml + kernel-drivers.yaml.
Definition: database.py:179
lirc.database.Database.drivers
def drivers(self)
The drivers dictionary, drivers.yaml + kernel-drivers.yaml.
Definition: database.py:184
lirc.database.ItemLookupError
A lookup failed, either too namy or no matches found.
Definition: database.py:91
lirc.database.Config.modprobe
modprobe
Substituted data from driver.
Definition: database.py:104
lirc.database.Database.find_config
def find_config(self, key, value)
Return item (a config) in configs where config[key] == value.
Definition: database.py:218
lirc.database.Config.label
label
Name of lircmd.conf file.
Definition: database.py:107
lirc.database.Config.note
def note(self)
The possible note to display when selected.
Definition: database.py:114
lirc.database.Database
Reflects the *.yaml files in the configs/ directory.
Definition: database.py:122
lirc.database.Config.lircmd_conf
lircmd_conf
Name of lircd.conf file.
Definition: database.py:106
lirc.database.Database.remotes_by_driver
def remotes_by_driver(self, driver)
Return the list of remotes suggested for a given driver.
Definition: database.py:193
lirc.database.Database.configs
def configs(self)
Return dict of parsed config/*.conf files, keyd by id.
Definition: database.py:189
lirc.database.Database.lircmd_by_driver
def lircmd_by_driver(self, driver)
Return list of lircmd.conf file for given driver or None.
Definition: database.py:202
lirc.database.Config.modinit
modinit
Read-only config dict in db.
Definition: database.py:103
lirc.database.Config.config
config
Read-only driver dict in db.
Definition: database.py:102
lirc.database.Database.db
db
Definition: database.py:174