myslice reputation plugin v0.2.1
[myslice.git] / portal / reputationview.py
1 from django.contrib.auth        import authenticate, login, logout\r
2 from django.template            import RequestContext\r
3 from django.shortcuts           import render, render_to_response\r
4 \r
5 from manifoldapi.manifoldresult import ManifoldResult\r
6 from ui.topmenu                 import topmenu_items, the_user\r
7 from myslice.configengine       import ConfigEngine\r
8 from manifold.core.query        import Query\r
9 from unfold.page                import Page\r
10 from manifoldapi.manifoldapi    import execute_admin_query, execute_query\r
11 from unfold.loginrequired       import LoginRequiredAutoLogoutView\r
12 \r
13 from myslice.theme import ThemeView\r
14 import json\r
15 import hashlib\r
16 import datetime\r
17 import urllib2\r
18 import ast\r
19 from django.views.decorators.csrf import csrf_exempt\r
20 from django.http                  import *\r
21 \r
22 def response_mimetype(request):\r
23         \r
24     if "application/json" in request.META['HTTP_ACCEPT']:\r
25         return "application/json"\r
26     else:\r
27         return "text/plain"\r
28     \r
29 \r
30 def json_to_rest(url, data ):\r
31         \r
32     req = urllib2.Request(url)\r
33     req.add_header('Content-Type', 'application/json')\r
34     response = urllib2.urlopen(req, json.dumps(data))\r
35     \r
36     if data == "a":\r
37         mylist = ast.literal_eval(response.read())\r
38     else:\r
39         mylist = response.read().translate(None, '"[]').split(",")\r
40         \r
41     return (mylist)\r
42 \r
43 \r
44 def unix_to_timestamp(timest):\r
45     try:\r
46         return datetime.datetime.fromtimestamp(int(timest)).strftime('%Y-%m-%d %H:%M:%S')\r
47     except:\r
48         return timest\r
49 \r
50 def timestamp_to_unix(timest):\r
51     try:\r
52         pass\r
53     except:\r
54         pass\r
55     \r
56     \r
57 def slice_to_exp(slices_users):\r
58     experiments = {}\r
59     testbeds = {}\r
60     \r
61     \r
62     for slice in slices_users:\r
63         nodes={}\r
64         leases = slice['lease']\r
65         if leases is not None:\r
66             for lease in leases:\r
67                 resource = lease['resource']\r
68                 start_t = lease['start_time']\r
69                 end_t = lease['end_time']\r
70                 #node = lease['resource']\r
71                 \r
72                 testbed_start = resource.index('IDN+')+4\r
73                 testbed_end = resource.index('+node+')\r
74                 \r
75                 testbed = resource[testbed_start:testbed_end]\r
76                 node = resource[testbed_end+6:]\r
77                 \r
78                 if testbed in testbeds:\r
79                     if node not in testbeds[testbed]:\r
80                         testbeds[testbed].append(node)\r
81                 else:\r
82                     testbeds[testbed] = [node]\r
83                 \r
84                 #group nodes in consecutive timeslots\r
85                 if not node in nodes:       \r
86                     nodes[node]={str(start_t):{'start_t':start_t, 'nodes':node, 'end_t':end_t}}\r
87                 else:\r
88                     if not str(start_t) in nodes[node]:\r
89                         f=0\r
90                         for n in nodes[node]:\r
91                             if n[str(end_t)] == start_t:\r
92                                 n[str(end_t)] == end_t\r
93                                 f=1\r
94                         if f==0:\r
95                             nodes[node][str(start_t)]={'start_t':start_t, 'nodes':node, 'end_t':end_t}\r
96                         \r
97         #group grouped nodes in experiments\r
98         for n in nodes:\r
99             for exp in nodes[n]:\r
100                 key = str(exp) + str(nodes[n][exp]['end_t'])\r
101                 \r
102                 if key not in experiments:\r
103                     experiments[key]={'slice_hrn':slice['slice_hrn'], \\r
104                                       'start':nodes[n][exp]['start_t'], 'end':nodes[n][exp]['end_t'], 'nodes':[nodes[n][exp]['nodes']]}   \r
105                 elif nodes[n][exp]['end_t'] == experiments[key]['end']:\r
106                     experiments[key]['nodes'].append(nodes[n][exp]['nodes'])\r
107                     \r
108     return (experiments,testbeds)\r
109    \r
110 class ReputationView (LoginRequiredAutoLogoutView, ThemeView):\r
111     template_name = 'reputation.html'\r
112         \r
113     # expose this so we can mention the backend URL on the welcome page\r
114     def default_env (self):\r
115         return { \r
116                  'MANIFOLD_URL':ConfigEngine().manifold_url(),\r
117                  }\r
118 \r
119     def post (self,request):\r
120         env = self.default_env()\r
121         env['theme'] = self.theme\r
122                 \r
123         return render_to_response(self.template, env, context_instance=RequestContext(request))\r
124 \r
125 \r
126     \r
127     \r
128     def get (self, request, state=None):\r
129         env = self.default_env()\r
130                 \r
131         #####    *** Reputation Plugin-specific START       ***     ############\r
132         #The following 'if' is a dirty way for bypassing the JS AJAX cross-domain prevention policy...not pretty\r
133         if request.GET.has_key(u'slicedata[user_eval][overall]'):\r
134             dict_to_send = {}\r
135             dict_to_send['eid'] = str(request.GET[u'slicedata[id]'])\r
136             dict_to_send['slice_hrn'] = str(request.GET[u'slicedata[slice_hrn]'])\r
137             dict_to_send['user_hrn'] = str(request.GET[u'slicedata[user_hrn]'])\r
138             dict_to_send['start_tunix'] = str(request.GET[u'slicedata[start_tunix]'])\r
139             dict_to_send['end_tunix'] = str(request.GET[u'slicedata[end_tunix]'])\r
140             dict_to_send['start_t'] = str(request.GET[u'slicedata[start_t]'])\r
141             dict_to_send['end_t'] = str(request.GET[u'slicedata[end_t]'])\r
142             dict_to_send['testbeds'] = ast.literal_eval(str(request.GET[u'testbeds']))\r
143             dict_to_send['user_eval'] = {}\r
144             dict_to_send['user_eval']['reuse'] = str(request.GET[u'slicedata[user_eval][reuse]'])\r
145             dict_to_send['user_eval']['availability'] = str(request.GET[u'slicedata[user_eval][availability]'])\r
146             dict_to_send['user_eval']['pay'] = str(request.GET[u'slicedata[user_eval][pay]'])\r
147             dict_to_send['user_eval']['support'] = str(request.GET[u'slicedata[user_eval][support]'])\r
148             dict_to_send['user_eval']['overall'] = str(request.GET[u'slicedata[user_eval][overall]'])\r
149             dict_to_send['user_eval']['link_quality'] = str(request.GET[u'slicedata[user_eval][link_quality]'])\r
150             dict_to_send['user_eval']['problems'] = str(request.GET[u'slicedata[user_eval][problems]'])\r
151             dict_to_send['user_eval']['quality'] = str(request.GET[u'slicedata[user_eval][quality]'])\r
152             \r
153             slicedata_received = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/json', dict_to_send )\r
154                         \r
155             return HttpResponse(json.dumps(slicedata_received), content_type = response_mimetype(self.request))\r
156 \r
157                 \r
158         slices_users = []\r
159         \r
160         #get slices\r
161         userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease')\r
162         slice_details = execute_query(self.request, userslice_query)\r
163         \r
164         #get local users\r
165         local_user_query  = Query().get('local:user').select('email','status','config')\r
166         local_user_details = execute_admin_query(self.request, local_user_query)\r
167         \r
168         #get users - create dict[email]=hrn\r
169         user_query  = Query().get('user').select('user_hrn','user_urn','user_email')\r
170         user_details = execute_admin_query(self.request, user_query)\r
171         users_hrn = {}\r
172         for item in user_details:\r
173             users_hrn[item['user_email']] = item['user_hrn']\r
174         \r
175         #get currenct username (email)\r
176         if request.user.is_authenticated():\r
177             cur_username = request.user.username  \r
178         \r
179         #get a list of all the slices for the logged in user\r
180         testbeds = []\r
181 \r
182         for slice in slice_details:\r
183             \r
184             if users_hrn[cur_username] in slice['users']:\r
185                 slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \\r
186                                      , 'resource':slice['resource'], 'lease':slice['lease'] })  \r
187                 \r
188                              \r
189         env['slices_users'] = slices_users  ### For logging\r
190        \r
191         #####create slicelist for template & JSON\r
192         experiments,testbeds =  slice_to_exp(slices_users)\r
193     \r
194         all_exp = []\r
195         iddata = []\r
196                           \r
197         for exp in experiments:\r
198             experiment = {}\r
199             experiment['slice_hrn'] = experiments[exp]['slice_hrn']\r
200             experiment['user_hrn'] = users_hrn[cur_username]\r
201             experiment['start_tunix'] = experiments[exp]['start']\r
202             experiment['end_tunix'] = experiments[exp]['end']\r
203             experiment['start_t'] = unix_to_timestamp(experiments[exp]['start'])\r
204             experiment['end_t'] = unix_to_timestamp(experiments[exp]['end'])\r
205             experiment['testbeds'] = {}\r
206             for exp_node in experiments[exp]['nodes']:\r
207                 list_testbeds = [ key for key,val in testbeds.items()]\r
208                 for tkey in list_testbeds:\r
209                     if exp_node in testbeds[tkey]:\r
210                         if tkey in experiment['testbeds']:\r
211                             if exp_node not in experiment['testbeds'][tkey]:\r
212                                 experiment['testbeds'][tkey].append(exp_node)\r
213                         else:\r
214                             experiment['testbeds'][tkey] = [exp_node]\r
215             tempid = hashlib.sha1(str(experiment)).hexdigest()                    \r
216             experiment['id'] = tempid\r
217             \r
218             iddata.append(tempid)\r
219             all_exp.append(experiment)\r
220         \r
221         \r
222         ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated\r
223         unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata)    \r
224         \r
225         for item in all_exp:\r
226             if item['id'] in unrated_exp:\r
227                 pass\r
228             else:\r
229                 all_exp.pop(all_exp.index(item))\r
230 \r
231 \r
232 \r
233         ###### Get Reputation values from Reputation DB\r
234         reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a")\r
235         #env['logging_test'] = reps    \r
236         \r
237         #create a services list and a dict containing the services for each testbed\r
238         serv_per_tb = {}\r
239         services = []\r
240         for item in reps:\r
241             serv_per_tb[item['testbed']]=[]\r
242             for serv in item['services']:\r
243                 if serv.keys()[0] not in services:\r
244                     services.append(serv.keys()[0])\r
245                     serv_per_tb[item['testbed']].append(serv.keys()[0])        \r
246         \r
247         #in json, sevices are in the form: 'services':[{'serv1':x}, {'serv2':y}], so we transform it to 'services':[x,y] based on\r
248         # the services dict above. If for a specific service there is no applicable value, we put N/A            \r
249         for testbed in reps:\r
250             d = list(testbed['services'])\r
251             del testbed['services']\r
252             testbed['services'] = []\r
253             for s in services:\r
254                 set_v = 0\r
255                 for i in d:\r
256                     try:\r
257                         testbed['services'].append(i[s])\r
258                         set_v=1\r
259                     except:\r
260                         pass\r
261                 if set_v == 0 :\r
262                     testbed['services'].append('N/A')\r
263                 \r
264         ###### Pass variables to template\r
265         env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
266         env['serv_per_tb'] = json.dumps(serv_per_tb, ensure_ascii=False)\r
267         env['reputation'] = reps\r
268         env['rep_serv'] = services\r
269         env['slicelist'] = all_exp\r
270         env['json_data'] = json.dumps(all_exp, ensure_ascii=False)\r
271         \r
272         ######    *** Reputation Plugin-specific END       ***     ############\r
273         \r
274         \r
275         if request.user.is_authenticated(): \r
276             env['person'] = self.request.user\r
277         else: \r
278             env['person'] = None\r
279     \r
280         env['theme'] = self.theme\r
281         #env['user_list']= user_list\r
282 \r
283         env['username']=the_user(request)\r
284         env['topmenu_items'] = topmenu_items(None, request)\r
285         if state: env['state'] = state\r
286         elif not env['username']: env['state'] = None\r
287         # use one or two columns for the layout - not logged in users will see the login prompt\r
288         env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"        \r
289         \r
290         return render_to_response(self.template, env, context_instance=RequestContext(request))\r
291     \r
292 \r
293 \r
294     \r
295 \r
296                     \r
297                     \r
298                     \r
299                     \r
300