Example #1
0
    def __init__(self, bot):
        super().__init__(bot)
        self.scheduler = TimedScheduler(prefer_utc=True)
        self.scheduler.start()

        AssignableRole.inject_bot(bot)
        RoleAlias.inject_bot(bot)
        RoleClear.inject_bot(bot)
Example #2
0
    def __init__(self, bot):
        super().__init__(bot)
        self.scheduler = TimedScheduler(prefer_utc=True)
        self.scheduler.start()

        Reminder.inject_bot(bot)

        super(AinitMixin).__init__()
Example #3
0
File: bot.py Project: indij/IdleRPG
    def __init__(self, **kwargs):
        self.cluster_name = kwargs.pop("cluster_name")
        self.cluster_id = kwargs.pop("cluster_id")
        super().__init__(
            command_prefix=config.global_prefix,
            **kwargs)  # we overwrite the prefix when it is connected
        # setup stuff
        self.queue = asyncio.Queue()  # global queue for ordered tasks
        self.schedule_manager = TimedScheduler()
        self.config = config
        self.version = config.version
        self.paginator = paginator
        self.BASE_URL = config.base_url
        self.bans = set(config.bans)
        self.linecount = 0
        self.make_linecount()
        self.all_prefixes = {}
        self.activity = discord.Game(name=f"IdleRPG v{config.version}"
                                     if config.is_beta else config.base_url)
        self.logger = logging.getLogger()

        # global cooldown
        self.add_check(self.global_cooldown, call_once=True)

        # we assume the bot is created for use right now
        self.launch_time = datetime.datetime.now()
        self.eligible_for_cooldown_reduce = set()  # caching
        self.not_eligible_for_cooldown_reduce = set()  # caching
Example #4
0
    def __init__(self, **kwargs):
        self.cluster_name = kwargs.pop("cluster_name")
        self.cluster_id = kwargs.pop("cluster_id")
        self.config = ConfigLoader("config.toml")
        mentions = AllowedMentions.none()
        mentions.users = True
        super().__init__(
            allowed_mentions=mentions,
            command_prefix=self.config.bot.global_prefix,
            **kwargs,
        )  # we overwrite the prefix when it is connected
        # setup stuff
        self.queue = asyncio.Queue()  # global queue for ordered tasks
        self.schedule_manager = TimedScheduler()
        self.version = self.config.bot.version
        self.paginator = paginator
        self.BASE_URL = self.config.external.base_url
        self.bans = set(self.config.game.bans)
        self.support_server_id = self.config.game.support_server_id
        self.linecount = 0
        self.make_linecount()
        self.all_prefixes = {}
        self.activity = discord.Game(name=f"IdleRPG v{self.version}" if self.
                                     config.bot.is_beta else self.BASE_URL)
        self.logger = logging.getLogger()

        # global cooldown
        self.add_check(self.global_cooldown, call_once=True)

        # we assume the bot is created for use right now
        self.launch_time = datetime.datetime.now()
        self.eligible_for_cooldown_reduce = set()  # caching
        self.not_eligible_for_cooldown_reduce = set()  # caching

        self.normal_cooldown = commands.CooldownMapping.from_cooldown(
            1,
            self.config.bot.global_cooldown,
            commands.BucketType.user,
        )
        self.donator_cooldown = commands.CooldownMapping.from_cooldown(
            1,
            self.config.bot.donator_cooldown,
            commands.BucketType.user,
        )
