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