Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
[myslice.git] / rest / __init__.py
1 from manifold.core.query            import Query
2 from manifoldapi.manifoldapi        import execute_query
3
4 from django.http                    import HttpResponse
5
6
7 import decimal
8 import datetime
9 import json
10
11 # handles serialization of datetime in json
12 DateEncoder = lambda obj: obj.strftime("%B %d, %Y %H:%M:%S") if isinstance(obj, datetime.datetime) else None
13
14 # support converting decimal in json
15 json.encoder.FLOAT_REPR = lambda o: format(o, '.2f')
16
17 # handles decimal numbers serialization in json
18 class DecimalEncoder(json.JSONEncoder):
19     def _iterencode(self, o, markers=None):
20         if isinstance(o, decimal.Decimal):
21             return (str(o) for o in [o])
22         return super(DecimalEncoder, self)._iterencode(o, markers)
23     
24 class ObjectRequest(object):
25     
26     def __init__(self, request, object_type, object_name):
27         self.type = object_type
28         self.name = object_name
29         self.fields = []
30         self.params = {}
31         self.filters = {}
32         self.options = None
33
34         self.request = request
35         
36         if ((self.type == 'platform') or (self.type == 'testbed')) :
37             self.type = 'local:platform'
38             self.id = 'platform'
39             self.fields = ['platform', 'platform_longname', 'platform_url', 'platform_description','gateway_type'];
40             self.filters['disabled'] = '0'
41             self.filters['gateway_type'] = 'sfa'
42             self.filters['platform'] = '!myslice'
43         else :
44             self.setKey()
45             self.setLocalFields()
46         
47     
48     def setKey(self):
49         # What about key formed of multiple fields???
50         query = Query.get('local:object').filter_by('table', '==', self.type).select('key')
51         results = execute_query(self.request, query)
52         print "key of object = %s" % results
53         if results :
54             for r in results[0]['key'] :
55                 self.id = r
56         else :
57             raise Exception, 'Manifold db error'
58     
59     def setLocalFields(self):
60         query = Query.get('local:object').filter_by('table', '==', self.type).select('column.name')
61         results = execute_query(self.request, query)
62         if results :
63             for r in results[0]['column'] :
64                 self.fields.append(r['name'])
65         else :
66             raise Exception, 'Manifold db error'
67     
68     def setFields(self, fields):
69         selected_fields = []
70         for p in fields :
71             if p in self.fields :
72                 selected_fields.append(p)
73         self.fields = selected_fields
74         
75     
76     def applyFilters(self, query, force_filters = False):
77         if (force_filters and not self.filters) :
78             raise Exception, "Filters required"
79         if self.filters :
80             for k, f in self.filters.iteritems() :
81                 if (f[:1] == "!") :
82                     query.filter_by(k, '!=', f[1:])
83                 elif (f[:2] == ">=") :
84                     query.filter_by(k, '>=', f[2:])
85                 elif (f[:1] == ">") :
86                     query.filter_by(k, '>', f[1:])
87                 elif (f[:2] == "<=") :
88                     query.filter_by(k, '<=', f[2:])
89                 elif (f[:1] == "<") :
90                     query.filter_by(k, '<', f[1:])
91                 else :
92                     query.filter_by(k, '==', f)
93         return query
94     
95     def get(self):
96         query = Query.get(self.type)
97         if (self.id not in self.fields) :
98             query.select(self.fields + [self.id])
99         else :
100             query.select(self.fields)
101         
102         query = self.applyFilters(query)
103         return execute_query(self.request, query)
104
105     def create(self):
106         query = Query.create(self.type)
107         # No filters for create
108         if self.params :
109             query.set(self.params)
110         else:
111             raise Exception, "Params are required for create"
112         return execute_query(self.request, query)
113    
114     def update(self):
115         query = Query.update(self.type)
116         query = self.applyFilters(query, True)
117         if self.filters :
118             query.set(self.filters)
119         else:
120             raise Exception, "Filters are required for update"
121
122         if self.params :
123             query.set(self.params)
124         else:
125             raise Exception, "Params are required for update"
126         return execute_query(self.request, query)
127     
128     def delete(self):
129         query = Query.delete(self.type)
130         query = self.applyFilters(query, True)
131         if self.filters :
132             query.set(self.filters)
133         else:
134             raise Exception, "Filters are required for update"
135         return execute_query(self.request, query)
136     
137     def json(self):
138         return HttpResponse(json.dumps(self.get(), cls=DecimalEncoder, default=DateEncoder), content_type="application/json")
139     
140     def datatable(self):
141         response = self.get()
142         response_data = {}
143         response_data['fields'] = self.fields
144         response_data['labels'] = self.fields
145         response_data['data'] = []
146         response_data['total'] = len(response)
147         for r in response :
148             d = []
149             for p in self.fields :
150                 d.append(r[p])
151             response_data['data'].append(d)
152         
153         return HttpResponse(json.dumps(response_data, cls=DecimalEncoder, default=DateEncoder), content_type="application/json")
154
155 def error(msg):
156     return HttpResponse(json.dumps({'error' : msg}), content_type="application/json")
157
158 def success(msg):
159     return HttpResponse(json.dumps({'success' : msg}), content_type="application/json")