def __init__(self): self.templates = jinja2.Environment( loader=jinja2.FileSystemLoader('templates'), trim_blocks=True, autoescape=True) self.templates.filters['get_device_icon'] = self.get_device_icon self.device_list = DeviceManager() self.unlocked_ports = {} self.device_list.register('added', router.add_device)
class Client(QtCore.QObject): playerChanged = QtCore.Signal() def __init__(self, showApp=False): QtCore.QObject.__init__(self) self.showApp = showApp self.player = None self.deviceMan = DeviceManager(startWatcher=True) self.updatePlayer() self.deviceMan.setActiveDeviceCapabilities([devices.Capability.ProvideContent, devices.Capability.PlayMusic]) self.devicePresenceBroadcaster = DevicePresenceBroadcaster(self.deviceMan.getActiveDevice()) def init(self): try: self.app = QtGui.QApplication(sys.argv) except RuntimeError: self.app = QtCore.QCoreApplication.instance() self.app.setApplicationName('yamclient') self.mainWin = MainWindow() self.bindEvents() self.deviceStateChangeWatcher = DeviceWatcher(portToWatch=5556, callback=self.playerStateChanged) self.deviceStateChangeWatcher.start() #self.devicePresenceBroadcaster.start() def bindEvents(self): self.app.aboutToQuit.connect(self.stop) def updatePlayer(self): activeDevice = self.deviceMan.getActiveDevice() if activeDevice: self.player = players.getPlayerByType(activeDevice) self.player.registerToStateChanges(activeDevice.host) self.playerChanged.emit() def playerStateChanged(self, state): self.player.stateChanged.emit(state) def start(self): try: if self.showApp: self.mainWin.show_and_raise() # Enter Qt application main loop self.app.exec_() except (KeyboardInterrupt, SystemExit): pass def close(self): #TODO : Remove self.deviceMan.dispose() self.app.exit() self.player.stop() def stop(self): if self.deviceMan: self.deviceMan.dispose() if self.app: self.app.exit() if self.player: self.player.stop()
def __init__(self): super().__init__() self.espState = False #self.second_key = str(randint(10000, 99999)) self.setWindowTitle('IoT Device Manager') self.resize(250, 120) self.devices = DeviceManager() layout = QGridLayout() label_key = QLabel('<font size="4"> Device1 </font>') layout.addWidget(label_key, 0, 0) label_key = QLabel('<font size="4"> Device2 </font>') layout.addWidget(label_key, 1, 0) ch_bx1 = MySwitch() ch_bx1.setChecked(True) ch_bx1.clicked.connect(self.changeStateOne) layout.addWidget(ch_bx1, 0, 1, 1, 2) ch_bx3 = MySwitch() ch_bx3.setChecked(True) ch_bx3.clicked.connect(self.changeStateTwo) layout.addWidget(ch_bx3, 1, 1, 1, 2) self.setLayout(layout)
def main(port=DEFAULT_PORT_NUMBER): ''' Performs the main operations of the server program on a given port. ''' try: # Create a global thread manager for all our devices thread_mgr = ThreadManager() # Create a global state manager for handling device queues state_mgr = StateManager() # Initialise the device manager dev_mgr = DeviceManager(thread_mgr, state_mgr) def handler(*args): ''' Initialise our custom handler with the device manager. ''' RequestHandler(dev_mgr, *args) # Create a web server and define the handler to manage the incoming # requests on separate threads. server = ThreadedHTTPServer(('', port), handler) print "Started ThreadedHTTPServer on port %d" % port # Wait forever for incoming HTTP requests server.serve_forever() except KeyboardInterrupt: print "Shutting down HTTPServer." server.socket.close()
def __init__(self, showApp=False): QtCore.QObject.__init__(self) self.showApp = showApp self.player = None self.deviceMan = DeviceManager(startWatcher=True) self.updatePlayer() self.deviceMan.setActiveDeviceCapabilities([devices.Capability.ProvideContent, devices.Capability.PlayMusic]) self.devicePresenceBroadcaster = DevicePresenceBroadcaster(self.deviceMan.getActiveDevice())
def test_deviceman_default_watcher(self): self.deviceManWithBc = DeviceManager(startWatcher=True) assert self.deviceManWithBc.isWatching() == True self.remoteDevice = Device(type="remote", visibleName="remoteDevice", url="localhost:5021", lastSeen=time.localtime()) presenceBroadcaster = DevicePresenceBroadcaster(self.remoteDevice, delayBetweenBroadcastsInSec=1) presenceBroadcaster.start() assert presenceBroadcaster.isRunning() time.sleep(1) presenceBroadcaster.stop() assert presenceBroadcaster.isRunning() == False self.deviceManWithBc.dispose() assert self.deviceManWithBc.isWatching() == False
def test_deviceman_and_watcher_integration(self): self.watcher = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.deviceManWithBc = DeviceManager(startWatcher=True, watcher=self.watcher) assert self.deviceManWithBc.isWatching() == True self.remoteDevice = Device(type="remote", visibleName="remoteDevice", url="localhost:5021", lastSeen=time.localtime()) presenceBroadcaster = DevicePresenceBroadcaster(self.remoteDevice, delayBetweenBroadcastsInSec=1) self.receivedBroadcast == False presenceBroadcaster.start() assert presenceBroadcaster.isRunning() time.sleep(1) assert self.receivedBroadcast == True presenceBroadcaster.stop() assert presenceBroadcaster.isRunning() == False self.deviceManWithBc.dispose() assert self.watcher.isRunning() == False
def __init__(self): self.templates = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'), trim_blocks=True, autoescape=True) self.templates.filters['get_device_icon'] = self.get_device_icon self.device_list = DeviceManager() self.unlocked_ports = {} self.device_list.register('added', router.add_device)
class UpnpResource(Resource): isLeaf = True def __init__(self): self.templates = jinja2.Environment(loader=jinja2.FileSystemLoader('templates'), trim_blocks=True, autoescape=True) self.templates.filters['get_device_icon'] = self.get_device_icon self.device_list = DeviceManager() self.unlocked_ports = {} self.device_list.register('added', router.add_device) @ensure_utf8 def render(self, request): try: if request.path.startswith('/devices/'): return self.devices(request) except: traceback.print_exc() raise def _get_device_for_uri(self, uri): """ Takes a request uri and returns a device that it corresponds to """ rest = uri[len('/devices/'):] slash_idx = rest.find('/') dev_id = urllib.unquote(rest[:slash_idx]) if dev_id in self.unlocked_ports: dev_id = dev_id[:dev_id.rfind(':')] device = self.device_list._get_device_by_id(dev_id) return device def devices(self, request): if request.uri == '/devices/': return self.format_device_list(request) rest = request.uri[len('/devices/'):] slash_idx = rest.find('/') device = self._get_device_for_uri(request.uri) dev_id = urllib.unquote(rest[:slash_idx]) if device and self.is_device_whitelisted(device): dev_url = device.get_location() if dev_id in self.unlocked_ports: dev_port = dev_id[dev_id.rfind(':')+1:] urlparsed = urlparse.urlparse(device.get_location()) proto, netloc = urlparsed[0:2] url_ip = netloc.split(':')[0] dev_url = '%s://%s:%s/'%(proto, url_ip, dev_port) url = urlparse.urljoin(dev_url, rest[slash_idx:]) logger.debug(url) return router.dispatch_device_request(request, url) else: logger.info("Could not find device %s"%(dev_id,)) request.setResponseCode(404) return 'Could not find device %s'%(dev_id,) def is_device_whitelisted(self, device): return any(['X_MS_MediaReceiver' in s.service_type or 'ContentDirectory' in s.service_type for s in device.get_services() ]) def format_device_list(self, request): def whitelisted_devices(devices): return [ d for d in devices if self.is_device_whitelisted(d) ] if 'json' not in request.requestHeaders.getRawHeaders('Accept', [''])[0]: template = self.templates.get_template('devices.djhtml') return template.render(devices=whitelisted_devices(self.device_list.devices)) else: devices = [{ "uuid": d.get_id(), "usn": d.get_usn(), "st": d.get_st(), "server": d.server, "location": self.get_proxied_url(d, urlparse.urlparse(d.get_location())[2]), "subdevices": [{ "usn": s.get_id()+"::"+s.service_type, "st": s.service_type, "location": self.get_proxied_url(d, urlparse.urlparse(d.get_location())[2]) } for s in d.get_services()] } for d in whitelisted_devices(self.device_list.devices)] request.responseHeaders.setRawHeaders('Content-Type', ['application/json']) return json.dumps({"devices":devices}) def get_proxied_url(self, device, url): # given a url on the device's upnp service # return a url relative to /devices/ to proxy to it # base is devices/ if '://' in url: proto, netloc = urlparse.urlparse(device.get_location())[0:2] if ':' in netloc: dev_ip, dev_port = netloc.split(':', 1) else: dev_ip, dev_port = netloc, '443' if proto=='https' else '80' urlparsed = urlparse.urlparse(url) proto, netloc = urlparsed[0:2] if ':' in netloc: url_ip, url_port = netloc.split(':', 1) else: url_ip, url_port = netloc, '443' if proto=='https' else '80' prefix = '%s://%s' % (urlparsed[0:2]) rest = url[len(prefix):] logger.debug("Comparing %s:%s to %s:%s"%(dev_ip, dev_port, url_ip, url_port)) if url_ip == dev_ip and url_port == dev_port: result = device.get_id() + rest logger.debug('Converting same-device %s to %s'%(url, result)) return result elif url_ip == dev_ip: unlocked_port = device.get_id() + ':' + url_port self.unlocked_ports[unlocked_port] = True result = unlocked_port + rest logger.debug('Converting same-device alt port %s to %s'%(url, result)) return result else: logger.debug('Not converting external %s'%(url,)) return url if len(url)>1 and url[0] != '/': url = '/' + url result = device.get_id() + url logger.debug('Converting upnp relative %s to %s'%(url, result)) return result def rewrite_base(self, device, base): if urlparse.urljoin(device.get_location(), 'sub') == urlparse.urljoin(base, 'sub'): # unnecessary base return None return self.get_proxied_url(device, base) def get_device_icon(self, device): if len(device.icons) > 0: icon = sorted(device.icons, key=lambda i:abs(120-int(i['width'])))[0] icon_url = self.get_proxied_url(device, icon['realurl']) return icon_url else: return '' def hack_description_response(self, request, response_data): request.setResponseCode(response_data['code']) request.responseHeaders = response_data['headers'] if 'xml' not in response_data['headers'].getRawHeaders('Content-Type', [''])[0]: request.responseHeaders.setRawHeaders('Content-Length', [len(response_data['content'])]) request.write(response_data['content']) request.finish() return request.responseHeaders.removeHeader('Content-Length') request.responseHeaders.removeHeader('Content-Encoding') # get the device that we're talking to, and its ip device = self._get_device_for_uri(request.uri) # load up the response upnp = 'urn:schemas-upnp-org:device-1-0' root = ElementTree.fromstring(response_data['content']) for urlbase in root.findall("./{%s}URLBase"%(upnp,)): newbase = self.rewrite_base(device, urlbase.text) if newbase: urlbase.text = newbase else: root.remove(newbase) # write out doc = ElementTree.ElementTree(root) docout = StringIO.StringIO() doc.write(docout, encoding='utf-8', xml_declaration=True) docoutstr = docout.getvalue() request.responseHeaders.setRawHeaders('Content-Length', [len(docoutstr)]) request.write(docoutstr) request.finish() def hack_mediaserver_response(self, request, response_data): request.setResponseCode(response_data['code']) request.responseHeaders = response_data['headers'] if 'xml' not in response_data['headers'].getRawHeaders('Content-Type', [''])[0]: request.responseHeaders.setRawHeaders('Content-Length', [len(response_data['content'])]) request.write(response_data['content']) request.finish() return request.responseHeaders.removeHeader('Content-Length') request.responseHeaders.removeHeader('Content-Encoding') # get the device that we're talking to, and its ip device = self._get_device_for_uri(request.uri) # load up response didl = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/' upnp = 'urn:schemas-upnp-org:metadata-1-0/upnp/' root = ElementTree.fromstring(response_data['content']) for result in root.iter('Result'): resultdoc = ElementTree.fromstring(result.text.encode('utf-8')) for uritag in resultdoc.iter('{%s}albumArtURI'%(upnp,)): uritag.text = self.get_proxied_url(device, uritag.text).decode('utf-8') for uritag in resultdoc.iter('{%s}res'%(didl,)): uritag.text = self.get_proxied_url(device, uritag.text).decode('utf-8') result.text = ElementTree.tostring(resultdoc, encoding='utf-8').decode('utf-8') # write out doc = ElementTree.ElementTree(root) docout = StringIO.StringIO() doc.write(docout, encoding='utf-8', xml_declaration=True) docoutstr = docout.getvalue() request.responseHeaders.setRawHeaders('Content-Length', [len(docoutstr)]) request.write(docoutstr) request.finish()
def test_device_watcher_can_start_and_stop(self): self.deviceManWithBc = DeviceManager(startWatcher=True) assert self.deviceManWithBc.isWatching() == True self.deviceManWithBc.dispose() assert self.deviceManWithBc.isWatching() == False
class TestDeviceMan: config.setConfigFolder('tests/config/') deviceMan = DeviceManager() deviceMan.deleteRegistry() receivedBroadcast = False device = Device(type="remote", visibleName="testDevice", url="testLocation", lastSeen=time.localtime()) def test_registry_not_found(self): self.deviceMan.deleteRegistry() assert self.deviceMan.createRegistry() == True assert self.deviceMan.getDevices() == [] assert self.deviceMan.deleteRegistry() def test_delete_registry(self): self.deviceMan.deleteRegistry() assert self.deviceMan.createRegistry() assert os.path.isfile(self.deviceMan.devicesRegistryPath) self.deviceMan.deleteRegistry() assert len(self.deviceMan.getDevices()) == 0 def test_add_entry_to_registry(self): self.deviceMan.deleteRegistry() self.deviceMan.registerDevice(self.device) assert self.device in self.deviceMan.getDevices() assert len(self.deviceMan.getDevices()) == 1 savedDevice = self.deviceMan.getDevices()[0] assert savedDevice.type == self.device.type assert savedDevice.visibleName == self.device.visibleName assert savedDevice.url == self.device.url #assert savedDevice.lastSeen == self.device.lastSeen def test_device_watcher_can_start_and_stop(self): self.deviceManWithBc = DeviceManager(startWatcher=True) assert self.deviceManWithBc.isWatching() == True self.deviceManWithBc.dispose() assert self.deviceManWithBc.isWatching() == False def test_device_watcher_can_receive(self): self.watcher = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.watcher.start() assert self.watcher.isRunning() == True self.remoteDevice = Device(type="remote", visibleName="remoteDevice", url="localhost:5021", lastSeen=time.localtime()) presenceBroadcaster = DevicePresenceBroadcaster(self.remoteDevice, delayBetweenBroadcastsInSec=1) self.receivedBroadcast == False presenceBroadcaster.start() assert presenceBroadcaster.isRunning() time.sleep(1) assert self.receivedBroadcast == True presenceBroadcaster.stop() assert presenceBroadcaster.isRunning() == False self.watcher.stop() assert self.watcher.isRunning() == False def assert_watcher_receive_correct_data(self, device): assert device == self.remoteDevice self.receivedBroadcast = True def test_deviceman_and_watcher_integration(self): self.watcher = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.deviceManWithBc = DeviceManager(startWatcher=True, watcher=self.watcher) assert self.deviceManWithBc.isWatching() == True self.remoteDevice = Device(type="remote", visibleName="remoteDevice", url="localhost:5021", lastSeen=time.localtime()) presenceBroadcaster = DevicePresenceBroadcaster(self.remoteDevice, delayBetweenBroadcastsInSec=1) self.receivedBroadcast == False presenceBroadcaster.start() assert presenceBroadcaster.isRunning() time.sleep(1) assert self.receivedBroadcast == True presenceBroadcaster.stop() assert presenceBroadcaster.isRunning() == False self.deviceManWithBc.dispose() assert self.watcher.isRunning() == False def test_deviceman_default_watcher(self): self.deviceManWithBc = DeviceManager(startWatcher=True) assert self.deviceManWithBc.isWatching() == True self.remoteDevice = Device(type="remote", visibleName="remoteDevice", url="localhost:5021", lastSeen=time.localtime()) presenceBroadcaster = DevicePresenceBroadcaster(self.remoteDevice, delayBetweenBroadcastsInSec=1) presenceBroadcaster.start() assert presenceBroadcaster.isRunning() time.sleep(1) presenceBroadcaster.stop() assert presenceBroadcaster.isRunning() == False self.deviceManWithBc.dispose() assert self.deviceManWithBc.isWatching() == False def test_set_active_device(self): self.deviceMan.setActiveDevice(self.device) assert self.deviceMan.getActiveDevice() == self.device def test_clear_registry(self): pass def test_watcher_does_not_leak(self): try: self.watcher = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.watcher.start() assert self.watcher.isRunning() == True self.watcher.stop() procName = self.watcher.getProcName() isReallyRunning = False for proc in psutil.process_iter(): if proc.name == self.watcher.getProcName(): assert proc.status == psutil.STATUS_RUNNING isReallyRunning == True assert isReallyRunning self.watcher.stop() assert self.watcher.isRunning() == False isReallyClosed = True for proc in psutil.process_iter(): if proc.name == procName: isReallyClosed = False assert isReallyClosed except Exception as e: print e #May not work on all platform #TODO : Make it work on MAC self.watcher.stop() pass def test_concurrent_watchers(self): self.watcher1 = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.watcher1.start() assert self.watcher1.isRunning() == True self.watcher2 = DeviceWatcher(portToWatch=5555, callback=self.assert_watcher_receive_correct_data) self.watcher2.start() assert self.watcher2.isRunning() == True presenceBroadcaster = DevicePresenceBroadcaster(self.device, delayBetweenBroadcastsInSec=1) presenceBroadcaster.start() time.sleep(1) self.watcher1.stop() self.watcher2.stop() presenceBroadcaster.stop()
class UpnpResource(Resource): isLeaf = True def __init__(self): self.templates = jinja2.Environment( loader=jinja2.FileSystemLoader('templates'), trim_blocks=True, autoescape=True) self.templates.filters['get_device_icon'] = self.get_device_icon self.device_list = DeviceManager() self.unlocked_ports = {} self.device_list.register('added', router.add_device) @ensure_utf8 def render(self, request): try: if request.path.startswith('/devices/'): return self.devices(request) except: traceback.print_exc() raise def _get_device_for_uri(self, uri): """ Takes a request uri and returns a device that it corresponds to """ rest = uri[len('/devices/'):] slash_idx = rest.find('/') dev_id = urllib.unquote(rest[:slash_idx]) if dev_id in self.unlocked_ports: dev_id = dev_id[:dev_id.rfind(':')] device = self.device_list._get_device_by_id(dev_id) return device def devices(self, request): if request.uri == '/devices/': return self.format_device_list(request) rest = request.uri[len('/devices/'):] slash_idx = rest.find('/') device = self._get_device_for_uri(request.uri) dev_id = urllib.unquote(rest[:slash_idx]) if device and self.is_device_whitelisted(device): dev_url = device.get_location() if dev_id in self.unlocked_ports: dev_port = dev_id[dev_id.rfind(':') + 1:] urlparsed = urlparse.urlparse(device.get_location()) proto, netloc = urlparsed[0:2] url_ip = netloc.split(':')[0] dev_url = '%s://%s:%s/' % (proto, url_ip, dev_port) url = urlparse.urljoin(dev_url, rest[slash_idx:]) logger.debug(url) return router.dispatch_device_request(request, url) else: logger.info("Could not find device %s" % (dev_id, )) request.setResponseCode(404) return 'Could not find device %s' % (dev_id, ) def is_device_whitelisted(self, device): return any([ 'X_MS_MediaReceiver' in s.service_type or 'ContentDirectory' in s.service_type for s in device.get_services() ]) def format_device_list(self, request): def whitelisted_devices(devices): return [d for d in devices if self.is_device_whitelisted(d)] if 'json' not in request.requestHeaders.getRawHeaders('Accept', [''])[0]: template = self.templates.get_template('devices.djhtml') return template.render( devices=whitelisted_devices(self.device_list.devices)) else: devices = [{ "uuid": d.get_id(), "usn": d.get_usn(), "st": d.get_st(), "server": d.server, "location": self.get_proxied_url(d, urlparse.urlparse(d.get_location())[2]), "subdevices": [{ "usn": s.get_id() + "::" + s.service_type, "st": s.service_type, "location": self.get_proxied_url( d, urlparse.urlparse(d.get_location())[2]) } for s in d.get_services()] } for d in whitelisted_devices(self.device_list.devices)] request.responseHeaders.setRawHeaders('Content-Type', ['application/json']) return json.dumps({"devices": devices}) def get_proxied_url(self, device, url): # given a url on the device's upnp service # return a url relative to /devices/ to proxy to it # base is devices/ if '://' in url: proto, netloc = urlparse.urlparse(device.get_location())[0:2] if ':' in netloc: dev_ip, dev_port = netloc.split(':', 1) else: dev_ip, dev_port = netloc, '443' if proto == 'https' else '80' urlparsed = urlparse.urlparse(url) proto, netloc = urlparsed[0:2] if ':' in netloc: url_ip, url_port = netloc.split(':', 1) else: url_ip, url_port = netloc, '443' if proto == 'https' else '80' prefix = '%s://%s' % (urlparsed[0:2]) rest = url[len(prefix):] logger.debug("Comparing %s:%s to %s:%s" % (dev_ip, dev_port, url_ip, url_port)) if url_ip == dev_ip and url_port == dev_port: result = device.get_id() + rest logger.debug('Converting same-device %s to %s' % (url, result)) return result elif url_ip == dev_ip: unlocked_port = device.get_id() + ':' + url_port self.unlocked_ports[unlocked_port] = True result = unlocked_port + rest logger.debug('Converting same-device alt port %s to %s' % (url, result)) return result else: logger.debug('Not converting external %s' % (url, )) return url if len(url) > 1 and url[0] != '/': url = '/' + url result = device.get_id() + url logger.debug('Converting upnp relative %s to %s' % (url, result)) return result def rewrite_base(self, device, base): if urlparse.urljoin(device.get_location(), 'sub') == urlparse.urljoin(base, 'sub'): # unnecessary base return None return self.get_proxied_url(device, base) def get_device_icon(self, device): if len(device.icons) > 0: icon = sorted(device.icons, key=lambda i: abs(120 - int(i['width'])))[0] icon_url = self.get_proxied_url(device, icon['realurl']) return icon_url else: return '' def hack_description_response(self, request, response_data): request.setResponseCode(response_data['code']) request.responseHeaders = response_data['headers'] if 'xml' not in response_data['headers'].getRawHeaders( 'Content-Type', [''])[0]: request.responseHeaders.setRawHeaders( 'Content-Length', [len(response_data['content'])]) request.write(response_data['content']) request.finish() return request.responseHeaders.removeHeader('Content-Length') request.responseHeaders.removeHeader('Content-Encoding') # get the device that we're talking to, and its ip device = self._get_device_for_uri(request.uri) # load up the response upnp = 'urn:schemas-upnp-org:device-1-0' root = ElementTree.fromstring(response_data['content']) for urlbase in root.findall("./{%s}URLBase" % (upnp, )): newbase = self.rewrite_base(device, urlbase.text) if newbase: urlbase.text = newbase else: root.remove(newbase) # write out doc = ElementTree.ElementTree(root) docout = StringIO.StringIO() doc.write(docout, encoding='utf-8', xml_declaration=True) docoutstr = docout.getvalue() request.responseHeaders.setRawHeaders('Content-Length', [len(docoutstr)]) request.write(docoutstr) request.finish() def hack_mediaserver_response(self, request, response_data): request.setResponseCode(response_data['code']) request.responseHeaders = response_data['headers'] if 'xml' not in response_data['headers'].getRawHeaders( 'Content-Type', [''])[0]: request.responseHeaders.setRawHeaders( 'Content-Length', [len(response_data['content'])]) request.write(response_data['content']) request.finish() return request.responseHeaders.removeHeader('Content-Length') request.responseHeaders.removeHeader('Content-Encoding') # get the device that we're talking to, and its ip device = self._get_device_for_uri(request.uri) # load up response didl = 'urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/' upnp = 'urn:schemas-upnp-org:metadata-1-0/upnp/' root = ElementTree.fromstring(response_data['content']) for result in root.iter('Result'): resultdoc = ElementTree.fromstring(result.text.encode('utf-8')) for uritag in resultdoc.iter('{%s}albumArtURI' % (upnp, )): uritag.text = self.get_proxied_url(device, uritag.text).decode('utf-8') for uritag in resultdoc.iter('{%s}res' % (didl, )): uritag.text = self.get_proxied_url(device, uritag.text).decode('utf-8') result.text = ElementTree.tostring( resultdoc, encoding='utf-8').decode('utf-8') # write out doc = ElementTree.ElementTree(root) docout = StringIO.StringIO() doc.write(docout, encoding='utf-8', xml_declaration=True) docoutstr = docout.getvalue() request.responseHeaders.setRawHeaders('Content-Length', [len(docoutstr)]) request.write(docoutstr) request.finish()
def __init__(self, *args, **kwargs): """ Constructs a QuarterWidget. QuarterWidget(QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLContext context, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLFormat format, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") """ params = ["parent", "sharewidget"] values = {"parent": None, "sharewidget": None, "f": 0, "scxml": "coin:scxml/navigation/examiner.xml"} values.update(kwargs) if len(args) > 0 and isinstance(args[0], QtOpenGL.QGLContext) or "context" in kwargs: params.insert(0, "context") elif len(args) > 0 and isinstance(args[0], QtOpenGL.QGLFormat) or "format" in kwargs: params.insert(0, "format") if len(args) > len(params): values["f"] = args[len(params)] if len(args) > len(params) + 1: values["scxml"] = args[len(params) + 1] for i in range(len(args), len(params)): args += (values[params[i]],) QtOpenGL.QGLWidget.__init__(self, *args[:len(params)]) if values["f"]: self.setWindowFlags(values["f"]) # initialize Sensormanager and ImageReader instances only once if not QuarterWidget._sensormanager: QuarterWidget._sensormanager = SensorManager() if not QuarterWidget._imagereader: QuarterWidget._imagereader = ImageReader() self.cachecontext_list = [] self.cachecontext = self.findCacheContext(self, values["sharewidget"]) self.statecursormap = {} self.scene = None self.contextmenu = None self.contextmenuenabled = True self.sorendermanager = coin.SoRenderManager() self.soeventmanager = coin.SoEventManager() # Mind the order of initialization as the XML state machine uses # callbacks which depends on other state being initialized self.eventmanager = EventManager(self) self.devicemanager = DeviceManager(self) statemachine = coin.ScXML.readFile(values["scxml"]) if statemachine and statemachine.isOfType(coin.SoScXMLStateMachine.getClassTypeId()): sostatemachine = coin.cast(statemachine, "SoScXMLStateMachine") statemachine.addStateChangeCallback(statechangeCB, self) self.soeventmanager.addSoScXMLStateMachine(sostatemachine) sostatemachine.initialize() else: raise "could not initialize statemachine, given file not found?" self.headlight = coin.SoDirectionalLight() self.sorendermanager.setAutoClipping(coin.SoRenderManager.VARIABLE_NEAR_PLANE) self.sorendermanager.setRenderCallback(renderCB, self) self.sorendermanager.setBackgroundColor(coin.SbColor4f(0, 0, 0, 0)) self.sorendermanager.activate() self.sorendermanager.addPreRenderCallback(prerenderCB, self) self.sorendermanager.addPostRenderCallback(postrenderCB, self) self.soeventmanager.setNavigationState(coin.SoEventManager.MIXED_NAVIGATION) self.devicemanager.registerDevice(MouseHandler()) self.devicemanager.registerDevice(KeyboardHandler()) self.eventmanager.registerEventHandler(DragDropHandler()) # set up a cache context for the default SoGLRenderAction self.sorendermanager.getGLRenderAction().setCacheContext(self.getCacheContextId()) self.setStateCursor("interact", QtCore.Qt.ArrowCursor) self.setStateCursor("idle", QtCore.Qt.OpenHandCursor) self.setStateCursor("rotate", QtCore.Qt.ClosedHandCursor) self.setStateCursor("pan", QtCore.Qt.SizeAllCursor) self.setStateCursor("zoom", QtCore.Qt.SizeVerCursor) self.setStateCursor("seek", QtCore.Qt.CrossCursor) self.setStateCursor("spin", QtCore.Qt.OpenHandCursor) self.setMouseTracking(True) self.setFocusPolicy(QtCore.Qt.StrongFocus);
class QuarterWidget(QtOpenGL.QGLWidget): _sensormanager = None _imagereader = None def __init__(self, *args, **kwargs): """ Constructs a QuarterWidget. QuarterWidget(QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLContext context, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLFormat format, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") """ params = ["parent", "sharewidget"] values = {"parent": None, "sharewidget": None, "f": 0, "scxml": "coin:scxml/navigation/examiner.xml"} values.update(kwargs) if len(args) > 0 and isinstance(args[0], QtOpenGL.QGLContext) or "context" in kwargs: params.insert(0, "context") elif len(args) > 0 and isinstance(args[0], QtOpenGL.QGLFormat) or "format" in kwargs: params.insert(0, "format") if len(args) > len(params): values["f"] = args[len(params)] if len(args) > len(params) + 1: values["scxml"] = args[len(params) + 1] for i in range(len(args), len(params)): args += (values[params[i]],) QtOpenGL.QGLWidget.__init__(self, *args[:len(params)]) if values["f"]: self.setWindowFlags(values["f"]) # initialize Sensormanager and ImageReader instances only once if not QuarterWidget._sensormanager: QuarterWidget._sensormanager = SensorManager() if not QuarterWidget._imagereader: QuarterWidget._imagereader = ImageReader() self.cachecontext_list = [] self.cachecontext = self.findCacheContext(self, values["sharewidget"]) self.statecursormap = {} self.scene = None self.contextmenu = None self.contextmenuenabled = True self.sorendermanager = coin.SoRenderManager() self.soeventmanager = coin.SoEventManager() # Mind the order of initialization as the XML state machine uses # callbacks which depends on other state being initialized self.eventmanager = EventManager(self) self.devicemanager = DeviceManager(self) statemachine = coin.ScXML.readFile(values["scxml"]) if statemachine and statemachine.isOfType(coin.SoScXMLStateMachine.getClassTypeId()): sostatemachine = coin.cast(statemachine, "SoScXMLStateMachine") statemachine.addStateChangeCallback(statechangeCB, self) self.soeventmanager.addSoScXMLStateMachine(sostatemachine) sostatemachine.initialize() else: raise "could not initialize statemachine, given file not found?" self.headlight = coin.SoDirectionalLight() self.sorendermanager.setAutoClipping(coin.SoRenderManager.VARIABLE_NEAR_PLANE) self.sorendermanager.setRenderCallback(renderCB, self) self.sorendermanager.setBackgroundColor(coin.SbColor4f(0, 0, 0, 0)) self.sorendermanager.activate() self.sorendermanager.addPreRenderCallback(prerenderCB, self) self.sorendermanager.addPostRenderCallback(postrenderCB, self) self.soeventmanager.setNavigationState(coin.SoEventManager.MIXED_NAVIGATION) self.devicemanager.registerDevice(MouseHandler()) self.devicemanager.registerDevice(KeyboardHandler()) self.eventmanager.registerEventHandler(DragDropHandler()) # set up a cache context for the default SoGLRenderAction self.sorendermanager.getGLRenderAction().setCacheContext(self.getCacheContextId()) self.setStateCursor("interact", QtCore.Qt.ArrowCursor) self.setStateCursor("idle", QtCore.Qt.OpenHandCursor) self.setStateCursor("rotate", QtCore.Qt.ClosedHandCursor) self.setStateCursor("pan", QtCore.Qt.SizeAllCursor) self.setStateCursor("zoom", QtCore.Qt.SizeVerCursor) self.setStateCursor("seek", QtCore.Qt.CrossCursor) self.setStateCursor("spin", QtCore.Qt.OpenHandCursor) self.setMouseTracking(True) self.setFocusPolicy(QtCore.Qt.StrongFocus); def setSceneGraph(self, node): if node and self.scene==node: return camera = None superscene = None viewall = False if node: self.scene = node self.scene.ref() superscene = coin.SoSeparator() superscene.addChild(coin.SoDepthBuffer()) superscene.addChild(self.headlight) camera = self.searchForCamera(node) if not camera: camera = coin.SoPerspectiveCamera() superscene.addChild(camera) viewall = True superscene.addChild(node) self.soeventmanager.setSceneGraph(superscene) self.sorendermanager.setSceneGraph(superscene) self.soeventmanager.setCamera(camera) self.sorendermanager.setCamera(camera) if viewall: self.viewAll() if superscene: superscene.touch() def viewAll(self): """ Reposition the current camera to display the entire scene""" viewallevent = coin.SbName("sim.coin3d.coin.navigation.ViewAll") for c in range(self.soeventmanager.getNumSoScXMLStateMachines()): sostatemachine = self.soeventmanager.getSoScXMLStateMachine(c) if (sostatemachine.isActive()): sostatemachine.queueEvent(viewallevent) sostatemachine.processEventQueue() def resizeGL(self, width, height): vp = coin.SbViewportRegion(width, height) self.sorendermanager.setViewportRegion(vp) self.soeventmanager.setViewportRegion(vp) def paintGL(self): self.actualRedraw() def actualRedraw(self): self.sorendermanager.render(True, True) def event(self, qevent): """Translates Qt Events into Coin events and passes them on to the scenemanager for processing. If the event can not be translated or processed, it is forwarded to Qt and the method returns false. This method could be overridden in a subclass in order to catch events of particular interest to the application programmer.""" if self.eventmanager.handleEvent(qevent): return True soevent = self.devicemanager.translateEvent(qevent) if (soevent and self.soeventmanager.processEvent(soevent)): return True # NOTE jkg: we must return True or False return QtOpenGL.QGLWidget.event(self, qevent) def setStateCursor(self, state, cursor): self.statecursormap[state] = cursor def searchForCamera(self, root): sa = coin.SoSearchAction() sa.setInterest(coin.SoSearchAction.FIRST) sa.setType(coin.SoCamera.getClassTypeId()) sa.apply(root) if sa.getPath(): node = sa.getPath().getTail() if node and node.isOfType(coin.SoCamera.getClassTypeId()): return node return None def getCacheContextId(self): return self.cachecontext.id def findCacheContext(self, widget, sharewidget): class QuarterWidgetP_cachecontext: def __init__(self): self.widgetlist = [] self.id = None for cachecontext in self.cachecontext_list: for widget in cachecontext.widgetlist: if (widget == sharewidget): cachecontext.widgetlist.append(widget) return cachecontext; cachecontext = QuarterWidgetP_cachecontext() cachecontext.id = coin.SoGLCacheContextElement.getUniqueCacheContext() cachecontext.widgetlist.append(widget) self.cachecontext_list.append(cachecontext) return cachecontext def getSoRenderManager(self): return self.sorendermanager def getSoEventManager(self): return self.soeventmanager def setBackgroundColor(self, color): """Set backgroundcolor to a given QColor Remember that QColors are given in integers between 0 and 255, as opposed to SbColor4f which is in [0 ,1]. The default alpha value for a QColor is 255, but you'll probably want to set it to zero before using it as an OpenGL clear color.""" bgcolor = coin.SbColor4f(max(0, min(1, color.red() / 255.0)), max(0, min(1, color.green() / 255.0)), max(0, min(1, color.blue() / 255.0)), max(0, min(1, color.alpha() / 255.0))) self.sorendermanager.setBackgroundColor(bgcolor) def getBackgroundColor(self): """ Returns color used for clearing the rendering area before rendering the scene.""" bg = self.sorendermanager.getBackgroundColor() return QtGui.QColor(max(0, min(255, int(bg[0] * 255.0))), max(0, min(255, int(bg[1] * 255.0))), max(0, min(255, int(bg[2] * 255.0))), max(0, min(255, int(bg[3] * 255.0)))) def getContextMenu(self): """Returns the context menu used by the widget.""" if not self.contextmenu: self.contextmenu = ContextMenu(self) # NOTE 20080508 jkg: seems like we can drop .getMenu() but I dont see why that works return self.contextmenu.getMenu() def contextMenuEnabled(self): return contextmenuenabled def enableContextMenu(self, yesno): self.contextmenuenabled = yesno def setTransparencyType(self, type): """This method sets the transparency type to be used for the scene.""" assert(self.sorendermanager) self.sorendermanager.getGLRenderAction().setTransparencyType(type) self.sorendermanager.scheduleRedraw() def enableHeadlight(self, onoff): """ Enable/disable the headlight. This wille toggle the SoDirectionalLigh::on field (returned from getHeadlight()).""" self.headlight.on = onoff def getHeadlight(self): """Returns the light used for the headlight.""" return self.headlight
def __init__(self, *args, **kwargs): """ Constructs a QuarterWidget. QuarterWidget(QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLContext context, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLFormat format, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") """ params = ["parent", "sharewidget"] values = { "parent": None, "sharewidget": None, "f": 0, "scxml": "coin:scxml/navigation/examiner.xml" } values.update(kwargs) if len(args) > 0 and isinstance( args[0], QtOpenGL.QGLContext) or "context" in kwargs: params.insert(0, "context") elif len(args) > 0 and isinstance( args[0], QtOpenGL.QGLFormat) or "format" in kwargs: params.insert(0, "format") if len(args) > len(params): values["f"] = args[len(params)] if len(args) > len(params) + 1: values["scxml"] = args[len(params) + 1] for i in range(len(args), len(params)): args += (values[params[i]], ) QtOpenGL.QGLWidget.__init__(self, *args[:len(params)]) if values["f"]: self.setWindowFlags(values["f"]) # initialize Sensormanager and ImageReader instances only once if not QuarterWidget._sensormanager: QuarterWidget._sensormanager = SensorManager() if not QuarterWidget._imagereader: QuarterWidget._imagereader = ImageReader() self.cachecontext_list = [] self.cachecontext = self.findCacheContext(self, values["sharewidget"]) self.statecursormap = {} self.scene = None self.contextmenu = None self.contextmenuenabled = True self.sorendermanager = coin.SoRenderManager() self.soeventmanager = coin.SoEventManager() # Mind the order of initialization as the XML state machine uses # callbacks which depends on other state being initialized self.eventmanager = EventManager(self) self.devicemanager = DeviceManager(self) statemachine = coin.ScXML.readFile(values["scxml"]) if statemachine and statemachine.isOfType( coin.SoScXMLStateMachine.getClassTypeId()): sostatemachine = coin.cast(statemachine, "SoScXMLStateMachine") statemachine.addStateChangeCallback(statechangeCB, self) self.soeventmanager.addSoScXMLStateMachine(sostatemachine) sostatemachine.initialize() else: raise "could not initialize statemachine, given file not found?" self.headlight = coin.SoDirectionalLight() self.sorendermanager.setAutoClipping( coin.SoRenderManager.VARIABLE_NEAR_PLANE) self.sorendermanager.setRenderCallback(renderCB, self) self.sorendermanager.setBackgroundColor(coin.SbColor4f(0, 0, 0, 0)) self.sorendermanager.activate() self.sorendermanager.addPreRenderCallback(prerenderCB, self) self.sorendermanager.addPostRenderCallback(postrenderCB, self) self.soeventmanager.setNavigationState( coin.SoEventManager.MIXED_NAVIGATION) self.devicemanager.registerDevice(MouseHandler()) self.devicemanager.registerDevice(KeyboardHandler()) self.eventmanager.registerEventHandler(DragDropHandler()) # set up a cache context for the default SoGLRenderAction self.sorendermanager.getGLRenderAction().setCacheContext( self.getCacheContextId()) self.setStateCursor("interact", QtCore.Qt.ArrowCursor) self.setStateCursor("idle", QtCore.Qt.OpenHandCursor) self.setStateCursor("rotate", QtCore.Qt.ClosedHandCursor) self.setStateCursor("pan", QtCore.Qt.SizeAllCursor) self.setStateCursor("zoom", QtCore.Qt.SizeVerCursor) self.setStateCursor("seek", QtCore.Qt.CrossCursor) self.setStateCursor("spin", QtCore.Qt.OpenHandCursor) self.setMouseTracking(True) self.setFocusPolicy(QtCore.Qt.StrongFocus)
class QuarterWidget(QtOpenGL.QGLWidget): _sensormanager = None _imagereader = None def __init__(self, *args, **kwargs): """ Constructs a QuarterWidget. QuarterWidget(QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLContext context, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") QuarterWidget(QGLFormat format, QWidget parent = None, QGLWidget sharewidget = None, Qt.WindowFlags f = 0, scxml = "coin:scxml/navigation/examiner.xml") """ params = ["parent", "sharewidget"] values = { "parent": None, "sharewidget": None, "f": 0, "scxml": "coin:scxml/navigation/examiner.xml" } values.update(kwargs) if len(args) > 0 and isinstance( args[0], QtOpenGL.QGLContext) or "context" in kwargs: params.insert(0, "context") elif len(args) > 0 and isinstance( args[0], QtOpenGL.QGLFormat) or "format" in kwargs: params.insert(0, "format") if len(args) > len(params): values["f"] = args[len(params)] if len(args) > len(params) + 1: values["scxml"] = args[len(params) + 1] for i in range(len(args), len(params)): args += (values[params[i]], ) QtOpenGL.QGLWidget.__init__(self, *args[:len(params)]) if values["f"]: self.setWindowFlags(values["f"]) # initialize Sensormanager and ImageReader instances only once if not QuarterWidget._sensormanager: QuarterWidget._sensormanager = SensorManager() if not QuarterWidget._imagereader: QuarterWidget._imagereader = ImageReader() self.cachecontext_list = [] self.cachecontext = self.findCacheContext(self, values["sharewidget"]) self.statecursormap = {} self.scene = None self.contextmenu = None self.contextmenuenabled = True self.sorendermanager = coin.SoRenderManager() self.soeventmanager = coin.SoEventManager() # Mind the order of initialization as the XML state machine uses # callbacks which depends on other state being initialized self.eventmanager = EventManager(self) self.devicemanager = DeviceManager(self) statemachine = coin.ScXML.readFile(values["scxml"]) if statemachine and statemachine.isOfType( coin.SoScXMLStateMachine.getClassTypeId()): sostatemachine = coin.cast(statemachine, "SoScXMLStateMachine") statemachine.addStateChangeCallback(statechangeCB, self) self.soeventmanager.addSoScXMLStateMachine(sostatemachine) sostatemachine.initialize() else: raise "could not initialize statemachine, given file not found?" self.headlight = coin.SoDirectionalLight() self.sorendermanager.setAutoClipping( coin.SoRenderManager.VARIABLE_NEAR_PLANE) self.sorendermanager.setRenderCallback(renderCB, self) self.sorendermanager.setBackgroundColor(coin.SbColor4f(0, 0, 0, 0)) self.sorendermanager.activate() self.sorendermanager.addPreRenderCallback(prerenderCB, self) self.sorendermanager.addPostRenderCallback(postrenderCB, self) self.soeventmanager.setNavigationState( coin.SoEventManager.MIXED_NAVIGATION) self.devicemanager.registerDevice(MouseHandler()) self.devicemanager.registerDevice(KeyboardHandler()) self.eventmanager.registerEventHandler(DragDropHandler()) # set up a cache context for the default SoGLRenderAction self.sorendermanager.getGLRenderAction().setCacheContext( self.getCacheContextId()) self.setStateCursor("interact", QtCore.Qt.ArrowCursor) self.setStateCursor("idle", QtCore.Qt.OpenHandCursor) self.setStateCursor("rotate", QtCore.Qt.ClosedHandCursor) self.setStateCursor("pan", QtCore.Qt.SizeAllCursor) self.setStateCursor("zoom", QtCore.Qt.SizeVerCursor) self.setStateCursor("seek", QtCore.Qt.CrossCursor) self.setStateCursor("spin", QtCore.Qt.OpenHandCursor) self.setMouseTracking(True) self.setFocusPolicy(QtCore.Qt.StrongFocus) def setSceneGraph(self, node): if node and self.scene == node: return camera = None superscene = None viewall = False if node: self.scene = node self.scene.ref() superscene = coin.SoSeparator() superscene.addChild(coin.SoDepthBuffer()) superscene.addChild(self.headlight) camera = self.searchForCamera(node) if not camera: camera = coin.SoPerspectiveCamera() superscene.addChild(camera) viewall = True superscene.addChild(node) self.soeventmanager.setSceneGraph(superscene) self.sorendermanager.setSceneGraph(superscene) self.soeventmanager.setCamera(camera) self.sorendermanager.setCamera(camera) if viewall: self.viewAll() if superscene: superscene.touch() def viewAll(self): """ Reposition the current camera to display the entire scene""" viewallevent = coin.SbName("sim.coin3d.coin.navigation.ViewAll") for c in range(self.soeventmanager.getNumSoScXMLStateMachines()): sostatemachine = self.soeventmanager.getSoScXMLStateMachine(c) if (sostatemachine.isActive()): sostatemachine.queueEvent(viewallevent) sostatemachine.processEventQueue() def resizeGL(self, width, height): vp = coin.SbViewportRegion(width, height) self.sorendermanager.setViewportRegion(vp) self.soeventmanager.setViewportRegion(vp) def paintGL(self): self.actualRedraw() def actualRedraw(self): self.sorendermanager.render(True, True) def event(self, qevent): """Translates Qt Events into Coin events and passes them on to the scenemanager for processing. If the event can not be translated or processed, it is forwarded to Qt and the method returns false. This method could be overridden in a subclass in order to catch events of particular interest to the application programmer.""" if self.eventmanager.handleEvent(qevent): return True soevent = self.devicemanager.translateEvent(qevent) if (soevent and self.soeventmanager.processEvent(soevent)): return True # NOTE jkg: we must return True or False return QtOpenGL.QGLWidget.event(self, qevent) def setStateCursor(self, state, cursor): self.statecursormap[state] = cursor def searchForCamera(self, root): sa = coin.SoSearchAction() sa.setInterest(coin.SoSearchAction.FIRST) sa.setType(coin.SoCamera.getClassTypeId()) sa.apply(root) if sa.getPath(): node = sa.getPath().getTail() if node and node.isOfType(coin.SoCamera.getClassTypeId()): return node return None def getCacheContextId(self): return self.cachecontext.id def findCacheContext(self, widget, sharewidget): class QuarterWidgetP_cachecontext: def __init__(self): self.widgetlist = [] self.id = None for cachecontext in self.cachecontext_list: for widget in cachecontext.widgetlist: if (widget == sharewidget): cachecontext.widgetlist.append(widget) return cachecontext cachecontext = QuarterWidgetP_cachecontext() cachecontext.id = coin.SoGLCacheContextElement.getUniqueCacheContext() cachecontext.widgetlist.append(widget) self.cachecontext_list.append(cachecontext) return cachecontext def getSoRenderManager(self): return self.sorendermanager def getSoEventManager(self): return self.soeventmanager def setBackgroundColor(self, color): """Set backgroundcolor to a given QColor Remember that QColors are given in integers between 0 and 255, as opposed to SbColor4f which is in [0 ,1]. The default alpha value for a QColor is 255, but you'll probably want to set it to zero before using it as an OpenGL clear color.""" bgcolor = coin.SbColor4f(max(0, min(1, color.red() / 255.0)), max(0, min(1, color.green() / 255.0)), max(0, min(1, color.blue() / 255.0)), max(0, min(1, color.alpha() / 255.0))) self.sorendermanager.setBackgroundColor(bgcolor) def getBackgroundColor(self): """ Returns color used for clearing the rendering area before rendering the scene.""" bg = self.sorendermanager.getBackgroundColor() return QtGui.QColor(max(0, min(255, int(bg[0] * 255.0))), max(0, min(255, int(bg[1] * 255.0))), max(0, min(255, int(bg[2] * 255.0))), max(0, min(255, int(bg[3] * 255.0)))) def getContextMenu(self): """Returns the context menu used by the widget.""" if not self.contextmenu: self.contextmenu = ContextMenu(self) # NOTE 20080508 jkg: seems like we can drop .getMenu() but I dont see why that works return self.contextmenu.getMenu() def contextMenuEnabled(self): return contextmenuenabled def enableContextMenu(self, yesno): self.contextmenuenabled = yesno def setTransparencyType(self, type): """This method sets the transparency type to be used for the scene.""" assert (self.sorendermanager) self.sorendermanager.getGLRenderAction().setTransparencyType(type) self.sorendermanager.scheduleRedraw() def enableHeadlight(self, onoff): """ Enable/disable the headlight. This wille toggle the SoDirectionalLigh::on field (returned from getHeadlight()).""" self.headlight.on = onoff def getHeadlight(self): """Returns the light used for the headlight.""" return self.headlight