1''' Read-only configuration database. '''
48 from yaml
import CLoader
as Loader, CDumper
as Dumper
50 from yaml
import Loader, Dumper
53"Cannot import the yaml library. Please install the python3
54yaml package, on many distributions known as python3-PyYAML. It is also
55available as a pypi package at https://pypi.python.org/pypi/PyYAML.'''
63 ''' Return path added to current dir for __file__. '''
64 return os.path.join(os.path.dirname(os.path.abspath(__file__)), path)
67def _load_kerneldrivers(configdir):
68 ''' Parse the kerneldrivers.yaml file, discard unavailable
72 with open(os.path.join(configdir,
"kernel-drivers.yaml"))
as f:
73 cf = yaml.load(f.read(), Loader = Loader)
74 drivers = cf[
'drivers'].copy()
75 for driver
in cf[
'drivers']:
76 if driver ==
'default':
78 with open(
'/dev/null',
'w')
as f:
80 subprocess.check_output([config.MODINFO, driver],
82 except subprocess.CalledProcessError:
87class ItemLookupError(Exception):
88 """A lookup failed, either too namy or no matches found. """
93 ''' The configuration selected, and it's sources. '''
96 def __init__(self, cf=None):
103 self.lircmd_conf =
""
106 for key, value
in cf.items():
107 setattr(self, key, value)
111 ''' The possible note to display when selected. '''
112 if 'note' in self.config:
113 return self.config[
'note']
118class Database(object):
119 ''' Reflects the *.yaml files in the configs/ directory. '''
121 def __init__(self, path=None, yamlpath=None):
123 devel_path = _here(
'../../configs')
124 installed_path = os.path.join(config.DATADIR,
'lirc',
'configs')
125 if path
and os.path.exists(path):
128 raise FileNotFoundError(path)
129 elif os.path.exists(devel_path):
130 configdir = devel_path
131 elif os.path.exists(installed_path):
132 configdir = installed_path
134 raise FileNotFoundError(devel_path +
':' + installed_path)
138 with open(os.path.join(yamlpath,
"confs_by_driver.yaml"))
as f:
139 cf = yaml.load(f.read(), Loader = Loader)
140 db[
'lircd_by_driver'] = cf[
'lircd_by_driver'].copy()
141 db[
'lircmd_by_driver'] = cf[
'lircmd_by_driver'].copy()
143 db[
'kernel-drivers'] = _load_kerneldrivers(configdir)
144 db[
'drivers'] = db[
'kernel-drivers'].copy()
145 with open(os.path.join(yamlpath,
"drivers.yaml"))
as f:
146 cf = yaml.load(f.read(), Loader = Loader)
147 db[
'drivers'].update(cf[
'drivers'].copy())
148 for key, d
in db[
'drivers'].items():
150 hint = d[
'device_hint']
154 if hint.startswith(
'"')
and hint.endswith(
'"'):
156 hint = hint.replace(
r'\"',
"@$#!")
157 hint = hint.replace(
'"',
'')
158 hint = hint.replace(
"@$#!",
'"')
159 hint = hint.replace(
"\\\\",
"\\")
160 d[
'device_hint'] = hint
163 for path
in glob.glob(configdir +
'/*.conf'):
164 with open(path)
as f:
165 cf = yaml.load(f.read(), Loader = Loader)
166 configs[cf[
'config'][
'id']] = cf[
'config']
167 db[
'configs'] = configs
171 def kernel_drivers(self):
172 ''' The kernel-drivers dictionary, drivers.yaml + kernel-drivers.yaml.
174 return self.db[
'kernel-drivers']
178 ''' The drivers dictionary, drivers.yaml + kernel-drivers.yaml. '''
179 return self.db[
'drivers']
183 ''' Return dict of parsed config/*.conf files, keyd by id. '''
184 return self.db[
'configs']
186 def remotes_by_driver(self, driver):
187 ''' Return the list of remotes suggested for a given driver. '''
188 if isinstance(driver, dict):
189 driver = driver[
'id']
191 return self.db[
'lircd_by_driver'][driver]
195 def lircmd_by_driver(self, driver):
196 ''' Return list of lircmd.conf file for given driver or None. '''
197 if isinstance(driver, dict):
198 driver = driver[
'id']
200 return self.db[
'lircmd_by_driver'][driver]
204 def driver_by_remote(self, remote):
205 ''' Return the driver (possibly None) suggested for a remote. '''
206 for driver, files
in self.db[
'lircd_by_driver'].items():
208 return self.db[
'drivers'][driver]
211 def find_config(self, key, value):
212 ''' Return item (a config) in configs where config[key] == value. '''
213 found = [c
for c
in self.db[
'configs'].values()
214 if key
in c
and c[key] == value]
216 raise ItemLookupError(
217 "find_config: Too many matches for %s, %s): " % (key, value)
218 +
', '.join([c[
'id']
for c
in found]))
220 raise ItemLookupError(
221 "find_config: Nothing found for %s, %s): " % (key, value))
222 found = dict(found[0])
223 if 'device_hint' not in found:
225 found[
'device_hint'] = \
226 self.db[
'drivers'][found[
'driver']][
'device_hint']
228 found[
'device_hint'] = \
229 self.db[
'kernel-drivers'][found[
'driver']][
'device_hint']