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