示例#1
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)))
示例#2
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")
示例#3
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.''')
示例#4
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
示例#5
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)
示例#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")
示例#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.
""")
        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)))
示例#8
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
示例#9
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)
示例#10
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)
示例#11
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))
示例#12
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())
示例#13
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)))
示例#14
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)
示例#15
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))
示例#16
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."
        )
示例#17
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)
示例#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.
""")
        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)
示例#19
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)
示例#20
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()
示例#21
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)
示例#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]
        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())
示例#23
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)
示例#24
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)
            ])
示例#25
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)
示例#26
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)
示例#27
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)
示例#28
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)
示例#29
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'])])
示例#30
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)
示例#31
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)
示例#32
0
def subverse(bot, event, *args):
    if ''.join(args) == '?':
        segments = UtilBot.text_to_segments("""\
**SubVerse**
Usage: /subverse <subverse>
Purpose: Responds with url for the specidied subverse, voat is cool right?
""")
        bot.send_message_segments(event.conv, segments)
    else:
        subverse = args[0]
        voat_url_prefix = 'https://www.voat.co/v/'
        link_url = voat_url_prefix + subverse

        user_agent = 'python:HangoutsBot:r233 (by /u/shillbert)'
        res = requests.head(link_url, headers={'User-Agent': user_agent})
        if (res.status_code == 404 or
               (res.status_code == 302 and
                'subverses/search' in res.headers.get('location'))):
            bot.send_message(event.conv, "That subverse does not exist.")
        else:
            bot.send_message_segments(event.conv,
                                      [hangups.ChatMessageSegment(link_url,
                                                                 hangups.SegmentType.LINK,
                                                                 link_target=link_url)])
示例#33
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.")
示例#34
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!
""")
        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.")
        if songs[0].artist.name == 'James Joyce':
            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])
        if len(lyrics[currmin[0]][0]) == 1:
            chopped = ""
        else:
            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
示例#35
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()
示例#36
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'))