class DummyPlayer(providers.MediaPlayer): ''' classdocs ''' manifest = Manifest("Dummy Player", "CoCy Dummy Media Player") def __init__(self): super(DummyPlayer, self).__init__(self.manifest) self._timer = None @handler("provider_updated") def _on_provider_updated_handler(self, provider, changed): if "state" in changed: state = changed["state"] if state == "PLAYING": self.current_track_duration = 60 if self._timer: self._timer.unregister() self._timer = Timer(self.current_track_duration, MediaPlayer.EndOfMedia()).register(self) elif state == "IDLE": if self._timer: self._timer.unregister() def current_position(self): if self._timer is None: return None return self._current_track_duration - (self._timer.expiry - time.time())
def test_datetime(self): now = datetime.now() d = now + timedelta(seconds=0.1) timer = Timer(d, test(), "timer") timer.register(self.app) wait_for(self.app, "flag") self.app.reset()
def _send_request(self, method, url, body=None, headers={}, timeout=None): p = urlparse(url) if p.hostname and p.hostname != self._host \ or p.scheme == "http" and self._secure \ or p.scheme == "https" and not self._secure \ or p.port and p.port != self._port: self.fire(NotConnected()) return resource = p.path if p.query: resource += "?" + p.query headers = Headers([(k, v) for k, v in list(headers.items())]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if "Host" not in headers: headers["Host"] = self._host \ + (":" + str(self._port)) if self._port else "" command = "%s %s HTTP/1.1" % (method, resource) if body is not None: headers["Content-Length"] = len(body) message = "%s\r\n%s" % (command, headers) self._outstanding += 1 if timeout is not None: self._timer = Timer(timeout, SocketError(ETIMEDOUT), self.channel) \ .register(self) self.fire(write(message.encode('utf-8')), self._transport) if body is not None: self.fire(write(body), self._transport)
def test_datetime(self): now = datetime.now() d = now + timedelta(seconds=0.1) timer = Timer(d, test(), "timer") timer.register(self.app) wait_for(self.app, "flag") self.app.reset()
def test_persistent(self): timer = Timer(0.1, test(), "timer", persist=True) timer.register(self.app) for _ in range(2): wait_for(self.app, "flag") self.app.reset() timer.unregister()
def _on_off_changed(self, value, session=None, **kwargs): if value and self._timer is None: evt = Event.create("time_over", session) evt.channels = (self.channel, ) self._timer = Timer(1, evt, persist=True).register(self) locales = kwargs.get("locales", []) self.fire(portal_message \ (session, self.translation(locales) \ .ugettext("TimeUpdateOn")), self._portal_channel) if not value and self._timer is not None: self._timer.unregister() self._timer = None
def _on_provider_updated_handler(self, provider, changed): if "state" in changed: state = changed["state"] if state == "PLAYING": self.current_track_duration = 60 if self._timer: self._timer.unregister() self._timer = Timer(self.current_track_duration, MediaPlayer.EndOfMedia()).register(self) elif state == "IDLE": if self._timer: self._timer.unregister()
class ServerTimePortlet(TemplatePortlet): def __init__(self, *args, **kwargs): super(ServerTimePortlet, self) \ .__init__("templates", "servertime", *args, **kwargs) self._portal_channel = None self._time_channel = self.channel + "-time" self._timer = None def description(self, locales=[]): return Portlet.Description\ (self._handle, self.translation(locales) \ .ugettext("Server Time Portlet"), events=[(on_off_changed, self.channel)]) @handler("portlet_added") def _on_portlet_added(self, portal, portlet): self._portal_channel = portal.channel @handler("portal_client_connect", channel=portal.channel) def _on_ws_connect(self, session): self._update_time(session) self.addHandler(_on_ws_connect) def _update_time(self, session): td = datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1) td = td.microseconds / 1000 + (td.seconds + td.days * 86400) * 1000 td = int(td) self.fire(portal_update(self, session, "new_time", str(td)), \ self._portal_channel) @property def updating(self): return getattr(self, "_timer", None) is not None @handler("on_off_changed") def _on_off_changed(self, value, session=None, **kwargs): if value and self._timer is None: evt = Event.create("time_over", session) evt.channels = (self.channel, ) self._timer = Timer(1, evt, persist=True).register(self) locales = kwargs.get("locales", []) self.fire(portal_message \ (session, self.translation(locales) \ .ugettext("TimeUpdateOn")), self._portal_channel) if not value and self._timer is not None: self._timer.unregister() self._timer = None @handler("time_over") def _on_time_over(self, session): self._update_time(session)
def _on_play(self): if self.source is None or self.state == "PLAYING": return if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) self.state = "PLAYING"
class ServerTimePortlet(TemplatePortlet): def __init__(self, *args, **kwargs): super(ServerTimePortlet, self) \ .__init__("templates", "servertime", *args, **kwargs) self._portal_channel = None self._time_channel = self.channel + "-time" self._timer = None def description(self, locales=[]): return Portlet.Description\ (self._handle, self.translation(locales) \ .ugettext("Server Time Portlet"), events=[(on_off_changed, self.channel)]) @handler("portlet_added") def _on_portlet_added(self, portal, portlet): self._portal_channel=portal.channel @handler("portal_client_connect", channel=portal.channel) def _on_ws_connect(self, session): self._update_time(session) self.addHandler(_on_ws_connect) def _update_time(self, session): td = datetime.datetime.utcnow() - datetime.datetime(1970, 1, 1) td = td.microseconds / 1000 + (td.seconds + td.days * 86400) * 1000 td = int(td) self.fire(portal_update(self, session, "new_time", str(td)), \ self._portal_channel) @property def updating(self): return getattr(self, "_timer", None) is not None @handler("on_off_changed") def _on_off_changed(self, value, session=None, **kwargs): if value and self._timer is None: evt = Event.create("time_over", session) evt.channels = (self.channel,) self._timer = Timer(1, evt, persist=True).register(self) locales = kwargs.get("locales", []) self.fire(portal_message \ (session, self.translation(locales) \ .ugettext("TimeUpdateOn")), self._portal_channel) if not value and self._timer is not None: self._timer.unregister() self._timer = None @handler("time_over") def _on_time_over(self, session): self._update_time(session)
def _on_device_available(self, event, upnp_device): self._update_message_env(upnp_device) self._send_device_messages(upnp_device, "available") # Service announcements for service in upnp_device.services: self._send_service_message(upnp_device, service, "available") # Handle repeats if getattr(event, 'times_sent', 0) < 3: self._timers[upnp_device.uuid] \ = Timer(0.25, event, *event.channels).register(self) event.times_sent = getattr(event, 'times_sent', 0) + 1 else: self._timers[upnp_device.uuid] \ = Timer(self._message_expiry / 4, event, *event.channels).register(self)
def _on_search_request(self, event, search_target=UPNP_ROOTDEVICE, mx=1): self._send_template("m-search-request", { "ST": search_target, "MX": mx }) # Handle repeats if getattr(event, 'times_sent', 0) < 3: Timer(mx, event, *event.channels).register(self) event.times_sent = getattr(event, 'times_sent', 0) + 1
def _send_request(self, method, url, body=None, headers=None, timeout=None): p = urlparse(url) if p.hostname and p.hostname != self._host \ or p.scheme == "http" and self._secure \ or p.scheme == "https" and not self._secure \ or p.port and p.port != self._port: self.fire(NotConnected()) return resource = p.path if p.query: resource += "?" + p.query if headers is None: headers = Headers([]) else: headers = Headers([(k, v) for k, v in headers.items()]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if not headers.has_key("Host"): headers["Host"] = self._host \ + (":" + str(self._port)) if self._port else "" command = "%s %s HTTP/1.1" % (method, resource) if body is not None: headers["Content-Length"] = len(body) message = "%s\r\n%s" % (command, headers) self._outstanding += 1 if timeout is not None: self._timer = Timer(timeout, SocketError(ETIMEDOUT), self.channel) \ .register(self) self.fire(write(message.encode('utf-8')), self._transport) if body is not None: self.fire(write(body), self._transport)
def flushChanges(self): if self._updates_locked or len(self._changes) == 0: return self._updates_locked = True self.fire(Notification({"LastChange": self.LastChange()}), self.notification_channel) self._changes.clear() Timer(0.2, Event.create("UnlockUpdates"), self).register(self)
def _on_provider_updated_handler(self, provider, changed): if "source" in changed: if self.state == "PLAYING": if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) if "state" in changed: state = changed["state"] if state == "IDLE": if self._timer: self._timer.unregister()
def __init__(self, location, max_age, usn): super(UPnPRootDevice, self).__init__(channel=usn) self._location = location self._usn = usn self._ready = False self._comm_chan = "client." + usn self._client = Client(location, channel=self._comm_chan).register(self) @handler("response", channel=self._comm_chan) def _on_response(self, response): if response.status == http_client.OK: self._initialize(response.read()) self.addHandler(_on_response) @handler("error", channel=self._comm_chan) def _on_error(self, *args, **kwargs): self._client.close() self.unregister() self.addHandler(_on_error) self.fire(Request("GET", self._location), self._client) self._expiry_timer \ = Timer(max_age, UPnPDeviceByeBye(usn)).register(self)
def _on_off_changed(self, value, session=None, **kwargs): if value and self._timer is None: evt = Event.create("time_over", session) evt.channels = (self.channel,) self._timer = Timer(1, evt, persist=True).register(self) locales = kwargs.get("locales", []) self.fire(portal_message \ (session, self.translation(locales) \ .ugettext("TimeUpdateOn")), self._portal_channel) if not value and self._timer is not None: self._timer.unregister() self._timer = None
def __init__(self, callbacks, timeout, protocol): self._uuid = str(uuid4()) super(UPnPSubscription, self).__init__(channel="subs:" + self._uuid) self._callbacks = callbacks self._used_callback = 0 self._client = Client(self._callbacks[self._used_callback], self.channel).register(self) self._protocol = protocol self._seq = 0 if timeout > 0: self._expiry_timer = Timer \ (timeout, Event.create("upnp_subs_end"), self).register(self)
def __init__(self, callbacks, timeout, protocol): self._uuid = str(uuid4()) super(UPnPSubscription, self).__init__(channel="subs:" + self._uuid) self._callbacks = callbacks self._used_callback = 0 self._client = Client(self._callbacks[self._used_callback], self.channel).register(self) self._protocol = protocol self._seq = 0 if timeout > 0: self._expiry_timer = Timer \ (timeout, Event.create("upnp_subs_end"), self).register(self)
def _on_play(self): if self.source is None or self.state == "PLAYING": return if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) self.state = "PLAYING"
def test_persistent(self): timer = Timer(0.1, test(), "timer", persist=True) timer.register(self.app) for _ in range(2): wait_for(self.app, "flag") self.app.reset() timer.unregister()
def _on_provider_updated_handler(self, provider, changed): if "source" in changed: if self.state == "PLAYING": if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) if "state" in changed: state = changed["state"] if state == "IDLE": if self._timer: self._timer.unregister()
def __init__(self, location, max_age, usn): super(UPnPRootDevice, self).__init__(channel=usn) self._location = location self._usn = usn self._ready = False self._comm_chan = "client." + usn self._client = Client(location, channel=self._comm_chan).register(self) @handler("response", channel=self._comm_chan) def _on_response(self, response): if response.status == httplib.OK: self._initialize(response.read()) self.addHandler(_on_response) @handler("error", channel=self._comm_chan) def _on_error(self, *args, **kwargs): self._client.close() self.unregister() self.addHandler(_on_error) self.fire(Request("GET", self._location), self._client) self._expiry_timer \ = Timer(max_age, UPnPDeviceByeBye(usn)).register(self)
class UPnPSubscription(BaseController): def __init__(self, callbacks, timeout, protocol): self._uuid = str(uuid4()) super(UPnPSubscription, self).__init__(channel="subs:" + self._uuid) self._callbacks = callbacks self._used_callback = 0 self._client = Client(self._callbacks[self._used_callback], self.channel).register(self) self._protocol = protocol self._seq = 0 if timeout > 0: self._expiry_timer = Timer \ (timeout, Event.create("upnp_subs_end"), self).register(self) @handler("registered") 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 _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 @handler("upnp_subs_end") def _on_subs_end(self): self.unregister() self.fire(Log(logging.DEBUG, "Subscribtion for " + str(self._callbacks) + " on " + self.parent.notification_channel + " cancelled"), "logger") @handler("upnp_subs_renewal") 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") @property def sid(self): return "uuid:" + self._uuid @classmethod def sid2chan(cls, sid): return "subs:" + sid[5:]
def test_basic(self): timer = Timer(0.1, test(), "timer") timer.register(self.app) wait_for(self.app, "flag") self.app.reset()
class Client(BaseComponent): """ This is a variation of the Client class from circuits that fixes a problem with channel names and provides a slightly simplified interface that doesn't need explicit connect events. """ channel = "web" def __init__(self, url, channel=channel, timeout=-1): super(Client, self).__init__(channel=channel) self._host, self._port, self._resource, self._secure = parse_url(url) self._response = None self._transport = None self._outstanding = 0 self._pending = deque() self._timeout = None self._timer = None @handler("request") def request(self, event, method, url, body=None, headers={}, timeout=None): timeout = timeout or self._timeout if self._transport == None or not self._transport.connected: self._transport = TCPClient(channel=self.channel).register(self) HTTP(channel=self.channel).register(self._transport) self.fire(connect(self._host, self._port, self._secure), self._transport) self._pending.append((method, url, body, headers, timeout)) else: self._send_request(method, url, body, headers, timeout) @handler("connected") def _on_connected(self, host, port): if len(self._pending) > 0: args = self._pending.popleft() self._send_request(*args) @handler("disconnected") def _on_disconnected(self): if len(self._pending) > 0: self.fire(connect(self._host, self._port, self._secure), self._transport) def _send_request(self, method, url, body=None, headers=None, timeout=None): p = urlparse(url) if p.hostname and p.hostname != self._host \ or p.scheme == "http" and self._secure \ or p.scheme == "https" and not self._secure \ or p.port and p.port != self._port: self.fire(NotConnected()) return resource = p.path if p.query: resource += "?" + p.query if headers is None: headers = Headers([]) else: headers = Headers([(k, v) for k, v in headers.items()]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if not headers.has_key("Host"): headers["Host"] = self._host \ + (":" + str(self._port)) if self._port else "" command = "%s %s HTTP/1.1" % (method, resource) if body is not None: headers["Content-Length"] = len(body) message = "%s\r\n%s" % (command, headers) self._outstanding += 1 if timeout is not None: self._timer = Timer(timeout, SocketError(ETIMEDOUT), self.channel) \ .register(self) self.fire(write(message.encode('utf-8')), self._transport) if body is not None: self.fire(write(body), self._transport) def _clear_timer(self): if self._timer is not None: self._timer.unregister() self._timer = None @handler("response") def _on_response(self, response): self._response = response self._outstanding -= 1 self._clear_timer() if response.headers.get("Connection") == "Close": self.fire(close(), self._transport) @handler("close") def close(self): self._clear_timer() if self._transport.connected: self.fire(close(), self._transport) @property def connected(self): return getattr(self._transport, "connected", False) \ if hasattr(self, "_transport") else False @property def response(self): return getattr(self, "_response", None)
class Client(BaseComponent): """ This is a variation of the Client class from circuits that fixes a problem with channel names and provides a slightly simplified interface that doesn't need explicit connect events. """ channel = "web" def __init__(self, url, channel=channel, timeout=-1): super(Client, self).__init__(channel=channel) self._host, self._port, self._resource, self._secure = parse_url(url) self._response = None self._transport = None self._outstanding = 0 self._pending = deque() self._timeout = None self._timer = None @handler("request") def request(self, event, method, url, body=None, headers={}, timeout=None): timeout = timeout or self._timeout if self._transport == None or not self._transport.connected: self._transport = TCPClient(channel=self.channel).register(self) HTTP(channel=self.channel).register(self._transport) self.fire(connect(self._host, self._port, self._secure), self._transport) self._pending.append((method, url, body, headers, timeout)) else: self._send_request(method, url, body, headers, timeout) @handler("connected") def _on_connected(self, host, port): if len(self._pending) > 0: args = self._pending.popleft() self._send_request(*args) @handler("disconnected") def _on_disconnected(self): if len(self._pending) > 0: self.fire(connect(self._host, self._port, self._secure), self._transport) def _send_request(self, method, url, body=None, headers={}, timeout=None): p = urlparse(url) if p.hostname and p.hostname != self._host \ or p.scheme == "http" and self._secure \ or p.scheme == "https" and not self._secure \ or p.port and p.port != self._port: self.fire(NotConnected()) return resource = p.path if p.query: resource += "?" + p.query headers = Headers([(k, v) for k, v in list(headers.items())]) # Clients MUST include Host header in HTTP/1.1 requests (RFC 2616) if "Host" not in headers: headers["Host"] = self._host \ + (":" + str(self._port)) if self._port else "" command = "%s %s HTTP/1.1" % (method, resource) if body is not None: headers["Content-Length"] = len(body) message = "%s\r\n%s" % (command, headers) self._outstanding += 1 if timeout is not None: self._timer = Timer(timeout, SocketError(ETIMEDOUT), self.channel) \ .register(self) self.fire(write(message.encode('utf-8')), self._transport) if body is not None: self.fire(write(body), self._transport) def _clear_timer(self): if self._timer is not None: self._timer.unregister() self._timer = None @handler("response") def _on_response(self, response): self._response = response self._outstanding -= 1 self._clear_timer() if response.headers.get("Connection") == "Close": self.fire(close(), self._transport) @handler("close") def close(self): self._clear_timer() if self._transport.connected: self.fire(close(), self._transport) @property def connected(self): return getattr(self._transport, "connected", False) \ if hasattr(self, "_transport") else False @property def response(self): return getattr(self, "_response", None)
class UPnPSubscription(BaseController): def __init__(self, callbacks, timeout, protocol): self._uuid = str(uuid4()) super(UPnPSubscription, self).__init__(channel="subs:" + self._uuid) self._callbacks = callbacks self._used_callback = 0 self._client = Client(self._callbacks[self._used_callback], self.channel).register(self) self._protocol = protocol self._seq = 0 if timeout > 0: self._expiry_timer = Timer \ (timeout, Event.create("upnp_subs_end"), self).register(self) @handler("registered") def _on_registered(self, component, parent): if component != self: return @handler("upnp_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 _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 = unicode(value) misc.set_ns_prefixes(root, { "": UPNP_EVENT_NS }) # Keep body as str for safe request handling body = "<?xml version='1.0' encoding='utf-8'?>" \ + ElementTree.tostring(root, encoding="utf-8") 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 @handler("upnp_subs_end") def _on_subs_end(self): self.unregister() self.fire(log(logging.DEBUG, "Subscribtion for " + str(self._callbacks) + " on " + self.parent.notification_channel + " cancelled"), "logger") @handler("upnp_subs_renewal") 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") @property def sid(self): return "uuid:" + self._uuid @classmethod def sid2chan(cls, sid): return "subs:" + sid[5:]
class DummyPlayer(providers.MediaPlayer): ''' classdocs ''' manifest = Manifest("Dummy Player", "CoCy Dummy Media Player") def __init__(self): super(DummyPlayer, self).__init__(self.manifest) self._timer = None def supportedMediaTypes(self): return [ "http-get:*:audio/mpeg:*", "http-get:*:audio/ogg:*", "http-get:*:audio/3gpp:*", "http-get:*:video/3gpp:*", "http-get:*:audio/3gpp2:*", "http-get:*:video/3gpp2:*" ] @handler("provider_updated") def _on_provider_updated_handler(self, provider, changed): if "source" in changed: if self.state == "PLAYING": if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) if "state" in changed: state = changed["state"] if state == "IDLE": if self._timer: self._timer.unregister() @handler("play", override=True) @combine_events def _on_play(self): if self.source is None or self.state == "PLAYING": return if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) self.state = "PLAYING" @handler("end_reached") def _on_end_reached(self, event): if self._timer: self._timer.unregister() self._timer = None self.fire(MediaPlayer.end_of_media()) @handler("seek", override=True) def _on_seek(self, position): if self.state != "PLAYING": return self._timer.unregister() self._timer = Timer(self.current_track_duration - position, end_reached()).register(self) def current_position(self): if self._timer is None: return None return self._current_track_duration - (self._timer.expiry - time.time())
class DummyPlayer(providers.MediaPlayer): ''' classdocs ''' manifest = Manifest("Dummy Player", "CoCy Dummy Media Player") def __init__(self): super(DummyPlayer, self).__init__(self.manifest) self._timer = None def supportedMediaTypes(self): return ["http-get:*:audio/mpeg:*", "http-get:*:audio/ogg:*", "http-get:*:audio/3gpp:*", "http-get:*:video/3gpp:*", "http-get:*:audio/3gpp2:*", "http-get:*:video/3gpp2:*"] @handler("provider_updated") def _on_provider_updated_handler(self, provider, changed): if "source" in changed: if self.state == "PLAYING": if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) if "state" in changed: state = changed["state"] if state == "IDLE": if self._timer: self._timer.unregister() @handler("play", override=True) @combine_events def _on_play(self): if self.source is None or self.state == "PLAYING": return if self._timer: self._timer.unregister() from cocy.upnp import DIDL_LITE_NS duration = self.source_meta_dom.find( str(QName(DIDL_LITE_NS, "item")) + "/" + str(QName(DIDL_LITE_NS, "res"))) \ .get("duration") self.current_track_duration = duration_to_secs(duration) self._timer = Timer(self.current_track_duration, end_reached()).register(self) self.state = "PLAYING" @handler("end_reached") def _on_end_reached(self, event): if self._timer: self._timer.unregister() self._timer = None self.fire(MediaPlayer.end_of_media()) @handler("seek", override=True) def _on_seek(self, position): if self.state != "PLAYING": return self._timer.unregister() self._timer = Timer(self.current_track_duration - position, end_reached()).register(self) def current_position(self): if self._timer is None: return None return self._current_track_duration - (self._timer.expiry - time.time())
def test_basic(self): timer = Timer(0.1, test(), "timer") timer.register(self.app) wait_for(self.app, "flag") self.app.reset()
def _on_seek(self, position): if self.state != "PLAYING": return self._timer.unregister() self._timer = Timer(self.current_track_duration - position, end_reached()).register(self)
class UPnPRootDevice(BaseComponent): def __init__(self, location, max_age, usn): super(UPnPRootDevice, self).__init__(channel=usn) self._location = location self._usn = usn self._ready = False self._comm_chan = "client." + usn self._client = Client(location, channel=self._comm_chan).register(self) @handler("response", channel=self._comm_chan) def _on_response(self, response): if response.status == http_client.OK: self._initialize(response.read()) self.addHandler(_on_response) @handler("error", channel=self._comm_chan) def _on_error(self, *args, **kwargs): self._client.close() self.unregister() self.addHandler(_on_error) self.fire(Request("GET", self._location), self._client) self._expiry_timer \ = Timer(max_age, UPnPDeviceByeBye(usn)).register(self) def _initialize(self, xml_src): data = XML(xml_src) self._friendly_name = data.findtext \ ("{%s}device/{%s}friendlyName" \ % (SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA)) icons = data.findall \ ("{%s}device/{%s}iconList/{%s}icon" \ % (SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA)) self._icons = [] for icon in icons: width = int(icon.findtext("{%s}width" % SSDP_DEVICE_SCHEMA)) height = int(icon.findtext("{%s}height" % SSDP_DEVICE_SCHEMA)) url = urljoin(self._location, icon.findtext("{%s}url" % SSDP_DEVICE_SCHEMA)) self._icons.append(IconInfo(width, height, url)) self._ready = True @handler("upnp_device_alive") def _on_device_alive \ (self, location, notification_type, max_age, server, usn): self._expiry_timer.interval = max_age self._expiry_timer.reset() @handler("upnp_device_bye_bye") def _on_device_bye_bye (self, usn): self._client.close() self.unregister() @property def usn(self): return getattr(self, "_usn", None) @property def location(self): return getattr(self, "_location", None) @property def ready(self): return getattr(self, "_ready", None) @property def friendly_name(self): return getattr(self, "_friendly_name", None) @property def icons(self): return copy(getattr(self, "_icons", None)) @property def valid_until(self): return self._expiry_timer._eTime \ if hasattr(self, "_expiry_timer") else None
def _on_seek(self, position): if self.state != "PLAYING": return self._timer.unregister() self._timer = Timer(self.current_track_duration - position, end_reached()).register(self)
class UPnPRootDevice(BaseComponent): def __init__(self, location, max_age, usn): super(UPnPRootDevice, self).__init__(channel=usn) self._location = location self._usn = usn self._ready = False self._comm_chan = "client." + usn self._client = Client(location, channel=self._comm_chan).register(self) @handler("response", channel=self._comm_chan) def _on_response(self, response): if response.status == httplib.OK: self._initialize(response.read()) self.addHandler(_on_response) @handler("error", channel=self._comm_chan) def _on_error(self, *args, **kwargs): self._client.close() self.unregister() self.addHandler(_on_error) self.fire(Request("GET", self._location), self._client) self._expiry_timer \ = Timer(max_age, UPnPDeviceByeBye(usn)).register(self) def _initialize(self, xml_src): data = XML(xml_src) self._friendly_name = data.findtext \ ("{%s}device/{%s}friendlyName" \ % (SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA)) icons = data.findall \ ("{%s}device/{%s}iconList/{%s}icon" \ % (SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA, SSDP_DEVICE_SCHEMA)) self._icons = [] for icon in icons: width = int(icon.findtext("{%s}width" % SSDP_DEVICE_SCHEMA)) height = int(icon.findtext("{%s}height" % SSDP_DEVICE_SCHEMA)) url = urljoin(self._location, icon.findtext("{%s}url" % SSDP_DEVICE_SCHEMA)) self._icons.append(IconInfo(width, height, url)) self._ready = True @handler("upnp_device_alive") def _on_device_alive \ (self, location, notification_type, max_age, server, usn): self._expiry_timer.interval = max_age self._expiry_timer.reset() @handler("upnp_device_bye_bye") def _on_device_bye_bye (self, usn): self._client.close() self.unregister() @property def usn(self): return getattr(self, "_usn", None) @property def location(self): return getattr(self, "_location", None) @property def ready(self): return getattr(self, "_ready", None) @property def friendly_name(self): return getattr(self, "_friendly_name", None) @property def icons(self): return copy(getattr(self, "_icons", None)) @property def valid_until(self): return self._expiry_timer._eTime \ if hasattr(self, "_expiry_timer") else None