Пример #1
0
    def __init__(self, bot, counter, xp_aggregator, notifier, config):
        self.bot = bot
        self.counter = counter
        self.xp_aggregator = xp_aggregator
        self.notifier = notifier
        self.spam_channel = config["spam_channel"]

        xp_loop = loop(seconds=config["delays"]["xp"])(self.update_xp)
        xp_loop.start()

        notify_loop = loop(seconds=config["delays"]["notify"])(
            self.notify_levels)
        notify_loop.start()
Пример #2
0
async def test_explicit_initial_runs_tomorrow_multi():
    now = utils.utcnow()

    if not ((0, 4) < (now.hour, now.minute) < (23, 59)):
        await asyncio.sleep(5 * 60)  # sleep for 5 minutes

    now = utils.utcnow()

    # multiple times that are in the past for today
    times = []
    for _ in range(3):
        now -= datetime.timedelta(minutes=1)
        times.append(datetime.time(hour=now.hour, minute=now.minute))

    has_run = False

    async def inner():
        nonlocal has_run
        has_run = True

    # a loop that should have an initial run tomorrow
    loop = tasks.loop(time=times)(inner)

    loop.start()
    await asyncio.sleep(1)

    try:
        assert not has_run
    finally:
        loop.cancel()
Пример #3
0
async def test_explicit_initial_runs_tomorrow_single():
    now = utils.utcnow()

    if not ((0, 4) < (now.hour, now.minute) < (23, 59)):
        await asyncio.sleep(5 * 60)  # sleep for 5 minutes

    now = utils.utcnow()

    has_run = False

    async def inner():
        nonlocal has_run
        has_run = True

    time = utils.utcnow() - datetime.timedelta(minutes=1)

    # a loop that should have an initial run tomorrow
    loop = tasks.loop(time=datetime.time(hour=time.hour, minute=time.minute))(inner)

    loop.start()
    await asyncio.sleep(1)

    try:
        assert not has_run
    finally:
        loop.cancel()
Пример #4
0
    async def on_ready(self):
        await self.update_price()

        self.bot.priceloop = tasks.loop(
            seconds=self.bot.config['refresh_rate'])(self.update_price)
        self.bot.priceloop.add_exception_type(discord.errors.HTTPException)
        self.bot.priceloop.start()
 def decorator(func):
     async def wrapper(*args, **kwargs):
         await bot.wait_until_ready()
         is_time = lambda dt: (datetime.now() - dt).seconds < 60
         if any(is_time(dt) for dt in timestamps):
             await func(*args, **kwargs)
     return tasks.loop(seconds=60)(wrapper)
Пример #6
0
    def __init__(self, bot, redis, config):
        self.bot = bot
        self.redis = redis
        self.spam_channel = config["spam_channel"]

        notify_loop = loop(seconds=config["delays"]["notify"])(self.notify_reminders)
        notify_loop.start()
Пример #7
0
 def __init__(self, bot):
     self.bot = bot
     self.midnight_helper = tasks.loop(seconds=3,
                                       loop=bot.loop)(self.midnight_helper)
     self.midnight_helper.before_loop(self.pre_midnight_loop_start)
     self.midnight_helper.after_loop(self.post_midnight_loop_complete)
     self.midnight_helper.start()
Пример #8
0
    async def on_ready(self):
        await self.update()

        self.bot.epoch_loop = tasks.loop(
            seconds=self.bot.config['refresh_rate'])(self.update)
        self.bot.epoch_loop.add_exception_type(discord.errors.HTTPException)
        self.bot.epoch_loop.add_exception_type(ValueError)
        self.bot.epoch_loop.start()

        if 'stats_channels' in self.bot.boardroom:
            refresh_rate = self.bot.common.get('refresh_rate',
                                               self.bot.config['refresh_rate'])
            self.bot.events_loop = tasks.loop(seconds=refresh_rate)(
                self.bot.get_latest_events)
            self.bot.events_loop.add_exception_type(
                discord.errors.HTTPException)
            self.bot.events_loop.add_exception_type(ValueError)
            self.bot.events_loop.start()
