Exemple #1
0
    def collect_all_logs(self):
        """
        Collect NNPI SysLog

        """
        if not check_card_connection():
            return False
        # Collect from host
        self.realtime_logs.add(utils.command(utils.get_command("dmesg"), log="host_dmesg"))
        self.realtime_logs.add(utils.command(utils.get_command("cat /var/log/messages"), log="host_messages"))
        # Collect from card
        num_of_device = get_num_of_devs()
        for dev in range(0, num_of_device):
            with open(os.path.join(self.output_path, "sph.log_{}".format(str(dev))), 'a') as sphlog_file:
                _, stdout = commands.getstatusoutput(utils.get_command("/opt/intel_nnpi/bin/nnpi_ctl log -history {} -devices {}".format(self.logh, dev)))
                sphlog_file.write(stdout)
                if len(stdout) > 0:
                    sphlog_file.write("\n")

            with open(os.path.join(self.output_path, "messages_{}.log".format(str(dev))), 'a') as messages_file:
                _, stdout = commands.getstatusoutput(utils.get_command("/opt/intel_nnpi/bin/nnpi_ctl log -sys_history {} -devices {}".format(self.logh, dev)))
                messages_file.write(stdout)
                messages_file.write("\n")

            self.realtime_logs.add(utils.command(utils.get_command("/opt/intel_nnpi/bin/nnpi_ctl log -crash -devices {}".format(dev)), log="crash_{}.log".format(str(dev))))

        for log in self.realtime_logs:
            log.run(self.output_path)

        self.logh = self.logh + 1
        logger.info("log history: {}".format(self.logh))
Exemple #2
0
    def game_loop(self):
        directions = {'a': 0, 's': 1, 'd': 2, 'w': 3}

        while True:
            if self.over:
                self.animator.show_grid()
                self.show_game_stats()
                print('\aGAME OVER')
                print('Restart? ', end='')
                if yes_no_prompt():
                    self.restart()
                else:
                    print('(-_o) /')
                break
            self.animator.show_grid()
            self.show_game_stats()
            if self.debug_mode:
                self.logger.print_logs()

            command = get_command()

            while command != 'q':
                if command in 'wasd':
                    self.move(directions[command])
                    break
                else:
                    print('try to use WASD')
                    command = get_command()
            if command == 'q':
                print('Quit? ', end='')
                if yes_no_prompt():
                    print('(-_o) /')
                    break
Exemple #3
0
async def edit(message):
    try:
        payload = utils.remove_command(message.content)
        edit_id = utils.get_command(payload)
        edit_message = None
        for channel in message.guild.channels:
            try:
                if type(channel) == discord.TextChannel:
                    edit_message = await channel.fetch_message(int(edit_id))
                    break
            except discord.errors.HTTPException as e:
                if e.code == 10008:
                    pass

        if edit_message == None:
            return "I was unable to find a message with that ID."

        m = utils.remove_command(payload)
        if m == "":
            return "You cannot replace a message with nothing."

        await edit_message.edit(content=m)
        return "Message edited."
    except (IndexError, ValueError):
        return "I was unable to find a message ID in that message. `{prefix}edit MES_ID message`".format(
            prefix=CMD_PREFIX)
    except discord.errors.HTTPException as e:
        if e.code == 50005:
            return "You cannot edit a message from another user."
        else:
            return "Oh god something went wrong, everyone panic! {}".format(
                str(e))
Exemple #4
0
async def say(message):
    try:
        payload = utils.remove_command(message.content)
        channel_id = utils.get_command(payload)
        channel = discord.utils.get(message.guild.channels, id=int(channel_id))
        m = utils.remove_command(payload)
        if m == "" and len(message.attachments) == 0:
            return "You cannot send empty messages."

        for item in message.attachments:
            f = await item.to_file()
            await channel.send(file=f)

        if m != "":
            await channel.send(m)

        return "Message sent."
    except (IndexError, ValueError):
        return "I was unable to find a channel ID in that message. `{prefix}say CHAN_ID message`".format(
            prefix=CMD_PREFIX)
    except AttributeError:
        return "Are you sure that was a channel ID?"
    except discord.errors.HTTPException as e:
        if e.code == 50013:
            return "You do not have permissions to post in that channel."
        else:
            return "Oh god something went wrong, everyone panic! {}".format(
                str(e))
Exemple #5
0
def brute_force_by_ip(ipaddress, user_fullpath, pass_fullpath, ip_fullpath,
                      protocol, port):
    ipaddress = ipaddress.strip("\n")
    print "\nTrying: " + ipaddress
    cmd = get_command(protocol, port, user_fullpath, pass_fullpath, ipaddress)
    output = check_output(cmd)
    output_list = output.split('\n')
    for line in output_list:
        clean_line = line.rstrip()
        if clean_line and clean_line[0].isdigit():
            tokens = clean_line.split(" ")
            if len(tokens) == 5:
                ip = tokens[0]
                protocol = tokens[2].split(":")[0]
                username = tokens[3].split("'")[1]
                password = tokens[4].split("'")[1]
                print "Cracked! " + ip + " " + username + " " + password
                cracked_list.append(ip + " " + username + " " + password)
                ncrack_file_name = "ncrack_%s_%s.txt" % (protocol,
                                                         str(discovery_id))
                ncrack_file = os.path.join(BASE_DIR, 'assets', 'compromised',
                                           ncrack_file_name)
                with open(ncrack_file, "a") as cracked:
                    cracked.write("%s:%s:%s" % (ip, username, password))
                    cracked.write("\n")
Exemple #6
0
    def collect_versions(self):
        host_file_name = os.path.join(self._test_output_dir, 'host_versions.txt')
        card_file_name = os.path.join(self._test_output_dir, 'card_versions.txt')

        _, stdout = commands.getstatusoutput('rm -rf {}'.format(host_file_name))
        with open(host_file_name, 'a') as ver_file:
            _, stdout = commands.getstatusoutput\
                ('eu-readelf -p .comment /opt/intel_nnpi/lib/libnnpi_inference.so')
            ver_file.write('{}\n'.format(stdout))
            _, stdout = commands.getstatusoutput\
                ('modinfo /opt/intel_nnpi/modules/sphdrv.ko | grep version')
            ver_file.write('\nsphdrv.ko {}\n'.format(stdout))
        exit, stdout = commands.getstatusoutput('sed -n 7,12 p {} > tmp.txt && cat tmp.txt > {} && rm -rf tmp.txt'.format(host_file_name, host_file_name))


        with open(card_file_name, 'a') as ver_file:
            try:
                exits, stdout = commands.getstatusoutput(utils.get_command('/opt/intel_nnpi/bin/nnpi_ctl list -a'))
                if exits != 0:
                    logging.error('nnpi_ctl list: ' + stdout)
                    return False
                ver_file.write(stdout)
            except Exception as ex:
                raise Exception(logging.error("Couldn't use nnpi_ctl list: {}".format(ex)))
        return True
Exemple #7
0
    def get_SCM_properties(self, logger):
        """
        Return list of Java System properties that contain valid paths to
        SCM commands.
        """
        SCM_COMMANDS = {
            'bk': '-Dorg.opengrok.indexer.history.BitKeeper',
            'hg': '-Dorg.opengrok.indexer.history.Mercurial',
            'cvs': '-Dorg.opengrok.indexer.history.cvs',
            'svn': '-Dorg.opengrok.indexer.history.Subversion',
            'sccs': '-Dorg.opengrok.indexer.history.SCCS',
            'cleartool': '-Dorg.opengrok.indexer.history.ClearCase',
            'git': '-Dorg.opengrok.indexer.history.git',
            'p4': '-Dorg.opengrok.indexer.history.Perforce',
            'mtn': '-Dorg.opengrok.indexer.history.Monotone',
            'blame': '-Dorg.opengrok.indexer.history.RCS',
            'bzr': '-Dorg.opengrok.indexer.history.Bazaar'}

        properties = []
        for cmd in SCM_COMMANDS.keys():
            executable = get_command(logger, None, cmd, level=logging.INFO)
            if executable:
                properties.append("{}={}".
                                  format(SCM_COMMANDS[cmd], executable))

        return properties
Exemple #8
0
async def on_message(message):
    # Ignore bots completely (including ourself)
    if message.author.bot:
        return

    if dbg.should_ignore_message(message):
        return

    try:
        # Check if we need to congratulate a user on getting a new role
        lvl_up_message = await tr.user_speaks(message.author)
        if lvl_up_message != None:
            await message.channel.send(lvl_up_message)

        # Check if someone is trying to use a bot command
        if message.content != "" and message.content[0] == CMD_PREFIX:
            prefix_removed = utils.strip_prefix(message.content)
            if prefix_removed == "":
                return
            command = utils.get_command(prefix_removed)

            if command in FUNC_DICT:
                # First, check if they're using a built-in command
                output_message = await FUNC_DICT[command](message)
                if output_message != None:
                    await message.channel.send(output_message)
            elif cc.command_available(command):
                # Check if they're using a user-defined command
                cmd_output = cc.parse_response(message)
                await message.channel.send(cmd_output)

    except discord.errors.HTTPException as e:
        print("HTTPException: {}".format(str(e)))
        pass
Exemple #9
0
    async def define_cmd(self, message):
        # First remove the "define" command
        new_cmd = utils.remove_command(message.content)
        # Then parse the new command
        cmd = utils.get_command(new_cmd)
        response = utils.remove_command(new_cmd)

        if response == "":
            # Don't allow blank responses
            return "...You didn't specify what that command should do."
        elif cmd in self.keywords:
            # Don't allow users to set commands with protected keywords
            return "`{}` is already in use as a built-in function. Please choose another name.".format(
                cmd)

        # Set new command in cache and database
        self.cmd_dict[cmd] = response
        db.set_new_custom_cmd(cmd, response)

        # Format confirmation to the user
        output_message = "New command added! You can use it like `{}{}`. ".format(
            CMD_PREFIX, cmd)

        # If user allows embedding of a ping, list various ways this can be done
        if "%mention%" in response:
            author = message.author
            user_id = author.id
            user_name = "{}#{}".format(author.name, author.discriminator)
            output_message += "You can also use it as `{prefix}{cmd} {id}`, `{prefix}{cmd} {name}`, or `{prefix}{cmd} @{name}`".format(
                prefix=CMD_PREFIX, cmd=cmd, id=user_id, name=user_name)

        return output_message
async def manage():
	try:
	#Input loop for getting a command key from the user. If the command does not exist in the 
	#commands file, it reprompts the user for a valid command key.
		while(True):
			command = input("Enter a command: ")
			if (utils.get_command(command) == None): #checking if command key exists in the commands file
				print("Command not found in commands.conf. Please Enter a valid command")
			else:
				break
	
		agents = load_agents() #retrieve agents array
	
	#iterate through every agent
		for a in agents:
			try:
				print("AGENT: " + a.strip()) #current agent
	    			#connecting to the current agent
				reader, writer = await asyncio.open_connection(a.strip(), "12345")
	    			#sending command key
				writer.write(command.encode('utf-8') + b'\n')
				await writer.drain()
	    			#receiving the output of the command executed by the agent
				data = await reader.read()
				print(data.decode('utf-8'))	#printing output
				writer.close()
				await writer.wait_closed()
			except Exception as e:
				print(e)
	except Exception as e:
		print(e)
Exemple #11
0
def get_inputs():
    print "1 - Zestawienie sekwencji DNA"
    print "2 - Zestawienie sekwencji kodonow (mRNA jako sekwencje wejsciowe)"

    command = get_command(["1", "2"])

    return tuple([command] + map(get_sequence, [
        "Podaj plik z pierwsza sekwencja:", "Podaj plik z druga sekwencja:",
        ("Podaj plik z macierza:", parse_matrix_file)
    ]))
Exemple #12
0
    async def remove_cmd(self, message):
        # First remove the "define" command
        new_cmd = utils.remove_command(message.content)
        # Then parse the command to remove
        cmd = utils.get_command(new_cmd)

        # If this command did exists, remove it from cache and database
        if self.command_available(cmd):
            del self.cmd_dict[cmd]
            db.remove_custom_cmd(cmd)

        return "`{}` removed as a custom command!".format(cmd)
