Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

# 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 

 

 

class Argument: 

 

    def __init__(self, name, direction, state_variable): 

        self.name = name 

        self.direction = direction 

        self.state_variable = state_variable 

 

    def get_name(self): 

        return self.name 

 

    def get_direction(self): 

        return self.direction 

 

    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()) 

 

    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 

 

    def as_dict(self): 

        return {'name': self.name, 'direction': self.direction, 

                'related_state_variable': self.state_variable} 

 

 

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 

 

    def _get_client(self): 

        client = self.service._get_client(self.name) 

        return client 

 

    def get_name(self): 

        return self.name 

 

    def get_implementation(self): 

        return self.implementation 

 

    def get_arguments_list(self): 

        return self.arguments_list 

 

    def get_in_arguments(self): 

        return [arg for arg in self.arguments_list if 

                arg.get_direction() == 'in'] 

 

    def get_out_arguments(self): 

        return [arg for arg in self.arguments_list if 

                arg.get_direction() == 'out'] 

 

    def get_service(self): 

        return self.service 

 

    def set_callback(self, callback): 

        self.callback = callback 

 

    def get_callback(self): 

        try: 

            return self.callback 

        except AttributeError: 

            return None 

 

    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 

 

    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())) 

 

    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 

 

    def as_dict(self): 

        return {'name': self.get_name(), 

                'arguments': [a.as_dict() for a in self.arguments_list]}