Package brisa :: Package upnp :: Package device :: Module device
[hide private]
[frames] | no frames]

Source Code for Module brisa.upnp.device.device

  1  # Licensed under the MIT license 
  2  # http://opensource.org/licenses/mit-license.php or see LICENSE file. 
  3  # Copyright 2007-2008 Brisa Team <brisa-develop@garage.maemo.org> 
  4   
  5  """ Device-side device class used for implementing and deploying UPnP devices. 
  6  """ 
  7   
  8  from os import path, mkdir 
  9   
 10  from brisa.core import log, config, webserver, network 
 11   
 12  from brisa.upnp.ssdp import SSDPServer 
 13  from brisa.upnp.base_device import BaseDevice 
 14  from brisa.upnp.device.xml_gen import DeviceXMLBuilder 
 15   
 16   
17 -class Device(BaseDevice):
18 """ Class that represents a device. 19 20 When used with default settings, usage should be minimized to 21 instantiation, start() and stop(). 22 23 The special setting is a create_webserver keyword that can be passed during 24 construction. If False, it disables the automatic creation of the internal 25 webserver for serving device files, so, the user should create his own 26 webserver and set Device.webserver to it. 27 """ 28
29 - def __init__(self, *args, **kwargs):
30 """ Constructor for the Device class. 31 32 @param device_type: device type as described on the device reference 33 @param friendly_name: a friendly name 34 35 Optional parameters follow below: 36 37 @param udn: uuid for the device. If not specified will be 38 automatically generated. 39 @param parent: parent device 40 @param manufacturer: manufacturer 41 @param manufacturer_url: manufacturer url 42 @param model_description: model description 43 @param model_name: model name 44 @param model_number: model number 45 @param model_url: model url 46 @param serial_number: serial number 47 @param upc: upc 48 @param presentation_url: presentation url 49 @param create_webserver: see class description for more information. 50 Default value is True and you should normally 51 don't pass anything 52 @param force_listen_url: forces the webserver to listen on a specific 53 address. If it's not possible to listen on 54 that address, another random one will be 55 generated and used automatically. 56 57 @type device_type: string 58 @type friendly_name: string 59 @type udn: string 60 @type parent: Device 61 @type manufacturer: string 62 @type manufacturer_url: string 63 @type model_description: string 64 @type model_name: string 65 @type model_number: string 66 @type model_url: string 67 @type serial_number: string 68 @type upc: string 69 @type presentation_url: string 70 @type create_webserver: bool 71 @type force_listen_url: bool 72 """ 73 create_webserver = kwargs.pop('create_webserver', True) 74 force_listen_url = kwargs.pop('force_listen_url', '') 75 BaseDevice.__init__(self, *args, **kwargs) 76 self._generate_xml() 77 self.SSDP = SSDPServer(self.friendly_name, self.xml_filename) 78 self.webserver = None 79 if create_webserver: 80 self._create_webserver(force_listen_url)
81
82 - def add_service(self, service):
83 """ Adds a service to the device. 84 """ 85 assert self.location, 'service does not have a location attribute yet'\ 86 '. It must have a location set before adding '\ 87 'services. If you passed create_webserver=Fal'\ 88 'se, you must create the webserver in your '\ 89 'own fashion and set self.location to the '\ 90 'listening URL before adding services. This '\ 91 'problem may also occur if you pass an '\ 92 'invalid force_listen_url parameter.' 93 service.url_base = self.location 94 BaseDevice.add_service(self, service)
95
96 - def _create_webserver(self, force_listen_url=''):
97 if force_listen_url: 98 p = network.parse_url(force_listen_url) 99 self.webserver = webserver.WebServer(host=p.hostname, port=p.port) 100 else: 101 self.webserver = webserver.WebServer() 102 103 self.location = self.webserver.get_listen_url()
104
105 - def _generate_xml(self):
106 self.xml_filename = '%s-root-device.xml' % self.friendly_name 107 self.xml_filename = self.xml_filename.replace(' ', '') 108 self._xml_filepath = path.join(config.manager.brisa_home, 'tmp_xml') 109 if not path.exists(self._xml_filepath): 110 mkdir(self._xml_filepath) 111 self._xml_filepath = path.join(self._xml_filepath, self.xml_filename)
112
113 - def _publish(self):
114 assert self.webserver is not None, 'Device was told not to create '\ 115 'webserver (with False on the '\ 116 'create_webserver parameter) and'\ 117 'device.webserver was not set'\ 118 'manually as it should.' 119 log.info('Publishing device %s' % self.friendly_name) 120 DeviceXMLBuilder(self).generate_to_file(self._xml_filepath) 121 self.webserver.add_static_file(webserver.StaticFile(self.xml_filename, 122 self._xml_filepath)) 123 124 log.info('Publishing device\'s services') 125 for v in self.services.values(): 126 v.publish(self.webserver)
127
128 - def start(self):
129 """ Starts the device. 130 """ 131 log.info('Starting device %s' % self.friendly_name) 132 log.info('Starting device\'s services') 133 for k, v in self.services.items(): 134 try: 135 log.info('Starting service %s' % k) 136 v.start() 137 except Exception, e: 138 log.error('Error starting service %s: %s' % (k, e)) 139 self._publish() 140 self.SSDP.register_device(self) 141 self.webserver.start() 142 self.SSDP.start() 143 self.SSDP.announce_device() 144 log.info('Finished starting device %s' % self.friendly_name)
145
146 - def stop(self):
147 """ Stops the device. 148 """ 149 self.SSDP.stop() 150 self.webserver.stop()
151
152 - def is_running(self):
153 return self.webserver.is_running() and \ 154 self.SSDP.is_running()
155
156 - def destroy(self):
157 if self.is_running(): 158 self.stop() 159 self._cleanup()
160
161 - def _cleanup(self):
162 self.SSDP = None 163 self.webserver = None
164