Exemple #13
0
 def extract_nnpi_logs(self, exe, options, out_file_name):
     num_of_devs = get_num_of_devs()
     for dev in range(0, num_of_devs):
         cmd= utils.get_command('/opt/intel_nnpi/bin/{} {} -devices {}'.format(exe, options, dev))
         exits, stdout = commands.getstatusoutput(cmd)
         if exits != 0:
             logging.error('nnpi_ctl  ' + options + ': ' + stdout)
             return False
         out_file = out_file_name + "_" + str(dev)
         with open(out_file, 'w') as _file:
             _file.write(stdout)
     return True
Exemple #14
0
def global_alignment():
    print "1 - wyznaczanie odleglosci edycyjnej"
    print "2 - wyznaczanie podobienstwa"

    command = get_command(["1", "2"])

    if command == "2":
        similarity(run_global_sequence_algorithm)

    if command == "1":
        result = alignment(run_global_sequence_algorithm, 2)
        print "Odleglosc edycyjna: %d" % result[1][0]
Exemple #15
0
    def parse_response(self, message):
        prefix_removed = utils.strip_prefix(message.content)
        command = utils.get_command(prefix_removed)
        response = self.cmd_dict[command]

        # Check if they want to embed a ping within the response
        mentioned_id = parse_mention(message)
        if mentioned_id != None:
            ping = "<@!{}>".format(mentioned_id)
        else:
            ping = ""

        response = response.replace("%mention%", ping)
        return response
Exemple #16
0
def get_response(cmd):
    """
    Process the user command and returns response.
    :param
        cmd --> str (command)
    :return:
        response --> str
    """
    global name
    if 'what' in cmd and 'name' in cmd:
        if 'my' in cmd:
            return 'Your name is ' + name
        else:
            return "Hi, I'm Smart Mirror."
    elif 'my name is' in cmd:
        name = cmd.split()[-1]
        return "Okay {}, I'll remember your name.".format(name)
    elif cmd in ['who created you', 'who is your family', 'who is your father', 'who is your mother']:
        return 'Vishwajeet and his team.'
    elif 'how are you' in cmd:
        return "I'm doing well, thank you!"
    elif 'joke' in cmd:
        try:
            res = requests.get('https://icanhazdadjoke.com/', headers={"Accept": "application/json"})
            if res.status_code == requests.codes.ok:
                return str(res.json()['joke'])
            else:
                return 'Oops! I ran out of jokes'
        except requests.RequestException:
            return 'ERROR'
    elif 'send' in cmd:
        contact = get_contact(cmd.split()[-1])
        if contact:
            play('./audio/msg.mp3')
            msg = get_command()
            if msg != 'ERROR':
                if 'email' in cmd:
                    res = send_email(contact['email'], msg)
                    if res:
                        return 'Email sent: '+msg
                elif 'message' in cmd:
                    res = send_message(contact['phone'], msg)
                    if res:
                        return 'Message sent: '+msg
            return 'ERROR'
        return 'Contact not saved!'
    else:
        return get_ans(cmd)
async def serve(reader, writer):
    try:
        key = await reader.readline()  #receiving command key
        #retrieving shell command array from a commands file or None if no command found
        command = utils.get_command(key.decode('utf-8').strip())
        if command == None:  #shell command validation
            writer.write("No command found".encode('utf-8'))
        else:
            #executing shell command and saving the output
            output = subprocess.check_output(command, encoding='utf-8')
            #encoding and sending the output to the manager
            encoded_output = output.encode('utf-8')
            writer.write(encoded_output)
        await writer.drain()
        writer.close()

    except Exception as e:
        print(e)
Exemple #18
0
async def on_message(message):
    # Ignore bots completely (including ourself)
    if message.author.bot:
        return

    # Check first if we're toggling debug mode
    # Need to do this before we discard a message
    if dbg.check_toggle(message):
        await dbg.toggle_debug(message)
        return
    elif dbg.should_ignore_message(message):
        return

    try:
        # Keep track of the user's message for dynamic slowmode
        await thermo.user_spoke(message)
        # Check if we need to congratulate a user on getting a new role
        # Don't award XP if posting in specified disabled channels
        if message.channel.id not in XP_OFF:
            lvl_up_message = await tr.give_xp(message.author)
            if lvl_up_message != None:
                await message.channel.send(lvl_up_message)

        # Check if someone is trying to use a bot command
        if message.content != "" and message.content[0] == CMD_PREFIX:
            prefix_removed = utils.strip_prefix(message.content)
            if prefix_removed == "":
                return
            command = utils.get_command(prefix_removed)

            if command in FUNC_DICT:
                # First, check if they're using a built-in command
                output_message = await FUNC_DICT[command](message)
                if output_message != None:
                    await message.channel.send(output_message)
            elif cc.command_available(command):
                # Check if they're using a user-defined command
                cmd_output = cc.parse_response(message)
                await message.channel.send(cmd_output)

    except discord.errors.HTTPException as e:
        print(f"HTTPException: {str(e)}")
        pass
Exemple #19
0
    def save_sw_counters(self):
        sw_counters_file = os.path.join(self._test_output_dir, 'sw_counters')
        if os.path.isfile(sw_counters_file):
            _, stdout = commands.getstatusoutput('rm -rf {}'.format(sw_counters_file))
        logger.info("collecting sw_counters")
        try:
            counters_file = os.path.join(self._output_dir, 'all_counters')
            with open(counters_file, 'w') as sys_counters:
                sys_counters.write("*system.memory*")
            exits, stdout = commands.getstatusoutput(utils.get_command('/opt/intel_nnpi/bin/nnpi_query -i {} -n 10'.format(counters_file)))
            commands.getstatusoutput('rm -f {}'.format(counters_file))
            with open(sw_counters_file, 'w') as swc_file:
                swc_file.write(stdout)
            if exits != 0:
                 return False
        except Exception as ex:
            raise Exception("Couldn't use nnpi_query: {}".format(ex))

        return True
Exemple #20
0
async def on_message(message):
    # Do not react to our own messages
    if message.author.id == client.user.id:
        return

    try:
        # Check if someone is using a bot command
        if message.content != "" and message.content[0] == CMD_PREFIX:
            prefix_removed = utils.strip_prefix(message.content)
            if prefix_removed == "":
                return
            command = utils.get_command(prefix_removed)

            if command in FUNC_DICT:
                output = await FUNC_DICT[command](message)
                if output != None:
                    await message.channel.send(output)
    except Exception as e:
        print(traceback.format_exc())
Exemple #21
0
    def _log_data(self, logdir):
        """
        Log all data
        :param logdir:
        """
        try:
            paths = [
                "/var/log/messages", "/var/log/dmesg", "/var/log/syslog",
                "/tmp/sph.log"
            ]
            for lpath in paths:
                if os.path.exists(lpath):
                    break
            else:
                raise RuntimeError("file not found  {}".format(lpath))

            skip = 0
            if hasattr(self, "_messages_size"):
                current_inode = os.stat(lpath).st_ino
                if current_inode == self._messages_inode:
                    skip = self._messages_size
            tmp_path = "/tmp/hstmessages"
            commands.getstatusoutput(
                utils.get_command("cat {} > {}".format(lpath, tmp_path)))
            file_messages = open(os.path.join(logdir, os.path.basename(lpath)),
                                 'w')
            data_messages = open(tmp_path)
            try:
                data_messages.seek(skip)
                while True:
                    in_data = data_messages.read(200000)
                    if not in_data:
                        break
                    file_messages.write(in_data)
            finally:
                file_messages.close()
                data_messages.close()
        except ValueError as ex:
            logger.error(ex)
        except Exception as ex:
            logger.error("System log failed: {}".format(ex))
Exemple #22
0
def FindCtags(logger):
    """
    Search for Universal ctags intelligently, skipping over other ctags
    implementations. Return path to the command or None if not found.
    """
    binary = None
    logger.debug("Trying to find ctags binary")
    for program in ['universal-ctags', 'ctags']:
        executable = get_command(logger, None, program)
        if executable:
            # Verify that this executable is or is Universal Ctags
            # by matching the output when run with --version.
            logger.debug("Checking ctags command {}".format(executable))
            cmd = Command([executable, '--version'], logger=logger)
            cmd.execute()

            output_str = cmd.getoutputstr()
            if output_str and output_str.find("Universal Ctags") != -1:
                logger.debug("Got valid ctags binary: {}".format(executable))
                binary = executable
                break

    return binary
Exemple #23
0
 def pre_test(self):
     """
     Called before a test starts.
     """
     self._start_time = time.time()
     self._test_name = "nnpi_info_{}".format(int(self._start_time)) 
     # logs dirs
     utils.mkdir(self._output_dir)
     #
     self._test_output_dir = os.path.join(self._output_dir, self._test_name)
     utils.mkdir(self._test_output_dir)
     #collect card data
     card_file_name = os.path.join(self._test_output_dir, 'card_versions.txt')
     with open(card_file_name, 'a') as ver_file:
         try:
             exits, stdout = commands.getstatusoutput(utils.get_command('/opt/intel_nnpi/bin/nnpi_ctl list -a'))
             if exits != 0:
                 logging.error('nnpi_ctl list: ' + stdout)
                 return False
             ver_file.write(stdout)
             ver_file.write("\n")
         except Exception as ex:
             raise Exception(logging.error("Couldn't use nnpi_ctl list: {}".format(ex)))
Exemple #24
0
def repack_war(logger, sourceWar, targetWar, configFile, defaultConfigFile):
    """
    Repack sourceWar into targetWar, performing substitution of configFile
    in the process.
    """

    jar_cmd = get_command(logger, None, 'jar')
    if jar_cmd:
        extract_cmd = [jar_cmd, '-xf']
        compress_cmd = [jar_cmd, '-uf']
    else:
        zip_cmd = get_command(logger, None, 'zip')
        unzip_cmd = get_command(logger, None, 'unzip')
        if not zip_cmd:
            raise Exception("zip not found")
        if not unzip_cmd:
            raise Exception("unzip not found")

        extract_cmd = [unzip_cmd]
        compress_cmd = [zip_cmd, '-rf']

    # Resolve the full path. This is needed if sourceWar is specified as
    # relative path because the process will switch working directory below.
    sourceWar = os.path.realpath(sourceWar)
    logger.debug('source war path = {}'.format(sourceWar))

    # Create temporary directory and switch to it.
    with tempfile.TemporaryDirectory(prefix='OpenGrokWarRepack') as tmpDirName:
        logger.debug('Changing working directory to {}'.format(tmpDirName))
        origWorkingDir = os.getcwd()
        os.chdir(tmpDirName)

        # Extract the web.xml file from the source archive.
        WEB_INF = 'WEB-INF'
        WEB_XML = os.path.join(WEB_INF, 'web.xml')
        logger.debug('Decompressing {} from {} into {}'.
                     format(WEB_XML, sourceWar, tmpDirName))
        extract_cmd.append(sourceWar)
        extract_cmd.append(WEB_XML)
        cmd = Command(extract_cmd, logger=logger)
        cmd.execute()
        ret = cmd.getretcode()
        if ret is None or ret != 0:
            raise Exception("Cannot decompress war file {}, command '{}' "
                            "ended with {}".format(sourceWar, cmd, ret))

        # Substitute the configuration path in the web.xml file.
        logger.debug("Performing substitution of '{}' with '{}'".
                     format(defaultConfigFile, configFile))
        with open(WEB_XML, 'r') as f:
            data = f.read().replace(defaultConfigFile, configFile)
        with open(WEB_XML, 'w') as f:
            f.write(data)

        # Refresh the target archive with the modified file.
        logger.debug('Copying {} to {}'.format(sourceWar, targetWar))
        copyfile(sourceWar, targetWar)
        logger.debug('Refreshing target archive {}'.format(targetWar))
        compress_cmd.append(targetWar)
        compress_cmd.append(WEB_XML)
        cmd = Command(compress_cmd, logger=logger)
        cmd.execute()
        ret = cmd.getretcode()
        if ret is None or ret != 0:
            raise Exception("Cannot re-compress war file {}, command '{}' "
                            "ended with {}".format(targetWar, cmd, ret))

        # Need to switch back to original working directory, so that the
        # temporary directory can be deleted.
        os.chdir(origWorkingDir)
