Example #1
0
def load_aliased_images(bot, event, *args):
    file_exception = False
    try:
        imageids_filename = 'imageids.json'
        imageids = json.loads(open(imageids_filename, encoding='utf-8').read(), encoding='utf-8')
    except IOError as e:
        if e.errno == errno.ENOENT:
            imageids = {}
        else:
           print('Exception:')
           print(str(e))
           file_exception = True
    # loop through values in image_aliases.json
    aliases = load_json('image_aliases.json')
    for v in aliases.values():
        print('V = ' + str(v))
        for url in v if not isinstance(v, str) else [v]:
            print('URL = ' + url)
            # if url is not in imageids, upload it and store filename,id
            image_id = imageids.get(url)
            if image_id is None:
                print('URL = ' + url)
                filename = UtilBot.download_image(url, 'images')
                image_id = yield from UtilBot.upload_image(bot, filename)
                if not file_exception:
                    imageids[url] = image_id
                    with open(imageids_filename, 'w') as f:
                        json.dump(imageids, f, indent=2, sort_keys=True)
                    os.remove(filename)
Example #2
0
def _karma(bot, event, *args):
    username = '******'.join(args)
    username = username.replace('@', '')
    add = username.count("+")
    sub = username.count("-")
    if add > 6:
        add = 6
    if sub > 6:
        sub = 6
    username = username.replace("+", "")
    username = username.replace("-", "")
    username = username.lower()
    for u in sorted(event.conv.users, key=lambda x: x.full_name.split()[-1]):
        if username not in u.full_name.lower():
            continue
        if u.id_ == event.user.id_:
            bot.send_message(event.conv, "Your Karma changes with actions upon others, not actions upon oneself.")
            return

        new_karma = None
        if add >= 2 and sub == 0:
            new_karma = UtilBot.change_karma(u.id_[0], add - 1)
        elif sub >= 2 and add == 0:
            new_karma = UtilBot.change_karma(u.id_[0], (sub - 1) * -1)
        if new_karma is not None:
            bot.send_message(event.conv, "{}'s karma is now {}".format(u.full_name, new_karma))
            return

    yield from bot._client.settyping(event.conv_id, schemas.TypingStatus.STOPPED)
Example #3
0
def finish(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Finish*
Usage: /finish <lyrics to finish> <optional: * symbol to show guessed song>
Purpose: Finish a lyric!
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        showguess = False
        if args[-1] == '*':
            showguess = True
            args = args[0:-1]
        lyric = ' '.join(args)
        songs = Genius.search_songs(lyric)

        if len(songs) < 1:
            yield from bot.send_message(event.conv, "I couldn't find your lyrics.")
        if songs[0].artist.name == 'James Joyce':
            yield from bot.send_message(event.conv, "Sorry, that author is banned.")
            return
        lyrics = songs[0].raw_lyrics
        anchors = {}

        lyrics = lyrics.split('\n')
        currmin = (0, UtilBot.levenshtein_distance(lyrics[0], lyric)[0])
        for x in range(1, len(lyrics) - 1):
            try:
                currlyric = lyrics[x]
                if not currlyric.isspace():
                    # Returns the distance and whether or not the lyric had to be chopped to compare
                    result = UtilBot.levenshtein_distance(currlyric, lyric)
                else:
                    continue
                distance = abs(result[0])
                lyrics[x] = lyrics[x], result[1]

                if currmin[1] > distance:
                    currmin = (x, distance)
                if currlyric.startswith('[') and currlyric not in anchors:
                    next = UtilBot.find_next_non_blank(lyrics, x)
                    anchors[currlyric] = lyrics[next]
            except Exception:
                pass
        next = UtilBot.find_next_non_blank(lyrics, currmin[0])
        chopped = lyrics[currmin[0]][1]
        found_lyric = lyrics[currmin[0]][0] + " " + lyrics[next][0] if chopped else lyrics[next][0]
        if found_lyric.startswith('['):
            found_lyric = anchors[found_lyric]
        if showguess:
            segments = [hangups.ChatMessageSegment(found_lyric),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                        hangups.ChatMessageSegment(songs[0].name)]
            yield from bot.send_message_segments(event.conv, segments)
        else:
            yield from bot.send_message(event.conv, found_lyric)

        return
Example #4
0
def finish(bot, event, *args):
    if ''.join(args) == '?':
        segments = [hangups.ChatMessageSegment('Finish', is_bold=True),
                    hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment(
                        'Usage: /finish <lyrics to finish> <optional: * symbol to show guessed song>'),
                    hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment('Purpose: Finish a lyric!')]
        bot.send_message_segments(event.conv, segments)
    else:
        showguess = False
        if args[-1] == '*':
            showguess = True
            args = args[0:-1]
        lyric = ' '.join(args)
        songs = Genius.search_songs(lyric)

        if len(songs) < 1:
            bot.send_message(event.conv, "I couldn't find your lyrics.")
        lyrics = songs[0].raw_lyrics
        anchors = {}

        lyrics = lyrics.split('\n')
        currmin = (0, UtilBot.levenshtein_distance(lyrics[0], lyric)[0])
        for x in range(1, len(lyrics) - 1):
            try:
                currlyric = lyrics[x]
                if not currlyric.isspace():
                    # Returns the distance and whether or not the lyric had to be chopped to compare
                    result = UtilBot.levenshtein_distance(currlyric, lyric)
                else:
                    continue
                distance = abs(result[0])
                lyrics[x] = lyrics[x], result[1]

                if currmin[1] > distance:
                    currmin = (x, distance)
                if currlyric.startswith('[') and currlyric not in anchors:
                    next = UtilBot.find_next_non_blank(lyrics, x)
                    anchors[currlyric] = lyrics[next]
            except Exception:
                pass
        next = UtilBot.find_next_non_blank(lyrics, currmin[0])
        chopped = lyrics[currmin[0]][1]
        found_lyric = lyrics[currmin[0]][0] + " " + lyrics[next][0] if chopped else lyrics[next][0]
        if found_lyric.startswith('['):
            found_lyric = anchors[found_lyric]
        if showguess:
            segments = [hangups.ChatMessageSegment(found_lyric),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                        hangups.ChatMessageSegment(songs[0].name)]
            bot.send_message_segments(event.conv, segments)
        else:
            bot.send_message(event.conv, found_lyric)

        return
Example #5
0
def karma(bot, event, name=None, *args):
    if name:
        if name[0] == '@':
            name = name[1:]
        lower_name = name.lower()
        for u in sorted(event.conv.users, key=lambda x: x.full_name.split()[-1]):
            if lower_name not in u.full_name.lower():
                continue

            segments = [hangups.ChatMessageSegment('%s:' % u.full_name, is_bold=True),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                        hangups.ChatMessageSegment('Karma: ' + str(UtilBot.get_current_karma(u.id_[0])))]
            bot.send_message_segments(event.conv, segments)
            return
        bot.send_message(event.conv, 'No user found matching "%s".' % name)

    else:
        karma_list = []
        list_num = min(5, int(len(event.conv.users) / 2) + 1)
        for u in event.conv.users:
            karma_list.append((u.full_name, UtilBot.get_current_karma(u.id_[0])))
        karma_list.sort(key=lambda x: -x[1])
        segments = [hangups.ChatMessageSegment("Karma Stats:", is_bold=True),
                    hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment("Top:", is_italic=True),
                    hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK)]
        if len(event.conv.users) > 10:
            for i in range(0, min(list_num, len(event.conv.users))):
                segments.append(hangups.ChatMessageSegment("{}: {}".format(karma_list[i][0], karma_list[i][1])))
                segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))

            segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))
            segments.append(hangups.ChatMessageSegment("Bottom:", is_italic=True))
            segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))

            for i in range(-1, -min(list_num, len(event.conv.users)) - 1, -1):
                segments.append(hangups.ChatMessageSegment("{}: {}".format(karma_list[i][0], karma_list[i][1])))
                segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))
        else:
            for i in range(0, len(event.conv.users)):
                segments.append(hangups.ChatMessageSegment("{}: {}".format(karma_list[i][0], karma_list[i][1])))
                segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))

        segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))
        segments.append(hangups.ChatMessageSegment("Average Karma:", is_italic=True))
        segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))
        segments.append(hangups.ChatMessageSegment('{}'.format((sum([i[1] for i in karma_list]) / len(karma_list)))))
        bot.send_message_segments(event.conv, segments)
