2 # Shared admin commands.
5 from sys_base
import Subsystem
6 from datetime
import datetime
9 def build_ban_message(entity
):
10 message
= 'Source: @b%s@b.' % entity
.ban_source
12 if entity
.ban_date
!= None:
13 message
+= ' Date: @b%s@b.' % datetime
.fromtimestamp(entity
.ban_date
)
15 if entity
.ban_expiry
!= None:
16 message
+= ' Expiry: @b%s@b.' % datetime
.fromtimestamp(entity
.ban_expiry
)
18 if entity
.ban_reason
!= None:
19 message
+= ' Reason: @b%s@b.' % entity
.ban_reason
23 def admin_db(self
, source
, target
, pieces
):
25 state
= pieces
[0].lower()
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']:
36 self
.msg(target
, 'Automatic database commits: @b%s@b.' % (
37 'enabled' if Subsystem
.get_db_up() else 'disabled')
42 def admin_opt(self
, source
, target
, pieces
):
44 for option
in sorted(self
.options
):
45 opt
= self
.options
[option
]
46 self
.msg(target
, '@b%s@b: %s' % (opt
[0], opt
[1]))
56 if operation
== 'get':
57 value
= self
.options
.get(name
, unicode)
60 self
.msg(target
, 'Option @b%s@b not found.' % name
)
62 self
.msg(target
, '@b%s@b: %s' % (name
, value
))
63 elif operation
== 'set':
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
)
74 self
.msg(target
, 'Option @b%s@b not found.' % name
)
78 def admin_user(self
, source
, target
, pieces
, meta
=None):
85 if action
in ['l', 'list']:
86 users
= ['%s' % user
.name
for user
in self
.users
.list_valid()]
89 self
.msg(target
, 'No users.')
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()]
96 self
.msg(target
, 'No banned users.')
98 self
.multimsg(target
, 1, '', ', ', bans
)
106 if action
in ['b', 'ban']:
107 now
= unix_time(datetime
.now())
111 duration
= parse_timespan(pieces
[2])
116 self
.msg(target
, '%s is not a valid duration.' % pieces
[2])
119 expiry
= now
+ duration
124 reason
= ' '.join(pieces
[3:])
128 message
= 'Banned user @b%s@b.' % username
131 message
+= ' Reason: @b%s@b.' % reason
134 message
+= ' Expiry: @b%s@b.' % datetime
.fromtimestamp(expiry
)
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
)
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
]
151 if not user
.registered
:
152 message
+= '(Temporary) '
154 message
+= '@b%s@b.' % user
.name
156 if isinstance(meta
, dict) and 'extra_info' in meta
:
157 message
+= meta
['extra_info'](user
)
159 if self
.users
.is_banned(username
):
160 message
+= ' Banned by @b%s@b' % user
.ban_source
162 if user
.ban_reason
!= None:
163 message
+= ' for @b%s@b' % user
.ban_reason
165 message
+= ' on @b%s@b.' % datetime
.fromtimestamp(user
.ban_date
)
167 if user
.ban_expiry
!= None:
168 message
+= ' Ban expires on @b%s@b.' % datetime
.fromtimestamp(user
.ban_expiry
)
170 self
.msg(target
, message
)
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
)
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
)
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
)
192 def admin_chan(self
, source
, target
, pieces
, meta
=None):
199 if action
in ['l', 'list']:
200 channels
= ['%s' % chan
.name
for chan
in self
.channels
.list_valid()]
202 if len(channels
) == 0:
203 self
.msg(target
, 'No channels.')
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()]
210 self
.msg(target
, 'No banned channels.')
212 self
.multimsg(target
, 1, '', ', ', bans
)
220 if action
in ['b', 'ban']:
221 now
= unix_time(datetime
.now())
225 duration
= parse_timespan(pieces
[2])
230 self
.msg(target
, '%s is not a valid duration.' % pieces
[2])
233 expiry
= now
+ duration
238 reason
= ' '.join(pieces
[3:])
242 message
= 'Banned channel @b%s@b.' % channel
245 message
+= ' Reason: @b%s@b.' % reason
248 message
+= ' Expiry: @b%s@b.' % datetime
.fromtimestamp(expiry
)
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
)
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
]
265 if not chan
.registered
:
266 message
+= '(Temporary) '
268 message
+= '@b%s@b.' % chan
.name
270 if isinstance(meta
, dict) and 'extra_info' in meta
:
271 message
+= meta
['extra_info'](chan
)
273 if self
.channels
.is_banned(channel
):
274 message
+= ' Banned by @b%s@b' % chan
.ban_source
276 if chan
.ban_reason
!= None:
277 message
+= ' for @b%s@b' % chan
.ban_reason
279 message
+= ' on @b%s@b.' % datetime
.fromtimestamp(chan
.ban_date
)
281 if chan
.ban_expiry
!= None:
282 message
+= ' Ban expires on @b%s@b.' % datetime
.fromtimestamp(chan
.ban_expiry
)
284 self
.msg(target
, message
)
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
)
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
)
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'))
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
316 def admin_unregistered(self
, source
, target
, pieces
):
322 if action
not in ['check', 'list', 'part']:
326 for chan
in self
.channels
.list_all():
327 c
= self
.inter
.findChannel(chan
.name
)
332 channels
.append({'name': chan.name, 'modes': modes, 'users': c.size()}
)
334 total
= len(channels
)
336 self
.msg(target
, 'No unregistered channels.')
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' % {
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' % {
353 'name': chan
['name']})
357 def admin_log(self
, source
, target
, pieces
):
359 self
.msg(target
, 'Log level is @b%d@b.' % self
.elog
.level
)
363 level
= int(pieces
[0])
367 if level
< 0 or level
> 7:
370 self
.elog
.set_level(level
)
371 self
.msg(target
, 'Log level set to @b%d@b.' % level
)
374 def admin_msg(self
, source
, target
, pieces
):
378 srcu
= self
.inter
.findUser(source
)
379 sender
= srcu
['nick']
380 message
= ' '.join(pieces
)
382 for channel
in self
.channels
.list_valid():
383 self
.msg(channel
.name
, '@b[Global message by %s]@b %s' % (sender
, message
))