Example #1
0
def main():
    k = db.bot_vars.tbl_k
    bot_nick = bot_utils.get_item('nick', db)
    bot_user = bot_utils.get_item('user', db)
    bot_rname = bot_utils.get_item('rname', db)
    bot_server = bot_utils.get_item('server', db)
    bot_port = int(bot_utils.get_item('port', db))
    bot_chans = eval(bot_utils.get_item('chans', db))
    db(k == 'pid').update(v=os.getpid())
    db(k == 'ppid').update(v=os.getppid())

    print "Connecting:"
    print bot_server + ':' + str(bot_port)
    print bot_chans
    print bot_nick + ':' + bot_user + ':' + bot_rname

    #signal(SIGUSR1, get_cmd)

    our_bot = bot.ircBot(bot_nick)
    #our_bot._mode = '+B-x'
    our_bot.db = db
    our_bot.user = bot_user
    our_bot.real_name = bot_rname
    our_bot.storage = Storage()
    our_bot.connect(bot_server,
                port=bot_port,
                channel=bot_chans,
                )
    our_bot.conn_host = bot_server
    our_bot.conn_port = bot_port
    our_bot.conn_channel = bot_chans
    our_bot.start()
Example #2
0
def run(bot, event, db):
    this_mod = db(db.bot_modules.name == 'url_resolver').select().first()
    prefix = this_mod.vars_pre
    prev_url = bot_utils.get_item(prefix+'prev', db)
    i = event.message.find('http://')
    if i == -1:
        i = event.message.find('https://')
    if i > -1:
        u = ''
        for c in event.message[i:]:
            if c == ' ':
                break
            u += c
        if prev_url != u:
            bot_utils.set_item(prefix+'prev', u, db)
            try:
                req = urllib2.Request(u, headers=H_HTTP)
                res = urllib2.urlopen(req)
                page = res.read().strip(' \t\n\r')
                res.close()
                del res
                if page.startswith('<!doctype>'):
                    page = page[10:]
                page = BeautifulSoup(page)
                try:
                    #not exactly the most optimized, I know
                    s = page.title.get_text().strip()
                    rchars = '\n\r\t\0'
                    for c in rchars:
                        s = s.replace(c, ' ')
                    title_in_url = True
                    title = s.lower()
                    pattern = re.compile('[\W_]+')
                    title = pattern.sub(' ', title).strip()
                    u = u.lower()
                    for word in title.split():
                        if word not in u:
                            title_in_url = False
                            break
                    if not title_in_url:
                        bot.bot_reply(event, s, False)
                        del page
                except AttributeError, e:
                    bot.bot_log('ERROR', event.source, 'url_resolver', "AttributeError: %s" % e)
                    del page
                    pass
            except Exception, e:
                bot.bot_log('ERROR', event.source, 'url_resolver', traceback.format_exc())
                del page
                pass
