예제 #1
0
async def canceltask(dbrowid: int):
    scheduler.cancel(loadedtasks[dbrowid])
    async with aiosqlite.connect("database.sqlite") as db:
        await db.execute("DELETE FROM schedule WHERE id=?", (dbrowid,))
        await db.commit()
    del loadedtasks[dbrowid]
    logger.debug(f"Cancelled task {dbrowid}")
예제 #2
0
 def __exit__(self, type, value, traceback):
     logger.info(f"Cleaning up {len(self.files_created)} files created by TFS #{self.id}")
     logger.debug(f"Temp File Session #{self.id} exiting.")
     for file in self.files_created:
         try:
             os.remove(file)
             logger.debug(f"Removed {file}")
         except FileNotFoundError:
             logger.debug(f"Tried to remove {file}, already removed.")
         except PermissionError:
             logger.debug(f"Tried to remove {file}, file is in use.")
     logger.debug(f"Temp File Session #{self.id} exited.")
예제 #3
0
async def schedule(time: datetime, eventtype: str, eventdata: dict):
    assert time.tzinfo is not None  # offset aware datetimes my beloved
    if time <= datetime.now(tz=timezone.utc):
        logger.debug(f"running event now")
        await run_event(None, eventtype, eventdata)

    async with aiosqlite.connect("database.sqlite") as db:
        async with db.execute("INSERT INTO schedule (eventtime, eventtype, eventdata) VALUES (?,?,?)",
                              (time.timestamp(), eventtype, json.dumps(eventdata))) as cursor:
            lri = cursor.lastrowid
            timef = time.replace(tzinfo=timezone.utc).replace(tzinfo=None)
            task = scheduler.schedule(run_event(lri, eventtype, eventdata), timef)
            loadedtasks[lri] = task
            logger.debug(f"scheduled event #{lri} for {time}")
            # logger.debug(loadedtasks)
        await db.commit()
    return lri
예제 #4
0
async def run_event(dbrowid, eventtype: str, eventdata: dict):
    try:
        logger.debug(f"Running Event #{dbrowid} type {eventtype} data {eventdata}")
        if dbrowid is not None:
            async with aiosqlite.connect("database.sqlite") as db:
                await db.execute("DELETE FROM schedule WHERE id=?", (dbrowid,))
                await db.commit()
        del loadedtasks[dbrowid]
        if eventtype == "debug":
            logger.debug("Hello world! (debug event)")
        elif eventtype == "message":
            ch = eventdata["channel"]
            try:
                ch = await botcopy.fetch_channel(ch)
            except discord.errors.NotFound:
                ch = await botcopy.fetch_user(ch)
            await ch.send(eventdata["message"])
        elif eventtype == "unban":
            guild, member = await asyncio.gather(botcopy.fetch_guild(eventdata["guild"]),
                                                 botcopy.fetch_user(eventdata["member"]))
            await asyncio.gather(guild.unban(member, reason="End of temp-ban."),
                                 member.send(f"You were unbanned in **{guild.name}**."),
                                 modlog.modlog(f"{member.mention} (`{member}`) "
                                               f"was automatically unbanned.", guild.id, member.id))
        elif eventtype == "unmute":
            guild = await botcopy.fetch_guild(eventdata["guild"])
            member = await guild.fetch_member(eventdata["member"])
            await asyncio.gather(member.remove_roles(discord.Object(eventdata["mute_role"])),
                                 member.send(f"You were unmuted in **{guild.name}**."),
                                 modlog.modlog(f"{member.mention} (`{member}`) "
                                               f"was automatically unmuted.", guild.id, member.id))
        elif eventtype == "un_thin_ice":
            guild = await botcopy.fetch_guild(eventdata["guild"])
            member = await guild.fetch_member(eventdata["member"])
            await asyncio.gather(member.remove_roles(discord.Object(eventdata["thin_ice_role"])),
                                 member.send(f"Your thin ice has expired in **{guild.name}**."),
                                 modlog.modlog(f"{member.mention}'s (`{member}`) "
                                               f"thin ice has expired.", guild.id, member.id))
            async with aiosqlite.connect("database.sqlite") as db:
                await db.execute("DELETE FROM thin_ice WHERE guild=? and user=?", (guild.id, member.id))
                await db.commit()
        else:
            logger.error(f"Unknown event type {eventtype} for event {dbrowid}")

    except Exception as e:
        logger.error(e, exc_info=(type(e), e, e.__traceback__))
