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