def cmd_directions(msg): drcts = directions(["{0},{1}".format(*firstgeocode(g)[0]) for g in msg.args], profile=msg.kwargs["profile"] if "profile" in msg.kwargs else "foot-walking", preference=msg.kwargs["preference"] if "preference" in msg.kwargs else "recommended", units="m", language=msg.kwargs["lang"] if "lang" in msg.kwargs else "en", geometry=False, instructions=True, instruction_format="text") if "error" in drcts and "message" in drcts["error"] and drcts["error"]["message"]: raise IMException(drcts["error"]["message"]) if "routes" not in drcts or not drcts["routes"]: raise IMException("No route available for this trip") myway = drcts["routes"][0] myway["summary"]["strduration"] = approx_duration(myway["summary"]["duration"]) myway["summary"]["strdistance"] = approx_distance(myway["summary"]["distance"]) res = Response("Trip summary: {strdistance} in approximate {strduration}; elevation +{ascent} m -{descent} m".format(**myway["summary"]), channel=msg.channel, count=" (%d more steps)", nomore="You have arrived!") def formatSegments(segments): for segment in segments: for step in segment["steps"]: step["strtype"] = waytype[step["type"]] step["strduration"] = approx_duration(step["duration"]) step["strdistance"] = approx_distance(step["distance"]) yield "{instruction} for {strdistance} on {strtype} (approximate time: {strduration})".format(**step) if "segments" in myway: res.append_message([m for m in formatSegments(myway["segments"])]) return res
def cmd_github(msg): if not len(msg.args): raise IMException("indicate a repository name to search") repos = info_repos(" ".join(msg.args)) res = Response(channel=msg.channel, nomore="No more repository", count=" (%d more repo)") for repo in repos["items"]: homepage = "" if repo["homepage"] is not None: homepage = repo["homepage"] + " - " res.append_message("Repository %s: %s%s Main language: %s; %d forks; %d stars; %d watchers; %d opened_issues; view it at %s" % (repo["full_name"], homepage, repo["description"], repo["language"], repo["forks"], repo["stargazers_count"], repo["watchers_count"], repo["open_issues_count"], repo["html_url"])) return res
def cmd_alert(msg): loc, coords, specific = treat_coord(msg) wth = get_json_weather( coords, lang=msg.kwargs["lang"] if "lang" in msg.kwargs else "en", units=msg.kwargs["units"] if "units" in msg.kwargs else "ca") res = Response(channel=msg.channel, nomore="No more weather alert", count=" (%d more alerts)") if "alerts" in wth: for alert in wth["alerts"]: if "expires" in alert: res.append_message( "\x03\x02%s\x03\x02 (see %s expire on %s): %s" % (alert["title"], alert["uri"], format_timestamp(int(alert["expires"]), wth["timezone"], wth["offset"]), alert["description"].replace("\n", " "))) else: res.append_message("\x03\x02%s\x03\x02 (see %s): %s" % (alert["title"], alert["uri"], alert["description"].replace("\n", " "))) return res
def cmd_github_issue(msg): if not len(msg.args): raise IMException("indicate a repository to view its issues") issue = None li = re.match("^#?([0-9]+)$", msg.args[0]) ri = re.match("^#?([0-9]+)$", msg.args[-1]) if li is not None: issue = li.group(1) del msg.args[0] elif ri is not None: issue = ri.group(1) del msg.args[-1] repo = " ".join(msg.args) count = " (%d more issues)" if issue is None else None res = Response(channel=msg.channel, nomore="No more issue", count=count) issues = info_issue(repo, issue) if issues is None: raise IMException("Repository not found") for issue in issues: res.append_message("%s%s issue #%d: \x03\x02%s\x03\x02 opened by %s on %s: %s" % (issue["state"][0].upper(), issue["state"][1:], issue["number"], issue["title"], issue["user"]["login"], issue["created_at"], issue["body"].replace("\n", " "))) return res
def cmd_w3m(msg): if not len(msg.args): raise IMException("Indicate the URL to visit.") res = Response(channel=msg.channel) for line in page.render(" ".join(msg.args)).split("\n"): res.append_message(line) return res
def get_tracking_info(msg): if not len(msg.args): raise IMException("Renseignez un identifiant d'envoi.") res = Response(channel=msg.channel, count=" (%d suivis supplémentaires)") if 'tracker' in msg.kwargs: if msg.kwargs['tracker'] in TRACKING_HANDLERS: trackers = { msg.kwargs['tracker']: TRACKING_HANDLERS[msg.kwargs['tracker']] } else: raise IMException("No tracker named \x02{tracker}\x0F, please use" " one of the following: \x02{trackers}\x0F" .format(tracker=msg.kwargs['tracker'], trackers=', ' .join(TRACKING_HANDLERS.keys()))) else: trackers = TRACKING_HANDLERS for tracknum in msg.args: for name, tracker in trackers.items(): ret = tracker(tracknum) if ret: res.append_message(ret) break if not ret: res.append_message("L'identifiant \x02{id}\x0F semble incorrect," " merci de vérifier son exactitude." .format(id=tracknum)) return res
def cmd_imdb(msg): if not len(msg.args): raise IMException("precise a movie/serie title!") title = ' '.join(msg.args) if re.match("^tt[0-9]{7}$", title) is not None: data = get_movie_by_id(imdbid=title) else: rm = re.match(r"^(.+)\s\(([0-9]{4})\)$", title) if rm is not None: data = find_movies(rm.group(1), year=rm.group(2)) else: data = find_movies(title) if not data: raise IMException("Movie/series not found") data = get_movie_by_id(data[0]["id"]) res = Response(channel=msg.channel, title="%s (%s)" % (data['Title'], data['Year']), nomore="No more information, more at http://www.imdb.com/title/%s" % data['imdbID']) res.append_message("%s \x02genre:\x0F %s; \x02rating\x0F: %s (%s votes); \x02plot\x0F: %s" % (data['Type'], data['Genre'], data['imdbRating'], data['imdbVotes'], data['Plot'])) res.append_message("%s \x02from\x0F %s; %s" % (data['Type'], data['Country'], data['Credits'])) return res
def go(msg, what): if not len(msg.args): raise IMException("de quel mot veux-tu connaître la liste des synonymes ?") lang = msg.kwargs["lang"] if "lang" in msg.kwargs else "fr" word = ' '.join(msg.args) try: best, synos, anton = lang_binding[lang](word) except: best, synos, anton = (list(), list(), list()) if what == "synonymes": if len(synos) > 0 or len(best) > 0: res = Response(channel=msg.channel, title="Synonymes de %s" % word) if len(best) > 0: res.append_message(best) if len(synos) > 0: res.append_message(synos) return res else: raise IMException("Aucun synonyme de %s n'a été trouvé" % word) elif what == "antonymes": if len(anton) > 0: res = Response(anton, channel=msg.channel, title="Antonymes de %s" % word) return res else: raise IMException("Aucun antonyme de %s n'a été trouvé" % word) else: raise IMException("WHAT?!")
def cmd_github_commit(msg): if not len(msg.args): raise IMException("indicate a repository to view its commits") commit = None if re.match("^[a-fA-F0-9]+$", msg.args[0]): commit = msg.args[0] del msg.args[0] elif re.match("^[a-fA-F0-9]+$", msg.args[-1]): commit = msg.args[-1] del msg.args[-1] repo = " ".join(msg.args) count = " (%d more commits)" if commit is None else None res = Response(channel=msg.channel, nomore="No more commit", count=count) commits = info_commit(repo, commit) if commits is None: raise IMException("Repository or commit not found") for commit in commits: res.append_message("Commit %s by %s on %s: %s" % (commit["sha"][:10], commit["commit"]["author"]["name"], commit["commit"]["author"]["date"], commit["commit"]["message"].replace("\n", " "))) return res
def cmd_whois(msg): if len(msg.args) < 1: raise IMException("Provide a name") def format_response(t): srch, l = t if type(l) is Login: pic = l.get_photo() return "%s is %s (%s %s): %s%s" % ( srch, l.cn.capitalize(), l.login, l.uid, l.get_promo(), " and looks like %s" % pic if pic is not None else "") else: return l % srch res = Response(channel=msg.channel, count=" (%d more logins)", line_treat=format_response) for srch in msg.args: found = False for l in login_lookup(srch, "lookup" in msg.kwargs): found = True res.append_message((srch, l)) if not found: res.append_message((srch, "Unknown %s :(")) return res
def cmd_imdb(msg): if not len(msg.args): raise IMException("precise a movie/serie title!") title = ' '.join(msg.args) if re.match("^tt[0-9]{7}$", title) is not None: data = get_movie_by_id(imdbid=title) else: rm = re.match(r"^(.+)\s\(([0-9]{4})\)$", title) if rm is not None: data = find_movies(rm.group(1), year=rm.group(2)) else: data = find_movies(title) if not data: raise IMException("Movie/series not found") data = get_movie_by_id(data[0]["id"]) res = Response( channel=msg.channel, title="%s (%s)" % (data['Title'], data['Year']), nomore="No more information, more at http://www.imdb.com/title/%s" % data['imdbID']) res.append_message( "%s \x02genre:\x0F %s; \x02rating\x0F: %s (%s votes); \x02plot\x0F: %s" % (data['Type'], data['Genre'], data['imdbRating'], data['imdbVotes'], data['Plot'])) res.append_message("%s \x02from\x0F %s; %s" % (data['Type'], data['Country'], data['Credits'])) return res
def cmd_flight(msg): if not len(msg.args): raise IMException("please indicate a flight") res = Response(channel=msg.channel, nick=msg.frm, nomore="No more flights", count=" (%s more flights)") for param in msg.args: for flight in virtual_radar(param): if 'Lat' in flight and 'Long' in flight: loc = None for location in mapquest.geocode( '{Lat},{Long}'.format(**flight)): loc = location break if loc: res.append_message('\x02{0}\x0F: Position: \x02{1}\x0F, {2}'.format(flight['Call'], \ mapquest.where(loc), \ ', '.join(filter(None, flight_info(flight))))) continue res.append_message('\x02{0}\x0F: {1}'.format(flight['Call'], \ ', '.join(filter(None, flight_info(flight))))) return res
def cmd_github_user(msg): if not len(msg.args): raise IMException("indicate a user name to search") res = Response(channel=msg.channel, nomore="No more user") user = info_user(" ".join(msg.args)) if "login" in user: if user["repos"]: kf = (" Known for: " + ", ".join([repo["name"] for repo in user["repos"]])) else: kf = "" if "name" in user: name = user["name"] else: name = user["login"] res.append_message("User %s: %d public repositories; %d public gists; %d followers; %d following; view it at %s.%s" % (name, user["public_repos"], user["public_gists"], user["followers"], user["following"], user["html_url"], kf)) else: raise IMException("User not found") return res
def cmd_curl(msg): if not len(msg.args): raise IMException("Indicate the URL to visit.") res = Response(channel=msg.channel) for m in page.fetch(" ".join(msg.args)).split("\n"): res.append_message(m) return res
def get_freetarif(msg): res = Response(channel=msg.channel) for country in msg.args: t = get_land_tarif(country.lower().capitalize(), "pkg" + (msg.kwargs["forfait"] if "forfait" in msg.kwargs else "FREE").upper()) res.append_message(["\x02%s\x0F : %s" % (ACT[k], t[k]) for k in sorted(ACT.keys(), reverse=True)], title=country) return res
def cmd_github_user_keys(msg): if not len(msg.args): raise IMException("indicate a user name to search") res = Response(channel=msg.channel, nomore="No more keys") for k in user_keys(" ".join(msg.args)): res.append_message(k) return res
def cmd_srchmediawiki(msg): if len(msg.args) < 2: raise IMException("indicate a domain and a term to search") res = Response(channel=msg.to_response, nomore="No more results", count=" (%d more results)") for r in search(msg.args[0], " ".join(msg.args[1:]), **msg.kwargs): res.append_message("%s: %s" % r) return res
def cmd_geocode(msg): res = Response(channel=msg.channel, nick=msg.frm, nomore="No more geocode", count=" (%s more geocode)") for loc in geocode(' '.join(msg.args)): res.append_message("%s is at %s,%s" % ( where(loc[1]), loc[0][1], loc[0][0], )) return res
def cmd_snap(msg): images = getJSON("https://ohsnap.p0m.fr/api/images") if "errmsg" in images: raise IMException(images["errmsg"]) res = Response(channel=msg.channel, nomore="No more snap to show") for image in images: res.append_message( "Snap de {author}, le {upload_time} : https://ohsnap.p0m.fr/{hash}" .format(**image)) return res
def get_info_yt(msg): soup = BeautifulSoup(getURLContent(URL)) res = Response(channel=msg.channel, nomore="No more upcoming CTF") for line in soup.body.find_all('tr'): n = line.find_all('td') if len(n) == 7: res.append_message("\x02%s:\x0F from %s type %s at %s. Weight: %s. %s%s" % tuple([striphtml(x.text).strip() for x in n])) return res
def cmd_srchmediawiki(msg): if len(msg.args) < 2: raise IMException("indicate a domain and a term to search") res = Response(channel=msg.to_response, nomore="No more results", count=" (%d more results)") for r in search(msg.args[0], " ".join(msg.args[1:]), **msg.kwargs): res.append_message("%s: %s" % r) return res
def liste(msg): """!eventslist: gets list of timer""" if len(msg.args): res = Response(channel=msg.channel) for user in msg.args: cmptr = [k for k in context.data if context.data[k].creator == user] if len(cmptr) > 0: res.append_message(cmptr, title="Events created by %s" % user) else: res.append_message("%s doesn't have any counting events" % user) return res else: return Response(list(context.data.keys()), channel=msg.channel, title="Known events")
def cmd_subreddit(msg): global LAST_SUBS if not len(msg.args): if msg.channel in LAST_SUBS and len(LAST_SUBS[msg.channel]) > 0: subs = [LAST_SUBS[msg.channel].pop()] else: raise IMException("Which subreddit? Need inspiration? " "type !horny or !bored") else: subs = msg.args all_res = list() for osub in subs: sub = re.match(r"^/?(?:(\w)/)?(\w+)/?$", osub) if sub is not None: if sub.group(1) is not None and sub.group(1) != "": where = sub.group(1) else: where = "r" sbr = web.getJSON("https://www.reddit.com/%s/%s/about.json" % (where, sub.group(2))) if sbr is None: raise IMException("subreddit not found") if "title" in sbr["data"]: res = Response(channel=msg.channel, nomore="No more information") res.append_message( ("[NSFW] " if sbr["data"]["over18"] else "") + sbr["data"]["url"] + " " + sbr["data"]["title"] + ": " + sbr["data"] ["public_description" if sbr["data"]["public_description"] != "" else "description"].replace("\n", " ") + " %s subscriber(s)" % sbr["data"]["subscribers"]) if sbr["data"]["public_description"] != "": res.append_message(sbr["data"]["description"].replace( "\n", " ")) all_res.append(res) else: all_res.append( Response("/%s/%s doesn't exist" % (where, sub.group(2)), channel=msg.channel)) else: all_res.append( Response("%s is not a valid subreddit" % osub, channel=msg.channel, nick=msg.frm)) return all_res
def cmd_geocode(msg): res = Response(channel=msg.channel, nick=msg.frm, nomore="No more geocode", count=" (%s more geocode)") for loc in geocode(' '.join(msg.args)): res.append_message("%s is at %s,%s" % ( where(loc[1]), loc[0][1], loc[0][0], )) return res
def cmd_whatis(msg): args = ["whatis", " ".join(msg.args)] res = Response(channel=msg.channel) with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: for line in proc.stdout.read().split(b"\n"): (line, n) = RGXP_s.subn(b'', line) res.append_message(" ".join(line.decode().split())) if len(res.messages) <= 0: res.append_message("There is no man page for %s." % msg.args[0]) return res
def cmd_eix(msg): if not len(msg.args): raise IMException("please give me a package to search") def srch(term): try: yield package_info(term) except portage.exception.AmbiguousPackageName as e: for i in e.args[0]: yield package_info(i) res = Response(channel=msg.channel, count=" (%d more packages)", nomore="No more package '%s'" % msg.args[0]) for pi in srch(msg.args[0]): res.append_message("\x03\x02{pkgname}:\x03\x02 {description} - {homepage} - {license} - last revisions: \x03\x02{lastvers}\x03\x02{ov}".format(ov=(", " + ', '.join(pi["othersvers"])) if pi["othersvers"] else "", **pi)) return res
def cmd_whatis(msg): args = ["whatis", " ".join(msg.args)] res = Response(channel=msg.channel) with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: for line in proc.stdout.read().split(b"\n"): (line, n) = RGXP_s.subn(b'', line) res.append_message(" ".join(line.decode().split())) if len(res.messages) <= 0: res.append_message("There is no man page for %s." % msg.args[0]) return res
def udsearch(msg): if not len(msg.args): raise IMException("Indicate a term to search") s = search(msg.args) res = Response(channel=msg.channel, nomore="No more results", count=" (%d more definitions)") for i in s["list"]: res.append_message(i["definition"].replace("\n", " "), title=i["word"]) return res
def cmd_geocode(msg): if not len(msg.args): raise IMException("indicate a name") res = Response(channel=msg.channel, nick=msg.frm, nomore="No more geocode", count=" (%s more geocode)") for loc in geocode(' '.join(msg.args)): res.append_message("%s is at %s,%s (%s precision)" % (where(loc), loc["latLng"]["lat"], loc["latLng"]["lng"], loc["geocodeQuality"].lower())) return res
def cmd_news(msg): if not len(msg.args): raise IMException("Indicate the URL to visit.") url = " ".join(msg.args) links = [x for x in find_rss_links(url)] if len(links) == 0: links = [ url ] res = Response(channel=msg.channel, nomore="No more news from %s" % url) for n in get_last_news(links[0]): res.append_message("%s published %s: %s %s" % (("\x02" + web.striphtml(n.title) + "\x0F") if n.title else "An article without title", (n.updated.strftime("on %A %d. %B %Y at %H:%M") if n.updated else "someday") if isinstance(n, AtomEntry) else n.pubDate, web.striphtml(n.summary) if n.summary else "", n.link if n.link else "")) return res
def cmd_tpb(msg): if not len(msg.args): raise IMException("indicate an item to search!") torrents = getJSON(URL_TPBAPI + urllib.parse.quote(" ".join(msg.args))) res = Response(channel=msg.channel, nomore="No more torrents", count=" (%d more torrents)") if torrents: for t in torrents: t["sizeH"] = human.size(t["size"]) t["dateH"] = datetime.fromtimestamp(t["date"]).strftime('%Y-%m-%d %H:%M:%S') res.append_message("\x03\x02{title}\x03\x02 in {category}, {sizeH}; added at {dateH}; id: {id}; magnet:?xt=urn:btih:{magnet}&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Fopen.demonii.com%3A1337".format(**t)) return res
def cmd_book(msg): if not len(msg.args): raise IMException("please give me a title to search") book = get_book(" ".join(msg.args)) if book is None: raise IMException("unable to find book named like this") res = Response(channel=msg.channel) res.append_message("%s, written by %s: %s" % ( book.getElementsByTagName("title")[0].firstChild.nodeValue, book.getElementsByTagName("author")[0].getElementsByTagName( "name")[0].firstChild.nodeValue, web.striphtml( book.getElementsByTagName("description")[0].firstChild.nodeValue if book.getElementsByTagName("description")[0].firstChild else ""))) return res
def cmd_alert(msg): loc, coords, specific = treat_coord(msg) wth = get_json_weather(coords, lang=msg.kwargs["lang"] if "lang" in msg.kwargs else "en", units=msg.kwargs["units"] if "units" in msg.kwargs else "ca") res = Response(channel=msg.channel, nomore="No more weather alert", count=" (%d more alerts)") if "alerts" in wth: for alert in wth["alerts"]: if "expires" in alert: res.append_message("\x03\x02%s\x03\x02 (see %s expire on %s): %s" % (alert["title"], alert["uri"], format_timestamp(int(alert["expires"]), wth["timezone"], wth["offset"]), alert["description"].replace("\n", " "))) else: res.append_message("\x03\x02%s\x03\x02 (see %s): %s" % (alert["title"], alert["uri"], alert["description"].replace("\n", " "))) return res
def calculate(msg): if not len(msg.args): raise IMException("Indicate a calcul to compute") s = WFAResults(' '.join(msg.args)) if not s.success: raise IMException(s.error) res = Response(channel=msg.channel, nomore="No more results") for result in s.results: res.append_message(re.sub(r' +', ' ', result)) if len(res.messages): res.messages.pop(0) return res
def calculate(msg): if not len(msg.args): raise IMException("Indicate a calcul to compute") s = WFAResults(' '.join(msg.args)) if not s.success: raise IMException(s.error) res = Response(channel=msg.channel, nomore="No more results") for result in s.results: res.append_message(re.sub(r' +', ' ', result)) if len(res.messages): res.messages.pop(0) return res
def get_info_yt(msg): links = list() if len(msg.args) <= 0: global LAST_URLS if msg.channel in LAST_URLS and len(LAST_URLS[msg.channel]) > 0: links.append(LAST_URLS[msg.channel].pop()) else: raise IMException("I don't have any youtube URL for now, please provide me one to get information!") else: for url in msg.args: links.append(url) data = _get_ytdl(links) res = Response(channel=msg.channel) for msg in data: res.append_message(msg) return res
def liste(msg): """!eventslist: gets list of timer""" if len(msg.args): res = Response(channel=msg.channel) for user in msg.args: cmptr = [ k for k in context.data if context.data[k].creator == user ] if len(cmptr) > 0: res.append_message(cmptr, title="Events created by %s" % user) else: res.append_message("%s doesn't have any counting events" % user) return res else: return Response(list(context.data.keys()), channel=msg.channel, title="Known events")
def cmd_books(msg): if not len(msg.args): raise IMException("please give me a title to search") title = " ".join(msg.args) res = Response(channel=msg.channel, title="%s" % (title), count=" (%d more books)") for book in search_books(title): res.append_message( "%s, writed by %s" % (book.getElementsByTagName("best_book")[0].getElementsByTagName( "title")[0].firstChild.nodeValue, book.getElementsByTagName("best_book")[0].getElementsByTagName( "author")[0].getElementsByTagName("name") [0].firstChild.nodeValue)) return res
def cmd_directions(msg): drcts = directions( ["{0},{1}".format(*firstgeocode(g)[0]) for g in msg.args], profile=msg.kwargs["profile"] if "profile" in msg.kwargs else "foot-walking", preference=msg.kwargs["preference"] if "preference" in msg.kwargs else "recommended", units="m", language=msg.kwargs["lang"] if "lang" in msg.kwargs else "en", geometry=False, instructions=True, instruction_format="text") if "error" in drcts and "message" in drcts["error"] and drcts["error"][ "message"]: raise IMException(drcts["error"]["message"]) if "routes" not in drcts or not drcts["routes"]: raise IMException("No route available for this trip") myway = drcts["routes"][0] myway["summary"]["strduration"] = approx_duration( myway["summary"]["duration"]) myway["summary"]["strdistance"] = approx_distance( myway["summary"]["distance"]) res = Response( "Trip summary: {strdistance} in approximate {strduration}; elevation +{ascent} m -{descent} m" .format(**myway["summary"]), channel=msg.channel, count=" (%d more steps)", nomore="You have arrived!") def formatSegments(segments): for segment in segments: for step in segment["steps"]: step["strtype"] = waytype[step["type"]] step["strduration"] = approx_duration(step["duration"]) step["strdistance"] = approx_distance(step["distance"]) yield "{instruction} for {strdistance} on {strtype} (approximate time: {strduration})".format( **step) if "segments" in myway: res.append_message([m for m in formatSegments(myway["segments"])]) return res
def cmd_tcode(msg): if not len(msg.args): raise IMException("indicate a transaction code or " "a keyword to search!") url = ("https://www.tcodesearch.com/tcodes/search?q=%s" % urllib.parse.quote(msg.args[0])) page = web.getURLContent(url) soup = BeautifulSoup(page) res = Response(channel=msg.channel, nomore="No more transaction code", count=" (%d more tcodes)") search_res = soup.find("", {'id': 'searchresults'}) for item in search_res.find_all('dd'): res.append_message(item.get_text().split('\n')[1].strip()) return res
def cmd_tpb(msg): if not len(msg.args): raise IMException("indicate an item to search!") torrents = getJSON(URL_TPBAPI + urllib.parse.quote(" ".join(msg.args))) res = Response(channel=msg.channel, nomore="No more torrents", count=" (%d more torrents)") if torrents: for t in torrents: t["sizeH"] = human.size(t["size"]) t["dateH"] = datetime.fromtimestamp( t["date"]).strftime('%Y-%m-%d %H:%M:%S') res.append_message( "\x03\x02{title}\x03\x02 in {category}, {sizeH}; added at {dateH}; id: {id}; magnet:?xt=urn:btih:{magnet}&tr=udp%3A%2F%2Ftracker.openbittorrent.com%3A80&tr=udp%3A%2F%2Ftracker.publicbt.com%3A80&tr=udp%3A%2F%2Ftracker.istole.it%3A6969&tr=udp%3A%2F%2Fopen.demonii.com%3A1337" .format(**t)) return res
def cmd_whois(msg): if len(msg.args) < 1: raise IMException("Provide a name") def format_response(t): srch, l = t if type(l) is Login: pic = l.get_photo() return "%s is %s (%s %s): %s%s" % (srch, l.cn.capitalize(), l.login, l.uid, l.get_promo(), " and looks like %s" % pic if pic is not None else "") else: return l % srch res = Response(channel=msg.channel, count=" (%d more logins)", line_treat=format_response) for srch in msg.args: found = False for l in login_lookup(srch, "lookup" in msg.kwargs): found = True res.append_message((srch, l)) if not found: res.append_message((srch, "Unknown %s :(")) return res
def cmd_man(msg): args = ["man"] num = None if len(msg.args) == 1: args.append(msg.args[0]) elif len(msg.args) >= 2: try: num = int(msg.args[0]) args.append("%d" % num) args.append(msg.args[1]) except ValueError: args.append(msg.args[0]) os.unsetenv("LANG") res = Response(channel=msg.channel) with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc: for line in proc.stdout.read().split(b"\n"): (line, n) = RGXP_s.subn(b'', line) res.append_message(line.decode()) if len(res.messages) <= 0: if num is not None: res.append_message("There is no entry %s in section %d." % (msg.args[0], num)) else: res.append_message("There is no man page for %s." % msg.args[0]) return res
def cmd_spell(msg): if not len(msg.args): raise IMException("indique une orthographe approximative du mot dont tu veux vérifier l'orthographe.") lang = msg.kwargs["lang"] if "lang" in msg.kwargs else "fr" res = Response(channel=msg.channel) for word in msg.args: try: r = check_spell(word, lang) except AspellError: raise IMException("Je n'ai pas le dictionnaire `%s' :(" % lang) if r == True: add_score(msg.frm, "correct") res.append_message("l'orthographe de `%s' est correcte" % word) elif len(r) > 0: add_score(msg.frm, "bad") res.append_message(r, title="suggestions pour `%s'" % word) else: add_score(msg.frm, "bad") res.append_message("aucune suggestion pour `%s'" % word) return res
def shodan(msg): if not msg.args: raise IMException("indicate an IP or a term to search!") terms = " ".join(msg.args) try: ip = ipaddress.ip_address(terms) except ValueError: ip = None if ip: h = host_lookup(terms) res = Response(channel=msg.channel, title="%s" % ((h["ip_str"] if ip.version == 4 else "[%s]" % h["ip_str"]) + (" (" + ", ".join(h["hostnames"]) + ")") if h["hostnames"] else "")) res.append_message("{isp} ({asn}) -> {city} ({country_code}), running {os}. Vulns: {vulns_str}. Open ports: {open_ports}. Last update: {last_update}".format( open_ports=", ".join(map(lambda a: str(a), h["ports"])), vulns_str=", ".join(h["vulns"]) if "vulns" in h else None, **h).strip()) for d in h["data"]: res.append_message(print_service(d)) else: q = search_hosts(terms) res = Response(channel=msg.channel, count=" (%%s/%s results)" % q["total"]) for r in q["matches"]: res.append_message(print_service(r)) return res
def cmd_flight(msg): if not len(msg.args): raise IMException("please indicate a flight") res = Response(channel=msg.channel, nick=msg.frm, nomore="No more flights", count=" (%s more flights)") for param in msg.args: for flight in virtual_radar(param): if 'Lat' in flight and 'Long' in flight: loc = None for location in mapquest.geocode('{Lat},{Long}'.format(**flight)): loc = location break if loc: res.append_message('\x02{0}\x0F: Position: \x02{1}\x0F, {2}'.format(flight['Call'], \ mapquest.where(loc), \ ', '.join(filter(None, flight_info(flight))))) continue res.append_message('\x02{0}\x0F: {1}'.format(flight['Call'], \ ', '.join(filter(None, flight_info(flight))))) return res
def cmd_disas(msg): if not len(msg.args): raise IMException("please give me some code") # Determine the architecture if "arch" in msg.kwargs: if msg.kwargs["arch"] not in ARCHITECTURES: raise IMException("unknown architectures '%s'" % msg.kwargs["arch"]) architecture = ARCHITECTURES[msg.kwargs["arch"]] else: architecture = capstone.CS_ARCH_X86 # Determine hardware modes modes = 0 if "modes" in msg.kwargs: for mode in msg.kwargs["modes"].split(','): if mode not in MODES: raise IMException("unknown mode '%s'" % mode) modes += MODES[mode] elif architecture == capstone.CS_ARCH_X86 or architecture == capstone.CS_ARCH_PPC: modes = capstone.CS_MODE_32 elif architecture == capstone.CS_ARCH_ARM or architecture == capstone.CS_ARCH_ARM64: modes = capstone.CS_MODE_ARM elif architecture == capstone.CS_ARCH_MIPS: modes = capstone.CS_MODE_MIPS32 # Get the code code = bytearray.fromhex(''.join([a.replace("0x", "") for a in msg.args])) # Setup capstone md = capstone.Cs(architecture, modes) res = Response(channel=msg.channel, nomore="No more instruction") for isn in md.disasm(code, 0x1000): res.append_message("%s %s" %(isn.mnemonic, isn.op_str), title="0x%x" % isn.address) return res
def get_cve_desc(msg): res = Response(channel=msg.channel) for cve_id in msg.args: if cve_id[:3].lower() != 'cve': cve_id = 'cve-' + cve_id cve = get_cve(cve_id) if not cve: raise IMException("CVE %s doesn't exists." % cve_id) if "alert-title" in cve or "alert-content" in cve: alert = "\x02%s:\x0F %s " % (cve["alert-title"] if "alert-title" in cve else "", cve["alert-content"] if "alert-content" in cve else "") else: alert = "" if "base_score" not in cve and "description" in cve: res.append_message("{alert}From \x02{source}\x0F, last modified on \x02{last_modified}\x0F. {description}".format(alert=alert, **cve), title=cve_id) else: metrics = display_metrics(**cve) res.append_message("{alert}Base score: \x02{base_score} {severity}\x0F (impact: \x02{impact_score}\x0F, exploitability: \x02{exploitability_score}\x0F; {metrics}), from \x02{source}\x0F, last modified on \x02{last_modified}\x0F. {description}".format(alert=alert, metrics=metrics, **cve), title=cve_id) return res
def cmd_worldcup(msg): res = Response(channel=msg.channel, nomore="No more match to display", count=" (%d more matches)") url = None if len(msg.args) == 1: if msg.args[0] == "today" or msg.args[0] == "aujourd'hui": url = "matches/today?by_date=ASC" elif msg.args[0] == "tomorrow" or msg.args[0] == "demain": url = "matches/tomorrow?by_date=ASC" elif msg.args[0] == "all" or msg.args[0] == "tout" or msg.args[0] == "tous": url = "matches/" elif len(msg.args[0]) == 3: url = "matches/country?fifa_code=%s&by_date=DESC" % msg.args[0] elif is_int(msg.args[0]): url = int(msg.args[0]) else: raise IMException("unrecognized request; choose between 'today', 'tomorrow', a FIFA country code or a match identifier") if url is None: url = "matches/current?by_date=ASC" res.nomore = "There is no match currently" if isinstance(url, int): matches = get_match(API_URL % "matches/", url) else: matches = [m for m in get_matches(API_URL % url)] for match in matches: if len(matches) == 1: res.count = " (%d more actions)" for m in prettify(match): res.append_message(m) else: res.append_message(prettify(match)[0]) return res
def parseanswer(msg): res = Response(channel=msg.channel) # Avoid message starting by ! which can be interpreted as command by other bots if msg.cmd[0] == "!": res.nick = msg.frm if msg.cmd in context.data: if context.data[msg.cmd].end: res.append_message("%s commencé il y a %s et se terminera dans %s." % (msg.cmd, countdown(msg.date - context.data[msg.cmd].start), countdown(context.data[msg.cmd].end - msg.date))) else: res.append_message("%s commencé il y a %s." % (msg.cmd, countdown(msg.date - context.data[msg.cmd].start))) else: res.append_message(countdown_format(context.data[msg.cmd].start, context.data[msg.cmd]["msg_before"], context.data[msg.cmd]["msg_after"])) return res
def cmd_w3c(msg): if not len(msg.args): raise IMException("Indicate an URL to validate!") headers, validator = w3c.validator(msg.args[0]) res = Response(channel=msg.channel, nomore="No more error") res.append_message("%s: status: %s, %s warning(s), %s error(s)" % (validator["url"], headers["X-W3C-Validator-Status"], headers["X-W3C-Validator-Warnings"], headers["X-W3C-Validator-Errors"])) for m in validator["messages"]: if "lastLine" not in m: res.append_message("%s%s: %s" % (m["type"][0].upper(), m["type"][1:], m["message"])) else: res.append_message("%s%s on line %s, col %s: %s" % (m["type"][0].upper(), m["type"][1:], m["lastLine"], m["lastColumn"], m["message"])) return res
def cmd_smmry(msg): if not len(msg.args): global LAST_URLS if msg.channel in LAST_URLS and len(LAST_URLS[msg.channel]) > 0: msg.args.append(LAST_URLS[msg.channel].pop()) else: raise IMException("I have no more URL to sum up.") URL = URL_API if "length" in msg.kwargs: if int(msg.kwargs["length"]) > 0 : URL += "&SM_LENGTH=" + msg.kwargs["length"] else: msg.kwargs["ignore_length"] = True if "break" in msg.kwargs: URL += "&SM_WITH_BREAK" if "ignore_length" in msg.kwargs: URL += "&SM_IGNORE_LENGTH" if "quote_avoid" in msg.kwargs: URL += "&SM_QUOTE_AVOID" if "question_avoid" in msg.kwargs: URL += "&SM_QUESTION_AVOID" if "exclamation_avoid" in msg.kwargs: URL += "&SM_EXCLAMATION_AVOID" if "keywords" in msg.kwargs and msg.kwargs["keywords"] is not None and int(msg.kwargs["keywords"]) > 0: URL += "&SM_KEYWORD_COUNT=" + msg.kwargs["keywords"] res = Response(channel=msg.channel) if web.isURL(" ".join(msg.args)): smmry = web.getJSON(URL + "&SM_URL=" + quote(" ".join(msg.args)), timeout=23) else: cnt = "" for r in context.subtreat(context.subparse(msg, " ".join(msg.args))): if isinstance(r, Response): for i in range(len(r.messages) - 1, -1, -1): if isinstance(r.messages[i], list): for j in range(len(r.messages[i]) - 1, -1, -1): cnt += r.messages[i][j] + "\n" elif isinstance(r.messages[i], str): cnt += r.messages[i] + "\n" else: cnt += str(r.messages) + "\n" elif isinstance(r, Text): cnt += r.message + "\n" else: cnt += str(r) + "\n" smmry = web.getJSON(URL, body="sm_api_input=" + quote(cnt), timeout=23) if "sm_api_error" in smmry: if smmry["sm_api_error"] == 0: title = "Internal server problem (not your fault)" elif smmry["sm_api_error"] == 1: title = "Incorrect submission variables" elif smmry["sm_api_error"] == 2: title = "Intentional restriction (low credits?)" elif smmry["sm_api_error"] == 3: title = "Summarization error" else: title = "Unknown error" raise IMException(title + ": " + smmry['sm_api_message'].lower()) if "keywords" in msg.kwargs: smmry["sm_api_content"] = ", ".join(smmry["sm_api_keyword_array"]) if "sm_api_title" in smmry and smmry["sm_api_title"] != "": res.append_message(smmry["sm_api_content"], title=smmry["sm_api_title"]) else: res.append_message(smmry["sm_api_content"]) return res