]> jfr.im git - irc/rizon/acid.git/blob - pyva/src/main/python/pseudoclient/cmd_admin.py
.gitignore: Ignore all pyva logs
[irc/rizon/acid.git] / pyva / src / main / python / pseudoclient / cmd_admin.py
1 #
2 # Shared admin commands.
3 #
4
5 from sys_base import Subsystem
6 from datetime import datetime
7 from utils import *
8
9 def build_ban_message(entity):
10 message = 'Source: @b%s@b.' % entity.ban_source
11
12 if entity.ban_date != None:
13 message += ' Date: @b%s@b.' % datetime.fromtimestamp(entity.ban_date)
14
15 if entity.ban_expiry != None:
16 message += ' Expiry: @b%s@b.' % datetime.fromtimestamp(entity.ban_expiry)
17
18 if entity.ban_reason != None:
19 message += ' Reason: @b%s@b.' % entity.ban_reason
20
21 return message
22
23 def admin_db(self, source, target, pieces):
24 if len(pieces) >= 1:
25 state = pieces[0].lower()
26
27 if state in ['on', 'enable']:
28 Subsystem.set_db_up(True)
29 elif state in ['off', 'disable']:
30 Subsystem.set_db_up(False)
31 elif state in ['state']:
32 pass
33 else:
34 return False
35
36 self.msg(target, 'Automatic database commits: @b%s@b.' % (
37 'enabled' if Subsystem.get_db_up() else 'disabled')
38 )
39
40 return True
41
42 def admin_opt(self, source, target, pieces):
43 if len(pieces) < 1:
44 for option in sorted(self.options):
45 opt = self.options[option]
46 self.msg(target, '@b%s@b: %s' % (opt[0], opt[1]))
47
48 return True
49
50 if len(pieces) < 2:
51 return False
52
53 operation = pieces[0]
54 name = pieces[1]
55
56 if operation == 'get':
57 value = self.options.get(name, unicode)
58
59 if value == None:
60 self.msg(target, 'Option @b%s@b not found.' % name)
61 else:
62 self.msg(target, '@b%s@b: %s' % (name, value))
63 elif operation == 'set':
64 if len(pieces) < 3:
65 return False
66
67 value = ' '.join(pieces[2:])
68 value = self.options.set(name, value)
69 self.msg(target, '@b%s@b: %s' % (name, value))
70 elif operation == 'clear':
71 if self.options.clear(name):
72 self.msg(target, 'Option @b%s@b cleared.' % name)
73 else:
74 self.msg(target, 'Option @b%s@b not found.' % name)
75
76 return True
77
78 def admin_user(self, source, target, pieces, meta=None):
79 if len(pieces) < 1:
80 return False
81
82 action = pieces[0]
83
84 if len(pieces) < 2:
85 if action in ['l', 'list']:
86 users = ['%s' % user.name for user in self.users.list_valid()]
87
88 if len(users) == 0:
89 self.msg(target, 'No users.')
90 else:
91 self.multimsg(target, 10, 'Users: ', ', ', users)
92 elif action in ['bl', 'blist']:
93 bans = ['@c10@b%s@o - %s' % (user.name, build_ban_message(user)) for user in self.users.list_banned()]
94
95 if len(bans) == 0:
96 self.msg(target, 'No banned users.')
97 else:
98 self.multimsg(target, 1, '', ', ', bans)
99 else:
100 return False
101
102 return True
103
104 username = pieces[1]
105
106 if action in ['b', 'ban']:
107 now = unix_time(datetime.now())
108
109 if len(pieces) > 2:
110 try:
111 duration = parse_timespan(pieces[2])
112 except:
113 duration = 0
114
115 if duration <= 0:
116 self.msg(target, '%s is not a valid duration.' % pieces[2])
117 return True
118
119 expiry = now + duration
120 else:
121 expiry = None
122
123 if len(pieces) > 3:
124 reason = ' '.join(pieces[3:])
125 else:
126 reason = None
127
128 message = 'Banned user @b%s@b.' % username
129
130 if reason != None:
131 message += ' Reason: @b%s@b.' % reason
132
133 if expiry != None:
134 message += ' Expiry: @b%s@b.' % datetime.fromtimestamp(expiry)
135
136 srcu = self.inter.findUser(source)
137 self.users.ban(username, srcu['nick'], reason, now, expiry)
138 self.msg(target, message)
139 elif action in ['u', 'unban']:
140 if not self.users.is_banned(username):
141 self.msg(target, 'User @b%s@b is not banned.' % username)
142 else:
143 self.users.unban(username)
144 self.msg(target, 'Unbanned user @b%s@b' % username)
145 elif action in ['i', 'info']:
146 if username in self.users:
147 user = self.users[username]
148
149 message = ''
150
151 if not user.registered:
152 message += '(Temporary) '
153
154 message += '@b%s@b.' % user.name
155
156 if isinstance(meta, dict) and 'extra_info' in meta:
157 message += meta['extra_info'](user)
158
159 if self.users.is_banned(username):
160 message += ' Banned by @b%s@b' % user.ban_source
161
162 if user.ban_reason != None:
163 message += ' for @b%s@b' % user.ban_reason
164
165 message += ' on @b%s@b.' % datetime.fromtimestamp(user.ban_date)
166
167 if user.ban_expiry != None:
168 message += ' Ban expires on @b%s@b.' % datetime.fromtimestamp(user.ban_expiry)
169
170 self.msg(target, message)
171 else:
172 self.msg(target, 'User @b%s@b is not in the database.' % username)
173 elif action in ['a', 'add']:
174 if not username in self.users:
175 self.users.add(username)
176 self.msg(target, 'Added user @b%s@b.' % username)
177 else:
178 self.msg(target, 'User @b%s@b is already in the database.' % username)
179 elif action in ['r', 'remove']:
180 if username in self.users:
181 self.users.remove(username)
182 self.msg(target, 'Removed user @b%s@b.' % username)
183 else:
184 self.msg(target, 'User @b%s@b is not in the database.' % username)
185 elif isinstance(meta, dict) and 'cmds' in meta and action in meta['cmds']:
186 return meta[action](self, action, username, source, target, pieces)
187 else:
188 return False
189
190 return True
191
192 def admin_chan(self, source, target, pieces, meta=None):
193 if len(pieces) < 1:
194 return False
195
196 action = pieces[0]
197
198 if len(pieces) < 2:
199 if action in ['l', 'list']:
200 channels = ['%s' % chan.name for chan in self.channels.list_valid()]
201
202 if len(channels) == 0:
203 self.msg(target, 'No channels.')
204 else:
205 self.multimsg(target, 10, 'Channels: ', ', ', channels)
206 elif action in ['bl', 'blist']:
207 bans = ['@c10@b%s@o - %s' % (chan.name, build_ban_message(chan)) for chan in self.channels.list_banned()]
208
209 if len(bans) == 0:
210 self.msg(target, 'No banned channels.')
211 else:
212 self.multimsg(target, 1, '', ', ', bans)
213 else:
214 return False
215
216 return True
217
218 channel = pieces[1]
219
220 if action in ['b', 'ban']:
221 now = unix_time(datetime.now())
222
223 if len(pieces) > 2:
224 try:
225 duration = parse_timespan(pieces[2])
226 except:
227 duration = 0
228
229 if duration <= 0:
230 self.msg(target, '%s is not a valid duration.' % pieces[2])
231 return True
232
233 expiry = now + duration
234 else:
235 expiry = None
236
237 if len(pieces) > 3:
238 reason = ' '.join(pieces[3:])
239 else:
240 reason = None
241
242 message = 'Banned channel @b%s@b.' % channel
243
244 if reason != None:
245 message += ' Reason: @b%s@b.' % reason
246
247 if expiry != None:
248 message += ' Expiry: @b%s@b.' % datetime.fromtimestamp(expiry)
249
250 srcu = self.inter.findUser(source)
251 self.channels.ban(channel, srcu['nick'], reason, now, expiry)
252 self.msg(target, message)
253 elif action in ['u', 'unban']:
254 if not self.channels.is_banned(channel):
255 self.msg(target, 'Channel @b%s@b is not banned.' % channel)
256 else:
257 self.channels.unban(channel)
258 self.msg(target, 'Unbanned channel @b%s@b' % channel)
259 elif action in ['i', 'info']:
260 if channel in self.channels:
261 chan = self.channels[channel]
262
263 message = ''
264
265 if not chan.registered:
266 message += '(Temporary) '
267
268 message += '@b%s@b.' % chan.name
269
270 if isinstance(meta, dict) and 'extra_info' in meta:
271 message += meta['extra_info'](chan)
272
273 if self.channels.is_banned(channel):
274 message += ' Banned by @b%s@b' % chan.ban_source
275
276 if chan.ban_reason != None:
277 message += ' for @b%s@b' % chan.ban_reason
278
279 message += ' on @b%s@b.' % datetime.fromtimestamp(chan.ban_date)
280
281 if chan.ban_expiry != None:
282 message += ' Ban expires on @b%s@b.' % datetime.fromtimestamp(chan.ban_expiry)
283
284 self.msg(target, message)
285 else:
286 self.msg(target, 'Channel @b%s@b is not in the database.' % channel)
287 elif action in ['a', 'add']:
288 if not channel in self.channels:
289 self.channels.add(channel)
290 self.msg(target, 'Added channel @b%s@b.' % channel)
291 else:
292 self.msg(target, 'Channel @b%s@b is already in the database.' % channel)
293 elif action in ['r', 'remove']:
294 if channel in self.channels:
295 self.channels.remove(channel)
296 self.msg(target, 'Removed channel @b%s@b.' % channel)
297 else:
298 self.msg(target, 'Channel @b%s@b is not in the database.' % channel)
299 elif action in ['n', 'news']:
300 if channel in self.channels:
301 cur_state = self.channels[channel].news
302 self.channels.set(channel, 'news', not cur_state)
303 self.msg(target, 'Toggled news for channel @b%s@b. Current state: %s.' % (channel, 'disabled' if cur_state else 'enabled'))
304 else:
305 self.msg(target, 'Channel @b%s@b is not in the database.' % channel)
306 elif isinstance(meta, dict) and 'cmds' in meta and action in meta['cmds']:
307 ret = meta[action](self, action, channel, source, target, pieces)
308 # i'm letting None imply that this command succeded
309 # just sort of easier that way
310 return True if ret is None else ret
311 else:
312 return False
313
314 return True
315
316 def admin_unregistered(self, source, target, pieces):
317 if len(pieces) < 1:
318 return False
319
320 action = pieces[0]
321
322 if action not in ['check', 'list', 'part']:
323 return
324
325 channels = []
326 for chan in self.channels.list_all():
327 c = self.inter.findChannel(chan.name)
328 if not c:
329 continue
330 modes = c['modes']
331 if 'z' not in modes:
332 channels.append({'name': chan.name, 'modes': modes, 'users': c.size()})
333
334 total = len(channels)
335 if total == 0:
336 self.msg(target, 'No unregistered channels.')
337 return True
338
339 if action == 'check':
340 self.msg(target, 'There are %d unregistered channels.' % total)
341 elif action == 'list':
342 for n, chan in enumerate(channels, 1):
343 self.msg(target, '%(n)d) @b%(name)s@b [%(modes)s] @b%(users)d@b users' % {
344 'n': n,
345 'name': chan['name'],
346 'modes': chan['modes'] if chan['modes'].startswith('+') else '+' + chan['modes'],
347 'users': chan['users']})
348 elif action == 'part':
349 for n, chan in enumerate(channels, 1):
350 self.channels.remove(str(chan['name']))
351 self.msg(target, '%(n)d) Removed unregistered channel @b%(name)s@b' % {
352 'n': n,
353 'name': chan['name']})
354
355 return True
356
357 def admin_log(self, source, target, pieces):
358 if len(pieces) < 1:
359 self.msg(target, 'Log level is @b%d@b.' % self.elog.level)
360 return True
361
362 try:
363 level = int(pieces[0])
364 except:
365 return False
366
367 if level < 0 or level > 7:
368 return False
369
370 self.elog.set_level(level)
371 self.msg(target, 'Log level set to @b%d@b.' % level)
372 return True
373
374 def admin_msg(self, source, target, pieces):
375 if len(pieces) < 1:
376 return False
377
378 srcu = self.inter.findUser(source)
379 sender = srcu['nick']
380 message = ' '.join(pieces)
381
382 for channel in self.channels.list_valid():
383 self.msg(channel.name, '@b[Global message by %s]@b %s' % (sender, message))
384
385 return True