1
### This file is part of KoFooBot and is licensed under BSD-license according to the   ###
2
### LICENSE file in the base directory.                                                ###
3
### Code in this file is contributed by:                                               ###
4
###    Krister Svanlund <krister.svanlund gmail.com>                                   ###
5
6
import irclib
7
import re
8
9
do_help_command = {'description': "Display this help or help for specific commands",
10
                   'arguments': [("", "Display general help and list commands availible to your level."),
11
                                 ("<command>", "Display help for a specific command."),
12
                                 ("commands", "Display a list of commands without description."),
13
                                 ("alias", "List all aliases currently inplace."),
14
                                 ("modules", "List all modules that are loaded and that can be loaded.")],
15
                   'public': False,
16
                   'level': 0}
17
18
def do_help(self, server, sender, target, args):
19
    print "Show help to %s." % irclib.nm_to_n(sender)
20
    sender_level = self.get_level(sender)
21
    if args:
22
        for command in args:
23
            m = re.match(r'level=([0-9]+)', command)
24
            if m:
25
                args.remove(m.group(0))
26
                try: sender_level = min(int(m.group(1)), sender_level)
27
                except: sender_level = 0
28
                print " + Showing help for level %d." % sender_level
29
    if args:
30
        for command in args:
31
            do_help_for(self, server, sender, target, command, sender_level)
32
    else:
33
        do_general_help(self, server, sender, target, sender_level)
34
    return True
35
36
def do_help_for(self, server, sender, target, command_name, sender_level):
37
    print "%s wants help for '%s'." % (irclib.nm_to_n(sender), command_name)
38
    if command_name in self.globals.bot_commands:
39
        command = self.globals.bot_commands[command_name]
40
        command_level = command.get('level', 0)
41
        command_description = command.get('long help', "")
42
        command_arguments = command.get('arguments', [])
43
        help_string = "Help for command \x02{0}\x02\n".format(command_name)
44
        if sender_level < command_level:
45
            self.respond(server, sender, target, "You are not allowed to use this command.")
46
            return
47
        if not type(command_arguments) is list:
48
            command_arguments = [command_arguments]
49
        if len(command_arguments) > 0:
50
            width = []
51
            for argument in command_arguments:
52
                if type(argument) is not tuple:
53
                    width.append(len(argument))
54
                else:
55
                    width.append(len(argument[0]))
56
            if width: width = max(width)
57
            else: width = 0
58
            for argument in command_arguments:
59
                if type(argument) is tuple:
60
                    help_string += " \x02Syntax:\x02 {0:{2}}  -  {1}\n".format(command_name+' '+argument[0], argument[1], width)
61
                else:
62
                    help_string += " \x02Syntax:\x02 {0} {1}\n".format(command_name, argument)
63
        else:
64
            help_string += " \x02Syntax:\x02 {0}\n".format(command_name)
65
        if command_description:
66
            help_string += " \x02Description:\x02 {0}\n".format(command_description)
67
        if command_level:
68
            help_string += " \x02Minimum level:\x02 {0}\n".format(command_level)
69
        self.respond(server, sender, target, help_string)
70
    elif command_name == 'alias':
71
        help_string = "Aliases defined at this point is\n"
72
        for alias, command in self.globals.bot_command_alias.iteritems():
73
            help_string += " \x02{0}\x02 -> {1}\n".format(alias, command)
74
        help_string += "End of alias list."
75
        self.respond(server, sender, target, help_string)
76
    elif command_name == 'modules':
77
        help_string = "The following modules are currently loaded: %s" % ", ".join(self.module_list)
78
        help_string += "\nThe following modules can be loaded: %s" % ", ".join([m for m in self.found_modules if m not in self.module_list])
79
        self.respond(server, sender, target, help_string)
80
    elif command_name == 'commands':
81
        commands = []
82
        for command_name, command in self.globals.bot_commands.iteritems():
83
            command_level = command.get('level', 0)
84
            if sender_level >= command_level:
85
                commands.append(command_name)
86
        help_string = "The following commands are available: %s" % ", ".join(commands)
87
        self.respond(server, sender, target, help_string)
88
    else:
89
        self.respond(server, sender, target, "There is no \x02%s\x02 command." % command_name)
90
91
def get_first(tos):
92
    if type(tos) is tuple or type(tos) is list:
93
        return tos[0]
94
    else:
95
        return tos
96
        
97
def do_general_help(self, server, sender, target, sender_level):
98
    help_string = "The commands availible are:\n"
99
    width = []
100
    print " + Figure out width."
101
    for cn, c in self.globals.bot_commands.iteritems():
102
        alw = []
103
        al = c.get('arguments', ())
104
        if type(al) is not list: al = [al]
105
        for a in al:
106
            if a:
107
                if type(a) is not tuple: a = (a, "")
108
                alw.append(len(a[0]))
109
        if alw: width.append(len(cn)+max(alw)+3)
110
        else: width.append(len(cn))
111
    if width: width = max(width)
112
    else: width = 0
113
    print "  + Width is %d." % width
114
115
    for command_name, command in self.globals.bot_commands.iteritems():
116
        command_arguments = command.get('arguments', "")
117
        if not type(command_arguments) is list:
118
            command_arguments = [command_arguments]
119
        for argument in command_arguments:
120
            command_level = command.get('level', 0)
121
            if type(argument) is tuple:
122
                command_description = argument[1]
123
                argument = argument[0]
124
            else:
125
                command_description = command.get('description', "")
126
            if command_description == "":
127
                continue
128
            command_public = command.get('public', False)
129
            if sender_level >= command_level:
130
                # Ex: *name arguments             description (>level)
131
                #     ^ ^       ^                                 ^-Minimum level to use command
132
                #     | |       |-Arguments for command
133
                #     | |-Command name
134
                #     |-Public command indicator
135
                help_string += "{public}{namearg:{width}} - {description} {level}\n".format(\
136
                    width = width,
137
                    public = (' ', '*')[command_public],
138
                    namearg = "\x02{0}\x02 {1}".format(command_name, argument),
139
                    description = command_description,
140
                    level = ('(>'+str(command_level)+')', '')[command_level is 0])
141
    help_string += "To see help for specific commands use \x02help command\x02."
142
    self.respond(server, sender, target, help_string)