Beispiel #1
0
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)
Beispiel #2
0
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('_',
                                                                     ' ')))
Beispiel #3
0
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]))
Beispiel #4
0
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)
Beispiel #5
0
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)
Beispiel #6
0
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.")
Beispiel #7
0
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?")
Beispiel #8
0
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)
Beispiel #9
0
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'])
Beispiel #10
0
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'))
Beispiel #11
0
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)
Beispiel #12
0
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.')
Beispiel #13
0
    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
Beispiel #14
0
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"
        )
Beispiel #15
0
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))
Beispiel #16
0
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)
Beispiel #17
0
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.")
Beispiel #18
0
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))