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