Пример #1
0
def xkcd(m):
    """Get an xkcd comic based on given arguments."""
    if len(m.line) == 1:
        url = "http://c.xkcd.com/random/comic/"
        html = get_url(m, url)
        message = xkcd_direct(html)
        if message is None:
            m.bot.logger.error("Couldn't get random xkcd comic.")
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    elif len(m.line) == 2 and m.line[1].isdigit():
        url = "http://xkcd.com/{0}/".format(m.line[1])
        html = get_url(m, url)
        if html is None:
            m.bot.private_message(m.location, "There is no xkcd #{0}.".format(m.line[1]))
            return
        message = xkcd_direct(html, url)
        if message is None:
            m.bot.logger.error("Couldn't get xkcd comic #{0}.".format(m.line[1]))
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    else:
        query = " ".join(m.line[1:])
        url = 'https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=site:xkcd.com%20{0}'\
              .format(quote(query))
        html = get_url(m, url)
        message = xkcd_google(html)
    m.bot.private_message(m.location, message)
def reddit(m, url):
    """Retrieve information about the Reddit link."""

    # I'm sorry
    reddit_regex = re.compile(
        r'reddit\.com/(?:u(?:ser)?/(?P<user>.+?)(?:\Z|#|/)|r/(?P<sub>.+?)'
        r'(?:/?\Z|/comments/(?P<id>.+?)(?:/?\Z|/(?P<title>.+?)'
        r'(?:/?\Z|/(?P<cid>.+?)(?:/|#|\Z)))))')

    match = re.search(reddit_regex, url)
    if match:
        m.bot.logger.info(
            "Retrieving information from the Reddit API for {}.".format(url))
        if match.group("user"):
            api_url = "http://www.reddit.com/user/{}/about.json"
            user = match.group("user")
            resp = get_url(m, api_url.format(user))
            blob = json.loads(resp)["data"]
            return "User {name}: {link_karma} link karma, {comment_karma} comment " \
                   "karma.".format(**blob)
        else:
            api_url = "http://www.reddit.com/api/info.json?id={}"
            sub, id, cid = match.group("sub"), match.group("id"), match.group(
                "cid")
            if cid:
                resp = get_url(m, api_url.format("t1_" + cid))
                blob = json.loads(resp)["data"]["children"][0]["data"]
                parent_resp = get_url(m, api_url.format("t3_" + id))
                parent_blob = json.loads(
                    parent_resp)["data"]["children"][0]["data"]
                parent_blob["nsfw"] = " \x0304[NSFW]\x03" if parent_blob[
                    "over_18"] else ""
                return "Comment by {user} on \"{title}\"{nsfw} in /r/{sub}. {up}↑.".format(
                    user=blob["author"],
                    title=parent_blob["title"],
                    nsfw=parent_blob["nsfw"],
                    sub=blob["subreddit"],
                    up=blob["ups"])
            elif id:
                resp = get_url(m, api_url.format("t3_" + id))
                blob = json.loads(resp)["data"]["children"][0]["data"]
                blob["nsfw"] = "\x0304[NSFW]\x03" if blob["over_18"] else ""
                return "\"{title}\" in /r/{subreddit}. {ups}↑. {nsfw}".format(
                    **blob)
            else:
                api_url = "http://www.reddit.com/r/{}/about.json"
                resp = get_url(m, api_url.format(sub))
                blob = json.loads(resp)["data"]
                blob["nsfw"] = "\x0304[NSFW]\x03" if blob["over18"] else ""
                return "/r/{display_name}. {title}. {subscribers} subscribers." \
                       " {nsfw}".format(**blob)
    return generic(m, url)
Пример #3
0
def get_weather(m, loc, api_key):
    """Make the API call to get the weather."""
    if loc:
        m.bot.logger.info("Finding weather for {}.".format(loc["name"]))
        forecast_api = "https://api.forecast.io/forecast/{0}/{1},{2}?exclude=flags"
        resp = get_url(m, forecast_api.format(api_key, loc["lat"], loc["long"]))
        return json.loads(resp)
