Exemple #1
0
    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))
Exemple #2
0
    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()
Exemple #4
0
    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))
Exemple #5
0
    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()
Exemple #9
0
 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()
Exemple #10
0
    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"
                        )
Exemple #11
0
    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()
Exemple #12
0
    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."
                )
Exemple #13
0
    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())
Exemple #14
0
 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
Exemple #16
0
 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()
Exemple #17
0
 def get_pigeon_channel(self, guild):
     with database.connection_context():
         settings, _ = Settings.get_or_create(guild_id=guild.id)
     return settings.get_channel("pigeon")
Exemple #18
0
    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()
Exemple #19
0
    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()
Exemple #20
0
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