コード例 #1
0
ファイル: remind.py プロジェクト: Jakeable/Ralybot
def remind(text, nick, chan, db, conn, notice, async):
    """<1 minute, 30 seconds>: <do task> -- reminds you to <do task> in <1 minute, 30 seconds>"""

    count = len([x for x in reminder_cache if x[0] == conn.name and x[3] == nick.lower()])

    if text == "clear":
        if count == 0:
            return "You have no reminders to delete."

        yield from delete_all(async, db, conn.name, nick)
        yield from load_cache(async, db)
        return "Deleted all ({}) reminders for {}!".format(count, nick)

    # split the input on the first ":"
    parts = text.split(":", 1)

    if len(parts) == 1:
        # user didn't add a message, send them help
        notice(remind.__doc__)
        return

    if count > 10:
        return "Sorry, you already have too many reminders queued (10), you will need to wait or " \
               "clear your reminders to add any more."

    time_string = parts[0].strip()
    message = colors.strip_all(parts[1].strip())

    # get the current time in both DateTime and Unix Epoch
    current_epoch = time.time()
    current_time = datetime.fromtimestamp(current_epoch)

    # parse the time input, return error if invalid
    seconds = time_parse(time_string)
    if not seconds:
        return "Invalid input."

    if seconds > 2764800 or seconds < 60:
        return "Sorry, remind input must be more then a minute, and less then one month."

    # work out the time to remind the user, and check if that time is in the past
    remind_time = datetime.fromtimestamp(current_epoch + seconds)
    if remind_time < current_time:
        return "I can't remind you in the past!"

    # finally, add the reminder and send a confirmation message
    yield from add_reminder(async, db, conn.name, nick, chan, message, remind_time, current_time)
    yield from load_cache(async, db)

    remind_text = format_time(seconds, count=2)
    output = "Alright, I'll remind you \"{}\" in $(b){}$(clear)!".format(message, remind_text)

    return colors.parse(output)
コード例 #2
0
ファイル: bing.py プロジェクト: Jakeable/Ralybot
def bing(text, bot):
    """<query> - returns the first Bing search result for <query>"""
    api_key = bot.config.get("api_keys", {}).get("bing_azure")

    # handle NSFW
    show_nsfw = text.endswith(" nsfw")
    # remove "nsfw" from the input string after checking for it
    if show_nsfw:
        text = text[:-5].strip().lower()

    rating = NSFW_FILTER if show_nsfw else DEFAULT_FILTER

    if not api_key:
        return "Error: No Bing Azure API details."

    # why are these all differing formats and why does format have a $? ask microsoft
    params = {
        "Sources": bingify("web"),
        "Query": bingify(text),
        "Adult": bingify(rating),
        "$format": "json"
    }

    request = requests.get(API_URL, params=params, auth=(api_key, api_key))

    # I'm not even going to pretend to know why results are in ['d']['results'][0]
    j = request.json()['d']['results'][0]

    if not j["Web"]:
        return "No results."

    result = j["Web"][0]

    # not entirely sure this even needs un-escaping, but it wont hurt to leave it in
    title = formatting.truncate(unescape(result["Title"]), 60)
    desc = formatting.truncate(unescape(result["Description"]), 150)
    url = unescape(result["Url"])

    return colors.parse('{} -- $(b){}$(b): "{}"'.format(url, title, desc))
コード例 #3
0
ファイル: factoids.py プロジェクト: Jakeable/Ralybot
        arguments = ""

    if factoid_id in factoid_cache:
        data = factoid_cache[factoid_id]
        # factoid pre-processors
        if data.startswith("<py>"):
            code = data[4:].strip()
            variables = 'input="""{}"""; nick="{}"; chan="{}"; bot_nick="{}";'.format(arguments.replace('"', '\\"'),
                                                                                      event.nick, event.chan,
                                                                                      event.conn.nick)
            result = yield from async(web.pyeval, variables + code)
        else:
            result = data

        # factoid post-processors
        result = colors.parse(result)

        if result.startswith("<act>"):
            result = result[5:].strip()
            action(result)
        elif result.startswith("<url>"):
            url = result[5:].strip()
            response = requests.get(url)
            if response.status_code != requests.codes.ok:
                message("Failed to fetch resource.")
            else:
                message(response.text)
        else:
            message(result)

