forked from lilydjwg/xmpptalk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmessages.py
160 lines (138 loc) · 4.88 KB
/
messages.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
#
# (C) Copyright 2012 lilydjwg <[email protected]>
#
# This file is part of xmpptalk.
#
# xmpptalk is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# xmpptalk is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with xmpptalk. If not, see <http://www.gnu.org/licenses/>.
#
import logging
from functools import wraps
import datetime
import commands
import config
import models
from models import logmsg
from misc import *
'''message handling
This module supports extending by the following means:
It will try to get two iterables from the plugin package with the names
`message_plugin_early` and `message_plugin`. Each message handler in
`message_plugin_early` will be executed *before* standard handling, and those in
`message_plugin` will be executed *after* standard handling.
Message handlers accept two argument: the bot itself and the message string.
If the handler returns `True`, no further actions are done; if `str`, it's
the new message that will be handled later.
'''
logger = logging.getLogger(__name__)
_message_handles = []
def message_handler_register(func):
'''register a message handler
use a register func instead of decorator so that it's easier to (re-)order
the handlers'''
_message_handles.append(func)
def pingpong(self, msg):
'''availability test'''
if msg == 'ping':
self.reply('pong at ' + \
(self.now+config.timezoneoffset).strftime(longdateformat))
self.user_reset_stop()
return True
return False
def command(self, msg):
return commands.handle_command(self, msg)
def filter_otr(self, msg):
if msg.startswith('?OTR'):
self.reply(_('Your client is trying OTR encryption, which is not supported by this group.'))
return True
else:
return False
def give_help(self, msg):
'''special handling for help messages'''
if config.help_regex.match(msg):
return commands.handle_command(self, 'help')
else:
return False
def check_auth(self, msg):
'''check if the user has joined or not'''
bare = self.current_jid.bare()
subscribers = [x.jid for x in self.roster if x.subscription == 'both']
if bare in subscribers:
return False
if config.private:
self.reply(_('You are not allowed to send messages to this group until invited'))
else:
self.reply(_('You are currently not joined in this group, message ignored'))
self.xmpp_add_user(bare)
return True
class MessageMixin:
def handle_message(self, msg, timestamp=None):
'''apply handlers; timestamp indicates a delayed messages'''
for h in _message_handles:
ret = h(self, msg)
if ret is True:
break
elif isinstance(ret, str):
msg = ret
else:
if self.now < self.current_user.mute_until:
t = (self.current_user.mute_until + \
config.timezoneoffset).strftime(dateformat)
self.reply(_('You are disallowed to speak until %s') % t)
return
msg = msg.strip()
if not msg:
return
self.user_update_msglog(msg)
msg = '[%s] ' % self.user_get_nick(str(self.current_jid.bare())) + msg
if self.current_user.stop_until > self.now:
self.user_reset_stop() # self.current_user is reloaded here
self.dispatch_message(msg, timestamp)
def dispatch_message(self, msg, timestamp=None, but=None):
'''dispatch message to group members, also log the message in database'''
if but is None:
but = {self.current_user.jid}
if timestamp:
dt = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
interval = self.now - dt
if interval.days == 0:
dt += config.timezoneoffset
msg = '(%s) ' % dt.strftime(timeformat) + msg
logmsg(self.current_jid, msg)
for u in self.get_message_receivers():
if str(u) not in but:
self.send_message(u, msg)
return True
def get_message_receivers(self):
allusers = {u['jid'] for u in models.connection.User.find({
'stop_until': {'$lte': self.now}
}, ['jid'])}
return [u for u in self.get_online_users() if str(u) in allusers]
try:
from plugin import message_plugin_early
for h in message_plugin_early:
message_handler_register(h)
except ImportError:
pass
# these are standard message plugins that normally desired
message_handler_register(check_auth)
message_handler_register(pingpong)
message_handler_register(give_help)
message_handler_register(command)
message_handler_register(filter_otr)
try:
from plugin import message_plugin
for h in message_plugin:
message_handler_register(h)
except ImportError:
pass