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

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

# Copyright (C) 2009  Internet Systems Consortium. 

# 

# Permission to use, copy, modify, and distribute this software for any 

# purpose with or without fee is hereby granted, provided that the above 

# copyright notice and this permission notice appear in all copies. 

# 

# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM 

# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL 

# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 

# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, 

# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING 

# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 

# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 

# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 

 

"""This module holds classes representing modules, commands and 

   parameters for use in bindctl""" 

 

import textwrap 

 

try: 

    from collections import OrderedDict 

except ImportError: 

    from bindctl.mycollections import OrderedDict 

 

# Define value type 

STRING_TYPE = "string" 

LIST_TYPE = "list" 

INT_TYPE = "int" 

 

MODULE_NODE_NAME = 'module' 

COMMAND_NODE_NAME = 'command' 

PARAM_NODE_NAME = 'param' 

 

# this is used to align the descriptions in help output 

CONST_BINDCTL_HELP_INDENT_WIDTH=12 

 

 

class ParamInfo: 

    """One parameter of one command. 

    Each command parameter has five attributes: 

    parameter name, parameter type, parameter value, 

    parameter description and paramter's spec(got from 

    module spec file).  

    """ 

    def __init__(self, name, desc = '', type = STRING_TYPE, 

                 optional = False, value = '', default_value = '', 

                 param_spec = None): 

        self.name = name 

        self.type = type 

        self.value = value 

        self.default_value = default_value 

        self.desc = desc 

        self.is_optional = optional 

        self.param_spec = param_spec 

 

    def __str__(self): 

        return str("\t%s <type: %s> \t(%s)" % (self.name, self.type, self.desc)) 

 

    def get_basic_info(self): 

        if self.is_optional: 

            opt_str = "optional" 

        else: 

            opt_str = "mandatory" 

        return "%s (%s, %s)" % (self.name, self.type, opt_str) 

 

    def get_desc(self): 

        return self.desc 

 

class CommandInfo: 

    """One command which is provided by one bind10 module, it has zero 

       or more parameters 

    """ 

 

    def __init__(self, name, desc = ""): 

        self.name = name 

        self.desc = desc 

        self.params = OrderedDict() 

        # Set default parameter "help" 

        self.add_param(ParamInfo("help", 

                                  desc = "Get help for command.", 

                                  optional = True)) 

 

    def __str__(self): 

        return str("%s \t(%s)" % (self.name, self.desc)) 

 

    def get_name(self): 

        return self.name 

 

    def get_desc(self): 

        return self.desc; 

 

    def add_param(self, paraminfo): 

        """Add a ParamInfo object to this CommandInfo""" 

        self.params[paraminfo.name] = paraminfo 

 

 

    def has_param_with_name(self, param_name): 

        """Returns true if the parameter with param_name exists""" 

        return param_name in self.params 

 

 

    def get_param_with_name(self, param_name): 

        """Returns the ParamInfo with the given name. Raises a 

           KeyError if it doesn't exist""" 

        return self.params[param_name] 

 

 

    def get_params(self): 

        """Returns a list of all ParamInfo objects for this CommandInfo""" 

        return list(self.params.values()) 

 

 

    def get_param_names(self): 

        """Returns a list of the names of all parameters for this command""" 

        return list(self.params.keys()) 

 

 

    def get_mandatory_param_names(self): 

        """Returns a list of the names of all mandatory parameters for 

           this command""" 

        all_names = self.params.keys() 

        return [name for name in all_names 

                if not self.params[name].is_optional] 

 

    def get_param_name_by_position(self, pos, param_count): 

        """ 

        Find a proper parameter name for the position 'pos': 

        If param_count is equal to the count of mandatory parameters of command, 

        and there is some optional parameter, find the first mandatory parameter  

        from the position 'pos' to the end. Else, return the name on position pos. 

        (This function will be changed if bindctl command line syntax is changed 

        in the future. ) 

        """ 

136        if type(pos) != int: 

            raise KeyError(str(pos) + " is not an integer") 

 

        else: 

            params = self.params.copy() 

            del params['help'] 

            count = len(params) 

            if (pos >= count): 

                raise KeyError(str(pos) + " out of range") 

 

            mandatory_count = len(self.get_mandatory_param_names()) 

            param_names = list(params.keys()) 

            if (param_count == mandatory_count) and (param_count < count): 

153                while pos < count: 

                    if not params[param_names[pos]].is_optional: 

                        return param_names[pos] 

                    pos += 1 

 

                raise KeyError(str(pos) + "parameters have error") 

            else: 

                return param_names[pos] 

 

 

    def command_help(self): 

        """Prints the help info for this command to stdout""" 

        print("Command ", self) 

        print("\t\thelp (Get help for command)") 

 

        params = self.params.copy() 

        del params["help"] 

 

        if len(params) == 0: 

            print("This command has no parameters") 

            return 

 

        print("Parameters:") 

        for info in params.values(): 

            print("    %s" % info.get_basic_info()) 

            description = info.get_desc() 

            if description != "": 

                print(textwrap.fill(description, 

                      initial_indent="        ", 

                      subsequent_indent="        ", 

                      width=70)) 

 

class ModuleInfo: 

    """Define the information of one module, include module name,  

    module supporting commands. 

    """ 

 

    def __init__(self, name, desc = ""): 

        self.name = name 

        self.desc = desc 

        self.commands = OrderedDict() 

        self.add_command(CommandInfo(name = "help", 

                                     desc = "Get help for module.")) 

 

    def __str__(self): 

        return str("%s \t%s" % (self.name, self.desc)) 

 

    def get_name(self): 

        return self.name 

 

    def get_desc(self): 

        return self.desc 

 

    def add_command(self, command_info): 

        """Add a CommandInfo to this ModuleInfo.""" 

        self.commands[command_info.name] = command_info 

 

    def has_command_with_name(self, command_name): 

        """Returns true if this module has a command with the given name.""" 

        return command_name in self.commands 

 

    def get_command_with_name(self, command_name): 

        """Returns the CommandInfo for the command with the given name. 

           Raises a KeyError if not found""" 

        return self.commands[command_name] 

 

    def get_commands(self): 

        """Returns a list of all CommandInfo objects for this module.""" 

        return list(self.commands.values()) 

 

    def get_command_names(self): 

        """Returns a list of the names of all commands for this module.""" 

        return list(self.commands.keys()) 

 

    def module_help(self): 

        """Prints the help info for this module to stdout""" 

        print("Module ", self, "\nAvailable commands:") 

        for k in self.commands.values(): 

            n = k.get_name() 

            if len(n) >= CONST_BINDCTL_HELP_INDENT_WIDTH: 

                print("    %s" % n) 

                print(textwrap.fill(k.get_desc(), 

                      initial_indent="            ", 

                      subsequent_indent="    " + 

                      " " * CONST_BINDCTL_HELP_INDENT_WIDTH, 

                      width=70)) 

            else: 

                print(textwrap.fill("%s%s%s" % 

                    (k.get_name(), 

                     " "*(CONST_BINDCTL_HELP_INDENT_WIDTH - len(k.get_name())), 

                     k.get_desc()), 

                    initial_indent="    ", 

                    subsequent_indent="    " + 

                    " " * CONST_BINDCTL_HELP_INDENT_WIDTH, 

                    width=70)) 

 

    def command_help(self, command): 

        """Prints the help info for the command with the given name. 

           Raises KeyError if not found""" 

        self.commands[command].command_help()