示例#1
0
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?!")
示例#2
0
def cmd_watch(msg):

    # Get current state
    node = None
    for n in context.data.getChilds():
        if n["server"] == msg.server and n["channel"] == msg.channel:
            node = n
            break

    if len(msg.args):
        if msg.args[0] == "stop" and node is not None:
            context.data.delChild(node)
            context.save()
            raise IMException(
                "This channel will not anymore receives world cup events.")
        elif msg.args[0] == "start" and node is None:
            start_watch(msg)
        else:
            raise IMException("Use only start or stop as first argument")
    else:
        if node is None:
            start_watch(msg)
        else:
            context.data.delChild(node)
            context.save()
            raise IMException(
                "This channel will not anymore receives world cup events.")
示例#3
0
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.")
示例#4
0
    def _nextURLContent(res):
        size = int(res.getheader("Content-Length", 524288))
        cntype = res.getheader("Content-Type")

        if max_size >= 0 and (size > max_size or
                              (cntype is not None and cntype[:4] != "text"
                               and cntype[:4] != "appl")):
            raise IMException("Content too large to be retrieved")

        data = res.read(size)

        # Decode content
        charset = "utf-8"
        if cntype is not None:
            lcharset = res.getheader("Content-Type").split(";")
            if len(lcharset) > 1:
                for c in lcharset:
                    ch = c.split("=")
                    if ch[0].strip().lower() == "charset" and len(ch) > 1:
                        cha = ch[1].split(".")
                        if len(cha) > 1:
                            charset = cha[1]
                        else:
                            charset = cha[0]

        import http.client

        if res.status == http.client.OK or res.status == http.client.SEE_OTHER:
            return data.decode(charset).strip()
        elif decode_error:
            return data.decode(charset).strip()
        else:
            raise IMException("A HTTP error occurs: %d - %s" %
                              (res.status, http.client.responses[res.status]))
示例#5
0
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 ""))
示例#6
0
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
示例#7
0
def headers(url):
    """Retrieve HTTP header for the given URL

    Argument:
    url -- the page URL to get header
    """

    o = urllib.parse.urlparse(web.getNormalizedURL(url), "http")
    if o.netloc == "":
        raise IMException("invalid URL")
    if o.scheme == "http":
        conn = http.client.HTTPConnection(o.hostname, port=o.port, timeout=5)
    else:
        conn = http.client.HTTPSConnection(o.hostname, port=o.port, timeout=5)
    try:
        conn.request("HEAD", o.path, None,
                     {"User-agent": "Nemubot v%s" % __version__})
    except ConnectionError as e:
        raise IMException(e.strerror)
    except socket.timeout:
        raise IMException("request timeout")
    except socket.gaierror:
        print("<tools.web> Unable to receive page %s from %s on %d." %
              (o.path, o.hostname, o.port if o.port is not None else 0))
        raise IMException("an unexpected error occurs")

    try:
        res = conn.getresponse()
    except http.client.BadStatusLine:
        raise IMException("An error occurs")
    finally:
        conn.close()

    return (res.version, res.status, res.reason, res.getheaders())
示例#8
0
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
示例#9
0
def cmd_reduceurl(msg):
    minify = list()

    if not len(msg.args):
        global LAST_URLS
        if msg.channel in LAST_URLS and len(LAST_URLS[msg.channel]) > 0:
            minify.append(LAST_URLS[msg.channel].pop())
        else:
            raise IMException("I have no more URL to reduce.")

    if len(msg.args) > 4:
        raise IMException("I cannot reduce that many URLs at once.")
    else:
        minify += msg.args

    if 'provider' in msg.kwargs and msg.kwargs['provider'] in PROVIDERS:
        provider = msg.kwargs['provider']
    else:
        provider = DEFAULT_PROVIDER

    res = list()
    for url in minify:
        o = urlparse(web.getNormalizedURL(url), "http")
        minief_url = reduce(url, provider)
        if o.netloc == "":
            res.append(gen_response(minief_url, msg, o.scheme))
        else:
            res.append(gen_response(minief_url, msg, o.netloc))
    return res