Example #3
0
def run(bot, event, db):
    mod_name = __name__.rsplit('.', 1)[1]
    if event.message.startswith('!wuname'):
        bot.bot_reply(event, mod_name)
    this_mod = db(db.bot_modules.name == mod_name).select()
    prefix = this_mod.first().vars_pre
    k_apikey = prefix + 'apikey'
    apikey = bot_utils.get_item(k_apikey, db)
    w_fmt = bot_utils.get_item(prefix + 'wfmt', db) or W_FMT
    f_fmt = bot_utils.get_item(prefix + 'ffmt', db) or F_FMT
    w_locs = prefix + 'locations'
    if w_locs not in db:
        db.define_table(
            w_locs,
            Field('tbl_k', 'string', unique=True, length=32),
            Field('v', 'string', length=512),
        )

    if event.message.startswith(k_apikey):
        apikey = event.message.split()[1]
        bot_utils.set_item(k_apikey, apikey, db)
        bot.bot_reply(event, "Wunderground API key set to %s" % apikey)
    elif event.message.lower().startswith('!weather'):
        if apikey == '':
            bot.bot_reply(
                event,
                "Wunderground API key not installed.  Please let the bot admin know."
            )
            return
        if len(event.message.split()) > 1:
            q = '+'.join(event.message.split()[1:])
            bot_utils.set_item(event.source, q, db, w_locs)
        else:
            q = bot_utils.get_item(event.source, db, w_locs)
            if q is None:
                bot.bot_reply(
                    event,
                    'There is no stored location for you.  Please try "!weather [location]".'
                )
                return

        try:
            req = urllib2.Request(W_URL % locals())
            response = urllib2.urlopen(req)
        except urllib2.HTTPError:
            bot.bot_reply(event, "Unable to retrieve weather")
            return
        try:
            w_data = json.load(response)['current_observation']
        except KeyError:
            #dbgf = open('wu_dbg.log', 'w')
            #dbgf.write(response)
            #dbgf.close()
            bot.bot_reply(
                event,
                "No results, or too many.  Try being more specific, or some other error has occurred."
            )
            return

        station = w_data['observation_location']['full']
        time = dateutil.parser.parse(
            w_data['observation_time_rfc822']).strftime(T_FMT)
        f = w_data['temp_f']
        c = w_data['temp_c']
        cond = w_data['weather']
        hum = w_data['relative_humidity']
        wind = w_data['wind_dir']
        mph = w_data['wind_mph']
        kph = w_data['wind_kph']
        weather = w_fmt % locals()
        bot.bot_reply(event, weather)
    elif event.message.lower().startswith('!forecast'):
        if apikey == '':
            bot.bot_reply(
                event,
                "Wunderground API key not installed.  Please let the bot admin know."
            )
            return
        if len(event.message.split()) > 1:
            q = '+'.join(event.message.split()[1:])
            bot_utils.set_item(event.source, q, db, w_locs)
        else:
            q = bot_utils.get_item(event.source, db, w_locs)
            if q is None:
                bot.bot_reply(
                    event,
                    'There is no stored location for you.  Please try "!forecast [location]".'
                )
                return

        try:
            req = urllib2.Request(W_URL % locals())
            response = urllib2.urlopen(req)
        except urllib2.HTTPError:
            bot.bot_reply(event, "Unable to retrieve forecast")
            return
        try:
            w_data = json.load(response)['current_observation']
        except KeyError:
            bot.bot_reply(
                event,
                "No results, or too many.  Try being more specific, or some other error has occurred."
            )
            return

        station = w_data['observation_location']['full']
        country = w_data['observation_location']['country_iso3166']

        try:
            req = urllib2.Request(F_URL % locals())
            response = urllib2.urlopen(req)
        except urllib2.HTTPError:
            bot.bot_reply(event, "Unable to retrieve forecast")
            return
        f_data = json.load(response)['forecast']
        #if f_data['simpleforecast']['forecastday'][0]['date']['tz_long'].startswith('America'):
        if country == 'US':
            f1 = f_data['txt_forecast']['forecastday'][0]['fcttext']
            f2 = f_data['txt_forecast']['forecastday'][1]['fcttext']
        else:
            f1 = f_data['txt_forecast']['forecastday'][0]['fcttext_metric']
            f2 = f_data['txt_forecast']['forecastday'][1]['fcttext_metric']
        d1 = f_data['txt_forecast']['forecastday'][0]['title']
        d2 = f_data['txt_forecast']['forecastday'][1]['title']
        forecast = f_fmt % locals()
        bot.bot_reply(event, forecast)
Example #4
0
def run(bot, event, db):
    mod_name = __name__.rsplit('.', 1)[1]
    this_mod = db(db.bot_modules.name == mod_name).select()
    prefix = this_mod.first().vars_pre
    k_apikey = prefix + 'apikey'
    apikey = bot_utils.get_item(k_apikey, db)

    m = event.message.lower()
    msg = event.message
    s = msg.split()

    if m.startswith(k_apikey) and len(s) == 2:
        apikey = s[1]
        bot_utils.set_item(k_apikey, apikey, db)
        bot.bot_reply(event, "Wolfram|Alpha API key set to %s" % apikey)
        return

    if m.startswith('!wa '):
        q = quote(' '.join(s[1:]))

        if apikey == '':
            bot.bot_reply(
                event,
                "Wolfram|Alpha API key not installed. Please let the bot admin know."
            )
            return

        try:
            req = urllib2.Request(WA_URL % locals())
            res = urllib2.urlopen(req)
        except urllib2.HTTPError:
            bot.bot_reply(event, "HTTP error, unable to retrieve results.")
            return

        page = res.read()
        #dbg_log = open('cicero_debug.log', 'w')
        #dbg_log.write(page)
        #dbg_log.close()
        page = BeautifulSoup(page)

        qr = page.queryresult
        if qr['success'] == 'false':
            bot.bot_reply(event,
                          "Wolfram|Alpha error, unable to retrieve results.")
            return

        try:
            out_txt = "No text result (check your input interpretation)."
            in_txt = ''
            for pod in page.find_all('pod'):
                if pod['id'] == 'Input':
                    in_txt = pod.subpod.plaintext.get_text()
                elif pod['id'] == 'Result' and pod['primary'] == 'true':
                    out_txt = pod.subpod.plaintext.get_text()
        except KeyError:
            bot.bot_reply(event, "Error parsing results.")
            return

        if in_txt == '':
            bot.bot_reply(event,
                          "Wolfram|Alpha error, could not interpret input.")
            return

        bot.bot_reply(event, out_txt)
        bot.bot_reply(event, 'Input interpretation: ' + in_txt, False)
        bot.bot_reply(event, 'More: http://www.wolframalpha.com/input/?i=' + q,
                      False)
