async def load_giveaways(self): sql = 'SELECT * FROM `giveaways`' try: rows = (await self.bot.dbutil.execute(sql)).fetchall() except SQLAlchemyError: logger.exception('Failed to load giveaways') return for row in rows: guild = row['guild'] channel = row['channel'] message = row['message'] title = row['title'] winners = row['winners'] timeout = max( (row['expires_in'] - datetime.utcnow()).total_seconds(), 0) if message in self.bot.every_giveaways: self.bot.every_giveaways[message].cancel() fut = call_later( self.remove_every, self.bot.loop, timeout, guild, channel, message, title, winners, after=lambda f: self.bot.every_giveaways.pop(message)) self.bot.every_giveaways[message] = fut
def __init__(self, bot): super().__init__(bot) self.gachilist = self.bot.gachilist if not self.gachilist: self.reload_gachilist() self.reload_call = call_later(self._reload_and_post, self.bot.loop, self.time2tomorrow())
async def _toggle_every(self, channel, winners: int, expires_in): guild = channel.guild perms = channel.permissions_for(guild.get_member(self.bot.user.id)) if not perms.manage_roles and not perms.administrator: return await channel.send('Invalid server perms') role = guild.get_role(323098643030736919 if not self.bot.test_mode else 440964128178307082) if role is None: return await channel.send('Every role not found') sql = 'INSERT INTO `giveaways` (`guild`, `title`, `message`, `channel`, `winners`, `expires_in`) VALUES (:guild, :title, :message, :channel, :winners, :expires_in)' now = datetime.utcnow() expired_date = now + expires_in sql_date = datetime2sql(expired_date) title = 'Toggle the every role on the winner.' embed = discord.Embed( title='Giveaway: {}'.format(title), description= 'React with <:GWjojoGachiGASM:363025405562585088> to enter', timestamp=expired_date) text = 'Expires at' if winners > 1: text = '{} winners | '.format(winners) + text embed.set_footer(text=text, icon_url=get_avatar(self.bot.user)) message = await channel.send(embed=embed) try: await message.add_reaction('GWjojoGachiGASM:363025405562585088') except: pass try: await self.bot.dbutil.execute(sql, params={ 'guild': guild.id, 'title': 'Toggle every', 'message': message.id, 'channel': channel.id, 'winners': winners, 'expires_in': sql_date }, commit=True) except SQLAlchemyError: logger.exception('Failed to create every toggle') return await channel.send('SQL error') task = call_later(self.remove_every, self.bot.loop, expires_in.total_seconds(), guild.id, channel.id, message.id, title, winners) self.bot.every_giveaways[message.id] = task
async def call_later(self, ctx, *, call): msg = ctx.message # Parse timeout can basically parse anything where you want time # separated from the rest run_in, call = parse_timeout(call) msg.content = f'{ctx.prefix}{call}' new_ctx = await self.bot.get_context(msg) self.bot.call_laters[msg.id] = call_later(self.bot.invoke, self.bot.loop, run_in.total_seconds(), new_ctx, after=functools.partial(self.remove_call, msg_id=msg.id)) await ctx.send(f'Scheduled call `{msg.id}` to run in {seconds2str(run_in.total_seconds(), False)}')
async def _reload_and_post(self): self.reload_gachilist() for guild in self.bot.guilds: vid = Random(self.get_day() + guild.id).choice(self.gachilist) channel = self.bot.guild_cache.dailygachi(guild.id) if not channel: continue channel = guild.get_channel(channel) if not channel: continue try: await channel.send(f'Daily gachi {vid}') except: pass self.reload_call = call_later(self._reload_and_post, self.bot.loop, self.time2tomorrow())