Пример #4
0
def spotify(m):
    """Retrieve information about a Spotify URI."""

    #-     !spotify URI
    #-
    #- ```irc
    #- < GorillaWarfare> !spotify spotify:track:6NmXV4o6bmp704aPGyTVVG
    #- < GorillaBot> "Bøn Fra Helvete (Live)" by Kaizers Orchestra
    #- ```
    #-
    #- Provide information about the Spotify URI. Accepts Spotify- and HTTP-style URIs.
    #-
    #- #### Settings
    #- * `auto` - All Spotify URIs in the chat will be parsed, regardless of whether they're
    #-  prefaced with `!spotify`.

    spotify_uris = re.findall(SPOTIFY_URI_REGEX, m.body)
    for spotify_uri in spotify_uris:
        media_type, identifier = spotify_uri
        req = get_url(m, ENDPOINT.format(media_type, identifier))
        if req:
            blob = json.loads(req)
            if media_type == "track" or media_type == "album":
                m.bot.private_message(
                    m.location,
                    '"{0}" by {1}'.format(blob["name"],
                                          blob["artists"][0]["name"]))
            else:
                m.bot.private_message(m.location, blob["name"])
Пример #5
0
def spotify(m):
    """Retrieve information about a Spotify URI."""

    #-     !spotify URI
    #-
    #- ```irc
    #- < GorillaWarfare> !spotify spotify:track:6NmXV4o6bmp704aPGyTVVG
    #- < GorillaBot> "Bøn Fra Helvete (Live)" by Kaizers Orchestra
    #- ```
    #-
    #- Provide information about the Spotify URI. Accepts Spotify- and HTTP-style URIs.
    #-
    #- #### Settings
    #- * `auto` - All Spotify URIs in the chat will be parsed, regardless of whether they're
    #-  prefaced with `!spotify`.

    spotify_uris = re.findall(SPOTIFY_URI_REGEX, m.body)
    for spotify_uri in spotify_uris:
        media_type, identifier = spotify_uri
        req = get_url(m, ENDPOINT.format(media_type, identifier))
        if req:
            blob = json.loads(req)
            if media_type == "track" or media_type == "album":
                m.bot.private_message(m.location, '"{0}" by {1}'.format(blob["name"], blob["artists"][0]["name"]))
            else:
                m.bot.private_message(m.location, blob["name"])
Пример #6
0
def reddit(m, url):
    """Retrieve information about the Reddit link."""

    # I'm sorry
    reddit_regex = re.compile(r'reddit\.com/(?:u(?:ser)?/(?P<user>.+?)(?:\Z|#|/)|r/(?P<sub>.+?)'
                              r'(?:/?\Z|/comments/(?P<id>.+?)(?:/?\Z|/(?P<title>.+?)'
                              r'(?:/?\Z|/(?P<cid>.+?)(?:/|#|\Z)))))')

    match = re.search(reddit_regex, url)
    if match:
        m.bot.logger.info("Retrieving information from the Reddit API for {}.".format(url))
        if match.group("user"):
            api_url = "http://www.reddit.com/user/{}/about.json"
            user = match.group("user")
            resp = get_url(m, api_url.format(user))
            blob = json.loads(resp)["data"]
            return "User {name}: {link_karma} link karma, {comment_karma} comment " \
                   "karma.".format(**blob)
        else:
            api_url = "http://www.reddit.com/api/info.json?id={}"
            sub, id, cid = match.group("sub"), match.group("id"), match.group("cid")
            if cid:
                resp = get_url(m, api_url.format("t1_" + cid))
                blob = json.loads(resp)["data"]["children"][0]["data"]
                parent_resp = get_url(m, api_url.format("t3_" + id))
                parent_blob = json.loads(parent_resp)["data"]["children"][0]["data"]
                parent_blob["nsfw"] = " \x0304[NSFW]\x03" if parent_blob["over_18"] else ""
                return "Comment by {user} on \"{title}\"{nsfw} in /r/{sub}. {up}↑.".format(
                    user = blob["author"],
                    title = parent_blob["title"],
                    nsfw = parent_blob["nsfw"],
                    sub = blob["subreddit"],
                    up = blob["ups"]
                )
            elif id:
                resp = get_url(m, api_url.format("t3_" + id))
                blob = json.loads(resp)["data"]["children"][0]["data"]
                blob["nsfw"] = "\x0304[NSFW]\x03" if blob["over_18"] else ""
                return "\"{title}\" in /r/{subreddit}. {ups}↑. {nsfw}".format(**blob)
            else:
                api_url = "http://www.reddit.com/r/{}/about.json"
                resp = get_url(m, api_url.format(sub))
                blob = json.loads(resp)["data"]
                blob["nsfw"] = "\x0304[NSFW]\x03" if blob["over18"] else ""
                return "/r/{display_name}. {title}. {subscribers} subscribers." \
                       " {nsfw}".format(**blob)
    return generic(m, url)
