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