Ejemplo n.º 1
0
Archivo: dice.py Proyecto: eywat/rollo
async def rp(ctx: Context, dice: str, history: Dict[Union[str, Guild], np.ndarray]):
    """ Roll a dice in NdN format hidden, no info is shown """
    LOGGER.debug("Rolled and passed")
    result = await _r(ctx, dice, history)
    if not result:
        return
    await ctx.send(f"{ctx.message.author.mention} rolled hidden and passed on!")
Ejemplo n.º 2
0
Archivo: dice.py Proyecto: eywat/rollo
async def ro(ctx: Context, dice: str, history: Dict[Union[str, Guild], np.ndarray]):
    """ Roll a dice in NdN format openly """
    LOGGER.debug("Rolling open")
    result = await _r(ctx, dice, history)
    if not result:
        return
    await ctx.send(result)
Ejemplo n.º 3
0
    def render_GET(self, request):
        LOGGER.info('Rendering TimelineView %s' % request.path)

        request.setHeader('content-type', 'text/html')

        processes = []

        # This array will hold all of the data for the timeline view.
        data = [['Timestamp']]

        # Add the list of processes to the timeline table.
        for row in self.db.get_process_cmdlines(name=self.process_name_filter):
            processes.append(row[0])
            data[0].append(row[1].strip())

        LOGGER.debug('got process data: %s' % data)

        # Now add the top-level PSS values for the processes to the table.
        for row in self.db.get_process_stats(name=self.process_name_filter):
            timestamp = row[0]
            if timestamp != data[-1][0]:
                # Moved onto a new snapshot
                data.append([0] * (len(processes) + 1))
                data[-1][0] = timestamp

            # Add process for this snapshot
            pos = 1 + processes.index(row[2])
            data[-1][pos] = int(row[4])

        flattenString(None,
                      TimelineElement('static/timeline.html',
                                      data)).addCallback(self.renderOutput)
        request.write(self.output)
        return ""
Ejemplo n.º 4
0
Archivo: dice.py Proyecto: eywat/rollo
async def rh(ctx: Context, dice: str, history: Dict[Union[str, Guild], np.ndarray]):
    """ Roll a dice in NdN format hidden (PM) """
    LOGGER.debug("Rolling hidden")
    result = await _r(ctx, dice, history)
    if not result:
        return
    await ctx.send(f"{ctx.message.author.mention} rolled hidden!")
    await ctx.message.author.send(result)
Ejemplo n.º 5
0
 def post(self) -> HTMLResponse:
     """Make post request to page."""
     LOGGER.debug(msg=f"POSTing to url: {self.url}")
     response: HTMLResponse = \
         self.session.post(url=self.url,
                           headers=self.session.headers,
                           data=self.payload)
     return response
Ejemplo n.º 6
0
Archivo: vote.py Proyecto: eywat/rollo
    def __init__(self, bot: Bot, guild: Guild, choices: List[Tuple[int, str]]):
        self.bot = bot
        self.guild = guild
        self.voters = set()
        self.open = not any(choices)
        self.choices = list(map(lambda choice: [*choice, 0], choices))

        LOGGER.debug(self.choices)
async def shutdown():
    if SHUTDOWN_VARIABLES['killed']:
        os._exit(1)
    SHUTDOWN_VARIABLES['killed'] = True
    LOGGER.warning('Exiting')
    for t in TASKS:
        t.cancel()
    if TASKS:
        await asyncio.wait(TASKS)
    LOGGER.debug(f'{TASKS=}')
    SHUTDOWN_VARIABLES['event'].set()