Пример #9
0
    def __init__(self, bot):
        self.bot = bot

        self.timeout_secs = TIMEOUT_SECS

        interval = self.update_interval_secs
        log.info('[%s] Starting update check loop, interval: %s sec',
                 self._derived_name, interval)
        self._task = tasks.loop(seconds=interval)(self.task)
        self._task.start()
Пример #10
0
async def automeme(ctx):
    '''Triggers the automeme taskloop for the channel context'''
    channel_id = ctx.channel.id
    if channel_id in automeme_loops:
        await ctx.send('Automeme already running here')
    else:
        # using decorator instead of tasks.Loop directly to preserve default arguments
        loop = tasks.loop(seconds=600)(automeme_routine)
        automeme_loops[channel_id] = loop
        loop.start(ctx)
Пример #11
0
    def task(self, ext) -> Loop:
        self.kwargs['loop'] = asyncio.get_running_loop()

        async def method(*args, **kwargs):
            try:
                await self.func(ext, *args, **kwargs)
            except KeyboardInterrupt:
                raise
            except:
                await ext.on_error(self.func.__name__, *args, **kwargs)

        return tasks.loop(**self.kwargs)(method)
Пример #12
0
    def add_task(self, delay: int, coro, *args, **kwargs):
        """Schedule a task for later, using discord.ext tasks manager"""
        delay = round(delay)

        async def launch(task, coro, *args, **kwargs):
            if task.current_loop != 0:
                await self.bot.wait_until_ready()
                self.bot.log.info("[TaskManager] Tâche {} arrivée à terme".format(coro.__func__))
                await coro(*args, **kwargs)
        a = tasks.loop(seconds=delay, count=2)(launch)
        a.error(self.bot.get_cog("Errors").on_error)
        a.start(a, coro, *args, **kwargs)
        self.bot.log.info(
            "[TaskManager] Nouvelle tâche {} programmée pour dans {}s".format(coro.__func__, delay))
        return a
Пример #13
0
        """"
        else:
            buf.close()
        """
    if vc.guild.id in queue:
        pair = queue[vc.guild.id][0]
        if len(queue[vc.guild.id]) == 1:
            del queue[vc.guild.id]
        else:
            del queue[vc.guild.id][0]
        await play_sound(pair[0], pair[1])
        return

    for _ in range(600):
        if vc.is_playing():
            return
        await asyncio.sleep(.5)
    await vc.disconnect()


@bot.event
async def on_ready():
    text = 'Logged in as ' + bot.user.name + ' (' + str(bot.user.id) + ')'
    print(text)
    print('-' * len(text))
    oscce.start()


tasks.loop(hours=24)(clean_cache).start()
bot.run(TOKEN)
Пример #14
0
cmdManager_collection = database["cmd_manager"]


# --------------------------------Main startup event--------------------------------#
@bot.event
async def on_ready():
    change_status.start()
    print("updating databases...")
    update_cmdManager_coll(bot, database)
    print('Logged in as {0.user}'.format(bot))


# --------------------------------Task loops--------------------------------#

loops = Loops(bot, custom_statuses)
change_status = tasks.loop(seconds=60)(loops.change_status)

# --------------------------------Events--------------------------------#
events = Events(bot, database, total_guilds_api_url, ["help", "kick", "ban", "warn", "warninfo", "warns", "mute", "unmute", "clear"],
                ChintuAI=True)
bot.event(events.on_command_error)
bot.event(events.on_message)
bot.event(events.on_guild_join)
bot.event(events.on_command_completion)


# --------------------------------Load Extensions/cogs--------------------------------#
def load_extensions(fun_bot, unloaded_cogs: list):
    """Loads all extensions (Cogs) from the cogs directory"""
    if unloaded_cogs is None:
        unloaded_cogs = []
Пример #15
0
 async def start(self, ctx, *, args: convert_to_seconds):
     self.automeme = tasks.loop(seconds=10)(self.automemer)
     await self.automeme.start(ctx)
     await ctx.send('enjoy memes :smirk:')
