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()
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
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)
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)
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
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))