def rtopic(self, cmd): '''put a random quote in the topic periodically (if not locked) rtopic [channel] <numhours> ["<format>"] ex: rtopic #foo 4 "The best of #foo: %s" Set <numhours> to 0 to stop. ''' syntax = 'rtopic [channel] <numhours> ["<format>"]' args = cmd.shsplit() channel = cmd.channel # default channel if args and is_channel(args[0]): channel = args.pop(0) if not channel: return cmd.reply("What channel?") if args: try: period = float(args.pop(0)) except: return cmd.reply(syntax) else: cmap = self.rtopic_list.get(channel) if cmap is None: return cmd.reply('not setting %s topic' % channel) return cmd.reply('setting %s topic every %f hours with format %s' % \ (channel, cmap['period'], repr(cmap['format']))) if period == 0.0 and self.rtopic_list.has_key(channel): if self.rtopic_timers.has_key(channel): self.bot.del_timer(self.rtopic_timers[channel]) del self.rtopic_timers[channel] del self.rtopic_list[channel] self._stash() return cmd.reply('disabling random topics on %s' % channel) if args: format = args.pop(0) else: format = "The best of %s: %%s" % channel self.rtopic_list[channel] = {'period': period, 'format': format} self._stash() self._update_channel(channel) cmd.reply('done')
def _on_topic(self, c, e): if is_channel(e.target) and self._match_list(e.target, self.channels): m = {'nick': nm_to_n(e.source), 'channel': e.target, 'topic': e.args[0]} self._add_times(m) m = self._strip(m) self.write(self._topic_f % m)
def _on_mode(self, c, e): """handler for mode changes This method is more complex than the others. First, it ONLY handles channel mode changes. This includes bans, ops, voice, topic lock, etc. Non-channel modes are ignored. For each mode individually, the following things happen: 1) if the instance has a method called _handle_mode_X (where X is the specific mode) it will be called with the following args: connection_object, event_object, source_nick, target_channel, sign, mode, arg For example, if seth gives michael ops on #dhg, you would see this: (<conn>, <event>, 'seth', '#dhg', '+', 'o', 'michael') if the function returns None (this is what happens when there is no explicit "return") then processing goes on to the next "chunk". Otherwise, processing continues to (2) 2) The standard "m" dict is formed. 3) if the instance has an attribute called _mode_X_f then it will be used as the format string for writing the mode. Otherwise, the attribute _mode_f will be used. Therefore, you should define _mode_f as a "generic mode" format, which you can override with _mode_X_f attributes or _handle_mode_X methods. Note that this happens for each perm "chunk". A single mode command can contain may chunks. For example: /mode #dhg +ov michael michael This will first be processed with (sign, mode, arg) = ('+', 'o', 'michael') and then (sign, mode, arg) = ('+', 'v', 'michael') m contains the following keys: utime, htime, source, channel, sign, mode, arg, raw where raw is (for example) '+v michael' """ if not (is_channel(e.target) and self._match_list(e.target, self.channels)): return t = e.target s = nm_to_n(e.source) string_modes = ' '.join(e.args) modes = parse_channel_modes(string_modes) m = {'source': s, 'channel': t} self._add_times(m) for sign, mode, arg in modes: meth = getattr(self, '_handle_mode_' + mode, None) if meth is not None: if not meth(c, e, s, t, sign, mode, arg): continue raw = '%s%s %s' % (sign, mode, arg) new = {'sign': sign, 'mode': mode, 'arg': arg, 'raw': raw} m.update(self._strip(new)) format = getattr(self, '_mode_%s_f' % mode, self._mode_f) self.write(format % m)
def _on_ctcp_action(self, c, e): m = {'target': e.target, 'source': nm_to_n(e.source), 'message': e.args[0]} if is_channel(e.target): if not self._match_list(e.target, self.channels): return m['type'] = 'public' form = self._pubaction_f else: if not self._match_list(e.target, self.nicks): return m['type'] = 'private' form = self._privaction_f self._add_times(m) m = self._strip(m) self.write(form % m)
def _on_send_ctcp_action(self, c, e): target, text = e.args m = {'target': target, 'source': self.bot.nick, 'message': text} if is_channel(target): if not self._match_list(target, self.channels): return m['type'] = 'public' form = self._send_pubaction_f else: if not self._match_list(target, self.nicks): return m['type'] = 'private' form = self._send_privaction_f self._add_times(m) m = self._strip(m) self.write(form % m)