from copy import deepcopy from .alfred import AlfredParser from .batman import BatmanParser from .dashing import DashingClient from .graphite import GraphitePush from .server import ApiServer from .storage import Storage __all__ = [ 'AlfredParser', 'BatmanParser', 'DashingClient', 'GraphitePush', 'Storage', 'ApiServer', 'dict_merge', 'merge_alfred_batman', 'mac2id' ] def mac2id(mac): return mac.lower().replace(':', '') def dict_merge(a, b): '''recursively merges dict's. not just simple a['key'] = b['key'], if both a and bhave a key who's value is a dict then dict_merge is called on both values and the result stored in the returned dictionary.''' if not isinstance(b, dict): return b result = deepcopy(a) for k, v in b.iteritems(): if k in result and isinstance(result[k], dict): result[k] = dict_merge(result[k], v) elif k in result and isinstance(result[k], list): result[k] = result[k] + [ deepcopy(x) for x in v if x not in result[k] ] else: result[k] = deepcopy(v) return result def merge_alfred_batman(alfreddata, batmandata): merged = {} batlookup = {} for nodeid in batmandata: batlookup[nodeid] = nodeid for bda in batmandata[nodeid]['aliases']: batlookup[bda] = nodeid for nodeid in alfreddata: nodeinfo = alfreddata[nodeid] candidates = set() candidates.add(nodeid) if 'mac' in nodeinfo: candidates.add(mac2id(nodeinfo['mac'])) if 'macs' in nodeinfo: for mac in nodeinfo['macs']: candidates.add(mac2id(mac)) if 'network' in nodeinfo: n = nodeinfo['network'] if 'mac' in n: candidates.add(mac2id(n['mac'])) if 'mesh_interfaces' in n: for mac in n['mesh_interfaces']: candidates.add(mac2id(mac)) if not 'neighbours' in nodeinfo: nodeinfo['neighbours'] = [] for candidate_raw in candidates: candidate = batlookup[candidate_raw] if candidate_raw in batlookup else candidate_raw if candidate in batmandata: nodeinfo = dict_merge(nodeinfo, batmandata[candidate]) merged[nodeid] = nodeinfo return merged