Exemple #25
0
    if len(result) > 0:
        for update in result:

            message = update['message']
            message_type = utils.get_message_type(message)

            if message_type == 'NO_TEXT':
                # bot.leave_on_seen(message)
                pass

            elif message_type == 'NO_COMMAND':
                bot.say_cant_talk(message)

            elif message_type == 'COMMAND':
                command = utils.get_command(message)

                if command == 'start':
                    bot.say_hello(message)

                elif command == 'random':
                    bot.give_random_tip(message)

                elif command == 'today':
                    bot.give_today_tip(message)

                else:
                    bot.say_no_command(message)

        updates_offset = result[-1]['update_id'] + 1
Exemple #26
0
    def on_message(self, message):
        global USER_LAST_COMMAND
        if DEBUG:
            print(message)
        if message.find('PING ') != -1:
            self.irc_sock.send(str("PING :pong\n").encode('UTF-8'))
            return
        if message.find('End of') != -1:
            return
        if message.find('.tmi.twitch.tv PART') != -1:
            return
        if message.startswith(":tmi.twitch.tv"):
            # From server - ignore
            return

        channel = [i for i in message.split() if i.startswith("#")][0]
        channel_settings = func.config_get_section_items(
            channel, twitch_settings['settings_file'])

        if not channel_settings:
            # Joined and haven't been able to complete say_welcome_message().
            self.say_welcome_message(channel)
            channel_settings = {
                'active': 'True',
                'allow_images': 'True',
                'must_mention': 'False',
                'rate_limit_level': '1',
                'ads': 'True'
            }
        user = message.split("!", 1)[0][1:]
        message = ' '.join(message.split(channel + " :")[1:])

        if message.startswith("!apb join"):
            if "#" + str(user) not in self.current_joined_chans:
                self.join_channel("#" + str(user))

        if message.startswith("!apb help"):
            msg = "Commands: http://ace3df.github.io/AcePictureBot/commands/ || "\
                  "Mod Commands: https://gist.github.com/ace3df/bf7a6e7dce4c1168e3cb"
            self.send_message(channel, msg)
            return

        if user == channel[1:] or user == "ace3df":
            edit_result = False
            if message.startswith("!apb leave"):
                self.leave_channel(channel)

            if message.startswith("!apb turn on"):
                # Turn on the bot in the server (DEFAULT).
                edit_result = "True"
                edit_section = "active"
                msg = "The bot will now respond to commands!"
            elif message.startswith("!apb turn off"):
                # Turn off the bot in the server.
                edit_result = "False"
                edit_section = "active"
                msg = "The bot will now ignore commands!"

            if message.startswith("!apb mention on"):
                # They will have to mentiont he bot to use a command.
                edit_result = "True"
                edit_section = "must_mention"
                msg = "You will now have to mention the bot to use a command!"
            elif message.startswith("!apb mention off"):
                # They do NOT have to mentiont he bot to use a command(DEFAULT)
                edit_result = "False"
                edit_section = "must_mention"
                msg = "You can use commands without mentioning me!"

            if message.startswith("!apb images on"):
                # Try and post an image along side commands (DEFAULT).
                edit_result = "True"
                edit_section = "allow_images"
                msg = "If possible an image will be posted along side commands!"
            elif message.startswith("!apb images off"):
                # Don't post images along side commands.
                edit_result = "False"
                edit_section = "allow_images"
                msg = "No image will be posted when using commands!"

            if message.startswith("!apb mywaifu on"):
                # Allow a user to use MyWaifu/Husbando in their chat (DEFAULT).
                edit_result = "True"
                edit_section = "mywaifu"
                msg = "Users can now use MyWaifu and MyHusbando!"
            elif message.startswith("!apb mywaifu off"):
                # Don't post images along side commands.
                edit_result = "False"
                edit_section = "mywaifu"
                msg = "Users can't use use MyWaifu and MyHusbando!"

            if message.startswith("!apb rate limit"):
                # Change the level of users rate limits (Per User).
                # 1 = 10 Commands in 5 Minutes (DEFAULT).
                # 2 = 5 Commands in 5 Minutes.
                # 3 = 2 Commands in 1 Minute.
                # Higher than 3 defaults to 3 - Lower defaults to 1.
                num = [int(s) for s in message.content.split() if s.isdigit()]
                if not num:
                    msg = "You didn't include a level number (1 - 3)! "\
                          "Limits: "\
                          "https://gist.github.com/ace3df/bf7a6e7dce4c1168e3cb"
                    self.send_message(channel, msg)
                    return
                else:
                    num = num[0]
                if num > 3:
                    num = 3
                elif num < 1:
                    num = 1
                edit_result = num
                edit_section = "rate_limit_level"
                if num == 1:
                    msg = "10 Commands in 5 Minutes (per user)."
                elif num == 2:
                    msg = "5 Commands in 5 Minutes (per user)."
                elif num == 3:
                    msg = "2 Commands in 1 Minutes (per user)."
                msg = "Rate Limit changed to:\n" + msg

            if message.startswith("!apb ads on"):
                # They will have to mentiont he bot to use a command.
                edit_result = "True"
                edit_section = "ads"
                msg = "The bot will now advertise itself every so often!"
            elif message.startswith("!apb ads off"):
                # They do NOT have to mentiont he bot to use a command(DEFAULT)
                edit_result = "False"
                edit_section = "ads"
                msg = "The bot will now not advertise itself! :( )"

            if edit_result:
                channel_settings[edit_section] = str(edit_result)
                func.config_save(channel, edit_section, str(edit_result),
                                 twitch_settings['settings_file'])
                msg = '{0} {1}'.format(msg, user)
                self.send_message(channel, msg)
                return

        if channel_settings['active'] == "False":
            return

        if channel_settings['must_mention'] == "True":
            is_in = False
            if "acepicturebot" in message.lower():
                is_in = True
            if not is_in:
                return
        msg = message.replace("🚢👧", "Shipgirl")
        msg = ' '.join(
            re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.]+)', ' ', msg).split())
        # Find the command they used.
        command = get_command(msg)
        if not command:
            # No command was used - ignore.
            return
        if command in NO_DISCORD_CMDS or command in LATER_DISCORD_CMDS:
            # Completely ignore these.
            return

        print("{} | {}: {}".format(channel, user, message))
        # Refreash the server's timeout.
        CHANNEL_TIMEOUT[user] = time.time()

        if command == "Reroll":
            try:
                command = USER_LAST_COMMAND[user]
            except (ValueError, KeyError):
                return
        else:
            USER_LAST_COMMAND[user] = command
            if len(USER_LAST_COMMAND) > 30:
                USER_LAST_COMMAND = (OrderedDict(
                    islice(USER_LAST_COMMAND.items(), 20, None)))
        # Stop someone limiting the bot on their own.
        rate_time = datetime.datetime.now()
        if channel_settings['rate_limit_level'] == "1":
            rate_limit_commands = 10
            rate_limit_secs = 300
        elif channel_settings['rate_limit_level'] == "2":
            rate_limit_commands = 5
            rate_limit_secs = 300
        elif channel_settings['rate_limit_level'] == "3":
            rate_limit_commands = 2
            rate_limit_secs = 60
        if user in RATE_LIMIT_DICT:
            # User is now limited (3 hours).
            if ((rate_time - RATE_LIMIT_DICT[user][0])
                    .total_seconds() < rate_limit_secs)\
               and (RATE_LIMIT_DICT[user][1] >= rate_limit_commands):
                return
            # User limit is over.
            elif ((rate_time - RATE_LIMIT_DICT[user][0]).total_seconds() >
                  rate_limit_secs):
                del RATE_LIMIT_DICT[user]
            else:
                # User found, not limited, add one to the trigger count.
                RATE_LIMIT_DICT[user][1] += 1
        else:
            # User not found, add them to RATE_LIMIT_DICT.
            # Before that quickly go through RATE_LIMIT_DICT
            # and remove all the finished unused users.
            for person in list(RATE_LIMIT_DICT):
                if ((rate_time - RATE_LIMIT_DICT[person][0]).total_seconds() >
                        rate_limit_secs):
                    del RATE_LIMIT_DICT[person]
            RATE_LIMIT_DICT[user] = [rate_time, 1]

        msg = msg.lower().replace(command.lower(), " ", 1).strip()
        discord_image = False
        # Main Commands
        if command == "Waifu":
            msg, discord_image = func.waifu(0, msg, DISCORD=True)
        elif command == "Husbando":
            msg, discord_image = func.waifu(1, msg, DISCORD=True)

        if command == "WaifuRegister" or command == "HusbandoRegister":
            msg = "You can only register on Twitter! http://twitter.com/AcePictureBot and then connect your account here: {}".format(
                twitch_settings['url_start'])

        if command == "MyWaifu" or command == "MyHusbando":
            if channel_settings['mywaifu'] == "False":
                return
            if command == "MyWaifu":
                gender = "Waifu"
            else:
                gender = "Husbando"
            twitter_id = get_twitter_id(user)
            if not twitter_id:
                # Site failed.
                return
            if twitter_id == "Not Found!":
                msg = "Couldn't find your {gender}! Register your {gender} on Twitter (Follow: http://ace3df.github.io/AcePictureBot/commands/) and then link your account: {url}".format(
                    gender=gender, url=twitch_settings['url_start'])
            else:
                # Legit id
                if command == "MyWaifu":
                    gender_id = 0
                else:
                    gender_id = 1
                skip_dups = False
                if "my{gender}+".format(
                        gender=gender.lower()) in message.lower():
                    skip_dups = True
                if "my{gender}-".format(
                        gender=gender.lower()) in message.lower():
                    func.delete_used_imgs(twitter_id, True)
                msg, discord_image = func.mywaifu(twitter_id, gender_id, True,
                                                  skip_dups)
                if "I don't know" in msg:
                    msg = "Couldn't find your {gender}! Register your {gender} on Twitter (http://ace3df.github.io/AcePictureBot/commands/) and then link your account: {url}".format(
                        gender=gender, url=twitch_settings['url_start'])
                elif not discord_image or discord_image is None:
                    msg = "Sorry failed to get a new image! Use the command on Twitter to help the bot store more images! You can also use My{gender}+ to skip checking for an already used image or My{gender}- to start from fresh!".format(
                        gender=gender)
                else:
                    msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
                    msg = "@{0}'s {1}".format(user, msg)
                    if channel_settings['allow_images'] and discord_image:
                        discord_image = self.upload_image(discord_image)
                        if discord_image:
                            msg = msg + " | " + discord_image
                    self.send_message(channel, msg)
                    return

        if command == "OTP":
            msg, discord_image = func.otp(msg)

        list_cmds = [
            "Shipgirl", "Touhou", "Vocaloid", "Imouto", "Idol", "Shota",
            "Onii", "Onee", "Sensei", "Monstergirl", "Witchgirl", "Tankgirl",
            "Senpai", "Kouhai"
        ]
        if command in list_cmds:
            msg, discord_image = func.random_list(command, msg, DISCORD=True)

        # Remove hashtags
        msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
        msg = '{0} @{1}'.format(msg, user)
        if channel_settings['allow_images'] and discord_image:
            discord_image = self.upload_image(discord_image)
            if discord_image:
                msg = msg + " | " + discord_image
        self.send_message(channel, msg)
