Esempio n. 1
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())
Esempio n. 2
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")
Esempio n. 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))
Esempio n. 4
0
def timers(event, bot):
    command, args = commandSplit(event.argument)

    if command == "show":
        bot.say("Timers:")
        for timer in Timers.getTimers().itervalues():
            bot.say(" - %s: reps = %s, delay = %s, f = %s" %
                    (timer.name, timer.reps, timer.interval, timer.f))

    elif command == "add":
        args = argumentSplit(args, 4)  #add timername delay reps msg
        if not args:
            bot.say(
                "Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)"
            )
            return
        msg = Timers.addtimer(args[0],
                              float(args[1]),
                              timercallback,
                              reps=int(args[2]),
                              msg=args[3],
                              bot=bot,
                              channel=event.target)[1]
        bot.say("%s (%s)" % (msg, args[0]))

    elif command == "stop":
        bot.say(Timers.deltimer(args)[1])
Esempio n. 5
0
def butts(event, bot):
    """ butts [~del] [input].  Add or delete an entry in the bestbutts quote database.
	If no input is supplied the entire database will be dumped.
	e.g. .butts <@bbm> butt is love
	"""
    if not bot.getOption("BUTTS", module="pbm_butt"): return
    if not event.argument:
        items = bot.dbQuery('''SELECT id, butt FROM butts;''')
        if items:
            pastehelper(bot,
                        basemsg="butts: %s",
                        force=True,
                        altmsg="%s",
                        items=("%s: %s" % (row[0], row[1]) for row in items))
        else:
            bot.say("no butts.")
    else:
        cmd, arg = argumentSplit(event.argument, 2)
        if cmd == "~del":
            bot.dbQuery('''DELETE FROM butts WHERE id = ?;''', (arg, ))
            bot.say("OK.")
        else:
            # add a butts
            bot.dbQuery('''INSERT INTO butts (butt) VALUES(?);''',
                        (event.argument, ))
            bot.say("OK.")
Esempio n. 6
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())
Esempio n. 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 ""))
Esempio n. 8
0
def timers(event, bot):
	command, args = commandSplit(event.argument)
	
	if command == "show":
		bot.say("Timers:")
		for timer in Timers.getTimers().itervalues():
			bot.say(" - %s: reps = %s, delay = %s, f = %s" % (timer.name, timer.reps, timer.interval, timer.f))
		
	elif command == "add":
		args = argumentSplit(args, 4) #add timername delay reps msg
		if not args:
			bot.say("Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)")
			return
		try:
			if Timers.addtimer(args[0], float(args[1]), timercallback, reps=int(args[2]), msg=args[3], bot=bot, channel=event.target):
				bot.say("Timer added (%s)" % args[0])
			else:
				bot.say("Timer not added for some reason?")
		except TimerExists:
			bot.say("Timer not added because it exists already.")
		except TimerInvalidName:
			bot.say("Timer not added because it has an invalid name.")

	elif command == "stop":
		try: 
			Timers.deltimer(args)
			bot.say("Timer stopped (%s)" % args)
		except (TimerNotFound, TimerInvalidName):
			bot.say("Can't stop (%s) because timer not found or internal timer." % args)
