Home | Trees | Indices | Help |
---|
|
1 # Elisa - Home multimedia server 2 # Copyright (C) 2006-2008 Fluendo, S.A. (www.fluendo.com). 3 # All rights reserved. 4 # 5 # This file is available under one of two license agreements. 6 # 7 # This file is licensed under the GPL version 3. 8 # See "LICENSE.GPL" in the root of this distribution including a special 9 # exception to use Elisa with Fluendo's plugins. 10 # 11 # The GPL part of Elisa is also available under a commercial licensing 12 # agreement from Fluendo. 13 # See "LICENSE.Elisa" in the root directory of this distribution package 14 # for details on that license. 15 16 17 __maintainer__ = 'Florian Boucault <florian@fluendo.com>' 18 __maintainer2__ = 'Lionel Martin <lionel@fluendo.com>' 19 20 21 from elisa.core import log, config 22 from elisa.core.frontend import Frontend 23 from elisa.core.backend import Backend 24 from elisa.core import common 25 from elisa.core.utils import locale_helper 26 27 from twisted.internet import defer 28 import os 2931 """ 32 Raised by L{InterfaceController} when no Model/View or 33 Model/Controller association is found in the MVC mappings of the 34 frontend or backend managed by the interface controller. 35 """ 36 pass3739 """ InterfaceController is responsible for creating, managing and deleting 40 L{elisa.core.frontend.Frontend}s and L{elisa.core.backend.Backend}s 41 defined by the user, and to associate them together. It also links the 42 chosen L{elisa.base_components.input_provider.InputProvider}s with them. 43 """ 44 45 # Backends dictionary: 46 # key : name defined in config 47 # value : backend instance 48 _backends = {} 49 50 # Frontends dictionary: 51 # key : name defined in config 52 # value : frontend instance 53 _frontends = {} 54 55 # Activities dictionary: 56 # key : Activity path 57 # value : Activity instance 58 _activities = {} 59 6336665 self._mvc_mappings = {} 66 67 app_config = common.application.config 68 69 paths = backend_paths + frontend_paths 70 for path in paths: 71 mvc_mappings = app_config.get_option('mvc_mappings', 72 section=path, 73 default='') 74 if mvc_mappings: 75 config_file = self._get_mvc_config_file(mvc_mappings) 76 self._mvc_mappings[path] = config_file7779 app_config_dir = common.application.config.get_config_dir() 80 plugin_registry = common.application.plugin_registry 81 82 if ':' not in mvc_mappings: 83 mvc_mappings_config_file = os.path.join(app_config_dir, 84 mvc_mappings) 85 else: 86 plugin_name, rel_path = mvc_mappings.split(':') 87 plugin = plugin_registry.plugin_classes[plugin_name] 88 mvc_mappings_config_file = plugin.get_resource_file(rel_path) 89 90 return mvc_mappings_config_file9193 mvc_config = None 94 config = common.application.config 95 frontend_paths = config.get_option('frontends', section='general', 96 default=[]) 97 for frontend_path in frontend_paths: 98 backend = config.get_option('backend', section=frontend_path) 99 if backend and backend_name == backend: 100 mvc_config = self._mvc_mappings.get(frontend_path) 101 if mvc_config: 102 break 103 104 return mvc_config105107 """ Initialize various variables internal to the InterfaceController 108 such as the backends and the frontends. 109 110 This method is called after the application's configuration is loaded. 111 """ 112 self.info("Initializing") 113 application = common.application 114 115 self._backends = {} 116 self._frontends = {} 117 self._activities = {} 118 119 backend_paths = application.config.get_option('backends', 120 section='general', 121 default=[]) 122 frontend_paths = application.config.get_option('frontends', 123 section='general', 124 default=[]) 125 126 self._initialize_mvc_mappings(backend_paths, frontend_paths) 127 128 # Create backend instances declared in the configuration 129 for backend_path in backend_paths: 130 try: 131 self._create_backend(backend_path) 132 except Exception, e: 133 self.warning("An error occured causing backend '%s' creation " \ 134 "to fail" % backend_path) 135 application.handle_traceback() 136 if backend_path in self._backends: 137 self._backends.pop(backend_path) 138 139 # Create frontend instances declared in the configuration 140 for frontend_path in frontend_paths: 141 try: 142 self._create_frontend(frontend_path) 143 except Exception, exc: 144 self.warning("An error occured causing frontend '%s' creation " \ 145 "to fail" % frontend_path) 146 application.handle_traceback() 147 if frontend_path in self._frontends: 148 self._frontends.pop(frontend_path)149151 self.debug("Initializing backend %s" % backend_name) 152 application = common.application 153 plugin_registry = application.plugin_registry 154 155 master_backend = application.config.get_option('master', backend_name, 156 default='') 157 158 mvc_config = None 159 mvc_mappings_config_file = self._mvc_mappings.get(backend_name) 160 if not mvc_mappings_config_file: 161 mvc_mappings_config_file = self._get_mvc_config_from_frontend(backend_name) 162 mvc_config = config.Config(mvc_mappings_config_file) 163 164 backend = Backend(mvc_config) 165 166 self._backends[backend_name] = backend 167 168 # Create Activity and retrieve the root Model from it 169 if master_backend == '': 170 activity_path = application.config.get_option('activity', 171 backend_name, 172 default=[]) 173 try: 174 activity = plugin_registry.create_component(activity_path) 175 except Exception, exc: 176 msg = "Cannot create activity %r for backend %r" % (activity_path, 177 backend_name) 178 self.warning(msg) 179 raise 180 181 root_model = activity.get_model() 182 activity_key = "%s/%s" % (backend_name, activity.path) 183 self._activities[activity_key] = activity 184 else: 185 root_model = self._backends[master_backend].root_controller.model 186 backend.mvc_config = self._backends[master_backend].mvc_config 187 188 # Create root controller 189 controller_path = application.config.get_option('controller', 190 backend_name) 191 controller_path = backend.get_controller_path(root_model.path) 192 193 try: 194 root_controller = plugin_registry.create_component(controller_path) 195 except: 196 self.warning("Cannot create controller %r for backend %r", 197 controller_path, backend_name) 198 raise 199 200 root_controller.backend = backend 201 202 backend.root_controller = root_controller 203 204 # Create and connect InputProviders found in the config to root 205 # Controller 206 # FIXME: no checking is done for duplicated InputProviders 207 providers_paths = self._create_input_providers(backend_name, backend) 208 for provider in providers_paths: 209 application.input_manager.subscribe(provider, 210 backend.dispatch_input) 211 212 root_controller.model = root_model 213 root_controller.focus()214216 self.debug("Initializing frontend %s" % frontend_name) 217 application = common.application 218 plugin_registry = application.plugin_registry 219 220 221 # Retrieving the backend the new frontend will connect to 222 # FIXME: this has to be changed to support remote backends 223 backend_name = application.config.get_option('backend', frontend_name, 224 default=[]) 225 if backend_name in self._backends: 226 backend = self._backends[backend_name] 227 root_controller = backend.root_controller 228 else: 229 msg = "Backend %r not existing for frontend %r" % (backend_name, 230 frontend_name) 231 self.warning(msg) 232 raise 233 234 if root_controller == None: 235 msg = "Invalid backend %r for frontend %r" % (backend_name, 236 frontend_name) 237 self.warning(msg) 238 raise 239 240 mvc_mappings = self._mvc_mappings.get(frontend_name) 241 if mvc_mappings: 242 mvc_config = config.Config(mvc_mappings) 243 else: 244 mvc_config = backend.mvc_config 245 246 # create the frontend 247 frontend = Frontend(mvc_config) 248 frontend.name = frontend_name 249 250 model_path = root_controller.model.path 251 view_path = frontend.get_view_path(model_path) 252 root_view = plugin_registry.create_component(view_path) 253 root_view.parent = None 254 255 # Create theme 256 theme_path = application.config.get_option('theme', frontend_name, 257 default=[]) 258 try: 259 theme = plugin_registry.create_component(theme_path) 260 except: 261 msg = "Cannot create theme %r for frontend %r" % (theme_path, 262 frontend_name) 263 self.warning(msg) 264 raise 265 266 # Create a Context needed by the root View to render 267 try: 268 context = plugin_registry.create_component(root_view.context_path) 269 except: 270 msg = "Cannot create context %r for frontend %r" % (root_view.context_path, 271 frontend_name) 272 self.warning(msg) 273 raise 274 275 # do the translation things 276 languages = application.config.get_option('languages', frontend_name, 277 None) 278 if not languages: 279 languages = [] 280 locale = locale_helper.get_from_system_locale() 281 if locale: 282 languages.append(locale) 283 284 # update the frontend 285 frontend.view = root_view 286 frontend.context = context 287 frontend.theme = theme 288 frontend.languages = languages 289 frontend.backend = backend 290 self._frontends[frontend_name] = frontend 291 292 # Create and connect InputProviders found in the config to root Controller 293 # FIXME: no checking is done for duplicated InputProviders 294 providers_paths = self._create_input_providers(frontend_name, 295 frontend, 296 context.viewport_handle) 297 for provider in providers_paths: 298 application.input_manager.subscribe(provider, 299 backend.dispatch_input) 300 301 # connect the root controller to the root view 302 root_view.frontend = frontend 303 root_view.controller = root_controller 304 305 return True306 307309 application = common.application 310 plugin_registry = application.plugin_registry 311 providers_paths = application.config.get_option("input_providers", 312 section=path, 313 default=[]) 314 315 count = 0 316 for provider_path in providers_paths: 317 try: 318 provider = plugin_registry.create_component(provider_path) 319 provider.origin = origin 320 provider.viewport = viewport 321 application.input_manager.register_component(provider) 322 count += 1 323 except Exception, error: 324 self.warning(error) 325 326 self.debug("Loaded and connected %s input_providers" % count) 327 return providers_paths328 329331 """ 332 Start refreshing the frontends periodically. 333 """ 334 self.info("Starting") 335 336 for frontend in self._frontends.values(): 337 frontend.context.context_handle = frontend.view.context_handle338 339341 """ 342 Stop refreshing the frontends and terminate the backends. 343 344 @rtype: L{twisted.internet.defer.Deferred} 345 """ 346 dfrs = [] 347 self.info("Stopping") 348 349 for frontend in self._frontends.values(): 350 dfr = defer.maybeDeferred(frontend.clean) 351 dfrs.append(dfr) 352 353 # FIXME: unsubscribe InputProviders ? 354 355 def all_done(result): 356 application = common.application 357 358 for activity_path, activity in self._activities.iteritems(): 359 activity.clean() 360 361 return result362 363 dfr = defer.DeferredList(dfrs) 364 dfr.addCallback(all_done) 365 return dfr
Home | Trees | Indices | Help |
---|
Generated by Epydoc 3.0beta1 on Wed Jan 16 19:10:31 2008 | http://epydoc.sourceforge.net |