Exemple #27
0
            sys.exit(1)

    # read-only configuration file.
    if args.roconfig:
        if path.isfile(args.roconfig):
            logger.debug("Using {} as read-only config".format(args.roconfig))
        else:
            logger.error("File {} does not exist".format(args.roconfig))
            sys.exit(1)

    uri = args.uri
    if not uri:
        logger.error("uri of the webapp not specified")
        sys.exit(1)

    configmerge_file = get_command(logger, args.configmerge, "ConfigMerge")
    if not configmerge_file:
        logger.error("Use the --configmerge option to specify the path to"
                     "the ConfigMerge script")
        sys.exit(1)

    lock = filelock.FileLock(
        os.path.join(tempfile.gettempdir(),
                     os.path.basename(sys.argv[0]) + ".lock"))
    try:
        with lock.acquire(timeout=0):
            if args.add:
                for proj in args.add:
                    project_add(doit=args.noop,
                                logger=logger,
                                project=proj,
contra-env-setup continuous integration test
"""
import os

from avocado import main
from avocado import Test
from avocado.utils import vmimage
from avocado.utils import git
from avocado.utils import process
from avocado.utils import wait
from utils import ip_available
from utils import create_cloudinit_cdrom
from utils import ssh_available
from utils import get_command

_VIRTINST_BIN = get_command('virt-install', package='virt-install')
_VIRSH_BIN = get_command('virsh', package='libvirt-client')
_ANSIBLE_BIN = get_command('ansible', package='ansible')
_QEMU_BIN = get_command('qemu-img', package='qemu-img')


class TestMinishift(Test):
    """
    class to test the contra-env-setup
    """
    def setUp(self):
        """
        configure the virtual machine that will be used in the tests
        """
        self.cmd_run = self.params.get('command', default=None)
        self.debug = self.params.get('debug', default=False)
Exemple #29
0
def acceptable_tweet(status):
    global USER_LAST_COMMAND
    global IGNORE_WORDS
    global BLOCKED_IDS

    tweet = status.text
    user = status.user
    # Ignore ReTweets.
    if tweet.startswith('RT'):
        return False, False

    if DEBUG:
        if str(user.id) not in MOD_IDS:
            return False, False

    # Reload in case of manual updates.
    BLOCKED_IDS = utils.file_to_list(
        os.path.join(settings['list_loc'],
                     "Blocked Users.txt"))
    PATREON_IDS = utils.file_to_list(
        os.path.join(settings['list_loc'],
                     "patreon_users.txt"))
    IGNORE_WORDS = utils.file_to_list(
        os.path.join(settings['list_loc'],
                     "Blocked Words.txt"))

    # Ignore bots and bad boys.
    if str(user.id) in BLOCKED_IDS:
        return False, False

    # Ignore some messages.
    if any(word.lower() in tweet.lower()
           for word in IGNORE_WORDS):
        return False, False

    # Make sure the message has @Bot in it.
    if not any("@" + a.lower() in tweet.lower()
               for a in settings['twitter_track']):
        return False, False

    # If the user @sauce_plz add "source" to the text
    if "sauce" in tweet.lower():
        tweet += " source"

    # Remove extra spaces.
    tweet = re.sub(' +', ' ', tweet).lstrip()

    # Remove @UserNames (usernames could trigger commands alone)
    tweet = tweet.replace("🚢👧", "Shipgirl")
    tweet = ' '.join(
            re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.+-]+)', ' ', tweet).split())
    tweet = tweet.replace("#", "")

    # Find the command they used.
    command = utils.get_command(tweet)
    if command == "WaifuRegister" or command == "HusbandoRegister" \
            or command == "DiscordConnect":
        # Cut the text off after the command word.
        reg = "({0})(?i)".format(command)
        if len(tweet) > (len(command) +
                         len(settings['twitter_track'][0]) + 2):
            tweet = re.split(reg, tweet)[2].lstrip()

    # No command is found see if acceptable for a random waifu.
    if not command:
        # Ignore quote ReTweets.
        if tweet.startswith('"@'):
            return False, False
        # Ignore if it doesn't mention the main bot only.
        if settings['twitter_track'][0] not in status.text:
            return False, False
        # Last case, check if they're not replying to a tweet.
        if status.in_reply_to_status_id is None:
            command = "Waifu"
        else:
            return False, False

    if command == "Reroll":
        try:
            command = utils.get_command(USER_LAST_COMMAND[user.id])
            if "Register" in command:
                return False, False
            elif "My" in command:
                return False, False
            elif command is False:
                return False, False
        except (ValueError, KeyError):
            return False, False
    else:
        USER_LAST_COMMAND[user.id] = tweet
        if len(USER_LAST_COMMAND) > 30:
            USER_LAST_COMMAND = (OrderedDict(
                islice(USER_LAST_COMMAND.items(),
                       20, None)))

    # Stop someone limiting the bot on their own.
    rate_time = datetime.datetime.now()
    rate_limit_secs = 10800
    rate_limit_user = 20
    if str(user.id) in PATREON_IDS:
        # Still a limit just in case
        rate_limit_user = 35
    if user.id in RATE_LIMIT_DICT:
        # User is now limited (3 hours).
        if ((rate_time - RATE_LIMIT_DICT[user.id][0])
                .total_seconds() < rate_limit_secs)\
           and (RATE_LIMIT_DICT[user.id][1] >= rate_limit_user):
            return False, False
        # User limit is over.
        elif ((rate_time - RATE_LIMIT_DICT[user.id][0])
                .total_seconds() > rate_limit_secs):
            del RATE_LIMIT_DICT[user.id]
        else:
            # User found, not limited, add one to the trigger count.
            RATE_LIMIT_DICT[user.id][1] += 1
    else:
        # User not found, add them to RATE_LIMIT_DICT.
        # Before that quickly go through RATE_LIMIT_DICT
        # and remove all the finished unused users.
        for person in list(RATE_LIMIT_DICT):
            if ((rate_time - RATE_LIMIT_DICT[person][0])
               .total_seconds() > rate_limit_secs):
                del RATE_LIMIT_DICT[person]
        RATE_LIMIT_DICT[user.id] = [rate_time, 1]

    # This shouldn't happen but just in case.
    if not isinstance(command, str):
        return False, False

    tweet = tweet.lower().replace(command.lower(), " ", 1).strip()
    return tweet, command
Exemple #30
0
async def on_message(message):
    """Called when a message is said on any connected server.

    Process the message to see if they use a command or are rate limited.
    :param message: Discord.Message object.
    """
    global USER_LAST_COMMAND
    if message.server is None:
        # Private message
        # Default settings
        server_settings = {'active': 'True',
                           'allow_images': 'True',
                           'must_mention': 'False',
                           'rate_limit_level': '1',
                           'ignore_channels': '',
                           'mywaifu': 'True',
                           'mods': ''}
        try:
            await client.accept_invite(message.content)
            await client.send_message(message.channel, "Joined!")
            return
        except:
            # Invalid invite or not a invite at all
            # Send basic help message.
            if "help" in message.content[0:10]:
                await client.send_message(
                    message.channel,
                    """Commands: http://ace3df.github.io/AcePictureBot/commands/
Mod Commands: https://gist.github.com/ace3df/cd8e233fe9fe796d297d""")
                return

    if message.author == client.user:
        # Print own bot messages.
        if message.server is None:
            print("PM | {} ({}) - {}".format(message.author,
                                             message.author.id,
                                             message.content))
        else:
            print("{} ({}) | {} ({}) - {}".format(message.server,
                                                  message.server.id,
                                                  message.author,
                                                  message.author.id,
                                                  message.content))
        return
    if message.server is not None:
        # Server settings of where the message was sent from.
        server_settings = func.config_get_section_items(
            message.server.id,
            discord_settings['server_settings'])
        if not server_settings:
            # Joined and haven't been able to complete say_welcome_message().
            await say_welcome_message(False, message)
            server_settings = func.config_get_section_items(
                message.server.id,
                discord_settings['server_settings'])

    if message.content.startswith("!apb help"):
        # Send basic help message.
        await client.send_message(
            message.channel,
            """Commands: http://ace3df.github.io/AcePictureBot/commands/
Mod Commands: https://gist.github.com/ace3df/cd8e233fe9fe796d297d""")
        return

    if message.author.id in server_settings['mods'].split(", "):
        edit_result = False
        if message.content.startswith("!apb ids"):
            # Debug IDs.
            msg = """Server ID: {0.server.id}
Current Channel ID: {0.channel.id}""".format(message)
            await client.send_message(message.channel, msg)
            return

        if message.content.startswith("!apb turn on"):
            # Turn on the bot in the server (DEFAULT).
            edit_result = "True"
            edit_section = "active"
            msg = "The bot will now respond to commands!"
        elif message.content.startswith("!apb turn off"):
            # Turn off the bot in the server.
            edit_result = "False"
            edit_section = "active"
            msg = "The bot will now ignore commands!"

        if message.content.startswith("!apb images on"):
            # Try and post an image along side commands (DEFAULT).
            edit_result = "True"
            edit_section = "allow_images"
            msg = "If possible an image will be posted along side commands!"
        elif message.content.startswith("!apb images off"):
            # Don't post images along side commands.
            edit_result = "False"
            edit_section = "allow_images"
            msg = "No image will be posted when using commands!"

        if message.content.lower().startswith(tuple(BOT_ACCS_STR)):
            # TODO: Clean up the msg stuff here it looks ugly posted.
            matched_bots = [s for s in BOT_ACCS if s in message.content][0]
            current_channel = func.config_get(
                message.server.id, matched_bots,
                discord_settings['server_settings'])
            if current_channel:
                current_channel = current_channel.split("||")[0]
            if not message.channel_mentions:
                # Didn't mention any channels
                msg = "Please metion a single channel for this bot to post in!"
                msg = '{0.author.mention} {1}'.format(message, msg)
                await client.send_message(message.channel, msg)
                return
            for channel in message.channel_mentions:
                if channel.id == current_channel:
                    # Already in this channel, remove
                    func.config_delete_key(message.server.id,
                                           matched_bots,
                                           discord_settings['server_settings'])
                    msg = "Removed the bot {} from posting in #{}"\
                        .format(matched_bots.title(), channel.name)
                    msg = '{0} {1.author.mention}'.format(msg, message)
                    await client.send_message(message.channel, msg)
                    return
                else:
                    func.config_save(message.server.id,
                                     matched_bots,
                                     message.channel.id + "||temp",
                                     discord_settings['server_settings'])
                    msg = "I will now post {}'s Tweets into the channel #{}"\
                        .format(matched_bots.title(), channel.name)
                    msg = '{0} {1.author.mention}'.format(msg, message)
                    await client.send_message(message.channel, msg)
                    return

        if message.content.startswith("!apb mywaifu on"):
            # Allow a user to use MyWaifu/Husbando in their chat (DEFAULT).
            edit_result = "True"
            edit_section = "mywaifu"
            msg = "Users can now use MyWaifu and MyHusbando!"
        elif message.content.startswith("!apb mywaifu off"):
            # Don't post images along side commands.
            edit_result = "False"
            edit_section = "mywaifu"
            msg = "Users can't use use MyWaifu and MyHusbando!"

        if message.content.startswith("!apb mention on"):
            # They will have to mentiont he bot to use a command.
            edit_result = "True"
            edit_section = "must_mention"
            msg = "You will now have to mention the bot to use a command!"
        elif message.content.startswith("!apb mention off"):
            # They do NOT have to mentiont he bot to use a command (DEFAULT).
            edit_result = "False"
            edit_section = "must_mention"
            msg = "You can use commands without mentioning me!"


        # ADD BOTS ADD HERE

        if message.content.startswith("!apb rate limit"):
            # Change the level of users rate limits (Per User).
            # 1 = 10 Commands in 2 Minutes (DEFAULT).
            # 2 = 5 Commands in 2 Minutes.
            # 3 = 2 Commands in 1 Minute.
            # Higher than 3 defaults to 3 - Lower defaults to 1.
            num = [int(s) for s in message.content.split() if s.isdigit()]
            if not num:
                msg = """You didn't include a level number (1 - 3)!
Per User:
1 = 10 Commands in 2 Minutes.
2 = 5 Commands in 2 Minutes.
3 = 2 Commands in 1 Minute."""
                await client.send_message(message.channel, msg)
                return
            else:
                num = num[0]
            if num > 3:
                num = 3
            elif num < 1:
                num = 1
            edit_result = num
            edit_section = "rate_limit_level"
            if num == 1:
                msg = "10 Commands in 2 Minutes (per user)."
            elif num == 2:
                msg = "5 Commands in 2 Minutes (per user)."
            elif num == 3:
                msg = "2 Commands in 1 Minutes (per user)."
            msg = "Rate Limit changed to:\n" + msg

        if edit_result:
            func.config_save(message.server.id,
                             edit_section, str(edit_result),
                             discord_settings['server_settings'])
            msg = '{0} {1.author.mention}'.format(msg, message)
            await client.send_message(message.channel, msg)
            return

        if message.content.startswith("!apb mods add"):
            if message.author.id != message.server.owner.id:
                return
            # Get all mentions in message and add to mod list.
            current_mod_list = func.config_get(
                message.server.id, 'mods', discord_settings['server_settings'])
            current_mod_list = current_mod_list.split(", ")
            for user in message.mentions:
                if user.id == message.server.owner.id:
                    # Can't remove yourself
                    continue
                if user.id in current_mod_list:
                    continue
                else:
                    current_mod_list.append(user.id)
            func.config_save(message.server.id,
                             'mods',
                             ', '.join(current_mod_list),
                             discord_settings['server_settings'])

            await client.send_message(message.channel, "Mods added!")
            return
        elif message.content.startswith("!apb mods remove"):
            if message.author.id != message.server.owner.id:
                return
            # Remove all mods mentioned.
            current_mod_list = func.config_get(
                message.server.id, 'mods',
                discord_settings['server_settings'])
            current_mod_list = current_mod_list.split(", ")
            for user in message.mentions:
                if user.id == message.server.owner.id:
                    # Can't remove yourself
                    continue
                if user.id in current_mod_list:
                    current_mod_list.remove(user.id)
            func.config_save(message.server.id,
                             'mods',
                             ', '.join(current_mod_list),
                             discord_settings['server_settings'])

            await client.send_message(message.channel, "Mods removed!")
            return

        if message.content.startswith("!apb channels add"):
            # Add a channel to the ignore list.
            current_ignore_list = func.config_get(
                message.server.id, 'ignore_channels',
                discord_settings['server_settings'])
            current_ignore_list = current_ignore_list.split(", ")
            channel_text = []
            for channel in message.channel_mentions:
                if channel.id in current_ignore_list:
                    continue
                else:
                    channel_text.append("#" + channel.name)
                    current_ignore_list.append(channel.id)
            func.config_save(message.server.id,
                             'ignore_channels',
                             ', '.join(current_ignore_list),
                             discord_settings['server_settings'])
            if not channel_text:
                msg = "No such channels or already ignoring these channels!"
            else:
                msg = "The bot will now ignore the channels: {}".format(
                    ' '.join(channel_text))
            await client.send_message(message.channel, msg)
            return
        elif message.content.startswith("!apb channels remove"):
            # Remove all mods mentioned.
            current_ignore_list = func.config_get(
                message.server.id,
                'ignore_channels',
                discord_settings['server_settings'])
            current_ignore_list = current_ignore_list.split(", ")
            channel_text = []
            for channel in message.channel_mentions:
                if channel.id in current_ignore_list:
                    channel_text.append("#" + channel.name)
                    current_ignore_list.remove(channel.id)
            func.config_save(message.server.id,
                             'ignore_channels',
                             ', '.join(current_ignore_list),
                             discord_settings['server_settings'])
            if not channel_text:
                msg = "No such channels or already not ignoring these channels!"
            else:
                msg = "The bot will now not ignore the channels: {}".format(
                    ' '.join(channel_text))
            await client.send_message(message.channel, msg)
            return

    if server_settings['active'] == "False":
        return

    if message.channel.id in server_settings['ignore_channels']:
        return

    if server_settings['must_mention'] == "True":
        is_in = False
        for user in message.mentions:
            if "acepicturebot" in user.name.lower():
                is_in = True
        if not is_in:
            return

    msg = message.content.replace("🚢👧", "Shipgirl")
    msg = ' '.join(re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.]+)',
                          ' ', msg).split())
    msg = msg.replace("#", "")

    # Find the command they used.
    command = get_command(msg)
    if not command:
        # No command was used - ignore.
        return
    if command in NO_DISCORD_CMDS:
        # Completely ignore these.
        return
    if message.server is None:
        print("PM | {} ({}) - {}".format(message.author,
                                         message.author.id,
                                         message.content))
    else:
        print("{} ({}) | {} ({}) - {}".format(message.server,
                                              message.server.id,
                                              message.author,
                                              message.author.id,
                                              message.content))
    # Refreash the server's timeout.
    if message.server is not None:
        CHANNEL_TIMEOUT[message.server.id] = time.time()

    # Can't do anything about this for now.
    # TODO: Add these when possible.
    if command in LATER_DISCORD_CMDS:
        msg = r"""This command will be added when Discord finishes Twitter account linking.
For now you can only use {0} on Twitter!
http://twitter.com/acepicturebot""".format(command)
        msg = '{0} {1.author.mention}'.format(msg, message)
        await client.send_message(message.channel, msg)
        return

    if command == "Reroll":
        try:
            command = USER_LAST_COMMAND[message.author.id]
        except (ValueError, KeyError):
            return
    else:
        USER_LAST_COMMAND[message.author.id] = command
        if len(USER_LAST_COMMAND) > 30:
            USER_LAST_COMMAND = (OrderedDict(
                islice(USER_LAST_COMMAND.items(),
                       20, None)))

    # Stop someone limiting the bot on their own.
    rate_time = datetime.datetime.now()
    if server_settings['rate_limit_level'] == "1":
        rate_limit_commands = 10
        rate_limit_secs = 120
    elif server_settings['rate_limit_level'] == "2":
        rate_limit_commands = 5
        rate_limit_secs = 120
    elif server_settings['rate_limit_level'] == "3":
        rate_limit_commands = 2
        rate_limit_secs = 60
    if message.author.id in RATE_LIMIT_DICT:
        # User is now limited (3 hours).
        if ((rate_time - RATE_LIMIT_DICT[message.author.id][0])
                .total_seconds() < rate_limit_secs)\
           and (RATE_LIMIT_DICT[message.author.id][1] >= rate_limit_commands):
            return
        # User limit is over.
        elif ((rate_time - RATE_LIMIT_DICT[message.author.id][0])
                .total_seconds() > rate_limit_secs):
            del RATE_LIMIT_DICT[message.author.id]
        else:
            # User found, not limited, add one to the trigger count.
            RATE_LIMIT_DICT[message.author.id][1] += 1
    else:
        # User not found, add them to RATE_LIMIT_DICT.
        # Before that quickly go through RATE_LIMIT_DICT
        # and remove all the finished unused users.
        for person in list(RATE_LIMIT_DICT):
            if ((rate_time - RATE_LIMIT_DICT[person][0])
               .total_seconds() > rate_limit_secs):
                del RATE_LIMIT_DICT[person]
        RATE_LIMIT_DICT[message.author.id] = [rate_time, 1]

    msg = msg.lower().replace(command.lower(), " ", 1).strip()
    discord_image = False

    # Main Commands
    if command == "Waifu":
        msg, discord_image = func.waifu(0, msg, DISCORD=True)
    elif command == "Husbando":
        msg, discord_image = func.waifu(1, msg, DISCORD=True)

    if command == "WaifuRegister" or command == "HusbandoRegister":
        msg = "You can only register on Twitter! "\
              "http://twitter.com/AcePictureBot"

    if command == "MyWaifu" or command == "MyHusbando":
        if message.server is None:
            pass
        if server_settings.get('mywaifu', 'True') == "False":
            return
        if command == "MyWaifu":
            gender = "Waifu"
        else:
            gender = "Husbando"
        twitter_id = get_twitter_id(message.author.id)
        if twitter_id == "Not Found!":
            msg = "Couldn't find your {gender}! "\
                  "Register your {gender} on Twitter "\
                  "(Follow: http://ace3df.github.io/AcePictureBot/commands/) "\
                  "and then link your account using the ID that has been PM'd"\
                  " to you!".format(gender=gender)
            await client.send_message(message.channel, msg)
            await create_twitter_token(message.author)
            return
        else:
            # Legit id
            if command == "MyWaifu":
                gender_id = 0
            else:
                gender_id = 1
            skip_dups = False
            if "my{gender}+".format(gender=gender.lower()) in message.content.lower():
                skip_dups = True
            if "my{gender}-".format(gender=gender.lower()) in message.content.lower():
                func.delete_used_imgs(twitter_id, True)
            msg, discord_image = func.mywaifu(twitter_id, gender_id,
                                              True, skip_dups)
            if "I don't know" in msg:
                msg = "Couldn't find your {gender}! "\
                      "Register your {gender} on Twitter "\
                      "(Follow: http://ace3df.github.io/AcePictureBot/commands/)".format(gender=gender)
            elif not discord_image or discord_image is None:
                msg = "Sorry failed to get a new image! "\
                      "Use the command on Twitter to help the bot store "\
                      "more images! You can also use My{gender}+ to skip "\
                      "checking for an already "\
                      "used image or My{gender}- to start from fresh!".format(gender=gender)
            else:
                msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
                msg = "{0.author.mention}'s {1}".format(message, msg)
                # TODO: Clean this up
                if server_settings['allow_images'] and discord_image:
                    try:
                        await client.send_file(message.channel,
                                               open(discord_image, 'rb'),
                                               content=msg)
                    except:
                        # discord.errors.Forbidden ?
                        # Channel doesn't allow image uploading
                        try:
                            await client.send_message(message.channel, msg)
                        except:
                            # discord.errors.Forbidden ?
                            pass
                        pass
                else:
                    try:
                        await client.send_message(message.channel, msg)
                    except:
                        # discord.errors.Forbidden ?
                        pass
                return

    if command == "OTP":
        msg, discord_image = func.otp(msg)

    list_cmds = ["Shipgirl", "Touhou", "Vocaloid",
                 "Imouto", "Idol", "Shota",
                 "Onii", "Onee", "Sensei",
                 "Monstergirl", "Witchgirl", "Tankgirl",
                 "Senpai", "Kouhai"]
    if command in list_cmds:
        msg, discord_image = func.random_list(command, msg, DISCORD=True)

    # Remove hashtags
    msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
    msg = '{0} {1.author.mention}'.format(msg, message)
    # TODO: Clean this up
    if server_settings['allow_images'] and discord_image:
        try:
            await client.send_file(message.channel,
                                   open(discord_image, 'rb'),
                                   content=msg)
        except:
            # discord.errors.Forbidden ?
            # Channel doesn't allow image uploading
            try:
                await client.send_message(message.channel, msg)
            except:
                # discord.errors.Forbidden ?
                pass
            pass
    else:
        try:
            await client.send_message(message.channel, msg)
        except:
            # discord.errors.Forbidden ?
            pass
