Beispiel #1
0
async def check_reminders(bot, async_call, db):
    current_time = datetime.now()

    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
                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 = current_time - remind_time
            if delta > timedelta(minutes=30):
                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))

            await delete_reminder(async_call, db, network, remind_time, user)
            await load_cache(async_call, db)
Beispiel #2
0
def check_reminders(bot, async_call, db):
    current_time = datetime.now()

    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_call, db, network, remind_time, user)
                yield from load_cache(async_call, 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_call, db, network, remind_time, user)
            yield from load_cache(async_call, db)
Beispiel #3
0
def check_reminders(bot, async_call, db):
    current_time = datetime.now()

    for reminder in reminder_cache:
        network, user, added_time, added_chan, message, remind_time = reminder
        if remind_time <= current_time:
            if network not in bot.connections:
                # connection is invalid
                yield from add_reminder(async_call, db, network, user, added_chan, message, remind_time, added_time)
                yield from load_cache(async_call, db)
                continue

            conn = bot.connections[network]

            if not conn.ready:
                return

            remind_text = time_since(added_time, count=2)
            alert = "{}, you have a reminder from $(b){}$(b) 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){}$(b) late," \
                       " it seems I was unable to deliver it on time)".format(late_time)
                conn.message(user, late)

            yield from delete_reminder(async_call, db, network, remind_time, user)
            yield from load_cache(async_call, db)
Beispiel #4
0
def test_timesince():
    then = datetime(2010, 4, 12, 12, 30, 0)
    then_timestamp = 1271075400.0
    then_future = datetime(2012, 4, 12, 12, 30, 0)
    now = datetime(2010, 5, 15, 1, 50, 0)
    now_timestamp = 1273888200.0
    # timestamp
    assert time_since(then_timestamp, now_timestamp) == "1 month and 2 days"
    # basic
    assert time_since(then, now) == "1 month and 2 days"
    # count
    assert time_since(then, now, count=3) == "1 month, 2 days and 13 hours"
    # future
    assert time_since(then_future, now) == "0 minutes"
Beispiel #5
0
def test_timesince():
    then = datetime(2010, 4, 12, 12, 30, 0)
    then_timestamp = 1271075400.0
    then_future = datetime(2012, 4, 12, 12, 30, 0)
    now = datetime(2010, 5, 15, 1, 50, 0)
    now_timestamp = 1273888200.0
    # timestamp
    assert time_since(then_timestamp, now_timestamp) == "1 month and 2 days"
    # basic
    assert time_since(then, now) == "1 month and 2 days"
    # count
    assert time_since(then, now, count=3) == "1 month, 2 days and 13 hours"
    # future
    assert time_since(then_future, now) == "0 minutes"
Beispiel #6
0
def tellinput(event, conn, db, nick, notice):
    """
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    :type db: sqlalchemy.orm.Session
    """
    if 'showtells' in event.content.lower():
        return

    if tell_check(conn.name, nick): 
        tells = get_unread(db, conn.name, nick)
    else:
        return

    if tells:
        user_from, message, time_sent = tells[0]
        reltime = timeformat.time_since(time_sent)

        if reltime == 0:
            reltime_formatted = "just a moment"
        else:
            reltime_formatted = reltime

        reply = "{} sent you a message {} ago: {}".format(user_from, reltime_formatted, message)
        if len(tells) > 1:
            reply += " (+{} more, {}showtells to view)".format(len(tells) - 1, conn.config["command_prefix"])

        read_tell(db, conn.name, nick, message)
        notice(reply)
Beispiel #7
0
def seen(text, nick, chan, db, event, is_nick_valid):
    """<nick> <channel> - tells when a nickname was last in active in one of my channels

    :type db: sqlalchemy.orm.Session
    :type event: cloudbot.event.Event
    """

    if event.conn.nick.lower() == text.lower():
        return "You need to get your eyes checked."

    if text.lower() == nick.lower():
        return "Have you looked in a mirror lately?"

    if not is_nick_valid(text):
        return "I can't look up that name, its impossible to use!"

    last_seen = db.execute(
        select([table.c.name, table.c.time, table.c.quote]).where(
            and_(table.c.name == text.lower(),
                 table.c.chan == chan))).fetchone()

    if last_seen:
        reltime = timeformat.time_since(last_seen[1])
        if last_seen[2][0:1] == "\x01":
            return '{} was last seen {} ago: * {} {}'.format(
                text, reltime, text, last_seen[2][8:-1])

        return '{} was last seen {} ago saying: {}'.format(
            text, reltime, last_seen[2])

    return "I've never seen {} talking in this channel.".format(text)
Beispiel #8
0
def format_output(item, show_url=False):
    """ takes a voat post and returns a formatted string """
    if not item["Title"]:
        item["Title"] = formatting.truncate(item["Linkdescription"], 70)
    else:
        item["Title"] = formatting.truncate(item["Title"], 70)
    item["link"] = voat_fill_url.format(item["Subverse"], item["Id"])

    raw_time = isodate.parse_date(item["Date"])
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize(item["CommentCount"], "comment")
    item["points"] = formatting.pluralize(item["Likes"], "point")

    if item["Type"] == 2:
        item["warning"] = " \x02Link\x02"
    else:
        item["warning"] = ""

    if show_url:
        return (
            "\x02{Title} : {Subverse}\x02 - {comments}, {points}"
            " - \x02{Name}\x02 {timesince} ago - {link}{warning}".format(**item)
        )
    else:
        return (
            "\x02{Title} : {Subverse}\x02 - {comments}, {points}"
            " - \x02{Name}\x02, {timesince} ago{warning}".format(**item)
        )