Esempio n. 9
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.")
Esempio n. 10
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 ""))
Esempio n. 11
0
def gdq(event, bot):
	""" gdq [gamename,~list,~del gamename]. Show gdq info. If gamename is provided, alert will be given when gamename is seen.
		gamename is searched in the time of the stream game, so "kirby" is possible for all kirby games."""
	gamename = argumentSplit(event.argument, 1)[0]
	if gamename:
		if gamename.startswith("~"):
			#process ~list, ~del
			bot.say("Griff halp pls.")
			return
		item = bot.dbQuery('''SELECT source, source_name, game_text
				FROM gdq_alert WHERE source=? AND source_name=? AND game_text=?; ''', (event.target, event.nick, gamename))
		if item:
			bot.say("I'm already going to tell you about (%s)" % gamename)
			return
		bot.dbQuery('''INSERT INTO gdq_alert(source, source_name, game_text, notified_time) VALUES (?,?,?,?);''',
				(event.target, event.nick, gamename, 0))
		bot.say("I'll let you know when (%s) is on." % gamename)
		return
	upcoming = []
	o = build_opener()
	o.addheaders = [('Client-ID', TWITCH_CLIENTID)]
	f = o.open(TWITCH_API_URL)
	game = "Don't know"
	eta = None
	if f.getcode() == 200:
		data = load(f)
		game = data['game']
		gstart = timegm(strptime(data['updated_at'], "%Y-%m-%dT%H:%M:%SZ")) #"2015-01-06T01:11:32Z" UTC
		ngame = game.lower()
		o = build_opener()
		o.addheaders = [('User-agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36')]
		f = o.open(GDQ_URL)
		# http://stackoverflow.com/a/9920703
		page = parse(f)
		rows = page.xpath("body/div//table/tbody")[0].findall("tr")

		data = []
		for row in rows:
			data.append([c.text_content() for c in row.getchildren()])
		# find current
		upcoming = None
		# try searching for incorrect name in timetable because bads...
		for igametitle in modifyNameIter(ngame):
			upcoming, eta = _searchGame(data, igametitle)
			if upcoming: break
		else:
			if ngame[:4] == "the ":
				upcoming, eta = _searchGame(data, ngame[4:])

		if eta:
			curr = timegm(gmtime())
			neta = timegm(strptime(eta, "%H:%M:%S")) - timegm(strptime("0:00:00", "%H:%M:%S"))
			eta = "%s/%s" % (eta.lstrip("0:")[:-3], (neta - (curr-gstart))/60)
		else: eta = "?"
	if not upcoming: upcoming = ["Don't know"]
	bot.say(RPL % (game, eta, "http://www.twitch.tv/gamesdonequick/popout", "https://gamesdonequick.com/schedule"),
		strins=", ".join(upcoming))
Esempio n. 12
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))
Esempio n. 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(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
Esempio n. 14
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.")
Esempio n. 15
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)))
Esempio n. 16
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
Esempio n. 17
0
def butts(event, bot):
	""" butts [~del] [input].  Add or delete an entry in the bestbutts quote database.
	If no input is supplied the entire database will be dumped.
	e.g. .butts <@bbm> butt is love
	"""
	if not bot.getOption("BUTTS", module="pbm_butt"): return
	if not event.argument:
		items = bot.dbQuery('''SELECT id, butt FROM butts;''')
		if items:
			pastehelper(bot, basemsg="butts: %s", force=True, altmsg="%s", items=("%s: %s" % (row[0], row[1]) for row in items))
		else:
			bot.say("no butts.")
	else:
		cmd, arg = argumentSplit(event.argument, 2)
		if cmd == "~del":
			bot.dbQuery('''DELETE FROM butts WHERE id = ?;''', (arg, ))
			bot.say("OK.")
		else:
			# add a butts
			bot.dbQuery('''INSERT INTO butts (butt) VALUES(?);''', (event.argument,))
			bot.say("OK.")
Esempio n. 18
0
def timers(event, bot):
    command, args = commandSplit(event.argument)

    if command == "show":
        bot.say("Timers:")
        for timer in Timers.getTimers().itervalues():
            bot.say(" - %s: reps = %s, delay = %s, f = %s" %
                    (timer.name, timer.reps, timer.interval, timer.f))

    elif command == "add":
        args = argumentSplit(args, 4)  #add timername delay reps msg
        if not args:
            bot.say(
                "Not enough arguments. Need: timername delay reps message (reps <= 0 means forever)"
            )
            return
        try:
            if Timers.addtimer(args[0],
                               float(args[1]),
                               timercallback,
                               reps=int(args[2]),
                               msg=args[3],
                               bot=bot,
                               channel=event.target):
                bot.say("Timer added (%s)" % args[0])
            else:
                bot.say("Timer not added for some reason?")
        except TimerExists:
            bot.say("Timer not added because it exists already.")
        except TimerInvalidName:
            bot.say("Timer not added because it has an invalid name.")

    elif command == "stop":
        try:
            Timers.deltimer(args)
            bot.say("Timer stopped (%s)" % args)
        except (TimerNotFound, TimerInvalidName):
            bot.say(
                "Can't stop (%s) because timer not found or internal timer." %
                args)
Esempio n. 19
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")
Esempio n. 20
0
def dochoice(event, bot):
    """ choice values. choice will randomly select one of the given values."""
    if not event.argument: return bot.say(functionHelp(dochoice))
    values = argumentSplit(event.argument, -1)
    return bot.say("%s" % choice(values))
Esempio n. 21
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 ""))
Esempio n. 22
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)
Esempio n. 23
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]))
Esempio n. 24
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))
Esempio n. 25
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
Esempio n. 26
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))
Esempio n. 27
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 ""))
Esempio n. 28
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)
Esempio n. 29
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]))