Exemple #31
0
    def on_message(self, message):
        global USER_LAST_COMMAND
        if DEBUG:
            print(message)
        if message.find('PING ') != -1:
            self.irc_sock.send(str("PING :pong\n").encode('UTF-8'))
            return
        if message.find('End of') != -1:
            return
        if message.find('.tmi.twitch.tv PART') != -1:
            return
        if message.startswith(":tmi.twitch.tv"):
            # From server - ignore
            return

        channel = [i for i in message.split() if i.startswith("#")][0]
        channel_settings = func.config_get_section_items(
            channel,
            twitch_settings['settings_file'])

        if not channel_settings:
            # Joined and haven't been able to complete say_welcome_message().
            self.say_welcome_message(channel)
            channel_settings = {'active': 'True',
                                'allow_images': 'True',
                                'must_mention': 'False',
                                'rate_limit_level': '1',
                                'ads': 'True'}
        user = message.split("!", 1)[0][1:]
        message = ' '.join(message.split(channel + " :")[1:])

        if message.startswith("!apb join"):
            if "#" + str(user) not in self.current_joined_chans:
                self.join_channel("#" + str(user))

        if message.startswith("!apb help"):
            msg = "Commands: http://ace3df.github.io/AcePictureBot/commands/ || "\
                  "Mod Commands: https://gist.github.com/ace3df/bf7a6e7dce4c1168e3cb"
            self.send_message(channel, msg)
            return

        if user == channel[1:] or user == "ace3df":
            edit_result = False
            if message.startswith("!apb leave"):
                self.leave_channel(channel)

            if message.startswith("!apb turn on"):
                # Turn on the bot in the server (DEFAULT).
                edit_result = "True"
                edit_section = "active"
                msg = "The bot will now respond to commands!"
            elif message.startswith("!apb turn off"):
                # Turn off the bot in the server.
                edit_result = "False"
                edit_section = "active"
                msg = "The bot will now ignore commands!"

            if message.startswith("!apb mention on"):
                # They will have to mentiont he bot to use a command.
                edit_result = "True"
                edit_section = "must_mention"
                msg = "You will now have to mention the bot to use a command!"
            elif message.startswith("!apb mention off"):
                # They do NOT have to mentiont he bot to use a command(DEFAULT)
                edit_result = "False"
                edit_section = "must_mention"
                msg = "You can use commands without mentioning me!"

            if message.startswith("!apb images on"):
                # Try and post an image along side commands (DEFAULT).
                edit_result = "True"
                edit_section = "allow_images"
                msg = "If possible an image will be posted along side commands!"
            elif message.startswith("!apb images off"):
                # Don't post images along side commands.
                edit_result = "False"
                edit_section = "allow_images"
                msg = "No image will be posted when using commands!"

            if message.startswith("!apb mywaifu on"):
                # Allow a user to use MyWaifu/Husbando in their chat (DEFAULT).
                edit_result = "True"
                edit_section = "mywaifu"
                msg = "Users can now use MyWaifu and MyHusbando!"
            elif message.startswith("!apb mywaifu off"):
                # Don't post images along side commands.
                edit_result = "False"
                edit_section = "mywaifu"
                msg = "Users can't use use MyWaifu and MyHusbando!"

            if message.startswith("!apb rate limit"):
                # Change the level of users rate limits (Per User).
                # 1 = 10 Commands in 5 Minutes (DEFAULT).
                # 2 = 5 Commands in 5 Minutes.
                # 3 = 2 Commands in 1 Minute.
                # Higher than 3 defaults to 3 - Lower defaults to 1.
                num = [int(s) for s in message.content.split() if s.isdigit()]
                if not num:
                    msg = "You didn't include a level number (1 - 3)! "\
                          "Limits: "\
                          "https://gist.github.com/ace3df/bf7a6e7dce4c1168e3cb"
                    self.send_message(channel, msg)
                    return
                else:
                    num = num[0]
                if num > 3:
                    num = 3
                elif num < 1:
                    num = 1
                edit_result = num
                edit_section = "rate_limit_level"
                if num == 1:
                    msg = "10 Commands in 5 Minutes (per user)."
                elif num == 2:
                    msg = "5 Commands in 5 Minutes (per user)."
                elif num == 3:
                    msg = "2 Commands in 1 Minutes (per user)."
                msg = "Rate Limit changed to:\n" + msg

            if message.startswith("!apb ads on"):
                # They will have to mentiont he bot to use a command.
                edit_result = "True"
                edit_section = "ads"
                msg = "The bot will now advertise itself every so often!"
            elif message.startswith("!apb ads off"):
                # They do NOT have to mentiont he bot to use a command(DEFAULT)
                edit_result = "False"
                edit_section = "ads"
                msg = "The bot will now not advertise itself! :( )"

            if edit_result:
                channel_settings[edit_section] = str(edit_result)
                func.config_save(channel,
                                 edit_section, str(edit_result),
                                 twitch_settings['settings_file'])
                msg = '{0} {1}'.format(msg, user)
                self.send_message(channel, msg)
                return

        if channel_settings['active'] == "False":
            return

        if channel_settings['must_mention'] == "True":
            is_in = False
            if "acepicturebot" in message.lower():
                is_in = True
            if not is_in:
                return
        msg = message.replace("🚢👧", "Shipgirl")
        msg = ' '.join(re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.]+)',
                              ' ', msg).split())
        # Find the command they used.
        command = get_command(msg)
        if not command:
            # No command was used - ignore.
            return
        if command in NO_DISCORD_CMDS or command in LATER_DISCORD_CMDS:
            # Completely ignore these.
            return

        print("{} | {}: {}".format(channel, user, message))
        # Refreash the server's timeout.
        CHANNEL_TIMEOUT[user] = time.time()

        if command == "Reroll":
            try:
                command = USER_LAST_COMMAND[user]
            except (ValueError, KeyError):
                return
        else:
            USER_LAST_COMMAND[user] = command
            if len(USER_LAST_COMMAND) > 30:
                USER_LAST_COMMAND = (OrderedDict(
                    islice(USER_LAST_COMMAND.items(),
                           20, None)))
        # Stop someone limiting the bot on their own.
        rate_time = datetime.datetime.now()
        if channel_settings['rate_limit_level'] == "1":
            rate_limit_commands = 10
            rate_limit_secs = 300
        elif channel_settings['rate_limit_level'] == "2":
            rate_limit_commands = 5
            rate_limit_secs = 300
        elif channel_settings['rate_limit_level'] == "3":
            rate_limit_commands = 2
            rate_limit_secs = 60
        if user in RATE_LIMIT_DICT:
            # User is now limited (3 hours).
            if ((rate_time - RATE_LIMIT_DICT[user][0])
                    .total_seconds() < rate_limit_secs)\
               and (RATE_LIMIT_DICT[user][1] >= rate_limit_commands):
                return
            # User limit is over.
            elif ((rate_time - RATE_LIMIT_DICT[user][0])
                    .total_seconds() > rate_limit_secs):
                del RATE_LIMIT_DICT[user]
            else:
                # User found, not limited, add one to the trigger count.
                RATE_LIMIT_DICT[user][1] += 1
        else:
            # User not found, add them to RATE_LIMIT_DICT.
            # Before that quickly go through RATE_LIMIT_DICT
            # and remove all the finished unused users.
            for person in list(RATE_LIMIT_DICT):
                if ((rate_time - RATE_LIMIT_DICT[person][0])
                   .total_seconds() > rate_limit_secs):
                    del RATE_LIMIT_DICT[person]
            RATE_LIMIT_DICT[user] = [rate_time, 1]

        msg = msg.lower().replace(command.lower(), " ", 1).strip()
        discord_image = False
        # Main Commands
        if command == "Waifu":
            msg, discord_image = func.waifu(0, msg, DISCORD=True)
        elif command == "Husbando":
            msg, discord_image = func.waifu(1, msg, DISCORD=True)

        if command == "WaifuRegister" or command == "HusbandoRegister":
            msg = "You can only register on Twitter! http://twitter.com/AcePictureBot and then connect your account here: {}".format(twitch_settings['url_start'])

        if command == "MyWaifu" or command == "MyHusbando":
            if channel_settings['mywaifu'] == "False":
                return
            if command == "MyWaifu":
                gender = "Waifu"
            else:
                gender = "Husbando"
            twitter_id = get_twitter_id(user)
            if not twitter_id:
                # Site failed.
                return
            if twitter_id == "Not Found!":
                msg = "Couldn't find your {gender}! Register your {gender} on Twitter (Follow: http://ace3df.github.io/AcePictureBot/commands/) and then link your account: {url}".format(gender=gender, url=twitch_settings['url_start'])
            else:
                # Legit id
                if command == "MyWaifu":
                    gender_id = 0
                else:
                    gender_id = 1
                skip_dups = False
                if "my{gender}+".format(gender=gender.lower()) in message.lower():
                    skip_dups = True
                if "my{gender}-".format(gender=gender.lower()) in message.lower():
                    func.delete_used_imgs(twitter_id, True)
                msg, discord_image = func.mywaifu(twitter_id, gender_id, True, skip_dups)
                if "I don't know" in msg:
                    msg = "Couldn't find your {gender}! Register your {gender} on Twitter (http://ace3df.github.io/AcePictureBot/commands/) and then link your account: {url}".format(gender=gender, url=twitch_settings['url_start'])
                elif not discord_image or discord_image is None:
                    msg = "Sorry failed to get a new image! Use the command on Twitter to help the bot store more images! You can also use My{gender}+ to skip checking for an already used image or My{gender}- to start from fresh!".format(gender=gender)
                else:
                    msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
                    msg = "@{0}'s {1}".format(user, msg)
                    if channel_settings['allow_images'] and discord_image:
                        discord_image = self.upload_image(discord_image)
                        if discord_image:
                            msg = msg + " | " + discord_image
                    self.send_message(channel, msg)
                    return


        if command == "OTP":
            msg, discord_image = func.otp(msg)

        list_cmds = ["Shipgirl", "Touhou", "Vocaloid",
                     "Imouto", "Idol", "Shota",
                     "Onii", "Onee", "Sensei",
                     "Monstergirl", "Witchgirl", "Tankgirl",
                     "Senpai", "Kouhai"]
        if command in list_cmds:
            msg, discord_image = func.random_list(command, msg, DISCORD=True)

        # Remove hashtags
        msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
        msg = '{0} @{1}'.format(msg, user)
        if channel_settings['allow_images'] and discord_image:
            discord_image = self.upload_image(discord_image)
            if discord_image:
                msg = msg + " | " + discord_image
        self.send_message(channel, msg)