Beispiel #9
0
def twitter_url(match):
    # Find the tweet ID from the URL
    tweet_id = match.group(1)

    # Get the tweet using the tweepy API
    if tw_api is None:
        return

    try:
        tweet = tw_api.get_status(tweet_id)
        user = tweet.user
    except tweepy.error.TweepError:
        return

    # Format the return the text of the tweet
    text = " ".join(tweet.text.split())

    if user.verified:
        prefix = "\u2713"
    else:
        prefix = ""

    time = timeformat.time_since(tweet.created_at, datetime.utcnow())

    return "{}@\x02{}\x02 ({}): {} ({} ago)".format(prefix, user.screen_name, user.name, text, time)
Beispiel #10
0
def tellinput(event, conn, db, nick, notice):
    """
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    :type db: sqlalchemy.orm.Session
    """
    if 'showtells' in event.content.lower():
        return

    if tell_check(conn.name, nick):
        tells = get_unread(db, conn.name, nick)
    else:
        return

    if tells:
        user_from, message, time_sent = tells[0]
        reltime = timeformat.time_since(time_sent)

        if reltime == 0:
            reltime_formatted = "just a moment"
        else:
            reltime_formatted = reltime

        reply = "{} sent you a message {} ago: {}".format(
            user_from, reltime_formatted, message)
        if len(tells) > 1:
            reply += " (+{} more, {}showtells to view)".format(
                len(tells) - 1, conn.config["command_prefix"])

        read_tell(db, conn.name, nick, message)
        notice(reply)
Beispiel #11
0
def seen(text, nick, chan, db, event, conn):
    """<nick> <channel> - tells when a nickname was last in active in one of my channels
    :type db: sqlalchemy.orm.Session
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    """

    if event.conn.nick.lower() == text.lower():
        return "You need to get your eyes checked."

    if text.lower() == nick.lower():
        return "Have you looked in a mirror lately?"

    if not re.match("^[A-Za-z0-9_|\^\*\`.\-\]\[\{\}\\\\]*$", text.lower()):
        return "I can't look up that name, its impossible to use!"

    db_init(db, conn.name)

    if '_' in text:
        text = text.replace("_", "/_")

    last_seen = db.execute("select name, time, quote from seen_user where name like :name escape '/' and chan = :chan",
                            {'name': text, 'chan': chan}).fetchone()

    if last_seen:
        reltime = timeformat.time_since(last_seen[1])
        if last_seen[0] != text.lower():  # for glob matching
            text = last_seen[0]
        if last_seen[2][0:1] == "\x01":
            return '{} was last seen {} ago: * {} {}'.format(text, reltime, text, last_seen[2][8:-1])
        else:
            return '{} was last seen {} ago saying: {}'.format(text, reltime, last_seen[2])
    else:
        return "I've never seen {} talking in this channel.".format(text)
Beispiel #12
0
def tell_watch(event, conn, db, chan, nick, ctcp, reply):
    """
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    :type db: sqlalchemy.orm.Session
    """
    if tell_check(conn.name, nick):
        tells = get_unread(db, conn.name, nick, chan)
    else:
        return

    sent = 0
    ratelimit = 5
    for _from, _channel, _message, _sent in tells:
        # format the send time
        reltime = timeformat.time_since(_sent, simple=True, count=1)
        if reltime == 0:
            reltime = "just now"
        else:
            reltime += " ago"

        out = "[{}, {}] {}".format(_from, reltime, _message)
        read_tell(db, conn.name, _channel, nick, _message)

        if sent < ratelimit:
            reply(out)
        else:
            if sent == ratelimit + 1:
                reply(
                    "{} more tells sent privately.".format(len(tells) - sent))
            ctcp(out)
        sent += 1
Beispiel #13
0
def seen(text, nick, chan, db, event, conn):
    """<nick> <channel> - tells when a nickname was last in active in one of my channels
    :type db: sqlalchemy.orm.Session
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    """

    if event.conn.nick.lower() == text.lower():
        return "You need to get your eyes checked."

    if text.lower() == nick.lower():
        return "Have you looked in a mirror lately?"

    if not re.match("^[A-Za-z0-9_|.\-\]\[]*$", text.lower()):
        return "I can't look up that name, its impossible to use!"

    db_init(db, conn.name)

    last_seen = db.execute("select name, time, quote from seen_user where name like :name and chan = :chan",
                           {'name': text, 'chan': chan}).fetchone()

    if last_seen:
        reltime = timeformat.time_since(last_seen[1])
        if last_seen[0] != text.lower():  # for glob matching
            text = last_seen[0]
        if last_seen[2][0:1] == "\x01":
            return '{} was last seen {} ago: * {} {}'.format(text, reltime, text, last_seen[2][8:-1])
        else:
            return '{} was last seen {} ago saying: {}'.format(text, reltime, last_seen[2])
    else:
        return "I've never seen {} talking in this channel.".format(text)