コード例 #4
0
ファイル: amazon.py プロジェクト: Jakeable/Ralybot
def amazon(text, _parsed=False):
    """<query> -- Searches Amazon for query"""
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, '
                      'like Gecko) Chrome/41.0.2228.0 Safari/537.36',
        'Referer': 'http://www.amazon.com/'
    }
    params = {
        'url': 'search-alias',
        'field-keywords': text.strip()
    }
    if _parsed:
        # input is from a link parser, we need a specific URL
        request = requests.get(SEARCH_URL.format(_parsed), params=params, headers=headers)
    else:
        request = requests.get(SEARCH_URL.format(REGION), params=params, headers=headers)

    soup = BeautifulSoup(request.text)

    results = soup.find('div', {'id': 'atfResults'})
    if not results:
        if not _parsed:
            return "No results found."
        else:
            return

    results = results.find('ul', {'id': 's-results-list-atf'}).find_all('li', {'class': 's-result-item'})
    item = results[0]
    asin = item['data-asin']

    # here we use dirty html scraping to get everything we need
    title = formatting.truncate(item.find('h2', {'class': 's-access-title'}).text, 60)
    tags = []

    # tags!
    if item.find('i', {'class': 'a-icon-prime'}):
        tags.append("$(b)Prime$(b)")

    if item.find('i', {'class': 'sx-bestseller-badge-primary'}):
        tags.append("$(b)Bestseller$(b)")

    if re.search(r"(Kostenlose Lieferung|Livraison gratuite|FREE Shipping|Envío GRATIS"
                 r"|Spedizione gratuita)", item.text, re.I):
        tags.append("$(b)Free Shipping$(b)")

    price = item.find('span', {'class': ['s-price', 'a-color-price']}).text

    # use a whole lot of BS4 and regex to get the ratings
    try:
        pattern = re.compile(r'(product-reviews|#customerReviews)')
        rating = item.find('i', {'class': 'a-icon-star'}).find('span', {'class': 'a-icon-alt'}).text
        rating = re.search(r"([0-9]+(?:(?:\.|,)[0-9])?).*5", rating).group(1).replace(",", ".")
        num_ratings = item.find('a', {'href': pattern}).text.replace(".", ",")
        rating_str = "{}/5 stars ({} ratings)".format(rating, num_ratings)
    except AttributeError:
        rating_str = "No Ratings"

    # generate a short url
    if AFFILIATE_TAG:
        url = "http://www.amazon.com/dp/" + asin + "/?tag=" + AFFILIATE_TAG
    else:
        url = "http://www.amazon.com/dp/" + asin + "/"

    url = web.try_shorten(url)

    tag_str = " - " + ", ".join(tags) if tags else ""

    if not _parsed:
        return colors.parse("$(b){}$(b) ({}) - {}{} - {}".format(title, price, rating_str, tag_str, url))
    else:
        return colors.parse("$(b){}$(b) ({}) - {}{}".format(title, price, rating_str, tag_str))
コード例 #5
0
ファイル: remind.py プロジェクト: Jakeable/Ralybot
    for reminder in reminder_cache:
        network, remind_time, added_time, user, message = reminder
        if remind_time <= current_time:
            if network not in bot.connections:
                # connection is invalid
                yield from add_reminder(async, db, network, remind_time, user)
                yield from load_cache(async, db)
                continue

            conn = bot.connections[network]

            if not conn.ready:
                return

            remind_text = colors.parse(time_since(added_time, count=2))
            alert = colors.parse("{}, you have a reminder from $(b){}$(clear) ago!".format(user, remind_text))

            conn.message(user, alert)
            conn.message(user, '"{}"'.format(message))

            delta = (remind_time-added_time).seconds
            if delta > (30*60):
                late_time = time_since(remind_time, count=2)
                late = "(I'm sorry for delivering this message $(b){}$(clear) late," \
                       " it seems I was unable to deliver it on time)".format(late_time)
                conn.message(user, colors.parse(late))

            yield from delete_reminder(async, db, network, remind_time, user)
            yield from load_cache(async, db)
コード例 #6
0
ファイル: utility.py プロジェクト: Jakeable/Ralybot
def color_parse(text):
    return colors.parse(text)
コード例 #7
0
ファイル: eightball.py プロジェクト: Jakeable/Ralybot
def eightball(action):
    """<question> - asks the all knowing magic electronic eight ball <question>"""
    magic = random.choice(responses)
    message = colors.parse("shakes the magic 8 ball... {}".format(magic))

    action(message)
コード例 #8
0
ファイル: test_colors.py プロジェクト: Jakeable/Ralybot
def test_parse():
    assert parse(test_input) == test_parse_output