fixed hazelnut checkbox management
[myslice.git] / trash / sliceview.py
1 # Create your views here.
2
3 from django.template                 import RequestContext
4 from django.shortcuts                import render_to_response
5 from django.contrib.auth.decorators  import login_required
6 from django.http                     import HttpResponseRedirect
7
8 from unfold.page                     import Page
9 from manifold.core.query             import Query, AnalyzedQuery
10 from manifold.manifoldresult         import ManifoldException
11 from manifold.metadata               import MetaData as Metadata
12 from myslice.viewutils               import quickfilter_criterias, topmenu_items, the_user
13
14 from plugins.raw.raw                 import Raw
15 from plugins.stack.stack             import Stack
16 from plugins.tabs.tabs               import Tabs
17 from plugins.lists.slicelist         import SliceList
18 from plugins.hazelnut.hazelnut       import Hazelnut 
19 from plugins.resources_selected      import ResourcesSelected
20 from plugins.googlemap.googlemap     import GoogleMap 
21 from plugins.senslabmap.senslabmap   import SensLabMap
22 from plugins.querycode.querycode     import QueryCode
23 from plugins.quickfilter.quickfilter import QuickFilter
24 from plugins.messages.messages       import Messages
25 from plugins.updater.updater         import Updater
26
27 tmp_default_slice='ple.inria.heartbeat'
28 debug = True
29
30 @login_required
31 def slice_view (request, slicename=tmp_default_slice):
32     # xxx Thierry - ugly hack
33     # fetching metadata here might fail - e.g. with an expired session..
34     # let's catch this early on and log out our user if needed
35     # it should of course be handled in a more generic way
36     try:
37         return _slice_view(request,slicename)
38     except ManifoldException, manifold_result:
39         # xxx needs a means to display this message to user...
40         from django.contrib.auth import logout
41         logout(request)
42         return HttpResponseRedirect ('/')
43     except Exception, e:
44         # xxx we need to sugarcoat this error message in some error template...
45         print "Unexpected exception",e
46         import traceback
47         traceback.print_exc()
48         # return ...
49
50 def _slice_view (request, slicename):
51
52     page = Page(request)
53     page.expose_js_metadata()
54
55     # TODO The query to run is embedded in the URL
56     main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
57     query_resource_all = Query.get('resource').select('resource_hrn', 'hostname', 'type', 'authority')
58
59     # Get default fields from metadata unless specified
60     if not main_query.fields:
61         metadata = page.get_metadata()
62         md_fields = metadata.details_by_object('slice')
63         if debug:
64             print "METADATA", md_fields
65         # TODO Get default fields
66         main_query.select(
67                 'slice_hrn',
68                 'resource.resource_hrn', 'resource.hostname', 'resource.type', 'resource.authority',
69                 'lease.urn',
70                 'user.user_hrn',
71 #                'application.measurement_point.counter'
72         )
73
74     aq = AnalyzedQuery(main_query, metadata=metadata)
75     page.enqueue_query(main_query, analyzed_query=aq)
76     page.enqueue_query(query_resource_all)
77
78     # Prepare the display according to all metadata
79     # (some parts will be pending, others can be triggered by users).
80     # 
81     # For example slice measurements will not be requested by default...
82
83     # Create the base layout (Stack)...
84     main_plugin = Stack (
85         page=page,
86         title="Slice !!view for %s"%slicename,
87         sons=[],
88     )
89
90     # ... responsible for the slice properties...
91
92
93     main_plugin.insert (
94         Raw (page=page,togglable=False, toggled=True,html="<h2> Slice page for %s</h2>"%slicename)
95     )
96
97     main_plugin.insert(
98         Raw (page=page,togglable=False, toggled=True,html='<b>Description:</b> TODO')
99     )
100
101     sq_plugin = Tabs (
102         page=page,
103         title="Slice view for %s"%slicename,
104         togglable=False,
105         sons=[],
106     )
107
108
109     # ... and for the relations
110     # XXX Let's hardcode resources for now
111     sq_resource = aq.subquery('resource')
112     sq_user     = aq.subquery('user')
113     sq_lease    = aq.subquery('lease')
114     sq_measurement = aq.subquery('measurement')
115     
116
117     ############################################################################
118     # RESOURCES
119     # 
120     # A stack inserted in the subquery tab that will hold all operations
121     # related to resources
122     # 
123     
124     stack_resources = Stack(
125         page = page,
126         title        = 'Resources',
127         sons=[],
128     )
129
130     # --------------------------------------------------------------------------
131     # Different displays = DataTables + GoogleMaps
132     #
133     tab_resource_plugins = Tabs(
134         page    = page,
135         sons = []
136     )
137
138     tab_resource_plugins.insert(Hazelnut( 
139         page           = page,
140         title          = 'List',
141         domid          = 'checkboxes',
142         # this is the query at the core of the slice list
143         query          = sq_resource,
144         query_all_uuid = query_resource_all.query_uuid,
145         checkboxes     = True,
146         datatables_options = { 
147             # for now we turn off sorting on the checkboxes columns this way
148             # this of course should be automatic in hazelnut
149             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
150             'iDisplayLength' : 25,
151             'bLengthChange'  : True,
152         },
153     ))
154
155     tab_resource_plugins.insert(GoogleMap(
156         page        = page,
157         title       = 'Geographic view',
158         domid       = 'gmap',
159         # tab's sons preferably turn this off
160         togglable   = False,
161         query       = sq_resource,
162         # center on Paris
163         latitude    = 49.,
164         longitude   = 2.2,
165         zoom        = 3,
166     ))
167
168     stack_resources.insert(tab_resource_plugins)
169
170     # --------------------------------------------------------------------------
171     # ResourcesSelected
172     #
173     stack_resources.insert(ResourcesSelected(
174         page                = page,
175         title               = 'Pending operations',
176         resource_query_uuid = sq_resource,
177         lease_query_uuid    = sq_lease,
178         togglable           = True,
179     ))
180
181     sq_plugin.insert(stack_resources)
182
183     ############################################################################
184     # USERS
185     # 
186
187     tab_users = Tabs(
188         page         = page,
189         title        = 'Users',
190         domid        = 'thetabs2',
191         # activeid   = 'checkboxes',
192         active_domid = 'checkboxes2',
193     )
194     sq_plugin.insert(tab_users)
195
196     tab_users.insert(Hazelnut( 
197         page        = page,
198         title       = 'List',
199         domid       = 'checkboxes2',
200         # tab's sons preferably turn this off
201         togglable   = False,
202         # this is the query at the core of the slice list
203         query       = sq_user,
204         checkboxes  = True,
205         datatables_options = { 
206             # for now we turn off sorting on the checkboxes columns this way
207             # this of course should be automatic in hazelnut
208             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
209             'iDisplayLength' : 25,
210             'bLengthChange'  : True,
211         },
212     ))
213
214     tab_measurements = Tabs (
215         page         = page,
216         title        = 'Measurements',
217         domid        = 'thetabs3',
218         # activeid   = 'checkboxes',
219         active_domid = 'checkboxes3',
220     )
221     sq_plugin.insert(tab_measurements)
222
223     tab_measurements.insert(Hazelnut( 
224         page        = page,
225         title       = 'List',
226         domid       = 'checkboxes3',
227         # tab's sons preferably turn this off
228         togglable   = False,
229         # this is the query at the core of the slice list
230         query       = sq_measurement,
231         checkboxes  = True,
232         datatables_options = { 
233             # for now we turn off sorting on the checkboxes columns this way
234             # this of course should be automatic in hazelnut
235             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
236             'iDisplayLength' : 25,
237             'bLengthChange'  : True,
238         },
239     ))
240
241     main_plugin.insert(sq_plugin)
242
243     main_plugin.insert(Messages(
244         page   = page,
245         title  = "Runtime messages for slice %s"%slicename,
246         domid  = "msgs-pre",
247         levels = "ALL",
248     ))
249     main_plugin.insert(Updater(
250         page   = page,
251         title  = "wont show up as non togglable by default",
252         query  = main_query,
253         label  = "Update slice",
254     ))
255     
256
257     # END OF JORDAN's CODE
258
259 #old#    main_plugin = Stack (
260 #old#        page=page,
261 #old#        title="Slice view for %s"%slicename,
262 #old#        domid='thestack',
263 #old#        togglable=False,
264 #old#        sons=[
265 #old#            Raw (page=page,togglable=False, toggled=True,html="<h2> Slice page for %s</h2>"%slicename),
266 #old#            Messages (
267 #old#                page=page,
268 #old#                title="Runtime messages for slice %s"%slicename,
269 #old#                domid="msgs-pre",
270 #old#                levels="ALL",
271 #old#                ),
272 #old#            Tabs (
273 #old#                page=page,
274 #old#                title="2 tabs : w/ and w/o checkboxes",
275 #old#                domid='thetabs',
276 #old#                # active_domid='checkboxes',
277 #old#                active_domid='gmap',
278 #old#                sons=[
279 #old#                    Hazelnut ( 
280 #old#                        page=page,
281 #old#                        title='a sample and simple hazelnut',
282 #old#                        domid='simple',
283 #old#                        # tab's sons preferably turn this off
284 #old#                        togglable=False,
285 #old#                        # this is the query at the core of the slice list
286 #old#                        query=main_query,
287 #old#                        ),
288 #old#                    Hazelnut ( 
289 #old#                        page=page,
290 #old#                        title='with checkboxes',
291 #old#                        domid='checkboxes',
292 #old#                        # tab's sons preferably turn this off
293 #old#                        togglable=False,
294 #old#                        # this is the query at the core of the slice list
295 #old#                        query=main_query,
296 #old#                        checkboxes=True,
297 #old#                        datatables_options = { 
298 #old#                            # for now we turn off sorting on the checkboxes columns this way
299 #old#                            # this of course should be automatic in hazelnut
300 #old#                            'aoColumns' : [ None, None, None, None, {'bSortable': False} ],
301 #old#                            'iDisplayLength' : 25,
302 #old#                            'bLengthChange' : True,
303 #old#                            },
304 #old#                        ),
305 #old#                    GoogleMap (
306 #old#                        page=page,
307 #old#                        title='geographic view',
308 #old#                        domid='gmap',
309 #old#                        # tab's sons preferably turn this off
310 #old#                        togglable=False,
311 #old#                        query=main_query,
312 #old#                        # center on Paris
313 #old#                        latitude=49.,
314 #old#                        longitude=2.2,
315 #old#                        zoom=3,
316 #old#                        ),
317 #old#                    Raw (
318 #old##                    SensLabMap (
319 #old#                        page=page,
320 #old#                        title='3D view (disabled)',
321 #old#                        domid='smap',
322 #old##                        # tab's sons preferably turn this off
323 #old#                        togglable=False,
324 #old##                        query=main_query,
325 #old#                        html="""<p class='well'>
326 #old#Thierry: I am commeting off the use of <button class="btn btn-danger">SensLabMap</button> which,
327 #old# although rudimentarily ported to the django framework, 
328 #old#causes a weird behaviour especially wrt scrolling. 
329 #old#On my Mac <button class="btn btn-warning"> I cannot use the mouse to scroll</button> any longer
330 #old#if I keep this active, so for now it's disabled
331 #old#</p>""",
332 #old#                        ),
333 #old#                    ]),
334 #old#            Hazelnut ( 
335 #old#                page=page,
336 #old#                title='a hazelnut not in tabs',
337 #old#                domid='standalone',
338 #old#                # this is the query at the core of the slice list
339 #old#                query=main_query,
340 #old#                columns=['hrn','hostname'],
341 #old#                ),
342 #old#              # you don't *have to* set a domid, but if you plan on using toggled=persistent then it's required
343 #old#              # because domid is the key for storing toggle status in the browser
344 #old#            QueryCode (
345 #old#                page=page,
346 #old#                title='xmlrpc code (toggled=False)',
347 #old#                query=main_query,
348 #old##                domid='xmlrpc',
349 #old#                toggled=False,
350 #old#                ),
351 #old#            QuickFilter (
352 #old#                page=page,
353 #old#                title="QuickFilter - requires metadata (toggled=False)",
354 #old#                criterias=quickfilter_criterias,
355 #old#                domid='filters',
356 #old#                toggled=False,
357 #old#                ),
358 #old#            Messages (
359 #old#                page=page,
360 #old#                title="Runtime messages (again)",
361 #old#                domid="msgs-post",
362 #old#                )
363 #old#              ])
364
365     # variables that will get passed to the view-unfold1.html template
366     template_env = {}
367     
368     # define 'unfold1_main' to the template engine - the main contents
369     template_env [ 'unfold1_main' ] = main_plugin.render(request)
370
371     # more general variables expected in the template
372     template_env [ 'title' ] = 'Test view that combines various plugins'
373     # the menu items on the top
374     template_env [ 'topmenu_items' ] = topmenu_items('slice', request) 
375     # so we can sho who is logged
376     template_env [ 'username' ] = the_user (request) 
377
378     # don't forget to run the requests
379     page.expose_queries ()
380
381     # xxx create another plugin with the same query and a different layout (with_datatables)
382     # show that it worls as expected, one single api call to backend and 2 refreshed views
383
384     # the prelude object in page contains a summary of the requirements() for all plugins
385     # define {js,css}_{files,chunks}
386     prelude_env = page.prelude_env()
387     template_env.update(prelude_env)
388     result=render_to_response ('view-unfold1.html',template_env,
389                                context_instance=RequestContext(request))
390     return result