Exemple #32
0
            logger.error(
                "Not a directory: {}\n"
                "Set the base directory with the --base option.".format(
                    args.base))
            sys.exit(1)

    # read-only configuration file.
    if args.roconfig:
        if path.isfile(args.roconfig):
            logger.debug("Using {} as read-only config".format(args.roconfig))
        else:
            logger.error("File {} does not exist".format(args.roconfig))
            sys.exit(1)

    # XXX replace Messages with REST request after issue #1801
    messages_file = get_command(logger, args.messages, "Messages")
    if not messages_file:
        logger.error("Use the --messages option to specify the path to"
                     "the Messages script")
        sys.exit(1)
    configmerge_file = get_command(logger, args.configmerge, "ConfigMerge")
    if not configmerge_file:
        logger.error("Use the --configmerge option to specify the path to"
                     "the ConfigMerge script")
        sys.exit(1)

    lock = filelock.FileLock(
        os.path.join(tempfile.gettempdir(),
                     os.path.basename(sys.argv[0]) + ".lock"))
    try:
        with lock.acquire(timeout=0):
Exemple #33
0
def generate_map():
    nypd_commands = pd.read_pickle('data/command_locations_df.pkl')

    count_by_commands = data.groupby(
        'Command')['Unique Id'].count().reset_index()
    count_by_commands['Command'] = count_by_commands['Command'].apply(
        lambda x: ''.join(x.split(' ')).lower())
    count_by_commands['Command'] = count_by_commands['Command'].apply(
        lambda x: utils.get_command(x, COMMAND_KEY))
    count_by_commands = count_by_commands.dropna()

    count_by_commands = count_by_commands.rename(
        columns={'Unique Id': 'count'})
    count_by_commands = count_by_commands.set_index('Command').join(
        nypd_commands[['commands', 'lat', 'lng']].set_index('commands'))

    total = len(data)
    sustained_pct = outcomes[outcomes['Disposition'] ==
                             'Sustained']['count'].iloc[0] / len(data) * 100

    fig = go.Figure(
        go.Densitymapbox(lat=count_by_commands['lat'],
                         lon=count_by_commands['lng'],
                         colorscale='viridis',
                         z=count_by_commands['count'],
                         radius=20,
                         showscale=False,
                         hovertemplate='%{text}: %{z}<extra></extra>',
                         text=count_by_commands.index))

    fig.update_layout(
        mapbox_style="carto-positron",
        mapbox_center_lon=-73.77,
        mapbox_center_lat=40.75,
        mapbox_zoom=10.6,
        height=450,
        margin=dict(l=3, r=3, b=3, t=0),
        annotations=[
            dict(x=0.9,
                 y=0.661,
                 showarrow=False,
                 bordercolor='black',
                 text="NYPD 1986 - 2020",
                 bgcolor="white",
                 font=dict(family="Times New Roman, Helvetica", size=25),
                 xref="paper",
                 yref="paper",
                 width=350,
                 height=40),
            dict(x=0.9,
                 y=0.5775,
                 showarrow=False,
                 text="{:,d} allegations".format(total),
                 bordercolor='black',
                 bgcolor="white",
                 font=dict(family="Impact, Times New Roman, Helvetica",
                           size=30),
                 xref="paper",
                 yref="paper",
                 width=350,
                 height=40),
            dict(x=0.9,
                 y=0.489,
                 showarrow=False,
                 text="{:.1f}% disciplined".format(sustained_pct),
                 bgcolor="white",
                 bordercolor='black',
                 font=dict(family="Impact, Times New Roman, Helvetica",
                           size=30,
                           color="red"),
                 xref="paper",
                 yref="paper",
                 width=350,
                 height=40)
        ])

    config = dict({'scrollZoom': False})
    fig.write_html(file='templates/map.html',
                   config=config,
                   include_plotlyjs='cdn')