Example #5
0
class Roles(CustomCog, AinitMixin):
    def __init__(self, bot):
        super().__init__(bot)
        self.scheduler = TimedScheduler(prefer_utc=True)
        self.scheduler.start()

        AssignableRole.inject_bot(bot)
        RoleAlias.inject_bot(bot)
        RoleClear.inject_bot(bot)

    async def _ainit(self):
        await self.bot.wait_until_ready()

        async with self.bot.Session() as session:
            role_clears = await db.get_role_clears(session)

            for role_clear in role_clears:
                if not role_clear.guild:
                    await db.delete_role_clear(session, role_clear._member,
                                               role_clear._role)
                elif role_clear.is_due():
                    await self._clear_role(role_clear.guild, role_clear.member,
                                           role_clear.role)
                else:
                    self.scheduler.schedule(
                        self._clear_role(role_clear.guild, role_clear.member,
                                         role_clear.role),
                        role_clear.when,
                    )

    async def _clear_role(self, guild: discord.Guild, member: discord.Member,
                          role: discord.Role):
        async with self.bot.Session() as session:
            if guild:
                if member and role:
                    await member.remove_roles(role,
                                              reason="Automatic unassign")
                    logger.info(
                        f"Automatically unassigned {role} from {member} in {guild}."
                    )

            await db.delete_role_clear(session, member.id, role.id)

            await session.commit()

    async def _toggle_role(self, ctx, alias, member: discord.Member):
        async with self.bot.Session() as session:
            assignable_role = await db.get_role_by_alias(
                session, ctx.guild.id, alias)
            if not assignable_role:
                raise commands.BadArgument("This role does not exist.")

            role = assignable_role.role

            try:
                if role not in member.roles:
                    await member.add_roles(role,
                                           reason="Self-assigned by member")
                    await ctx.send(
                        f"{member.mention}, you now have the role {role.mention}."
                    )

                    if assignable_role.clear_after:
                        when = pendulum.now("UTC").add(
                            hours=assignable_role.clear_after)

                        self.scheduler.schedule(
                            self._clear_role(member.guild, member, role), when)

                        role_clear = RoleClear(
                            _role=role.id,
                            _member=member.id,
                            _guild=ctx.guild.id,
                            when=when,
                        )
                        await session.merge(role_clear)

                        await session.commit()
                else:
                    await member.remove_roles(
                        role, reason="Self-unassigned by member")
                    await ctx.send(
                        f"{member.mention}, you no longer have the role {role.mention}."
                    )
            except discord.Forbidden:
                raise commands.BadArgument("I am not allowed to manage roles.")

    @commands.group(aliases=["r", "role"], invoke_without_command=True)
    async def roles(self, ctx, *, role_alias=None):
        if role_alias:
            await self._toggle_role(ctx, role_alias, ctx.author)
        else:
            await ctx.send(f"Assign a role using `{ctx.prefix}role name`.")
            await ctx.invoke(self.list)

    @roles.command()
    async def list(self, ctx):
        async with self.bot.Session() as session:
            assignable_roles = await db.get_roles(session, ctx.guild.id)
            roles_to_show = []

            for a_role in assignable_roles:
                if not a_role.role:
                    session.delete(a_role)
                    await ctx.send(
                        f"Removing assignable role that no longer exists: `{a_role.aliases[0].alias}`"
                    )
                else:
                    roles_to_show.append(a_role)

            roles_to_show.sort(key=lambda a_role: a_role.role.position,
                               reverse=True)
            roles = [a_role.role.mention for a_role in roles_to_show]

            if len(roles) > 0:
                await ctx.send(f'Available roles: {", ".join(roles)}')
            else:
                await ctx.send(
                    f"Try to make some roles self-assignable using `{ctx.prefix}role create`."
                )

            await session.commit()

    @roles.command()
    @commands.has_permissions(administrator=True)
    async def create(self, ctx, role: discord.Role,
                     clear_after: typing.Optional[int], *aliases):
        async with self.bot.Session() as session:
            if await db.get_role(session, role.id):
                raise commands.BadArgument(
                    f"{role.mention} is already self-assignable.")

            assignable_role = AssignableRole(_guild=ctx.guild.id,
                                             _role=role.id,
                                             clear_after=clear_after)
            session.add(assignable_role)

            aliases = set(aliases + (role.name, ))

            role_aliases = [
                RoleAlias(_role=role.id, _guild=ctx.guild.id, alias=alias)
                for alias in aliases
            ]

            for role_alias in role_aliases:
                try:
                    session.add(role_alias)
                except asyncpg.exceptions.UniqueViolationError:
                    raise commands.BadArgument(
                        f"The alias `{role_alias.alias}` is already in use.")

            await session.commit()

            await ctx.send(f"{role.mention} is now self-assignable.")

    @roles.command(aliases=["remove"])
    @commands.has_permissions(administrator=True)
    @ack
    async def delete(self, ctx, role: discord.Role):
        async with self.bot.Session() as session:
            await db.delete_role(session, role.id)

            await session.commit()

    @roles.command()
    async def info(self, ctx, *, alias):
        async with self.bot.Session() as session:
            assignable_role = await db.get_role_by_alias(
                session, ctx.guild.id, alias)
            if not assignable_role:
                raise commands.BadArgument("This role does not exist.")

            aliases = [
                f"`{role_alias.alias}`"
                for role_alias in assignable_role.aliases
            ]
            await ctx.send(
                f'Role: {assignable_role.role.mention}, clears after: {assignable_role.clear_after or "∞"} hours.'
                f'\nAliases: {", ".join(aliases)}')
