# Licensed under the MIT license
# http://opensource.org/licenses/mit-license.php
# Copyright (C) 2006 Fluendo, S.A. (www.fluendo.com).
# Copyright 2006,2007,2008,2009 Frank Scholz <coherence@beebits.net>
from twisted.python.util import OrderedDict
from coherence import log
[docs]class Argument:
def __init__(self, name, direction, state_variable):
self.name = name
self.direction = direction
self.state_variable = state_variable
[docs] def get_name(self):
return self.name
[docs] def get_direction(self):
return self.direction
[docs] def get_state_variable(self):
return self.state_variable
def __repr__(self):
return "Argument: %s, %s, %s" % (self.get_name(),
self.get_direction(),
self.get_state_variable())
[docs] def as_tuples(self):
r = []
r.append(('Name', self.name))
r.append(('Direction', self.direction))
r.append(('Related State Variable', self.state_variable))
return r
[docs] def as_dict(self):
return {'name': self.name, 'direction': self.direction,
'related_state_variable': self.state_variable}
[docs]class Action(log.LogAble):
logCategory = 'action'
def __init__(self, service, name, implementation, arguments_list):
log.LogAble.__init__(self)
self.service = service
self.name = name
self.implementation = implementation
self.arguments_list = arguments_list
[docs] def _get_client(self):
client = self.service._get_client(self.name)
return client
[docs] def get_name(self):
return self.name
[docs] def get_implementation(self):
return self.implementation
[docs] def get_arguments_list(self):
return self.arguments_list
[docs] def get_in_arguments(self):
return [arg for arg in self.arguments_list if
arg.get_direction() == 'in']
[docs] def get_out_arguments(self):
return [arg for arg in self.arguments_list if
arg.get_direction() == 'out']
[docs] def get_service(self):
return self.service
[docs] def set_callback(self, callback):
self.callback = callback
[docs] def get_callback(self):
try:
return self.callback
except AttributeError:
return None
[docs] def call(self, *args, **kwargs):
self.info("calling %s", self.name)
in_arguments = self.get_in_arguments()
self.info("in arguments %s", [a.get_name() for a in in_arguments])
instance_id = 0
for arg_name, arg in kwargs.items():
al = [a for a in in_arguments if arg_name == a.get_name()]
if len(al) > 0:
in_arguments.remove(al[0])
else:
self.error("argument %s not valid for action %s", arg_name,
self.name)
return
if arg_name == 'InstanceID':
instance_id = int(arg)
if len(in_arguments) > 0:
self.error("argument %s missing for action %s",
[a.get_name() for a in in_arguments], self.name)
return
action_name = self.name
if (hasattr(self.service.device.client, 'overlay_actions') and
self.name in self.service.device.client.overlay_actions):
self.info("we have an overlay method %r for action %r",
self.service.device.client.overlay_actions[self.name],
self.name)
action_name, kwargs = self.service.device.client.overlay_actions[
self.name](**kwargs)
self.info("changing action to %r %r", action_name, kwargs)
def got_error(failure):
self.warning("error on %s request with %s %s", self.name, self.
service.service_type,
self.service.control_url)
self.info(failure)
return failure
if hasattr(self.service.device.client, 'overlay_headers'):
self.info("action call has headers %r", 'headers' in kwargs)
if 'headers' in kwargs:
kwargs['headers'].update(
self.service.device.client.overlay_headers)
else:
kwargs['headers'] = self.service.device.client.overlay_headers
self.info("action call with new/updated headers %r",
kwargs['headers'])
client = self._get_client()
ordered_arguments = OrderedDict()
for argument in self.get_in_arguments():
ordered_arguments[argument.name] = kwargs[argument.name]
if 'headers' in kwargs:
ordered_arguments['headers'] = kwargs['headers']
d = client.callRemote(action_name, ordered_arguments)
d.addCallback(self.got_results, instance_id=instance_id,
name=action_name)
d.addErrback(got_error)
return d
[docs] def got_results(self, results, instance_id, name):
instance_id = int(instance_id)
out_arguments = self.get_out_arguments()
self.info("call %s (instance %d) returns %d arguments: %r", name,
instance_id,
len(out_arguments),
results)
# XXX A_ARG_TYPE_ arguments probably don't need a variable update
# if len(out_arguments) == 1:
# self.service.get_state_variable(
# out_arguments[0].get_state_variable(),
# instance_id).update(results)
# elif len(out_arguments) > 1:
if len(out_arguments) > 0:
for arg_name, value in list(results.items()):
state_variable_name = \
[a.get_state_variable() for a in out_arguments if
a.get_name() == arg_name]
self.service.get_state_variable(
state_variable_name[0], instance_id).update(value)
return results
def __repr__(self):
return "Action: %s [%s], (%s args)" % \
(self.get_name(), self.get_implementation(),
len(self.get_arguments_list()))
[docs] def as_tuples(self):
r = []
r.append(('Name', self.get_name()))
r.append(("Number of 'in' arguments", len(self.get_in_arguments())))
r.append(("Number of 'out' arguments", len(self.get_out_arguments())))
return r
[docs] def as_dict(self):
return {'name': self.get_name(),
'arguments': [a.as_dict() for a in self.arguments_list]}