async def free_games_notifier(self): ids = [742205149862428702] channels = [self.bot.get_channel(x) for x in ids] with database.connection_context(): for subreddit in Subreddit.select().where( Subreddit.automatic == False): post = subreddit.latest_post if post is None: return id = post.url.split("comments/")[1].split("/")[0] submission = self.bot.reddit.submission(id) skipped_channel_ids = [] game = FreeGame.from_reddit_submission(submission) embed = game.get_embed() if game.type not in (FreeGameType.steam, FreeGameType.gog, FreeGameType.epicgames, FreeGameType.unknown): skipped_channel_ids.append(784439833975062546) channels.append(subreddit.sendable) for channel in [ x for x in channels if x.id not in skipped_channel_ids ]: asyncio.gather(channel.send(embed=embed))
async def stats_ticker(self): with database.connection_context(): query = Pigeon.select() query = query.where(Pigeon.condition == Pigeon.Condition.active) query = query.where(Pigeon.status == Pigeon.Status.idle) for pigeon in query: data = { "food": -1, "health": -0, "happiness": -1, "cleanliness": -1, } for pigeon_buff in pigeon.buffs: if pigeon_buff.buff.code == "fully_fed": data["food"] = 0 if pigeon_buff.buff.code == "bleeding": data["health"] += -2 if pigeon.food <= 20 or pigeon.cleanliness <= 20: data["health"] += -1 if pigeon.food == 0: data["health"] += -2 pigeon.update_stats(data) pigeon.save()
async def before_any_command(self, ctx): ctx.db = database.connection_context() ctx.db.__enter__() ctx.get_id = self.get_id if ctx.guild is not None and ctx.guild.id not in self._locales: settings, _ = Settings.get_or_create(guild_id=ctx.guild.id) self._locales[ctx.guild.id] = settings.locale.name ctx.get_human = lambda user=None: self.get_human(ctx, user=user) ctx.locale = self._locales.get(ctx.get_id(ctx.guild), "en_US") ctx.translate = lambda x: self.translate(x, ctx.locale) ctx.success = self.success(ctx) ctx.error = self.error(ctx) ctx.raise_if_not_enough_gold = self.raise_if_not_enough_gold(ctx) ctx.guild_color = self.get_dominant_color(ctx.guild) timeout = 60 if ctx.author.id in self.cooldowned_users: if ctx.author.id not in self.cooldowns: self.cooldowns[ctx.author.id] = datetime.datetime.utcnow() else: difference_in_seconds = (datetime.datetime.utcnow() - self.cooldowns[ctx.author.id]).seconds if difference_in_seconds != 0 and difference_in_seconds < timeout: raise commands.errors.CommandOnCooldown( None, retry_after=(timeout - difference_in_seconds)) else: self.cooldowns[ctx.author.id] = datetime.datetime.utcnow()
async def poller(self): with database.connection_context(): query = CategoryChannel.select() query = query.where((CategoryChannel.last_day == None) | ( CategoryChannel.last_day < datetime.datetime.utcnow().date())) for category_channel in query: query = Question.select() query = query.where( Question.category == category_channel.category) query = query.join(QuestionConfig, peewee.JOIN.LEFT_OUTER) query = query.where((QuestionConfig.question == None) | (QuestionConfig.asked == False)) query = query.order_by(peewee.fn.Rand()) query = query.limit(1) question = query.first() if question is None: continue question_config, _ = QuestionConfig.get_or_create( question=question, category_channel=category_channel) question_config.asked = True question_config.save() category_channel.last_day = datetime.datetime.utcnow().date() category_channel.save() asyncio.gather(category_channel.channel.send(question.value))
def on_milkyway_purchased(self, channel, member, amount): with database.connection_context(): item = Item.get(code="milky_way") human = self.bot.get_human(user=member) human.add_item(item, amount) embed = discord.Embed(color=self.bot.get_dominant_color(None)) embed.description = f"Good job in purchasing {amount} milky way(s).\nInstructions:\n`/milkyway create` or `/milkyway extend #channel`" asyncio.gather(channel.send(embed=embed))
def set_active_or_create(self, member): if member.bot: return with database.connection_context(): earthling, created = Earthling.get_or_create_for_member(member) if not created: earthling.last_active = datetime.datetime.utcnow() earthling.save()
async def on_raw_reaction_add(self, payload): if not self.any_active_polls: return if not self.bot.production: return emoji = str(payload.emoji) member = payload.member if member is None: return if member.bot: return channel = self.bot.get_channel(payload.channel_id) try: message = await channel.fetch_message(payload.message_id) except discord.errors.NotFound: return if not message.author.bot: return with database.connection_context(): try: poll = Poll.get(message_id = payload.message_id, ended = False) except Poll.DoesNotExist: return allowed_reactions = {x.reaction:x for x in poll.options} if emoji not in allowed_reactions: return if poll.anonymous: asyncio.gather(message.remove_reaction(emoji, member)) option = allowed_reactions[emoji] if poll.role_id_needed_to_vote is not None: role = member.guild.get_role(poll.role_id_needed_to_vote) if role not in member.roles: #TODO: translate! return asyncio.gather(member.send(embed = Embed.error(f"To vote for this poll you need the **{role}** role."))) new_vote, created = Vote.get_or_create(option = option, user_id = member.id) votes = [new_vote] for option in poll.options: vote = option.votes.where(Vote.user_id == member.id).first() if vote is not None and vote not in votes: votes.append(vote) votes.sort(key = lambda x : x.voted_on) for i in range(0, len(votes)-poll.max_votes_per_user): vote = votes[i] vote.delete_instance()
async def earthling_purger(self): with database.connection_context(): to_purge = [] earthlings = list(Earthling) for earthling in earthlings: if earthling.guild is None or earthling.member is None: to_purge.append(earthling) if len(to_purge) != len(earthlings): for earthling in to_purge: role = earthling.personal_role if role is not None: await role.delete() earthling.delete_instance()
async def temp_channel_checker(self): with database.connection_context(): query = TemporaryChannel.select() query = query.where(TemporaryChannel.active == True) query = query.where(TemporaryChannel.expiry_date != None) query = query.where( TemporaryChannel.expiry_date <= datetime.datetime.utcnow()) for temp_channel in query: channel = temp_channel.channel temp_channel.active = False if channel is not None: await channel.delete(reason="Expired") temp_channel.channel_id = None temp_channel.save()
async def illegal_member_notifier(self): for member in self.guild.members: if member.bot: continue if not member_is_legal(member): with database.connection_context(): time_here = relativedelta(datetime.datetime.utcnow(), member.joined_at) if time_here.hours >= 6: asyncio.gather( member.kick(reason="Missing mandatory roles.")) await self.log( "c3po-log", f"**{member}** {member.mention} was kicked due to missing roles" )
async def fight_ticker(self): with database.connection_context(): query = Fight.select() query = query.where(Fight.finished == False) query = query.where(Fight.accepted == True) query = query.where(Fight.end_date <= datetime.datetime.utcnow()) for fight in query: won = random.randint(0, 1) == 0 guild = fight.guild channel = self.get_pigeon_channel(guild) if won: winner = fight.challenger loser = fight.challengee else: winner = fight.challengee loser = fight.challenger embed = self.get_base_embed(guild) embed.description = f"`{winner.name}` creeps into `{loser.name}`’s room. `{winner.name}`’s jaw unhinges and swallows `{loser.name}` whole." winner_data = {"experience": 30, "health": -10} loser_data = {"experience": 5, "health": -25} embed.add_field(name=f"💩 {loser.name} ({loser.human.user})", value=get_winnings_value(**loser_data, gold=-fight.bet)) embed.add_field(name=f"🏆 {winner.name} ({winner.human.user})", value=get_winnings_value(**winner_data, gold=fight.bet)) asyncio.gather( channel.send( content= f"{winner.human.mention} | {loser.human.mention}", embed=embed)) winner.status = Pigeon.Status.idle loser.status = Pigeon.Status.idle winner_data["gold"] = fight.bet * 2 winner.update_stats(winner_data) loser.update_stats(loser_data) fight.won = won fight.finished = True fight.save()
async def birthday_poller(self): now = datetime.datetime.utcnow() query = Human.select() query = query.join(Earthling, on=(Human.id == Earthling.human)) query = query.where(Earthling.guild_id == self.guild.id) query = query.where(Human.date_of_birth != None) query = query.where(Human.date_of_birth.month == now.month) query = query.where(Human.date_of_birth.day == now.day) query = query.order_by(Human.date_of_birth.asc()) with database.connection_context(): for human in query: await self.log( "c3po-log", f"**{human.user}** {human.mention} Should be celebrating their birthday today." )
async def prank_poller(self): with database.connection_context(): pranks = [NicknamePrank, RolePrank, EmojiPrank] for cls in pranks: query = cls.select() query = query.where(cls.finished == False) if cls != NicknamePrank: query = query.where( cls.end_date <= datetime.datetime.utcnow()) for prank in query: if cls != NicknamePrank or prank.end_date_passed: prank.finished = True prank.victim.pranked = False prank.victim.prank_type = None prank.save() prank.victim.save() if prank.victim.member: asyncio.gather(prank.revert()) else: if prank.should_reapply: asyncio.gather(prank.apply())
def remove_points(self, points): with database.connection_context(): human = config.bot.get_human(user=self.member) human.gold -= points human.save()
def predicate(ctx): with database.connection_context(): human = config.bot.get_human(user = ctx.author) return human.tester
async def temp_vc_poller(self): with database.connection_context(): for temporary_voice_channel in TemporaryVoiceChannel: channel = temporary_voice_channel.channel if channel is None or len(channel.members) == 0: temporary_voice_channel.delete_instance()
def get_pigeon_channel(self, guild): with database.connection_context(): settings, _ = Settings.get_or_create(guild_id=guild.id) return settings.get_channel("pigeon")
async def poller(self): with database.connection_context(): query = Giveaway.select() query = query.where(Giveaway.finished == False) query = query.where( Giveaway.due_date <= datetime.datetime.utcnow()) for giveaway in query: channel = giveaway.channel try: message = await channel.fetch_message(giveaway.message_id) except discord.errors.NotFound: giveaway.finished = True giveaway.save() continue reaction = [ x for x in message.reactions if str(x.emoji) == self.participate_emoji ][0] role_needed = giveaway.role_needed participants = [] for user in await reaction.users().flatten(): if isinstance(user, discord.User) or user.bot: continue if role_needed is None or role_needed in user.roles: participants.append(user) if len(participants) == 0: continue random.shuffle(participants) if len(participants) >= giveaway.amount: winners = participants[:giveaway.amount] else: winners = [x for x in participants] while len(winners) < giveaway.amount: winners.append(random.choice(participants)) embed = message.embeds[0] notes = [f"**{giveaway.title}**\n"] for winner in winners: notes.append(f"Winner: **{winner}**") embed.description = "\n".join(notes) embed.timestamp = discord.Embed.Empty embed.set_footer(text=discord.Embed.Empty) await message.edit(embed=embed) for winner in winners: dm_owner = giveaway.key is None if not dm_owner: try: await winner.send( f"Congratulations, you won giveaway **{giveaway.id}**\n`{giveaway.title}`\nHere are your rewards:\n`{giveaway.key}`" ) except discord.errors.Forbidden: dm_owner = True if dm_owner: await giveaway.user.send( f"Giveaway **{giveaway.id}** has been won by **{winner}**. They will have to be informed and their rewards sent by you." ) asyncio.gather(message.clear_reactions()) giveaway.finished = True giveaway.save()
async def date_ticker(self): with database.connection_context(): query = Date.select() query = query.where(Date.finished == False) query = query.where(Date.accepted == True) query = query.where(Date.end_date <= datetime.datetime.utcnow()) for date in query: guild = date.guild channel = self.get_pigeon_channel(guild) embed = self.get_base_embed(guild) score = 0 lines = [] for pigeon in (date.pigeon1, date.pigeon2): other = date.pigeon1 if pigeon == date.pigeon2 else date.pigeon2 if pigeon.cleanliness >= 60: lines.append( f"{pigeon.name} smells like fresh fries, delicious (+10)" ) score += 10 elif pigeon.cleanliness >= 40: lines.append( f"{pigeon.name} has a slight body odor, but it's tolerable (+0)" ) elif pigeon.cleanliness >= 20: lines.append( f"{pigeon.name} has a clear body odor. (-10)") score -= 10 else: lines.append( f"{pigeon.name} is caked in feces, absolutely disgusting! (-20)" ) score -= 20 if pigeon.food >= 60: lines.append( f"{pigeon.name} ellegantly and majestically enjoys {pigeon.gender.get_posessive_pronoun()} fry. (+10)" ) score += 10 elif pigeon.food >= 30: lines.append( f"{pigeon.name} is clearly a bit hungry but still manages to (barely) not embarrass {pigeon.gender.get_pronoun(object = True)}self (+0)" ) else: lines.append( f"{pigeon.name} is starving. As soon as {pigeon.gender.get_pronoun()} sees a fry {pigeon.gender.get_pronoun()} starts to drool, runs at it like a wild animal and devours it in one go. How unappealing. (-10)" ) score -= 10 if pigeon.health <= 30: lines.append( f"{pigeon.name} is covered in blood. {pigeon.gender.get_pronoun()} tries to make it work but accidentally drips some blood on {other.name}s fry . Not a good sauce. (-10)" ) score -= 10 if pigeon.happiness >= 60: lines.append( f"{pigeon.name} smiled in confidence the entire date. (+10)" ) score += 10 elif pigeon.happiness >= 30: lines.append( f"{pigeon.name} was clearly not in his best spirits. Slightly bringing his date down as well. (-5)" ) score -= 5 else: lines.append( f"{pigeon.name} is miserable. From the start, {pigeon.gender.get_pronoun()} starts asking what the point of this date even is, what the point of anything is, and why {pigeon.gender.get_pronoun()} should even bother eating at all. (-10)" ) score -= 10 lines = "\n- " + ("\n\n- ".join(lines)) embed.description = f"{lines}\n\nScore: **{score}**" embed.set_footer(text=f"{score // 10} relations") asyncio.gather(channel.send(embed=embed)) for pigeon in date.pigeons: pigeon.status = Pigeon.Status.idle pigeon.save() date.score = score relationship = PigeonRelationship.get_or_create_for( date.pigeon1, date.pigeon2) relationship.score += date.score // 10 relationship.save() date.finished = True date.save()
def location_save(): post = json.loads(request.data) with database.connection_context(): location = Location.create(**post) return {"success": True, "id": location.id}
def is_tester(member): with database.connection_context(): human = config.bot.get_human(user=member) return human.tester