Example #6
0
class Reminders(CustomCog, AinitMixin):
    def __init__(self, bot):
        super().__init__(bot)
        self.scheduler = TimedScheduler(prefer_utc=True)
        self.scheduler.start()

        Reminder.inject_bot(bot)

        super(AinitMixin).__init__()

    async def _ainit(self):
        await self.bot.wait_until_ready()

        async with self.bot.Session() as session:
            reminders = await db.get_reminders(session)

            for reminder in reminders:
                if reminder.is_due():
                    await self.remind_user(reminder.reminder_id, late=True)
                else:
                    self.scheduler.schedule(
                        self.remind_user(reminder.reminder_id), reminder.due)

        logger.info(f"# Initial reminders from db: {len(reminders)}")

    def cog_unload(self):
        self.scheduler._task.cancel()

    @auto_help
    @commands.group(
        name="reminders",
        aliases=["remindme", "remind"],
        invoke_without_command=True,
        brief="Set reminders in the future",
    )
    async def reminders_(self, ctx, *, args: ReminderConverter = None):
        if args:
            await ctx.invoke(self.add, args=args)
        else:
            await ctx.send_help(self.reminders_)

    @reminders_.command(brief="Adds a new reminder")
    @log_usage(command_name="remind")
    async def add(self, ctx, *, args: ReminderConverter):
        """
        Adds a new reminder.

        Example usage:
        `{prefix}remind in 3 hours to do the laundry`
        `{prefix}remind 15-06-20 at 6pm KST to Irene & Seulgi debut`
        `{prefix}remind in 6 minutes 30 seconds to eggs`
        """
        when, what = args
        parsed_date = parse_date(when)

        now = pendulum.now("UTC")
        diff = parsed_date.diff_for_humans(now, True)

        async with self.bot.Session() as session:
            reminder = Reminder(_user=ctx.author.id,
                                due=parsed_date,
                                content=what)
            session.add(reminder)
            await session.flush()
            self.scheduler.schedule(self.remind_user(reminder.reminder_id),
                                    parsed_date)
            await session.commit()

        await ctx.send(
            f"I'll remind you on `{parsed_date.to_cookie_string()}` (in {diff}): `{what}`."
        )

    @reminders_.command()
    async def list(self, ctx):
        """
        Lists your reminders
        """
        async with self.bot.Session() as session:
            reminders = await db.get_reminders(session, user_id=ctx.author.id)

            if len(reminders) > 0:
                pages = MenuPages(source=ReminderListSource(reminders),
                                  clear_reactions_after=True)
                await pages.start(ctx)
            else:
                await ctx.send("You have 0 pending reminders!")

    async def remind_user(self, reminder_id, late=False):
        async with self.bot.Session() as session:
            reminder = await db.get_reminder(session, reminder_id)

            diff = reminder.created.diff_for_humans(reminder.due, True)
            assert not reminder.done

            user = reminder.user

            if user and late:
                await safe_send(
                    user,
                    f"{self.bot.custom_emoji['SHOUT']} You told me to remind you some time ago. "
                    f"Sorry for being late:\n{reminder.content}",
                )
            elif user:
                message = await safe_send(
                    user,
                    f"{self.bot.custom_emoji['SHOUT']} You told me to remind you {diff} ago:\n{reminder.content}",
                )

                if message:
                    ctx = await self.bot.get_context(message)
                    ctx.author = user

                    confirm = await SimpleConfirm(
                        message, timeout=120.0,
                        emoji=UNICODE_EMOJI["SNOOZE"]).prompt(ctx)
                    if confirm:
                        try:
                            new_due = await self.prompt_snooze_time(reminder)
                            reminder.due = new_due
                            self.scheduler.schedule(
                                self.remind_user(reminder.reminder_id),
                                new_due)
                            await session.commit()
                            return
                        except commands.BadArgument as ba:
                            await ctx.send(ba)

            reminder.done = True
            await session.commit()

    async def prompt_snooze_time(self, reminder):
        user = reminder.user

        message = await user.send(
            "When do you want me to remind you again? (e.g.: `in 30 minutes`)")
        channel = message.channel

        answer = await self.bot.wait_for(
            "message",
            check=lambda msg: msg.channel == channel and msg.author == user)
        parsed_date = parse_date(answer.content)

        now = pendulum.now("UTC")
        diff = parsed_date.diff_for_humans(now, True)

        await channel.send(f"Reminding you again in {diff}.")
        return parsed_date
Example #7
0
import asyncio
import json
from datetime import datetime, timezone

import aiosqlite
import discord
from aioscheduler import TimedScheduler
from discord.ext import commands

import modlog
from clogs import logger

scheduler = TimedScheduler(prefer_utc=True)
botcopy = commands.Bot
loadedtasks = dict()  # keep track of task objects to cancel if needed.


class ScheduleInitCog(commands.Cog):
    def __init__(self, bot):
        global botcopy
        botcopy = bot
        self.bot = bot
        bot.loop.create_task(start())


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: