turn off senslabmap temporarily
[myslice.git] / portal / sliceview.py
1 from django.template                 import RequestContext
2 from django.shortcuts                import render_to_response
3
4 from unfold.loginrequired            import LoginRequiredAutoLogoutView
5
6 from unfold.page                     import Page
7 from manifold.core.query             import Query, AnalyzedQuery
8
9 from ui.topmenu                      import topmenu_items, the_user
10
11 from plugins.raw                     import Raw
12 from plugins.stack                   import Stack
13 from plugins.tabs                    import Tabs
14 from plugins.querytable              import QueryTable 
15 from plugins.queryupdater            import QueryUpdater
16 from plugins.googlemap               import GoogleMap
17 from plugins.senslabmap              import SensLabMap
18 from plugins.querycode               import QueryCode
19 from plugins.query_editor            import QueryEditor
20 from plugins.active_filters          import ActiveFilters
21 from plugins.quickfilter             import QuickFilter
22 from plugins.messages                import Messages
23 from plugins.slicestat               import SliceStat
24
25 from myslice.config                  import Config
26
27 tmp_default_slice='ple.upmc.myslicedemo'
28
29 # temporary : turn off the users part to speed things up
30 #do_query_users=True
31 do_query_users=False
32
33 insert_messages=False
34 #insert_messages=True
35
36 class SliceView (LoginRequiredAutoLogoutView):
37
38     def get (self,request, slicename=tmp_default_slice):
39     
40         page = Page(request)
41         page.add_css_files ('css/slice-view.css')
42         page.add_js_files  ( [ "js/common.functions.js" ] )
43         page.add_js_chunks ('$(function() { messages.debug("sliceview: jQuery version " + $.fn.jquery); });')
44         page.add_js_chunks ('$(function() { messages.debug("sliceview: users turned %s"); });'%("on" if do_query_users else "off"))
45         config=Config()
46         page.add_js_chunks ('$(function() { messages.debug("manifold URL %s"); });'%(config.manifold_url()))
47         page.expose_js_metadata()
48     
49         metadata = page.get_metadata()
50         resource_md = metadata.details_by_object('resource')
51         resource_fields = [column['name'] for column in resource_md['column']]
52     
53         user_md = metadata.details_by_object('user')
54         user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
55     
56         # TODO The query to run is embedded in the URL
57         main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
58         main_query.select(
59                 'slice_hrn',
60                 'resource.hrn', 'resource.hostname', 'resource.type', 
61                 'resource.network_hrn',
62                 #'lease.urn',
63                 'user.user_hrn',
64                 #'application.measurement_point.counter'
65         )
66     
67         query_resource_all = Query.get('resource').select(resource_fields)
68         if do_query_users:
69             query_user_all = Query.get('user').select(user_fields)
70     
71         aq = AnalyzedQuery(main_query, metadata=metadata)
72         page.enqueue_query(main_query, analyzed_query=aq)
73         page.enqueue_query(query_resource_all)
74         if do_query_users:
75             page.enqueue_query(query_user_all)
76     
77         # ... and for the relations
78         # XXX Let's hardcode resources for now
79         sq_resource    = aq.subquery('resource')
80         sq_user        = aq.subquery('user')
81         sq_lease       = aq.subquery('lease')
82         sq_measurement = aq.subquery('measurement')
83         
84     
85         # Prepare the display according to all metadata
86         # (some parts will be pending, others can be triggered by users).
87         # 
88         # For example slice measurements will not be requested by default...
89     
90         # Create the base layout (Stack)...
91         main_stack = Stack (
92             page=page,
93             title="Slice %s"%slicename,
94             sons=[],
95         )
96     
97         # ... responsible for the slice properties...
98     
99         # a nice header
100         main_stack.insert (
101             Raw (page=page,
102                  togglable=False, 
103                  toggled=True,
104                  html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
105         )
106     
107         # --------------------------------------------------------------------------
108         # QueryUpdater (Pending Operations)
109
110         main_stack.insert(QueryUpdater(
111             page                = page,
112             title               = 'Pending operations',
113             query               = main_query,
114             togglable           = True,
115             # start turned off, it will open up itself when stuff comes in
116             toggled             = False, 
117             domid               = 'pending',
118             outline_complete    = True,
119         ))
120
121         # --------------------------------------------------------------------------
122         # Filter Resources
123        
124         filter_query_editor = QueryEditor(
125             page  = page,
126             query = sq_resource, 
127             query_all = query_resource_all,
128             title = "Select Columns",
129             domid = 'select-columns',
130             )
131         filter_active_filters = ActiveFilters(
132             page  = page,
133             query = sq_resource,
134             title = "Active Filters",
135             )
136         filters_area = Stack(
137             page                = page,
138             title               = 'Filter Resources',
139             domid               = 'filters',
140             sons                = [filter_query_editor, filter_active_filters],
141             togglable           = True,
142             toggled             = 'persistent',
143             outline_complete    = True, 
144         )
145         main_stack.insert (filters_area)
146
147         # --------------------------------------------------------------------------
148         # RESOURCES
149         # the resources part is made of a Tabs (Geographic, List), 
150
151         resources_as_gmap = GoogleMap(
152             page       = page,
153             title      = 'Geographic view',
154             domid      = 'resources-map',
155             # tab's sons preferably turn this off
156             togglable  = False,
157             query      = sq_resource,
158             query_all  = query_resource_all,
159             checkboxes = True,
160             # center on Paris
161             latitude   = 49.,
162             longitude  = 9,
163             zoom       = 4,
164         )
165
166 # because (senslab)map.css changes stuff for *all* canvas elements
167 # it destroys the googlemap behaviour
168 # turning this off for now until Anthony can fix that
169 #        resources_as_3dmap = SensLabMap(
170 #            page       = page,
171 #            title      = '3D Map',
172 #            domid      = 'senslabmap',
173 #            query      = sq_resource,
174 #            query_all  = query_resource_all,
175 #        )
176
177         resources_as_list = QueryTable( 
178             page       = page,
179             domid      = 'resources-list',
180             title      = 'List view',
181             # this is the query at the core of the slice list
182             query      = sq_resource,
183             query_all  = query_resource_all,
184             checkboxes = True,
185             datatables_options = { 
186                 'iDisplayLength': 25,
187                 'bLengthChange' : True,
188                 'bAutoWidth'    : True,
189                 },
190             )
191
192        # with the new 'Filter' stuff on top, no need for anything but the querytable
193         resources_as_list_area = resources_as_list 
194
195         resources_area = Tabs ( page=page, 
196                                 domid="resources",
197                                 togglable=True,
198                                 title="Resources",
199                                 outline_complete=True,
200                                 sons=[ resources_as_gmap, 
201 # see above
202 #                                       resources_as_3dmap,
203                                        resources_as_list_area, ],
204                                 active_domid = 'resources-map',
205                                 )
206         main_stack.insert (resources_area)
207
208         # --------------------------------------------------------------------------
209         # USERS
210     
211         if do_query_users:
212             tab_users = Tabs(
213                 page                = page,
214                 domid               = 'users',
215                 outline_complete    = True,
216                 togglable           = True,
217                 title               = 'Users',
218                 active_domid        = 'users-list',
219                 )
220             main_stack.insert(tab_users)
221     
222             tab_users.insert(QueryTable( 
223                 page        = page,
224                 title       = 'Users List',
225                 domid       = 'users-list',
226                 # tab's sons preferably turn this off
227                 togglable   = False,
228                 # this is the query at the core of the slice list
229                 query       = sq_user,
230                 query_all  = query_user_all,
231                 checkboxes  = True,
232                 datatables_options = { 
233                     'iDisplayLength' : 25,
234                     'bLengthChange'  : True,
235                     'bAutoWidth'     : True,
236                 },
237             ))
238
239 # DEMO    
240         # --------------------------------------------------------------------------
241         # MEASUREMENTS
242         measurements_stats_cpu = SliceStat(
243             title = "CPU Usage",
244             domid = 'resources-stats-cpu',
245             page  = page,
246             stats = 'slice',
247             key   = 'hrn',
248             query = 'none',
249             slicename = slicename,
250             o = 'cpu'
251         )
252         
253         measurements_stats_mem = SliceStat(
254             title = "Memory Usage",
255             domid = 'resources-stats-mem',
256             page  = page,
257             stats = 'slice',
258             key   = 'hrn',
259             query = 'none',
260             slicename = slicename,
261             o = 'mem'
262         )
263         
264         measurements_stats_asb = SliceStat(
265             title = "Traffic Sent",
266             domid = 'resources-stats-asb',
267             page  = page,
268             stats = 'slice',
269             key   = 'hrn',
270             query = 'none',
271             slicename = slicename,
272             o = 'asb'
273         )
274         
275         measurements_stats_arb = SliceStat(
276             title = "Traffic Received",
277             domid = 'resources-stats-arb',
278             page  = page,
279             stats = 'slice',
280             key   = 'hrn',
281             query = 'none',
282             slicename = slicename,
283             o = 'arb'
284         )
285
286         tab_measurements = Tabs ( page=page,
287                                 domid="measurements",
288                                 togglable=True,
289                                 toggled  = False,
290                                 title="Measurements",
291                                 outline_complete=True,
292                                 sons=[ measurements_stats_cpu, measurements_stats_mem, measurements_stats_asb, measurements_stats_arb ],
293                                 active_domid = 'measurements_stats_cpu',
294                                 )
295         main_stack.insert (tab_measurements)
296         
297 #        tab_measurements = Tabs (
298 #            page                = page,
299 #            active_domid        = 'measurements-list',
300 #            outline_complete    = True,
301 #            togglable           = True,
302 #            title               = 'Measurements',
303 #            domid               = 'measurements',
304 #        )
305 #        main_stack.insert(tab_measurements)
306 #    
307 #        tab_measurements.insert(QueryTable( 
308 #            page        = page,
309 #            title       = 'Measurements',
310 #            domid       = 'measurements-list',
311 #            # tab's sons preferably turn this off
312 #            togglable   = False,
313 #            # this is the query at the core of the slice list
314 #            query       = sq_measurement,
315 #            # do NOT set checkboxes to False
316 #            # this table being otherwise empty, it just does not fly with dataTables
317 #            checkboxes  = True,
318 #            datatables_options = { 
319 #                'iDisplayLength' : 25,
320 #                'bLengthChange'  : True,
321 #                'bAutoWidth'     : True,
322 #            },
323 #        ))
324 #    
325 #        # --------------------------------------------------------------------------
326 #        # MESSAGES (we use transient=False for now)
327         if insert_messages:
328             main_stack.insert(Messages(
329                     page   = page,
330                     title  = "Runtime messages for slice %s"%slicename,
331                     domid  = "msgs-pre",
332                     levels = "ALL",
333                     # plain messages are probably less nice for production but more reliable for development for now
334                     transient = False,
335                     # these make sense only in non-transient mode..
336                     togglable = True,
337                     toggled = 'persistent',
338                     outline_complete = True,
339                     ))
340     
341     
342         # variables that will get passed to the view-unfold1.html template
343         template_env = {}
344         
345         # define 'unfold_main' to the template engine - the main contents
346         template_env [ 'unfold_main' ] = main_stack.render(request)
347     
348         # more general variables expected in the template
349         template_env [ 'title' ] = '%(slicename)s'%locals()
350         # the menu items on the top
351         template_env [ 'topmenu_items' ] = topmenu_items('Slice', request) 
352         # so we can sho who is logged
353         template_env [ 'username' ] = the_user (request) 
354     
355         # don't forget to run the requests
356         page.expose_queries ()
357     
358         # xxx create another plugin with the same query and a different layout (with_datatables)
359         # show that it worls as expected, one single api call to backend and 2 refreshed views
360     
361         # the prelude object in page contains a summary of the requirements() for all plugins
362         # define {js,css}_{files,chunks}
363         prelude_env = page.prelude_env()
364         template_env.update(prelude_env)
365         result=render_to_response ('view-unfold1.html',template_env,
366                                    context_instance=RequestContext(request))
367         return result