def get_episodes_for_series(seriesname): res = {"error":None, "ended":False, "episodes":None, "name":None} # http://thetvdb.com/wiki/index.php/API:GetSeries try: query = http.get_xml(base_url + 'GetSeries.php', seriesname=seriesname) except URLError: res["error"]="error contacting thetvdb.com " + randout.fail() return res series_id = query.xpath('//seriesid/text()') if not series_id: res["error"] = "unknown tv series (using www.thetvdb.com) " + randout.fail() return res series_id = series_id[0] try: series = get_zipped_xml(base_url + '%s/series/%s/all/en.zip' % (api_key, series_id), path="en.xml") except URLError: res["error"] = "error contacting thetvdb.com " + randout.fail() return res series_name = series.xpath('//SeriesName/text()')[0] if series.xpath('//Status/text()')[0] == 'Ended': res["ended"] = True res["episodes"] = series.xpath('//Episode') res["name"] = series_name return res
def lastfm(inp, nick="", say=None, db=None, bot=None): api_key = bot.config.get("api", {}).get("lastfm") if not api_key: return "hey rant at my owner to get an API key added! " + randout.fail() db.execute("create table if not exists lastfm(nick primary key, acc)") sql = db.execute("select acc from lastfm where nick=lower(?)", (nick,)).fetchone() if sql: if not inp: user = sql[0] else: user = inp db.execute("insert or replace into lastfm(nick,acc) values(?,?)", (nick.lower(), user)) db.commit() else: if not inp: user = nick else: user = inp db.execute("insert or replace into lastfm(nick,acc) values(?,?)", (nick.lower(), user)) db.commit() response = http.get_json(api_url, method="user.getrecenttracks", api_key=api_key, user=user, limit=1) if "error" in response: if inp: # specified a user name return "error: %s" % response["message"] else: return "your nick is not a LastFM account " + randout.fail() + ". try '.lastfm username'. " tracks = response["recenttracks"]["track"] if len(tracks) == 0: return "no recent tracks for user %r found" % user if type(tracks) == list: # if the user is listening to something, the tracks entry is a list # the first item is the current track track = tracks[0] status = "current track" elif type(tracks) == dict: # otherwise, they aren't listening to anything right now, and # the tracks entry is a dict representing the most recent track track = tracks status = "last track" else: return "error parsing track listing" title = track["name"] album = track["album"]["#text"] artist = track["artist"]["#text"] ret = "\x02%s\x0F's %s - \x02%s\x0f" % (user, status, title) if artist: ret += " by \x02%s\x0f" % artist if album: ret += " on \x02%s\x0f" % album say(ret)
def mode(inp, input=None, db=None): ".mode - set modes on things. admin only." if input.nick not in input.bot.config["admins"]: input.notice("only bot admins can use this command, sorry " + randout.fail()) return db_init(db) split = inp.split(" ") print repr(split) if split[0] in ["set", "delete"]: names = dict(mode=None, nick="*", user="******", host="*", authed="*", admin="*", channel="*", chanmodes="*", usermodes="*") elif split[0] == "search": names = dict(mode="*", nick="*", user="******", host="*", authed="*", admin="*", channel="*", chanmodes="*", usermodes="*", limit="5") elif split[0] == "query": names = dict(mode="", nick="", user="", host="", authed="", admin="", channel="", chanmodes="", usermodes="", limit="5") dictized = dict([y for y in [x.split("=") for x in split[1:]] if len(y) == 2]) names.update(dictized) if names["mode"] == None: input.notice("mode name is required! " + randout. fail()) return namemap = "mode nick user host authed admin channel chanmodes usermodes".split(" ") sqlargs = [names[i] for i in namemap] if split[0] in ["query", "search"]: if split[0] == "query": result = query(db, sqlargs).fetchall() else: result = posquery(db, sqlargs).fetchall() names["limit"] = int(names["limit"]) if not len(result): input.notice("no results " + randout.fail()) return elif len(result) > names["limit"]: input.notice("exceeded your provided limit (limit=%d), cutting off" % names["limit"]) result = result[:names["limit"]] result = [namemap] + [[repr(j)[1:] for j in i] for i in result] #hack to justify into a table lengths = [[len(result[x][y]) for y in range(len(result[x]))] for x in range(len(result))] lengths = [max([lengths[x][i] for x in range(len(result))]) for i in range(len(result[0]))] for i in result: out = "" for j in range(len(result[0])): out += i[j].ljust(lengths[j] + 1) input.notice(out) elif split[0] == "set": if "".join(sqlargs[1:]) == "*******" and ("iamsure" not in names or names["iamsure"] != "yes"): input.notice("you're trying to set a mode on everything. please repeat with 'iamsure=yes' on the query to confirm.") return db.execute("insert into botmodes(modename, nick, user, host, authed, admin, channel, chanmodes, usermodes) values(?, ?, ?, ?, ?, ?, ?, ?, ?)", sqlargs) db.commit() input.notice("done. " + randout.success()) elif split[0] == "delete": db.execute("delete from botmodes where modename=? and nick=? and user=? and host=? and authed=? and admin=? and channel=? and chanmodes=? and usermodes=?", sqlargs) db.commit() input.notice("done. " + randout.success())
def title(inp, db=None, chan=None): ".title <url> - get title of <url>" if inp == '^': urlhistory.db_init(db) rows = db.execute("select url from urlhistory where chan = ? order by time desc limit 1", (chan,)) if not rows.rowcount: return "No url in history. " + randout.fail() inp = rows.fetchone()[0] try: parts = urlparse.urlsplit(inp) conn = httplib.HTTPConnection(parts.hostname, timeout=10) path = parts.path if parts.query: path += "?" + parts.query conn.request('HEAD', path) resp = conn.getresponse() if not (200 <= resp.status < 400): return "Error: HEAD %s %s " + randout.fail() % (resp.status, resp.reason) errors = check_response(dict(resp.getheaders())) if errors: return errors except Exception as e: return "Error: " + str(e) try: req = urllib2.urlopen(inp) except Exception as e: return "Error: GET %s " + randout.fail() % e errors = check_response(req.headers) if errors: return errors text = req.read(maxlen).decode('utf8', 'ignore') match = titler.search(text) if not match: return "Error: no title " + randout.fail() rawtitle = match.group(1) title = repaste.decode_html(rawtitle) title = " ".join(title.split()) return title
def imdb(inp): '''.imdb <movie> -- gets information about <movie> from IMDb''' content = http.get_json("http://www.imdbapi.com/", t=inp) if content['Response'] == 'Movie Not Found': return 'movie not found ' + randout.fail() elif content['Response'] == 'True': content['URL'] = 'http://www.imdb.com/title/%(ID)s' % content return "\x02%(Title)s\x02 (%(Year)s) (%(Genre)s): %(Plot)s " \ "\x02%(Runtime)s\x02. \x02%(Rating)s/10\x02 with " \ "\x02%(Votes)s\x02 votes. %(URL)s" % content else: return 'unknown error ' + randout.fail()
def deadfly(inp, db=None): ".deadfly <adf.ly url> -- scrapes link shortened by adf.ly" db_init(db) result = db_get(db, inp) if result: return result[0] parts = urlparse.urlsplit(inp) parts = parts._replace(netloc=parts.netloc + ".nyud.net") url = urlparse.urlunsplit(parts) timeout = 15 try: text = urllib2.urlopen(url, timeout=timeout).read() except Exception, e: print e url = inp try: text = urllib2.urlopen(url, timeout=timeout).read() except Exception, e: print e return "Error " + randout.fail()
def wolframalpha(inp, bot=None): ".wa <query> -- Computes <query> using Wolfram Alpha." api_key = bot.config.get("api", {}).get("wolframalpha") if api_key is None: return "I have a lazy owner, they won't even bother adding an API key! " + randout.fail() url = 'http://api.wolframalpha.com/v2/query?format=plaintext' result = http.get_xml(url, input=inp, appid=api_key) fail = 'No results. ' + randout.fail() pod_texts = [] for pod in result.xpath("//pod"): title = pod.attrib['title'] if pod.attrib['id'] == 'Input': continue results = [] for subpod in pod.xpath('subpod/plaintext/text()'): subpod = subpod.strip().replace('\\n', '; ') subpod = re.sub(r'\s+', ' ', subpod) if subpod: results.append(subpod) if results: pod_texts.append(title + ': ' + '|'.join(results)) ret = '. '.join(pod_texts) if not pod_texts: return fail ret = re.sub(r'\\(.)', r'\1', ret) def unicode_sub(match): return unichr(int(match.group(1), 16)) ret = re.sub(r'\\:([0-9a-z]{4})', unicode_sub, ret) if len(ret) > 430: ret = ret[:ret.rfind(' ', 0, 430)] ret = re.sub(r'\W+$', '', ret) + '...' if not ret: return fail return ret
def calc(inp): '''.calc <term> -- returns Google Calculator result''' page = http.get('http://www.google.com/search', q=inp) # ugh, scraping HTML with regexes m = re.search(r'<h2 class=r style="font-size:138%"><b>(.*?)</b>', page) if m is None: return "could not calculate " + inp + " " + randout.fail() result = m.group(1).replace("<font size=-2> </font>", ",") result = result.replace(" × 10<sup>", "E").replace("</sup>", "") result = result.replace("\xa0", ",") return result