예제 #5
0
 async def macros(self, ctx: commands.Context):
     macros = []
     async with aiosqlite.connect("database.sqlite") as db:
         async with db.execute("SELECT name FROM macros WHERE server=?",
                               (ctx.guild.id, )) as cursor:
             macros = [i[0] for i in await cursor.fetchall()]
     outstr = f"{len(macros)} macro{'' if len(macros) == 1 else 's'}: {', '.join(macros)}"
     if len(outstr) < 2000:
         await ctx.reply(outstr,
                         allowed_mentions=discord.AllowedMentions.none())
     else:
         with io.StringIO() as buf:
             buf.write(outstr)
             buf.seek(0)
             await ctx.reply(
                 f"{len(macros)} macro{'' if len(macros) == 1 else 's'}.",
                 file=discord.File(buf, filename="macros.txt"))
     logger.debug(macros)
예제 #6
0
def temp_file(extension="png", temp_name=None):
    """
    generates and reserves the name of a file in temp/
    :param extension: the extension of the file
    :param temp_name: optionally reserve a specific name for deletion
    :return: the reserved name (no file is created)
    """
    if temp_name is None:
        temp_name = temp_file_name(extension)
    frame = inspect.currentframe()
    try:
        while "tempfilesession" not in frame.f_locals:
            frame = frame.f_back
        frame.f_locals["tempfilesession"].append(temp_name)
    except AttributeError:
        if globallist is not None:
            globallist.append(temp_name)
        else:
            logger.warning("Temp file created outside TempFileSession.")
    logger.debug(f"temp_file reserved {temp_name}")
    return temp_name
예제 #7
0
 async def emojicount(self, ctx):
     replystr = f"Gathering emoji statistics for **{ctx.guild.name}**. This may take a while."
     replymsg = await ctx.reply(replystr)
     messagecount = 0
     emojicount = 0
     async with ctx.channel.typing():
         emojiregex = r"<a?:\w{2,32}:(\d{18,22})>"
         counts = defaultdict(int)
         for channel in ctx.guild.text_channels:
             logger.debug(f"counting emojis in {channel}")
             if channel.id == 830588015243427890:
                 continue
             async for msg in channel.history(limit=None):
                 if messagecount % 1000 == 0:
                     await replymsg.edit(
                         content=
                         f"{replystr}\nCurrently scanning:{channel.mention}"
                         f"\nScanned {messagecount} messages.\nFound {emojicount} emojis.\n"
                     )
                 messagecount += 1
                 for match in re.finditer(emojiregex, msg.content):
                     emoji = match.group(0)
                     counts[emoji] += 1
                     emojicount += 1
         await replymsg.edit(
             content=
             f"{replystr}\nScanned {messagecount} messages.\nFound {emojicount} emojis.\n"
         )
         sortedcount = {
             k: v
             for k, v in sorted(
                 counts.items(), key=lambda item: item[1], reverse=True)
         }
         with io.BytesIO() as buf:
             buf.write(json.dumps(sortedcount, indent=4).encode())
             buf.seek(0)
             await ctx.reply(file=discord.File(buf, filename="emojis.json"))
예제 #8
0
async def start():
    logger.debug("starting scheduler")
    scheduler.start()
    async with aiosqlite.connect("database.sqlite") as db:
        async with db.execute("SELECT id, eventtime, eventtype, eventdata FROM schedule") as cursor:
            async for event in cursor:
                data = json.loads(event[3])
                dt = datetime.fromtimestamp(event[1], tz=timezone.utc)
                if dt <= datetime.now(tz=timezone.utc):
                    logger.debug(f"running missed event #{event[0]}")
                    loadedtasks[event[0]] = task  # not needed but easier to put this here than to ignore the exception
                    await run_event(event[0], event[2], data)
                else:
                    logger.debug(f"scheduling stored event #{event[0]}")
                    task = scheduler.schedule(run_event(event[0], event[2], data), dt.replace(tzinfo=None))
                    loadedtasks[event[0]] = task
예제 #9
0
 def __enter__(self):
     logger.debug(f"Temp File Session #{self.id} entered.")
     return self.files_created
예제 #10
0
 def __init__(self):
     self.id = random.randint(0, 999999999999)
     logger.debug(f"Temp File Session #{self.id} init.")
     self.files_created = mgr.list()