Add check to verify that config file is not user readable
[dumbwifi.git] / sdict.py
blobf1b8e77a4cd5f1e4569d6f6b959724da967e4b7e
1 #!/usr/bin/env python
3 import regex
6 class sdictlist:
7 def __init__(self, init_list=None, sort_key=None):
8 self.lst = []
9 self.sort_key = sort_key
11 if init_list:
12 for item in init_list:
13 self.append(item)
15 def isvalid(self, dict):
16 if type(dict) == sdict:
17 return True
19 def __str__(self):
20 return self.lst.__str__()
22 def __len__(self):
23 return len(self.lst)
25 def __iter__(self):
26 return iter(self.lst)
28 def clear(self):
29 self.lst = []
31 def append(self, dict):
32 if not self.isvalid(dict):
33 raise Exception, "argument type of %s: %s invalid %s" %\
34 (dict, type(dict), sdict)
35 self.lst.append(dict)
36 self = self.sort(lst=self.lst)
38 def remove(self, index):
39 try: del(self.lst[index])
40 except: pass
42 def extend(self, dl):
43 items = dl.get_all()
44 if items:
45 for item in items:
46 self.append(item)
48 def get_top(self, pred=None):
49 if pred: return filter(pred, self.lst)[0]
50 return self.lst[0]
52 def get_all(self, pred=None):
53 if pred: return filter(pred, self.lst)
54 return self.lst
56 def sort(self, lst=None, sort_key=None, reverse=False):
57 def compare(x, y):
58 # insulate against unset keys
59 if sort_key not in x and sort_key not in y: return 0
60 elif sort_key not in x: return 1
61 if sort_key not in y: return -1
63 # numeric sort if string begins with digits
64 m = regex.find1("(-?[0-9]*)", x[sort_key])
65 n = regex.find1("(-?[0-9]*)", y[sort_key])
66 if m and n:
67 return cmp(int(n), int(m)) # reverse order to get desc
69 return cmp(x[sort_key].lower(), y[sort_key].lower())
71 if not lst: lst = self.lst
72 if not sort_key: sort_key = self.sort_key
73 lst = sorted(lst, compare)
74 if reverse: lst.reverse()
76 l = sdictlist()
77 l.__dict__['lst'] = lst
78 return l
80 def ammend(self, old, new): # update old dict with new data
81 if not new: return old
82 for key in new.keys():
83 if not new[key] or new[key] == "":
84 new[key] = old[key]
85 for key in [x for x in old.keys() if x not in new.keys()]:
86 new[key] = old[key]
87 return new
89 # merge new_dict into dictlist
90 def merge1(self, new_dict, key):
91 dicts = self.lst
92 found = False
93 for (i, dict) in enumerate(dicts):
94 if dict[key] == new_dict[key]:
95 found = True
96 dicts[i] = self.ammend(dict, new_dict)
97 if not found:
98 dicts.append(new_dict)
99 return self.sort(lst=dicts)
101 # merge new dictlist into dictlist
102 def merge(self, new_dicts, key):
103 dicts = self
104 if not new_dicts: return dicts
105 for new_dict in new_dicts:
106 dicts.merge1(new_dict, key)
107 return self.sort(lst=dicts)
110 class sdict(dict):
111 def __init__(self, *args):
112 dict.__init__(self)
114 if args and len(args) == 1:
115 (init_dict,) = args
116 for (key, value) in init_dict.items():
117 self.__setattr__(key, value)
120 ## Helper methods
122 def ___value_is_null___(self, value):
124 # ignore null values and strings with only whitespace
125 if not value or (type(value) == str and value.strip() == ""):
126 return True
129 # Dictionary interface
131 def __setitem__(self, key, value):
132 self.__setattr__(key, value)
134 def __getitem__(self, key):
135 return self.__getattribute__(key)
137 def __delitem__(self, key):
138 self.__delattr__(key)
140 def clear(self):
141 for key in dict.keys(self):
142 self.__delitem__(key)
144 def fromkeys(self, keys, value=None):
145 if keys:
146 new_sdict = sdict()
147 for key in keys: new_sdict.__setitem__(key, value)
148 return new_sdict
150 def pop(self, key, default=None):
151 value = self.__getitem__(key)
152 self.__delitem__(key)
153 if not value: return default
154 return value
156 def popitem(self):
157 try:
158 key = self.keys()[0]
159 return (key, self.pop(key))
160 except IndexError: return None
162 def setdefault(self, key, value=None):
163 v = self.__getitem__(key)
164 if v: return v
165 self.__setitem__(key, value)
166 return value
168 def update(self, pairs):
169 for (key, value) in pairs:
170 self.__setattr__(key, value)
173 # Attribute interface
175 def __setattr__(self, key, value):
176 if not self.___value_is_null___(value):
177 if type(value) == int: value = str(value)
178 dict.__setattr__(self, key, value)
179 dict.__setitem__(self, key, value)
181 def __getattribute__(self, key):
182 try:
183 return dict.__getattribute__(self, key)
184 except AttributeError: return None
186 def __delattr__(self, key):
187 try:
188 dict.__delattr__(self, key)
189 dict.__delitem__(self, key)
190 except: pass
194 if __name__ == "__main__":
195 d = sdict({'a':"3"})
196 print "d.a:", d.a
197 print "d['a']:", d['a']
198 d['name'] = 'dd-wrt'
199 d['a'] = '3'
200 d.b = 1
201 del(d['c'])
202 d.__delattr__('c')
204 print d
205 d.clear()
206 print d
208 d2 = sdict()
209 d2.a = "aa"
210 d2.b = "ab"
211 d2.c = 2
213 d3 = sdict()
214 d3.p = "fa"
215 d3.b = "ce"
216 d3.c = 3
218 d4 = sdict()
219 d4.p = "we"
220 d4.z = "qw"
221 d4.c = 9
223 dl = sdictlist(sort_key="a")
224 print dl.isvalid(d2)
225 dl.append(d2)
226 dl.append(d4)
227 print dl
229 print dl.get_top()
230 print dl.get_top(pred=lambda x: x.a != None)
232 dl2 = sdictlist(sort_key="c")
233 dl2.append(d3)
234 print dl2
235 print dl.merge(dl2, "c")