Ejemplo n.º 8
0
def parse_smaps_memory_region(pid, lines, has_header=True):
    """Parse a whole smaps region, which may look like:

7f5c8550e000-7f5c85554000 r--p 00000000 08:06 1309629   /fonts/Arial_Bold.ttf
Size:                280 kB
Rss:                 152 kB
Pss:                  86 kB
Shared_Clean:        132 kB
Shared_Dirty:         12 kB
Private_Clean:        20 kB
Private_Dirty:         1 kB
Referenced:          152 kB
Anonymous:             2 kB
AnonHugePages:         3 kB
Shared_Hugetlb:        4 kB
Private_Hugetlb:       5 kB
Swap:                  6 kB
SwapPss:               7 kB
KernelPageSize:        8 kB
MMUPageSize:           9 kB
Locked:               10 kB
VmFlags: rd mr mw me sd"""

    has_header = is_memory_region_header(lines[0])

    if has_header:
        region = parse_smaps_header(lines[0])
        if region.name == '[vsyscall]':
            return None
        lines = lines[1:]
    else:
        region = MemoryRegion(free=False)

    region.pid = pid

    global _smaps_string_mappings
    for line in lines:
        LOGGER.debug('Parsing line: %s' % line)
        parts = re.split('[ :]+', line.strip())
        if len(parts) < 2:
            LOGGER.debug('Skipping smaps line that is too short: %s' % line)
        elif 'Size' == parts[0]:
            # We calculate the size from the address ranges instead.
            pass
        elif 'VmFlags' == parts[0]:
            region.vm_flags = parts[1:]
        else:
            # All other lines should be an amount of some type of memory.
            try:
                region.__dict__[_smaps_string_mappings[parts[0]]] = int(
                    parts[1]) * 1024
            except KeyError:
                LOGGER.warn("Line not recognised: '%s'" % line)
    return region
Ejemplo n.º 9
0
async def main():
    """ Main function """
    env = Env()
    env.read_env()
    setup_logger(env.int("LOG_LEVEL", logging.INFO),
                 env.path("LOG_FILE", None))

    async with aiohttp.ClientSession() as session:
        bot = create_bot(env, session)

        LOGGER.debug("Starting bot")
        await bot.start(env.str("BOT_TOKEN"))
Ejemplo n.º 10
0
 def parse(self, data, out):
     out['meminfo'] = MemoryStats()
     for line in data.split('\n'):
         parts = re.split('[ :]+', line.strip())
         if len(parts) < 2:
             LOGGER.debug('Skipping meminfo line that is too short: %s' %
                          line)
         elif len(parts) == 2:
             # This is a number. eg HugePages_Total, HugePages_Free,
             # HugePages_Rsvd, HugePages_Surp
             out['meminfo'].meminfo[parts[0]] = int(parts[1])
         else:
             # These are sizes, with unit kB in the third column.
             # eg. AnonHugePages:   2355200 kB
             out['meminfo'].meminfo[parts[0]] = int(parts[1]) * 1024
     return out
Ejemplo n.º 11
0
def parse_meminfo(stats, data):
    if not isinstance(stats, MemoryStats):
        raise TypeError('%s is not of type MemoryStats' % type(stats))

    for line in data.split('\n'):
        parts = re.split('[ :]+', line.strip())
        if len(parts) < 2:
            LOGGER.debug('Skipping meminfo line that is too short: %s' % line)
        elif len(parts) == 2:
            # This is a number. eg HugePages_Total, HugePages_Free,
            # HugePages_Rsvd, HugePages_Surp
            stats.meminfo[parts[0]] = int(parts[1])
        else:
            # These are sizes, with unit kB in the third column.
            # eg. AnonHugePages:   2355200 kB
            stats.meminfo[parts[0]] = int(parts[1]) * 1024
Ejemplo n.º 12
0
Archivo: dice.py Proyecto: eywat/rollo
async def _r(ctx: Context, dice: str, history: Dict[Union[str, Guild], np.ndarray]):
    """ String parsing and rolling for all dice rolling functions """
    try:
        rolls, limit = map(int, dice.split("d"))
    except Exception:
        await ctx.send("Format has to be in NdN!")
        return None
    if rolls > 200 or limit > 200:
        await ctx.send("Pls use smaller numbers '_'")
        return None

    result = np.random.randint(low=1, high=limit + 1, size=rolls)
    result = np.sort(result)[::-1]
    LOGGER.debug(result)
    guild = ctx.guild if ctx.guild else "default"
    LOGGER.debug(guild)
    history[guild] = result
    result = ", ".join(map(str, result))
    return result
