def help(event, bot): """ help [argument]. If argument is specified, get the help string for that command. Otherwise list all commands (same as commands function). """ cmd, arg = argumentSplit(event.argument, 2) # other modules should probably not do this: if cmd: cmd_mappings = blockingCallFromThread(reactor, _filter_mappings, bot, event.isPM, cmd) if cmd_mappings: for mapping in cmd_mappings: if arg: h = functionHelp(mapping.function, arg) if h: bot.say(h) else: bot.say("No help for (%s) available." % cmd) else: h = functionHelp(mapping.function) if h: command = mapping.command if isIterable(command) and len(command) > 1: bot.say("%s Aliases: %s" % (h, ", ".join(command))) else: bot.say(h) else: bot.say("No help for (%s) available." % cmd) else: bot.say("Command %s not found." % cmd) else: list_commands(bot, event.isPM())
def help(event, bot): #inspect.getdoc #eventmap[etype]["command"].setdefault(commandname, []).append(mapping) cmd, arg = argumentSplit(event.argument, 2) # other modules should not do this: if cmd: cmds = bot._settings.dispatcher.getCommandFuncs(cmd) if cmds: for func, command in cmds: if arg: h = functionHelp(func, arg) if h: bot.say(h) else: bot.say("No help for (%s) available." % cmd) else: h = functionHelp(func) if h: if isIterable(command): bot.say("%s Aliases: %s" % (h, ", ".join(command))) else: bot.say(h) else: bot.say("No help for (%s) available." % cmd) else: bot.say("Command %s not found." % cmd) else: cmds = bot._settings.dispatcher.getCommands() try: cmds.remove("eval") except ValueError: pass cmds.sort() bot.say(" ".join(cmds))
def alias(event, bot): """ alias [target] aliasname. If only aliasname is supplied, aliases for aliasname are retrieved. Otherwise if target is also supplied, aliasname will become an alias of target (can also be a group.) See addtional help for ~del. |alias ~del aliasname: will remove the alias aliasname. """ # API is bit different from olde bot, and then group things arg1, arg2 = argumentSplit(event.argument, 2) if arg1 == "~del": if arg2: return del_alias(bot, arg2) else: # show help for del return bot.say(functionHelp(alias, "~del")) elif arg1 and arg2: #binding a new alias if arg2.lower() == "me": return bot.say("But you are already yourself.") source = USERS_MODULE.get_username(bot, arg1, source=event.nick, _inalias=True) if not source: # ATTEMPT GROUP if aliasgroup(bot, arg1, arg2) is False: return bot.say("(%s) is not a group or a user I know." % arg1) else: return # else continue with normal user return aliasuser(bot, arg1, arg2, source) elif arg1: #querying an alias nick = lookup_alias(bot.dbQuery, arg1) if nick: aliases = alias_list(bot.dbQuery, nick) if aliases: msg = "Aliases for (%s): %%s" % arg1 title = "Aliases for (%s)" % arg1 return pastehelper(bot, msg, items=aliases, altmsg="%s", title=title) # unknown alias or no aliases: return bot.say("No aliases for (%s)" % arg1) # if none of the above, show help bot.say(functionHelp(alias)) return
def funicode(event, bot): """ unicode [character(s)/description/hex]. Displays information about provided characters (limit of 3,) or does a search on the character description or provides information on the character indexed by the given hexidecimal.""" arg = event.argument if not arg: return bot.say(functionHelp(funicode)) if REGHEX.match(arg): i = int(arg, 16) u = unichr(i) return bot.say(RPLFORMAT % (i, _getname(u), u)) elif len(arg) <= 3: output = [] for u in arg: output.append(RPLFORMAT % (ord(u), _getname(u), u)) return bot.say(", ".join(output)) else: output = [] for i, entry in CHARACTER_DESC: if len(output) > 8: break # could be lowered to improve performance if arg.lower() in entry.lower(): output.append(RPLFORMAT % (i, entry, unichr(i))) if output: return bot.say(", ".join(output)) else: return bot.say("No characters found.")
def tell(event, bot): """ tell target msg. Will tell a user <target> a message <msg>.""" target, msg = argumentSplit(event.argument, 2) if not target: return bot.say(bot.say(functionHelp(tell))) if not msg: return bot.say("Need something to tell (%s)" % target) users, unknown, dupes, hasself = _generate_users(bot, target, USERS_MODULE.get_username(bot, event.nick)) if not users: if hasself: return bot.say("Use notepad.") else: return bot.say("Sorry, don't know (%s)." % target) cmd = event.command.lower() targets = [] for user, target in users: #cmd user msg imsg = "%s %s %s" % (event.command, target, msg) # TODO: do we do an alias lookup on event.nick also? bot.dbQuery('''INSERT INTO tell(user, telltime, source, msg) VALUES (?,?,?,?);''', (user, int(timegm(gmtime())), event.nick, imsg)) targets.append(target) # check if we need to warn about too many tell pastebin # https://github.com/Clam-/pyBurlyBot/issues/29 #~ n = bot.dbQuery('''SELECT COUNT(id) AS C FROM tell WHERE user = ? AND delivered = ? AND telltime < ?;''', (user, 0, time()), fetchone)['C'] #~ if n > 3: #~ print "GUNNA WARNING" if len(users) > 1: bot.say(RPLFORMAT % (event.nick, PASSON if cmd == "tell" else ASKTHAT, english_list(targets), "are", UNKNOWN % english_list(unknown) if unknown else "", URSELF if hasself else "", MULTIUSER % "Telling" if dupes else "")) else: bot.say(RPLFORMAT % (event.nick, PASSON if cmd == "tell" else ASKTHAT, english_list(targets), "is", UNKNOWN % english_list(unknown) if unknown else "", URSELF if hasself else "", MULTIUSER % "Telling" if dupes else ""))
def tell(event, bot): """ tell target msg. Will tell a user <target> a message <msg>.""" target, msg = argumentSplit(event.argument, 2) if not target: return bot.say(functionHelp(tell)) if not msg: return bot.say("Need something to tell (%s)" % target) users, unknown, dupes, hasself = _generate_users(bot, target, USERS_MODULE.get_username(bot, event.nick)) if not users: if hasself: return bot.say("Use notepad.") else: return bot.say("Sorry, don't know (%s)." % target) cmd = event.command.lower() targets = [] for user, target in users: #cmd user msg imsg = "%s %s %s" % (event.command, target, msg) # TODO: do we do an alias lookup on event.nick also? bot.dbQuery('''INSERT INTO tell(user, telltime, source, msg) VALUES (?,?,?,?);''', (user, int(timegm(gmtime())), event.nick, imsg)) targets.append(target) # check if we need to warn about too many tell pastebin # https://github.com/Clam-/pyBurlyBot/issues/29 #~ n = bot.dbQuery('''SELECT COUNT(id) AS C FROM tell WHERE user = ? AND delivered = ? AND telltime < ?;''', (user, 0, time()), fetchone)['C'] #~ if n > 3: #~ print "GUNNA WARNING" if len(users) > 1: bot.say(RPLFORMAT % (event.nick, PASSON if cmd == "tell" else ASKTHAT, english_list(targets), "are", UNKNOWN % english_list(unknown) if unknown else "", URSELF if hasself else "", MULTIUSER % "Telling" if dupes else "")) else: bot.say(RPLFORMAT % (event.nick, PASSON if cmd == "tell" else ASKTHAT, english_list(targets), "is", UNKNOWN % english_list(unknown) if unknown else "", URSELF if hasself else "", MULTIUSER % "Telling" if dupes else ""))
def calc(event, bot): """ calc calcquery. Will use WolframAlpha to calc calcquery.""" if not event.argument: return bot.say(functionHelp(calc)) s = (("input", event.argument.encode("utf-8")), ("appid", API_KEY), ("reinterpret", "true"), ("format", "plaintext"), ("podstate", "Rhyme:WordData__More")) + EXCLUDE # TODO: use "units" param in conjunction with calling user's location. f = urlopen(URL % (urlencode(s)), timeout=15) if f.getcode() == 200: # http://effbot.org/zone/element-iterparse.htm # get an iterable #~ print f.read() #~ return context = iterparse(f, events=("start", "end")) # get the root element ievent, root = context.next() input = None results = [] error = "" pod = None podnames = [] priority = 50 for ievent, elem in context: if ievent == "start" and elem.tag == "pod": pod = elem.attrib["id"] podnames.append((pod, elem.attrib['title'])) # .split(None, 3)[:2] elif ievent == "end" and elem.tag == "msg": #assuming msg is only used for error, pls results.append("(Error: %s)" % elem.text) elem.clear() elif ievent == "end" and elem.tag == "plaintext": if pod == "Input": input = elem.text else: if elem.text: results.append([(pod, priority), "%s" % elem.text.replace("\n ", " ").replace("\n", " ").replace(" ", " ")]) priority += 1 elem.clear() elif ievent == "end": if elem.tag == "pod": pod = None elem.clear() root.clear() # sort results #~ print podnames, results if not results: if input: return bot.say("WolframAlpha doesn't know [%s]." % input) else: return bot.say("WolframAlpha doesn't know and doesn't understand your input.") for entry in results: if isinstance(entry, list): entry[0] = POD_PRIORITY.get(entry[0][0], entry[0][1]) results.sort() msg = u"[%s] {0}" % (input,) #~ print msg, results bot.say(msg, strins=[x[1] for x in results], fcfs=True, joinsep=u"\x02,\x02 ") else: bot.say("Dunno.")
def google_image(event, bot): """ gis searchterm. Will search Google images using the provided searchterm.""" if not event.argument: return bot.say(functionHelp(google_image)) spelling, results = GAPI_MODULE.google_image(event.argument, NUM_IMGS) #TODO: consider displaying img stats like file size and resolution? if results: entries = [] # TODO: the following should probably be handled in the smart unicode cropping thing # or in a smarter generic result splitter thing. # TODO: (also) this is basically double iterating over the results. Griff fix later please, thanks. for item in results: if entries: entries.append(RESULT_IMG2 % (item[0], item[1])) else: entries.append(RESULT_IMG % (item[0], item[1])) if len(entries) < NUM_IMGS: entries = entries+[""]*(NUM_IMGS-len(l)) if spelling: bot.say(RESULTS_SPELL_IMG % spelling, fcfs=True, strins=entries) else: bot.say(RESULTS_IMG, fcfs=True, strins=entries) else: if spelling: bot.say("(SP: %s) No results found." % spelling) else: bot.say("No results found.")
def logsearch(event, bot): """ log [n] [searchterm]. Will search logs for searchterm. n is the number of results to display [1-99], default is 6 and anything over will be output to pastebin. """ iproxy = INDEX_PROXIES.get(bot.network) if iproxy: # parse input if not event.argument: return bot.say(functionHelp(logsearch)) n, q = argumentSplit(event.argument, 2) try: n = int(n) if n > 99: raise ValueError elif n < 0: raise ValueError if n == 0: n = None q = q except ValueError: q = event.argument n = 6 results = iproxy.search(event.target, q, n) if results is None: bot.say("Log search error happened. Check console.") else: #results.append((item["timestamp"], item["nick"], item["source"], item["content"])) if not results: return bot.say("No results.") if n > 6 or n is None: title = "Logsearch for (%s)" % q body = "%s: %%s" % title pastehelper(bot, body, items=(LOG_FORMAT % (x[1], x[3]) for x in results), title=title, altmsg="%s", force=True) else: bot.say("{0}", fcfs=True, strins=[LOG_FORMAT % (x[1], x[3]) for x in results], joinsep=u"\x02 | \x02")
def wiki(event, bot): """ wiki \x02searchterm\x02. Will search Wikipedia for \x02searchterm\x02. """ if not event.argument: return bot.say(functionHelp(wiki)) result = search(event.argument, results=1, suggestion=True) if not result[0]: if result[1]: return bot.say("No results found. Did you mean \x02%s\x02?" % result[1]) else: return bot.say("No results found.") errors = [] attempt = 0 p = None try: p = page(result[0]) # use preload=True when it's fixed: https://github.com/goldsmith/Wikipedia/issues/78 except DisambiguationError as e: errors.append("Random disambig page: ") while attempt < 3: try: p = page(choice(e.options)) except DisambiguationError: pass attempt += 1 if not p: return bot.say("Gave up looking for disambiguous entry from disambiguous page.") if result[1]: errors.append("(SP: %s?) " % result[1]) content = p.content[:800].replace("\n", " ").replace("====", "").replace("===", "").replace("==", "") bot.say(RESULT_RPL % ("".join(errors), p.url), strins=[p.title, content], fcfs=True)
def fdecode(event, bot): """ decode encoding content. content will be decoded according to provided encoding. Will be displayed using python's repr if not unicode. Available encodings: https://docs.python.org/2/library/codecs.html#standard-encodings . Append |repr to the method if you are supplying escaped ascii. """ method, content = argumentSplit(event.argument, 2) if not (method and content): return bot.say(functionHelp(fdecode)) # some crazy voodoo try: try: if method.endswith("|repr"): o = content.decode("string_escape").decode(method[:-5]) else: o = content.decode(method) if isinstance(o, unicode): bot.say(o) else: bot.say(repr(o)) except (UnicodeEncodeError, UnicodeDecodeError): if method.endswith("|repr"): o = content.encode("utf-8").decode("string_escape").decode(method[:-5]) else: o = content.encode("utf-8").decode(method) if isinstance(o, unicode): bot.say(o) else: bot.say(repr(o)) except LookupError: bot.say("Unknown encoding. Available encodings: https://docs.python.org/2/library/codecs.html#standard-encodings") except (UnicodeEncodeError, UnicodeDecodeError): bot.say("Can't decode.")
def alias(event, bot): """ alias [target] aliasname. If only aliasname is supplied, aliases for aliasname are retrieved. Otherwise if target is also supplied, aliasname will become an alias of target (can also be a group.) See addtional help for ~del. |alias ~del aliasname: will remove the alias aliasname. """ # API is bit different from olde bot, and then group things arg1, arg2 = argumentSplit(event.argument, 2) if arg1 == "~del": if arg2: return del_alias(arg2) else: # show help for del return bot.say(functionHelp(alias, "~del")) elif arg1 and arg2: #binding a new alias if arg2.lower() == "me": return bot.say("But you are already yourself.") source = USERS_MODULE.get_username(bot, arg1, source=event.nick, _inalias=True) if not source: # ATTEMPT GROUP if aliasgroup(bot, arg1, arg2) is False: return bot.say("(%s) is not a group or a user I know." % arg1) else: return # else continue with normal user return aliasuser(bot, arg1, arg2, source) elif arg1: #querying an alias nick = lookup_alias(bot.dbQuery, arg1) if nick: aliases = alias_list(bot.dbQuery, nick) if aliases: msg = "Aliases for (%s): %%s" % arg1 title = "Aliases for (%s)" % arg1 return pastehelper(bot, msg, items=aliases, altmsg="%s", title=title) # unknown alias or no aliases: return bot.say("No aliases for (%s)" % arg1) # if none of the above, show help bot.say(functionHelp(alias)) return
def synonym(event, bot): """ synonym [query]. Returns synonyms for query.""" if not event.argument: return bot.say(functionHelp(synonym)) syns = WORD_API.word_synonyms(event.argument) if syns is None: return spelling(event, bot, skipSearch=True) elif not syns: return bot.say("No synonyms found for \x02%s\x02" % event.argument) else: return bot.say("Synonyms for (%s): %s" % (event.argument, ", ".join(syns)))
def do_choice(event, bot): """ choice [value...]. choice will randomly select one of the given values, or if only one value a random character from the given value.""" if not event.argument: return bot.say(functionHelp(do_choice)) values = argumentSplit(event.argument, -1) if len(values) == 1: values = values[0] elif len(set(values)) == 1: # Only duplicate values return bot.say("%s, obviously." % values[0]) return bot.say("%s" % choice(values))
def unsubscripe(event, bot): """ unsubscripe groupname. unsubscripe will remove you from group groupname""" user = USERS_MODULE.get_username(bot, event.nick, _inalias=True) if not user: return bot.say("Do I know you?") if event.argument: gtarget = get_groupname(bot.dbQuery, event.argument) if not gtarget: return bot.say("Group (%s) not found." % event.argument) if not group_check(bot.dbQuery, gtarget, user): return bot.say("You aren't a member of (%s)." % gtarget) bot.dbQuery('''DELETE FROM aliasgrp WHERE grp = ? AND user = ?;''', (gtarget, user)) return bot.say("You have been removed from (%s) group." % gtarget) else: bot.say(functionHelp(unsubscripe))
def dictionary(event, bot): """ dictionary [query]. Returns definitions for query.""" if not event.argument: return bot.say(functionHelp(dictionary)) defs = WORD_API.word_search(event.argument) if not defs: return spelling(event, bot, skipSearch=True) # pre process list output = [] # could turn all this in to one huge comprehension but no. for p,ds in defs: ds = "; ".join((d[:-1] if d[:-1] == ":" else d for d in ds)) # strip trailing ":" output.append("%s: %s" % (p, ds)) return bot.say(". ".join(output))
def dictionary(event, bot): """ dictionary [query]. Returns definitions for query.""" if not event.argument: return bot.say(functionHelp(dictionary)) defs = WORD_API.word_search(event.argument) if not defs: return spelling(event, bot, skipSearch=True) # pre process list output = [] # could turn all this in to one huge comprehension but no. for p, ds in defs: ds = "; ".join( (d[:-1] if d[:-1] == ":" else d for d in ds)) # strip trailing ":" output.append("%s: %s" % (p, ds)) return bot.say(". ".join(output))
def fencode(event, bot): """ encode encoding content. content will be encoded according to provided encoding. Will be displayed using python's repr. Available encodings: https://docs.python.org/2/library/codecs.html#standard-encodings """ method, content = argumentSplit(event.argument, 2) if not (method and content): return bot.say(functionHelp(fencode)) try: try: bot.say(repr(content.encode(method))) except (UnicodeEncodeError, UnicodeDecodeError): bot.say(repr(content.encode("utf-8").encode(method))) except LookupError: bot.say("Unknown encoding. Available encodings: https://docs.python.org/2/library/codecs.html#standard-encodings") except (UnicodeEncodeError, UnicodeDecodeError): bot.say("Can't encode.")
def hash(event, bot): """ hash method content. content will be hashed according to method (after encoding to UTF-8.) Use "hash methods" to see what methods are supported.""" method, content = argumentSplit(event.argument, 2) if not (method and content): if method == "methods": if algorithms_available: return bot.say("Supported hash methods: %s" % ", ".join(algorithms_available)) else: return bot.say("Supported hash methods: %s" % ", ".join(algorithms)) return bot.say(functionHelp(hash)) if (algorithms_available and (method not in algorithms_available)) or (not algorithms_available and method not in algorithms): return bot.say("Unknown method (%s). Use \x02hash methods\x02 to see what methods are supported.") h = new(method) h.update(content.encode("utf-8")) bot.say("%s - %s" % (h.hexdigest(), repr(content)))
def samplecommand(event, bot): """ samplecommand [option] [argument]. samplecommand will do things depending on what option is used. Available option: something, dothing |samplecommand something [argument]: will output "something", and if argument is present, will follow. |samplecommand dothing [argument]: will output argument if it exists, followed by "dothing" """ #do some things command, args = commandSplit(event.argument) if command == "something": if args: bot.say("%s %s" % (command, args)) else: bot.say("%s" % command) elif command == "dothing": if args: bot.say("%s %s" % (args, command)) else: bot.say("%s" % command) else: bot.say(functionHelp(samplecommand))
def google(event, bot): """ google searchterm. Will search Google using the provided searchterm.""" if not event.argument: return bot.say(functionHelp(google)) spelling, results = GAPI_MODULE.google(event.argument) if results: item = results[0] if spelling: rpl = RESULT_SPELL_TEXT % (spelling, item[2]) else: rpl = RESULT_TEXT % item[2] bot.say(rpl, fcfs=True, strins=[item[0], item[1]]) else: if spelling: bot.say("(SP: %s) No results found." % spelling) else: bot.say("No results found.")
def samplecommand(event, bot): """ samplecommand [option] [argument]. samplecommand will do things depending on what option is used. Available option: something, dothing |samplecommand something [argument]: will output "something", and if argument is present, will follow. |samplecommand dothing [argument]: will output argument if it exists, followed by "dothing" """ #do some things command, args = commandSplit(event.argument) if command == "something": if args: bot.say("%s %s" % (command, args)) else : bot.say("%s" % command) elif command == "dothing": if args: bot.say("%s %s" % (args, command)) else : bot.say("%s" % command) else: bot.say(functionHelp(samplecommand))
def steamchatcmd(event, bot): """ steamchat [kick user]. steamchat without arguments will display currently joined/listening steam persons. steamchat kick user will kick the supplied user from listening/sending to this channel. """ if event.argument: command, argument = commandSplit(event.argument) if command == "kick" and argument: cthread = CHAT_THREADS.get(bot.network) if cthread: cthread.fromIRC("kickUser", event.nick if event.isPM() else event.target, argument) else: bot.say("Error: No Steamchat available for this network.") else: bot.say(functionHelp(steamchatcmd)) else: #list all cthread = CHAT_THREADS.get(bot.network) if cthread: cthread.fromIRC("listUsers", event.nick if event.isPM() else event.target) else: bot.say("Error: No Steamchat available for this network.")
def spelling(event, bot, skipSearch=False): """ spelling [query]. Returns spelling suggestions for query.""" if not event.argument: return bot.say(functionHelp(spelling)) suggestions = WORD_API.spell_check(event.argument, skipSearch) #TODO: Consider using googleapi to do a first pass if suggestions is None: return bot.say("\x02%s\x02 is spelt correct." % event.argument) else: if suggestions: return bot.say("Spelling suggestions: %s" % ", ".join(suggestions)) else: try: suggestion, _ = bot.getModule("pbm_googleapi").google(event.argument) if suggestion: return bot.say("Google suggests: %s" % suggestion) except ConfigException: pass return bot.say("\x02%s\x02 is spelt wrong but I don't have any suggestions, sorry." % event.argument)
def spelling(event, bot, skipSearch=False): """ spelling [query]. Returns spelling suggestions for query.""" if not event.argument: return bot.say(functionHelp(spelling)) suggestions = WORD_API.spell_check(event.argument, skipSearch) #TODO: Consider using googleapi to do a first pass if suggestions is None: return bot.say("\x02%s\x02 is spelt correct." % event.argument) else: if suggestions: return bot.say("Spelling suggestions: %s" % ", ".join(suggestions)) else: try: suggestion, _ = bot.getModule("google.api").google( event.argument) if suggestion: return bot.say("Google suggests: %s" % suggestion) except ConfigException: pass return bot.say( "\x02%s\x02 is spelt wrong but I don't have any suggestions, sorry." % event.argument)
def wiki(event, bot): """ wiki \x02searchterm\x02. Will search Wikipedia for \x02searchterm\x02. """ if not event.argument: return bot.say(functionHelp(wiki)) result = search(event.argument, results=1, suggestion=True) if not result[0]: if result[1]: return bot.say("No results found. Did you mean \x02%s\x02?" % result[1]) else: return bot.say("No results found.") errors = [] attempt = 0 p = None try: p = page( result[0] ) # use preload=True when it's fixed: https://github.com/goldsmith/Wikipedia/issues/78 except DisambiguationError as e: errors.append("Random disambig page: ") while attempt < 3: try: p = page(choice(e.options)) except DisambiguationError: pass attempt += 1 if not p: return bot.say( "Gave up looking for disambiguous entry from disambiguous page.") if result[1]: errors.append("(SP: %s?) " % result[1]) content = p.content[:800].replace("\n", " ").replace("====", "").replace( "===", "").replace("==", "") bot.say(RESULT_RPL % ("".join(errors), p.url), strins=[p.title, content], fcfs=True)
def rot13(event, bot): """ rot13 content. content will be rot13 encoded.""" arg = event.argument if not arg: return bot.say(functionHelp(rot13)) bot.say(arg.encode("rot13", "ignore"))
def config(event, bot): """ config serverchannel module opt [value]. serverchannel = servername:#channel (channel on server) or servername (default for server) or :#channel (channel globally) or #channel (channel on this server) or "-" (default) or "this" (current channel (unless PM) current server.) module = "-" for non-module options. value should be JSON """ command = "" if event.argument == "save": blockingCallFromThread(reactor, Settings.saveOptions) bot.say("Done (save is automatically done when setting config values.)") return elif event.argument: servchan, module, opt, value = argumentSplit(event.argument, 4) else: return bot.say(functionHelp(config)) # set or get value if servchan and module and opt: server, channel = servchanParse(servchan) if opt in PRIVATE_OPTIONS and not event.isPM(): if value: return bot.say("Use PM to set this option. If this is a password you probably want to change it now.") else: return bot.say("Use PM to get this option.") if module == "-": module = None else: if not bot.isModuleAvailable(module): return bot.say("module %s not available" % module) modopts = bot.getModule(module) if hasattr(modopts, "OPTIONS"): modopts = modopts.OPTIONS else: modopts = {} # set value if value: try: value = loads(value) except Exception as e: return bot.say("Error: %s" % e) tvalue = type(value) #get type for module type checking: if module and opt in modopts: t = modopts[opt][0] if not (t is tvalue): return bot.say("Incorrect type of %s: %s. Require %s." % (opt, tvalue, t)) msg = "Set %%s(%%s) to %%s (was: %s)" old = EmptyValue try: old = bot.getOption(opt, server=server, channel=channel, module=module) msg = msg % dumps(old) except AttributeError: msg = msg % "unset" except Exception as e: return bot.say("Error: %s" % e) # check type of non module option: # TODO: some things won't be able to have the same type, like set for modules, allowmodules and such. What do? # Use properties like .admins ?? if not module and (old is not EmptyValue): t = type(old) if not t is tvalue: return bot.sat("Incorrect type of %s: %s. Require %s." % (opt, tvalue, t)) try: bot.setOption(opt, value, server=server, channel=channel, module=module) except Exception as e: return bot.say("Error: %s" % e) blockingCallFromThread(reactor, Settings.saveOptions) bot.say(msg % (opt, servchan, dumps(value))) #get value else: try: value = dumps(bot.getOption(opt, server=server, channel=channel, module=module)) except Exception as e: return bot.say("Error: %s" % e) if module and opt in modopts: t, desc, default = modopts[opt] bot.say("Setting for %s(%s) is %s. %s Type: %s, Default: %s" % (opt, servchan, value, desc, t.__name__, dumps(default))) else: bot.say("Setting for %s(%s) is %s" % (opt, servchan, value)) else: return bot.say(functionHelp(config))
def md5(event, bot): """ md5 content. content will be md5 hashed (after encoding to UTF-8.)""" arg = event.argument if not arg: return bot.say(functionHelp(md5)) bot.say("%s - %s" % (md5(arg.encode("utf-8")).hexdigest(), repr(arg)))
def calc(event, bot): """ calc calcquery. Will use WolframAlpha to calc calcquery.""" if not event.argument: return bot.say(functionHelp(calc)) s = (("input", event.argument.encode("utf-8")), ("appid", API_KEY), ("reinterpret", "true"), ("format", "plaintext"), ("podstate", "Rhyme:WordData__More")) + EXCLUDE # TODO: use "units" param in conjunction with calling user's location. f = urlopen(URL % (urlencode(s)), timeout=15) if f.getcode() == 200: # http://effbot.org/zone/element-iterparse.htm # get an iterable #~ print f.read() #~ return context = iterparse(f, events=("start", "end")) # get the root element ievent, root = context.next() input = None results = [] error = "" pod = None podnames = [] priority = 50 for ievent, elem in context: if ievent == "start" and elem.tag == "pod": pod = elem.attrib["id"] podnames.append( (pod, elem.attrib['title'])) # .split(None, 3)[:2] elif ievent == "end" and elem.tag == "msg": #assuming msg is only used for error, pls results.append("(Error: %s)" % elem.text) elem.clear() elif ievent == "end" and elem.tag == "plaintext": if pod == "Input": input = elem.text else: if elem.text: results.append([ (pod, priority), "%s" % elem.text.replace("\n ", " ").replace( "\n", " ").replace(" ", " ") ]) priority += 1 elem.clear() elif ievent == "end": if elem.tag == "pod": pod = None elem.clear() root.clear() # sort results #~ print podnames, results if not results: if input: return bot.say("WolframAlpha doesn't know [%s]." % input) else: return bot.say( "WolframAlpha doesn't know and doesn't understand your input." ) for entry in results: if isinstance(entry, list): entry[0] = POD_PRIORITY.get(entry[0][0], entry[0][1]) results.sort() msg = "[%s] {0}" % (input, ) #~ print msg, results bot.say(msg, strins=[x[1] for x in results], fcfs=True, joinsep="\x02,\x02 ") else: bot.say("Dunno.")
def simplecommands(event, bot): """ simplecommands [(~del, ~list)] input[,alias1,alias2,...] output. Simple interface for adding/removing simplecommands. If only input is supplied, output is retrieved. If ~del is specified, input is deleted if found. e.g. .simplecommands google google.com """ arg1, arg2 = argumentSplit(event.argument, 2) commands = bot.getOption("commands", module="pbm_simplecommands") if not arg1: return bot.say(functionHelp(simplecommands)) elif arg1 == '~list': commands = bot.getOption("commands", module="pbm_simplecommands") cmdlist = [] commands.sort() for command, output in commands: if isinstance(command, (list, tuple)) and len(command) > 1: cmdlist.append('(%s)' % ', '.join(command)) else: cmdlist.extend(command) return bot.say('Simplecommands: %s' % ', '.join(cmdlist)) elif arg1 == '~del' and arg2: match = None temp_match = None newcmds = arg2.split(',') for index, command in enumerate(commands): for newcmd in newcmds: if (isinstance(command[0], list) and newcmd in command[0]) or newcmd == command[0]: temp_match = commands[index] if temp_match: if match: return bot.say( 'Simplecommand specified (%s) matches more than one simplecommand: (%s) and (%s)' % (arg2, ', '.join(temp_match[0]), ', '.join(match[0]))) match = temp_match temp_match = None if not match: return bot.say('(%s) is not a known simplecommand.' % arg2) commands.remove(match) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say('Simplecommand (%s) deleted. Options saved. Reloading...' % arg2) blockingCallFromThread(reactor, _reallyReload) return bot.say('Done.') elif arg2: match = None temp_match = None newcmds = arg1.split(',') for index, command in enumerate(commands): for newcmd in newcmds: if (isinstance(command[0], list) and newcmd in command[0]) or newcmd == command[0]: temp_match = commands[index] if temp_match: if match: return bot.say( 'Simplecommand specified (%s) matches more than one simplecommand: (%s) and (%s)' % (arg1, ', '.join(temp_match[0]), ', '.join(match[0]))) match = temp_match temp_match = None # Replace an existing simplecommand if match: if len(match[0]) > 1: return bot.say( "Can't modify simplecommand with multiple input mappings (%s), \ delete it first with \x02~del %s\x02 and recreate it." % (', '.join(match[0]), arg1)) commands.remove(match) commands.append([arg1.split(','), arg2]) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say( 'Simplecommand (%s) replaced. Options saved. Reloading...' % arg1) blockingCallFromThread(reactor, _reallyReload) bot.say('Done.') # Add a new simplecommand else: # TODO: Yeah, this probably isn't good -- or maybe it's fine for cmd in newcmds: ret = bot._settings.dispatcher._getCommandMappings(cmd.lower()) if ret: return bot.say( 'Command (%s) already in use by the \x02%s\x02 module.' % (cmd, ret[0].function.__module__)) commands.append([arg1.split(','), arg2]) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say('Simplecommand (%s) added. Options saved. Reloading...' % arg1) blockingCallFromThread(reactor, _reallyReload) bot.say('Done.') else: match = None for command, output in commands: if isinstance(command, list) and arg1 in command: match = (command, output) if not match: return bot.say('(%s) is not a known simplecommand.' % arg1) bot.say('Simplecommand (%s): %s' % (', '.join(match[0]), match[1]))
def group(event, bot): """ group [groupname [user]]. group will display all groups. If groupname is supplied will list all users in group. If groupname and user, add user to group groupname. See additional help for ~del. |group ~del groupname [user]. ~del groupname will remove entire group (admin.) ~del groupname user will remove user from group. """ arg1, arg2 = argumentSplit(event.argument, 2) if arg1 == "~del": arg1, arg2, arg3 = argumentSplit(event.argument, 3) # rebind arguments for more params # do a delete on group if arg2 and arg3: # assume arg2 is a groupname to remove arg3 from group = get_groupname(bot.dbQuery, arg2) if group: nick = USERS_MODULE.get_username(bot, arg3, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found." % arg3) if group_check(group, nick): bot.dbQuery('''DELETE FROM aliasgrp WHERE grp = ? AND user = ?;''', (group, nick)) return bot.say("Removed (%s) from (%s)" % (nick, group)) else: return bot.say("User (%s) not found in group (%s)" % (nick, group)) else: return bot.say("Group (%s) not found." % arg2) elif arg2: #remove entire group if not bot.isadmin(): return bot.say("Sry.") group = get_groupname(bot.dbQuery, arg2) if group: # delete aliases then group bot.dbBatch( ('''DELETE FROM aliasgrpalias WHERE grp = ?;''', (group,), '''DELETE FROM aliasgrp WHERE grp = ?;''', (group,)) ) return bot.say("Removed group (%s)" % arg3) else: return bot.say("Group (%s) not found." % arg3) else: # ~del help return bot.say(functionHelp(group, "~del")) if arg2: # check if group is already a user first: target = lookup_alias(bot.dbQuery, arg1) # check target if target: return bot.say("Group (%s) is in use by an alias/user already." % arg1) # binding to a group nick = USERS_MODULE.get_username(bot, arg2, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found or seen." % arg2) # unalias group group = get_groupname(bot.dbQuery, arg1) if not group: # add new group, so create dummy alias entry: add_groupalias(bot.dbQuery, arg1, arg1) group = arg1 if group_check(bot.dbQuery, group, nick): return bot.say("User (%s) is already a member of (%s)." % (nick, group)) group_add(bot.dbQuery, group, nick) return bot.say("User (%s) added to group (%s)." % (nick, group)) elif arg1: return listgroupusers(bot, arg1) # if nothing else show help return listgroups(bot)
def group(event, bot): """ group [groupname [user]]. group will display all groups. If groupname is supplied will list all users in group. If groupname and user, add user to group groupname. See additional help for ~del. |group ~del groupname [user]. ~del groupname will remove entire group (admin.) ~del groupname user will remove user from group. """ arg1, arg2 = argumentSplit(event.argument, 2) if arg1 == "~del": arg1, arg2, arg3 = argumentSplit(event.argument, 3) # rebind arguments for more params # do a delete on group if arg2 and arg3: # assume arg2 is a groupname to remove arg3 from group = get_groupname(bot.dbQuery, arg2) if group: nick = USERS_MODULE.get_username(bot, arg3, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found." % arg3) if group_check(group, nick): bot.dbQuery( '''DELETE FROM aliasgrp WHERE grp = ? AND user = ?;''', (group, nick)) return bot.say("Removed (%s) from (%s)" % (nick, group)) else: return bot.say("User (%s) not found in group (%s)" % (nick, group)) else: return bot.say("Group (%s) not found." % arg2) elif arg2: #remove entire group if not bot.isadmin(): return bot.say("Sry.") group = get_groupname(bot.dbQuery, arg2) if group: # delete aliases then group bot.dbBatch( ('''DELETE FROM aliasgrpalias WHERE grp = ?;''', (group, ), '''DELETE FROM aliasgrp WHERE grp = ?;''', (group, ))) return bot.say("Removed group (%s)" % arg3) else: return bot.say("Group (%s) not found." % arg3) else: # ~del help return bot.say(functionHelp(group, "~del")) if arg2: # check if group is already a user first: target = lookup_alias(bot.dbQuery, arg1) # check target if target: return bot.say("Group (%s) is in use by an alias/user already." % arg1) # binding to a group nick = USERS_MODULE.get_username(bot, arg2, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found or seen." % arg2) # unalias group group = get_groupname(bot.dbQuery, arg1) if not group: # add new group, so create dummy alias entry: add_groupalias(bot.dbQuery, arg1, arg1) group = arg1 if group_check(bot.dbQuery, group, nick): return bot.say("User (%s) is already a member of (%s)." % (nick, group)) group_add(bot.dbQuery, group, nick) return bot.say("User (%s) added to group (%s)." % (nick, group)) elif arg1: return listgroupusers(bot, arg1) # if nothing else show help return listgroups(bot)
def config(event, bot): """ config serverchannel module opt [value]. serverchannel = servername:#channel (channel on server) or servername (default for server) or :#channel (channel globally) or #channel (channel on this server) or "-" (default) or "this" (current channel (unless PM) current server.) module = "-" for non-module options. value should be JSON """ command = "" if event.argument == "save": blockingCallFromThread(reactor, Settings.saveOptions) bot.say( "Done (save is automatically done when setting config values.)") return elif event.argument: servchan, module, opt, value = argumentSplit(event.argument, 4) else: return bot.say(functionHelp(config)) # set or get value if servchan and module and opt: server, channel = servchanParse(servchan) if opt in PRIVATE_OPTIONS and not event.isPM(): if value: return bot.say( "Use PM to set this option. If this is a password you probably want to change it now." ) else: return bot.say("Use PM to get this option.") if module == "-": module = None else: if not bot.isModuleAvailable(module): return bot.say("module %s not available" % module) modopts = bot.getModule(module) if hasattr(modopts, "OPTIONS"): modopts = modopts.OPTIONS else: modopts = {} # set value if value: try: value = loads(value) except Exception as e: return bot.say("Error: %s" % e) tvalue = type(value) #get type for module type checking: if module and opt in modopts: t = modopts[opt][0] if not (t is tvalue): return bot.say("Incorrect type of %s: %s. Require %s." % (opt, tvalue, t)) msg = "Set %%s(%%s) to %%s (was: %s)" old = EmptyValue try: old = bot.getOption(opt, server=server, channel=channel, module=module) msg = msg % dumps(old) except AttributeError: msg = msg % "unset" except Exception as e: return bot.say("Error: %s" % e) # check type of non module option: # TODO: some things won't be able to have the same type, like set for modules, allowmodules and such. What do? # Use properties like .admins ?? if not module and (old is not EmptyValue): t = type(old) if not t is tvalue: return bot.sat("Incorrect type of %s: %s. Require %s." % (opt, tvalue, t)) try: bot.setOption(opt, value, server=server, channel=channel, module=module) except Exception as e: return bot.say("Error: %s" % e) blockingCallFromThread(reactor, Settings.saveOptions) bot.say(msg % (opt, servchan, dumps(value))) #get value else: try: value = dumps( bot.getOption(opt, server=server, channel=channel, module=module)) except Exception as e: return bot.say("Error: %s" % e) if module and opt in modopts: t, desc, default = modopts[opt] bot.say( "Setting for %s(%s) is %s. %s Type: %s, Default: %s" % (opt, servchan, value, desc, t.__name__, dumps(default))) else: bot.say("Setting for %s(%s) is %s" % (opt, servchan, value)) else: return bot.say(functionHelp(config))
def fquote(event, bot): """ quote content. content will be URL encoded.""" arg = event.argument if not arg: return bot.say(functionHelp(fquote)) bot.say(quote(arg.encode("utf-8")))
def crc(event, bot): """ crc content. content will be crc32 encoded (after encoding to utf-8.)""" arg = event.argument if not arg: return bot.say(functionHelp(crc)) bot.say("%x - %s" % (crc32(arg.encode("utf-8")) & 0xffffffff, repr(arg)))
def alert(event, bot): """ alert target datespec msg. Alert a user <target> about a message <msg> at <datespec> time. datespec can be relative (in) or calendar/day based (on), e.g. 'in 5 minutes'""" target, dtime1, dtime2, msg = argumentSplit(event.argument, 4) if not target: return bot.say(functionHelp(alert)) if dtime1.lower() == "tomorrow": target, dtime1, msg = argumentSplit(event.argument, 3) # reparse is easiest way I guess... resolves #30 if need to readdress dtime2 = "" else: if not (dtime1 and dtime2): return bot.say("Need time to alert.") if not msg: return bot.say("Need something to alert (%s)" % target) origuser = USERS_MODULE.get_username(bot, event.nick) users, unknown, dupes, _ = _lookup_users(bot, target, origuser, False) if not users: return bot.say("Sorry, don't know (%s)." % target) dtime = "%s %s" % (dtime1, dtime2) # user location aware destination times locmod = None goomod = None timelocale = False try: locmod = bot.getModule("pbm_location") goomod = bot.getModule("pbm_googleapi") timelocale = True except ConfigException: pass origin_time = timegm(gmtime()) alocal_time = localtime(origin_time) local_offset = timegm(alocal_time) - origin_time if locmod and goomod: t = origin_time loc = locmod.getlocation(bot.dbQuery, origuser) if not loc: timelocale = False t = alocal_time else: tz = goomod.google_timezone(loc[1], loc[2], t) if not tz: timelocale = False t = alocal_time else: t = gmtime(t + tz[2] + tz[3]) #[2] dst [3] timezone offset else: t = alocal_time ntime = parseDateTime(dtime, t) if not ntime: return bot.say("Don't know what time and/or day and/or date (%s) is." % dtime) # go on, change it. I dare you. if timelocale: t = timegm(t) - tz[2] - tz[3] ntime = ntime - tz[2] - tz[3] else: t = timegm(t) - local_offset ntime = ntime - local_offset if ntime < t or ntime > (t + MAX_REMIND_TIME): return bot.say("Don't sass me with your back to the future alerts.") if ntime < (t + 5): return bot.say("2fast") targets = [] for user, target in users: if user == origuser: source_user = None else: source_user = event.nick if event.isPM(): chan_or_user = event.nick else: chan_or_user = event.target bot.dbQuery('''INSERT INTO alert(target_user, alert_time, created_time, source, source_user, msg) VALUES (?,?,?,?,?,?);''', (user, int(ntime), int(origin_time), chan_or_user, source_user, msg)) if ntime < (t + LOOP_INTERVAL): Timers.restarttimer(TIMER_NAME) if not source_user: targets.append("you") else: targets.append(target) bot.say(RPL_ALERT_FORMAT % (event.nick, english_list(targets), distance_of_time_in_words(ntime, t), UNKNOWN % english_list(unknown) if unknown else "", MULTIUSER % "Alerting" if dupes else ""))
def remind(event, bot): """ remind target datespec msg. Will remind a user <target> about a message <msg> at <datespec> time. datespec can be relative (in) or calendar/day based (on), e.g. 'in 5 minutes'""" target, dtime1, dtime2, msg = argumentSplit(event.argument, 4) if not target: return bot.say(functionHelp(tell)) if dtime1.lower() == "tomorrow": target, dtime1, msg = argumentSplit(event.argument, 3) # reparse is easiest way I guess... resolves #30 if need to readdress dtime2 = "" else: if not (dtime1 and dtime2): return bot.say("Need time to remind.") if not msg: return bot.say("Need something to remind (%s)" % target) origuser = USERS_MODULE.get_username(bot, event.nick) users, unknown, dupes, _ = _generate_users(bot, target, origuser, False) if not users: return bot.say("Sorry, don't know (%s)." % target) dtime = "%s %s" % (dtime1, dtime2) # user location aware destination times locmod = None goomod = None timelocale = False try: locmod = bot.getModule("pbm_location") goomod = bot.getModule("pbm_googleapi") timelocale = True except ConfigException: pass origintime = timegm(gmtime()) alocaltime = localtime(origintime) localoffset = timegm(alocaltime) - origintime if locmod and goomod: t = origintime loc = locmod.getlocation(bot.dbQuery, origuser) if not loc: timelocale = False t = alocaltime else: tz = goomod.google_timezone(loc[1], loc[2], t) if not tz: timelocale = False t = alocaltime else: t = gmtime(t + tz[2] + tz[3]) #[2] dst [3] timezone offset else: t = alocaltime ntime = parseDateTime(dtime, t) if not ntime: return bot.say("Don't know what time and/or day and/or date (%s) is." % dtime) # go on, change it. I dare you. if timelocale: t = timegm(t) - tz[2] - tz[3] ntime = ntime - tz[2] - tz[3] else: t = timegm(t) - localoffset ntime = ntime - localoffset if ntime < t or ntime > t+MAX_REMIND_TIME: return bot.say("Don't sass me with your back to the future reminds.") targets = [] for user, target in users: if user == origuser: source = None else: source = event.nick bot.dbQuery('''INSERT INTO tell(user, telltime, origintime, remind, source, msg) VALUES (?,?,?,?,?,?);''', (user, int(ntime), int(origintime), 1, source, msg)) if not source: targets.append("you") else: targets.append(target) bot.say(RPLREMINDFORMAT % (event.nick, english_list(targets), distance_of_time_in_words(ntime, t), UNKNOWN % english_list(unknown) if unknown else "", MULTIUSER % "Reminding" if dupes else ""))
def alias(event, bot): """ alias [(source, ~group, ~del)] argument. If only argument is supplied, aliases for that argument are retrieved. Otherwise if source is supplied, argument will become an alias of source. See addtional help for ~group and ~del. |alias ~group [groupname] argument: will add argument to groupname is groupname is provided, else will return all users in groupname. |alias ~del [(~group, groupname)] argument: will remove the user alias argument if supplied on it's own. ~group will remove the entire group argument. If groupname is used will remove argument from group, in this case argument may be multiple entries. """ # API is similar to old bot arg1, arg2, arg3 = argumentSplit(event.argument, 3) if arg1 == "~group": if arg2 and arg3: # binding to a group nick = USERS_MODULE.get_username(bot, arg2, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found or seen." % arg2) if group_check(bot.dbQuery, arg2, arg3): return bot.say("User/alias (%s) is already a member of (%s)." % (arg3, arg2)) group_add(bot.dbQuery, arg2, arg3) return bot.say("User/alias (%s) added to group (%s)." % (arg2, arg3)) elif arg2: # querying a group members = group_list(bot.dbQuery, arg2) if members: msg = "Users in group (%s): %%s" % (arg2) return pastehelper(bot, msg, items=members, title="Members of (%s)" % arg2) else: return bot.say("Group not found: (%s)" % arg2) else: #show help for group return bot.say(functionHelp(alias, "~group")) elif arg1 == "~del": if arg2 and arg3: # do a delete on group if arg2 == "~group": #remove entire group group = bot.dbQuery('''SELECT grp FROM aliasgrp WHERE grp = ?;''', (arg3,), fetchone) if group: bot.dbQuery('''DELETE FROM aliasgrp WHERE grp = ?;''', (arg3,)) return bot.say("Removed group (%s)" % arg3) else: return bot.say("Group (%s) not found." % arg3) else: # assume arg2 is a groupname to remove entry from group = bot.dbQuery('''SELECT grp FROM aliasgrp WHERE grp = ?;''', (arg2,), fetchone) if group: nick = USERS_MODULE.get_username(bot, arg3, source=event.nick, _inalias=True) if not nick: return bot.say("User/alias (%s) not found." % arg3) if bot.dbQuery('''SELECT 1 FROM aliasgrp WHERE grp = ? AND user = ?;''', (arg2,nick), fetchone): bot.dbQuery('''DELETE FROM aliasgrp WHERE grp = ? AND user = ?;''', (arg2, nick)) return bot.say("Removed (%s) from (%s)" % (nick, arg2)) else: return bot.say("User/alias (%s) not found in group (%s)" % (nick, arg2)) else: return bot.say("Group (%s) not found." % arg2) elif arg2: # single alias delete origin = lookup_alias(bot.dbQuery, arg2) if origin: bot.dbQuery('''DELETE FROM alias WHERE alias = ?;''', (arg2,)) return bot.say("Alias (%s) for (%s) removed." % (arg2, origin)) else: return bot.say("Alias (%s) not found." % arg2) else: # show help for del return bot.say(functionHelp(alias, "~del")) elif arg1 and arg2: if arg3: arg2 += arg3 #binding a new alias if arg2.lower() == "me": return bot.say("But you are already yourself.") source = USERS_MODULE.get_username(bot, arg1, source=event.nick, _inalias=True) if not source: return bot.say("(%s) not seen before." % arg1) # Query target_user first so we can display error messages in sane order. target_user = USERS_MODULE._get_username(bot.dbQuery, arg2) if source == target_user: return bot.say("But %s is already %s." % (arg1, arg2)) target = lookup_alias(bot.dbQuery, arg2) # check target if target: #alias already in use by nnick return bot.say("Alias already in use by (%s)" % target) # check if target is an existing/seen user. # If it is, it means we are probably applying a user as an alias (remove old user in that case) # in this case we are going to remove target user and execute all observers to user's rename plans. target = target_user if source == target: return bot.say("But %s is already %s." % (arg1, arg2)) # see comments just above if target: USERS_MODULE._rename_user(bot.network, target, source) # find all groups that alias is a part of, and change membership to use "user" (source) bot.dbQuery('''UPDATE aliasgrp SET user=? WHERE user = ?;''', (source, arg2)) # add origin mapping so that origins can't get aliased # this will get called everytime but it's more messy if you check alias independently of alias, no big deal if add_alias(bot.dbQuery, source, source) # REPLACEing everytime. add_alias(bot.dbQuery, source, arg2) return bot.say("Added (%s) to (%s)" % (arg2, source)) elif arg1: #querying an alias nick = lookup_alias(bot.dbQuery, arg1) if nick: aliases = alias_list(bot.dbQuery, nick) if aliases: msg = "Aliases for (%s): %%s" % arg1 title = "Aliases for (%s)" % arg1 return pastehelper(bot, msg, items=aliases, altmsg="%s", title=title) # unknown alias or no aliases: return bot.say("No aliases for (%s)" % arg1) # if none of the above, show help bot.say(functionHelp(alias)) return
def simplecommands(event, bot): """ simplecommands [(~del, ~list)] input[,alias1,alias2,...] output. Simple interface for adding/removing simplecommands. If only input is supplied, output is retrieved. If ~del is specified, input is deleted if found. e.g. .simplecommands google google.com """ arg1, arg2 = argumentSplit(event.argument, 2) commands = bot.getOption("commands", module="pbm_simplecommands") if not arg1: return bot.say(functionHelp(simplecommands)) elif arg1 == '~list': commands = bot.getOption("commands", module="pbm_simplecommands") cmdlist = [] commands.sort() for command, output in commands: if isinstance(command, (list, tuple)) and len(command) > 1: cmdlist.append('(%s)' % ', '.join(command)) else: cmdlist.extend(command) return bot.say('Simplecommands: %s' % ', '.join(cmdlist)) elif arg1 == '~del' and arg2: match = None temp_match = None newcmds = arg2.split(',') for index, command in enumerate(commands): for newcmd in newcmds: if (isinstance(command[0], list) and newcmd in command[0]) or newcmd == command[0]: temp_match = commands[index] if temp_match: if match: return bot.say('Simplecommand specified (%s) matches more than one simplecommand: (%s) and (%s)' % (arg2, ', '.join(temp_match[0]), ', '.join(match[0]))) match = temp_match temp_match = None if not match: return bot.say('(%s) is not a known simplecommand.' % arg2) commands.remove(match) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say('Simplecommand (%s) deleted. Options saved. Reloading...' % arg2) blockingCallFromThread(reactor, _reallyReload) return bot.say('Done.') elif arg2: match = None temp_match = None newcmds = arg1.split(',') for index, command in enumerate(commands): for newcmd in newcmds: if (isinstance(command[0], list) and newcmd in command[0]) or newcmd == command[0]: temp_match = commands[index] if temp_match: if match: return bot.say('Simplecommand specified (%s) matches more than one simplecommand: (%s) and (%s)' % (arg1, ', '.join(temp_match[0]), ', '.join(match[0]))) match = temp_match temp_match = None # Replace an existing simplecommand if match: if len(match[0]) > 1: return bot.say("Can't modify simplecommand with multiple input mappings (%s), \ delete it first with \x02~del %s\x02 and recreate it." % (', '.join(match[0]), arg1)) commands.remove(match) commands.append([arg1.split(','), arg2]) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say('Simplecommand (%s) replaced. Options saved. Reloading...' % arg1) blockingCallFromThread(reactor, _reallyReload) bot.say('Done.') # Add a new simplecommand else: # TODO: Yeah, this probably isn't good -- or maybe it's fine for cmd in newcmds: ret = bot._settings.dispatcher._getCommandMappings(cmd.lower()) if ret: return bot.say('Command (%s) already in use by the \x02%s\x02 module.' % (cmd, ret[0].function.__module__)) commands.append([arg1.split(','), arg2]) bot.setOption("commands", commands, module="pbm_simplecommands", channel=False) blockingCallFromThread(reactor, Settings.saveOptions) bot.say('Simplecommand (%s) added. Options saved. Reloading...' % arg1) blockingCallFromThread(reactor, _reallyReload) bot.say('Done.') else: match = None for command, output in commands: if isinstance(command, list) and arg1 in command: match = (command, output) if not match: return bot.say('(%s) is not a known simplecommand.' % arg1) bot.say('Simplecommand (%s): %s' % (', '.join(match[0]), match[1]))
def funquote(event, bot): """ unquote content. content will be URL decoded.""" arg = event.argument if not arg: return bot.say(functionHelp(funquote)) bot.say(unquote(str(arg)).decode("utf-8"))