Example #6
0
def rate(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Rate smileys*
Usage: /rate <key> 
Purpose: Send a rating smiley, key can be: agree, disagree, funny, winner, 
zing, informative, friendly, useful, optimistic, artistic, late, dumb or box.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        ratings = dict(agree="\u2714",
                       disagree="\u274c",
                       funny="\U0001f604",
                       winner="\U0001f31f",
                       zing="\u26a1",
                       informative="\u2139",
                       friendly="\u2764",
                       useful="\U0001f527",
                       optimistic="\U0001f308",
                       artistic="\U0001f3a8",
                       late="\u23f0",
                       dumb="\U0001f4e6",
                       box="\U0001f4e6")
        try:
            yield from bot.send_message(event.conv, ratings[args[0].lower()])
        except KeyError:
            yield from bot.send_message(
                event.conv,
                "That's not a valid rating. You are \U0001f4e6 x 1")
Example #7
0
def flip(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Flip*
Usage: /flip <optional: number of times to flip>
Purpose: Flips a coin.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        times = 1
        if len(args) > 0 and args[-1].isdigit():
            times = int(args[-1]) if int(args[-1]) < 1000000 else 1000000
        heads, tails = 0, 0
        for x in range(0, times):
            n = random.randint(0, 1)
            if n == 1:
                heads += 1
            else:
                tails += 1
        if times == 1:
            bot.send_message(event.conv, "Heads!" if heads > tails else "Tails!")
        else:
            bot.send_message(event.conv,
                             "Winner: " + (
                                 "Heads!" if heads > tails else "Tails!" if tails > heads else "Tie!") + " Heads: " + str(
                                 heads) + " Tails: " + str(tails) + " Ratio: " + (str(
                                 Fraction(heads, tails)) if heads > 0 and tails > 0 else str(heads) + '/' + str(tails)))
Example #8
0
def imagesearch(bot, event, *args):
    num_requested = 0
    if len(args) == 0:
        bot.send_message(event.conv, "Error: requires more than 0 arguments.")
        return
    else:
        if args[-1][0] == '@' and UtilBot.is_integer(args[-1][1:]):
            # we subtract one here because image #1 is the 0 item in the list
            num_requested = int(args[-1][1:]) - 1
            args = args[:-1]

    if num_requested > 7 or num_requested < 0:
        bot.send_message(event.conv,
                         "Error: result number must be between 1 and 8.")
        return

    query = ' '.join(args)
    url = 'http://ajax.googleapis.com/ajax/services/search/images?v=1.0&rsz=8&' \
          + parse.urlencode({'q': query})

    resp = request.urlopen(url)
    image_json = json.loads(resp.read().decode())
    url = image_json['responseData']['results'][num_requested]['unescapedUrl']

    yield from send_image(bot, event, url)
Example #9
0
def img(bot, event, *args):
    if len(args) > 0:
        yield from bot.send_typing(event.conv)
        url = args[0]
        file_exception = False
        try:
            imageids_filename = os.path.join('images', 'imageids.json')
            imageids = json.loads(open(imageids_filename,
                                       encoding='utf-8').read(),
                                  encoding='utf-8')
            imageID = imageids.get(url)
        except IOError as e:
            if e.errno == errno.ENOENT:
                imageids = {}
            else:
                print('Exception:')
                print(str(e))
                file_exception = True
            imageID = None
        if imageID is None:
            filename = UtilBot.download_image(url, 'images')
            imageID = yield from bot._client.upload_image(filename)
            if not file_exception:
                imageids[url] = imageID
                with open(imageids_filename, 'w') as f:
                    json.dump(imageids, f, indent=2, sort_keys=True)
                os.remove(filename)
        bot.send_image(event.conv, imageID)
Example #10
0
def navyseals(bot, event, *args):
     if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Navy Seals**
Usage: /navyseals
Purpose: Shits fury all over you.
""")
        bot.send_message_segments(event.conv, segments)
     else:
        bot.send_message(event.conv,
'''What the f**k did you just f*****g say about me, you little bitch? \
I'll have you know I graduated top of my class in the Navy Seals, and \
I've been involved in numerous secret raids on Al-Quaeda, and I have over \
300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper \
in the entire US armed forces. You are nothing to me but just another target. \
I will wipe you the f**k out with precision the likes of which has never \
been seen before on this Earth, mark my f*****g words. You think you can \
get away with saying that shit to me over the Internet? Think again, f****r. \
As we speak I am contacting my secret network of spies across the USA and \
your IP is being traced right now so you better prepare for the storm, \
maggot. The storm that wipes out the pathetic little thing you call your \
life. You're f*****g dead, kid. I can be anywhere, anytime, and I can kill \
you in over seven hundred ways, and that's just with my bare hands. Not only \
am I extensively trained in unarmed combat, but I have access to the entire \
arsenal of the United States Marine Corps and I will use it to its full \
extent to wipe your miserable ass off the face of the continent, you little \
shit. If only you could have known what unholy retribution your little \
"clever" comment was about to bring down upon you, maybe you would have held \
your f*****g tongue. But you couldn't, you didn't, and now you're paying the \
price, you goddamn idiot. I will shit fury all over you and you will drown in \
it. You're f*****g dead, kiddo.''')
Example #11
0
def roulette(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Roulette**
Usage: /roulette
Purpose: Spins the chamber and tries to shoot you in the head
""")
        bot.send_message_segments(event.conv, segments)
    else:
        #static variables
        if not hasattr(roulette, "_rouletteChamber"):
            roulette._rouletteChamber = random.randrange(0, 6)
        if not hasattr(roulette, "_rouletteBullet"):
            roulette._rouletteBullet = random.randrange(0, 6)

        if len(args) > 0 and args[0] == 'spin':
            roulette._rouletteBullet = random.randrange(0, 6)
            bot.send_message(event.conv, '*SPIN* Are you feeling lucky?')
            return
        if roulette._rouletteChamber == roulette._rouletteBullet:
            roulette._rouletteBullet = random.randrange(0, 6)
            roulette._rouletteChamber = random.randrange(0, 6)
            bot.send_message(event.conv, '*BANG*')
        else:
            bot.send_message(event.conv, '*click*')
            roulette._rouletteChamber += 1
            roulette._rouletteChamber %= 6
Example #12
0
def config(bot, event, cmd=None, *args):
    if cmd == 'get' or cmd is None:
        config_args = list(args)
        value = bot.config.get_by_path(config_args) if config_args else dict(bot.config)
    elif cmd == 'set':
        config_args = list(args[:-1])
        if len(args) >= 2:
            bot.config.set_by_path(config_args, json.loads(args[-1]))
            bot.config.save()
            value = bot.config.get_by_path(config_args)
        else:
            yield from DispatcherSingleton.unknown_command(bot, event)
            return
    else:
        yield from DispatcherSingleton.unknown_command(bot, event)
        return

    if value is None:
        value = 'Parameter does not exist!'

    config_path = ' '.join(k for k in ['config'] + config_args)
    segments = [hangups.ChatMessageSegment('{}:'.format(config_path),
                                           is_bold=True),
                hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)]
    segments.extend(UtilBot.text_to_segments(json.dumps(value, indent=2, sort_keys=True)))
    bot.send_message_segments(event.conv, segments)