Beispiel #14
0
def format_output(item, show_url=False):
    """ takes a reddit post and returns a formatted string """
    item["title"] = formatting.truncate(item["title"], 70)
    item["link"] = short_url.format(item["id"])

    raw_time = datetime.fromtimestamp(int(item["created_utc"]))
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize_auto(item["num_comments"],
                                                 'comment')
    item["points"] = formatting.pluralize_auto(item["score"], 'point')

    if item["over_18"]:
        item["warning"] = colors.parse(" $(b, red)NSFW$(clear)")
    else:
        item["warning"] = ""

    if show_url:
        item["url"] = " - " + item["link"]
    else:
        item["url"] = ""

    return colors.parse(
        "$(b){title} : {subreddit}$(b) - {comments}, {points}"
        " - $(b){author}$(b) {timesince} ago{url}{warning}").format(**item)
Beispiel #15
0
def pre(text):
    """pre <query> -- searches scene releases using pre.corrupt.org"""

    try:
        headers = {'Accept-Language': 'en-US'}
        request = requests.get("https://pre.corrupt-net.org/search.php", params={"search": text}, headers=headers)
        request.raise_for_status()
    except requests.exceptions.HTTPError as e:
        return 'Unable to fetch results: {}'.format(e)
    split = request.text.partition('</tr><tr>')

    results = re.search("<tr><td id\=\"rlstype\".*>(.*)</td><td.*>&nbsp;&nbsp;(.*)<span id\=\"rlsgroup\"><font color\='#C0C0C0'>(.*)</font>.*>(\d*F).*>([\d\.]*M).*&nbsp;&nbsp;(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})</td>", split[0], flags=re.IGNORECASE)
    if results is None:
        return "No results found."

    date = results.group(6)
    section = results.group(1)
    name = results.group(2) + results.group(3)
    size = results.group(5)
    files = results.group(4)

    # parse date/time
    date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
    date_string = date.strftime("%d %b %Y")
    since = timeformat.time_since(date)

    return '{} - {} - {} - {} - {} ({} ago)'.format(section, name, size, files, date_string, since)
Beispiel #16
0
def pre(text, reply):
    """<query> - searches scene releases using orlydb.com"""

    try:
        request = requests.get("https://pre.corrupt-net.org/search.php", params={"search": text}, headers=HEADERS, timeout=30.0)
        request.raise_for_status()
    except requests.exceptions.HTTPError as e:
        reply('Unable to fetch results: {}'.format(e))
        raise

    request.close()
    html = BeautifulSoup(request.text, "lxml")

    cols = html.find_all("td", limit=5)
    if len(cols) < 2 or cols[0].text.strip().startswith("Nothing found"):
        return "No results"

    #section = cols[0].text.strip()
    name = cols[1].text.strip()
    files = cols[2].text.strip().replace("F", " files")
    size = cols[3].text.strip() + "iB"
    date = cols[4].text.strip() + "UTC"

    # parse date/time
    date = datetime.strptime(date, "%Y-%m-%d %H:%M:%S%Z")
    since = timeformat.time_since(date, datetime.utcnow(), simple=True)

    return '{} [div] {} [div] {} [div] {} ({} ago)'.format(name, size, files, date, since)
Beispiel #17
0
def format_output(item, show_url=False):
    """ takes a reddit post and returns a formatted string """
    item["title"] = formatting.truncate(item["title"], 70)
    item["link"] = short_url.format(item["id"])

    raw_time = datetime.fromtimestamp(int(item["created_utc"]))
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize(item["num_comments"], "comment")
    item["points"] = formatting.pluralize(item["score"], "point")

    if item["over_18"]:
        item["warning"] = " \x02NSFW\x02"
    else:
        item["warning"] = ""

    if show_url:
        return (
            "\x02{title} : {subreddit}\x02 - {comments}, {points}"
            " - \x02{author}\x02 {timesince} ago - {link}{warning}".format(**item)
        )
    else:
        return (
            "\x02{title} : {subreddit}\x02 - {comments}, {points}"
            " - \x02{author}\x02, {timesince} ago{warning}".format(**item)
        )
Beispiel #18
0
def tell_watch(event, conn, db, chan, nick, ctcp, reply):
    """
    :type event: cloudbot.event.Event
    :type conn: cloudbot.client.Client
    :type db: sqlalchemy.orm.Session
    """
    if tell_check(conn.name, nick):
        tells = get_unread(db, conn.name, nick, chan)
    else:
        return

    sent = 0
    ratelimit = 5
    for _from, _channel, _message, _sent in tells:
        # format the send time
        reltime = timeformat.time_since(_sent, simple=True, count=1)
        if reltime == 0:
            reltime = "just now"
        else:
            reltime += " ago"

        out = "[{}, {}] {}".format(_from, reltime, _message)
        read_tell(db, conn.name, _channel, nick, _message)

        if sent < ratelimit:
            reply(out)
        else:
            if sent == ratelimit + 1:
                reply("{} more tells sent privately.".format(len(tells) - sent))
            ctcp(out)
        sent += 1
