Ejemplo n.º 1
0
    def __init__(self):
        self.__class__.stateVariables = Lict(self.__class__.stateVariables)

        for name, arguments in self.__class__.actions.items():
            self.__class__.actions[name] = Lict(arguments)

        # Build action function map
        self.actionFunctions = {}
        for attr in dir(self):
            obj = getattr(self, attr)
            if callable(obj) and hasattr(obj, 'actionName'):
                setattr(self, attr, ServiceActionWrapper(self, obj))
                self.actionFunctions[getattr(obj, 'actionName')] = obj

        self.subscriptions = Lict(searchNames='sid')
        if self.event_properties is None:
            self.event_properties = Lict(searchNames='name')
Ejemplo n.º 2
0
    def _instance_initialize(self, instance):
        if not hasattr(instance, 'stateVariables'):
            raise TypeError()

        if self.name not in instance.stateVariables:
            raise KeyError()

        if not instance.stateVariables[self.name].sendEvents:
            raise ValueError()

        self.instance = instance
        self.state_variable = instance.stateVariables[self.name]

        if self.instance.event_properties is None:
            self.instance.event_properties = Lict(searchNames='name')
        self.instance.event_properties.append(self)

        self.initialized = True

        if self.value is None:
            self.value = self._default()
Ejemplo n.º 3
0
    def __init__(self):
        self.__class__.stateVariables = Lict(self.__class__.stateVariables)

        for name, arguments in self.__class__.actions.items():
            self.__class__.actions[name] = Lict(arguments)

        # Build action function map
        self.actionFunctions = {}
        for attr in dir(self):
            obj = getattr(self, attr)
            if callable(obj) and hasattr(obj, 'actionName'):
                setattr(self, attr, ServiceActionWrapper(self, obj))
                self.actionFunctions[getattr(obj, 'actionName')] = obj

        self.subscriptions = Lict(searchNames='sid')
        if self.event_properties is None:
            self.event_properties = Lict(searchNames='name')
Ejemplo n.º 4
0
class Service(object):
    version = (1, 0)
    serviceType = None
    serviceId = None

    actions = {}
    stateVariables = {}

    event_properties = None
    subscription_timeout_range = (1800, None)

    _description = None

    def __init__(self):
        self.__class__.stateVariables = Lict(self.__class__.stateVariables)

        for name, arguments in self.__class__.actions.items():
            self.__class__.actions[name] = Lict(arguments)

        # Build action function map
        self.actionFunctions = {}
        for attr in dir(self):
            obj = getattr(self, attr)
            if callable(obj) and hasattr(obj, 'actionName'):
                setattr(self, attr, ServiceActionWrapper(self, obj))
                self.actionFunctions[getattr(obj, 'actionName')] = obj

        self.subscriptions = Lict(searchNames='sid')
        if self.event_properties is None:
            self.event_properties = Lict(searchNames='name')

    def _generate_subscription_sid(self):
        result = None
        retries = 0
        while result is None and retries < 10:
            generated_uuid = str(uuid.uuid4())
            if generated_uuid not in self.subscriptions:
                result = generated_uuid
            else:
                retries += 1
        if result is None:
            raise Exception()
        return result

    def subscribe(self, callback, timeout):
        sid = 'uuid:' + self._generate_subscription_sid()

        if (self.subscription_timeout_range[0] is not None
                and timeout < self.subscription_timeout_range[0]):
            timeout = self.subscription_timeout_range[0]

        if (self.subscription_timeout_range[1] is not None
                and timeout > self.subscription_timeout_range[1]):
            timeout = self.subscription_timeout_range[1]

        subscription = EventSubscription(sid, callback, timeout)

        # Send initial event property notifications
        # TODO: calling this in 1 second isn't really a great way to do this
        reactor.callLater(1, subscription.notify,
                          self.event_properties.values())

        self.subscriptions.append(subscription)

        return {'SID': sid, 'TIMEOUT': 'Second-' + str(timeout)}

    def notify(self, prop):
        for sid in self.subscriptions.keys():
            subscription = self.subscriptions[sid]
            if subscription.expired:
                self.subscriptions.popvalue(sid)
            else:
                subscription.notify(prop)

    def dump(self):
        Logr.debug("xml tree dumped")
        scpd = et.Element('scpd',
                          attrib={
                              'xmlns': 'urn:schemas-upnp-org:service-1-0',
                          })

        # specVersion
        specVersion = et.Element('specVersion')
        specVersion.append(make_element('major', str(self.version[0])))
        specVersion.append(make_element('minor', str(self.version[1])))
        scpd.append(specVersion)

        # actionList
        actionList = et.Element('actionList')
        for action_name, action_args in self.actions.items():
            action = et.Element('action')
            action.append(make_element('name', action_name))

            argumentList = et.Element('argumentList')
            for arg in action_args:
                argumentList.append(arg.dump())
            action.append(argumentList)

            actionList.append(action)
        scpd.append(actionList)

        # serviceStateTable
        serviceStateTable = et.Element('serviceStateTable')
        for stateVariable in self.stateVariables.values():
            serviceStateTable.append(stateVariable.dump())
        scpd.append(serviceStateTable)

        return scpd

    def dumps(self, force=False):
        if self.__class__._description is None or force:
            self.__class__._description = '<?xml version="1.0" encoding="utf-8"?>' + \
                                          et.tostring(self.dump())
        return self.__class__._description
