def Seek(self, **kwargs): if not (self._transport_state == "PLAYING" or self._transport_state == "STOPPED"): raise UPnPServiceError(701) unit = kwargs["Unit"] if unit != "REL_TIME": self.fire(Log(logging.DEBUG, "Seek called"), "logger") raise UPnPServiceError(710) target = kwargs["Target"] self.fire(Log(logging.DEBUG, "Seek to " + target + " called"), "logger") target = target.split(":") target = int(target[0]) * 3600 + int(target[1]) * 60 + int(target[2]) self.fire(Event.create("Seek", target), self.parent.provider.channel) return []
def SetVolume(self, **kwargs): self.fire( Log(logging.DEBUG, 'SetVolume to ' + kwargs["DesiredVolume"]), "logger") self.fire( Event.create("SetVolume", int(kwargs["DesiredVolume"]) / 100.0), self.parent.provider.channel) return []
def SetNextAVTransportURI(self, **kwargs): self.fire( Log(logging.DEBUG, 'Next AV Transport URI set to ' + kwargs["NextURI"]), "logger") self.fire( Event.create("PrepareNext", kwargs["NextURI"], kwargs["NextURIMetaData"]), self.parent.provider.channel) return []
def __init__(self, path, channel=channel): super(UPnPDeviceServer, self).__init__(channel=channel) self._started = False # Build a web (HTTP) server for handling requests. This is # the server that will be announced by SSDP, so it has # no fixed port number. self.web_server = BaseServer(("", 0), channel="upnp-web").register(self) # Dispatcher for "/upnp-web". disp = ScopeDispatcher(channel="upnp-web").register(self.web_server) # Dummy root controller prevents requests for nested resources # from failing. DummyRoot().register(disp) # Initially empty list of providers self._devices = [] # The configuration id, incremented every time the # configuration changes self.config_id = 1 # Open the database for uuid persistence try: # Some people encounter problems on some boxes when opening # the db file self._uuid_db = dbm.open(os.path.join(path, 'upnp_uuids'), 'c') except: self.fire( Log( logging.WARN, "Could not determine type db type of " + os.path.join(path, 'upnp_uuids'))) try: os.remove(os.path.join(path, 'upnp_uuids')) self._uuid_db = dbm.open \ (os.path.join(path, 'upnp_uuids'), 'c') except: self.fire( Log(logging.WARN, "Giving up on " + os.path.join(path, 'upnp_uuids')))
def _on_registered(self, component, parent): if component != self: return @handler("notification", channel=parent.notification_channel) def _on_notification_handler(self, state_vars): self._on_notification(state_vars) self.addHandler(_on_notification_handler) state_vars = dict() for name, method in getmembers \ (self.parent, lambda x: ismethod(x) and hasattr(x, "_evented_by")): state_vars[name] = method() if len(state_vars) > 0: self._on_notification(state_vars) self.fire(Log(logging.DEBUG, "Subscribtion for " + str(self._callbacks) + " on " + self.parent.notification_channel + " created"), "logger")
def GetPositionInfo(self, **kwargs): rel_pos = self._provider.current_position() self.fire(Log(logging.DEBUG, "GetPositionInfo called"), "logger") info = [("Track", self._provider.current_track), ("TrackDuration", "NOT_IMPLEMENTED" \ if self._provider.current_track_duration is None \ else self._format_duration \ (self._provider.current_track_duration)), ("TrackMetaData", "NOT_IMPLEMENTED" \ if self._provider.source_meta_data is None \ else self._provider.source_meta_data), ("TrackURI", self._provider.source), ("RelTime", "NOT_IMPLEMENTED" if rel_pos is None \ else self._format_duration(rel_pos)), ("AbsTime", "NOT_IMPLEMENTED"), ("RelCount", 2147483647), ("AbsCount", 2147483647)] return info
def GetMediaInfo(self, **kwargs): self.fire(Log(logging.DEBUG, "GetMediaInfo called"), "logger") return [("NrTracks", self._provider.tracks), ("MediaDuration", "NOT_IMPLEMENTED" \ if self._provider.current_track_duration is None \ else self._format_duration \ (self._provider.current_track_duration)), ("CurrentURI", self._provider.source), ("CurrentURIMetaData", "NOT_IMPLEMENTED" \ if self._provider.source_meta_data is None \ else self._provider.source_meta_data), ("NextURI", self._provider.next_source), ("NextURIMetaData", "NOT_IMPLEMENTED" \ if self._provider.next_source_meta_data is None \ else self._provider.next_source_meta_data), ("PlayMedium", "NONE"), ("RecordMedium", "NOT_IMPLEMENTED"), ("WriteStatus", "NOT_IMPLEMENTED")]
def _control(self, *args): payload = parseSoapRequest(self.request)[2] action_ns, action = splitQTag(payload.tag) action_args = dict() for node in payload: action_args[node.tag] = node.text method = getattr(self, action, None) if method is None or not getattr(method, "_is_upnp_service", False): self.fire(Log(logging.INFO, 'Action ' + action + " not implemented"), "logger") return UPnPError(self.request, self.response, 401) try: out_args = method(**action_args) except UPnPServiceError as error: return UPnPError(self.request, self.response, error.code) result = Element("{%s}%sResponse" % (action_ns, action)) for name, value in out_args: arg = SubElement(result, name) arg.text = str(value) return buildSoapResponse(self.response, result)
def __init__(self, channel=channel): ''' Constructor ''' super(SSDPSender, self).__init__(channel=channel) # Setup the common entries in the dictionary that will be usd to # fill the UPnP templates. self._message_env['BOOTID'] = self._boot_id self._message_env['SERVER'] = SERVER_HELLO try: self.hostaddr = gethostbyname(gethostname()) if self.hostaddr.startswith("127.") and not "." in gethostname(): try: self.hostaddr = gethostbyname(gethostname() + ".") except: pass except Exception as e: self.fire(Log(logging.ERROR, "Failed to get host address: %s(%s)" \ % (type(e), str(e))), "logger")
def _on_notification(self, state_vars): root = Element(QName(UPNP_EVENT_NS, "propertyset")) for name, value in state_vars.items(): prop = SubElement(root, QName(UPNP_EVENT_NS, "property")) val = SubElement(prop, QName(UPNP_EVENT_NS, name)) if isinstance(value, bool): val.text = "1" if value else "0" else: val.text = str(value) misc.set_ns_prefixes(root, { "": UPNP_EVENT_NS }) writer = StringIO() writer.write("<?xml version='1.0' encoding='utf-8'?>") ElementTree(root).write(writer, encoding="utf-8") body = writer.getvalue() self.fire(Log(logging.DEBUG, "Notifying " + self._callbacks[self._used_callback] + " about " + str(state_vars)), "logger") self.fire(Request("NOTIFY", self._callbacks[self._used_callback], body, { "CONTENT-TYPE": "text/xml; charset=\"utf-8\"", "NT": "upnp:event", "NTS": "upnp:propchange", "SID": self.sid, "SEQ": self._seq })) self._seq += 1
def Stop(self, **kwargs): self.fire(Log(logging.DEBUG, "Stop called"), "logger") self.fire(Event.create("Stop"), self.parent.provider.channel) return []
def _on_renewal(self, timeout): self._expiry_timer.interval = timeout self._expiry_timer.reset() self.fire(Log(logging.DEBUG, "Subscribtion for " + str(self._callbacks) + " on " + self.parent.notification_channel + " renewed"), "logger")
def _on_subs_end(self): self.unregister() self.fire(Log(logging.DEBUG, "Subscribtion for " + str(self._callbacks) + " on " + self.parent.notification_channel + " cancelled"), "logger")
def GetProtocolInfo(self, **kwargs): self.fire(Log(logging.DEBUG, "GetProtocolInfo called"), "logger") types = self.parent._provider.supportedMediaTypes() return [("Source", ""), ("Sink", ",".join(types))]
def _on_provider_updated_handler(self, provider, changed): self.fire( Log(logging.DEBUG, str(provider) + " changed: " + str(changed)), "logger")
def GetCurrentConnectionIDs(self, **kwargs): self.fire(Log(logging.DEBUG, "GetCurrentConnectionIDs called"), "logger") return [("GetCurrentConnectionIDs", self.CurrentConnectionIDs())]
def GetVolume(self, **kwargs): self.fire(Log(logging.DEBUG, "GetVolume called"), "logger") return [("CurrentVolume", str(int(self._provider.volume * 100)))]
def GetTransportInfo(self, **kwargs): self.fire(Log(logging.DEBUG, "GetTransportInfo called"), "logger") return [("CurrentTransportState", self._transport_state), ("CurrentTransportStatus", "OK"), ("CurrentSpeed", "1")]
def Pause(self, **kwargs): self.fire(Log(logging.DEBUG, "Pause called"), "logger") self.fire(Event.create("Pause"), self.parent.provider.channel) return []