Beispiel #19
0
def pre(text):
    """pre <query> -- searches scene releases using pre.corrupt.org"""

    try:
        headers = {'Accept-Language': 'en-US'}
        request = requests.get("https://pre.corrupt-net.org/search.php",
                               params={"search": text},
                               headers=headers)
        request.raise_for_status()
    except requests.exceptions.HTTPError as e:
        return 'Unable to fetch results: {}'.format(e)
    split = request.text.partition('</tr><tr>')

    results = re.search(
        "<tr><td id\=\"rlstype\".*>(.*)</td><td.*>&nbsp;&nbsp;(.*)<span id\=\"rlsgroup\"><font color\='#C0C0C0'>(.*)</font>.*>(\d*F).*>([\d\.]*M).*&nbsp;&nbsp;(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})</td>",
        split[0],
        flags=re.IGNORECASE)
    if results is None:
        return "No results found."

    date = results.group(6)
    section = results.group(1)
    name = results.group(2) + results.group(3)
    size = results.group(5)
    files = results.group(4)

    # parse date/time
    date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
    date_string = date.strftime("%d %b %Y")
    since = timeformat.time_since(date)

    return '{} - {} - {} - {} - {} ({} ago)'.format(section, name, size, files,
                                                    date_string, since)
Beispiel #20
0
def pre(text):
    """pre <query> -- searches scene releases using orlydb.com"""

    try:
        request = requests.get("http://orlydb.com/", params={"q": text})
        request.raise_for_status()
    except requests.exceptions.HTTPError as e:
        return 'Unable to fetch results: {}'.format(e)

    h = html.fromstring(request.text)

    results = h.xpath("//div[@id='releases']/div/span[@class='release']/..")

    if not results:
        return "No results found."

    result = results[0]

    date = result.xpath("span[@class='timestamp']/text()")[0]
    section = result.xpath("span[@class='section']//text()")[0]
    name = result.xpath("span[@class='release']/text()")[0]

    # parse date/time
    date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
    date_string = date.strftime("%d %b %Y")
    since = timeformat.time_since(date)

    size = result.xpath("span[@class='inforight']//text()")
    if size:
        size = ' - ' + size[0].split()[0]
    else:
        size = ''

    return '{} - {}{} - {} ({} ago)'.format(section, name, size, date_string, since)
Beispiel #21
0
def format_output(item, show_url=False):
    """ takes a voat post and returns a formatted string """
    if not item["Title"]:
        item["Title"] = formatting.truncate(item["Linkdescription"], 70)
    else:
        item["Title"] = formatting.truncate(item["Title"], 70)
    item["link"] = voat_fill_url.format(item["Subverse"], item["Id"])

    raw_time = isodate.parse_date(item['Date'])
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize(item["CommentCount"], 'comment')
    item["points"] = formatting.pluralize(item["Likes"], 'point')

    if item["Type"] == 2:
        item["warning"] = " \x02Link\x02"
    else:
        item["warning"] = ""

    if show_url:
        return "\x02{Title} : {Subverse}\x02 - {comments}, {points}" \
               " - \x02{Name}\x02 {timesince} ago - {link}{warning}".format(**item)
    else:
        return "\x02{Title} : {Subverse}\x02 - {comments}, {points}" \
               " - \x02{Name}\x02, {timesince} ago{warning}".format(**item)
Beispiel #22
0
def pre(text):
    """pre <query> -- searches scene releases using orlydb.com"""

    try:
        request = requests.get("http://orlydb.com/", params={"q": text})
        request.raise_for_status()
    except requests.exceptions.HTTPError as e:
        return 'Unable to fetch results: {}'.format(e)

    h = html.fromstring(request.text)

    results = h.xpath("//div[@id='releases']/div/span[@class='release']/..")

    if not results:
        return "No results found."

    result = results[0]

    date = result.xpath("span[@class='timestamp']/text()")[0]
    section = result.xpath("span[@class='section']//text()")[0]
    name = result.xpath("span[@class='release']/text()")[0]

    # parse date/time
    date = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S")
    date_string = date.strftime("%d %b %Y")
    since = timeformat.time_since(date)

    size = result.xpath("span[@class='inforight']//text()")
    if size:
        size = ' - ' + size[0].split()[0]
    else:
        size = ''

    return '{} - {}{} - {} ({} ago)'.format(section, name, size, date_string, since)
Beispiel #23
0
def format_tweet(tweet, user):
    text = " ".join(tweet.text.split())

    if user.verified:
        prefix = "\u2713"
    else:
        prefix = ""

    time = timeformat.time_since(tweet.created_at, datetime.utcnow())

    return "{}@\x02{}\x02 ({}): {} ({} ago)".format(prefix, user.screen_name,
                                                    user.name,
                                                    html.unescape(text), time)
Beispiel #24
0
def showtells(nick, notice, db, conn):
    """- View all pending tell messages (sent in a notice)."""

    tells = get_unread(db, conn.name, nick)

    if not tells:
        notice("You have no pending messages.")
        return

    for tell in tells:
        sender, message, time_sent = tell
        past = timeformat.time_since(time_sent)
        notice("{} sent you a message {} ago: {}".format(sender, past, message))

    read_all_tells(db, conn.name, nick)
Beispiel #25
0
def showtells(nick, notice, db, conn):
    """showtells -- View all pending tell messages (sent in a notice)."""

    tells = get_unread(db, conn.name, nick)

    if not tells:
        notice("You have no pending messages.")
        return

    for tell in tells:
        sender, message, time_sent = tell
        past = timeformat.time_since(time_sent)
        notice("{} sent you a message {} ago: {}".format(sender, past, message))

    read_all_tells(db, conn.name, nick)
