fixed sfi + added generic wrapper/importer
[sfa.git] / sfa / generic / wrapper.py
1 class Wrapper:
2
3     def match_dict(self, dic, filter):
4        # We suppose if a field is in filter, it is therefore in the dic
5        if not filter:
6            return True
7        match = True
8        for k, v in filter.items():
9            if k[0] in Filter.modifiers:
10                op = k[0]
11                k = k[1:]
12            elif k in ['-SORT', '-LIMIT', '-OFFSET']:
13                continue;
14            else:
15                op = '='
16
17            if op == '=':
18                if isinstance(v, list):
19                    match &= (dic[k] in v) # array ?
20                else:
21                    match &= (dic[k] == v)
22            elif op == '~':
23                if isinstance(v, list):
24                    match &= (dic[k] not in v) # array ?
25                else:
26                    match &= (dic[k] != v) # array ?
27            elif op == '<':
28                if isinstance(v, StringTypes):
29                    # prefix match
30                    match &= dic[k].startswith('%s.' % v)
31                else:
32                    match &= (dic[k] < v)
33            elif op == '[':
34                if isinstance(v, StringTypes):
35                    match &= dic[k] == v or dic[k].startswith('%s.' % v)
36                else:
37                    match &= (dic[k] <= v)
38            elif op == '>':
39                if isinstance(v, StringTypes):
40                    # prefix match
41                    match &= v.startswith('%s.' % dic[k])
42                else:
43                    match &= (dic[k] > v)
44            elif op == ']':
45                if isinstance(v, StringTypes):
46                    # prefix match
47                    match &= dic[k] == v or v.startswith('%s.' % dic[k])
48                else:
49                    match &= (dic[k] >= v)
50            elif op == '&':
51                match &= (dic[k] & v) # array ?
52            elif op == '|':
53                match &= (dic[k] | v) # array ?
54            elif op == '{':
55                match &= (v in dic[k])
56        return match
57
58     def project_select_and_rename_fields(self, table, pkey, filters, fields):
59         filtered = []
60         for row in table:
61             # apply input filters 
62             if self.selection or self.match_dict(row, filters):
63                 # apply output_fields
64                 if self.projection:
65                     filtered.append(row)
66                 else:
67                     c = {}
68                     for k,v in row.items():
69                         # if no fields = keep everything
70                         if not fields or k in fields or k == pkey:
71                             c[k] = v
72                     filtered.append(c)
73         return filtered
74
75     def get_objects(self, method, filters=None, fields=None):
76         if not method in ['authorities', 'resources', 'users', 'slices']:
77             raise Exception, "Unknown object type"
78         results = self.get(method, filters, fields)
79         # Perform missing operations
80         if results and (filter and not self.selection) or (fields and not self.projection):
81             results = self.project_select_and_rename_fields(results, 'id', filters, fields)
82         return results