Example #13
0
def send_webpage_screenshot(bot, event, url, viewportsize='1280x1024'):
    filename = 'screenie.png'

    cliprectsize = '0x0x' + viewportsize;

    try:
        cmd = ['capturejs',
               '--uri',
               url,
               '--viewportsize',
               viewportsize,
               '--output',
               filename,
               '--cliprect',
               cliprectsize]

        output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        output = output.decode(encoding='UTF-8')
        if output != '':
            bot.send_message(event.conv, output)

        image_id = yield from UtilBot.upload_image(bot, filename)
        send_image(bot, event, image_id)
        os.remove(filename)
    except http.client.BadStatusLine as e:
        display.stop()
        bot.send_message(event.conv, 'Error: BadStatusLine')
Example #14
0
def flip(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Flip*
Usage: /flip <optional: number of times to flip>
Purpose: Flips a coin.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        times = 1
        if len(args) > 0 and args[-1].isdigit():
            times = int(args[-1]) if int(args[-1]) < 1000000 else 1000000
        heads, tails = 0, 0
        for x in range(0, times):
            n = random.randint(0, 1)
            if n == 1:
                heads += 1
            else:
                tails += 1
        if times == 1:
            yield from bot.send_message(event.conv, "Heads!" if heads > tails else "Tails!")
        else:
            yield from bot.send_message(event.conv,
                             "Winner: " + (
                                 "Heads!" if heads > tails else "Tails!" if tails > heads else "Tie!") + " Heads: " + str(
                                 heads) + " Tails: " + str(tails) + " Ratio: " + (str(
                                 Fraction(heads, tails)) if heads > 0 and tails > 0 else str(heads) + '/' + str(tails)))
Example #15
0
def rate(bot, event, *args):
    ratings = dict(
                   agree      ="\u2714"
                  ,disagree   ="\u274c"
                  ,funny      ="\U0001f604"
                  ,winner     ="\U0001f31f"
                  ,zing       ="\u26a1"
                  ,informative="\u2139"
                  ,friendly   ="\u2764"
                  ,useful     ="\U0001f527"
                  ,optimistic ="\U0001f308"
                  ,artistic   ="\U0001f3a8"
                  ,late       ="\u23f0"
                  ,dumb       ="\U0001f4e6"
                  ,box        ="\U0001f4e6"
                  )
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Rate**
Usage: /rate <rating>
Purpose: Responds to your rating, ratings are agree, disagree, funny, winner, zing, informative, friendly, optimistic, artistic, late, dumb and box.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        try:
            bot.send_message(event.conv, ratings[args[0]])
        except KeyError:
            bot.send_message(event.conv, "That's not a valid rating. You are \U0001f4e6 x 1")
Example #16
0
def block(bot, event, username=None, *args):
    if not username:
        segments = [hangups.ChatMessageSegment("Blocked Users: ", is_bold=True),
                    hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment("No users blocked.")]
        if len(UtilBot.get_blocked_users_in_conversations(event.conv_id)) > 0:
            segments.pop()
            for user in event.conv.users:
                if UtilBot.is_user_blocked(event.conv_id, user.id_):
                    segments.append(hangups.ChatMessageSegment(user.full_name))
                    segments.append(hangups.ChatMessageSegment("\n", segment_type=hangups.SegmentType.LINE_BREAK))
            segments.pop()
        bot.send_message_segments(event.conv, segments)
        return
    username_lower = username.strip().lower()
    for u in sorted(event.conv.users, key=lambda x: x.full_name.split()[-1]):
        if not username_lower in u.full_name.lower() or event.user.is_self:
            continue

        if u.id_ == event.user.id_:
            bot.send_message(event.conv, "Aborting block as it would block calling user. ({})".format(u.full_name))
            return

        if UtilBot.is_user_blocked(event.conv_id, u.id_):
            UtilBot.remove_from_blocklist(event.conv_id, u.id_)
            bot.send_message(event.conv, "Unblocked User: {}".format(u.full_name))
            return
        UtilBot.add_to_blocklist(event.conv_id, u.id_)
        bot.send_message(event.conv, "Blocked User: {}".format(u.full_name))
        return
Example #17
0
def _reminder_on_connect_listener(bot):
    reminders = UtilBot.get_all_reminders()
    for reminder in reminders:
        reminder_time = dateutil.parser.parse(reminder[2])
        reminder_interval = (reminder_time - datetime.now()).seconds
        conv = bot._conv_list.get(reminder[0])
        reminder_timer = threading.Timer(reminder_interval, send_reminder,
                                         [bot, conv, reminder_interval, reminder[1], asyncio.get_event_loop()])
        reminder_timer.start()
Example #18
0
def udefine(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Urbanly Define*
Usage: /udefine <word to search for> \
<optional: definition number [defaults to 1st]>
Purpose: Define a word.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        yield from bot.send_typing(event.conv)
        api_host = 'http://urbanscraper.herokuapp.com/search/'
        num_requested = 0
        returnall = False
        if len(args) == 0:
            yield from bot.send_message(event.conv,
                                        "Invalid usage of /udefine.")
            return
        else:
            if args[-1] == '*':
                args = args[:-1]
                returnall = True
            if args[-1].isdigit():
                # we subtract one here because def #1 is the 0 item in the list
                num_requested = int(args[-1]) - 1
                args = args[:-1]

            term = parse.quote('.'.join(args))
            response = requests.get(api_host + term)
            error_response = 'No definition found for \"{}\".'.format(
                ' '.join(args))
            if response.status_code != 200:
                yield from bot.send_message(event.conv, error_response)
            result = response.content.decode()
            result_list = json.loads(result)
            num_requested = min(num_requested, len(result_list) - 1)
            num_requested = max(0, num_requested)
            result = result_list[num_requested].get('definition',
                                                    error_response)
            if returnall:
                segments = []
                for string in result_list:
                    segments.append(hangups.ChatMessageSegment(string))
                    segments.append(
                        hangups.ChatMessageSegment(
                            '\n', hangups.SegmentType.LINE_BREAK))
                yield from bot.send_message_segments(event.conv, segments)
            else:
                segments = [
                    hangups.ChatMessageSegment(' '.join(args), is_bold=True),
                    hangups.ChatMessageSegment('\n',
                                               hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment(result + ' [{0} of {1}]'.format(
                        num_requested + 1, len(result_list)))
                ]
                yield from bot.send_message_segments(event.conv, segments)
Example #19
0
def xfiles(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Xfiles**
Usage: /xfiles
Purpose: but what if bot is not kill
""")
        bot.send_message_segments(event.conv, segments)
    else:
        args = ['xfiles','theme']
        youtube(bot, event, *args)
Example #20
0
def _reminder_on_connect_listener(bot):
    reminders = UtilBot.get_all_reminders()
    for reminder in reminders:
        reminder_time = dateutil.parser.parse(reminder[2])
        reminder_interval = (reminder_time - datetime.now()).seconds
        conv = bot._conv_list.get(reminder[0])
        reminder_timer = threading.Timer(reminder_interval, send_reminder, [
            bot, conv, reminder_interval, reminder[1],
            asyncio.get_event_loop()
        ])
        reminder_timer.start()
Example #21
0
def help(bot, event, command=None, *args):
    docstring = """
    *Current Implemented Commands:*
    {}
    Use: /<command name> ? or /help <command name> to find more information about the command.
    """.format(', '.join(sorted(DispatcherSingleton.commands.keys())))
    if command == '?' or command is None:
        yield from bot.send_message_segments(
            event.conv, UtilBot.text_to_segments(docstring))
    else:
        if command in DispatcherSingleton.commands.keys():
            func = DispatcherSingleton.commands[command]
            if func.__doc__:
                yield from bot.send_message_segments(
                    event.conv, UtilBot.text_to_segments(func.__doc__))
            else:  # Compatibility purposes for the old way of showing help text.
                args = ['?']
                yield from func(bot, event, *args)
        else:
            yield from bot.send_message(
                "The command {} is not registered.".format(command))
Example #22
0
    def run(self, bot, event, bot_command_char, *args, **kwds):

        bot_command_char = bot_command_char.strip()  # For cases like "/bot " or " / "

        if args[0] == bot_command_char:  # Either the command char is like "/bot" or the user did "/ ping"
            args = list(args[1:])
        if args[0].startswith(bot_command_char):
            command = args[0][len(bot_command_char):]
        else:
            command = args[0]
        if command[:2] == 'r/':
            command = 'subreddit'
            args = list(args)
            print(args)
            args.insert(1, args[0][3:])
        elif command[:2] == 'v/':
            command = 'subverse'
            args = list(args)
            print(args)
            args.insert(1, args[0][3:])
        try:
            func = self.commands[command]
        except KeyError:
            try:
                if event.user.is_self:
                    func = self.hidden_commands[command]
                else:
                    raise KeyError
            except KeyError:
                if self.unknown_command:
                    func = self.unknown_command
                else:
                    raise NoCommandFoundError(
                        "Command {} is not registered. Furthermore, no command found to handle unknown commands.".format
                        (command))

        func = asyncio.coroutine(func)

        args = list(args[1:])

        # For help cases.
        if len(args) > 0 and args[0] == '?':
            if func.__doc__:
                bot.send_message_segments(event.conv, UtilBot.text_to_segments(func.__doc__))
                return

        try:
            asyncio.async(func(bot, event, *args, **kwds))
        except Exception as e:
            log = open('log.txt', 'a+')
            log.writelines(str(datetime.now()) + ":\n " + traceback.format_exc() + "\n\n")
            log.close()
            print(traceback.format_exc())
Example #23
0
def latex(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**LaTeX**
Usage: /latex <LaTeX code>
Purpose: Renders LaTeX code to an image and sends it
""")
        bot.send_message_segments(event.conv, segments)
    else:
        cmd = "texvc /tmp images '" + \
              ' '.join(args).replace("'", "'\\''") + \
              "' utf-8 'rgb 1.0 1.0 1.0'"
        print('args: ')
        print(cmd)
        output = subprocess.check_output(cmd, shell=True)
        output = output.decode(encoding='UTF-8')
        print(output)
        filename = output[1:33] + '.png'
        filename = os.path.join('images', filename)
        image_id = yield from UtilBot.upload_image(bot, filename)
        send_image(bot, event, image_id)
Example #24
0
def ytban(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**YTBan**
Usage: /ytban <search parameters>
Purpose: Get the first result from YouTube\'s search using search parameter, then bans it!
""")
        bot.send_message_segments(event.conv, segments)
    else:
        search_terms = " ".join(args)
        youtube_info = UtilBot.find_youtube_info(search_terms)
        youtube_banlist = load_json('youtube_banlist.json')

        if youtube_info['item_id'] not in youtube_banlist:
            youtube_banlist.append(youtube_info['item_id'])

        bot.send_message(event.conv,
                         'Video "{title}" with ID "{id}" is now banned'.format(
                           title=youtube_info['item_title'], id=youtube_info['item_id']))

        save_json('youtube_banlist.json', youtube_banlist)
Example #25
0
def eightball(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Eightball**
Usage: /eightball
Purpose: Tells fortunes!
""")
        bot.send_message_segments(event.conv, segments)
    else:
        if len(args) > 0:
            bot.send_message(event.conv, _checkTheBall(len(' '.join(args))))
        else:
            bot.send_message(event.conv, _checkTheBall(random.randint(0, 2)))
Example #26
0
def fliptext(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Flip Text**
Usage: /fliptext <text>
Purpose: Flips your message 180 degrees
""")
        bot.send_message_segments(event.conv, segments)
    else:
        args = ' '.join(args)
        output = ''.join([fliptextdict.get(letter, letter) for letter in args])
        output = output[::-1]
        bot.send_message(event.conv, output)
Example #27
0
def fliptext(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Flip Text*
Usage: /fliptext <text>
Purpose: Flips your message 180 degrees
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        args = ' '.join(args)
        output = ''.join([fliptextdict.get(letter, letter) for letter in args])
        output = output[::-1]
        yield from bot.send_message(event.conv, output)
Example #28
0
def navyseals(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Navy Seals*
Usage: /navyseals
Purpose: Shits fury all over you.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        yield from bot.send_message(
            event.conv,
            "What the f**k did you just f*****g say about me, you little bitch? I'll have you know I graduated top of my class in the Navy Seals, and I've been involved in numerous secret raids on Al-Quaeda, and I have over 300 confirmed kills. I am trained in gorilla warfare and I'm the top sniper in the entire US armed forces. You are nothing to me but just another target. I will wipe you the f**k out with precision the likes of which has never been seen before on this Earth, mark my f*****g words. You think you can get away with saying that shit to me over the Internet? Think again, f****r. As we speak I am contacting my secret network of spies across the USA and your IP is being traced right now so you better prepare for the storm, maggot. The storm that wipes out the pathetic little thing you call your life. You're f*****g dead, kid. I can be anywhere, anytime, and I can kill you in over seven hundred ways, and that's just with my bare hands. Not only am I extensively trained in unarmed combat, but I have access to the entire arsenal of the United States Marine Corps and I will use it to its full extent to wipe your miserable ass off the face of the continent, you little shit. If only you could have known what unholy retribution your little “clever” comment was about to bring down upon you, maybe you would have held your f*****g tongue. But you couldn't, you didn't, and now you're paying the price, you goddamn idiot. I will shit fury all over you and you will drown in it. You're f*****g dead, kiddo."
        )
Example #29
0
def help(bot, event, command=None, *args):
    valid_user_commands = []
    for command_test in sorted(DispatcherSingleton.commands.keys()):
        if UtilBot.check_if_can_run_command(bot, event, command_test):
            valid_user_commands.append(command_test)
    docstring = """
    **Current Implemented Commands:**
    {}
    Use: /<command name> ? or /help <command name> to find more information about the command.
    """.format(', '.join(valid_user_commands))
    if command == '?' or command is None:
        bot.send_message_segments(event.conv, UtilBot.text_to_segments(docstring))
    else:
        if command in DispatcherSingleton.commands.keys():
            func = DispatcherSingleton.commands[command]
            if func.__doc__:
                bot.send_message_segments(event.conv, UtilBot.text_to_segments(func.__doc__))
            else:  # Compatibility purposes for the old way of showing help text.
                args = ['?']
                func(bot, event, *args)
        else:
            bot.send_message("The command {} is not registered.".format(command))
Example #30
0
def youtube(bot, event, *args):
    Segment = hangups.ChatMessageSegment
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**YouTube**
Usage: /youtube <optional: search parameter>
Purpose: Get the first result from YouTube\'s search using search parameter.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        search_terms = " ".join(args)
        youtube_info = UtilBot.find_youtube_info(search_terms)
        youtube_banlist = load_json('youtube_banlist.json')

        if youtube_info['item_id'] in youtube_banlist:
            bot.send_message(event.conv, 'Sorry, that video is banned.')
        else:
            bot.send_message_segments(event.conv, [hangups.ChatMessageSegment('Result:', is_bold=True),
                                                   hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                                                   hangups.ChatMessageSegment(youtube_info['item_title'],
                                                                              hangups.SegmentType.LINK,
                                                                              link_target=youtube_info['item_url'])])
Example #31
0
def udefine(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Urbanly Define*
Usage: /udefine <word to search for> \
<optional: definition number [defaults to 1st]>
Purpose: Define a word.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        api_host = 'http://urbanscraper.herokuapp.com/search/'
        num_requested = 0
        returnall = False
        if len(args) == 0:
            bot.send_message(event.conv, "Invalid usage of /udefine.")
            return
        else:
            if args[-1] == '*':
                args = args[:-1]
                returnall = True
            if args[-1].isdigit():
                # we subtract one here because def #1 is the 0 item in the list
                num_requested = int(args[-1]) - 1
                args = args[:-1]

            term = parse.quote('.'.join(args))
            response = requests.get(api_host + term)
            error_response = 'No definition found for \"{}\".'.format(' '.join(args))
            if response.status_code != 200:
                bot.send_message(event.conv, error_response)
            result = response.content.decode()
            result_list = json.loads(result)
            if len(result_list) == 0:
                bot.send_message(event.conv, error_response)
                return
            num_requested = min(num_requested, len(result_list) - 1)
            num_requested = max(0, num_requested)
            result = result_list[num_requested].get(
                'definition', error_response)
            if returnall:
                segments = []
                for string in result_list:
                    segments.append(hangups.ChatMessageSegment(string))
                    segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
                bot.send_message_segments(event.conv, segments)
            else:
                segments = [hangups.ChatMessageSegment(' '.join(args), is_bold=True),
                            hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                            hangups.ChatMessageSegment(result + ' [{0} of {1}]'.format(
                                num_requested + 1, len(result_list)))]
                bot.send_message_segments(event.conv, segments)
Example #32
0
def source(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Source**
Usage: /source
Purpose: Links to the GitHub
""")
        bot.send_message_segments(event.conv, segments)
    else:
        url = 'https://github.com/ShaunOfTheLive/HangoutsBot'
        segments = [hangups.ChatMessageSegment(url,
                                               hangups.SegmentType.LINK,
                                               link_target=url)]
        bot.send_message_segments(event.conv, segments)
Example #33
0
def log(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Log**
Usage: /log <text>
Purpose: Logs text to the log.txt file.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        msg = ' '.join(args)
        log = open('log.txt', 'a+')
        log.writelines(msg + "\n")
        for c in msg: log.writelines(hex(ord(c)) + " ")
        log.writelines("\n")
        log.close()
Example #34
0
    def run(self, bot, event, bot_command_char, *args, **kwds):

        bot_command_char = bot_command_char.strip(
        )  # For cases like "/bot " or " / "

        if args[0] == bot_command_char:  # Either the command char is like "/bot" or the user did "/ ping"
            args = list(args[1:])
        if args[0].startswith(bot_command_char):
            command = args[0][len(bot_command_char):]
        else:
            command = args[0]
        try:
            func = self.commands[command]
        except KeyError:
            try:
                if event.user.is_self:
                    func = self.hidden_commands[command]
                else:
                    raise KeyError
            except KeyError:
                if self.unknown_command:
                    func = self.unknown_command
                else:
                    raise NoCommandFoundError(
                        "Command {} is not registered. Furthermore, no command found to handle unknown commands."
                        .format(command))

        func = asyncio.coroutine(func)

        args = list(args[1:])

        # For help cases.
        if len(args) > 0 and args[0] == '?':
            if func.__doc__:
                bot.send_message_segments(
                    event.conv, UtilBot.text_to_segments(func.__doc__))
                return

        try:
            asyncio. async (func(bot, event, *args, **kwds))
        except Exception as e:
            log = open('log.txt', 'a+')
            log.writelines(
                str(datetime.now()) + ":\n " + traceback.format_exc() + "\n\n")
            log.close()
            print(traceback.format_exc())
Example #35
0
def spoof(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Spoof*
Usage: /spoof
Purpose: Who knows...
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        segments = [hangups.ChatMessageSegment('!!! CAUTION !!!', is_bold=True),
                    hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment('User ')]
        link = 'https://plus.google.com/u/0/{}/about'.format(event.user.id_.chat_id)
        segments.append(hangups.ChatMessageSegment(event.user.full_name, hangups.SegmentType.LINK,
                                                   link_target=link))
        segments.append(hangups.ChatMessageSegment(' has just been reporting to the NSA for attempted spoofing!'))
        yield from bot.send_message_segments(event.conv, segments)
Example #36
0
def spoof(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Spoof*
Usage: /spoof
Purpose: Who knows...
""")
        bot.send_message_segments(event.conv, segments)
    else:
        segments = [hangups.ChatMessageSegment('!!! CAUTION !!!', is_bold=True),
                    hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment('User ')]
        link = 'https://plus.google.com/u/0/{}/about'.format(event.user.id_.chat_id)
        segments.append(hangups.ChatMessageSegment(event.user.full_name, hangups.SegmentType.LINK,
                                                   link_target=link))
        segments.append(hangups.ChatMessageSegment(' has just been reporting to the NSA for attempted spoofing!'))
        bot.send_message_segments(event.conv, segments)
Example #37
0
def youtube(bot, event, *args):
    Segment = hangups.ChatMessageSegment
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*YouTube*
Usage: /youtube <optional: search parameter>
Purpose: Get the first result from YouTube\'s search using search parameter.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        yield from bot.send_typing(event.conv)
        search_terms = " ".join(args)
        if search_terms == "" or search_terms == " ":
            search_terms = "Fabulous Secret Powers"
        query = parse.urlencode({
            'search_query': search_terms,
            'filters': 'video'
        })
        results_url = 'https://www.youtube.com/results?%s' \
              % query
        headers = {
            'User-agent':
            'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36'
        }
        req = request.Request(results_url, None, headers)
        resp = request.urlopen(req)
        soup = BeautifulSoup(resp)
        item_id = soup.find_all("div",
                                class_="yt-lockup")[0]['data-context-item-id']
        query = parse.urlencode({'v': item_id})
        item_url = 'https://www.youtube.com/watch?%s' \
              % query
        item_title = soup.find_all("a", class_="yt-uix-tile-link")[0]['title']

        if item_id in youtube_banlist:
            yield from bot.send_message(event.conv,
                                        'Sorry, that video is banned.')
        else:
            yield from bot.send_message_segments(event.conv, [
                hangups.ChatMessageSegment('Result:', is_bold=True),
                hangups.ChatMessageSegment('\n',
                                           hangups.SegmentType.LINE_BREAK),
                hangups.ChatMessageSegment(
                    item_title, hangups.SegmentType.LINK, link_target=item_url)
            ])
Example #38
0
def load_images_from_folder(bot, event, *args):
    folder = args[0]
    # loop through folder
    for filename in glob(os.path.join('images', folder, '*')):
        # if filename not in imageids, upload it and store filename,id
        filetail = os.path.split(filename)[1]
        filehead = os.path.split(os.path.split(filename)[0])[1]
        filekey = os.path.join(filehead, filetail)
        print(filekey)
        image_id = UtilDB.get_imageid_for_filename(filekey)
        if image_id is None:
            bot.send_message(event.conv,
                             "Uploading {}".format(filekey))
            image_id = yield from UtilBot.upload_image(bot, filename)
            UtilDB.set_imageid_for_filename(filekey, image_id)
            ####os.remove(filename)
        UtilDB.set_alias_for_filename(filekey, folder)
    bot.send_message(event.conv, "Done.")
Example #39
0
def color(bot, event, *args):
    filename = 'color.png'
    cmd = ['convert',
           '-size',
           '500x500',
           'xc:%s' % ' '.join(args),
           filename]
    try:
        output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        output = output.decode(encoding='UTF-8')
        if output != '':
            bot.send_message(event.conv, output)
        image_id = yield from UtilBot.upload_image(bot, filename)
        send_image(bot, event, image_id)
        os.remove(filename)
    except subprocess.CalledProcessError as e:
        output = e.output.decode(encoding='UTF-8')
        if output != '':
            bot.send_message(event.conv, output)
Example #40
0
def latex(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*LaTeX*
Usage: /latex <LaTeX code>
Purpose: Renders LaTeX code to an image and sends it
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        cmd = "texvc /tmp images '" + \
              ' '.join(args).replace("'", "'\\''") + \
              "' utf-8 'rgb 1.0 1.0 1.0'"
        print('args: ')
        print(cmd)
        output = subprocess.check_output(cmd, shell=True)
        output = output.decode(encoding='UTF-8')
        print(output)
        filename = output[1:33] + '.png'
        filename = os.path.join('images', filename)
        imageID = yield from bot._client.upload_image(filename)
        bot.send_image(event.conv, imageID)
Example #41
0
def quote(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Quote*
Usage: /quote <optional: terms to search for> \
<optional: number of quote to show>
Purpose: Shows a quote.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        USER_ID = "3696"
        DEV_ID = "ZWBWJjlb5ImJiwqV"
        QUERY_TYPE = "RANDOM"
        fetch = 0
        if len(args) > 0 and args[-1].isdigit():
            fetch = int(args[-1])
            args = args[:-1]
        query = '+'.join(args)
        if len(query) > 0:
            QUERY_TYPE = "SEARCH"
        url = "http://www.stands4.com/services/v2/quotes.php?uid=" + USER_ID + "&tokenid=" + DEV_ID + "&searchtype=" + QUERY_TYPE + "&query=" + query
        soup = BeautifulSoup(request.urlopen(url))
        if QUERY_TYPE == "SEARCH":
            children = list(soup.results.children)
            numQuotes = len(children)
            if numQuotes == 0:
                yield from bot.send_message(event.conv, "Unable to find quote.")
                return

            if fetch > numQuotes - 1:
                fetch = numQuotes
            elif fetch < 1:
                fetch = 1
            yield from bot.send_message(event.conv, "\"" +
                             children[fetch - 1].quote.text + "\"" + ' - ' + children[
                fetch - 1].author.text + ' [' + str(
                fetch) + ' of ' + str(numQuotes) + ']')
        else:
            yield from bot.send_message(event.conv, "\"" + soup.quote.text + "\"" + ' -' + soup.author.text)
Example #42
0
def quote(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Quote*
Usage: /quote <optional: terms to search for> \
<optional: number of quote to show>
Purpose: Shows a quote.
""")
        bot.send_message_segments(event.conv, segments)
    else:
        USER_ID = "3696"
        DEV_ID = "ZWBWJjlb5ImJiwqV"
        QUERY_TYPE = "RANDOM"
        fetch = 0
        if len(args) > 0 and args[-1].isdigit():
            fetch = int(args[-1])
            args = args[:-1]
        query = '+'.join(args)
        if len(query) > 0:
            QUERY_TYPE = "SEARCH"
        url = "http://www.stands4.com/services/v2/quotes.php?uid=" + USER_ID + "&tokenid=" + DEV_ID + "&searchtype=" + QUERY_TYPE + "&query=" + query
        soup = BeautifulSoup(request.urlopen(url))
        if QUERY_TYPE == "SEARCH":
            children = list(soup.results.children)
            numQuotes = len(children)
            if numQuotes == 0:
                bot.send_message(event.conv, "Unable to find quote.")
                return

            if fetch > numQuotes - 1:
                fetch = numQuotes
            elif fetch < 1:
                fetch = 1
            bot.send_message(event.conv, "\"" +
                             children[fetch - 1].quote.text + "\"" + ' - ' + children[
                                 fetch - 1].author.text + ' [' + str(
                fetch) + ' of ' + str(numQuotes) + ']')
        else:
            bot.send_message(event.conv, "\"" + soup.quote.text + "\"" + ' -' + soup.author.text)
Example #43
0
def greentext(bot, event, *args):
    """
    **Greentext**
    Usage: /greentext <text>
    Purpose: makes your text green and adds an epic maymay arrow, add more maymay arrows for more fun
    """
    filename = 'greentext.png'
    message = ' '.join(args)
    if message[0] == '>':
        message = message[1:]
    message = message.replace('>', '\n>')
    message = '>' + message
    print(message)
    cmd = ['convert',
           '-size',
           '164x',
           '-font',
           '/usr/share/fonts/TTF/arial.ttf',
           '-pointsize',
           '13',
           '-fill',
           '#789922',
           '-background',
           '#ffffee',
           'caption:%s' % message,
           filename]
    try:
        output = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        output = output.decode(encoding='UTF-8')
        if output != '':
            bot.send_message(event.conv, output)
        image_id = yield from UtilBot.upload_image(bot, filename)
        send_image(bot, event, image_id)
        os.remove(filename)
    except subprocess.CalledProcessError as e:
        output = e.output.decode(encoding='UTF-8')
        if output != '':
            bot.send_message(event.conv, output)
Example #44
0
def webshot(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**Webshot**
Usage: /webshot <url>
Purpose: Screenshots a webpage
""")
        bot.send_message_segments(event.conv, segments)
    else:
        if len(args) == 1:
            url = args[0]
            viewportsize = '1280x1024'
        elif len(args) > 1:
            url = args[0]
            viewportsize = args[1]

        if not is_valid_url(url):
            url = 'http://' + url
            if not is_valid_url(url):
                bot.send_message(event.conv, "Error: invalid URL.")
                return            

        yield from send_webpage_screenshot(bot, event, url, viewportsize)
Example #45
0
def remind(bot, event, *args):
    # TODO Implement a private chat feature. Have reminders save across reboots?
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Remind*
Usage: /remind <optional: date [defaults to today]> \
<optional: time [defaults to an hour from now]> Message
Usage: /remind
Usage: /remind delete <index to delete>
Purpose: Will post a message the date and time specified to \
the current chat. With no arguments, it'll list all the reminders.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        if len(args) == 0:
            segments = [hangups.ChatMessageSegment('Reminders:', is_bold=True),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)]
            if len(reminders) > 0:
                for x in range(0, len(reminders)):
                    reminder = reminders[x]
                    reminder_timer = reminder[0]
                    reminder_text = reminder[1]
                    date_to_post = datetime.now() + timedelta(seconds=reminder_timer.interval)
                    segments.append(
                        hangups.ChatMessageSegment(
                            str(x + 1) + ' - ' + date_to_post.strftime('%m/%d/%y %I:%M%p') + ' : ' + reminder_text))
                    segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
                segments.pop()
                yield from bot.send_message_segments(event.conv, segments)
            else:
                yield from bot.send_message(event.conv, "No reminders are currently set.")
            return
        if args[0] == 'delete':
            try:
                x = int(args[1])
                x -= 1
            except ValueError:
                yield from bot.send_message(event.conv, 'Invalid integer: ' + args[1])
                return
            if x in range(0, len(reminders)):
                reminder_to_remove_text = reminders[x][1]
                reminders[x][0].cancel()
                reminders.remove(reminders[x])
                yield from bot.send_message(event.conv, 'Removed reminder: ' + reminder_to_remove_text)
            else:
                yield from bot.send_message(event.conv, 'Invalid integer: ' + str(x + 1))
            return

        def send_reminder(bot, conv, reminder_time, reminder_text, loop):
            asyncio.set_event_loop(loop)
            yield from bot.send_message(conv, reminder_text)
            for reminder in reminders:
                if reminder[0].interval == reminder_time and reminder[1] == reminder_text:
                    reminders.remove(reminder)

        args = list(args)
        date = str(datetime.now().today().date())
        time = str((datetime.now() + timedelta(hours=1)).time())
        set_date = False
        set_time = False
        index = 0
        while index < len(args):
            item = args[index]
            if item[0].isnumeric():
                if '/' in item or '-' in item:
                    date = item
                    args.remove(date)
                    set_date = True
                    index -= 1
                else:
                    time = item
                    args.remove(time)
                    set_time = True
                    index -= 1
            if set_date and set_time:
                break
            index += 1

        reminder_time = date + ' ' + time
        if len(args) > 0:
            reminder_text = ' '.join(args)
        else:
            yield from bot.send_message(event.conv, 'No reminder text set.')
            return
        current_time = datetime.now()
        try:
            reminder_time = parser.parse(reminder_time)
        except (ValueError, TypeError):
            yield from bot.send_message(event.conv, "Couldn't parse " + reminder_time + " as a valid date.")
            return
        if reminder_time < current_time:
            reminder_time = current_time + timedelta(hours=1)
        reminder_interval = (reminder_time - current_time).seconds
        reminder_timer = threading.Timer(reminder_interval, send_reminder,
                                         [bot, event.conv, reminder_interval, reminder_text, asyncio.get_event_loop()])
        reminders.append((reminder_timer, reminder_text))
        reminder_timer.start()
        bot.send_message(event.conv, "Reminder set for " + reminder_time.strftime('%B %d, %Y %I:%M%p'))
Example #46
0
def define(bot, event, *args):
    """
    **Define:**
    Usage: /define <word to search for> <optional: definition number [defaults to 1] OR * to show all definitions>
    Usage: /define <word to search for> <start index and end index in form of int:int (e.g., /define test 1:3)>
    Purpose: Show definitions for a word.
    """
    if args[-1].isdigit():
        definition, length = UtilBot.define(' '.join(args[0:-1]), num=int(args[-1]))
        segments = [hangups.ChatMessageSegment(' '.join(args[0:-1]).title(), is_bold=True),
                    hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK),
                    hangups.ChatMessageSegment(
                        definition.replace('\n', ''))]
        bot.send_message_segments(event.conv, segments)
    elif args[-1] == '*':
        args = list(args)
        args[-1] = '1:*'
    if ':' in args[-1]:
        start, end = re.split(':', args[-1])
        try:
            start = int(start)
        except ValueError:
            start = 1
        display_all = False
        if end == '*':
            end = 100
            display_all = True
        else:
            try:
                end = int(end)
            except ValueError:
                end = 3
        if start < 1:
            start = 1
        if start > end:
            end, start = start, end
        if start == end:
            end += 1
        if len(args) <= 1:
            bot.send_message(event.conv, "Invalid usage for /define.")
            return
        query = ' '.join(args[:-1])
        definition_segments = [hangups.ChatMessageSegment(query.title(), is_bold=True),
                               hangups.ChatMessageSegment('', segment_type=hangups.SegmentType.LINE_BREAK)]
        if start < end:
            x = start
            while x <= end:
                definition, length = UtilBot.define(query, num=x)
                definition_segments.append(hangups.ChatMessageSegment(definition))
                if x != end:
                    definition_segments.append(
                        hangups.ChatMessageSegment('', segment_type=hangups.SegmentType.LINE_BREAK))
                    definition_segments.append(
                        hangups.ChatMessageSegment('', segment_type=hangups.SegmentType.LINE_BREAK))
                if end > length:
                    end = length
                if display_all:
                    end = length
                    display_all = False
                x += 1
            bot.send_message_segments(event.conv, definition_segments)
        return
    else:
        args = list(args)
        args.append("1:3")
        define(bot, event, *args)
        return
Example #47
0
def record(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
*Record*
Usage: /record <text to record>
Usage: /record date <date to show records from>
Usage: /record list
Usage: /record search <search term>
Usage: /record strike
Usage: /record
Purpose: Store/Show records of conversations. Note: All records will be prepended by: "On the day of <date>," automatically.
""")
        yield from bot.send_message_segments(event.conv, segments)
    else:
        import datetime

        global last_recorded, last_recorder
        directory = "Records" + os.sep + str(event.conv_id)
        if not os.path.exists(directory):
            os.makedirs(directory)
        filename = str(datetime.date.today()) + ".txt"
        filepath = os.path.join(directory, filename)
        file = None

        # Deletes the record for the day. TODO Is it possible to make this admin only?
        if ''.join(args) == "clear":
            file = open(filepath, "a+")
            file.seek(0)
            file.truncate()

        # Shows the record for the day.
        elif ''.join(args) == '':
            file = open(filepath, "a+")
            # If the mode is r+, it won't create the file. If it's a+, I have to seek to the beginning.
            file.seek(0)
            segments = [hangups.ChatMessageSegment(
                'On the day of ' + datetime.date.today().strftime('%B %d, %Y') + ':', is_bold=True),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)]
            for line in file:
                segments.append(
                    hangups.ChatMessageSegment(line))
                segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
                segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
            yield from bot.send_message_segments(event.conv, segments)

        # Removes the last line recorded, iff the user striking is the same as the person who recorded last.
        # TODO This isn't working properly across multiple chats.
        elif args[0] == "strike":
            if event.user.id_ == last_recorder:
                file = open(filepath, "a+")
                file.seek(0)
                file_lines = file.readlines()
                if last_recorded is not None and last_recorded in file_lines:
                    file_lines.remove(last_recorded)
                file.seek(0)
                file.truncate()
                file.writelines(file_lines)
                last_recorded = None
                last_recorder = None
            else:
                yield from bot.send_message(event.conv, "You do not have the authority to strike from the Record.")

        # Lists every record available. TODO Paginate this?
        elif args[0] == "list":
            files = os.listdir(directory)
            segments = []
            for name in files:
                segments.append(hangups.ChatMessageSegment(name.replace(".txt", "")))
                segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
            yield from bot.send_message_segments(event.conv, segments)

        # Shows a list of records that match the search criteria.
        elif args[0] == "search":
            args = args[1:]
            searched_term = ' '.join(args)
            escaped_args = []
            for item in args:
                escaped_args.append(re.escape(item))
            term = '.*'.join(escaped_args)
            term = term.replace(' ', '.*')
            if len(args) > 1:
                term = '.*' + term
            else:
                term = '.*' + term + '.*'
            foundin = []
            for name in glob.glob(directory + os.sep + '*.txt'):
                with open(name) as f:
                    contents = f.read()
                if re.match(term, contents, re.IGNORECASE | re.DOTALL):
                    foundin.append(name.replace(directory, "").replace(".txt", "").replace("\\", ""))
            if len(foundin) > 0:
                segments = [hangups.ChatMessageSegment("Found "),
                            hangups.ChatMessageSegment(searched_term, is_bold=True),
                            hangups.ChatMessageSegment(" in:"),
                            hangups.ChatMessageSegment("\n", hangups.SegmentType.LINE_BREAK)]
                for filename in foundin:
                    segments.append(hangups.ChatMessageSegment(filename))
                    segments.append(hangups.ChatMessageSegment("\n", hangups.SegmentType.LINE_BREAK))
                yield from bot.send_message_segments(event.conv, segments)
            else:
                segments = [hangups.ChatMessageSegment("Couldn't find  "),
                            hangups.ChatMessageSegment(searched_term, is_bold=True),
                            hangups.ChatMessageSegment(" in any records.")]
                yield from bot.send_message_segments(event.conv, segments)

        # Lists a record from the specified date.
        elif args[0] == "date":
            from dateutil import parser

            args = args[1:]
            try:
                dt = parser.parse(' '.join(args))
            except Exception as e:
                yield from bot.send_message(event.conv, "Couldn't parse " + ' '.join(args) + " as a valid date.")
                return
            filename = str(dt.date()) + ".txt"
            filepath = os.path.join(directory, filename)
            try:
                file = open(filepath, "r")
            except IOError:
                yield from bot.send_message(event.conv, "No record for the day of " + dt.strftime('%B %d, %Y') + '.')
                return
            segments = [hangups.ChatMessageSegment('On the day of ' + dt.strftime('%B %d, %Y') + ':', is_bold=True),
                        hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)]
            for line in file:
                segments.append(hangups.ChatMessageSegment(line))
                segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
                segments.append(hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK))
            yield from bot.send_message_segments(event.conv, segments)

        # Saves a record.
        else:
            file = open(filepath, "a+")
            file.write(' '.join(args) + '\n')
            yield from bot.send_message(event.conv, "Record saved successfully.")
            last_recorder = event.user.id_
            last_recorded = ' '.join(args) + '\n'
        if file is not None:
            file.close()
Example #48
0
def vote(bot, event, set_vote=None, *args):
    """**Vote:**
    Usage: /vote <subject to vote on>
    Usage: /vote <yea|yes|for|nay|no|against (used to cast a vote)>
    Usage: /vote cancel
    Usage: /vote abstain
    Usage: /vote start <subject to vote on>
    Usage: /vote start admin (used to start a vote for a new conversation admin)
    """

    # Abstains user from voting.
    if set_vote is not None and set_vote.lower() == 'abstain':
        if UtilBot.is_vote_started(event.conv_id):
            bot.send_message(event.conv, 'User {} has abstained from voting.'.format(event.user.full_name))
            if UtilBot.abstain_voter(event.conv_id, event.user.full_name):
                bot.send_message(event.conv, "The vote has ended because all voters have abstained.")
                return
        else:
            bot.send_message(event.conv, 'No vote currently in process to abstain from.')
            return

        # Check if the vote has ended
        vote_result = UtilBot.check_if_vote_finished(event.conv_id)
        if vote_result is not None:
            if vote_result != 0:
                bot.send_message(event.conv,
                                 'In the matter of: "' + UtilBot.get_vote_subject(event.conv_id) + '", the ' + (
                                     'Yeas' if vote_result > 0 else 'Nays') + ' have it.')
            else:
                bot.send_message(event.conv, "The vote ended in a tie in the matter of: {}".format(
                    UtilBot.get_vote_subject(event.conv_id)))
            UtilBot.end_vote(event.conv_id)
        return

    # Cancels the vote
    if set_vote is not None and set_vote.lower() == "cancel":
        if UtilBot.is_vote_started(event.conv_id):
            bot.send_message(event.conv, 'Vote "{}" cancelled.'.format(UtilBot.get_vote_subject(event.conv_id)))
            UtilBot.end_vote(event.conv_id)
        else:
            bot.send_message(event.conv, 'No vote currently started.')
        return

    # Starts a new vote
    if not UtilBot.is_vote_started(event.conv_id) and set_vote == "start":
        vote_subject = ' '.join(args)
        vote_callback = None

        # TODO Refactor this into a more easily extensible system.
        if vote_subject.lower().strip() == "admin":  # For the special Conversation Admin case.

            vote_subject = '{} for Conversation Admin for chat {}'.format(event.user.full_name,
                                                                          get_conv_name(event.conv))

            def set_conv_admin(won):
                if won:
                    try:
                        bot.config["conversations"][event.conv_id]["conversation_admin"] = event.user.id_[0]
                    except (KeyError, TypeError):
                        bot.config["conversations"][event.conv_id] = {}
                        bot.config["conversations"][event.conv_id]["admin"] = event.user.id_[0]
                    bot.config.save()

            vote_callback = set_conv_admin

        UtilBot.set_vote_subject(event.conv_id, vote_subject)
        UtilBot.init_new_vote(event.conv_id, event.conv.users)
        if vote_callback is not None:
            UtilBot.set_vote_callback(event.conv_id, vote_callback)
        bot.send_message(event.conv, "Vote started for subject: " + vote_subject)
        return

    # Cast a vote.
    if set_vote is not None and UtilBot.is_vote_started(event.conv_id):
        if UtilBot.can_user_vote(event.conv_id, event.user):
            set_vote = set_vote.lower()
            if set_vote == "true" or set_vote == "yes" or set_vote == "yea" or set_vote == "for" or set_vote == "yay" or set_vote == "aye":
                UtilBot.set_vote(event.conv_id, event.user.full_name, True)
            elif set_vote == "false" or set_vote == "no" or set_vote == "nay" or set_vote == "against":
                UtilBot.set_vote(event.conv_id, event.user.full_name, False)
            else:
                bot.send_message(event.conv,
                                 "{}, you did not enter a valid vote parameter.".format(event.user.full_name))
                return

            # Check if the vote has ended
            vote_result = UtilBot.check_if_vote_finished(event.conv_id)
            if vote_result is not None:
                if vote_result != 0:
                    bot.send_message(event.conv,
                                     'In the matter of: "' + UtilBot.get_vote_subject(event.conv_id) + '", the ' + (
                                         'Yeas' if vote_result > 0 else 'Nays') + ' have it.')
                else:
                    bot.send_message(event.conv, "The vote ended in a tie in the matter of: {}".format(
                        UtilBot.get_vote_subject(event.conv_id)))
                UtilBot.end_vote(event.conv_id, vote_result)
            return
        else:
            bot.send_message(event.conv_id, 'User {} is not allowed to vote.'.format(event.user.full_name))
            return

    # Check the status of a vote.
    if UtilBot.is_vote_started(event.conv_id):
        status = UtilBot.get_vote_status(event.conv_id)
        if len(status) > 1:
            bot.send_message_segments(event.conv, UtilBot.text_to_segments('\n'.join(status)))
        else:
            bot.send_message(event.conv, "No vote currently started.")
    else:
        bot.send_message(event.conv, "No vote currently started.")
Example #49
0
def remind(bot, event, *args):
    # TODO Implement a private chat feature. Have reminders save across reboots?
    """
    **Remind:**
    Usage: /remind <optional: date [defaults to today]> <optional: time [defaults to an hour from now]> <message> {/remind 1/1/15 2:00PM Call mom}
    Usage: /remind
    Usage /remind delete <index to delete> {/remind delete 1}
    Purpose: Will post a message on the date and time specified to the current chat. With no arguments, it'll list all the reminders."""

    # Show all reminders
    if len(args) == 0:
        segments = [
            hangups.ChatMessageSegment('Reminders:', is_bold=True),
            hangups.ChatMessageSegment('\n', hangups.SegmentType.LINE_BREAK)
        ]
        reminders = UtilBot.get_all_reminders(event.conv_id)
        if len(reminders) > 0:
            for x in range(0, len(reminders)):
                reminder = reminders[x]
                reminder_text = reminder[1]
                date_to_post = dateutil.parser.parse(reminder[2])
                segments.append(
                    hangups.ChatMessageSegment(
                        str(x + 1) + ' - ' +
                        date_to_post.strftime('%m/%d/%y %I:%M%p') + ' : ' +
                        reminder_text))
                segments.append(
                    hangups.ChatMessageSegment('\n',
                                               hangups.SegmentType.LINE_BREAK))
            segments.pop()
            bot.send_message_segments(event.conv, segments)
        if len(segments) <= 2:
            bot.send_message(event.conv, "No reminders set for this chat.")
        return

    # Delete a reminder
    if args[0] == 'delete':
        try:
            x = int(args[1])
            x -= 1
        except ValueError:
            bot.send_message(event.conv, 'Invalid integer: ' + args[1])
            return
        reminders = UtilBot.get_all_reminders(event.conv_id)
        reminder_to_delete_text = None
        if x in range(0, len(reminders)):
            to_delete_reminder = reminders[x]
            for running_reminder in currently_running_reminders:
                if running_reminder[1] == to_delete_reminder:
                    running_reminder[0].cancel()
        if reminder_to_delete_text:
            bot.send_message(
                event.conv,
                'Removed reminder: ' + str(reminder_to_delete_text))
        else:
            bot.send_message(event.conv,
                             'The reminder chosen is not currently running.')
        return

    # Set a new reminder
    args = list(args)
    reminder_text = ' '.join(args)
    c = parsedatetime.Calendar()
    result = c.nlp(reminder_text)
    if result is None:
        bot.send_message(
            event.conv,
            "Couldn't parse a valid date from {}'s message.".format(
                event.user.full_name))
        return
    reminder_time = result[0][0]
    reminder_text = reminder_text.replace(result[0][-1], '')
    if reminder_text.strip() == '':
        bot.send_message(event.conv, 'No reminder text set.')
        return

    current_time = datetime.now()
    if reminder_time < current_time:
        bot.send_message("Invalid Date: {}".format(
            reminder_time.strftime('%B %d, %Y %I:%M%p')))

    reminder_interval = (reminder_time - current_time).total_seconds()

    reminder_timer = threading.Timer(reminder_interval, send_reminder, [
        bot, event.conv, reminder_interval, reminder_text,
        asyncio.get_event_loop()
    ])
    UtilBot.add_reminder(event.conv_id, reminder_text, reminder_time)
    reminder_timer.start()
    currently_running_reminders.append(
        (reminder_timer, (event.conv_id, reminder_text, reminder_time)))
    bot.send_message(
        event.conv,
        "Reminder set for " + reminder_time.strftime('%B %d, %Y %I:%M%p'))
Example #50
0
def send_reminder(bot, conv, reminder_time, reminder_text, loop):
    asyncio.set_event_loop(loop)
    bot.send_message(conv, "Reminder: " + reminder_text)
    UtilBot.delete_reminder(conv.id_, reminder_text, reminder_time)
Example #51
0
def count(bot, event, *args):
    words = ' '.join(args)
    count = UtilBot.syllable_count(words)
    bot.send_message(
        event.conv, '"' + words + '"' + " has " + str(count) +
        (' syllable.' if count == 1 else ' syllables.'))