Beispiel #26
0
def format_tweet(tweet):
    if isinstance(tweet, str):
        return tweet

    user = tweet.user

    # Format the return the text of the tweet
    text = html.unescape(" ".join(tweet.full_text.split()))

    # Get expanded URLs
    urls = {}
    if tweet.entities.get("urls"):
        for item in tweet.entities["urls"]:
            urls[item["url"]] = item["expanded_url"]

    if "extended_entities" in tweet._json:
        high_bitrate = -1  # mp4 of gif appears to be marked 0
        for item in tweet._json["extended_entities"]["media"]:
            # check for video
            if "video_info" in item:
                for vid in item["video_info"]["variants"]:
                    if vid["content_type"] == "video/mp4" and vid["bitrate"] > high_bitrate:
                        high_bitrate = vid["bitrate"]
                        urls[item["url"]] = vid["url"]
                        continue
            # Did we already set it?
            if not item["url"] in urls:
                urls[item["url"]] = item["media_url_https"]

    while True:
        m = TCO_RE.search(text)
        if not m:
            break
        if m.group() in urls:
            # Expand the URL
            text = TCO_RE.sub(urls[m.group()], text, count=1)
        else:
            # Ignore and move on
            TCO_RE.compile("(?!{}){}".format(m.group(), TCO_RE.pattern))

    verified = "\u2713" if user.verified else ""

    time = timeformat.time_since(tweet.created_at, datetime.utcnow(), simple=True)

    return "{} ({}@{}) [div] {} ago [div] {}".format(user.name, verified, user.screen_name, time, text.strip())
Beispiel #27
0
def format_output(item, show_url=False):
    """ takes a reddit post and returns a formatted string """
    item["title"] = html.unescape(formatting.truncate(item["title"], 200))
    item["link"] = short_url.format(item["id"])

    # Fix some URLs
    if not item["is_self"] and item["url"]:
        # Use .gifv links for imgur
        if "imgur.com/" in item["url"] and item["url"].endswith(".gif"):
            item["url"] += "v"
        # Fix i.reddituploads.com crap ("&amp;" in URL)
        if "i.reddituploads.com/" in item["url"]:
            # Get i.redditmedia.com preview (first one is full size)
            item["url"] = item["preview"]["images"][0]["source"]["url"]
        # Unescape since reddit gives links for HTML
        item["url"] = html.unescape(item["url"])

    raw_time = datetime.fromtimestamp(int(item["created_utc"]))
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize_auto(item["num_comments"], 'comment').replace(",", "")
    item["points"] = formatting.pluralize_auto(item["score"], 'point').replace(",", "")

    out = []

    if show_url and item["link"]:
        out.append("[h3]{link}[/h3]")

    out.append("{title}")

    if not item["is_self"]:
        out.append("{url}")
    if item["over_18"]:
        out.append("$(red)NSFW$(c)")

    out.extend(["/r/{subreddit}", "/u/{author}", "{timesince} ago", "{points}", "{comments}"])

    if item["gilded"]:
        item["gilded"] = formatting.pluralize_auto(item["gilded"], 'gild')
        out.append("$(yellow){gilded}$(c)")

    return "[h1]Reddit:[/h1] " + " [div] ".join(out).format(**item)
Beispiel #28
0
def format_output(item, show_url=False):
    """ takes a reddit post and returns a formatted string """
    item["title"] = formatting.truncate(item["title"], 70)
    item["link"] = short_url.format(item["id"])

    raw_time = datetime.fromtimestamp(int(item["created_utc"]))
    item["timesince"] = timeformat.time_since(raw_time, count=1, simple=True)

    item["comments"] = formatting.pluralize(item["num_comments"], 'comment')
    item["points"] = formatting.pluralize(item["score"], 'point')

    if item["over_18"]:
        item["warning"] = " \x02NSFW\x02"
    else:
        item["warning"] = ""

    if show_url:
        return "\x02{title} : {subreddit}\x02 - {comments}, {points}" \
               " - \x02{author}\x02 {timesince} ago - {link}{warning}".format(**item)
    else:
        return "\x02{title} : {subreddit}\x02 - {comments}, {points}" \
               " - \x02{author}\x02, {timesince} ago{warning}".format(**item)
