forked from quantifiedcode/quantifiedcode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexport.py
More file actions
104 lines (87 loc) · 3.16 KB
/
export.py
File metadata and controls
104 lines (87 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# -*- coding: utf-8 -*-
"""
Contains export function used to translate database objects into dictionaries based on a mapping.
"""
from __future__ import unicode_literals
from __future__ import print_function
from six import string_types
def isiterable(x):
try:
iter(x)
return True
except TypeError:
return False
def isdictionarylike(x):
return True if hasattr(x,'items') and hasattr(x,'keys') and hasattr(x,'values') else False
def export(d, key):
"""
Exports a set of values from a nested dict.
Example usage:
d = {
'name' : 'test',
'remote_servers' :
{ 'us' :
{'ip' : [111,201,32,1],
'password' : 'super_secret_pw'},
'eu' :
{'ip' : [111,22,37,3],
'password' : 'super_secret_pw'
},
}
}
#We only want to export the name and the ip of the remote servers, but not their passwords!
export(d,('name', {'remote_servers' : {'*' : ('ip',)} } ))
#Return value:
#{'name': 'test', 'remote_servers': {'eu': {'ip': [111, 22, 37, 3]}, 'us': {'ip': [111, 201, 32, 1]}}}
As usual, the '*' is a wildcard that matches all keys from a dict.
"""
ed = {}
if d is None:
return None
def set_if_not_null(d, key, value):
if value is not None:
d[key] = value
else:
d[key] = None
if isinstance(key, (tuple, list)):
for key_params in key:
res = export(d, key_params)
ed.update(res)
elif isinstance(key, string_types):
if key == '*':
if isdictionarylike(d):
for d_key in d:
set_if_not_null(ed, d_key, d[d_key])
else:
try:
# we must try to access this argument
# and should not check the "in" operator first
# since otherwise we will not load lazy-loaded
# documents correctly
set_if_not_null(ed, key, d[key])
except KeyError:
pass
elif isinstance(key, dict):
for key_name, key_value in key.items():
if key_name == '*':
if isinstance(d, dict):
for d_key in d:
set_if_not_null(ed, d_key, export(d[d_key], key_value))
elif isiterable(d):
return [v for v in [export(element, key_value) for element in d] if v is not None]
elif callable(key_name):
for d_key in d:
if key_name(d_key):
set_if_not_null(ed, d_key, export(d[d_key], key_value))
else:
try:
# we must try to access this argument
# and should not check the "in" operator first
# since otherwise we will not load lazy-loaded
# documents correctly
set_if_not_null(ed, key_name, export(d[key_name], key_value))
except KeyError:
pass
elif callable(key):
return key(d)
return ed