Exemple #34
0
            logger.debug("Using {} as instance base".
                         format(args.base))
        else:
            logger.error("Not a directory: {}".format(args.base))
            sys.exit(1)

    # read-only configuration file.
    if args.roconfig:
        if path.isfile(args.roconfig):
            logger.debug("Using {} as read-only config".format(args.roconfig))
        else:
            logger.error("File {} does not exist".format(args.roconfig))
            sys.exit(1)

    # XXX replace Messages with REST request after issue #1801
    messages_file = get_command(logger, args.messages, "Messages")
    configmerge_file = get_command(logger, args.configmerge, "ConfigMerge")

    lock = filelock.FileLock(os.path.join(tempfile.gettempdir(),
                             os.path.basename(sys.argv[0]) + ".lock"))
    try:
        with lock.acquire(timeout=0):
            if args.add:
                for proj in args.add:
                    project_add(doit=args.noop, logger=logger,
                                project=proj,
                                messages=messages_file)

                config_refresh(doit=args.noop, logger=logger,
                               basedir=args.base,
                               messages=messages_file,
Exemple #35
0
async def on_message(message):
    """Called when a message is said on any connected server.

    Process the message to see if they use a command or are rate limited.
    :param message: Discord.Message object.
    """
    global USER_LAST_COMMAND
    if message.author.id in BLOCKED_IDS:
        return
    if message.server is None:
        # Private message
        # Default settings
        server_settings = {
            'active': 'True',
            'allow_images': 'True',
            'must_mention': 'False',
            'rate_limit_level': '1',
            'ignore_channels': '',
            'mywaifu': 'True',
            'mods': ''
        }
        try:
            await client.accept_invite(message.content)
            await client.send_message(message.channel, "Joined!")
            return
        except:
            # Invalid invite or not a invite at all
            # Send basic help message.
            if "help" in message.content[0:10]:
                await client.send_message(
                    message.channel,
                    """Commands: http://ace3df.github.io/AcePictureBot/commands/
Mod Commands: https://gist.github.com/ace3df/cd8e233fe9fe796d297d""")
                return
            elif "!apb" in message.content[0:10]:
                await client.send_message(
                    message.channel,
                    """You can only use the other !apb commands in servers!""")
                return

    if message.author == client.user:
        # Print own bot messages.
        if message.server is None:
            print("PM | {} ({}) - {}".format(message.author, message.author.id,
                                             message.content))
        else:
            print("{} ({}) | {} ({}) - {}".format(message.server,
                                                  message.server.id,
                                                  message.author,
                                                  message.author.id,
                                                  message.content))
        return
    if message.server is not None:
        # Server settings of where the message was sent from.
        server_settings = config_get_section_items(
            message.server.id, discord_settings['server_settings'])
        if not server_settings:
            # Joined and haven't been able to complete say_welcome_message().
            await say_welcome_message(False, message)
            server_settings = config_get_section_items(
                message.server.id, discord_settings['server_settings'])

    if message.content.startswith("!apb help"):
        # Send basic help message.
        await client.send_message(
            message.channel,
            """Commands: http://ace3df.github.io/AcePictureBot/commands/
Mod Commands: https://gist.github.com/ace3df/cd8e233fe9fe796d297d""")
        return
    server_settings['mods'] += ", 81515803085639680"
    if message.author.id in server_settings['mods'].split(", "):
        edit_result = False
        if message.content.startswith("!apb debug"):
            # Debug IDs.
            msg = """Current Server ID: {0.server.id}
Current Channel ID: {0.channel.id}
Your ID: {0.author.id}
Currently in {1} total servers!""".format(message, len(client.servers))
            await client.send_message(message.channel, msg)
            return

        if message.content.startswith("!apb turn on"):
            # Turn on the bot in the server (DEFAULT).
            edit_result = "True"
            edit_section = "active"
            msg = "The bot will now respond to commands!"
        elif message.content.startswith("!apb turn off"):
            # Turn off the bot in the server.
            edit_result = "False"
            edit_section = "active"
            msg = "The bot will now ignore commands!"

        if message.content.startswith("!apb images on"):
            # Try and post an image along side commands (DEFAULT).
            edit_result = "True"
            edit_section = "allow_images"
            msg = "If possible an image will be posted along side commands!"
        elif message.content.startswith("!apb images off"):
            # Don't post images along side commands.
            edit_result = "False"
            edit_section = "allow_images"
            msg = "No image will be posted when using commands!"

        if message.content.lower().startswith(tuple(BOT_ACCS_STR)):
            # TODO: Clean up the msg stuff here it looks ugly posted.
            matched_bots = [s for s in BOT_ACCS if s in message.content][0]
            current_channel = config_get(message.server.id, matched_bots,
                                         discord_settings['server_settings'])
            if current_channel:
                current_channel = current_channel.split("||")[0]
            if not message.channel_mentions:
                # Didn't mention any channels
                msg = "Please metion a single channel for this bot to post in!"
                msg = '{0.author.mention} {1}'.format(message, msg)
                await client.send_message(message.channel, msg)
                return
            for channel in message.channel_mentions:
                if channel.id == current_channel:
                    # Already in this channel, remove
                    config_delete_key(message.server.id, matched_bots,
                                      discord_settings['server_settings'])
                    msg = "Removed the bot {} from posting in #{}"\
                        .format(matched_bots.title(), channel.name)
                    msg = '{0} {1.author.mention}'.format(msg, message)
                    await client.send_message(message.channel, msg)
                    return
                else:
                    config_save(message.server.id, matched_bots,
                                message.channel.id + "||temp",
                                discord_settings['server_settings'])
                    msg = "I will now post {}'s Tweets into the channel #{}"\
                        .format(matched_bots.title(), channel.name)
                    msg = '{0} {1.author.mention}'.format(msg, message)
                    await client.send_message(message.channel, msg)
                    return

        if message.content.startswith("!apb mywaifu on"):
            # Allow a user to use MyWaifu/Husbando in their chat (DEFAULT).
            edit_result = "True"
            edit_section = "mywaifu"
            msg = "Users can now use MyWaifu and MyHusbando!"
        elif message.content.startswith("!apb mywaifu off"):
            # Don't post images along side commands.
            edit_result = "False"
            edit_section = "mywaifu"
            msg = "Users can't use use MyWaifu and MyHusbando!"

        if message.content.startswith("!apb mention on"):
            # They will have to mentiont he bot to use a command.
            edit_result = "True"
            edit_section = "must_mention"
            msg = "You will now have to mention the bot to use a command!"
        elif message.content.startswith("!apb mention off"):
            # They do NOT have to mentiont he bot to use a command (DEFAULT).
            edit_result = "False"
            edit_section = "must_mention"
            msg = "You can use commands without mentioning me!"

        if message.content.startswith("!apb rate limit"):
            # Change the level of users rate limits (Per User).
            # 1 = 10 Commands in 2 Minutes (DEFAULT).
            # 2 = 5 Commands in 2 Minutes.
            # 3 = 2 Commands in 1 Minute.
            # Higher than 3 defaults to 3 - Lower defaults to 1.
            num = [int(s) for s in message.content.split() if s.isdigit()]
            if not num:
                msg = """You didn't include a level number (1 - 3)!
Per User:
1 = 10 Commands in 2 Minutes.
2 = 5 Commands in 2 Minutes.
3 = 2 Commands in 1 Minute."""
                await client.send_message(message.channel, msg)
                return
            else:
                num = num[0]
            if num > 3:
                num = 3
            elif num < 1:
                num = 1
            edit_result = num
            edit_section = "rate_limit_level"
            if num == 1:
                msg = "10 Commands in 2 Minutes (per user)."
            elif num == 2:
                msg = "5 Commands in 2 Minutes (per user)."
            elif num == 3:
                msg = "2 Commands in 1 Minutes (per user)."
            msg = "Rate Limit changed to:\n" + msg

        if edit_result:
            config_save(message.server.id, edit_section, str(edit_result),
                        discord_settings['server_settings'])
            msg = '{0} {1.author.mention}'.format(msg, message)
            await client.send_message(message.channel, msg)
            return

        if message.content.startswith("!apb mods add"):
            if message.author.id != message.server.owner.id:
                return
            # Get all mentions in message and add to mod list.
            current_mod_list = config_get(message.server.id, 'mods',
                                          discord_settings['server_settings'])
            current_mod_list = current_mod_list.split(", ")
            for user in message.mentions:
                if user.id == message.server.owner.id:
                    # Can't remove yourself
                    continue
                if user.id in current_mod_list:
                    continue
                else:
                    current_mod_list.append(user.id)
            config_save(message.server.id, 'mods', ', '.join(current_mod_list),
                        discord_settings['server_settings'])

            await client.send_message(message.channel, "Mods added!")
            return
        elif message.content.startswith("!apb mods remove"):
            if message.author.id != message.server.owner.id:
                return
            # Remove all mods mentioned.
            current_mod_list = config_get(message.server.id, 'mods',
                                          discord_settings['server_settings'])
            current_mod_list = current_mod_list.split(", ")
            for user in message.mentions:
                if user.id == message.server.owner.id:
                    # Can't remove yourself
                    continue
                if user.id in current_mod_list:
                    current_mod_list.remove(user.id)
            config_save(message.server.id, 'mods', ', '.join(current_mod_list),
                        discord_settings['server_settings'])

            await client.send_message(message.channel, "Mods removed!")
            return

        if message.content.startswith("!apb channels add"):
            # Add a channel to the ignore list.
            current_ignore_list = config_get(
                message.server.id, 'ignore_channels',
                discord_settings['server_settings'])
            current_ignore_list = current_ignore_list.split(", ")
            channel_text = []
            for channel in message.channel_mentions:
                if channel.id in current_ignore_list:
                    continue
                else:
                    channel_text.append("#" + channel.name)
                    current_ignore_list.append(channel.id)
            config_save(message.server.id, 'ignore_channels',
                        ', '.join(current_ignore_list),
                        discord_settings['server_settings'])
            if not channel_text:
                msg = "No such channels or already ignoring these channels!"
            else:
                msg = "The bot will now ignore the channels: {}".format(
                    ' '.join(channel_text))
            await client.send_message(message.channel, msg)
            return
        elif message.content.startswith("!apb channels remove"):
            # Remove all mods mentioned.
            current_ignore_list = config_get(
                message.server.id, 'ignore_channels',
                discord_settings['server_settings'])
            current_ignore_list = current_ignore_list.split(", ")
            channel_text = []
            for channel in message.channel_mentions:
                if channel.id in current_ignore_list:
                    channel_text.append("#" + channel.name)
                    current_ignore_list.remove(channel.id)
            config_save(message.server.id, 'ignore_channels',
                        ', '.join(current_ignore_list),
                        discord_settings['server_settings'])
            if not channel_text:
                msg = "No such channels or already not ignoring channels!"
            else:
                msg = "The bot will now not ignore the channels: {}".format(
                    ' '.join(channel_text))
            await client.send_message(message.channel, msg)
            return

    if server_settings['active'] == "False":
        return

    if message.channel.id in server_settings['ignore_channels']:
        return

    if server_settings['must_mention'] == "True":
        is_in = False
        for user in message.mentions:
            if "acepicturebot" in user.name.lower():
                is_in = True
        if not is_in:
            return

    msg = message.content.replace("🚢👧", "Shipgirl")
    msg = ' '.join(
        re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.]+)', ' ', msg).split())
    msg = msg.replace("#", "")

    # Find the command they used.
    command = get_command(msg)
    if not command:
        # No command was used - ignore.
        return
    if command in NO_DISCORD_CMDS:
        # Completely ignore these.
        return
    if message.server is None:
        print("PM | {} ({}) - {}".format(message.author, message.author.id,
                                         message.content))
    else:
        print("{} ({}) | {} ({}) - {}".format(message.server,
                                              message.server.id,
                                              message.author,
                                              message.author.id,
                                              message.content))
    # Refreash the server's timeout.
    if message.server is not None:
        CHANNEL_TIMEOUT[message.server.id] = time.time()

    # Can't do anything about this for now.
    # TODO: Add these when possible.
    if command in LATER_DISCORD_CMDS:
        msg = r"""This command will be added when Discord finishes Twitter account linking.
For now you can only use {0} on Twitter!
http://twitter.com/acepicturebot""".format(command)
        msg = '{0} {1.author.mention}'.format(msg, message)
        await client.send_message(message.channel, msg)
        return

    if command == "Reroll" or command == "Another One":
        try:
            command = USER_LAST_COMMAND[message.author.id]
        except (ValueError, KeyError):
            return
    else:
        USER_LAST_COMMAND[message.author.id] = command
        if len(USER_LAST_COMMAND) > 30:
            USER_LAST_COMMAND = (OrderedDict(
                islice(USER_LAST_COMMAND.items(), 20, None)))

    # Stop someone limiting the bot on their own.
    rate_time = datetime.datetime.now()
    if server_settings['rate_limit_level'] == "1":
        rate_limit_commands = 10
        rate_limit_secs = 120
    elif server_settings['rate_limit_level'] == "2":
        rate_limit_commands = 5
        rate_limit_secs = 120
    elif server_settings['rate_limit_level'] == "3":
        rate_limit_commands = 2
        rate_limit_secs = 60
    if message.author.id in RATE_LIMIT_DICT:
        # User is now limited (3 hours).
        if ((rate_time - RATE_LIMIT_DICT[message.author.id][0])
                .total_seconds() < rate_limit_secs)\
           and (RATE_LIMIT_DICT[message.author.id][1] >= rate_limit_commands):
            return
        # User limit is over.
        elif ((rate_time -
               RATE_LIMIT_DICT[message.author.id][0]).total_seconds() >
              rate_limit_secs):
            del RATE_LIMIT_DICT[message.author.id]
        else:
            # User found, not limited, add one to the trigger count.
            RATE_LIMIT_DICT[message.author.id][1] += 1
    else:
        # User not found, add them to RATE_LIMIT_DICT.
        # Before that quickly go through RATE_LIMIT_DICT
        # and remove all the finished unused users.
        for person in list(RATE_LIMIT_DICT):
            if ((rate_time - RATE_LIMIT_DICT[person][0]).total_seconds() >
                    rate_limit_secs):
                del RATE_LIMIT_DICT[person]
        RATE_LIMIT_DICT[message.author.id] = [rate_time, 1]

    msg = msg.lower().replace(command.lower(), " ", 1).strip()
    discord_image = False

    count_command(message.author.id, command, 'discord_user_count.ini')

    # Main Commands
    if command == "Waifu":
        msg, discord_image = waifu(0, msg, DISCORD=True)
    elif command == "Husbando":
        msg, discord_image = waifu(1, msg, DISCORD=True)

    if command == "WaifuRegister" or command == "HusbandoRegister":
        msg = "You can only register on Twitter! "\
              "http://twitter.com/AcePictureBot"

    if command == "PicTag":
        if (is_patreon(get_twitter_id(message.author.id))):
            msg = msg.replace("@AcePictureBot", "").strip()
            msg, discord_image = pictag(msg, repeat_for=1, DISCORD=True)
        else:
            msg = "This is a patreon only command! http://ace3df.github.io/AcePictureBot/donate/"

    if command == "MyWaifu" or command == "MyHusbando":
        if message.server is None:
            pass
        if server_settings.get('mywaifu', 'True') == "False":
            return
        if command == "MyWaifu":
            gender = "Waifu"
        else:
            gender = "Husbando"
        twitter_id = get_twitter_id(message.author.id)
        if not twitter_id:
            msg = "Couldn't find your {gender}! "\
                  "Register your {gender} on Twitter "\
                  "(Follow: http://ace3df.github.io/AcePictureBot/commands/) "\
                  "and then link your account using the ID that has been PM'd"\
                  " to you!".format(gender=gender)
            await client.send_message(message.channel, msg)
            await create_twitter_token(message.author)
            return
        else:
            # Legit id
            if command == "MyWaifu":
                gender_id = 0
            else:
                gender_id = 1
            skip_dups = False
            if "my{gender}+".format(gender=gender.lower())\
                    in message.content.lower():
                skip_dups = True
            if "my{gender}-".format(gender=gender.lower())\
                    in message.content.lower():
                delete_used_imgs(twitter_id, True)
            msg, discord_image = mywaifu(twitter_id, gender_id, True,
                                         skip_dups)
            if "I don't know" in msg:
                msg = "Couldn't find your {gender}! "\
                      "Register your {gender} on Twitter "\
                      "(Follow: "\
                      "http://ace3df.github.io/AcePictureBot/commands/)"\
                      .format(gender=gender)
            elif not discord_image or discord_image is None:
                msg = "Sorry failed to get a new image! "\
                      "Use the command on Twitter to help the bot store "\
                      "more images! You can also use My{gender}+ to skip "\
                      "checking for an already "\
                      "used image or My{gender}- to start from fresh!"\
                      .format(gender=gender)
            else:
                msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
                msg = "{0.author.mention}'s {1}".format(message, msg)
                # TODO: Clean this up
                if server_settings['allow_images'] and discord_image:
                    try:
                        await client.send_file(message.channel,
                                               open(discord_image, 'rb'),
                                               content=msg)
                    except:
                        # discord.errors.Forbidden ?
                        # Channel doesn't allow image uploading
                        try:
                            await client.send_message(message.channel, msg)
                        except:
                            # discord.errors.Forbidden ?
                            pass
                        pass
                else:
                    try:
                        await client.send_message(message.channel, msg)
                    except:
                        # discord.errors.Forbidden ?
                        pass
                return

    if command == "OTP":
        msg, discord_image = otp(msg)

    if command == "!Level":
        twitter_id = get_twitter_id(message.author.id)
        msg = get_level(twitter_id=twitter_id, discord_id=message.author.id)

    list_cmds = [
        "Shipgirl", "Touhou", "Vocaloid", "Imouto", "Idol", "Shota", "Onii",
        "Onee", "Sensei", "Monstergirl", "Witchgirl", "Tankgirl", "Senpai",
        "Kouhai", "Granblue"
    ]
    if command in list_cmds:
        msg, discord_image = random_list(command, msg, DISCORD=True)

    # Remove hashtags
    msg = ' '.join(re.sub("(#[A-Za-z0-9]+)", " ", msg).split())
    msg = '{0} {1.author.mention}'.format(msg, message)
    # TODO: Clean this up
    if server_settings['allow_images'] and discord_image:
        try:
            await client.send_file(message.channel,
                                   open(discord_image, 'rb'),
                                   content=msg)
        except:
            # discord.errors.Forbidden ?
            # Channel doesn't allow image uploading
            try:
                await client.send_message(message.channel, msg)
            except:
                # discord.errors.Forbidden ?
                pass
            pass
    else:
        try:
            await client.send_message(message.channel, msg)
        except:
            # discord.errors.Forbidden ?
            pass
