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