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