Beispiel #29
0
def lastfm(event, db, text, nick, bot):
    """[user] [dontsave] - displays the now playing (or last played) track of LastFM user [user]"""
    api_key = bot.config.get("api_keys", {}).get("lastfm")
    if not api_key:
        return "error: no api key set"

    # check if the user asked us not to save his details
    dontsave = text.endswith(" dontsave")
    if dontsave:
        user = text[:-9].strip().lower()
    else:
        user = text

    if not user:
        user = get_account(nick)
        if not user:
            event.notice_doc()
            return

    response, err = api_request('user.getrecenttracks',
                                api_key,
                                user=user,
                                limit=1)
    if err:
        return err

    if "track" not in response["recenttracks"] or len(
            response["recenttracks"]["track"]) == 0:
        return 'No recent tracks for user "{}" found.'.format(
            format_user(user))

    tracks = response["recenttracks"]["track"]

    if isinstance(tracks, list):
        track = tracks[0]

        if "@attr" in track and "nowplaying" in track["@attr"] and track[
                "@attr"]["nowplaying"] == "true":
            # if the user is listening to something, the first track (a dict) of the
            # tracks list will contain an item with the "@attr" key.
            # this item will will contain another item with the "nowplaying" key
            # which value will be "true"
            status = 'is listening to'
            ending = '.'
        else:
            # otherwise, the user is not listening to anything right now
            status = 'last listened to'
            # lets see how long ago they listened to it
            time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
            time_since = timeformat.time_since(time_listened)
            ending = ' ({} ago)'.format(time_since)
    else:
        return "error: could not parse track listing"

    title = track["name"]
    album = track["album"]["#text"]
    artist = track["artist"]["#text"]
    url = web.try_shorten(track["url"])

    tags = gettracktags(api_key, artist, title)
    if tags == "no tags":
        tags = getartisttags(api_key, artist)

    playcount = getusertrackplaycount(api_key, artist, title, user)

    out = '{} {} "{}"'.format(format_user(user), status, title)
    if artist:
        out += " by \x02{}\x02".format(artist)
    if album:
        out += " from the album \x02{}\x02".format(album)
    if playcount:
        out += " [playcount: {}]".format(playcount)
    else:
        out += " [playcount: 0]"
    if url:
        out += " {}".format(url)

    out += " ({})".format(tags)

    # append ending based on what type it was
    out += ending

    if text and not dontsave:
        if get_account(nick):
            db.execute(table.update().values(acc=user).where(
                table.c.nick == nick.lower()))
            db.commit()
        else:
            db.execute(table.insert().values(nick=nick.lower(), acc=user))
            db.commit()

        load_cache(db)
    return out
Beispiel #30
0
def librefm(text, nick, db, bot, notice):
    """[user] [dontsave] - displays the now playing (or last played) track of libre.fm user [user]"""

    # check if the user asked us not to save his details
    dontsave = text.endswith(" dontsave")
    if dontsave:
        user = text[:-9].strip().lower()
    else:
        user = text

    if not user:
        user = get_account(nick)
        if not user:
            notice(librefm.__doc__)
            return

    params = {'method': 'user.getrecenttracks',
                        'user': user, 'limit': 1}
    request = requests.get(api_url, params=params)

    if request.status_code != requests.codes.ok:
        return "Failed to fetch info ({})".format(request.status_code)

    response = request.json()

    if 'error' in response:
        #return "libre.fm Error: {}.".format(response["message"])
        return "libre.fm Error: {} Code: {}.".format(response["error"]["#text"], response["error"]["code"])

    if "track" not in response["recenttracks"] or len(response["recenttracks"]["track"]) == 0:
        return 'No recent tracks for user "{}" found.'.format(user)

    tracks = response["recenttracks"]["track"]

    if type(tracks) == list:
        track = tracks[0]

        if "@attr" in track and "nowplaying" in track["@attr"] and track["@attr"]["nowplaying"] == "true":
            # if the user is listening to something, the first track (a dict) of the
            # tracks list will contain an item with the "@attr" key.
            # this item will will contain another item with the "nowplaying" key
            # which value will be "true"
            status = 'is listening to'
            ending = '.'

    elif type(tracks) == dict:
        track = tracks
        # otherwise, the user is not listening to anything right now
        status = 'last listened to'
        # lets see how long ago they listened to it
        time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
        time_since = timeformat.time_since(time_listened)
        ending = ' ({} ago)'.format(time_since)

    else:
        return "error: could not parse track listing"

    title = track["name"]
    album = track["album"]["#text"]
    artist = track["artist"]["#text"]
    try:
        url = web.try_shorten(track["url"])
    except:
        url = track["url"]
        pass
    tags = getartisttags(artist, bot)

    out = '{} {} "{}"'.format(user, status, title)
    if artist:
        out += " by \x02{}\x0f".format(artist)
    if album:
        out += " from the album \x02{}\x0f".format(album)
    if url:
        out += " {}".format(url)

    out += " ({})".format(tags)

    # append ending based on what type it was
    out += ending

    if text and not dontsave:
        db.execute("insert or replace into librefm(nick, acc) values (:nick, :account)",
                   {'nick': nick.lower(), 'account': user})
        db.commit()
        load_cache(db)
    return out
Beispiel #31
0
    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)