示例#10
0
def cmd_smscmd(msg):
    if not len(msg.args):
        raise IMException("À qui veux-tu envoyer ce SMS ?")

    cur_epoch = time.mktime(time.localtime())
    dests = msg.args[0].split(",")
    frm = msg.frm if msg.to_response[
        0] == msg.frm else msg.frm + "@" + msg.to[0]
    cmd = " ".join(msg.args[1:])

    content = None
    for r in context.subtreat(context.subparse(msg, cmd)):
        if isinstance(r, Response):
            for m in r.messages:
                if isinstance(m, list):
                    for n in m:
                        content = n
                        break
                    if content is not None:
                        break
                elif isinstance(m, str):
                    content = m
                    break

        elif isinstance(r, Text):
            content = r.message

    if content is None:
        raise IMException(
            "Aucun SMS envoyé : le résultat de la commande n'a pas retourné de contenu."
        )

    check_sms_dests(dests, cur_epoch)
    return send_sms_to_list(msg, frm, dests, content, cur_epoch)
示例#11
0
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
示例#12
0
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
示例#13
0
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
示例#14
0
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))
示例#15
0
def validator(url):
    """Run the w3c validator on the given URL

    Argument:
    url -- the URL to validate
    """

    o = urllib.parse.urlparse(getNormalizedURL(url), "http")
    if o.netloc == "":
        raise IMException("Indicate a valid URL!")

    try:
        req = urllib.request.Request(
            "https://validator.w3.org/check?uri=%s&output=json" %
            (urllib.parse.quote(o.geturl())),
            headers={'User-Agent': "Nemubot v%s" % __version__})
        raw = urllib.request.urlopen(req, timeout=10)
    except urllib.error.HTTPError as e:
        raise IMException("HTTP error occurs: %s %s" % (e.code, e.reason))

    headers = dict()
    for Hname, Hval in raw.getheaders():
        headers[Hname] = Hval

    if "X-W3C-Validator-Status" not in headers or (
            headers["X-W3C-Validator-Status"] != "Valid"
            and headers["X-W3C-Validator-Status"] != "Invalid"):
        raise IMException("Unexpected error on W3C servers" +
                          (" (" + headers["X-W3C-Validator-Status"] +
                           ")" if "X-W3C-Validator-Status" in headers else ""))

    return headers, json.loads(raw.read().decode())
示例#16
0
def _get_ytdl(links):
  cmd = 'youtube-dl -j --'.split()
  cmd.extend(links)
  res = []
  with subprocess.Popen(cmd, stdout=subprocess.PIPE) as p:
    if p.wait() > 0:
      raise IMException("Error while retrieving video information.")
    for line in p.stdout.read().split(b"\n"):
      localres = ''
      if not line:
        continue
      info = json.loads(line.decode('utf-8'))
      if info.get('fulltitle'):
        localres += info['fulltitle']
      elif info.get('title'):
        localres += info['title']
      else:
        continue
      if info.get('duration'):
        d = info['duration']
        localres += ' [{0}:{1:06.3f}]'.format(int(d/60), d%60)
      if info.get('age_limit'):
        localres += ' [-{}]'.format(info['age_limit'])
      if info.get('uploader'):
        localres += ' by {}'.format(info['uploader'])
      if info.get('upload_date'):
        localres += ' on {}'.format(info['upload_date'])
      if info.get('description'):
        localres += ': ' +  info['description']
      if info.get('webpage_url'):
        localres += ' | ' +  info['webpage_url']
      res.append(localres)
  if not res:
    raise IMException("No video information to retrieve about this. Sorry!")
  return res
示例#17
0
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
示例#18
0
def define(msg):
    if not len(msg.args):
        raise IMException("Indicate a term to define")

    s = do_search(msg.args)

    if not s.definition:
        raise IMException("no definition found for '%s'." % " ".join(msg.args))

    return Response(s.definition, channel=msg.channel)
示例#19
0
def cmd_title(msg):
    if not len(msg.args):
        raise IMException("Indicate the URL to visit.")

    url = " ".join(msg.args)
    res = re.search("<title>(.*?)</title>", page.fetch(" ".join(msg.args)), re.DOTALL)

    if res is None:
        raise IMException("The page %s has no title" % url)
    else:
        return Response("%s: %s" % (url, res.group(1).replace("\n", " ")), channel=msg.channel)
