Beispiel #1
0
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())
Beispiel #2
0
 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()
Beispiel #3
0
    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)
Beispiel #4
0
 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()
Beispiel #5
0
    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
Beispiel #7
0
 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)
Beispiel #9
0
 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)
Beispiel #11
0
 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)
Beispiel #12
0
 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
Beispiel #13
0
    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)
Beispiel #14
0
 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)
Beispiel #15
0
 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()
Beispiel #16
0
 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
Beispiel #18
0
 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)
Beispiel #19
0
 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)
Beispiel #20
0
 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"
Beispiel #21
0
    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()
Beispiel #22
0
 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()
Beispiel #23
0
 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)
Beispiel #24
0
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:]
Beispiel #25
0
 def test_basic(self):
     timer = Timer(0.1, test(), "timer")
     timer.register(self.app)
     wait_for(self.app, "flag")
     self.app.reset()
Beispiel #26
0
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)
Beispiel #27
0
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)
Beispiel #28
0
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:]
Beispiel #29
0
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())
Beispiel #30
0
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())
Beispiel #31
0
 def test_basic(self):
     timer = Timer(0.1, test(), "timer")
     timer.register(self.app)
     wait_for(self.app, "flag")
     self.app.reset()
Beispiel #32
0
 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)
Beispiel #33
0
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
        
Beispiel #34
0
 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)
Beispiel #35
0
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