Ejemplo n.º 5
0
class Service(object):
    version = (1, 0)
    serviceType = None
    serviceId = None

    actions = {}
    stateVariables = {}

    event_properties = None
    subscription_timeout_range = (1800, None)

    _description = None

    def __init__(self):
        self.__class__.stateVariables = Lict(self.__class__.stateVariables)

        for name, arguments in self.__class__.actions.items():
            self.__class__.actions[name] = Lict(arguments)

        # Build action function map
        self.actionFunctions = {}
        for attr in dir(self):
            obj = getattr(self, attr)
            if callable(obj) and hasattr(obj, 'actionName'):
                setattr(self, attr, ServiceActionWrapper(self, obj))
                self.actionFunctions[getattr(obj, 'actionName')] = obj

        self.subscriptions = Lict(searchNames='sid')
        if self.event_properties is None:
            self.event_properties = Lict(searchNames='name')

    def _generate_subscription_sid(self):
        result = None
        retries = 0
        while result is None and retries < 10:
            generated_uuid = str(uuid.uuid4())
            if generated_uuid not in self.subscriptions:
                result = generated_uuid
            else:
                retries += 1
        if result is None:
            raise Exception()
        return result

    def subscribe(self, callback, timeout):
        sid = 'uuid:' + self._generate_subscription_sid()

        if (self.subscription_timeout_range[0] is not None and
                timeout < self.subscription_timeout_range[0]):
            timeout = self.subscription_timeout_range[0]

        if (self.subscription_timeout_range[1] is not None and
                timeout > self.subscription_timeout_range[1]):
            timeout = self.subscription_timeout_range[1]

        subscription = EventSubscription(sid, callback, timeout)

        # Send initial event property notifications
        # TODO: calling this in 1 second isn't really a great way to do this
        reactor.callLater(1, subscription.notify, self.event_properties.values())

        self.subscriptions.append(subscription)

        return {
            'SID': sid,
            'TIMEOUT': 'Second-' + str(timeout)
        }

    def notify(self, prop):
        for sid in self.subscriptions.keys():
            subscription = self.subscriptions[sid]
            if subscription.expired:
                self.subscriptions.popvalue(sid)
            else:
                subscription.notify(prop)

    def dump(self):
        Logr.debug("xml tree dumped")
        scpd = et.Element('scpd', attrib={
            'xmlns': 'urn:schemas-upnp-org:service-1-0',
        })

        # specVersion
        specVersion = et.Element('specVersion')
        specVersion.append(make_element('major', str(self.version[0])))
        specVersion.append(make_element('minor', str(self.version[1])))
        scpd.append(specVersion)

        # actionList
        actionList = et.Element('actionList')
        for action_name, action_args in self.actions.items():
            action = et.Element('action')
            action.append(make_element('name', action_name))

            argumentList = et.Element('argumentList')
            for arg in action_args:
                argumentList.append(arg.dump())
            action.append(argumentList)

            actionList.append(action)
        scpd.append(actionList)

        # serviceStateTable
        serviceStateTable = et.Element('serviceStateTable')
        for stateVariable in self.stateVariables.values():
            serviceStateTable.append(stateVariable.dump())
        scpd.append(serviceStateTable)

        return scpd

    def dumps(self, force=False):
        if self.__class__._description is None or force:
            self.__class__._description = '<?xml version="1.0" encoding="utf-8"?>' + \
                                          et.tostring(self.dump())
        return self.__class__._description