plugins: reworked the framework using inheritance + added active_filters
[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.query_editor            import QueryEditor
24 from plugins.active_filters          import ActiveFilters
25 from plugins.quickfilter.quickfilter import QuickFilter
26 from plugins.messages.messages       import Messages
27 from plugins.updater.updater         import Updater
28
29 tmp_default_slice='ple.inria.myslicedemo'
30 debug = True
31
32 @login_required
33 def slice_view (request, slicename=tmp_default_slice):
34     # xxx Thierry - ugly hack
35     # fetching metadata here might fail - e.g. with an expired session..
36     # let's catch this early on and log out our user if needed
37     # it should of course be handled in a more generic way
38     try:
39         return _slice_view(request,slicename)
40     except ManifoldException, manifold_result:
41         # xxx needs a means to display this message to user...
42         from django.contrib.auth import logout
43         logout(request)
44         return HttpResponseRedirect ('/')
45     except Exception, e:
46         # xxx we need to sugarcoat this error message in some error template...
47         print "Unexpected exception",e
48         import traceback
49         traceback.print_exc()
50         # return ...
51
52 def _slice_view (request, slicename):
53
54     page = Page(request)
55     page.expose_js_metadata()
56
57     metadata = page.get_metadata()
58     resource_md = metadata.details_by_object('resource')
59     resource_fields = [column['name'] for column in resource_md['column']]
60
61     # TODO The query to run is embedded in the URL
62     main_query = Query.get('slice').filter_by('slice_hrn', '=', slicename)
63     main_query.select(
64             'slice_hrn',
65             'resource.resource_hrn', 'resource.hostname', 'resource.type', 'resource.network_hrn',
66             #'lease.urn',
67             'user.user_hrn',
68             #'application.measurement_point.counter'
69     )
70
71     query_resource_all = Query.get('resource').select(resource_fields)
72
73     aq = AnalyzedQuery(main_query, metadata=metadata)
74     page.enqueue_query(main_query, analyzed_query=aq)
75     page.enqueue_query(query_resource_all)
76
77     # Prepare the display according to all metadata
78     # (some parts will be pending, others can be triggered by users).
79     # 
80     # For example slice measurements will not be requested by default...
81
82     # Create the base layout (Stack)...
83     main_plugin = Stack (
84         page=page,
85         title="Slice !!view for %s"%slicename,
86         sons=[],
87     )
88
89     # ... responsible for the slice properties...
90
91
92     main_plugin.insert (
93         Raw (page=page,togglable=False, toggled=True,html="<h2> Slice page for %s</h2>"%slicename)
94     )
95
96     main_plugin.insert(
97         Raw (page=page,togglable=False, toggled=True,html='<b>Description:</b> TODO')
98     )
99
100     sq_plugin = Tabs (
101         page=page,
102         title="Slice view for %s"%slicename,
103         togglable=False,
104         sons=[],
105     )
106
107
108     # ... and for the relations
109     # XXX Let's hardcode resources for now
110     sq_resource = aq.subquery('resource')
111     sq_user     = aq.subquery('user')
112     sq_lease    = aq.subquery('lease')
113     sq_measurement = aq.subquery('measurement')
114     
115
116     ############################################################################
117     # RESOURCES
118     # 
119     # A stack inserted in the subquery tab that will hold all operations
120     # related to resources
121     # 
122     
123     stack_resources = Stack(
124         page = page,
125         title        = 'Resources',
126         sons=[],
127     )
128
129     resource_query_editor = QueryEditor(
130         page  = page,
131         query = sq_resource,
132     )
133     stack_resources.insert(resource_query_editor)
134
135     resource_active_filters = ActiveFilters(
136         page  = page,
137         query = sq_resource,
138     )
139     stack_resources.insert(resource_active_filters)
140
141     # --------------------------------------------------------------------------
142     # Different displays = DataTables + GoogleMaps
143     #
144     tab_resource_plugins = Tabs(
145         page    = page,
146         sons = []
147     )
148
149     tab_resource_plugins.insert(Hazelnut( 
150         page       = page,
151         title      = 'List',
152         domid      = 'checkboxes',
153         # this is the query at the core of the slice list
154         query      = sq_resource,
155         query_all  = query_resource_all,
156         checkboxes = True,
157         datatables_options = { 
158             # for now we turn off sorting on the checkboxes columns this way
159             # this of course should be automatic in hazelnut
160             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
161             'iDisplayLength' : 25,
162             'bLengthChange'  : True,
163         },
164     ))
165
166     tab_resource_plugins.insert(GoogleMap(
167         page       = page,
168         title      = 'Geographic view',
169         domid      = 'gmap',
170         # tab's sons preferably turn this off
171         togglable  = False,
172         query      = sq_resource,
173         query_all  = query_resource_all,
174         checkboxes = True,
175         # center on Paris
176         latitude   = 49.,
177         longitude  = 2.2,
178         zoom       = 3,
179     ))
180
181     stack_resources.insert(tab_resource_plugins)
182
183     # --------------------------------------------------------------------------
184     # ResourcesSelected
185     #
186     stack_resources.insert(ResourcesSelected(
187         page                = page,
188         title               = 'Pending operations',
189         resource_query_uuid = sq_resource,
190         lease_query_uuid    = sq_lease,
191         togglable           = True,
192     ))
193
194     sq_plugin.insert(stack_resources)
195
196     ############################################################################
197     # USERS
198     # 
199
200     tab_users = Tabs(
201         page         = page,
202         title        = 'Users',
203         domid        = 'thetabs2',
204         # activeid   = 'checkboxes',
205         active_domid = 'checkboxes2',
206     )
207     sq_plugin.insert(tab_users)
208
209     tab_users.insert(Hazelnut( 
210         page        = page,
211         title       = 'List',
212         domid       = 'checkboxes2',
213         # tab's sons preferably turn this off
214         togglable   = False,
215         # this is the query at the core of the slice list
216         query       = sq_user,
217         checkboxes  = True,
218         datatables_options = { 
219             # for now we turn off sorting on the checkboxes columns this way
220             # this of course should be automatic in hazelnut
221             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
222             'iDisplayLength' : 25,
223             'bLengthChange'  : True,
224         },
225     ))
226
227     tab_measurements = Tabs (
228         page         = page,
229         title        = 'Measurements',
230         domid        = 'thetabs3',
231         # activeid   = 'checkboxes',
232         active_domid = 'checkboxes3',
233     )
234     sq_plugin.insert(tab_measurements)
235
236     tab_measurements.insert(Hazelnut( 
237         page        = page,
238         title       = 'List',
239         domid       = 'checkboxes3',
240         # tab's sons preferably turn this off
241         togglable   = False,
242         # this is the query at the core of the slice list
243         query       = sq_measurement,
244         checkboxes  = True,
245         datatables_options = { 
246             # for now we turn off sorting on the checkboxes columns this way
247             # this of course should be automatic in hazelnut
248             'aoColumns'      : [None, None, None, None, {'bSortable': False}],
249             'iDisplayLength' : 25,
250             'bLengthChange'  : True,
251         },
252     ))
253
254     main_plugin.insert(sq_plugin)
255
256     main_plugin.insert(Messages(
257         page   = page,
258         title  = "Runtime messages for slice %s"%slicename,
259         domid  = "msgs-pre",
260         levels = "ALL",
261     ))
262     main_plugin.insert(Updater(
263         page   = page,
264         title  = "wont show up as non togglable by default",
265         query  = main_query,
266         label  = "Update slice",
267     ))
268     
269
270
271     # variables that will get passed to the view-unfold1.html template
272     template_env = {}
273     
274     # define 'unfold1_main' to the template engine - the main contents
275     template_env [ 'unfold1_main' ] = main_plugin.render(request)
276
277     # more general variables expected in the template
278     template_env [ 'title' ] = 'Test view that combines various plugins'
279     # the menu items on the top
280     template_env [ 'topmenu_items' ] = topmenu_items('Slice', request) 
281     # so we can sho who is logged
282     template_env [ 'username' ] = the_user (request) 
283
284     # don't forget to run the requests
285     page.expose_queries ()
286
287     # xxx create another plugin with the same query and a different layout (with_datatables)
288     # show that it worls as expected, one single api call to backend and 2 refreshed views
289
290     # the prelude object in page contains a summary of the requirements() for all plugins
291     # define {js,css}_{files,chunks}
292     prelude_env = page.prelude_env()
293     template_env.update(prelude_env)
294     result=render_to_response ('view-unfold1.html',template_env,
295                                context_instance=RequestContext(request))
296     return result