Example #5
0
def bot_admin():
    """
    BotenAlfred admin panel

    Will display whether or not bot is running (if pid exists and os.getpgid(pid)
    (getpgid() will raise OSError if process doesn't exist)
    Will give option to start bot if not running, stop bot if running (link to bot/default/bot_start or bot/default/bot_stop)
    List all modules with edit button next to each (link to bot/default/bot_module/id)
    List current bot configuration (server, port, channels, nickname, etc.), provide edit button (link to /bot/default/bot_edit)
    """
    ## Modules
    #modules = list()
    #for r in db().select(db.bot_modules.ALL):
        #form = SQLFORM(db.bot_modules, r, formstyle='table3cols')
        #if form.process().accepted:
            #response.flash = "Module updated"
        #modules.append(form)
        
    modules = db().select(db.bot_modules.ALL)
    
    sets = dict(bot_settings=SQLTABLE(db().select(db.bot_vars.ALL)),
                modules=modules)
    
    ## start/stop
    if len(request.args) and request.args[0] == 'start':
        bot_pid = int(bot_utils.get_item('pid', db))
        if bot_pid:
            try:
                if os.getpgid(bot_pid):
                    # bot already running
                    response.flash = "Bot already running"
                    return sets
            except OSError:
                pass
        #if os.fork():
            #time.sleep(2)
            # Note: pid vars in db won't be updated until bot connects and joins channel,
            # about 5 seconds.  Same for kill.
            #apache_pid = os.getpid()
            #db(db.bot_vars.tbl_k == 'apache_pid').update(v=apache_pid)
            #response.flash = "Bot started successfully"
            #return sets
        #else:
            #os.system('python web2py.py -S bot -M -R applications/bot/private/bot_run.py')
            #os._exit(0)
        os.system('rm ponybot_stdout.log')
        os.system('python web2py.py -S freebot -M -R applications/freebot/private/bot_run.py > freebot_stdout.log')
        return sets
    elif len(request.args) and request.args[0] == 'stop':
        # There are four processes of interest when killing the bot
        # The first two are the Python instance and the sh instance
        # created by the call to os.system() (bot_pid and bot_ppid)
        # Those processes are parented to a child of the apache thread
        # that is created when we os.fork()
        # That process exit()s on its own when the children are killed,
        # but usually turns into a zombie process
        # Killing the parent apache thread (which is then replaced by
        # the apache daemon) cleans up the zombie process (apache_pid)
        bot_pid = int(bot_utils.get_item('pid', db))
        bot_ppid = int(bot_utils.get_item('ppid', db))
        apache_pid = int(bot_utils.get_item('apache_pid', db))
        if bot_pid:
            try:
                os.kill(bot_pid, signal.SIGKILL)
                #os.kill(bot_ppid, signal.SIGKILL)
            except OSError:
                response.flash = "No such process"
            else:
                response.flash = "Bot killed"
            db(db.bot_vars.tbl_k == 'pid').update(v='0')
            db(db.bot_vars.tbl_k == 'ppid').update(v='0')
            #os.kill(apache_pid, signal.SIGKILL)  # Oops, since apache recycles threads, this may kill the thread that called this function
            #db(db.bot_vars.tbl_k == 'apache_pid').update(v='0')
            return sets
        else:
            response.flash = "Bot not running or pid not stored"
            return sets
    else:
        return sets
Example #6
0
def run(bot, event, db):
    if event.message.lower().startswith(
            '!botlove') and event.target.startswith('#'):
        bot.send_action(event.target,
                        'hugs ' + bot_utils.get_item('love_name', db))