Ejemplo n.º 13
0
 def expect_address_connections(self, tmp_path, component_tests_config, protocol, edge_ip_version, assert_address_type):
     config = component_tests_config(
         self._extra_config(protocol, edge_ip_version))
     config_path = write_config(tmp_path, config.full_config)
     LOGGER.debug(config)
     with CloudflaredCli(config, config_path, LOGGER):
         wait_tunnel_ready(tunnel_url=config.get_url(),
                           require_min_connections=4)
         cfd_cli = CloudflaredCli(config, config_path, LOGGER)
         tunnel_id = config.get_tunnel_id()
         info = cfd_cli.get_tunnel_info(tunnel_id)
         connector_id = get_tunnel_connector_id()
         connector = next(
             (c for c in info["conns"] if c["id"] == connector_id), None)
         assert connector, f"Expected connection info from get tunnel info for the connected instance: {info}"
         conns = connector["conns"]
         assert conns == None or len(
             conns) == 4, f"There should be 4 connections registered: {conns}"
         for conn in conns:
             origin_ip = conn["origin_ip"]
             assert origin_ip, f"No available origin_ip for this connection: {conn}"
             assert_address_type(origin_ip)
Ejemplo n.º 14
0
    async def vote(self, ctx: Context, *choices: str, time=20):
        """ Create a vote. (Alt command: v) """
        # Check if voting is possible
        guild = ctx.guild
        if ctx.guild is None:
            await ctx.send("This feature is only supported in guilds")
            return
        vote = self.votes.get(guild)
        if vote:
            await ctx.send("There is already a vote running")
            return

        # Attach a number to each choice
        choice_enum: List[Tuple[int, str]] = list(
            enumerate(
                map(lambda choice: choice.strip(" ,\n").lower(), choices), 1))
        vote = Vote(self.bot, guild, choice_enum)
        self.votes[guild] = vote
        LOGGER.debug("Started voting listener")
        self.bot.add_listener(vote.on_vote, name="on_message")
        choice_text = ("\n".join(
            map(lambda choice: f"{choice[0]}\t\u21D2 \t{choice[1]}",
                choice_enum)) if choice_enum else "Open voting")
        await ctx.send(f"Voting started for {time}s.\n{choice_text}")

        await asyncio.sleep(time)

        self.bot.remove_listener(vote.on_vote, name="on_message")
        LOGGER.debug("Removed voting listener")
        results = vote.format_results()
        hist = vote.termogram()
        if hist is not None:
            await ctx.send(f"Voting finished!\n{hist}")
        else:
            await ctx.send(f"Voting finished!\n{results}")
        del self.votes[guild]
Ejemplo n.º 15
0
def parse_smaps_header(header):
    info = MemoryRegion(free=False)
    # Example line is:
    # 011e6000-01239000 rw-p 00000000 00:00 0    [heap]
    # 8ec00000-8ec01000 rw-s 00000000 00:14 20   /dev/shm/NS2371 (deleted)
    # All numbers are hex except for the inode
    parts = header.split()
    LOGGER.debug('Parsing smaps header %s' % header)

    # Parse the address range
    info.start_addr, info.end_addr = [long(x, 16) for x in parts[0].split('-')]

    # Parse the permissions
    permissions = parts[1]
    info.permissions.readable = "r" in permissions
    info.permissions.writable = "w" in permissions
    info.permissions.executable = "x" in permissions
    info.permissions.private = "p" in permissions
    info.permissions.shared = "s" in permissions

    info.offset = long(parts[2], 16)

    # eg. 08:06
    info.major_dev, info.minor_dev = [int(x, 16) for x in parts[3].split(':')]

    # The inode isn't a hex number
    info.inode = int(parts[4])

    # eg. [heap]
    # or  /dev/shm/NS2371
    if len(parts) > 5:
        info.name = parts[5]

    info.deleted = header.endswith('(deleted)')

    return info