def acceptable_tweet(status):
    global USER_LAST_COMMAND
    global IGNORE_WORDS
    global BLOCKED_IDS

    tweet = status.text
    user = status.user
    # Ignore ReTweets.
    if tweet.startswith('RT'):
        return False, False

    if DEBUG:
        if user.id not in MOD_IDS:
            return False, False

    # Reload in case of manual updates.
    BLOCKED_IDS = utils.file_to_list(
        os.path.join(settings['list_loc'], "Blocked Users.txt"))
    IGNORE_WORDS = utils.file_to_list(
        os.path.join(settings['list_loc'], "Blocked Words.txt"))

    # Ignore bots and bad boys.
    if str(user.id) in BLOCKED_IDS:
        return False, False

    # Ignore some messages.
    if any(word.lower() in tweet.lower() for word in IGNORE_WORDS):
        return False, False

    # Make sure the message has @Bot in it.
    if not any("@" + a.lower() in tweet.lower()
               for a in settings['twitter_track']):
        return False, False

    # If the user @sauce_plz add "source" to the text as every @ is later removed.
    if "sauce" in tweet.lower():
        tweet += " source"

    # Remove extra spaces.
    tweet = re.sub(' +', ' ', tweet).lstrip()

    # Remove @UserNames (usernames could trigger commands alone)
    tweet = tweet.replace("🚢👧", "Shipgirl")
    tweet = ' '.join(
        re.sub('(^|\n| )(@[A-Za-z0-9_🚢👧.]+)', ' ', tweet).split())
    tweet = tweet.replace("#", "")

    # Find the command they used.
    command = utils.get_command(tweet)
    if command == "WaifuRegister" or command == "HusbandoRegister":
        # Cut the text off after the command word.
        reg = "({0})(?i)".format(command)
        if len(tweet) > (len(command) + len(settings['twitter_track'][0]) + 2):
            tweet = re.split(reg, tweet)[2].lstrip()

    # No command is found see if acceptable for a random waifu.
    if not command:
        # Ignore quote ReTweets.
        if tweet.startswith('"@'):
            return False, False
        # Ignore if it doesn't mention the main bot only.
        if settings['twitter_track'][0] not in status.text:
            return False, False
        # Last case, check if they're not replying to a tweet.
        if status.in_reply_to_status_id is None:
            command = "Waifu"
        else:
            return False, False

    if command == "Reroll":
        try:
            command = USER_LAST_COMMAND[user.id]
            if "Register" in command:
                return False, False
            elif "My" in command:
                return False, False
        except ValueError:
            return False, False
    else:
        USER_LAST_COMMAND[user.id] = command
        if len(USER_LAST_COMMAND) > 30:
            USER_LAST_COMMAND = (OrderedDict(
                islice(USER_LAST_COMMAND.items(), 20, None)))

    # Stop someone limiting the bot on their own.
    rate_time = datetime.datetime.now()
    rate_limit_secs = 10800
    if user.id in RATE_LIMIT_DICT:
        # User is now limited (3 hours).
        if ((rate_time - RATE_LIMIT_DICT[user.id][0])
                .total_seconds() < rate_limit_secs)\
           and (RATE_LIMIT_DICT[user.id][1] >= 15):
            return False, False
        # User limit is over.
        elif ((rate_time - RATE_LIMIT_DICT[user.id][0]).total_seconds() >
              rate_limit_secs):
            del RATE_LIMIT_DICT[user.id]
        else:
            # User found, not limited, add one to the trigger count.
            RATE_LIMIT_DICT[user.id][1] += 1
    else:
        # User not found, add them to RATE_LIMIT_DICT.
        # Before that quickly go through RATE_LIMIT_DICT
        # and remove all the finished unused users.
        for person in list(RATE_LIMIT_DICT):
            if ((rate_time - RATE_LIMIT_DICT[person][0]).total_seconds() >
                    rate_limit_secs):
                del RATE_LIMIT_DICT[person]
        RATE_LIMIT_DICT[user.id] = [rate_time, 1]

    # This shouldn't happen but just in case.
    if not isinstance(command, str):
        return False, False

    tweet = tweet.lower().replace(command.lower(), " ", 1).strip()
    return tweet, command