Пример #7
0
def get_weather(m, loc, api_key):
    """Make the API call to get the weather."""
    if loc:
        m.bot.logger.info("Finding weather for {}.".format(loc["name"]))
        forecast_api = "https://api.forecast.io/forecast/{0}/{1},{2}?exclude=flags"
        resp = get_url(m, forecast_api.format(api_key, loc["lat"],
                                              loc["long"]))
        return json.loads(resp)
def xkcd(m):
    """Get an xkcd comic based on given arguments."""

    #-     !xkcd [number|query]
    #-
    #- ```irc
    #- < GorillaWarfare> !xkcd batman acne
    #- < GorillaBot> xkcd: Complexion: http://xkcd.com/700/
    #- < GorillaWarfare> !xkcd 700
    #- < GorillaBot> xkcd: Complexion: http://xkcd.com/700/
    #- < GorillaWarfare> !xkcd
    #- < GorillaBot> xkcd: Telescope Names: http://xkcd.com/1294/
    #- ```
    #-
    #- Without any arguments, this provides a random xkcd comic. When a number is supplied,
    #-  it tries to return the xkcd comic with that given number. When a query string is supplied,
    #-  it tries to return the xkcd comic that most closely matches that query.

    if len(m.line) == 1:
        url = "https://c.xkcd.com/random/comic/"
        html = get_url(m, url)
        message = xkcd_direct(html)
        if message is None:
            m.bot.logger.error("Couldn't get random xkcd comic.")
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    elif len(m.line) == 2 and m.line[1].isdigit():
        url = "http://xkcd.com/{0}/".format(m.line[1])
        html = get_url(m, url)
        if html is None:
            m.bot.private_message(m.location,
                                  "There is no xkcd #{0}.".format(m.line[1]))
            return
        message = xkcd_direct(html, url)
        if message is None:
            m.bot.logger.error("Couldn't get xkcd comic #{0}.".format(
                m.line[1]))
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    else:
        query = " ".join(m.line[1:])
        url = 'https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=site:xkcd.com%20{' \
              '0}'.format(quote(query))
        html = get_url(m, url)
        message = xkcd_google(html)
    m.bot.private_message(m.location, message)
Пример #9
0
def xkcd(m):
    """Get an xkcd comic based on given arguments."""

    #-     !xkcd [number|query]
    #-
    #- ```irc
    #- < GorillaWarfare> !xkcd batman acne
    #- < GorillaBot> xkcd: Complexion: http://xkcd.com/700/
    #- < GorillaWarfare> !xkcd 700
    #- < GorillaBot> xkcd: Complexion: http://xkcd.com/700/
    #- < GorillaWarfare> !xkcd
    #- < GorillaBot> xkcd: Telescope Names: http://xkcd.com/1294/
    #- ```
    #-
    #- Without any arguments, this provides a random xkcd comic. When a number is supplied,
    #-  it tries to return the xkcd comic with that given number. When a query string is supplied,
    #-  it tries to return the xkcd comic that most closely matches that query.

    if len(m.line) == 1:
        url = "http://c.xkcd.com/random/comic/"
        html = get_url(m, url)
        message = xkcd_direct(html)
        if message is None:
            m.bot.logger.error("Couldn't get random xkcd comic.")
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    elif len(m.line) == 2 and m.line[1].isdigit():
        url = "http://xkcd.com/{0}/".format(m.line[1])
        html = get_url(m, url)
        if html is None:
            m.bot.private_message(m.location, "There is no xkcd #{0}.".format(m.line[1]))
            return
        message = xkcd_direct(html, url)
        if message is None:
            m.bot.logger.error("Couldn't get xkcd comic #{0}.".format(m.line[1]))
            message = "Sorry, I'm broken. Tell GorillaWarfare to fix me."
    else:
        query = " ".join(m.line[1:])
        url = 'https://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=site:xkcd.com%20{' \
              '0}'.format(quote(query))
        html = get_url(m, url)
        message = xkcd_google(html)
    m.bot.private_message(m.location, message)
Пример #10
0
def generic(m, url):
    """Retrieve the title of the webpage."""
    m.bot.logger.info("Retrieving link for {}.".format(url))
    html = get_url(m, url, True)
    if html:
        title_regex = re.compile(r'<title>(.+?)</title>', re.DOTALL)
        match = re.search(title_regex, html)
        if match:
            return match.group(1)
        else:
            m.bot.logger.info("No title element found.")
            return None
