def startService(self): ''' ''' self.location = "http://%s:" % get_default_v4_address() + str( self.getPort()) for device in self.devices: device.location = "http://%s:" + str(self.getPort()) device.icons = [ DeviceIcon( 'image/png', 32, 32, 24, device.getLocation(get_default_v4_address()) + '/pictures/icon.png') ] log.msg('UPnP Service Started', loglevel=logging.INFO) self.started = True
def send_NOTIFY(self, nt, uuid=None, nts='ssdp:alive'): if self.ssdp.device.bootID is None: self.ssdp.device.bootID = int(time.time()) location = self.ssdp.device.getLocation(get_default_v4_address()) if uuid is None: uuid = self.ssdp.device.uuid usn, nt = build_notification_type(uuid, nt) log.msg("send_NOTIFY %s:%s" % (nts, usn)) headers = { # max-age is notifySequenceInterval + 10 minutes 'CACHE-CONTROL': 'max-age = %d' % (self.notifySequenceInterval + (10 * 60)), 'LOCATION': location, 'SERVER': self.ssdp.device.server, 'NT': nt, 'NTS': nts, 'USN': usn, 'BOOTID.UPNP.ORG': self.ssdp.device.bootID, 'CONFIGID.UPNP.ORG': self.ssdp.device.configID } self.send('NOTIFY', headers, (SSDP_ADDR_V4, SSDP_PORT))
def startService(self): ''' ''' self.location = "http://%s:" % get_default_v4_address() + str( self.getPort()) for device in self.devices: device.location = "http://%s:" + str(self.getPort()) device.icons = [ DeviceIcon( 'image/png', 32, 32, 24, device.getLocation( get_default_v4_address( )) + '/pictures/icon.png')] log.msg('UPnP Service Started', loglevel=logging.INFO) self.started = True
def send_NOTIFY(self, nt, uuid=None, nts="ssdp:alive"): if self.ssdp.device.bootID is None: self.ssdp.device.bootID = int(time.time()) location = self.ssdp.device.getLocation(get_default_v4_address()) if uuid is None: uuid = self.ssdp.device.uuid usn, nt = build_notification_type(uuid, nt) log.msg("send_NOTIFY %s:%s" % (nts, usn)) headers = { # max-age is notifySequenceInterval + 10 minutes "CACHE-CONTROL": "max-age = %d" % (self.notifySequenceInterval + (10 * 60)), "LOCATION": location, "SERVER": self.ssdp.device.server, "NT": nt, "NTS": nts, "USN": usn, "BOOTID.UPNP.ORG": self.ssdp.device.bootID, "CONFIGID.UPNP.ORG": self.ssdp.device.configID, } self.send("NOTIFY", headers, (SSDP_ADDR_V4, SSDP_PORT))
def model(self, ignored): log.err('Model from Product') return (self.modelName, self.modelDescription, self.manufacturerURL, ''.join(( self.getLocation(get_default_v4_address()), '/pictures/', self.modelName, '.png', )))
def manufacturer(self, ignored): log.err('Manufacturer from Product') return ( self.manufacturer, self.manufacturerInfo, self.manufacturerURL, ''.join((self.getLocation(get_default_v4_address()), '/pictures/icon.png')), )
def wait_connection(self): try: addr = self.getLocation(get_default_v4_address()) setattr(self, 'manufacturerimageurl', addr + '/pictures/icon.png') self.oh_product_event('manufacturerimageurl', self.manufacturerimageurl) setattr(self, 'modelimageurl', ''.join( (addr, '/pictures/', self.modelname, '.png'))) self.oh_product_event('modelimageurl', self.modelimageurl) except: reactor.callLater(1, self.wait_connection) # @UndefinedVariable
def wait_connection(self): try: addr = self.getLocation(get_default_v4_address()) setattr( self, 'manufacturerimageurl', addr + '/pictures/icon.png') self.oh_product_event( 'manufacturerimageurl', self.manufacturerimageurl) setattr(self, 'modelimageurl', ''.join((addr, '/pictures/', self.modelname, '.png'))) self.oh_product_event('modelimageurl', self.modelimageurl) except: reactor.callLater(1, self.wait_connection) # @UndefinedVariable
def add_device(self, device): self.devices.append(device) device.parent = self if self.started: device.location = "http://%s:" + str(self.getPort()) device.icons = [ DeviceIcon( 'image/png', 32, 32, 24, device.getLocation(get_default_v4_address()) + '/pictures/icon.png') ] for service in device.services: service.control_resource = TwistedWebResource(service.app) service.event_resource = ServiceEventResource(service) service.resource = ServiceResource(service) self.upnp.addDevice(device)
def mpd_decode(dic): d = {} if isinstance(dic, list): log.error('bad info: {dic}', dic=dic) return d for k in dic.keys(): if k == 'albumArtURI': d.update({k: dic[k]}) if k == 'Time': hrs = int(dic[k]) / 3600 mn = (int(dic[k]) - hrs * 3600) / 60 sec = (int(dic[k]) - mn * 60) t = ':'.join(['{:0>2}'.format(str(hrs)), '{:0>2}'.format(str(mn)), '{:0>2}'.format(str(sec))]) d.update({'duration': t}) elif k in ('Title', 'Date', 'Genre', 'Artist', 'Album', 'Composer', 'Id', 'Pos'): d.update({k.lower(): dic[k]}) # .decode('utf-8') elif k in ('Url', 'file'): d.update({'url': dic[k]}) # .decode('utf-8') c = dic[k].split('.')[-1] if len(c) < 5: d.update({'codec': dic[k].split('.')[-1]}) if dic[k].split('/')[0] in ('http:', 'http'): try: d.update( {'protocolInfo': dic[k].split(':')[0] + '-get:*:' + guess_type(dic[k])[0] + ':*'}) except: pass else: try: d.update( {'protocolInfo': 'internal:' + get_default_v4_address() + ':' + guess_type(dic[k])[0] + ':local'}) except: pass if 'duration' not in d.keys(): d.update({'duration': '00:00:00.000'}) return d
def add_device(self, device): self.devices.append(device) device.parent = self if self.started: device.location = "http://%s:" + str(self.getPort()) device.icons = [ DeviceIcon( 'image/png', 32, 32, 24, device.getLocation( get_default_v4_address( )) + '/pictures/icon.png')] for service in device.services: service.control_resource = TwistedWebResource(service.app) service.event_resource = ServiceEventResource(service) service.resource = ServiceResource(service) self.upnp.addDevice(device)
def mpd_decode(dic): d = {} if isinstance(dic, list): log.error('bad info: {dic}', dic=dic) return d for k in dic.keys(): if k == 'albumArtURI': d.update({k: dic[k]}) if k == 'Time': hrs = int(dic[k]) / 3600 mn = (int(dic[k]) - hrs * 3600) / 60 sec = (int(dic[k]) - mn * 60) t = ':'.join([ '{:0>2}'.format(str(hrs)), '{:0>2}'.format(str(mn)), '{:0>2}'.format(str(sec)) ]) d.update({'duration': t}) elif k in ('Title', 'Date', 'Genre', 'Artist', 'Album', 'Composer', 'Id', 'Pos'): d.update({k.lower(): dic[k]}) # .decode('utf-8') elif k in ('Url', 'file'): d.update({'url': dic[k]}) # .decode('utf-8') c = dic[k].split('.')[-1] if len(c) < 5: d.update({'codec': dic[k].split('.')[-1]}) if dic[k].split('/')[0] in ('http:', 'http'): try: d.update({ 'protocolInfo': dic[k].split(':')[0] + '-get:*:' + guess_type(dic[k])[0] + ':*' }) except: pass else: try: d.update({ 'protocolInfo': 'internal:' + get_default_v4_address() + ':' + guess_type(dic[k])[0] + ':local' }) except: pass if 'duration' not in d.keys(): d.update({'duration': '00:00:00.000'}) return d
def __init__(self, device): self.services = [] """ Initialization of SSDP server """ self.device = device if self.device.uuid is None: raise ValueError() self.targets.append("uuid:" + self.device.uuid) self.targets.append(self.device.deviceType) for service in self.device.services: self.targets.append(service.serviceType) if not self.listener: self.listener = SSDP_Listener(self) self.ssdp = internet.MulticastServer( # @UndefinedVariable SSDP_PORT, self.listener, listenMultiple=True, interface=SSDP_ADDR_V4 ) self.ssdp.setServiceParent(self) self.client = SSDP_Client(self, get_default_v4_address()) self.ssdp_client = internet.UDPServer(0, self.client, self.client.interface) # @UndefinedVariable self.ssdp_client.setServiceParent(self)
def __init__(self, device): self.services = [] ''' Initialization of SSDP server ''' self.device = device if self.device.uuid is None: raise ValueError() self.targets.append('uuid:' + self.device.uuid) self.targets.append(self.device.deviceType) for service in self.device.services: self.targets.append(service.serviceType) if not self.listener: self.listener = SSDP_Listener(self) self.ssdp = internet.MulticastServer( # @UndefinedVariable SSDP_PORT, self.listener, listenMultiple=True, interface=SSDP_ADDR_V4) self.ssdp.setServiceParent(self) self.client = SSDP_Client(self, get_default_v4_address()) self.ssdp_client = internet.UDPServer( # @UndefinedVariable 0, self.client, self.client.interface) self.ssdp_client.setServiceParent(self)
def manufacturer(self, ignored): log.err('Manufacturer from Product') return (self.manufacturer, self.manufacturerInfo, self.manufacturerURL, ''.join(( self.getLocation(get_default_v4_address()), '/pictures/icon.png')),)
def register_art_url(self, url, cloud=False): if cloud: return None newurl = hashlib.md5(url).hexdigest() + url[-4:] self.resource.putChild(newurl, static.File(url)) return self.webserver.weburl % get_default_v4_address() + '/' + newurl
try: self.transport.write(msg, (address, port)) except socket.error, e: log.err("socket.error: %s" % e) def respond_MSEARCH(self, st, (address, port)): log.msg("respond_MSEARCH to %s:%s, headers=%s" % (address, port, st)) if self.ssdp.device.bootID is None: self.ssdp.device.bootID = int(time.time()) if address == "127.0.0.1": location = self.ssdp.device.getLocation("127.0.0.1") else: location = self.ssdp.device.getLocation(get_default_v4_address()) usn, st = build_notification_type(self.ssdp.device.uuid, st) headers = { "CACHE-CONTROL": "max-age = %d" % self.responseExpire, "EXT": "", "LOCATION": location, "SERVER": self.ssdp.device.server, "ST": st, "USN": usn, "OPT": '"http://schemas.upnp.org/upnp/1/0/"; ns=01', "01-NLS": self.ssdp.device.bootID, "BOOTID.UPNP.ORG": self.ssdp.device.bootID, "CONFIGID.UPNP.ORG": self.ssdp.device.configID, }
def __init__( self, parent=None, searchables=None, xmldir=None, network='lan', cloud_user=None, cloud_servers=[], logger=None, uid=None, messager=None): self.connected = False self.messager = messager self.app_paused = False self.fail_count = 0 if not logger: self.log = Logger() else: self.log = logger self.log.debug('UPnP controller starts') self.xmldir = xmldir self.devices = {} self._services = {} self.parent = parent # self.amp = ControllerAmp(self) if uid: self.uuid = uid else: self.uuid = str( uuid.uuid5( uuid.NAMESPACE_DNS, socket.gethostname() + 'onDemand_Controller')) if searchables: for typ in searchables: self.searchables.update({typ[0]: typ[1]}) # print(self.searchables) else: self.searchables = {'upnp:rootdevice': self.log.debug} if network in ('lan', 'both'): self.log.debug('UPnP classic enabled') self.lan = True self.listener = ssdp.SSDP_Listener(self) self.mcast = internet.MulticastServer( # @UndefinedVariable SSDP_PORT, self.listener, listenMultiple=True, interface=SSDP_ADDR_V4) self.mcast.setServiceParent(self) self.ssdp_cli = ssdp.SSDP_Client( self, get_default_v4_address(), device=False) self.ucast = internet.UDPServer( # @UndefinedVariable 0, self.ssdp_cli, self.ssdp_cli.interface) self.ucast.setServiceParent(self) # self.agent = Agent(reactor) if network in ('cloud', 'both'): if cloud_user: self.log.debug('UPnP Cloud enabled') self.cloud = True self._jid, secret = cloud_user self.users = {self._jid: {'state': True}} for user in cloud_servers: self.users.update({user: {'state': False}}) self.hosts = {} self.resourcepart = ''.join(( 'urn:schemas-upnp-org:cloud-1-0:ControlPoint:1:uuid:', self.uuid)) full_jid = ''.join( (self._jid, '/', self.resourcepart)) self.jid = jid = JID(full_jid) self.reactor = reactor f = client.XMPPClientFactory(jid, secret) f.addBootstrap( xmlstream.STREAM_CONNECTED_EVENT, self.cloud_connected) f.addBootstrap( xmlstream.STREAM_END_EVENT, self.cloud_disconnected) f.addBootstrap( xmlstream.STREAM_AUTHD_EVENT, self.authenticated) f.addBootstrap( xmlstream.INIT_FAILED_EVENT, self.cloud_failed) self.connector = endpoints.HostnameEndpoint( reactor, jid.host, 5222) self.factory = f
def subscribe_classic( self, device, svc, var, callback_fct=None, callback_args=()): if not callback_fct: callback_fct = self.log.debug name = device.keys()[0] dev = device[name] def subscribe_failed(err, name): self.parent.remove_device(name.split('_')[0]) def subscribed(req, raddr, host, name): try: uuid = req.headers.getRawHeaders('sid')[0] print('subscription uuid = %s' % uuid) if name in self.subscriptions: if host in self.subscriptions[name]: self.subscriptions[name][host].update({uuid: raddr}) else: self.subscriptions[name].update({host: {uuid: raddr}}) else: self.subscriptions.update({name: {host: {uuid: raddr}}}) reactor.callLater( # @UndefinedVariable 20, self.renew_subscription, uuid) return name except TypeError: return subscribe_failed(None, name) if self.event_catcher is None: self.event_catcher = EventServer() self.event_catcher.setServiceParent(self) subscription_id = '_'.join((name, svc.split(':')[-2])) childpath = '_'.join((subscription_id, 'event',)) # log.error(childpath) if childpath in self.event_catcher.catcher.childs: self.event_catcher.catcher.childs[childpath].update( {var: (callback_fct, callback_args,)}) else: self.event_catcher.catcher.childs.update( {childpath: {var: (callback_fct, callback_args,)}}) # log.error(self.event_catcher.catcher.childs) if subscription_id in self.subscriptions: for k, value in self.event_catcher.catcher.unfiltered.items(): if k == var: if value == 'False': value = False elif value == 'True': value = True if isinstance(callback_args, str)\ or isinstance(callback_args, bool): callback_fct(value, callback_args) else: callback_fct(value, *callback_args) del self.event_catcher.catcher.unfiltered[k] return defer.succeed(None) else: self.subscriptions.update({subscription_id: {}}) clbk = '<' + 'http://' + get_default_v4_address() + ':' +\ str(self.event_catcher.getPort()) + '/' + childpath + '>' # print(clbk) headers = {'HOST': [get_default_v4_address() + ':' + str(self.event_catcher.getPort())], 'CALLBACK': [clbk], 'NT': ['upnp:event'], 'TIMEOUT': ['Second-25']} if svc in dev['services']: self.log.error(svc) addr = dev['services'][svc]['eventSubURL'] self.log.error(addr) d = self.agent.request( 'SUBSCRIBE', addr, Headers(headers)) d.addCallbacks( subscribed, subscribe_failed, callbackArgs=(addr, headers['HOST'][0], subscription_id), errbackArgs=(subscription_id,)) return d # log.error(dev['services']) return defer.fail(Exception('Service unknow'))
def model(self, ignored): log.err('Model from Product') return (self.modelName, self.modelDescription, self.manufacturerURL, ''.join((self.getLocation(get_default_v4_address()), '/pictures/', self.modelName, '.png',)))
try: self.transport.write(msg, (address, port)) except socket.error, e: log.err("socket.error: %s" % e) def respond_MSEARCH(self, st, (address, port)): log.msg("respond_MSEARCH to %s:%s, headers=%s" % (address, port, st)) if self.ssdp.device.bootID is None: self.ssdp.device.bootID = int(time.time()) if address == '127.0.0.1': location = self.ssdp.device.getLocation('127.0.0.1') else: location = self.ssdp.device.getLocation(get_default_v4_address()) usn, st = build_notification_type(self.ssdp.device.uuid, st) headers = { 'CACHE-CONTROL': 'max-age = %d' % self.responseExpire, 'EXT': '', 'LOCATION': location, 'SERVER': self.ssdp.device.server, 'ST': st, 'USN': usn, 'OPT': '"http://schemas.upnp.org/upnp/1/0/"; ns=01', '01-NLS': self.ssdp.device.bootID, 'BOOTID.UPNP.ORG': self.ssdp.device.bootID, 'CONFIGID.UPNP.ORG': self.ssdp.device.configID, }