def cmd_sleep(msg): if len(msg.args) and re.match("[0-9]{1,2}[h':.,-]([0-9]{1,2})?[m'\":.,-]?", msg.args[0]) is not None: # First, parse the hour p = re.match("([0-9]{1,2})[h':.,-]([0-9]{1,2})?[m':.,-]?", msg.args[0]) f = [ datetime(datetime.now(timezone.utc).year, datetime.now(timezone.utc).month, datetime.now(timezone.utc).day, hour=int(p.group(1))) ] if p.group(2) is not None: f[0] += timedelta(minutes=int(p.group(2))) g = list() for i in range(6): f.append(f[i] - timedelta(hours=1, minutes=30)) g.append(f[i + 1].strftime("%H:%M")) return Response("You should try to fall asleep at one of the following" " times: %s" % ', '.join(g), channel=msg.channel) # Just get awake times else: f = [datetime.now(timezone.utc) + timedelta(minutes=15)] g = list() for i in range(6): f.append(f[i] + timedelta(hours=1, minutes=30)) g.append(f[i + 1].strftime("%H:%M")) return Response("If you head to bed right now, you should try to wake" " up at one of the following times: %s" % ', '.join(g), channel=msg.channel)
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 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 parseask(msg): res = re.match( r"^(\S+)\s*('s|suis|est|is|was|were)?\s+(birthday|geburtstag|née? |nee? le|born on).*$", msg.message, re.I) if res is not None: try: extDate = extractDate(msg.message) if extDate is None or extDate.year > datetime.now().year: return Response("la date de naissance ne paraît pas valide...", msg.channel, msg.frm) else: nick = res.group(1) if nick == "my" or nick == "I" or nick == "i" or nick == "je" or nick == "mon" or nick == "ma": nick = msg.frm if nick.lower() in context.data.index: context.data.index[nick.lower()]["born"] = extDate else: ms = ModuleState("birthday") ms.setAttribute("name", nick.lower()) ms.setAttribute("born", extDate) context.data.addChild(ms) context.save() return Response( "ok, c'est noté, %s est né le %s" % (nick, extDate.strftime("%A %d %B %Y à %H:%M")), msg.channel, msg.frm) except: raise IMException("la date de naissance ne paraît pas valide.")
def cmd_anniv(msg): (matches, name) = findName(msg) if len(matches) == 1: name = matches[0] tyd = context.data.index[name].getDate("born") tyd = datetime(date.today().year, tyd.month, tyd.day) if (tyd.day == datetime.today().day and tyd.month == datetime.today().month): return Response( countdown_format( context.data.index[name].getDate("born"), "", "C'est aujourd'hui l'anniversaire de %s !" " Il a %s. Joyeux anniversaire :)" % (name, "%s")), msg.channel) else: if tyd < datetime.today(): tyd = datetime(date.today().year + 1, tyd.month, tyd.day) return Response( countdown_format( tyd, "Il reste %s avant l'anniversaire de %s !" % ("%s", name), ""), msg.channel) else: return Response( "désolé, je ne connais pas la date d'anniversaire" " de %s. Quand est-il né ?" % name, msg.channel, msg.frm)
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 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 parseask(msg): if msg.message.find("Free") >= 0 and ( msg.message.find("API") >= 0 or msg.message.find("api") >= 0) and ( msg.message.find("SMS") >= 0 or msg.message.find("sms") >= 0): resuser = apiuser_ask.search(msg.message) reskey = apikey_ask.search(msg.message) if resuser is not None and reskey is not None: apiuser = resuser.group("user") apikey = reskey.group("key") test = send_sms( "nemubot", apiuser, apikey, "Vous avez enregistré vos codes d'authentification dans nemubot, félicitation !" ) if test is not None: return Response( "je n'ai pas pu enregistrer tes identifiants : %s" % test, msg.channel, msg.frm) if msg.frm in context.data.index: context.data.index[msg.frm]["user"] = apiuser context.data.index[msg.frm]["key"] = apikey else: ms = ModuleState("phone") ms.setAttribute("name", msg.frm) ms.setAttribute("user", apiuser) ms.setAttribute("key", apikey) ms.setAttribute("lastuse", 0) context.data.addChild(ms) context.save() return Response( "ok, c'est noté. Je t'ai envoyé un SMS pour tester ;)", msg.channel, msg.frm)
def ask_ratp(msg): l = len(msg.args) transport = msg.args[0] if l > 0 else None line = msg.args[1] if l > 1 else None station = msg.args[2] if l > 2 else None direction = msg.args[3] if l > 3 else None if station is not None: times = sorted(ratp.getNextStopsAtStation(transport, line, station, direction), key=lambda i: i[0]) if len(times) == 0: raise IMException("la station %s n'existe pas sur le %s ligne %s." % (station, transport, line)) (time, direction, stationname) = times[0] return Response(message=["\x03\x02%s\x03\x02 direction %s" % (time, direction) for time, direction, stationname in times], title="Prochains passages du %s ligne %s à l'arrêt %s" % (transport, line, stationname), channel=msg.channel) elif line is not None: stations = ratp.getAllStations(transport, line) if len(stations) == 0: raise IMException("aucune station trouvée.") return Response(stations, title="Stations", channel=msg.channel) elif transport is not None: lines = ratp.getTransportLines(transport) if len(lines) == 0: raise IMException("aucune ligne trouvée.") return Response(lines, title="Lignes", channel=msg.channel) else: raise IMException("précise au moins un moyen de transport.")
def cmd_alias(msg): if not len(msg.args): raise IMException("!alias takes as argument an alias to extend.") alias = context.subparse(msg, msg.args[0]) if alias is None or not isinstance(alias, Command): raise IMException("%s is not a valid alias" % msg.args[0]) if alias.cmd in context.data.getNode("aliases").index: return Response( "%s corresponds to %s" % (alias.cmd, context.data.getNode("aliases").index[alias.cmd]["origin"]), channel=msg.channel, nick=msg.frm) elif len(msg.args) > 1: create_alias(alias.cmd, " ".join(msg.args[1:]), channel=msg.channel, creator=msg.frm) return Response("New alias %s successfully registered." % alias.cmd, channel=msg.channel) else: wym = [ m for m in guess(alias.cmd, context.data.getNode("aliases").index) ] raise IMException(msg.args[0] + " is not an alias." + (" Would you mean: %s?" % ", ".join(wym) if len(wym) else ""))
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 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_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_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 mediawiki_response(site, term, to, **kwargs): ns = get_namespaces(site, **kwargs) terms = term.split("#", 1) try: # Print the article if it exists return Response(strip_model( get_page(site, terms[0], subpart=terms[1] if len(terms) > 1 else None, **kwargs)), line_treat=lambda line: irc_format( parse_wikitext(site, line, ns, **kwargs)), channel=to) except: pass # Try looking at opensearch os = [x for x, _, _ in opensearch(site, terms[0], **kwargs)] print(os) # Fallback to global search if not len(os): os = [ x for x, _ in search(site, terms[0], **kwargs) if x is not None and x != "" ] return Response(os, channel=to, title="Article not found, would you mean")
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 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_listalias(msg): aliases = [a for a in list_alias(None) ] + [a for a in list_alias(msg.channel)] if len(aliases): return Response([a["alias"] for a in aliases], channel=msg.channel, title="Known aliases") return Response("There is no alias currently.", channel=msg.channel)
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 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 cmd_isup(msg): if not len(msg.args): raise IMException("Indicate an domain name to check!") res = list() for url in msg.args[:4]: rep = isup.isup(url) if rep: res.append(Response("%s is up (response time: %ss)" % (url, rep), channel=msg.channel)) else: res.append(Response("%s is down" % (url), channel=msg.channel)) 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 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_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 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_age(msg): (matches, name) = findName(msg) if len(matches) == 1: name = matches[0] d = context.data.index[name].getDate("born") return Response( countdown_format(d, "%s va naître dans %s." % (name, "%s"), "%s a %s." % (name, "%s")), msg.channel) else: return Response( "désolé, je ne connais pas l'âge de %s." " Quand est-il né ?" % name, msg.channel, msg.frm) return True
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_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 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_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_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_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 send_sms_to_list(msg, frm, dests, content, cur_epoch): fails = list() for u in dests: context.data.index[u]["lastuse"] = cur_epoch test = send_sms(frm, context.data.index[u]["user"], context.data.index[u]["key"], content) if test is not None: fails.append("%s: %s" % (u, test)) if len(fails) > 0: return Response( "quelque chose ne s'est pas bien passé durant l'envoi du SMS : " + ", ".join(fails), msg.channel, msg.frm) else: return Response("le SMS a bien été envoyé", msg.channel, msg.frm)
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_overview(msg): if "host" not in msg.kwargs: raise IMException("please give a hostname in keywords") if not len(msg.args): raise IMException("which group would you overview?") for g in msg.args: arts = [] for grp in read_group(g, **msg.kwargs): grp["X-FromName"], grp["X-FromEmail"] = parseaddr( grp["from"] if "from" in grp else "") if grp["X-FromName"] == '': grp["X-FromName"] = grp["X-FromEmail"] arts.append( "On {date}, from \x03{0:02d}{X-FromName}\x0F \x02{subject}\x0F: \x0314{message-id}\x0F" .format( adler32(grp["X-FromEmail"].encode()) & 0xf, **{h: decode_header(i) for h, i in grp.items()})) if len(arts): yield Response(arts, channel=msg.channel, title="In \x03{0:02d}{1}\x0F".format( adler32(g[0].encode()) & 0xf, g))
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 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 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 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_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 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_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_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_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 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