Пример #11
0
def generic(m, url):
    """Retrieve the title of the webpage."""
    m.bot.logger.info("Retrieving link for {}.".format(url))
    html = get_url(m, url, True)
    if html:
        title_regex = re.compile(r'<title>(.+?)</title>', re.DOTALL)
        match = re.search(title_regex, html)
        if match:
            return match.group(1)
        else:
            m.bot.logger.info("No title element found.")
            return None
def youtube(m, url):
    """Retrieve information about the YouTube video."""
    api_key = m.bot.configuration["youtube"]
    if api_key:
        match = re.search(r'youtu(?:be.com/watch\?v=|\.be/)(.+?)(?:\?|&|\Z)',
                          url)
        if match:
            video_id = match.group(1)
            m.bot.logger.info(
                "Retrieving information from the YouTube API for {}.".format(
                    url))
            api_url = "https://www.googleapis.com/youtube/v3/videos?id={id}" \
                      "&key={key}&part=snippet,contentDetails,statistics"
            resp = get_url(m, api_url.format(id=video_id, key=api_key))
            if resp:
                # Load JSON
                blob = json.loads(resp)["items"][0]

                # Parse uploaded time this was originally
                # raw_time =
                raw_time = datetime.strptime(blob["snippet"]["publishedAt"],
                                             "%Y-%m-%dT%H:%M:%S.%fZ")
                pretty_time = raw_time.strftime("%b %d, %Y")

                # Parse video duration
                dur_match = re.match(r'PT(?:(\d+)H)?(?:(\d+)M)?(\d+)S',
                                     blob["contentDetails"]["duration"])
                if dur_match:
                    hr, min, sec = dur_match.groups()
                    if hr:
                        pretty_dur = ":".join([
                            hr, "00" if min is None else min.zfill(2),
                            sec.zfill(2)
                        ])
                    else:
                        pretty_dur = ":".join([
                            "00" if min is None else min.zfill(2),
                            sec.zfill(2)
                        ])
                else:
                    pretty_dur = ""

                # Format and return message
                return "\"{title}\" ({duration}). Uploaded {date}. {views} views. {likes} likes, " \
                       "{dislikes} dislikes.".format(title=blob["snippet"]["title"],
                                                     duration=pretty_dur, date=raw_time, # this was originally pretty_time! I changed it to raw!
                                                     views=blob["statistics"]["viewCount"],
                                                     likes=blob["statistics"]["likeCount"],
                                                     dislikes=blob["statistics"]["dislikeCount"])
    # If there's no API key stored, or the URL is poorly formatted, fall back to generic linking
    return generic(m, url)
Пример #13
0
def get_location(m, line):
    """Get the latitude, longitude, and well-formatted name of the given location."""
    google_api = "http://maps.googleapis.com/maps/api/geocode/json?address={}"
    loc = {}
    loc["name"] = " ".join(line)
    resp = get_url(m, google_api.format("+".join(line)))
    blob = json.loads(resp)
    if not blob["results"]:
        m.bot.private_message(m.location, "Could not find weather information for {}."
                              .format(" ".join(line)))
    else:
        loc["lat"] = blob['results'][0]['geometry']['location']['lat']
        loc["long"] = blob['results'][0]['geometry']['location']['lng']
        loc["addr"] = blob['results'][0]['formatted_address']
        return loc
Пример #14
0
def bash_specific(m, number):
    """Get a specific quote from bash.org."""
    resp = get_url(m, "http://bash.org?" + number)
    soup = BeautifulSoup(resp)
    raw = soup.find(class_="qt")
    if raw:
        meta = soup.find(class_="quote")
        lines = raw.get_text().splitlines()
        if len(lines) > 5 and not m.is_pm:
            m.bot.private_message(m.location, "This quote is too long to post publicly, "
                                              "but you can view it at http://bash.org?"
                                              "{}.".format(number))
        else:
            format_quote(m, lines, meta, number)
    else:
        m.bot.private_message(m.location, "Could not find bash quote.")
