myslice reputation plugin v0.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         \r
124         \r
125         with open('/home/coyiotis/testlog.log') as f:\r
126             f.write(str('test'))\r
127                 \r
128                 \r
129         return render_to_response(self.template, env, context_instance=RequestContext(request))\r
130 \r
131 \r
132     \r
133     \r
134     def get (self, request, state=None):\r
135         env = self.default_env()\r
136                 \r
137         #####    *** Reputation Plugin-specific START       ***     ############\r
138         with open('/home/coyiotis/testlog.log', 'w') as f:\r
139                 f.write(str(request.GET))\r
140                 for key in request.GET:\r
141                     f.write('\n')\r
142                     f.write(str(request.GET[key]))\r
143                     \r
144         #The following 'if' is a dirty way for bypassing the JS AJAX cross-domain prevention policy...not pretty\r
145         if request.GET.has_key(u'slicedata[user_eval][overall]'):\r
146             dict_to_send = {}\r
147             dict_to_send['eid'] = str(request.GET[u'slicedata[id]'])\r
148             dict_to_send['slice_hrn'] = str(request.GET[u'slicedata[slice_hrn]'])\r
149             dict_to_send['user_hrn'] = str(request.GET[u'slicedata[user_hrn]'])\r
150             dict_to_send['start_tunix'] = str(request.GET[u'slicedata[start_tunix]'])\r
151             dict_to_send['end_tunix'] = str(request.GET[u'slicedata[end_tunix]'])\r
152             dict_to_send['start_t'] = str(request.GET[u'slicedata[start_t]'])\r
153             dict_to_send['end_t'] = str(request.GET[u'slicedata[end_t]'])\r
154             dict_to_send['testbeds'] = ast.literal_eval(str(request.GET[u'testbeds']))\r
155             dict_to_send['user_eval'] = {}\r
156             dict_to_send['user_eval']['reuse'] = str(request.GET[u'slicedata[user_eval][reuse]'])\r
157             dict_to_send['user_eval']['availability'] = str(request.GET[u'slicedata[user_eval][availability]'])\r
158             dict_to_send['user_eval']['pay'] = str(request.GET[u'slicedata[user_eval][pay]'])\r
159             dict_to_send['user_eval']['support'] = str(request.GET[u'slicedata[user_eval][support]'])\r
160             dict_to_send['user_eval']['overall'] = str(request.GET[u'slicedata[user_eval][overall]'])\r
161             dict_to_send['user_eval']['link_quality'] = str(request.GET[u'slicedata[user_eval][link_quality]'])\r
162             dict_to_send['user_eval']['problems'] = str(request.GET[u'slicedata[user_eval][problems]'])\r
163             dict_to_send['user_eval']['quality'] = str(request.GET[u'slicedata[user_eval][quality]'])\r
164             \r
165             slicedata_received = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/json', dict_to_send )\r
166                         \r
167             return HttpResponse(json.dumps(slicedata_received), content_type = response_mimetype(self.request))\r
168 \r
169                 \r
170         slices_users = []\r
171         \r
172         #get slices\r
173         userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease')\r
174         slice_details = execute_query(self.request, userslice_query)\r
175         \r
176         #get local users\r
177         local_user_query  = Query().get('local:user').select('email','status','config')\r
178         local_user_details = execute_admin_query(self.request, local_user_query)\r
179         \r
180         #get users - create dict[email]=hrn\r
181         user_query  = Query().get('user').select('user_hrn','user_urn','user_email')\r
182         user_details = execute_admin_query(self.request, user_query)\r
183         users_hrn = {}\r
184         for item in user_details:\r
185             users_hrn[item['user_email']] = item['user_hrn']\r
186         \r
187         #get currenct username (email)\r
188         if request.user.is_authenticated():\r
189             cur_username = request.user.username  \r
190         \r
191         #get a list of all the slices for the logged in user\r
192         testbeds = []\r
193 \r
194         for slice in slice_details:\r
195 \r
196             if users_hrn[cur_username] in slice['users']:\r
197                 slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \\r
198                                      , 'resource':slice['resource'], 'lease':slice['lease'] })  \r
199                 \r
200                              \r
201         env['slices_users'] = slices_users  ### For logging\r
202        \r
203         #####create slicelist for template & JSON\r
204         experiments,testbeds =  slice_to_exp(slices_users)\r
205     \r
206         all_exp = []\r
207         iddata = []\r
208                           \r
209         for exp in experiments:\r
210             experiment = {}\r
211             experiment['slice_hrn'] = experiments[exp]['slice_hrn']\r
212             experiment['user_hrn'] = users_hrn[cur_username]\r
213             experiment['start_tunix'] = experiments[exp]['start']\r
214             experiment['end_tunix'] = experiments[exp]['end']\r
215             experiment['start_t'] = unix_to_timestamp(experiments[exp]['start'])\r
216             experiment['end_t'] = unix_to_timestamp(experiments[exp]['end'])\r
217             experiment['testbeds'] = {}\r
218             for exp_node in experiments[exp]['nodes']:\r
219                 list_testbeds = [ key for key,val in testbeds.items()]\r
220                 for tkey in list_testbeds:\r
221                     if exp_node in testbeds[tkey]:\r
222                         if tkey in experiment['testbeds']:\r
223                             if exp_node not in experiment['testbeds'][tkey]:\r
224                                 experiment['testbeds'][tkey].append(exp_node)\r
225                         else:\r
226                             experiment['testbeds'][tkey] = [exp_node]\r
227             tempid = hashlib.sha1(str(experiment)).hexdigest()                    \r
228             experiment['id'] = tempid\r
229             \r
230             iddata.append(tempid)\r
231             all_exp.append(experiment)\r
232         \r
233         \r
234         ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated\r
235         unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata)    \r
236         \r
237         for item in all_exp:\r
238             if item['id'] in unrated_exp:\r
239                 pass\r
240             else:\r
241                 all_exp.pop(all_exp.index(item))\r
242 \r
243 \r
244 \r
245         ###### Get Reputation values from Reputation DB\r
246         reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a")\r
247         env['logging_test'] = reps    \r
248         \r
249         services = []\r
250         for item in reps:\r
251             for serv in item['services']:\r
252                 if serv.keys()[0] not in services:\r
253                     services.append(serv.keys()[0])\r
254         \r
255         \r
256         #in json, sevices are in the form: 'services':[{'serv1':x}, {'serv2':y}], so we transform it to 'services':[x,y] based on\r
257         # the services dict above. If for a specific service there is no applicable value, we put N/A            \r
258         for testbed in reps:\r
259             d = list(testbed['services'])\r
260             del testbed['services']\r
261             testbed['services'] = []\r
262             for s in services:\r
263                 set_v = 0\r
264                 for i in d:\r
265                     try:\r
266                         testbed['services'].append(i[s])\r
267                         set_v=1\r
268                     except:\r
269                         pass\r
270                 if set_v == 0 :\r
271                     testbed['services'].append('N/A')\r
272                 \r
273         ###### Pass variables to template\r
274         env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
275         env['reputation'] = reps\r
276         env['rep_serv'] = services\r
277         env['slicelist'] = all_exp\r
278         env['json_data'] = json.dumps(all_exp, ensure_ascii=False)\r
279         \r
280         ######    *** Reputation Plugin-specific END       ***     ############\r
281         \r
282         \r
283         if request.user.is_authenticated(): \r
284             env['person'] = self.request.user\r
285         else: \r
286             env['person'] = None\r
287     \r
288         env['theme'] = self.theme\r
289         #env['user_list']= user_list\r
290 \r
291         env['username']=the_user(request)\r
292         env['topmenu_items'] = topmenu_items(None, request)\r
293         if state: env['state'] = state\r
294         elif not env['username']: env['state'] = None\r
295         # use one or two columns for the layout - not logged in users will see the login prompt\r
296         env['layout_1_or_2']="layout-unfold2.html" if not env['username'] else "layout-unfold1.html"        \r
297         \r
298         return render_to_response(self.template, env, context_instance=RequestContext(request))\r
299     \r
300 \r
301 \r
302     \r
303 \r
304                     \r
305                     \r
306                     \r
307                     \r
308