]> jfr.im git - irc/rizon/acid.git/blob - pyva/pyva/src/main/python/limitserv/limitserv.py
pyva: De-duplicate join/part code across modules
[irc/rizon/acid.git] / pyva / pyva / src / main / python / limitserv / limitserv.py
1 #!/usr/bin/python pseudoserver.py
2 #psm-limitserv.py
3 # module for pypseudoserver
4 # written by celestin - martin <martin@rizon.net>
5
6 import sys
7 import types
8 from istring import istring
9 from pseudoclient import sys_log, sys_options, sys_channels, inviteable
10 from utils import *
11
12 from pyva import *
13 import logging
14 from core import *
15 from plugin import *
16
17 import cmd_admin, sys_auth, limitmanager
18
19 import pyva_net_rizon_acid_core_Acidictive as Acidictive
20 import pyva_net_rizon_acid_core_AcidCore as AcidCore
21 import pyva_net_rizon_acid_core_User as User
22 import pyva_net_rizon_acid_core_Channel as Channel
23
24 class limitserv(
25 AcidPlugin,
26 inviteable.InviteablePseudoclient
27 ):
28 initialized = False
29
30 def start_threads(self):
31 self.options.start()
32 self.channels.start()
33 self.auth.start()
34 self.limit_monitor.start()
35
36 def bind_function(self, function):
37 func = types.MethodType(function, self, limitserv)
38 setattr(limitserv, function.__name__, func)
39 return func
40
41 def bind_admin_commands(self):
42 list = cmd_admin.get_commands()
43 self.commands_admin = []
44
45 for command in list:
46 self.commands_admin.append((command, {'permission': 'j', 'callback': self.bind_function(list[command][0]),
47 'usage': list[command][1]}))
48
49 def __init__(self):
50 AcidPlugin.__init__(self)
51
52 self.name = "limitserv"
53 self.log = logging.getLogger(__name__)
54
55 try:
56 self.nick = istring(self.config.get('limitserv', 'nick'))
57 except Exception, err:
58 self.log.exception("Error reading 'limitserv:nick' configuration option: %s" % err)
59 raise
60
61 try:
62 self.chan = istring(self.config.get('limitserv', 'channel'))
63 except Exception, err:
64 self.log.exception("Error reading 'limitserv:channel' configuration option: %s" % err)
65 raise
66
67 self.bind_admin_commands()
68
69 def start(self):
70 try:
71 self.dbp.execute("CREATE TABLE IF NOT EXISTS limitserv_chans (item SMALLINT(5) NOT NULL AUTO_INCREMENT, channel VARCHAR(35), \
72 PRIMARY KEY (item), UNIQUE KEY (channel));")
73 except Exception, err:
74 self.log.exception("Error creating table for limitserv module (%s)" % err)
75 raise
76
77 try:
78 AcidPlugin.start(self)
79 inviteable.InviteablePseudoclient.start(self)
80
81 self.options = sys_options.OptionManager(self)
82 self.elog = sys_log.LogManager(self)
83 self.auth = sys_auth.LimitServAuthManager(self)
84 self.channels = sys_channels.ChannelManager(self)
85 self.limit_monitor = limitmanager.LimitManager(self)
86 except Exception, err:
87 self.log.exception('Error initializing subsystems for limitserv module (%s)' % err)
88 raise
89
90 for channel in self.channels.list_valid():
91 self.join(channel.name)
92
93 self.elog.debug('Joined channels.')
94
95 try:
96 self.start_threads()
97 except Exception, err:
98 self.log.exception('Error starting threads for limitserv module (%s)' % err)
99 raise
100
101 self.initialized = True
102 self.elog.debug('Started threads.')
103 return True
104
105 def onSync(self):
106 for channel in self.channels.list_valid():
107 self.msg('ChanServ', 'OP %s' % channel.name)
108
109 def stop(self):
110 if hasattr(self, 'auth'):
111 self.auth.stop()
112
113 if hasattr(self, 'channels'):
114 if self.initialized:
115 self.channels.force()
116
117 self.channels.stop()
118 self.channels.db_close()
119
120 if hasattr(self, 'options'):
121 if self.initialized:
122 self.options.force()
123
124 self.options.stop()
125 self.options.db_close()
126
127 if hasattr(self, 'limit_monitor'):
128 self.limit_monitor.stop()
129
130 def join(self, channel):
131 super(limitserv, self).join(channel)
132 self.msg('ChanServ', 'OP %s' % channel) # and the channel is not empty. For now, use /cs op
133
134 def msg(self, target, message):
135 if message != '':
136 Acidictive.privmsg(self.nick, target, format_ascii_irc(message))
137
138 def multimsg(self, target, count, intro, separator, pieces, outro = ''):
139 cur = 0
140
141 while cur < len(pieces):
142 self.msg(target, intro + separator.join(pieces[cur:cur + count]) + outro)
143 cur += count
144
145 def notice(self, target, message):
146 if message != '':
147 Acidictive.notice(self.nick, target, format_ascii_irc(message))
148
149 def onPrivmsg(self, source, target, message):
150 if inviteable.InviteablePseudoclient.onPrivmsg(self, source, target, message) and \
151 target == self.nick:
152 # if inviteable fell through, we don't have anything else to do
153 self.msg(source, 'Invalid message. Say help for a list of valid messages.')
154
155 def do_accept(self, nick, channel):
156 chan = Channel.findChannel(channel)
157 if chan.size() < self.options.get('required_users', int, 20):
158 self.auth.reject_not_enough_users(nick, channel)
159 else:
160 # super call
161 inviteable.InviteablePseudoclient.do_accept(self, nick, channel)
162
163 def onChanModes(self, prefix, channel, modes):
164 if not self.initialized:
165 return
166
167 if not modes == '-z':
168 return
169
170 if channel in self.channels:
171 self.channels.remove(channel)
172 self.elog.request('Channel @b%s@b was dropped. Deleting it.' % channel)
173
174 def onJoin(self, user, channel):
175 if self.channels.is_valid(channel) and channel not in self.limit_monitor:
176 self.limit_monitor.insert(channel)
177
178 def onPart(self, user, channel):
179 self.onJoin(None, channel)
180
181 def onKick(self, kicker, victim, channel, reason):
182 self.onJoin(None, channel)
183
184 def getCommands(self):
185 return self.commands_admin