Пример #16
0
class Time(commands.Cog):
    """Commands related to time and delaying messages."""
    def __init__(self, bot):
        self.bot = bot
        self.time_config = load_json(paths.TIME_SAVES)
        self.time_loop.start()
        self.event_loop.start()

    def cog_unload(self):
        self.time_loop.cancel()
        self.event_loop.cancel()

    def get_time(self, timezone_name):
        timezone = pytz.timezone(timezone_name)
        now = datetime.datetime.now().astimezone(timezone)
        return now.strftime("**%H:%M** (**%I:%M%p**) on %A (%Z, UTC%z)")

    @commands.group(aliases=["tz", "when", "t"], invoke_without_command=True)
    async def time(self, ctx, *, user: discord.Member = None):
        """Get a user's time."""
        user = ctx.author if not user else user
        try:
            time = self.get_time(self.time_config[str(user.id)])
        except KeyError:
            message = (
                "You don't have a timezone set. You can set one with `time set`."
                if user == ctx.author else
                "That user doesn't have a timezone set.")
            await show_error(ctx, message, "Timezone not set")
        else:
            await ctx.send(embed=make_embed(
                title=f"{user.name}'s time",
                description=time,
                color=colors.EMBED_SUCCESS,
            ))

    @time.command()
    async def set(self, ctx, timezone="invalid"):
        """Set a timezone for you in the database."""
        try:
            pytz.timezone(timezone)
            self.time_config[str(ctx.author.id)] = timezone
            await self.update_times()
            save_json(paths.TIME_SAVES, self.time_config)

            await ctx.send(embed=make_embed(
                title="Set timezone",
                description=f"Your timezone is now {timezone}.",
                color=colors.EMBED_SUCCESS,
            ))
        except pytz.exceptions.UnknownTimeZoneError:
            url = "https://github.com/sdispater/pytzdata/blob/master/pytzdata/_timezones.py"
            await show_error(
                ctx,
                message=
                "You either set an invalid timezone or didn't specify one at all. "
                f"Read a list of valid timezone names [here]({url}).",
                title="Invalid timezone",
            )

    @time.command(aliases=["remove"])
    async def unset(self, ctx):
        """Remove your timezone from the database."""
        if str(ctx.author.id) not in self.time_config:
            await show_error(ctx, "You don't have a timezone set.")

        self.time_config.pop(str(ctx.author.id))
        await self.update_times()
        save_json(paths.TIME_SAVES, self.time_config)

        await ctx.send(embed=make_embed(
            title="Unset timezone",
            description=f"Your timezone is now unset.",
            color=colors.EMBED_SUCCESS,
        ))

    async def update_times(self):
        channel = self.bot.get_channel(channels.TIME_CHANNEL)
        await channel.purge()

        paginator = commands.Paginator()
        time_config_members = {
            channel.guild.get_member(int(id)): timezone
            for id, timezone in self.time_config.items()
            if channel.guild.get_member(int(id))
        }
        groups = itertools.groupby(
            sorted(
                time_config_members.items(),
                key=lambda m: (
                    datetime.datetime.now().astimezone(pytz.timezone(m[
                        1])).replace(tzinfo=None).year,
                    datetime.datetime.now().astimezone(pytz.timezone(m[1])).
                    replace(tzinfo=None).month,
                    datetime.datetime.now().astimezone(pytz.timezone(m[
                        1])).replace(tzinfo=None).day,
                    self.get_time(m[1]),
                    str(m[0]),
                ),
            ),
            lambda x: self.get_time(x[1]),
        )
        for key, group in groups:
            if not key:
                continue
            group_message = [key]
            for member, _ in group:
                group_message.append(member.mention)
            paginator.add_line("\n    ".join(group_message))

        for page in paginator.pages:
            await channel.send(
                embed=make_embed(title="Times", description=page[3:-3]))

    time_loop = tasks.loop(minutes=1)(update_times)

    @time_loop.before_loop
    async def before_time(self):
        await self.bot.wait_until_ready()

    @commands.group(aliases=["pw", "pwhen", "pingw"])
    async def pingwhen(self, ctx):
        """Ping someone when a certain criterium is met.
        If the condition does not complete after 48 hours, then the command will terminate.
        """

    @pingwhen.command(aliases=["on"])
    async def online(self, ctx, member: discord.Member, *, message=None):
        """Ping when the user is online."""
        message = (
            f"{member.mention}, {ctx.author.mention} has sent you a scheduled ping."
            + (f" A message was attached:\n\n```\n{clean(message)}\n```"
               if message else ""))
        await ctx.send(embed=make_embed(
            title="Ping scheduled",
            description=
            f"{member.mention} will be pinged when they go online with the message:\n\n{message}",
            color=colors.EMBED_SUCCESS,
        ))
        if member.status != discord.Status.online:
            await self.bot.wait_for(
                "member_update",
                check=lambda before, after: after.id == member.id and after.
                status == discord.Status.online,
            )
        await ctx.send(message)

    @pingwhen.command(aliases=["nogame"])
    async def free(self, ctx, member: discord.Member, *, message=None):
        """Ping when the user is not playing a game."""
        message = (
            f"{member.mention}, {ctx.author.mention} has sent you a scheduled ping."
            + (f" A message was attached:\n\n```\n{message}\n```"
               if message else ""))
        await ctx.send(embed=make_embed(
            title="Ping scheduled",
            description=
            f"{member.mention} will be pinged when they stop playing a game with the message:\n\n{message}",
            color=colors.EMBED_SUCCESS,
        ))
        if member.activity:
            await self.bot.wait_for(
                "member_update",
                check=lambda before, after: after.id == member.id and after.
                activity == None,
            )
        await ctx.send(message)

    @commands.group(aliases=["ev", "feed"])
    async def event(self, ctx):
        """Commands related to events."""

    @event.command(aliases=["add"])
    async def create(self, ctx, name, *, times=""):
        """Create an event.
        If no times are given, the event will only be able to be triggered manually.
        Otherwise, you can schedule triggers, like `3 hours later` or `12:30PM`, seperated by commas.
        If you have a time added with the `time` command, your timezone will be assumed. Otherwise, UTC will be used unless you specify a timezone like `at 12:30PM EST`.
        Example usage: `event create game in two minutes, 6PM`
        """
        if name.lower() in event_config:
            await show_error(ctx, "That event already exists.")

        event = Event(name, [], [], ctx.author.id, [])
        await self.parse_times(ctx, event, times)

        event_config[name.lower()] = event
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Added event",
            description="Your event was created successfully.",
            color=colors.EMBED_SUCCESS,
        ))

    @event.command()
    async def remove(self, ctx, event: Event):
        """Remove an event."""
        if ctx.author.id != event.owner:
            await show_error(ctx, "You are not the owner of this event.")

        event_config.pop(event.name.lower())
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Deleted event",
            description="Your event was removed successfully.",
            color=colors.EMBED_SUCCESS,
        ))

    @event.command()
    async def schedule(self, ctx, event: Event, *, times):
        """Add more scheduled times to an existing event."""
        if ctx.author.id not in event.managers and ctx.author.id != event.owner:
            await show_error(ctx, "You're not a manager of this event.")

        await self.parse_times(ctx, event, times)
        await ctx.send(embed=make_embed(
            title="Scheduled time",
            description=
            "Successfully added a new scheduled time to that event.",
            color=colors.EMBED_SUCCESS,
        ))

    @event.command()
    async def trigger(self, ctx, event: Event, *, message=None):
        """Trigger an event manually."""
        if ctx.author.id not in event.managers and ctx.author.id != event.owner:
            await show_error(ctx, "You're not a manager of this event.")

        await self.trigger_event(event, message)

    @event.command(aliases=["sub", "join", "unleave"])
    async def subscribe(self, ctx, event: Event):
        """Subscribe to an event."""
        if str(ctx.author.id) in event.members:
            await show_error(ctx, "You're already subscribed to that event.")

        event.members.append(ctx.author.id)
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Subscribed to event",
            description=
            ("You were successfully subscribed to that event.\n"
             "Make sure that the bot is able to DM you, "
             "i.e. that you haven't blocked it and you have DMs from non-friends enabled on this server."
             ),
            color=colors.EMBED_SUCCESS,
        ))

    @event.command(aliases=["unsub", "leave", "unjoin"])
    async def unsubscribe(self, ctx, event: Event):
        """Unsubscribe to an event."""
        if str(ctx.author.id) not in event.members:
            await show_error(ctx, "You're not subscribed to that event.")

        event.members.remove(ctx.author.id)
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Unsubscribed to event",
            description="You were successfully unsubscribed to that event.",
            color=colors.EMBED_SUCCESS,
        ))

    @event.group(aliases=["managers"])
    async def manager(self, ctx):
        """Commands related to managers for events; that is, people who are allowed to trigger the event besides the owner."""

    @manager.command()
    async def add(self, ctx, event: Event, member: discord.Member):
        """Add a manager."""
        if ctx.author.id != event.owner:
            await show_error("You are not the owner of this event.")
        if member.id in event.managers:
            await show_error("That member is already a manager of this event.")

        event.managers.append(member.id)
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Added manager",
            description="Successfully added a manager to that event.",
            color=colors.EMBED_SUCCESS,
        ))

    @manager.command(name="remove")
    async def remove_(self, ctx, event: Event, member: discord.Member):
        """Remove a manager."""
        if ctx.author.id != event.owner:
            await show_error(ctx, "You are not the owner of this event.")
        if member.id not in event.managers:
            await show_error(ctx, "That member isn't a manager of this event.")

        event.managers.remove(member.id)
        saving = {}
        for event in event_config:
            saving[event] = list(event_config[event])
        save_json(paths.EVENT_SAVES, saving)

        await ctx.send(embed=make_embed(
            title="Removed manager",
            description="Successfully removed a manager from that event.",
            color=colors.EMBED_SUCCESS,
        ))

    @manager.command()
    async def list(self, ctx, event: Event):
        await ctx.send(embed=make_embed(
            title="Managers",
            description="\n".join(
                [self.bot.get_user(x).mention for x in event.managers]),
            color=colors.EMBED_SUCCESS,
        ))

    async def trigger_event(self, event, message=None):
        for id in event.members:
            user = self.bot.get_user(id)
            if not user:
                continue
            await user.send(embed=make_embed(
                title=f"{event.name}",
                description=message or f"This event has triggered.",
            ))

    async def parse_times(self, ctx, event, times):
        for t in times.split(","):
            parsed = dateparser.parse(
                t.strip(),
                settings={
                    "TIMEZONE": self.time_config[str(ctx.author.id)],
                    "TO_TIMEZONE": "UTC",
                },
            )
            if parsed:
                parsed_number = calendar.timegm(parsed.timetuple())
                print(parsed_number, time.time())
                while parsed_number < time.time():
                    parsed_number += 24 * 60 * 60
                event.times.append(parsed_number)
        event.times.sort()

    @tasks.loop(minutes=1)
    async def event_loop(self):
        for event in event_config:
            if (event_config[event].times
                    and time.time() >= event_config[event].times[0]):
                event_config[event].times.pop(0)
                with open(paths.CONFIG_FOLDER + "/" + paths.EVENT_SAVES,
                          "w") as f:
                    saving = {}
                    for event in event_config:
                        saving[event] = list(event_config[event])
                    json.dump(saving, f)
                await self.trigger_event(event_config[event])

    @event_loop.before_loop
    async def before_event(self):
        await self.wait_until_ready()
Пример #17
0
 def as_loop(**kwargs):
     return tasks_util.loop(**kwargs)
Пример #18
0
# --------------------------------Main startup event--------------------------------#
@bot.event
async def on_ready():
    change_status.start()
    clear_game.start()
    print("Updating databases...")
    update_guilds_data(bot, guilds_data, DEFAULT_PREFIX)
    print(
        f'Logged in as {bot.user.name}#{bot.user.discriminator} ID = {bot.user.id}'
    )


# --------------------------------Task loops--------------------------------#

loops = Loops(bot, custom_statuses)
change_status = tasks.loop(seconds=60)(loops.change_status)
clear_game = tasks.loop(seconds=10)(loops.clear_game)

# --------------------------------Events--------------------------------#
events = Events(bot,
                database,
                total_guilds_api_url,
                guild_prefix_storage,
                disabled_commands_store,
                DEFAULT_PREFIX, [
                    "help", "kick", "ban", "warn", "warninfo", "warns", "mute",
                    "unmute", "clear"
                ],
                ChintuAI=True)
bot.event(events.on_command_error)
bot.event(events.on_message)