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