25
25
from systemimage.helpers import Bag
28
def _parse_device_mappings(device_mapping):
30
# e.g. keys: nexus7, nexus4
31
for device_name, mapping_1 in device_mapping.items():
32
# Most of the keys at this level (e.g. index) have flat values,
33
# however the keyring key is itself a mapping.
34
keyring = mapping_1.pop('keyring', None)
35
if keyring is not None:
36
mapping_1['keyring'] = Bag(**keyring)
37
# e.g. nexus7 -> {index, keyring}
38
devices[device_name] = Bag(**mapping_1)
28
42
class Channels(Bag):
30
44
def from_json(cls, data):
31
45
mapping = json.loads(data)
33
# e.g. keys: daily, stable
34
for channel_name, device_mapping in mapping.items():
36
# e.g. keys: nexus7, nexus4
37
for device_name, detail_mapping in device_mapping.items():
38
# Most of the keys at this level (e.g. index) have flat
39
# values, however the keyring key is itself a mapping.
40
keyring = detail_mapping.pop('keyring', None)
41
if keyring is not None:
42
detail_mapping['keyring'] = Bag(**keyring)
43
# e.g. nexus7 -> {index, keyring}
44
devices[device_name] = Bag(**detail_mapping)
45
# e.g. daily -> {nexus7, nexus4}
46
channels[channel_name] = Bag(**devices)
47
# LP: #1221841 introduced a new channels.json format which introduced
48
# a new level between the channel name and the device name. This
49
# extra level can include optional 'alias' and 'hidden' keys, and must
50
# include a 'devices' key. Until LP: #1221843 we must support both
51
# formats, so to figure out which we're looking at, see if there's a
52
# 'devices' key under the channel name. We'll just assume there won't
53
# be a device called 'device'.
54
for channel_name, mapping_1 in mapping.items():
55
if 'devices' in mapping_1:
57
hidden = mapping_1.pop('hidden', None)
61
assert hidden in (True, False), (
62
"Unexpected value for 'hidden': {}".format(hidden))
63
mapping_1['hidden'] = hidden
64
device_mapping = mapping_1.pop('devices')
65
mapping_1['devices'] = _parse_device_mappings(device_mapping)
66
channels[channel_name] = Bag(**mapping_1)
68
# For better forward compatibility, even old style
69
# channel.json files get a 'devices' level.
70
device_mapping = _parse_device_mappings(mapping_1)
71
channels[channel_name] = Bag(devices=device_mapping)
47
72
return cls(**channels)