Ejemplo n.º 16
0
Archivo: vote.py Proyecto: eywat/rollo
    async def on_vote(self, message):
        """ React to a message sent in the guild """
        if message.author == self.bot.user:
            LOGGER.debug("Own message")
            return
        if message.content.startswith(self.bot.command_prefix):
            LOGGER.debug("Detected command")
            return
        if message.author in self.voters:
            LOGGER.debug("Already voted %s", message.author)
            return

        self.voters.add(message.author)
        content = message.content.strip(" ,\n").lower()
        LOGGER.debug(content)
        if self.open:
            choice = list(filter(lambda choice: choice[1] == content, self.choices))
            if choice:
                LOGGER.debug("Incrementing existing choice")
                choice[0][2] += 1
            else:
                LOGGER.debug("Creating new choice")
                self.choices.append([len(self.choices) + 1, content, 1])
            return

        try:
            index = int(content)
            choice = next(filter(lambda choice: choice[0] == index, self.choices))
            LOGGER.debug("Got integer")
            choice[2] += 1
        except:
            try:
                LOGGER.debug("Got name")
                choice = next(filter(lambda choice: choice[1] == content, self.choices))
                choice[2] += 1
            except:
                LOGGER.debug("Not found")
                return
Ejemplo n.º 17
0
 def get(self) -> HTMLResponse:
     LOGGER.debug(msg=f"GETing url: {self.url}")
     response: HTMLResponse = self.session.get(url=self.url,
                                               headers=self.session.headers)
     return response
Ejemplo n.º 18
0
def read_tailed_files(stream):
    section_name = ''
    data = ''
    processes = ProcessList()
    current_process = None
    current_thread = None
    out = {}
    out['stats'] = SystemStats()
    out['meminfo'] = MemoryStats()

    for line in stream:
        LOGGER.debug('Got line: %s' % line)
        if line == '':
            continue
        # tail gives us lines like:
        #
        #     ==> /proc/99/smaps <==
        #
        # between files
        elif line.startswith('==>'):
            _parse_section(section_name, current_process, current_thread, data,
                           out)
            data = ''
            section_name = ''
            current_process = None
            current_thread = None

            if '/proc/loadavg' in line:
                section_name = 'loadavg'
                continue
            elif '/proc/uptime' in line:
                section_name = 'uptime'
                continue
            elif '/proc/vmstat' in line:
                section_name = 'vmstat'
                continue
            elif '/proc/net/stat' in line:
                # We don't care about this entry. Skip it.
                continue

            # Now parse the new line.
            match = re.match(r'==> /proc/([0-9]+)/([\w]+) <==', line)
            if match is None:
                if any(x in line for x in
                       ['/proc/stat', '/proc/self/', '/proc/thread-self/']):
                    # We just ignore these entries, interetesting as they are,
                    # for now.
                    pass
                elif '/proc/meminfo' in line:
                    section_name = 'meminfo'
                else:
                    match = re.match(
                        r'==> /proc/([0-9]+)/task/([0-9]+)/stat <==', line)
                    if match is None:
                        # The line might not be parsed here. There are a few
                        LOGGER.warn('Unrecognised line, skipping: %s' % line)
                    else:
                        section_name = 'stat'
                        pid = int(match.group(1))  # process id
                        tid = int(match.group(2))  # thread id
                        current_thread = processes.get(pid).get_thread(tid)
            else:
                section_name = match.group(2)
                current_process = processes.get(pid=int(match.group(1)))

        elif current_process and section_name == 'smaps' and is_memory_region_header(
                line):
            # We get here on reaching a new memory region in a smaps file.
            _save_smaps_region(current_process.maps, out['meminfo'],
                               current_process.pid, data)
            data = line
        elif section_name != '':
            data += "\n" + line
        else:
            LOGGER.debug('Skipping line: %s' % line)

    # We've hit the end, parse the section we were in.
    _parse_section(section_name, current_process, current_thread, data, out)

    return out['stats'], processes, out['meminfo']