redrawing slice view
[myslice.git] / portal / sliceview.py
1 from django.template                 import RequestContext
2 from django.shortcuts                import render_to_response
3
4 from portal.templateviews            import LoginRequiredAutoLogoutView
5
6 from unfold.page                     import Page
7 from manifold.core.query             import Query, AnalyzedQuery
8
9 from myslice.viewutils               import topmenu_items, the_user
10
11 from plugins.raw.raw                 import Raw
12 from plugins.stack.stack             import Stack
13 from plugins.tabs.tabs               import Tabs
14 from plugins.lists.slicelist         import SliceList
15 from plugins.hazelnut                import Hazelnut 
16 from plugins.resources_selected      import ResourcesSelected
17 from plugins.googlemaps              import GoogleMaps
18 from plugins.senslabmap.senslabmap   import SensLabMap
19 from plugins.querycode.querycode     import QueryCode
20 from plugins.query_editor            import QueryEditor
21 from plugins.active_filters          import ActiveFilters
22 from plugins.quickfilter.quickfilter import QuickFilter
23 from plugins.messages.messages       import Messages
24 #from plugins.updater                 import Updater
25
26 tmp_default_slice='ple.upmc.myslicedemo'
27
28 class SliceView (LoginRequiredAutoLogoutView):
29
30     def get (self,request, slicename=tmp_default_slice):
31     
32         page = Page(request)
33         page.add_css_files ('css/slice-view.css')
34         page.expose_js_metadata()
35     
36         metadata = page.get_metadata()
37         resource_md = metadata.details_by_object('resource')
38         resource_fields = [column['name'] for column in resource_md['column']]
39     
40         user_md = metadata.details_by_object('user')
41         user_fields = ['user_hrn'] # [column['name'] for column in user_md['column']]
42     
43         # TODO The query to run is embedded in the URL
44         main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
45         main_query.select(
46                 'slice_hrn',
47                 'resource.resource_hrn', 'resource.hostname', 'resource.type', 'resource.network_hrn',
48                 #'lease.urn',
49                 'user.user_hrn',
50                 #'application.measurement_point.counter'
51         )
52     
53         query_resource_all = Query.get('resource').select(resource_fields)
54         query_user_all = Query.get('user').select(user_fields)
55     
56         aq = AnalyzedQuery(main_query, metadata=metadata)
57         page.enqueue_query(main_query, analyzed_query=aq)
58         page.enqueue_query(query_resource_all)
59         page.enqueue_query(query_user_all)
60     
61         # ... and for the relations
62         # XXX Let's hardcode resources for now
63         sq_resource = aq.subquery('resource')
64         sq_user     = aq.subquery('user')
65         sq_lease    = aq.subquery('lease')
66         sq_measurement = aq.subquery('measurement')
67         
68     
69         # Prepare the display according to all metadata
70         # (some parts will be pending, others can be triggered by users).
71         # 
72         # For example slice measurements will not be requested by default...
73     
74         # Create the base layout (Stack)...
75         main_stack = Stack (
76             page=page,
77             title="Slice %s"%slicename,
78             sons=[],
79         )
80     
81         # ... responsible for the slice properties...
82     
83         # a nice header
84         main_stack.insert (
85             Raw (page=page,
86                  togglable=False, 
87                  toggled=True,
88                  html="<h2 class='well well-lg'> Slice %s</h2>"%slicename)
89         )
90     
91 #        main_stack.insert(
92 #            Raw (page=page,togglable=False, toggled=True,html='<b>Description:</b> TODO')
93 #        )
94     
95         # the resources part is made of a Stack, 
96         # with first a Tabs (List, Geographic), 
97         # and second the QueryEditor to tweak the set of attributes to show
98         resources_as_list = Hazelnut( 
99             page       = page,
100             title      = 'Resources as a List',
101             domid      = 'checkboxes',
102             # this is the query at the core of the slice list
103             query      = sq_resource,
104             query_all  = query_resource_all,
105             checkboxes = True,
106             datatables_options = { 
107                 # for now we turn off sorting on the checkboxes columns this way
108                 # this of course should be automatic in hazelnut
109                 'aoColumns'      : [None, None, None, None, {'bSortable': False}],
110                 'iDisplayLength' : 25,
111                 'bLengthChange'  : True,
112                 },
113             )
114
115         resources_as_map = GoogleMaps(
116             page       = page,
117             title      = 'Geographic view',
118             domid      = 'gmap',
119             # tab's sons preferably turn this off
120             togglable  = False,
121             query      = sq_resource,
122             query_all  = query_resource_all,
123             checkboxes = True,
124             # center on Paris
125             latitude   = 49.,
126             longitude  = 2.2,
127             zoom       = 3,
128         )
129
130         resources_query_editor = QueryEditor(
131             page  = page,
132             query = sq_resource,
133             )
134         resources_active_filters = ActiveFilters(
135             page  = page,
136             query = sq_resource,
137             )
138
139         resources_area = Stack (
140             page=page,
141             domid="resources",
142             togglable=True,
143             title="Resources",
144             outline_complete=True,
145             sons = [
146                 Tabs ( page=page, 
147                        sons=[ resources_as_list, resources_as_map, ] 
148                        ),
149                 Stack ( page=page,
150                         title="Customize",
151                         togglable=True,
152                         sons = [ resources_query_editor, resources_active_filters, ]
153                         ),
154                 ]
155             )
156
157         main_stack.insert (resources_area)
158
159
160 #        sq_plugin = Tabs (
161 #            page=page,
162 #            title="Slice view for %s"%slicename,
163 #            togglable=True,
164 #            sons=[],
165 #        )
166     
167     
168         ############################################################################
169         # RESOURCES
170         # 
171         # A stack inserted in the subquery tab that will hold all operations
172         # related to resources
173         # 
174         
175 #        stack_resources = Stack(
176 #            page = page,
177 #            title = 'Resources',
178 #            sons=[],
179 #        )
180     
181 #        stack_resources.insert(resource_active_filters)
182 #    
183 #    
184 #        stack_resources.insert(tab_resource_plugins)
185     
186 #        sq_plugin.insert(stack_resources)
187     
188         ############################################################################
189         # USERS
190         # 
191     
192         tab_users = Tabs(
193             page                = page,
194             domid               = 'users',
195             outline_complete    = True,
196             togglable           = True,
197             title               = 'Users',
198             active_domid        = 'checkboxes2',
199         )
200         main_stack.insert(tab_users)
201     
202         tab_users.insert(Hazelnut( 
203             page        = page,
204             title       = 'Users List',
205             domid       = 'checkboxes2',
206             # tab's sons preferably turn this off
207             togglable   = False,
208             # this is the query at the core of the slice list
209             query       = sq_user,
210             query_all  = query_user_all,
211             checkboxes  = True,
212             datatables_options = { 
213                 # for now we turn off sorting on the checkboxes columns this way
214                 # this of course should be automatic in hazelnut
215                 'aoColumns'      : [None, None, None, None, {'bSortable': False}],
216                 'iDisplayLength' : 25,
217                 'bLengthChange'  : True,
218             },
219         ))
220     
221         tab_measurements = Tabs (
222             page                = page,
223             active_domid        = 'checkboxes3',
224             outline_complete    = True,
225             togglable           = True,
226             title               = 'Measurements',
227             domid               = 'measurements',
228         )
229         main_stack.insert(tab_measurements)
230     
231         tab_measurements.insert(Hazelnut( 
232             page        = page,
233             title       = 'Measurements',
234             domid       = 'checkboxes3',
235             # tab's sons preferably turn this off
236             togglable   = False,
237             # this is the query at the core of the slice list
238             query       = sq_measurement,
239             checkboxes  = True,
240             datatables_options = { 
241                 # for now we turn off sorting on the checkboxes columns this way
242                 # this of course should be automatic in hazelnut
243                 'aoColumns'      : [None, None, None, None, {'bSortable': False}],
244                 'iDisplayLength' : 25,
245                 'bLengthChange'  : True,
246             },
247         ))
248     
249 #        main_stack.insert(sq_plugin)
250     
251         # --------------------------------------------------------------------------
252         # ResourcesSelected
253         #
254         main_stack.insert(ResourcesSelected(
255             page                = page,
256             title               = 'Pending operations',
257             query               = main_query,
258             togglable           = True,
259             domid               = 'pending',
260             outline_complete    = True,
261         ))
262     
263         main_stack.insert(Messages(
264             page   = page,
265             title  = "Runtime messages for slice %s"%slicename,
266             domid  = "msgs-pre",
267             levels = "ALL",
268         ))
269     #    main_stack.insert(Updater(
270     #        page   = page,
271     #        title  = "wont show up as non togglable by default",
272     #        query  = main_query,
273     #        label  = "Update slice",
274     #    ))
275         
276     
277     
278         # variables that will get passed to the view-unfold1.html template
279         template_env = {}
280         
281         # define 'unfold1_main' to the template engine - the main contents
282         template_env [ 'unfold1_main' ] = main_stack.render(request)
283     
284         # more general variables expected in the template
285         template_env [ 'title' ] = '%(slicename)s'%locals()
286         # the menu items on the top
287         template_env [ 'topmenu_items' ] = topmenu_items('Slice', request) 
288         # so we can sho who is logged
289         template_env [ 'username' ] = the_user (request) 
290     
291         # don't forget to run the requests
292         page.expose_queries ()
293     
294         # xxx create another plugin with the same query and a different layout (with_datatables)
295         # show that it worls as expected, one single api call to backend and 2 refreshed views
296     
297         # the prelude object in page contains a summary of the requirements() for all plugins
298         # define {js,css}_{files,chunks}
299         prelude_env = page.prelude_env()
300         template_env.update(prelude_env)
301         result=render_to_response ('view-unfold1.html',template_env,
302                                    context_instance=RequestContext(request))
303         return result