proxmaster/utils.py

71 lines
1.8 KiB
Python

#. -*- coding: utf-8
#
# helper functions
from copy import deepcopy
import functools
def dict_merge(target, *args):
""" Recursively merges mutiple dicts """
# Merge multiple dicts
if len(args) > 1:
for obj in args:
dict_merge(target, obj)
return target
# Recursively merge dicts and set non-dict values
obj = args[0]
if not isinstance(obj, dict):
return obj
for k, v in obj.items():
if k in target and isinstance(target[k], dict):
dict_merge(target[k], v)
else:
target[k] = deepcopy(v)
return target
def find_rec(search_dict, field):
"""
Takes a dict with nested lists and dicts,
and searches all dicts for a key of the field
provided.
"""
fields_found = []
for key, value in search_dict.items():
if key == field:
fields_found.append(value)
elif isinstance(value, dict):
results = find_rec(value, field)
for result in results:
fields_found.append(result)
elif isinstance(value, list):
for item in value:
if isinstance(item, dict):
more_results = get_recursively(item, field)
for another_result in more_results:
fields_found.append(another_result)
return fields_found
def get_path(search_dict, key):
""" takes a nested dict and returns the path for the searched value """
for k,v in search_dict.items():
if isinstance(v,dict):
p = get_path(v,key)
if p:
return [k] + p
elif v == key:
return [k]
def chained_get(dct, *keys):
SENTRY = object()
def getter(level, key):
return 'NA' if level is SENTRY else level.get(key, SENTRY)
return functools.reduce(getter, keys, dct)