예제 #1
0
파일: pbm_help.py 프로젝트: ckx/pyBurlyBot
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())
예제 #2
0
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())
예제 #3
0
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))
예제 #4
0
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
예제 #5
0
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.")
예제 #6
0
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 ""))
예제 #7
0
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 ""))
예제 #8
0
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.")
예제 #9
0
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.")
예제 #10
0
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")
예제 #11
0
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)
예제 #12
0
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.")
예제 #13
0
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
예제 #14
0
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)))
예제 #15
0
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))
예제 #16
0
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)))
예제 #17
0
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))
예제 #18
0
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))
예제 #19
0
파일: pbm_words.py 프로젝트: ckx/pyBurlyBot
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))
예제 #20
0
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.")
예제 #21
0
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)))
예제 #22
0
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))
예제 #23
0
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))
예제 #24
0
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.")
예제 #25
0
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))
예제 #26
0
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.")
예제 #27
0
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)
예제 #28
0
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)
예제 #29
0
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")
예제 #30
0
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)
예제 #31
0
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.")
예제 #32
0
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"))
예제 #33
0
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))
예제 #34
0
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)))
예제 #35
0
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.")
예제 #36
0
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]))
예제 #37
0
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)
예제 #38
0
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)
예제 #39
0
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))
예제 #40
0
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")))
예제 #41
0
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)))
예제 #42
0
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 ""))
예제 #43
0
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 ""))
예제 #44
0
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
예제 #45
0
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]))
예제 #46
0
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"))