Beispiel #32
0
def lastfm(text, nick, db, bot, notice):
    """[user] [dontsave] - displays the now playing (or last played) track of LastFM user [user]"""
    api_key = bot.config.get("api_keys", {}).get("lastfm")
    if not api_key:
        return "No last.fm API key set."

    # check if the user asked us not to save his details
    dontsave = text.endswith(" dontsave")
    if dontsave:
        user = text[:-9].strip().lower()
    else:
        user = text

    if not user:
        user = get_account(nick)
        if not user:
            notice(lastfm.__doc__)
            return

    params = {'method': 'user.getrecenttracks',
              'api_key': api_key, 'user': user, 'limit': 1}
    request = requests.get(api_url, params=params)

    if request.status_code != requests.codes.ok:
        return "Failed to fetch info ({})".format(request.status_code)

    response = request.json()

    if 'error' in response:
        return "Last.FM Error: {}.".format(response["message"])

    if "track" not in response["recenttracks"] or len(response["recenttracks"]["track"]) == 0:
        return 'No recent tracks for user "{}" found.'.format(user)

    tracks = response["recenttracks"]["track"]

    if type(tracks) == list:
        # if the user is listening to something, the tracks entry is a list
        # the first item is the current track
        track = tracks[0]
        status = 'is listening to'
        ending = '.'
    elif type(tracks) == dict:
        # otherwise, they aren't listening to anything right now, and
        # the tracks entry is a dict representing the most recent track
        track = tracks
        status = 'last listened to'
        # lets see how long ago they listened to it
        time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
        time_since = timeformat.time_since(time_listened)
        ending = ' ({} ago)'.format(time_since)

    else:
        return "error: could not parse track listing"

    title = track["name"]
    album = track["album"]["#text"]
    artist = track["artist"]["#text"]
    url = web.try_shorten(track["url"])

    out = '{} {} "{}"'.format(user, status, title)
    if artist:
        out += " by \x02{}\x0f".format(artist)
    if album:
        out += " from the album \x02{}\x0f".format(album)
    if url:
        out += " {}".format(url)

    # append ending based on what type it was
    out += ending

    if text and not dontsave:
        db.execute("insert or replace into lastfm(nick, acc) values (:nick, :account)",
                   {'nick': nick.lower(), 'account': user})
        db.commit()
        load_cache(db)
    return out
Beispiel #33
0
    for reminder in reminder_cache:
        network, remind_time, added_chan, added_time, user, message = reminder
        if remind_time <= current_time:
            if network not in bot.connections:
                # connection is invalid: drop reminder
                yield from delete_reminder(async, db, network, remind_time,
                                           user)
                sent_something = True
                continue

            conn = bot.connections[network]
            if not conn.ready:
                return

            reltime = time_since(added_time, simple=True, count=1)
            conn.message(
                added_chan,
                '{}: [reminder from {} ago] {}'.format(user, reltime, message))

            delta = (remind_time - added_time).seconds
            if delta > (30 * 60):
                late_time = time_since(remind_time, count=2)
                late = "Sorry for delivering that message $(b){}$(clear) late" \
                    .format(late_time)
                conn.message(user, colors.parse(late))

            yield from delete_reminder(async, db, network, remind_time, user)
            sent_something = True

    if sent_something:
Beispiel #34
0
    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)
Beispiel #35
0
def twitter(text):
    """twitter <user> [n] -- Gets last/[n]th tweet from <user>"""

    if tw_api is None:
        return "This command requires a twitter API key."

    if re.match(r'^\d+$', text):
        # user is getting a tweet by id

        try:
            # get tweet by id
            tweet = tw_api.get_status(text)
        except tweepy.error.TweepError as e:
            if "404" in e.reason:
                return "Could not find tweet."
            else:
                return "Error: {}".format(e.reason)

        user = tweet.user

    elif re.match(r'^\w{1,15}$', text) or re.match(r'^\w{1,15}\s+\d+$', text):
        # user is getting a tweet by name

        if text.find(' ') == -1:
            username = text
            tweet_number = 0
        else:
            username, tweet_number = text.split()
            tweet_number = int(tweet_number) - 1

        if tweet_number > 200:
            return "This command can only find the last \x02200\x02 tweets."

        try:
            # try to get user by username
            user = tw_api.get_user(username)
        except tweepy.error.TweepError as e:
            if "404" in e.reason:
                return "Could not find user."
            else:
                return "Error: {}".format(e.reason)

        # get the users tweets
        user_timeline = tw_api.user_timeline(id=user.id, count=tweet_number + 1)

        # if the timeline is empty, return an error
        if not user_timeline:
            return "The user \x02{}\x02 has no tweets.".format(user.screen_name)

        # grab the newest tweet from the users timeline
        try:
            tweet = user_timeline[tweet_number]
        except IndexError:
            tweet_count = len(user_timeline)
            return "The user \x02{}\x02 only has \x02{}\x02 tweets.".format(user.screen_name, tweet_count)

    elif re.match(r'^#\w+$', text):
        # user is searching by hashtag
        search = tw_api.search(text)

        if not search:
            return "No tweets found."

        tweet = random.choice(search)
        user = tweet.user
    else:
        # ???
        return "Invalid Input"

    # Format the return the text of the tweet
    text = " ".join(tweet.text.split())

    if user.verified:
        prefix = "\u2713"
    else:
        prefix = ""

    time = timeformat.time_since(tweet.created_at, datetime.utcnow())

    return "{}@\x02{}\x02 ({}): {} ({} ago)".format(prefix, user.screen_name, user.name, text, time)
    current_time = datetime.now()

    for reminder in reminder_cache:
        network, remind_time, added_chan, added_time, user, message = reminder
        if remind_time <= current_time:
            if network not in bot.connections:
                # connection is invalid: drop reminder
                yield from delete_reminder(async, db, network, remind_time, user)
                sent_something = True
                continue

            conn = bot.connections[network]
            if not conn.ready:
                return

            reltime = time_since(added_time, simple=True, count=1)
            conn.message(added_chan, '{}: [reminder from {} ago] {}'
                                        .format(user, reltime, message))

            delta = (remind_time-added_time).seconds
            if delta > (30*60):
                late_time = time_since(remind_time, count=2)
                late = "Sorry for delivering that message $(b){}$(clear) late" \
                    .format(late_time)
                conn.message(user, colors.parse(late))

            yield from delete_reminder(async, db, network, remind_time, user)
            sent_something = True

    if sent_something:
        yield from load_cache(async, db)