示例#20
0
def lstu_reducer(url, data):
    json_data = json.loads(
        web.getURLContent(
            url,
            "lsturl=" + quote(data),
            header={"Content-Type": "application/x-www-form-urlencoded"}))
    if 'short' in json_data:
        return json_data['short']
    elif 'msg' in json_data:
        raise IMException("Error: %s" % json_data['msg'])
    else:
        IMException("An error occured while shortening %s." % data)
示例#21
0
def check_sms_dests(dests, cur_epoch):
    """Raise exception if one of the dest is not known or has already receive a SMS recently
    """
    for u in dests:
        if u not in context.data.index:
            raise IMException(
                "Désolé, je sais pas comment envoyer de SMS à %s." % u)
        elif cur_epoch - float(context.data.index[u]["lastuse"]) < 42:
            raise IMException(
                "Un peu de calme, %s a déjà reçu un SMS il n'y a pas si longtemps."
                % u)
    return True
示例#22
0
def cmd_coordinates(msg):
    if len(msg.args) < 1:
        raise IMException("indique-moi un nom de ville.")

    j = msg.args[0].lower()
    if j not in context.data.index:
        raise IMException("%s n'est pas une ville connue" % msg.args[0])

    coords = context.data.index[j]
    return Response("Les coordonnées de %s sont %s,%s" %
                    (msg.args[0], coords["lat"], coords["long"]),
                    channel=msg.channel)
示例#23
0
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
示例#24
0
def ask_stations(msg):
    if len(msg.args) > 4:
        raise IMException("demande-moi moins de stations à la fois.")
    elif not len(msg.args):
        raise IMException("pour quelle station ?")

    for station in msg.args:
        if re.match("^[0-9]{4,5}$", station):
            return print_station_status(msg, station)
        elif station in context.data.index:
            return print_station_status(msg,
                                        context.data.index[station]["number"])
        else:
            raise IMException("numéro de station invalide.")
示例#25
0
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
示例#26
0
def cmd_conjug(msg):
    if len(msg.args) < 2:
        raise IMException("donne moi un temps et un verbe, et je te donnerai "
                           "sa conjugaison!")

    tens = ' '.join(msg.args[:-1])

    verb = msg.args[-1]

    conjug = get_conjug(verb, tens)

    if len(conjug) > 0:
        return Response(conjug, channel=msg.channel,
                        title="Conjugaison de %s" % verb)
    else:
        raise IMException("aucune conjugaison de '%s' n'a été trouvé" % verb)
示例#27
0
def add_site(url, nick, channel, server, diffType="diff"):
    """Add a site to watching list

    Argument:
    url -- URL to watch
    """

    o = urlparse(getNormalizedURL(url), "http")
    if o.netloc == "":
        raise IMException("sorry, I can't watch this URL :(")

    alert = ModuleState("alert")
    alert["nick"] = nick
    alert["server"] = server
    alert["channel"] = channel
    alert["message"] = "{url} just changed!"

    if url not in DATAS.index:
        watch = ModuleState("watch")
        watch["type"] = diffType
        watch["url"] = url
        watch["time"] = 123
        DATAS.addChild(watch)
        watch.addChild(alert)
        start_watching(watch)
    else:
        DATAS.index[url].addChild(alert)

    save()
    return Response(channel=channel, nick=nick,
                    message="this site is now under my supervision.")
示例#28
0
def gen_response(res, msg, srv):
    if res is None:
        raise IMException("bad URL : %s" % srv)
    else:
        return Text("URL for %s: %s" % (srv, res),
                    server=None,
                    to=msg.to_response)
示例#29
0
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
示例#30
0
def available(dom):
    js = getJSON(URL_AVAIL % urllib.parse.quote(dom))

    if "ErrorMessage" in js:
        raise IMException(js["ErrorMessage"]["msg"])

    return js["DomainInfo"]["domainAvailability"] == "AVAILABLE"