def __init__(self, parent=None, event=None): if event: self.event = event else: self.event = Event('', '', '', ['']) self.source = event.source() self.source_nick = event.source_nick self.handler = parent self.bot = parent.bot self.conn = parent.conn self.storage = parent.storage self.storage.setdefault('extra_commands', {})
def group_to_event(group): e = Event('pubmsg', group['nick'], target, (group['message'],)) e.timestamp = datetime.datetime(int(stats['year']), months.index(stats['month']), int(stats['date']), \ int(group['H']), int(group['M']), int(group['S'])) e.keywords = Lexer(group['message']).keywords return e
class Commands(object): def __init__(self, parent=None, event=None): if event: self.event = event else: self.event = Event('', '', '', ['']) self.source = event.source() self.source_nick = event.source_nick self.handler = parent self.bot = parent.bot self.conn = parent.conn self.storage = parent.storage self.storage.setdefault('extra_commands', {}) def reply(self, message): self.handler.reply(self.event, message) def match(self, nick): if not len(self.event.arguments()): return text = self.event.arguments()[0] cmdline = '' match = COMMAND_REGEX.match(text) if match: cmdline = match.groups()[1] elif self.event.eventtype() == 'privmsg': cmdline = text if self.parse_cmdline(cmdline): return self def parse_cmdline(self, cmdline, doreturn=False): if not cmdline: return results = [] def find_cmd(cmdline, n): name = ('_'.join(cmdline.split(' ', n)[:n])).lower() if name in self.storage['extra_commands']: mod = util.get_module(self.storage['extra_commands'][name]) method = lambda: getattr(mod, "cmd_" + name, None)(self) else: method = getattr(self, "cmd_" + name, None) if method: params = (cmdline + ' ').split(' ', n)[1].strip() results.append((method, params)) [find_cmd(cmdline, n) for n in range(1, 5)] if results: if doreturn: return results[-1] else: self.command, self.params = results[-1] return True def do(self): self.handler.send(self.command(), self.event) def command(self): '''dummy function to be replaced by other commands''' pass @cmd.admin def cmd_die(self): self.storage.save() self.bot.die('*dies*') @cmd.admin def cmd_eval(self): '''this is a docstring i just added''' import code codestring = self.params.replace("[NL]", "\n") try: return str(eval(compile(codestring, '<irc>', 'eval'))) except Exception: self.enable_stdout() try: eval(code.compile_command(codestring)) except Exception: return util.exc_lines()[-1] self.disable_stdout() def enable_stdout(self): if hasattr(self.storage, "stdout") and self.storage.stdout: return self.storage.stdout = sys.stdout def message(buffer): self.reply("stdout: " + buffer.strip()) handler = self.handler class NewStdout(object): def __init__(self): self.buffer = StringIO() def write(self, text): self.buffer.write(text) if text.find("\n") != -1: message(self.buffer.getvalue()) self.buffer = StringIO() sys.stdout = NewStdout() def disable_stdout(self): if hasattr(self.storage, "stdout") and self.storage.stdout: sys.stdout = self.storage.stdout self.storage.stdout = None @cmd.user @params.new('#channel') def cmd_join(self, channel): self.conn.join(channel) @cmd.admin @params.new('#channel [...]') def cmd_leave(self, channel, msg): self.conn.part(channel, msg or '') @cmd.admin @params.auto def cmd_nick(self, nick): self.conn.nick(nick) @cmd.admin @params.new('/(markov|outputqueue)/') def cmd_reload(self, what): if what == 'markov': start = time.time() reload(markov).rebuild() return "took %s seconds" % (time.time() - start) elif what == 'outputqueue': self.storage.output = util.get_module('outputqueue').Manager() return "now what?" @cmd.user @params.auto def cmd_set(self, option, value=None): option = option.strip().lower() key = "option_%s" % option if value is None: self.storage[key] = not self.storage.get(key, False) else: self.storage[key] = bool(value) return "%s set to %s" % (option, self.storage[key]) @cmd.user def cmd_list_options(self): keys = [(x, y) for (x, y) in self.storage.items() if x.startswith("option_")] return (', '.join(['%s (%s)' % x for x in keys])) @cmd.admin @params.new('/(load|unload|list)/ [...]') def cmd_module(self, action, modules): modules = modules and modules.split() or [] for module in modules: try: if action == 'load' and module not in self.storage['modules']: mod = util.get_module(module) mod.load(self.handler) if getattr(mod, 'PROVIDES_COMMANDS', None): for cmd in mod.PROVIDES_COMMANDS: self.storage['extra_commands'][cmd] = module self.storage['modules'].append(module) self.storage.touch() elif action == 'unload' and module in self.storage['modules']: self.storage['modules'].remove(module) self.storage.touch() mod = util.get_module(module) mod.unload(self.handler) if getattr(mod, 'PROVIDES_COMMANDS', None): for cmd in mod.PROVIDES_COMMANDS: if cmd in self.storage['extra_commands']: del self.storage['extra_commands'][cmd] self.storage.touch() except: yield "%s: %s" % (module, util.exc_lines()[-1]) else: yield '%s: done' % module if action == 'list': modules = self.storage['modules'] all = [x.replace(".py", "").replace("mods/", "") for x in glob.glob("mods/*.py")] all = [x + (x in modules and "*" or "") for x in all if not x.startswith("_")] yield ', '.join(sorted(all)) @cmd.user @params.auto def cmd_help(self, what=None): if what is None or what == 'all': cmdlist = cmd.list + self.storage['extra_commands'].keys() if self.source_nick in config.ADMINS and what == 'all': yield ', '.join(cmd.list) else: yield ', '.join([x for x in cmd.list if not x.endswith("*")]) return elif hasattr(self, 'cmd_%s' % what): # command f = self.parse_cmdline(what, True)[0] usage = getattr(f, 'usage', DUNNO) yield "%s: Usage: %s" % (what, usage) if hasattr(f, '__doc__') and f.__doc__ is not None: yield "%s: %s" % (what, f.__doc__) else: # module try: mod = util.get_module(what) if hasattr(mod, '__doc__') and mod.__doc__ is not None: yield '%s (module): %s' % (what, mod.__doc__.split("\n")[0]) else: yield '%s (module)' % what except ImportError: pass @cmd.user @params.new('[#channel] ...') def cmd_say(self, to, msg): return Message(msg, to=to, event=self.event) @cmd.user @params.new('[#channel] ...') def cmd_action(self, to, msg): return Message(msg, to=to, event=self.event, action=True) @cmd.admin @params.new('[#channel] ...') def cmd_mode(self, channel, mode): channel = channel or self.event.target() self.conn.mode(channel, mode) @cmd.admin @params.new('...') def cmd_umode(self, mode): self.conn.mode(self.conn.get_nickname(), mode) @cmd.admin @params.new('[#channel] t:str [...]') def cmd_kick(self, channel, who, reason): channel = channel or self.event.target() reason = reason or '' self.conn.kick(channel, who, reason) @cmd.user @params.auto def cmd_markov(self, nick): return markov.markov(nick)[:400] @cmd.user def cmd_kriegs(self): return markov.markov("KriegsaffeNo9") @cmd.user def cmd_tumbleweed(self): r = random.randint(10,20) r2 = 7 + 15 - r r3 = random.randint(4, 7) r2 = r2 - r3 + 6 t = tuple(["." * x for x in (r, r2, r3)]) return "%s~*%s*%s*" % t @cmd.user @params.new('[#channel] [/wide/]') def cmd_nicks(self, channel, wide): channel = channel or self.event.target() if channel not in self.bot.channels: return users = self.bot.channels[channel].users() if wide == 'wide': filter = lambda s: ''.join([unichr(0xfee0 + ord(c)) for c in s]).replace(unichr(0xff00), unichr(0x3000)) else: ZWSP = u'\u200b' filter = lambda s: ''.join([''.join(x) for x in map(None, s, ZWSP * len(s))]) list = [] current = '' for x in users: text = filter(x.lstrip("!@+%")).encode("utf8") if len(current) + len(text) > 450: list.append(current.strip()) current = '' current += text + ' ' list.append(current.strip()) return list @cmd.user def cmd_kickban_stats(self): tops = self.storage.get('kickban_tops', {}) ranking = sorted(tops.items(), key=lambda x: x[1], reverse=True) ranking = [(n + 1, nick, times) for (n, (nick, times)) in enumerate(ranking)] return ', '.join(["%s. %s (%s)" % t for t in ranking]) @cmd.user @params.auto def cmd_attack(self, nick): return "&attack %s" % nick @cmd.user @params.auto def cmd_heal(self, nick): return "&heal %s" % nick @cmd.user def cmd_shut_up(self): self.storage.output.shut_up() @cmd.user def cmd_off(self): self.storage.output.shut_up() @cmd.user def cmd_come_back(self): self.storage.output.come_back() return 'ohai' @cmd.user def cmd_go_away(self): self.conn.part(self.event.target(), "bye") @cmd.user def cmd_gtfo(self): self.conn.part(self.event.target(), "bye") # kept for historical purposes # def make_cocks(locals, name, list): # f = lambda self: self.reply('%s (%s): %s' % (name, len(list), ', '.join(sorted(list)))) # f.__name__ = 'cmd_list_%s' % name # locals[f.__name__] = usercmd(f) # for x in list: # f = lambda self: self.reply(random.choice(list)) # f.__name__ = 'cmd_%s' % x.replace(" ", "_") # locals[f.__name__] = cmd.hidden(f) # # make_cocks(locals(), 'derp', ['hurr', 'durr', 'derp', 'hurrdurr']) @cmd.user @params.new('/(add|remove|set|off)/ [#channel] [t:float]') def cmd_idle(self, action, channel, idletime): self.storage.setdefault('idle_enabled', set()) self.storage.setdefault('idle_times', {}) if action == 'set' and idletime: idletime = int(60 * idletime) self.storage['idle_time'] = idletime return "Idle time set to %s seconds" % idletime elif action == 'off': self.storage['idle_enabled'] = set() return "Ok, ok..." if action == 'add': self.storage['idle_enabled'].update([channel]) self.storage['idle_times'][channel] = time.time() self.storage.touch() return 'Idle detectors enabled for %s' % channel elif action == 'remove': if channel in self.storage['idle_enabled']: self.storage['idle_enabled'].remove(channel) self.storage.touch() return 'Idle detectors disabled for %s' % channel else: return '%s not enabled' % channel @cmd.user @params.new('/(radio|dxdx|.+)/') def cmd_np(self, nick): if nick == 'dxdx': s = socket.socket() IPS = ["192.168.0.16", "192.168.1.5", "192.168.0.30"] connected = False for ip in IPS: try: s.connect((ip, 6600)) except socket.error: pass else: connected = True break if connected: s.send("currentsong\n") time.sleep(0.4) result = dict([x.split(": ", 1) for x in s.recv(2048).split("\n")[1:-2]]) if result: return (nick + " np: %(Artist)s - %(Title)s [%(Album)s]" % result) elif nick == 'radio': return ("desuradio np: " + [x for x in urllib.urlopen("http://desuchan.net:8000/").readlines() if x.count("streamdata")][-1].split(">")[1].split("<")[0]) else: key = "8977c4d8c9031da3608cd318bc56b70e" url = "http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=%s&api_key=%s&limit=1" track = ET.fromstring(urllib.urlopen(url % (nick, key)).read())[0][0] trackdict = dict([(x.tag, x.text) for x in track]) if 'date' in trackdict: datetime.strptime(trackdict['date'], "%d %b %Y, %H:%M") trackdate = datetime.strptime(trackdict['date'], "%d %b %Y, %H:%M") # up to 30 minutes recent = (datetime.now() - trackdate) < timedelta(0, 1800, 0) else: recent = True if recent: return (nick + (u" np: %(artist)s - %(name)s" % trackdict).encode("utf8")) return (nick + " np: nothing %s" % DESPAIR) @cmd.user @params.new('[#channel] [t:int] [/(line|reply|context|before)/] ...') def cmd_grepback(self, channel, results, what, words): channel = channel or '#desuchan' if not results or results > 10: results = 1 grep_params = [] if what == 'before': grep_params = ['-A1'] elif what == 'reply': grep_params = ['-B1'] elif what == 'context': grep_params = ['-C1'] grep_params.append('-m%s' % results) tac = Popen(["tac", LOGS_PATH + channel + ".log"], stdout=PIPE) grepv = Popen(["grep", "-v", "\(<.dekisu>\|> \(dekisu: \|:\)grepback\)"], stdin=tac.stdout, stdout=PIPE) grep = Popen(["grep", "-iF"] + grep_params + [words], stdin=grepv.stdout, stdout=PIPE) ret = grep.communicate()[0].strip() if ret.count("\n") == 0: return ret elif ret: r = [Message(x, to=self.source_nick) for x in ret.split("\n")[::-1]] return r else: return Message("Nothing found", to=self.source_nick) @cmd.user @params.new('[t:str]') def cmd_rena_stats(self, who): channel = '#desuchan' which = who and r'\2' or r'\1' who = who or '[^>]*' egrep = Popen(['egrep', '-i', '^[0-9:]{5} <.%s> &[0-9a-z]+' % who, LOGS_PATH + channel + ".log"], stdout=PIPE) sed = Popen(['sed', '-r', 's/^[0-9:]{5} <.(%s)> &([0-9a-z]+).*$/%s/g' % (who, which)], stdin=egrep.stdout, stdout=PIPE) sort = Popen(['sort'], stdin=sed.stdout, stdout=PIPE) uniq = Popen(['uniq', '-c'], stdin=sort.stdout, stdout=PIPE) sortn = Popen(['sort', '-n'], stdin=uniq.stdout, stdout=PIPE) tail = Popen(['tail', '-n20'], stdin=sortn.stdout, stdout=PIPE) list = [] for line in tail.communicate()[0].strip().split("\n"): yield repr(line.strip().split()) #number, item = line.strip().split() #list.append((number, item)) #list.sort(key=lambda x: x[0]) #return ','.join(['%s. %s (%s)' % (x, y[1], y[0]) for x, y in enumerate(list)]) @cmd.user @params.new('[t:str] [t:str]') def cmd_asd(self, who, word): channel = '#desuchan' egrep = Popen(['egrep', '-i', '^[0-9:]{5} <.%s> ' % who, LOGS_PATH + channel + ".log"], stdout=PIPE) all = 0 matched = 0 for line in egrep.communicate()[0].strip().split("\n"): if line.lower().find(word) != -1: matched += 1 all += 1 return '%s said %s %s out of %s messages (%s%%)' % (who, word, matched, all, matched / float(all) * 100) @cmd.user def cmd_pipe(self): redirect = re.compile("^(.*)> ?([#|a-zA-Z0-9_-]*) *$") m = redirect.match(self.params) if m: self.parse_cmdline(m.groups()[0]) target = m.groups()[1] self.event._target = target self.event._eventtype = 'pubmsg' retval = self.command() for m in messages.normalize(retval): m.to = target return retval else: return 'Usage: pipe somecommandhere > #channelname' @cmd.admin def cmd_storage_tree(self): def tree(dict): for key, value in dict.iteritems(): yield '%s = %s' % (key, value) return tree(self.storage) @cmd.admin @params.new('/(del|set|get)/ t:str [t:str]') def cmd_storage(self, action, key, value): if action == 'del': if key in self.storage: del self.storage[key] return '%s removed from storage' % key else: return 'No such key' elif action == 'set': self.storage[key] = eval(value) elif action == 'set': return repr(self.storage[key]) @cmd.user @params.new('t:str [...]') def cmd_test(self, filename, content): PATH = "/home/dx/cocks/%s" URL = "http://dequis.no-ip.org/%s" if content: open(PATH % filename, "w").write(eval(content)) return URL % filename else: return URL % filename + " - contents: " + repr(open(PATH % filename).read()) @cmd.user def cmd_raise_an_exception_motherfucker(self): raise Exception('ok') @cmd.user def cmd_fakemon(self): randomsort = lambda x: sorted(x, key=lambda y: random.random()) vowels = "aeiou" consonants = "bcdfghjklmnpqrstvwxyz" length = random.randint(2,3) return ''.join(map(lambda x, y: x + y, randomsort(consonants)[:length], randomsort(vowels)[:length])).title() + "mon" @cmd.user @params.new('[...]') def cmd_noop(self, arg): pass @cmd.user def cmd_colortable(self): table = ' '.join(['\3%s text %s' % (x, x) for x in range(16)]) return '\x031,1%s\n\x031,1\2%s' % (table, table)
def handler(self, **args): """Simply increments a counter in the database that keeps track of how many times a person has spoken. Also stores a random quote from the person (basically 10% chance a given quote is going to be chosen for the "random quote" in the database.""" import database, time, random from irclib import Event, nm_to_n # Get nick and quote text nick = nm_to_n(args["source"]).lower() quote = self.sqlEscape(" ".join(args["text"].split()[1:])) channel = args["channel"].lower() if args["type"] == "privmsg": target = nm_to_n(args["source"]) else: target = args["channel"] # Increment counter for that nick if it exists, otherwise insert into DB query = "select count, quote_time from webstats where nick='" + \ nick + "' and" + " channel='" + channel + "'" result = database.doSQL(query) response = [] if result == []: # Insert their first quote as their random quote and set count to 1 query = "insert into webstats(nick, channel, count, quote," \ + " quote_time) values('" + nick + "', '" + channel + "', 1, '" \ + quote + "', " + str(int(time.time())) + ")" database.doSQL(query) # response.append(Event("action", "", target, \ # ["jots down a new quote for " + nick])) else: import time # Get the current count and increment it new_count = int(result[0][0]) + 1 # Get the current quote's date quote_time = int(result[0][1]) curr_time = int(time.time()) secs_elapsed = curr_time - quote_time days_elapsed = secs_elapsed / 24 / 60 / 60 # We don't want quotes that are under 8 letters, they are boring. # # We also don't want quotes of less than 4 words, also usually # boring as well. # # We also don't want stale quotes, so use the number of days since # the current quote times some constant to pick the quote if (random.randrange(new_count) < (days_elapsed * 10)) and \ len(quote) > 8 and \ len(quote.split()) >= 4: query = "update webstats set count=" + str(new_count) \ + ", quote='" + quote + "', quote_time=" \ + str(int(time.time())) + " where nick='" + nick + "'" \ + " and channel='" + channel + "'" database.doSQL(query) if new_count > 10: response.append(Event("continue", "", target, [""])) else: query = "update webstats set count=" + str(new_count) + " where " \ + "nick='" + nick + "' and channel='" + channel + "'" database.doSQL(query) response.append(Event("continue", "", target, [""])) return response
def handler(self, **args): """Allows someone to alter material in a factoid by using a regular expression. Invoked like: "moobot: foo =~ s/moo/bar/".""" import priv, re, time from irclib import Event target = self.return_to_sender(args) # Grab the factoid to change: # first, drop the bot name factoid_key = " ".join(args["text"].split()[1:]) # Now split on " =~ " and take the left half factoid_key = factoid_key.split(" =~ ", 1)[0] locked_by = FactoIds.getLockedBy(factoid_key) if locked_by == None: message = "Factoid '%s' does not exist." % factoid_key return Event("privmsg", "", target, [message]) # Check for the appropriate privilege (delete_priv, even # though we aren't deleting - we are modifying, and there # is no modify priv) if priv.checkPriv(args["source"], "delete_priv") == 0 and ( locked_by != "" and locked_by != args["source"]): message = "You do not have permission to modify factoid '%s." % factoid_key return Event("privmsg", "", target, [message]) # get the original factoid value factoid = FactoIds.getValueByKey(factoid_key) # Grab the regex(es) to apply # First split on =~, then split on spaces for the RHS regexes_str = args["text"].split(" =~ ", 1)[1] # Now we can't split just on spaces, because the regex itself # can have spaces in it. We gotta grab each one individually # because a regex to get them all (potentially each having # unique separators, like "s/foo/bar blatz/g s:moo:mooooo!:i # s%this%makes it hard to parse%". # # The basic algorithm is: # 1 - find out the separator character (2nd) # 2 - find the index of the third occurrence of this character # 3 - find the next space, chop off everything before it and # append it to the regex_list regex_list = [] # regex for removing leading spaces, compiling it first lead_spaces = re.compile("^\s+") while len(regexes_str) > 2: # Strip leading spaces first (so regexes with many spaces # between them don't mess things up when we assume the separator # is the second character) regexes_str = lead_spaces.sub("", regexes_str) # Separator = 2nd char separator = regexes_str[1] # Find it once, then use that as a low range # NOTE - if there is garbage at any point, ignore everything # after it second_sep = regexes_str.find(separator, 2) if second_sep == 0: break third_sep = regexes_str.find(separator, second_sep + 1) if third_sep == 0: break # now the space space_index = regexes_str.find(" ", third_sep) if space_index == -1: # no space found regex_list.append(regexes_str) break else: regex_list.append(regexes_str[:space_index]) regexes_str = regexes_str[space_index:] # apply each of the regexes in order # For now we are assuming all of the regexes are search and replace # s/foo/bar/[gi] ACCEPTABLE_PREFIXES = "sy" ACCEPTABLE_SUFFIXES = "gi" for regex_string in regex_list: # Split the regex into parts - strictly, we split on the second # character, as s:foo:bar: is valid as well try: parts = regex_string.split(regex_string[1]) except IndexError: break # If we don't get four parts (even if the last is empty) # then it's not a valid regex - chastise them ... also, # if it's not one of the valid prefixes/suffixes, chastise them :) if len(parts) != 4 or \ parts[0] not in ACCEPTABLE_PREFIXES: message = "Invalid regular expression: " + regex_string return Event("privmsg", "", target, [message]) for letter in parts[3]: if letter not in ACCEPTABLE_SUFFIXES: message = "Invalid regular expression: " + regex_string return Event("privmsg", "", target, [message]) # Get some flags before we compile a regex if "g" in parts[3]: count = 0 else: count = 1 if "i" in parts[3]: case_sensitive = 0 else: case_sensitive = 1 # Make a regex object for the first pattern try: re_str = parts[1] if case_sensitive: regex = re.compile(re_str) else: regex = re.compile(re_str, re.I) except re.error: message = "Invalid regular expression: " + regex_string return Event("privmsg", "", target, [message]) # Actually perform the transformation if parts[0] == "s": factoid = regex.sub(parts[2], factoid) elif parts[0] == "y": message = "This regex not yet supported. Sorry :(" return Event("privmsg", "", target, [message]) # When all the regexes are applied, store the factoid again # with the new date as the modification date. FactoIds.update(factoid_key, factoid, args["source"]) return Event("privmsg", "", target, ["ok"])
def handler(self, **args): """ gets the factoid_value field """ import time from irclib import Event, nm_to_n # Store the ref # ref = args["ref"]() # If we were /msg'ed this, /msg it back, otherwise send it to the # channel # (set up here because there are some rather early returns for the # continue handler types and whatnot) target = self.return_to_sender(args) factoid_key = args["text"] factoid_key = self.strip_words(factoid_key, 1) # removes "moobot: " # By default we want to parse the factoid value after grabbing it from # the db, but certain flags along the way may set this flag so that we # don't do so (e.g., "literal"). dont_parse = 0 # If we are called with something like "moobot: literal foo", we want # to strip the "literal" from it as that is not part of the # factoid, unless of course nothing follows "literal", in which # case we would be looking for the factoid for "literal" if len(args["text"].split(" ")) > 1 and \ args["text"].split(" ")[1] == "literal": dont_parse = 1 # set for later, when we spit the value back factoid_key = self.strip_words(factoid_key, 1) # Strip trailing ?'s and !'s (so asking for "moobot: foo?!?!?!???" is # the same as just asking for "moobot: foo" factoid_key = self.strip_punctuation(factoid_key) text = FactoIds.getValueByKey(factoid_key, args["source"]) # If the factoid doesn't exist, simply continue trying # to match with other handlers using the continue event type if not text: return Event("continue", "", target, [""]) ### The new length stuff # Here we check to see if the total message length would be greater # than irclib.MESSAGE_SIZE_LIMIT, and if so, split it up accordingly # and return the requested one, or print out a warning. # Message format: # nickname!username@localhost privmsg #channel_name :factoid_text # self.debug("%s!%s@%s" % (ref.connection.ircname, # ref.connection.username, ref.connection.localhost)) # # msg_length = len(text) + len(" privmsg # :") + len(target) + \ # # len(ref.connection.nickname) + len(ref.connection.username) + \ # # len(ref.connection.localhost) # # self.debug(msg_length) # by default we will just say something to the target, but if the # factoid contains an <action> tag, we will make it an action # eventtype eventtype = "privmsg" # If the person says something like "moobot: literal foo", we don't # want to parse the factoid, we just want to spit it back in its raw # form. Otherwise, we want to replace parentheses and pipes as well # as see if we need to change the eventtype if not dont_parse: # awkward, but supports the more general case, # instead of having to set a flag for every case # where we DO want to parse, only set a flag where # we do NOT parse # Strip spaces from the left-hand side text = text.lstrip() # Parse parentheses and pipes to come up with one random string # from many choices specified in the factoid text = FactoIds.parseSar(text) # Replace $who and $nick with the person requesting the factoid text = text.replace("$who", nm_to_n(args["source"])) if args.has_key("channel"): text = text.replace("$chan", args["channel"]) text = text.replace("$nick", nm_to_n(args["source"])) # If the new string (after previous replacements) begins with # "<action>" or "<reply>" (case insensitive), then we strip them # and possibly change the eventtype if necessary. Otherwise, we # simply say "foo is bar" back to the target. if text[:8].lower() == "<action>": eventtype = "action" text = text[8:] elif text[:7].lower() == "<reply>": text = text[7:] else: text = factoid_key + " is " + text return Event(eventtype, "", target, [text.strip()])
def handler(self, **args): from irclib import Event, nm_to_n params = args['text'].strip().split(' ')[1:] cmd = params[0] params = params[1:] paramc = len(params) if paramc == 1 and params[0].lower() == 'help': msg = self.msg_help elif cmd == 'imspk' or cmd == 'imsnb' or cmd == 'imsbt': if paramc != 1 and paramc != 2: msg = self.msg_imspkhelp else: if paramc == 2: nick, rival = params else: nick = nm_to_n(args['source']) rival = params[0] if nick == rival: msg = "%s cannot pk her/himself" % (nick) else: birthday = Birthday(nick).get() if not birthday: msg = self.msgfmt_setbirtyday % (nick) else: rival_birthday = Birthday(rival).get() if not rival_birthday: msg = self.msgfmt_setbirtyday % (rival) else: today = ND() def sumIms(ims, absolute): if absolute: return abs(ims[0]) + abs(ims[1]) + abs(ims[2]) else: return ims[0] + ims[1] + ims[2] n_score = sumIms(self.calcIms(birthday, today), cmd == "imsbt") r_score = sumIms(self.calcIms(rival_birthday, today), cmd == "imsbt") if n_score == r_score: msg = "are %s and %s the same guy?" % (nick, rival) elif cmd == "imspk": if n_score > r_score: msg = "%s ROCKS and %s sucks today" % (nick, rival) elif n_score < r_score: msg = "%s sucks and %s ROCKS today" % (nick, rival) elif cmd == "imsnb": n_score = abs(n_score) r_score = abs(r_score) if n_score > r_score: msg = "%s is NBer than %s" % (nick, rival) elif n_score < r_score: msg = "%s is NBer than %s" % (rival, nick) elif cmd == "imsbt": if n_score > r_score: msg = "%s is BTer than %s" % (nick, rival) elif n_score < r_score: msg = "%s is BTer than %s" % (rival, nick) # 'ims here' elif paramc == 1 and self.pdate.search(params[0]): date = params[0] try: birthday = ND(date.split('-')) except: birthday = False if birthday: msg = self.calc(date, birthday) else: msg = "date error" elif paramc == 0 or paramc == 1: if paramc == 0: nick = nm_to_n(args['source']) elif paramc == 1: nick = params[0] b = Birthday(nick) birthday = b.get() if birthday: msg = self.calc(nick, birthday) else: msg = self.msgfmt_setbirtyday % (nick) else: msg = self.msg_help return Event("privmsg", "", self.return_to_sender(args), [ msg ])
def handler(self, **args): """when you say, for instance, hehstats, this function is called and reports your hehstats.""" import database from irclib import nm_to_n, Event target = self.return_to_sender(args) # Grab which type of stat we are trying to get # # Split into separate words, take the first word (which should be # "<type>stats"), and chop off the last five letters ("stats") type = args["text"].split(" ")[1][:-5] #type = args["text"] #type = type[type.find(" ")+1:] #type = type[:len(type)-5] # Grab the top 3 records=database.doSQL("select nick, counter from stats where type = '" + type + "' order by counter desc limit 3") stat=0 text = "Top 3 \"" + type +"\"ers" addUser = 1 while stat < 3 and stat < len(records) : text = text + " " + str(stat+1) + ") " + records[stat][0] + ": " + str(int(records[stat][1])) # If the user is in the top 3, no need to add their stats to the # end if records[stat][0] == nm_to_n(args["source"]): addUser = 0 stat=stat+1 # Grab the total stats and prepend them to the top 3 records=database.doSQL("select sum(counter) from stats where type='" + type + "'") total = records[0][0] text = '"' + type + '" said a total of ' + str(total)[:-2] + ' times. ' + text # If we need to add the user's stats on, grab them and add them if addUser == 1: # Find the user's place in the grand scheme # # First grab their totals usercount = database.doSQL("select counter from stats where type = '" + type + "' and nick = '" + nm_to_n(args["source"]) + "'") if len(usercount): usercount = usercount[0][0] else: usercount = 0 # Then see how many have stats query = "select count(nick) from stats where type='" + type + "'" total_users = database.doSQL(query)[0][0] # And lastly, see how many have better stats query = "select count(nick) from stats where type='" + type + \ "' and counter > " + str(usercount) beaten_by = database.doSQL(query)[0][0] + 1 text += " -- You have said \"" + type +"\" " + \ `int(usercount)` + " times, " + nm_to_n(args["source"]) + "." if usercount != 0: text += " You rank " + str(beaten_by) + " out of " + \ str(total_users) + "." return Event("privmsg", "", target, [ text ])