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