Пример #15
0
def get_location(m, line):
    """Get the latitude, longitude, and well-formatted name of the given location."""
    google_api = "http://maps.googleapis.com/maps/api/geocode/json?address={}"
    loc = {}
    loc["name"] = " ".join(line)
    resp = get_url(m, google_api.format("+".join(line)))
    blob = json.loads(resp)
    if not blob["results"]:
        m.bot.private_message(
            m.location, "Could not find weather information for {}.".format(
                " ".join(line)))
    else:
        loc["lat"] = blob['results'][0]['geometry']['location']['lat']
        loc["long"] = blob['results'][0]['geometry']['location']['lng']
        loc["addr"] = blob['results'][0]['formatted_address']
        return loc
Пример #16
0
def spotify(m):
    """Retrieve information about a Spotify URI."""
    spotify_uris = re.findall(SPOTIFY_URI_REGEX, m.body)
    for spotify_uri in spotify_uris:
        try:
            type, id = _parse_spotify_uri(spotify_uri)
        except ValueError:
            m.bot.logger.error("Invalid Spotify URI: " + spotify_uri)
        else:
            req = get_url(m, ENDPOINT.format(type, id))
            if req:
                blob = json.loads(req)
                if type == "track" or type == "album":
                    m.bot.private_message(m.location, '"{0}" by {1}'
                                          .format(blob["name"], blob["artists"][0]["name"]))
                else:
                    m.bot.private_message(m.location, blob["name"])
Пример #17
0
def bash_rand(m):
    """Get a random quote from bash.org"""
    resp = get_url(m, "http://bash.org?random1")
    soup = BeautifulSoup(resp, features="html.parser")
    raw = soup.find(class_="qt")
    if raw:
        meta = soup.find(class_="quote")
        while True:
            if not raw:
                bash_rand(m)
                return
            lines = raw.get_text().splitlines()
            if len(lines) <= 5:
                break
            raw = raw.find_next(class_="qt")
            meta = soup.find_next(class_="quote")
        format_quote(m, lines, meta)
    else:
        m.bot.private_message(m.location, "Could not find bash quote.")
Пример #18
0
def bash_rand(m):
    """Get a random quote from bash.org"""
    resp = get_url(m, "http://bash.org?random1")
    soup = BeautifulSoup(resp)
    raw = soup.find(class_="qt")
    if raw:
        meta = soup.find(class_="quote")
        while True:
            if not raw:
                bash_rand(m)
                return
            lines = raw.get_text().splitlines()
            if len(lines) <= 5:
                break
            raw = raw.find_next(class_="qt")
            meta = soup.find_next(class_="quote")
        format_quote(m, lines, meta)
    else:
        m.bot.private_message(m.location, "Could not find bash quote.")
Пример #19
0
def youtube(m, url):
    """Retrieve information about the YouTube video."""
    api_key = m.bot.get_config('youtube')
    if api_key:
        match = re.search(r'youtu(?:be.com/watch\?v=|\.be/)(.+?)(?:\?|&|\Z)', url)
        if match:
            video_id = match.group(1)
            m.bot.logger.info("Retrieving information from the YouTube API for {}.". format(url))
            api_url = "https://www.googleapis.com/youtube/v3/videos?id={id}" \
                      "&key={key}&part=snippet,contentDetails,statistics"
            resp = get_url(m, api_url.format(id = video_id, key = api_key))
            if resp:
                # Load JSON
                blob = json.loads(resp)["items"][0]

                # Parse uploaded time
                raw_time = datetime.strptime(blob["snippet"]["publishedAt"],
                                             "%Y-%m-%dT%H:%M:%S.%fZ")
                pretty_time = raw_time.strftime("%b %d, %Y")

                # Parse video duration
                dur_match = re.match(r'PT(?:(\d+)H)?(?:(\d+)M)?(\d+)S',
                                     blob["contentDetails"]["duration"])
                hr, min, sec = dur_match.groups()
                if hr:
                    pretty_dur = ":".join([hr, "00" if min is None else min.zfill(2), sec.zfill(2)])
                else:
                    pretty_dur = ":".join(["00" if min is None else min.zfill(2), sec.zfill(2)])

                # Format and return message
                return "\"{title}\" ({duration}). Uploaded {date}. {views} views. {likes} likes, " \
                       "{dislikes} dislikes.".format(
                    title = blob["snippet"]["title"],
                    duration = pretty_dur,
                    date = pretty_time,
                    views = blob["statistics"]["viewCount"],
                    likes = blob["statistics"]["likeCount"],
                    dislikes = blob["statistics"]["dislikeCount"]
                )
    # If there's no API key stored, or the URL is poorly formatted, fall back to generic linking
    return generic(m, url)