Beispiel #37
0
def librefm(text, nick, db, event):
    """[user] [dontsave] - displays the now playing (or last played) track of libre.fm user [user]"""

    # check if the user asked us not to save his details
    dontsave = text.endswith(" dontsave")
    if dontsave:
        user = text[:-9].strip().lower()
    else:
        user = text

    if not user:
        user = get_account(nick)
        if not user:
            event.notice_doc()
            return

    response, err = api_request('user.getrecenttracks', user=user, limit=1)
    if err:
        return err

    if 'error' in response:
        # return "libre.fm Error: {}.".format(response["message"])
        return "libre.fm Error: {} Code: {}.".format(
            response["error"]["#text"], response["error"]["code"])

    if 'track' not in response['recenttracks'] or response['recenttracks'][
            'track']:
        return "No recent tracks for user \"{}\" found.".format(user)

    tracks = response["recenttracks"]["track"]

    if isinstance(tracks, list):
        track = tracks[0]

        if "@attr" in track and "nowplaying" in track["@attr"] and track[
                "@attr"]["nowplaying"] == "true":
            # if the user is listening to something, the first track (a dict) of the
            # tracks list will contain an item with the "@attr" key.
            # this item will will contain another item with the "nowplaying" key
            # which value will be "true"
            status = 'is listening to'
            ending = '.'
        else:
            return

    elif isinstance(tracks, dict):
        track = tracks
        # otherwise, the user is not listening to anything right now
        status = 'last listened to'
        # lets see how long ago they listened to it
        time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
        time_since = timeformat.time_since(time_listened)
        ending = ' ({} ago)'.format(time_since)

    else:
        return "error: could not parse track listing"

    title = track["name"]
    album = track["album"]["#text"]
    artist = track["artist"]["#text"]
    url = web.try_shorten(track["url"])
    tags = getartisttags(artist)

    out = '{} {} "{}"'.format(user, status, title)
    if artist:
        out += " by \x02{}\x0f".format(artist)
    if album:
        out += " from the album \x02{}\x0f".format(album)
    if url:
        out += " {}".format(url)

    out += " ({})".format(tags)

    # append ending based on what type it was
    out += ending

    if text and not dontsave:
        res = db.execute(table.update().values(acc=user).where(
            table.c.nick == nick.lower()))
        if res.rowcount <= 0:
            db.execute(table.insert().values(nick=nick.lower(), acc=user))

        db.commit()
        load_cache(db)
    return out
Beispiel #38
0
def librefm(text, nick, db, bot, notice):
    """[user] [dontsave] - displays the now playing (or last played) track of libre.fm user [user]"""

    # check if the user asked us not to save his details
    dontsave = text.endswith(" dontsave")
    if dontsave:
        user = text[:-9].strip().lower()
    else:
        user = text

    if not user:
        user = get_account(nick)
        if not user:
            notice(librefm.__doc__)
            return

    params = {'method': 'user.getrecenttracks', 'user': user, 'limit': 1}
    request = requests.get(api_url, params=params)

    if request.status_code != requests.codes.ok:
        return "Failed to fetch info ({})".format(request.status_code)

    response = request.json()

    if 'error' in response:
        #return "libre.fm Error: {}.".format(response["message"])
        return "libre.fm Error: {} Code: {}.".format(
            response["error"]["#text"], response["error"]["code"])

    if "track" not in response["recenttracks"] or len(
            response["recenttracks"]["track"]) == 0:
        return 'No recent tracks for user "{}" found.'.format(user)

    tracks = response["recenttracks"]["track"]

    if type(tracks) == list:
        track = tracks[0]

        if "@attr" in track and "nowplaying" in track["@attr"] and track[
                "@attr"]["nowplaying"] == "true":
            # if the user is listening to something, the first track (a dict) of the
            # tracks list will contain an item with the "@attr" key.
            # this item will will contain another item with the "nowplaying" key
            # which value will be "true"
            status = 'is listening to'
            ending = '.'

    elif type(tracks) == dict:
        track = tracks
        # otherwise, the user is not listening to anything right now
        status = 'last listened to'
        # lets see how long ago they listened to it
        time_listened = datetime.fromtimestamp(int(track["date"]["uts"]))
        time_since = timeformat.time_since(time_listened)
        ending = ' ({} ago)'.format(time_since)

    else:
        return "error: could not parse track listing"

    title = track["name"]
    album = track["album"]["#text"]
    artist = track["artist"]["#text"]
    try:
        url = web.try_shorten(track["url"])
    except:
        url = track["url"]
        pass
    tags = getartisttags(artist, bot)

    out = '{} {} "{}"'.format(user, status, title)
    if artist:
        out += " by \x02{}\x0f".format(artist)
    if album:
        out += " from the album \x02{}\x0f".format(album)
    if url:
        out += " {}".format(url)

    out += " ({})".format(tags)

    # append ending based on what type it was
    out += ending

    if text and not dontsave:
        db.execute(
            "insert or replace into librefm(nick, acc) values (:nick, :account)",
            {
                'nick': nick.lower(),
                'account': user
            })
        db.commit()
        load_cache(db)
    return out