0036221c8f8ce3937cdd4090e0ccbf89cb364b62
[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.myslicedemo'
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', 'network_hrn', 'latitude', 'longitude')
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.network_hrn',
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         query_all_uuid = query_resource_all.query_uuid,
163         checkboxes     = True,
164         # center on Paris
165         latitude    = 49.,
166         longitude   = 2.2,
167         zoom        = 3,
168     ))
169
170     stack_resources.insert(tab_resource_plugins)
171
172     # --------------------------------------------------------------------------
173     # ResourcesSelected
174     #
175     stack_resources.insert(ResourcesSelected(
176         page                = page,
177         title               = 'Pending operations',
178         resource_query_uuid = sq_resource,
179         lease_query_uuid    = sq_lease,
180         togglable           = True,
181     ))
182
183     sq_plugin.insert(stack_resources)
184
185     ############################################################################
186     # USERS
187     # 
188
189     tab_users = Tabs(
190         page         = page,
191         title        = 'Users',
192         domid        = 'thetabs2',
193         # activeid   = 'checkboxes',
194         active_domid = 'checkboxes2',
195     )
196     sq_plugin.insert(tab_users)
197
198     tab_users.insert(Hazelnut( 
199         page        = page,
200         title       = 'List',
201         domid       = 'checkboxes2',
202         # tab's sons preferably turn this off
203         togglable   = False,
204         # this is the query at the core of the slice list
205         query       = sq_user,
206         checkboxes  = True,
207         datatables_options = { 
208             # for now we turn off sorting on the checkboxes columns this way
209             # this of course should be automatic in hazelnut
210             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
211             'iDisplayLength' : 25,
212             'bLengthChange'  : True,
213         },
214     ))
215
216     tab_measurements = Tabs (
217         page         = page,
218         title        = 'Measurements',
219         domid        = 'thetabs3',
220         # activeid   = 'checkboxes',
221         active_domid = 'checkboxes3',
222     )
223     sq_plugin.insert(tab_measurements)
224
225     tab_measurements.insert(Hazelnut( 
226         page        = page,
227         title       = 'List',
228         domid       = 'checkboxes3',
229         # tab's sons preferably turn this off
230         togglable   = False,
231         # this is the query at the core of the slice list
232         query       = sq_measurement,
233         checkboxes  = True,
234         datatables_options = { 
235             # for now we turn off sorting on the checkboxes columns this way
236             # this of course should be automatic in hazelnut
237             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
238             'iDisplayLength' : 25,
239             'bLengthChange'  : True,
240         },
241     ))
242
243     main_plugin.insert(sq_plugin)
244
245     main_plugin.insert(Messages(
246         page   = page,
247         title  = "Runtime messages for slice %s"%slicename,
248         domid  = "msgs-pre",
249         levels = "ALL",
250     ))
251     main_plugin.insert(Updater(
252         page   = page,
253         title  = "wont show up as non togglable by default",
254         query  = main_query,
255         label  = "Update slice",
256     ))
257     
258
259     # END OF JORDAN's CODE
260
261 #old#    main_plugin = Stack (
262 #old#        page=page,
263 #old#        title="Slice view for %s"%slicename,
264 #old#        domid='thestack',
265 #old#        togglable=False,
266 #old#        sons=[
267 #old#            Raw (page=page,togglable=False, toggled=True,html="<h2> Slice page for %s</h2>"%slicename),
268 #old#            Messages (
269 #old#                page=page,
270 #old#                title="Runtime messages for slice %s"%slicename,
271 #old#                domid="msgs-pre",
272 #old#                levels="ALL",
273 #old#                ),
274 #old#            Tabs (
275 #old#                page=page,
276 #old#                title="2 tabs : w/ and w/o checkboxes",
277 #old#                domid='thetabs',
278 #old#                # active_domid='checkboxes',
279 #old#                active_domid='gmap',
280 #old#                sons=[
281 #old#                    Hazelnut ( 
282 #old#                        page=page,
283 #old#                        title='a sample and simple hazelnut',
284 #old#                        domid='simple',
285 #old#                        # tab's sons preferably turn this off
286 #old#                        togglable=False,
287 #old#                        # this is the query at the core of the slice list
288 #old#                        query=main_query,
289 #old#                        ),
290 #old#                    Hazelnut ( 
291 #old#                        page=page,
292 #old#                        title='with checkboxes',
293 #old#                        domid='checkboxes',
294 #old#                        # tab's sons preferably turn this off
295 #old#                        togglable=False,
296 #old#                        # this is the query at the core of the slice list
297 #old#                        query=main_query,
298 #old#                        checkboxes=True,
299 #old#                        datatables_options = { 
300 #old#                            # for now we turn off sorting on the checkboxes columns this way
301 #old#                            # this of course should be automatic in hazelnut
302 #old#                            'aoColumns' : [ None, None, None, None, {'bSortable': False} ],
303 #old#                            'iDisplayLength' : 25,
304 #old#                            'bLengthChange' : True,
305 #old#                            },
306 #old#                        ),
307 #old#                    GoogleMap (
308 #old#                        page=page,
309 #old#                        title='geographic view',
310 #old#                        domid='gmap',
311 #old#                        # tab's sons preferably turn this off
312 #old#                        togglable=False,
313 #old#                        query=main_query,
314 #old#                        # center on Paris
315 #old#                        latitude=49.,
316 #old#                        longitude=2.2,
317 #old#                        zoom=3,
318 #old#                        ),
319 #old#                    Raw (
320 #old##                    SensLabMap (
321 #old#                        page=page,
322 #old#                        title='3D view (disabled)',
323 #old#                        domid='smap',
324 #old##                        # tab's sons preferably turn this off
325 #old#                        togglable=False,
326 #old##                        query=main_query,
327 #old#                        html="""<p class='well'>
328 #old#Thierry: I am commeting off the use of <button class="btn btn-danger">SensLabMap</button> which,
329 #old# although rudimentarily ported to the django framework, 
330 #old#causes a weird behaviour especially wrt scrolling. 
331 #old#On my Mac <button class="btn btn-warning"> I cannot use the mouse to scroll</button> any longer
332 #old#if I keep this active, so for now it's disabled
333 #old#</p>""",
334 #old#                        ),
335 #old#                    ]),
336 #old#            Hazelnut ( 
337 #old#                page=page,
338 #old#                title='a hazelnut not in tabs',
339 #old#                domid='standalone',
340 #old#                # this is the query at the core of the slice list
341 #old#                query=main_query,
342 #old#                columns=['hrn','hostname'],
343 #old#                ),
344 #old#              # you don't *have to* set a domid, but if you plan on using toggled=persistent then it's required
345 #old#              # because domid is the key for storing toggle status in the browser
346 #old#            QueryCode (
347 #old#                page=page,
348 #old#                title='xmlrpc code (toggled=False)',
349 #old#                query=main_query,
350 #old##                domid='xmlrpc',
351 #old#                toggled=False,
352 #old#                ),
353 #old#            QuickFilter (
354 #old#                page=page,
355 #old#                title="QuickFilter - requires metadata (toggled=False)",
356 #old#                criterias=quickfilter_criterias,
357 #old#                domid='filters',
358 #old#                toggled=False,
359 #old#                ),
360 #old#            Messages (
361 #old#                page=page,
362 #old#                title="Runtime messages (again)",
363 #old#                domid="msgs-post",
364 #old#                )
365 #old#              ])
366
367     # variables that will get passed to the view-unfold1.html template
368     template_env = {}
369     
370     # define 'unfold1_main' to the template engine - the main contents
371     template_env [ 'unfold1_main' ] = main_plugin.render(request)
372
373     # more general variables expected in the template
374     template_env [ 'title' ] = 'Test view that combines various plugins'
375     # the menu items on the top
376     template_env [ 'topmenu_items' ] = topmenu_items('Slice', request) 
377     # so we can sho who is logged
378     template_env [ 'username' ] = the_user (request) 
379
380     # don't forget to run the requests
381     page.expose_queries ()
382
383     # xxx create another plugin with the same query and a different layout (with_datatables)
384     # show that it worls as expected, one single api call to backend and 2 refreshed views
385
386     # the prelude object in page contains a summary of the requirements() for all plugins
387     # define {js,css}_{files,chunks}
388     prelude_env = page.prelude_env()
389     template_env.update(prelude_env)
390     result=render_to_response ('view-unfold1.html',template_env,
391                                context_instance=RequestContext(request))
392     return result