def cmd(send, msg, args): """Reports the difference between now and some specified time. Syntax: !timeuntil <time> """ parser = arguments.ArgParser(args['config']) parser.add_argument('date', nargs='*', action=arguments.DateParser) try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if not cmdargs.date: send("Time until when?") return delta = dateutil.relativedelta.relativedelta(cmdargs.date, datetime.datetime.now()) diff = "%s is " % cmdargs.date.strftime("%x") if delta.years: diff += "%d years " % (delta.years) if delta.months: diff += "%d months " % (delta.months) if delta.days: diff += "%d days " % (delta.days) if delta.hours: diff += "%d hours " % (delta.hours) if delta.minutes: diff += "%d minutes " % (delta.minutes) if delta.seconds: diff += "%d seconds " % (delta.seconds) diff += "away" send(diff)
def cmd(send, msg, args): """Find a path between two wikipedia articles. Syntax: {command} [article] [article] """ parser = arguments.ArgParser(args['config']) parser.add_argument('first', nargs='?') parser.add_argument('second', nargs='?') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if not cmdargs.first: cmdargs.first = get_article() else: if not check_article(cmdargs.first): send("%s isn't a valid wikipedia article, fetching a random one..." % cmdargs.first) cmdargs.first = get_article() if not cmdargs.second: cmdargs.second = get_article() else: if not check_article(cmdargs.second): send("%s isn't a valid wikipedia article, fetching a random one..." % cmdargs.second) cmdargs.second = get_article() path = gen_path(cmdargs) if path: send(path.replace('_', ' ')) else: send( "No path found between %s and %s. Do you need to add more links?" % (cmdargs.first.replace('_', ' '), cmdargs.second.replace('_', ' ')))
def cmd(send, msg, args): """Gets stats. Syntax: {command} <--high|--low|--userhigh|--nick <nick>|command> """ parser = arguments.ArgParser(args['config']) group = parser.add_mutually_exclusive_group() group.add_argument('--high', action='store_true') group.add_argument('--low', action='store_true') group.add_argument('--userhigh', action='store_true') group.add_argument('--nick', action=arguments.NickParser) group.add_argument('command', nargs='?') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return session = args['db'] commands = get_commands(session) totals = get_command_totals(session, commands) sortedtotals = sorted(totals, key=totals.get) if is_registered(cmdargs.command): nicktotals = get_nick_totals(session, cmdargs.command) maxuser = sorted(nicktotals, key=nicktotals.get) if not maxuser: send("Nobody has used that command.") else: maxuser = maxuser[-1] send("%s is the most frequent user of %s with %d out of %d uses." % (maxuser, cmdargs.command, nicktotals[maxuser], totals[cmdargs.command])) elif cmdargs.high: send('Most Used Commands:') high = list(reversed(sortedtotals)) for x in range(3): if x < len(high): send("%s: %s" % (high[x], totals[high[x]])) elif cmdargs.low: send('Least Used Commands:') low = sortedtotals for x in range(3): if x < len(low): send("%s: %s" % (low[x], totals[low[x]])) elif cmdargs.userhigh: totals = get_nick_totals(session) sortedtotals = sorted(totals, key=totals.get) high = list(reversed(sortedtotals)) send('Most active bot users:') for x in range(3): if x < len(high): send("%s: %s" % (high[x], totals[high[x]])) elif cmdargs.nick: totals = get_nick_totals(session) if cmdargs.nick not in totals.keys(): send("%s has never used a bot command." % cmdargs.nick) else: send("%s has used %d bot commands." % (cmdargs.nick, totals[cmdargs.nick])) else: command = choice(list(totals.keys())) send("%s has been used %s times." % (command, totals[command]))
def cmd(send, msg, args): """Gets the weather. Syntax: {command} <[--date date] [--hour hour] location|--set default> Powered by Weather Underground, www.wunderground.com """ apikey = args['config']['api']['weatherapikey'] parser = arguments.ArgParser(args['config']) parser.add_argument('--date', action=arguments.DateParser) parser.add_argument('--hour', type=int) parser.add_argument('--set', action='store_true') parser.add_argument('string', nargs='*') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if isinstance(cmdargs.string, list): cmdargs.string = " ".join(cmdargs.string) if cmdargs.set: set_default(args['nick'], cmdargs.string, args['db'], send, apikey) return if cmdargs.hour is not None and cmdargs.hour > 23: send("Invalid Hour") cmdargs.hour = None nick = args['nick'] if args['name'] == 'weather' else '`bjones' if not cmdargs.string: cmdargs.string = get_default(nick, args['db'], args['handler'], send, args['config'], args['source']) if cmdargs.hour is not None: get_hourly(cmdargs, send, apikey) elif cmdargs.date: get_forecast(cmdargs, send, apikey) else: get_weather(cmdargs, send, apikey)
def cmd(send, msg, args): """Check the git revison. Syntax: {command} [check|master] """ parser = arguments.ArgParser(args['config']) parser.add_argument('action', choices=['check', 'master', 'commit'], nargs='?') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return apiOutput = get('https://api.github.com/repos/%s/branches/master' % args['config']['api']['githubrepo']).json() commit, version = misc.get_version() if commit is None: send("Couldn't get the version.") if not cmdargs.action: send(version) return if cmdargs.action == 'master': send(apiOutput['commit']['sha']) elif cmdargs.action == 'check': check = 'Same' if apiOutput['commit']['sha'] == commit else 'Different' send(check) elif cmdargs.action == 'commit': send(commit)
def cmd(send, msg, args): """Shows or clears the abuse list Syntax: {command} <--clear|--show> """ parser = arguments.ArgParser(args['config']) group = parser.add_mutually_exclusive_group() group.add_argument('--clear', action='store_true') group.add_argument('--show', action='store_true') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if cmdargs.clear: args['handler'].abuselist.clear() send("Abuse list cleared.") elif cmdargs.show: abusers = [ x for x in args['handler'].abuselist.keys() if x in args['handler'].ignored ] if abusers: send(", ".join(abusers)) else: send("No abusers.") else: send("Please specify an option.")
def cmd(send, msg, args): """Handles ignoring/unignoring people Syntax: {command} <--clear|--show/--list|--delete|nick> """ parser = arguments.ArgParser(args['config']) group = parser.add_mutually_exclusive_group() group.add_argument('--clear', action='store_true') group.add_argument('--show', '--list', action='store_true') group.add_argument('--delete', action='store_true') parser.add_argument('nick', nargs='?') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if cmdargs.clear: args['handler'].ignored.clear() send("Ignore list cleared.") elif cmdargs.show: if args['handler'].ignored: send(", ".join(args['handler'].ignored)) else: send("Nobody is ignored.") elif cmdargs.delete: if not cmdargs.nick: send("Unignore who?") elif cmdargs.nick not in args['handler'].ignored: send("%s is not ignored." % cmdargs.nick) else: args['handler'].ignored.remove(cmdargs.nick) send("%s is no longer ignored." % cmdargs.nick) elif cmdargs.nick: args['handler'].ignore(send, cmdargs.nick) else: send("Ignore who?")
def cmd(send, msg, args): """Greps the log for a string. Syntax: !grep (--nick <nick>) <string> """ parser = arguments.ArgParser(args['config']) parser.add_argument('--nick', action=arguments.NickParser) parser.add_argument('string', nargs='?') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if not cmdargs.string: send('Please specify a search term.') return cmdchar = args['config']['core']['cmdchar'] if cmdargs.nick: row = args['db'].query(Log).filter( Log.type == 'pubmsg', Log.source == cmdargs.nick, ~Log.msg.startswith(cmdchar), Log.msg.like('%' + cmdargs.string + '%')).order_by( Log.id.desc()).first() else: row = args['db'].query(Log).filter( Log.type == 'pubmsg', ~Log.msg.startswith(cmdchar), Log.msg.like('%' + cmdargs.string + '%')).order_by( Log.id.desc()).first() if row: logtime = strftime('%Y-%m-%d %H:%M:%S', localtime(row.time)) send("%s said %s at %s" % (row.source, row.msg, logtime)) elif cmdargs.nick: send('%s has never said %s.' % (cmdargs.nick, cmdargs.string)) else: send('%s has never been said.' % cmdargs.string)
def cmd(send, msg, args): """Sets a mode. Syntax: !mode (--chan <chan>) <mode> """ parser = arguments.ArgParser(args['config']) parser.add_argument('--chan', '--channel', action=arguments.ChanParser) try: cmdargs, extra = parser.parse_known_args(msg) except arguments.ArgumentException as e: send(str(e)) return target = cmdargs.chan if cmdargs.chan else args['target'] mode = " ".join(extra) if not mode: send('Please specify a mode.') elif target == 'private': send("Modes don't work in a PM!") elif not args['is_admin'](args['nick']): send("Admins only") elif target not in args['handler'].channels: send("Bot not in channel %s" % target) elif args['botnick'] not in list(args['handler'].channels[target].opers()): send("Bot must be opped in channel %s" % target) else: args['handler'].connection.mode(target, mode) if args['target'] != args['config']['core']['ctrlchan']: send("Mode \"%s\" on %s by %s" % (mode, target, args['nick']), target=args['config']['core']['ctrlchan'])
def cmd(send, msg, args): """Gets scores. Syntax: {command} <--high|--low|nick> """ if not args['config']['feature'].getboolean('hooks'): send( "Hooks are disabled, and this command depends on hooks. Please contact the bot admin(s)." ) return session = args['db'] parser = arguments.ArgParser(args['config']) group = parser.add_mutually_exclusive_group() group.add_argument('--high', action='store_true') group.add_argument('--low', action='store_true') group.add_argument('nick', nargs='?', action=arguments.NickParser) try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if cmdargs.high: data = session.query(Scores).order_by( Scores.score.desc()).limit(3).all() send('High Scores:') for x in data: send("%s: %s" % (x.nick, x.score)) elif cmdargs.low: data = session.query(Scores).order_by(Scores.score).limit(3).all() send('Low Scores:') for x in data: send("%s: %s" % (x.nick, x.score)) elif cmdargs.nick: name = cmdargs.nick.lower() if name == 'c': send( "We all know you love C better than anything else, so why rub it in?" ) return score = session.query(Scores).filter(Scores.nick == name).scalar() if score is not None: if name == args['botnick'].lower(): emote = ':)' if score.score > 0 else ':(' if score.score < 0 else ':|' output = 'has %s points! %s' % (score.score, emote) send(output, 'action') else: send("%s has %i points!" % (name, score.score)) else: send("Nobody cares about %s" % name) else: count = session.query(Scores).count() if count == 0: send("Nobody cares about anything =(") else: randid = randint(1, count) query = session.query(Scores).get(randid) send("%s has %i point%s!" % (query.nick, query.score, '' if abs(query.score) == 1 else 's'))
def cmd(send, msg, args): """Orders the bot to join a channel Syntax: {command} <channel> [channel] ... """ parser = arguments.ArgParser(args['config']) parser.add_argument('channel', nargs='+', action=arguments.ChanParser) try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return for chan in cmdargs.channels: args['handler'].do_join(chan, args['nick'], args['type'], send, args['handler'].connection)
def cmd(send, msg, args): """Changes the output filter. Syntax: {command} <filter|--show|--list|--reset|--chain filter,[filter2,...]> """ if args['type'] == 'privmsg': send('Filters must be set in channels, not via private message.') isadmin = args['is_admin'](args['nick']) parser = arguments.ArgParser(args['config']) group = parser.add_mutually_exclusive_group() group.add_argument('filter', nargs='?') group.add_argument('--show', action='store_true') group.add_argument('--list', action='store_true') group.add_argument('--reset', '--clear', action='store_true') group.add_argument('--chain') if not msg: send(get_filters(args['handler'])) return try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if cmdargs.list: send("Available filters are %s" % ", ".join(textutils.output_filters.keys())) elif cmdargs.reset and isadmin: args['handler'].outputfilter.clear() send("Okay!") elif cmdargs.chain and isadmin: if not args['handler'].outputfilter: send("Must have a filter set in order to chain.") return filter_list, output = misc.append_filters(cmdargs.chain) if filter_list is not None: args['handler'].outputfilter.extend(filter_list) send(output) elif cmdargs.show: send(get_filters(args['handler'])) elif isadmin: # If we're just adding a filter without chain, blow away any existing filters. filter_list, output = misc.append_filters(cmdargs.filter) if filter_list is not None: args['handler'].outputfilter.clear() args['handler'].outputfilter.extend(filter_list) send(output) else: send('This command requires admin privileges.')
def get_filtered_send(self, cmdargs, send, target): """Parse out any filters.""" parser = arguments.ArgParser(self.config) parser.add_argument('--filter') try: filterargs, remainder = parser.parse_known_args(cmdargs) except arguments.ArgumentException as ex: return str(ex), None cmdargs = ' '.join(remainder) if filterargs.filter is None: return cmdargs, send filter_list, output = misc.append_filters(filterargs.filter) if filter_list is None: return output, None # define a new send to handle filter chaining def filtersend(msg, mtype='privmsg', target=target, ignore_length=False): self.send(target, self.connection.real_nickname, msg, mtype, ignore_length, filters=filter_list) return cmdargs, filtersend
def cmd(send, msg, args): """Babbles like a user Syntax: {command} [nick] [--start <word>] """ parser = arguments.ArgParser(args['config']) parser.add_argument('speaker', nargs='?', default=args['config']['core']['channel']) parser.add_argument('--start', nargs='*') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if args['db'].query(Babble).count(): send(build_msg(args['db'], cmdargs.speaker, cmdargs.start)) else: send( "Please run ./scripts/gen_babble.py to initialize the babble cache" )
def cmd(send, msg, args): """Converts a message to/from dvorak. Syntax: !dvorak <--nick <nick>|msg> """ parser = arguments.ArgParser(args['config']) parser.add_argument('--nick', action=arguments.NickParser) parser.add_argument('msg', nargs='*') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if cmdargs.msg: if cmdargs.nick: send('--nick cannot be combined with a message') else: send(translate(" ".join(cmdargs.msg), False).strip()) else: log = get_log(args['db'], cmdargs.nick, args['target']) if not log: send("Couldn't find a message from %s :(" % cmdargs.nick) else: send(translate(log))
def cmd(send, msg, args): """Gets the weather. Syntax: {command} <station> [station2...] """ parser = arguments.ArgParser(args['config']) parser.add_argument('stations', nargs='*') try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return if not cmdargs.stations: send("What station?") return if isinstance(cmdargs.stations, list): cmdargs.stations = ','.join(cmdargs.stations) req = get('https://aviationweather.gov/adds/dataserver_current/httpparam', params={ 'datasource': 'metars', 'requestType': 'retrieve', 'format': 'xml', 'mostRecentForEachStation': 'constraint', 'hoursBeforeNow': '1.25', 'stationString': cmdargs.stations }) xml = ElementTree.fromstring(req.text) errors = xml.find('./errors') if len(errors): errstring = ','.join([error.text for error in errors]) send('Error: %s' % errstring) return data = xml.find('./data') if data.attrib['num_results'] == '0': send('No results found.') else: for station in data: send(station.find('raw_text').text)
def cmd(send, msg, args): """Files a github issue or gets a open one. Syntax: {command} <title [--desc description]|--get <number>> """ repo = args['config']['api']['githubrepo'] apikey = args['config']['api']['githubapikey'] if not repo: send("GitHub repository undefined in config.cfg!") return parser = arguments.ArgParser(args['config']) parser.add_argument('title', nargs='*', default='') parser.add_argument('--get', '--show', action='store_true') parser.add_argument('--description', nargs='+', default="No description given.") cmdargs = parser.parse_args(msg) if isinstance(cmdargs.title, list): cmdargs.title = ' '.join(cmdargs.title) if isinstance(cmdargs.description, list): cmdargs.description = ' '.join(cmdargs.description) if args['type'] == 'privmsg': send('You want to let everybody know about your problems, right?') elif cmdargs.get or cmdargs.title.isdigit(): issue = get('https://api.github.com/repos/%s/issues/%d' % (repo, int(cmdargs.title))).json() if 'message' in issue: send("Invalid Issue Number") else: send("%s (%s) -- %s" % (issue['title'], issue['state'], issue['html_url'])) elif not cmdargs.title: issues = [] n = 1 while True: headers = {'Authorization': 'token %s' % apikey} page = get('https://api.github.com/repos/%s/issues' % repo, params={ 'per_page': '100', 'page': n }, headers=headers).json() n += 1 if page: issues += page else: break if len(issues) == 0: send("No open issues to choose from!") else: issue = choice(issues) num_issues = len([x for x in issues if 'pull_request' not in x]) send("There are %d open issues, here's one." % num_issues) send("#%d -- %s -- %s" % (issue['number'], issue['title'], issue['html_url'])) elif cmdargs.title and args['is_admin'](args['nick']): url, success = create_issue(cmdargs.title, cmdargs.description, args['source'], repo, apikey) if success: send("Issue created -- %s -- %s -- %s" % (url, cmdargs.title, cmdargs.description)) else: send("Error creating issue: %s" % url) elif cmdargs.title: row = Issues(title=cmdargs.title, description=cmdargs.description, source=args['source']) args['db'].add(row) args['db'].flush() send("New Issue: #%d -- %s -- %s, Submitted by %s" % (row.id, cmdargs.title, cmdargs.description, args['nick']), target=args['config']['core']['ctrlchan']) send("Issue submitted for approval.", target=args['nick']) else: send("Invalid arguments.")
def cmd(send, msg, args): """Handles quotes. Syntax: {command} <number|nick>, !quote --add <quote> --nick <nick>, !quote --list, !quote --delete <number>, !quote --edit <number> <quote> --nick <nick> """ session = args['db'] parser = arguments.ArgParser(args['config']) parser.add_argument('--nick', nargs='?') parser.add_argument('quote', nargs='*') group = parser.add_mutually_exclusive_group() group.add_argument('--list', action='store_true') group.add_argument('--add', action='store_true') group.add_argument('--delete', '--remove', type=int) group.add_argument('--edit', type=int) if not msg: send(do_get_quote(session)) return try: cmdargs = parser.parse_args(msg) except arguments.ArgumentException as e: send(str(e)) return isadmin = args['is_admin'](args['nick']) if cmdargs.add: if args['type'] == 'privmsg': send("You want everybody to know about your witty sayings, right?") else: if cmdargs.nick is None: send('You must specify a nick.') elif not cmdargs.quote: send('You must specify a quote.') else: do_add_quote(cmdargs.nick, " ".join(cmdargs.quote), session, isadmin, send, args) elif cmdargs.list: send(do_list_quotes(session, args['config']['core']['url'])) elif cmdargs.delete: if isadmin: send(do_delete_quote(session, cmdargs.delete)) else: send( "You aren't allowed to delete quotes. Please ask a bot admin to do it" ) elif cmdargs.edit: if isadmin: send( do_update_quote(session, cmdargs.edit, cmdargs.nick, cmdargs.quote)) else: send( "You aren't allowed to edit quotes. Please ask a bot admin to do it" ) else: if msg.isdigit(): send(do_get_quote(session, int(msg))) else: if not re.match(args['config']['core']['nickregex'], msg): send('Invalid nick %s.' % msg) else: send(get_quotes_nick(session, msg))