-
Notifications
You must be signed in to change notification settings - Fork 1
/
tells.py
163 lines (131 loc) · 6.1 KB
/
tells.py
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
#!/usr/bin/env python
#-*- coding:utf-8 -*-
"""
Module to include a basic tell parsing functionality. As usually, it defines
the a register and unregister tell handlers.
"""
import os
import re
class PrivateTells(object):
def __init__(self, icsbot=None, tell_logger=None, help_command='help'):
"""Initialize Tells class with icsbot instance.
(command_string, execution_function, priviledge_check=lambda *arg: True)
Unregistering works via the command_string.
Note:
o The priviledge function will make a command invisible for all
not allowed to use it.
o If there is not helpfile for a command in the helpfile folder,
the documentation of that function is used instead if it exists.
In this case the priviledge of the user is checked as well!
IMPORTANT: For correct printing the documentation must fullfill
the Docstring Conventions for good printing. (in owther
words, the last line is used to determine the size of
indent)
For now no alias support, but of course completion.
The class defines the two commands:
o help -> get a helpfile from the help folder.
o =commands -> list all commands available to a person.
"""
self._registered = {'=commands': (self._listcommands, lambda *arg: True),
help_command: (self._help, lambda *arg: True),
'next': (self._next, lambda *arg: True)}
self.help_command = help_command
self.tell_logger = tell_logger
self._icsbot = icsbot
self._users = self._icsbot['users']
import misc.regex as reg
regex = '^(?P<handle>%s)(?P<tags>%s)? tells you: (?P<message>.*)$' % (reg.HANDLE, reg.TAGS)
self._icsbot.reg_comm(regex, self)
self.qtell = self._icsbot.qtell
def __call__(self, match):
"""
Call the instance with the mach object.
"""
usr = self._users[match.group('handle')]
tags = match.group('tags')
# Get the message and strip it and split of the first argument.
mess = match.group('message').strip().split(None, 1)
if self.tell_logger is not None:
self.tell_logger('%s%s tells you: %s\n' % (usr, tags, match.group('message')))
comm = mess[0].lower()
if len(mess) == 2:
args = mess[1]
else:
args = ''
#if len(comm) == 1:
# return self.qtell.split(usr, 'A command must be more then one character long.')
matches = []
for (c, v) in self._registered.items():
f, p = v
if c.startswith(comm) and p(usr, tags):
if c == comm:
matches = [(c, f)]
continue
matches += [(c, f)]
if len(matches) > 1:
to_tell = 'The following commands all match your input:\n'+'\n'.join((c for c, f in matches))
return self.qtell.split(usr, to_tell)
elif len(matches) == 0:
return self.qtell.split(usr, 'No corresponding command found. Please use'\
' the =commands command to get a list of '\
'all commands that are available to you. '\
'Or try the helpfiles (%s command).' % self.help_command)
return matches[0][1](usr, args, tags)
def register(self, command_str, function, priv=lambda *arg: True):
"""Register a function to be executed when the command_str fits.
register(string, function, [check]), where function is the
actual command, and check is a function to check wether a user
is allowed to use the command. Gets:
function(user, arguments, tags)
check(user)
Where tags is just a string so that handle+tags looks like it should.
"""
self._registered[command_str.lower()] = (function, priv)
def decorate(self, command_str, priv=lambda *arg: True):
def newfunc(func):
self.register(command_str, func, priv)
return func
return newfunc
def _listcommands(self, usr, args, tags):
"""=commands lists all commands available to you."""
commands = []
for (c, v) in self._registered.items():
f, p = v
if p(usr, tags):
commands += [c]
commands.sort()
to_tell = 'The following commands are accesseble for you:\n' + '\n'.join(commands)
return self.qtell.split(usr, to_tell)
def _help(self, usr, args, tags):
"""Prints a helpfile.
EXAMPLES:
o help
o help =commands
o help help
"""
args = args.strip()
if not args:
h = 'help_overview'
else:
h = args.split(None, 1)[0].lower()
try:
if os.path.sep in h:
# We can't have users use ../, etc, just act as if the file
# does not exist, may the user think it wroked, ha!
raise IOError
help_file = file('help'+os.path.sep+'%s.txt' % h)
except IOError:
if h in self._registered:
if self._registered[h][0].__doc__ and self._registered[h][1](usr, tags):
s = self._registered[h][0].__doc__
res = re.findall(re.compile('(\n\s*).*$'), s)
if res:
s = s.replace(res[0], '\n')
return self.qtell.split(usr, s.rstrip())
return self.qtell.split(usr, 'Helpfile "%s" was not found' % h)
help_text = help_file.read()
return self.qtell.split(usr, help_text, transliterate=True)
def _next(self, usr, args, tags):
"""The next command prints the next page for long output.
"""
return self.qtell.send(usr)