コード例 #1
0
ファイル: SlashGroups.py プロジェクト: bsavage81/TheOldKing
class Example2(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    greetings = SlashCommandGroup("greetings", "Various greeting from cogs!")

    international_greetings = greetings.create_subgroup(
        "international", "International greetings")

    secret_greetings = SlashCommandGroup(
        "secret_greetings",
        "Secret greetings",
        permissions=[
            CommandPermission(
                "owner", 2, True
            )  # Ensures the owner_id user can access this, and no one else
        ],
    )

    @greetings.command()
    async def hello(self, ctx):
        await ctx.respond("Hello, this is a slash subcommand from a cog!")

    @international_greetings.command()
    async def aloha(self, ctx):
        await ctx.respond("Aloha, a Hawaiian greeting")

    @secret_greetings.command()
    async def secret_handshake(self, ctx, member: discord.Member):
        await ctx.respond(f"{member.mention} secret handshakes you")
コード例 #2
0
class RepCommands(Cog):
    def __init__(self, bot):
        self.bot = bot

    repGroup = SlashCommandGroup('rep', 'Give out reputation points')

    @repGroup.command(name='lead', description='Rep leaderboards!')
    async def leaderboard(self, ctx):
        formatted = '\n'.join([f'{rank}: {details[0]} ({details[1]} points)' for rank, details in
                               enumerate(leader_list(await ctx.guild.fetch_members().flatten()), start=1)])
        embed = Embed(title='Current Rep Leaderboard:', description=formatted)
        await ctx.respond('', embed=embed)

    @repGroup.command(name='give', description='Give a reputation point!')
    async def give_rep(self, ctx, target: Option(Member, 'Who gets the rep?')):
        if ctx.user.id == target.id:
            return await self.rep_check(ctx, target)
        giver = load_user(ctx.user)
        if giver.get_pool() > 0:
            giver.spend_pool()
            receiver = load_user(target)
            receiver.received += 1
            save_user(giver, ctx.user)
            save_user(receiver, target)
            await ctx.respond(f'{ctx.user.mention}, you gave a rep to {target.mention}!')
        else:
            await ctx.respond(f'Sorry {ctx.user.mention}, you have no rep to give!', ephemeral=True)

    @repGroup.command(name='check', description='Check the rep a user has accumulated.')
    async def rep_check(self, ctx,
                        target: Option(Member, 'Whose rep do you want to view?', required=False)):
        if target:
            user = target
        else:
            user = ctx.user
        rep_info = load_user(user)
        await ctx.respond(
            f'{user.mention} has received {rep_info.received} rep and has {rep_info.get_pool()} rep available to give!')
コード例 #3
0
class Music(commands.Cog, name="🎵 Muzyka (beta)"):
    def __init__(self, bot: Atorin):
        self.bot = bot

        if self.bot and not hasattr(self.bot, "lavalink"):
            lavalink.add_event_hook(self.track_hook)
            self.bot.lavalink = lavalink.Client(
                config["dashboard"]["client_id"])
            self.bot.lavalink.add_node(address, port, password, region, node)
            self.bot.add_listener(self.bot.lavalink.voice_update_handler,
                                  "on_socket_response")

    def cog_unload(self):
        """Cog unload handler. This removes any event hooks that were registered."""
        self.bot.lavalink._event_hooks.clear()

    async def cog_before_invoke(self, ctx):
        """Command before-invoke handler."""
        guild_check = ctx.guild is not None
        #  This is essentially the same as `@commands.guild_only()`
        #  except it saves us repeating ourselves (and also a few lines).

        if guild_check:
            await self.ensure_voice(ctx)
            #  Ensure that the bot and command author share a mutual voicechannel.

        return guild_check

    async def ensure_voice(self, ctx):
        # These are commands that doesn't require author to join a voicechannel
        if ctx.command.name in ("lyrics", ):
            return True
        """This check ensures that the bot and command author are in the same voicechannel."""
        player = self.bot.lavalink.player_manager.create(ctx.guild.id,
                                                         endpoint=str(
                                                             ctx.guild.region))
        # Create returns a player if one exists, otherwise creates.

        # These are commands that require the bot to join a voicechannel (i.e. initiating playback).
        if isinstance(ctx.command, str):
            should_connect = ctx.command in ("play", )
        else:
            should_connect = ctx.command.name in ("play", )

        if not ctx.author.voice or not ctx.author.voice.channel:
            raise commands.CommandError(
                "Musisz być połączony do kanału głosowego!")

        if not player.is_connected:
            if not should_connect:
                raise commands.CommandError("Atorin nie odtwarza muzyki!")

            permissions = ctx.author.voice.channel.permissions_for(ctx.me)

            if not permissions.connect or not permissions.speak:
                raise commands.CommandError(
                    "Atorin nie ma uprawnień potrzebnych do odtwarzania muzyki."
                    " Daj roli `Atorin` uprawnienia `Łączenie` oraz `Mówienie`"
                    " i spróbuj ponownie.")

            player.store("channel", ctx.channel.id)
            await ctx.author.voice.channel.connect(cls=LavalinkVoiceClient)
        else:
            if int(player.channel_id) != ctx.author.voice.channel.id:
                raise commands.CommandError(
                    "Nie jesteś połączony do kanału na którym jest Atorin!")

    async def track_hook(self, event):
        if isinstance(event, lavalink.events.QueueEndEvent):
            guild_id = int(event.player.guild_id)
            guild: discord.Guild = self.bot.get_guild(guild_id)
            player = self.bot.lavalink.player_manager.get(guild_id)
            if not player.is_connected:
                return
            player.queue.clear()
            await player.stop()
            await guild.voice_client.disconnect(force=True)
        if isinstance(event, lavalink.events.TrackStartEvent):
            song = event.track
            channel = self.bot.get_channel(event.player.fetch("channel"))
            embed = discord.Embed()
            embed.title = "Teraz odtwarzane"
            embed.add_field(name="🎧 Utwór", value=song.title, inline=False)
            if not song.duration == 9223372036854775807:
                embed.add_field(
                    name="🛤️ Długość",
                    value=str(
                        timedelta(milliseconds=song.duration)).split(".")[0],
                )
            else:
                embed.add_field(name="🛤️ Długość", value="🔴 Na żywo")
            embed.add_field(name="💃 Zaproponowany przez",
                            value=f"<@{song.requester}>")
            embed.set_thumbnail(
                url=
                f"https://img.youtube.com/vi/{song.identifier}/maxresdefault.jpg"
            )
            await channel.send(embed=embed)

    @slash_command(
        description=
        "Odtwarza utwór lub playlistę z YT/Twitch/MP3 na kanale głosowym",
        guild_ids=config["guild_ids"],
    )
    async def play(
            self,
            ctx: discord.ApplicationContext,
            query: Option(str, "Tytuł lub link do Youtube/Twitch/MP3"),
    ):
        """Searches and plays a song from a given query."""
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        query = query.strip("<>")

        if not url_rx.match(query):
            query = f"ytsearch:{query}"
        else:
            if "open.spotify.com/track/" in query:
                song = get_song_from_spotify(
                    query.split("open.spotify.com/track/")[1].split("?")[0])
                query = f"ytsearch:{song}"
            elif "spotify:track:" in query:
                song = get_song_from_spotify(query.split("spotify:track:")[1])
                query = f"ytsearch:{song}"

        results = await player.node.get_tracks(query)

        if not results or not results["tracks"]:
            return await ctx.send_followup(
                "❌ Nie znaleziono utworu o podanej nazwie!")

        embed = discord.Embed()

        # Valid loadTypes are:
        #   TRACK_LOADED    - single video/direct URL)
        #   PLAYLIST_LOADED - direct URL to playlist)
        #   SEARCH_RESULT   - query prefixed with either ytsearch: or scsearch:.
        #   NO_MATCHES      - query yielded no results
        #   LOAD_FAILED     - most likely, the video encountered an exception during loading.
        if results["loadType"] == "PLAYLIST_LOADED":
            tracks = results["tracks"]

            for track in tracks:
                player.add(requester=ctx.author.id, track=track)

            embed.title = "Dodano playlistę do kolejki!"
            embed.description = (
                f'{results["playlistInfo"]["name"]} - {len(tracks)} utworów')
        else:
            track = results["tracks"][0]
            embed.title = "Dodano do kolejki"
            embed.description = f'[{track["info"]["title"]}]({track["info"]["uri"]})'
            embed.set_thumbnail(
                url=
                f"https://img.youtube.com/vi/{track['info']['identifier']}/maxresdefault.jpg"
            )
            track = lavalink.models.AudioTrack(track, ctx.author.id)
            player.add(requester=ctx.author.id, track=track)

        await ctx.send_followup(embed=embed)

        if not player.is_playing:
            await player.play()

    @slash_command(description="Rozłącza bota z kanału głosowego",
                   guild_ids=config["guild_ids"])
    async def stop(self, ctx: discord.ApplicationContext):
        """Disconnects the player from the voice channel and clears its queue."""
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.is_playing:
            player.queue.clear()
            await player.stop()
            await ctx.voice_client.disconnect(force=True)
            embed = discord.Embed()
            embed.description = "⏹ **Zatrzymano odtwarzanie.**"
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    @slash_command(description="Wstrzymuje odtwarzanie muzyki",
                   guild_ids=config["guild_ids"])
    async def pause(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if not player.paused:
            await player.set_pause(True)
            embed = discord.Embed()
            embed.description = (
                "⏸ **Wstrzymano odtwarzanie. Aby wznowić wpisz `/resume`.**")
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    @slash_command(description="Wznawia odtwarzanie muzyki",
                   guild_ids=config["guild_ids"])
    async def resume(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.paused:
            await player.set_pause(False)
            embed = discord.Embed()
            embed.description = "▶️ **Wznowiono odtwarzanie.**"
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    @slash_command(description="Pomija aktualnie odtwarzany utwór",
                   guild_ids=config["guild_ids"])
    async def skip(
        self,
        ctx: discord.ApplicationContext,
        number: Option(int,
                       "Podaj numer utworu który chcesz odtworzyć",
                       min_value=1) = None,
    ):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.is_playing:
            if number:
                if number > len(player.queue):
                    raise commands.BadArgument(
                        "Podano niepoprawny numer utworu! Sprawdź kolejkę komendą `/queue view`"
                    )
                player.queue = player.queue[number - 1:]
            await player.skip()
            embed = discord.Embed()
            embed.description = "⏭ ️**Pominięto utwór.**"
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    @slash_command(
        description="Ustawia głośność aktualnie odtwarzanego utworu",
        guild_ids=config["guild_ids"],
    )
    async def volume(
        self,
        ctx: discord.ApplicationContext,
        vol: Option(int, "Głośność od 1 do 100", min_value=1, max_value=100),
    ):
        await ctx.defer()
        if vol > 100 or vol < 0:
            raise commands.BadArgument(
                "Wartość musi być w przedziale od 1 do 100!")
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.is_playing:
            await player.set_volume(vol)
            embed = discord.Embed()
            embed.description = f"🔉 **Ustawiono glośność na {vol}%.**"
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    queue_group = SlashCommandGroup(
        "queue",
        "Komendy do zarządzania kolejką odtwarzania",
        guild_ids=config["guild_ids"],
    )

    @queue_group.command(
        name="view",
        description="Wyświetla kolejkę utworów do odtworzenia",
    )
    async def queue_view(self, ctx: discord.ApplicationContext):
        emoji_numbers = {
            1: "1️⃣",
            2: "2️⃣",
            3: "3️⃣",
            4: "4️⃣",
            5: "5️⃣",
            6: "6️⃣",
            7: "7️⃣",
            8: "8️⃣",
            9: "9️⃣",
            10: "🔟",
        }
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        embed = discord.Embed()
        if not player.queue:
            embed.description = "🕳️ **Kolejka jest pusta!**"
            return await ctx.send_followup(embed=embed)
        fmt = "\n".join(f"{emoji_numbers[i]} **{song.title}**"
                        for i, song in enumerate(player.queue, start=1))
        embed.title = f"Utwory w kolejce: {len(player.queue)}"
        embed.description = fmt
        await ctx.send_followup(embed=embed)

    @queue_group.command(
        name="clear",
        description="Czyści kolejkę",
    )
    async def queue_clear(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        embed = discord.Embed()
        if not player.queue:
            embed.description = "🕳️ **Kolejka jest pusta!**"
            return await ctx.send_followup(embed=embed)
        embed.title = "Wyczyszczono kolejkę"
        embed.description = (
            f"✅  **Pomyślnie usunięto *{len(player.queue)}* utworów z kolejki.**"
        )
        player.queue = []
        await ctx.send_followup(embed=embed)

    @queue_group.command(
        name="remove",
        description="Usuwa z kolejki podany utwór",
    )
    async def queue_remove(
            self,
            ctx: discord.ApplicationContext,
            number: Option(int, "Wpisz numer utworu w kolejce", min_value=1),
    ):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        embed = discord.Embed()
        if not player.queue:
            embed.description = "🕳️ **Kolejka jest pusta!**"
            return await ctx.send_followup(embed=embed)
        try:
            song: lavalink.AudioTrack = player.queue.pop(number - 1)
        except IndexError:
            raise commands.BadArgument(
                "Podano niepoprawny numer utworu! Sprawdź kolejkę komendą `/queue view`"
            )
        embed.title = "Usunięto z kolejki"
        embed.description = f"🗑 {song.title}"
        await ctx.send_followup(embed=embed)

    @slash_command(
        description="Wyświetla aktualnie odtwarzany utwór",
        guild_ids=config["guild_ids"],
    )
    async def nowplaying(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.is_playing:
            song: lavalink.AudioTrack = player.current
            embed = discord.Embed()
            embed.title = "Teraz odtwarzane"
            embed.add_field(name="🎧 Utwór", value=song.title, inline=False)
            if not song.duration == 9223372036854775807:
                duration = str(timedelta(milliseconds=song.duration))
                position = str(timedelta(
                    milliseconds=round(player.position))).split(".")[0]
                progress = progress_bar(
                    round(player.position) / song.duration * 100)[:-5]
                embed.add_field(
                    name="🛤️ Postęp",
                    value=f"```css\n{progress} {position}/{duration}```",
                    inline=False,
                )
            else:
                embed.add_field(name="🛤️ Postęp", value="🔴 Na żywo")

            embed.add_field(
                name="🔂 Powtarzanie utworu",
                value="✅ Włączone" if player.repeat else "❌ Wyłączone",
            )
            embed.add_field(name="🔉 Głośność", value=f"{player.volume}%")
            embed.add_field(
                name="🎚 Bass Boost",
                value="✅ Włączony"
                if player.fetch("bassboost") else "❌ Wyłączony",
            )
            embed.add_field(
                name="🔀 Losowo",
                value="✅ Włączony" if player.shuffle else "❌ Wyłączony")
            embed.add_field(
                name="💃 Zaproponowany przez",
                value=f"<@{song.requester}>",
            )
            embed.set_thumbnail(
                url=
                f"https://img.youtube.com/vi/{song.identifier}/maxresdefault.jpg"
            )
            await ctx.send_followup(embed=embed)
        else:
            raise commands.CommandError("Atorin nie odtwarza muzyki!")

    @slash_command(
        description="Ustawia powtarzanie aktualnie odtwarzanego utworu",
        guild_ids=config["guild_ids"],
    )
    async def loop(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.repeat:
            player.repeat = False
        else:
            player.repeat = True
        await ctx.send_followup(
            f"🔂 Powtarzanie aktualnego utworu zostało {'włączone' if player.repeat else 'wyłączone'}."
        )

    @slash_command(description="Ustawia losowe odtwarzanie kolejki",
                   guild_ids=config["guild_ids"])
    async def shuffle(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        if player.shuffle:
            player.shuffle = False
        else:
            player.shuffle = True
        await ctx.send_followup(
            f"🔀 Losowe odtwarzanie kolejki zostało {'włączone' if player.shuffle else 'wyłączone'}."
        )

    @slash_command(description="Bass Boost", guild_ids=config["guild_ids"])
    async def bassboost(self, ctx: discord.ApplicationContext):
        await ctx.defer()
        player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
            ctx.guild.id)
        equalizer = lavalink.filters.Equalizer()
        if not player.fetch("bassboost"):
            bands = [(0, 0.25), (1, 0.25), (2, 0.25)]
            equalizer.update(bands=bands)
            await player.set_filter(equalizer)
            player.store("bassboost", True)
        else:
            await player.remove_filter(equalizer)
            player.store("bassboost", False)
        await ctx.send_followup(
            f"🎚 Bass boost został **{'włączony' if player.fetch('bassboost') else 'wyłączony'}**."
        )

    @slash_command(description="Tekst piosenki", guild_ids=config["guild_ids"])
    async def lyrics(
        self,
        ctx: discord.ApplicationContext,
        title: Option(
            str,
            "Podaj tytuł utworu lub pozostaw puste, jeśli chcesz tekst aktualnie odtwarzanego utworu",
        ) = None,
    ):
        await ctx.defer()
        from_player: bool = False
        if not title:
            player: lavalink.DefaultPlayer = self.bot.lavalink.player_manager.get(
                ctx.guild.id)
            if not player or not player.is_playing:
                raise commands.BadArgument(
                    "Atorin nie odtwarza muzyki, musisz podać tytuł utworu!")
            song: lavalink.AudioTrack = player.current
            title: str = song.title.split(" (")[0]
            from_player = True
        search = requests.get(
            "https://genius.com/api/search/multi",
            params={"q": title},
            headers={"User-agent": "Atorin"},
        )
        if not search.status_code == 200:
            raise commands.CommandError(
                f"Wystąpił błąd podczas wyszukiwania tekstu piosenki! [{search.status_code}]"
            )
        search_data = search.json()["response"]["sections"]
        if not search_data:
            if from_player:
                raise commands.BadArgument(
                    "Nie znaleziono tekstu odtwarzanego utworu! Spróbuj wpisać komendę jeszcze raz, podając tytuł utworu."
                )
            else:
                raise commands.BadArgument(
                    "Nie znaleziono tekstu podanego utworu!")
        for section in search_data:
            if section["type"] == "song":
                lyrics_data = section["hits"][0]["result"]
        lyrics_url = lyrics_data["path"]
        lyrics_artist = lyrics_data["artist_names"]
        lyrics_title = lyrics_data["title"]
        lyrics_thumbnail = lyrics_data["song_art_image_url"]
        r = requests.get(f"https://genius.com{lyrics_url}",
                         headers={"User-agent": "Atorin"})
        if not r.status_code == 200:
            raise commands.CommandError(
                f"Wystąpił błąd podczas pobierania tekstu piosenki! [{r.status_code}]"
            )
        soup = BeautifulSoup(r.content, "html.parser")
        containers: list[Tag] = soup.find_all(
            "div", attrs={"data-lyrics-container": "true"})
        if not containers:
            raise commands.CommandError(
                f"Wystąpił błąd podczas przetwarzania tekstu!")
        lyrics: str = ""
        for container in containers:
            i_tags: list[Tag] = container.find_all("i")
            for tag in i_tags:
                tag.replace_with(f"*{tag.text}*")
            b_tags: list[Tag] = container.find_all("b")
            for tag in b_tags:
                tag.replace_with(f"**{tag.text}**")
            lyrics += container.get_text("\n", strip=True) + "\n"
        splited_lyrics = lyrics.splitlines()
        for i, line in enumerate(splited_lyrics):
            if line.startswith("[") and line.endswith("]"):
                splited_lyrics[i] = f"\n**{line}**"
        lyrics = "\n".join(splited_lyrics)
        embed = discord.Embed()
        embed.title = f"🎶 {lyrics_artist} - {lyrics_title}"
        embed.set_thumbnail(url=lyrics_thumbnail)
        if len(lyrics) > 4096:
            splited_message = []
            limit = 4096
            for i in range(0, len(lyrics), limit):
                splited_message.append(lyrics[i:i + limit])
                if i > 2:
                    break
            embed.description = splited_message.pop(0)
            await ctx.send_followup(embed=embed)
            for message in splited_message:
                embed.description = message
                await ctx.send(embed=embed)
        else:
            embed.description = lyrics
            await ctx.send_followup(embed=embed)
コード例 #4
0
ファイル: Paginator.py プロジェクト: bsavage81/TheOldKing
class PageTest(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.pages = [
            "Page 1",
            [
                discord.Embed(title="Page 2, Embed 1"),
                discord.Embed(title="Page 2, Embed 2"),
            ],
            "Page Three",
            discord.Embed(title="Page Four"),
            discord.Embed(title="Page Five"),
            [
                discord.Embed(title="Page Six, Embed 1"),
                discord.Embed(title="Page Seven, Embed 2"),
            ],
        ]
        self.pages[3].set_image(
            url="https://c.tenor.com/pPKOYQpTO8AAAAAM/monkey-developer.gif"
        )
        self.pages[4].add_field(
            name="Example Field", value="Example Value", inline=False
        )
        self.pages[4].add_field(
            name="Another Example Field", value="Another Example Value", inline=False
        )

        self.more_pages = [
            "Second Page One",
            discord.Embed(title="Second Page Two"),
            discord.Embed(title="Second Page Three"),
        ]

        self.even_more_pages = ["11111", "22222", "33333"]

    def get_pages(self):
        return self.pages

    pagetest = SlashCommandGroup("pagetest", "Commands for testing ext.pages")

    # These examples use a Slash Command Group in a cog for better organization - it's not required for using ext.pages.
    @pagetest.command(name="default")
    async def pagetest_default(self, ctx: discord.ApplicationContext):
        """Demonstrates using the paginator with the default options."""
        paginator = pages.Paginator(pages=self.get_pages())
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="hidden")
    async def pagetest_hidden(self, ctx: discord.ApplicationContext):
        """Demonstrates using the paginator with disabled buttons hidden."""
        paginator = pages.Paginator(pages=self.get_pages(), show_disabled=False)
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="loop")
    async def pagetest_loop(self, ctx: discord.ApplicationContext):
        """Demonstrates using the loop_pages option."""
        paginator = pages.Paginator(pages=self.get_pages(), loop_pages=True)
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="strings")
    async def pagetest_strings(self, ctx: discord.ApplicationContext):
        """Demonstrates passing a list of strings as pages."""
        paginator = pages.Paginator(
            pages=["Page 1", "Page 2", "Page 3"], loop_pages=True
        )
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="timeout")
    async def pagetest_timeout(self, ctx: discord.ApplicationContext):
        """Demonstrates having the buttons be disabled when the paginator view times out."""
        paginator = pages.Paginator(
            pages=self.get_pages(), disable_on_timeout=True, timeout=30
        )
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="remove_buttons")
    async def pagetest_remove(self, ctx: discord.ApplicationContext):
        """Demonstrates using the default buttons, but removing some of them."""
        paginator = pages.Paginator(pages=self.get_pages())
        paginator.remove_button("first")
        paginator.remove_button("last")
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="init")
    async def pagetest_init(self, ctx: discord.ApplicationContext):
        """Demonstrates how to pass a list of custom buttons when creating the Paginator instance."""
        pagelist = [
            pages.PaginatorButton(
                "first", label="<<-", style=discord.ButtonStyle.green
            ),
            pages.PaginatorButton("prev", label="<-", style=discord.ButtonStyle.green),
            pages.PaginatorButton(
                "page_indicator", style=discord.ButtonStyle.gray, disabled=True
            ),
            pages.PaginatorButton("next", label="->", style=discord.ButtonStyle.green),
            pages.PaginatorButton("last", label="->>", style=discord.ButtonStyle.green),
        ]
        paginator = pages.Paginator(
            pages=self.get_pages(),
            show_disabled=True,
            show_indicator=True,
            use_default_buttons=False,
            custom_buttons=pagelist,
            loop_pages=True,
        )
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="custom_buttons")
    async def pagetest_custom_buttons(self, ctx: discord.ApplicationContext):
        """Demonstrates adding buttons to the paginator when the default buttons are not used."""
        paginator = pages.Paginator(
            pages=self.get_pages(),
            use_default_buttons=False,
            loop_pages=False,
            show_disabled=False,
        )
        paginator.add_button(
            pages.PaginatorButton(
                "prev", label="<", style=discord.ButtonStyle.green, loop_label="lst"
            )
        )
        paginator.add_button(
            pages.PaginatorButton(
                "page_indicator", style=discord.ButtonStyle.gray, disabled=True
            )
        )
        paginator.add_button(
            pages.PaginatorButton(
                "next", style=discord.ButtonStyle.green, loop_label="fst"
            )
        )
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="custom_view")
    async def pagetest_custom_view(self, ctx: discord.ApplicationContext):
        """Demonstrates passing a custom view to the paginator."""
        view = discord.ui.View()
        view.add_item(discord.ui.Button(label="Test Button, Does Nothing", row=1))
        view.add_item(
            discord.ui.Select(
                placeholder="Test Select Menu, Does Nothing",
                options=[
                    discord.SelectOption(
                        label="Example Option",
                        value="Example Value",
                        description="This menu does nothing!",
                    )
                ],
            )
        )
        paginator = pages.Paginator(pages=self.get_pages(), custom_view=view)
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="groups")
    async def pagetest_groups(self, ctx: discord.ApplicationContext):
        """Demonstrates using page groups to switch between different sets of pages."""
        page_buttons = [
            pages.PaginatorButton(
                "first", label="<<-", style=discord.ButtonStyle.green
            ),
            pages.PaginatorButton("prev", label="<-", style=discord.ButtonStyle.green),
            pages.PaginatorButton(
                "page_indicator", style=discord.ButtonStyle.gray, disabled=True
            ),
            pages.PaginatorButton("next", label="->", style=discord.ButtonStyle.green),
            pages.PaginatorButton("last", label="->>", style=discord.ButtonStyle.green),
        ]
        view = discord.ui.View()
        view.add_item(discord.ui.Button(label="Test Button, Does Nothing", row=2))
        view.add_item(
            discord.ui.Select(
                placeholder="Test Select Menu, Does Nothing",
                options=[
                    discord.SelectOption(
                        label="Example Option",
                        value="Example Value",
                        description="This menu does nothing!",
                    )
                ],
            )
        )
        page_groups = [
            pages.PageGroup(
                pages=self.get_pages(),
                label="Main Page Group",
                description="Main Pages for Main Things",
            ),
            pages.PageGroup(
                pages=[
                    "Second Set of Pages, Page 1",
                    "Second Set of Pages, Page 2",
                    "Look, it's group 2, page 3!",
                ],
                label="Second Page Group",
                description="Secondary Pages for Secondary Things",
                custom_buttons=page_buttons,
                use_default_buttons=False,
                custom_view=view,
            ),
        ]
        paginator = pages.Paginator(pages=page_groups, show_menu=True)
        await paginator.respond(ctx.interaction, ephemeral=False)

    @pagetest.command(name="update")
    async def pagetest_update(self, ctx: discord.ApplicationContext):
        """Demonstrates updating an existing paginator instance with different options."""
        paginator = pages.Paginator(pages=self.get_pages(), show_disabled=False)
        await paginator.respond(ctx.interaction)
        await asyncio.sleep(3)
        await paginator.update(show_disabled=True, show_indicator=False)

    @pagetest.command(name="target")
    async def pagetest_target(self, ctx: discord.ApplicationContext):
        """Demonstrates sending the paginator to a different target than where it was invoked."""
        paginator = pages.Paginator(pages=self.get_pages())
        await paginator.respond(ctx.interaction, target=ctx.interaction.user)

    @commands.command()
    async def pagetest_prefix(self, ctx: commands.Context):
        """Demonstrates using the paginator with a prefix-based command."""
        paginator = pages.Paginator(pages=self.get_pages(), use_default_buttons=False)
        paginator.add_button(
            pages.PaginatorButton("prev", label="<", style=discord.ButtonStyle.green)
        )
        paginator.add_button(
            pages.PaginatorButton(
                "page_indicator", style=discord.ButtonStyle.gray, disabled=True
            )
        )
        paginator.add_button(
            pages.PaginatorButton("next", style=discord.ButtonStyle.green)
        )
        await paginator.send(ctx)

    @commands.command()
    async def pagetest_target(self, ctx: commands.Context):
        """Demonstrates sending the paginator to a different target than where it was invoked (prefix-command version)."""
        paginator = pages.Paginator(pages=self.get_pages())
        await paginator.send(ctx, target=ctx.author, target_message="Paginator sent!")
コード例 #5
0
class Dev(commands.Cog, name="🧑‍💻 Programowanie"):
    def __init__(self, bot: Atorin):
        self.bot = bot
        self.rtfm_cache = {}

    @slash_command(description="Informacje o bibliotekach z PyPi",
                   guild_ids=config["guild_ids"])
    async def pypi(self, ctx: discord.ApplicationContext,
                   package: Option(str, "Nazwa biblioteki")):
        await ctx.defer()
        r = requests.get(
            f"https://pypi.org/pypi/{package}/json",
            headers={"User-agent": "Atorin"},
        )
        if r.status_code == 200:
            data = r.json()
            embed = discord.Embed()
            embed.title = f"PyPi - {data['info']['name']}"
            embed.add_field(
                name=
                f"{data['info']['summary'] if data['info']['summary'] else 'Brak opisu'}",
                value=f"```bash\npip install {data['info']['name']}```",
                inline=False,
            )
            embed.add_field(
                name="👨‍💻 Autor",
                value=data["info"]["author"]
                if data["info"]["author"] else "Nieznany",
            )
            embed.add_field(
                name="⚙️ Wersja",
                value=data["info"]["version"]
                if data["info"]["version"] else "Nieznana",
            )
            embed.add_field(
                name="📜 Licencja",
                value=data["info"]["license"]
                if data["info"]["license"] else "Brak",
            )
            if "project_urls" in data["info"]:
                links = []
                if "Documentation" in data["info"]["project_urls"]:
                    links.append(
                        f"[Dokumentacja]({data['info']['project_urls']['Documentation']})"
                    )
                if "Homepage" in data["info"]["project_urls"]:
                    links.append(
                        f"[Strona]({data['info']['project_urls']['Homepage']})"
                    )
                if "package_url" in data["info"]:
                    links.append(f"[PyPi]({data['info']['package_url']})")
                embed.add_field(
                    name="🔗 Linki",
                    value=f"**{' | '.join(links)}**",
                )
            await ctx.send_followup(embed=embed)
        elif r.status_code == 404:
            raise commands.BadArgument(
                "Nie znaleziono biblioteki o podanej nazwie!")
        else:
            raise commands.CommandError(r.text)

    @slash_command(description="Informacje o bibliotekach z NPM",
                   guild_ids=config["guild_ids"])
    async def npm(self, ctx: discord.ApplicationContext,
                  package: Option(str, "Nazwa biblioteki")):
        await ctx.defer()
        r = requests.get(
            f"https://registry.npmjs.org/{package}/",
            headers={"User-agent": "Atorin"},
        )
        if r.status_code == 200:
            data = r.json()
            embed = discord.Embed()
            embed.title = f"NPM - {data['name']}"
            embed.add_field(
                name=
                f"{data['description'] if data['description'] else 'Brak opisu'}",
                value=f"```bash\nnpm i {data['name']}```",
                inline=False,
            )
            if "author" in data:
                embed.add_field(
                    name="👨‍💻 Autor",
                    value=data["author"]
                    if type(data["author"]) is str else data["author"]["name"],
                )
            embed.add_field(name="⚙️ Wersja",
                            value=data["dist-tags"]["latest"])
            embed.add_field(
                name="📜 Licencja",
                value=data["license"] if data["license"] else "Brak",
            )
            links = []
            if "homepage" in data:
                links.append(f"[Strona]({data['homepage']})")
            links.append(f"[NPM](https://npmjs.com/package/{data['name']})")
            embed.add_field(
                name="🔗 Linki",
                value=f"**{' | '.join(links)}**",
            )
            await ctx.send_followup(embed=embed)
        elif r.status_code == 404:
            raise commands.BadArgument(
                "Nie znaleziono biblioteki o podanej nazwie!")
        else:
            raise commands.CommandError(r.text)

    @slash_command(
        description="Wyszukiwanie w dokumentacjach bibliotek do Pythona",
        guild_ids=config["guild_ids"],
    )
    async def rtfm(
            self,
            ctx: discord.ApplicationContext,
            package: Option(str, "Nazwa biblioteki"),
            term: Option(str, "Szukana fraza"),
    ):
        package = package.lower()
        await ctx.defer()
        embed = discord.Embed()
        embed.title = "Znalezione w dokumentacji"
        pypi = requests.get(
            f"https://pypi.org/pypi/{package}/json",
            headers={"User-agent": "Atorin"},
        )
        if pypi.status_code == 200:
            data = pypi.json()
            embed.add_field(name="🔤 Biblioteka", value=data["info"]["name"])
            embed.add_field(name="⚙️ Wersja", value=data["info"]["version"])
        else:
            embed.add_field(name="🔤 Biblioteka", value=package)
        if not self.rtfm_cache.get(package):
            url = docs.get(package)
            if not url:
                if ("project_urls" in data["info"]
                        and "Documentation" in data["info"]["project_urls"]):
                    url = data["info"]["project_urls"]["Documentation"]
                    if "readthedocs.io" in url and not "/en/latest" in url:
                        url = os.path.join(url, "en", "latest")
                else:
                    url = f"https://{package}.readthedocs.io/en/latest/"
            r = requests.get(
                os.path.join(url, "objects.inv"),
                headers={"User-agent": "Atorin"},
            )
            if r.status_code == 200:
                self.rtfm_cache[package] = SphinxObjectFileReader(
                    r.content).parse_object_inv(url)
            elif r.status_code == 404:
                raise commands.BadArgument("Nie znaleziono dokumentacji!")
            else:
                raise commands.CommandError(
                    f"Wystąpił błąd przy pobieraniu dokumentacji! ({r.status_code})"
                )
        cache = self.rtfm_cache.get(package)
        results = finder(term,
                         list(cache.items()),
                         key=lambda x: x[0],
                         lazy=False)[:5]
        if results:
            embed.description = "\n".join(
                [f"[`{key}`]({url})" for key, url in results])
        else:
            embed.description = "Brak wyników wyszukiwania"
        await ctx.send_followup(embed=embed)

    @slash_command(
        description="Uruchamianie kodu",
        guild_ids=config["guild_ids"],
    )
    async def exec(
        self,
        ctx: discord.ApplicationContext,
        language: Option(
            str,
            "Wybierz język programowania",
            choices=[
                OptionChoice(name="Bash", value="bash"),
                OptionChoice(name="C#", value="csharp"),
                OptionChoice(name="C", value="c"),
                OptionChoice(name="C++", value="c++"),
                OptionChoice(name="Go", value="go"),
                OptionChoice(name="Java", value="java"),
                OptionChoice(name="JavaScript", value="javascript"),
                OptionChoice(name="PHP", value="php"),
                OptionChoice(name="PowerShell", value="powershell"),
                OptionChoice(name="Python", value="python"),
                OptionChoice(name="Rust", value="rust"),
                OptionChoice(name="Ruby", value="ruby"),
                OptionChoice(name="TypeScript", value="typescript"),
            ],
        ),
    ):
        class ExecModal(Modal):
            def __init__(self) -> None:
                super().__init__("Uruchamianie kodu")
                self.add_item(
                    InputText(
                        label="Twój kod",
                        placeholder="print('Hello world!')",
                        style=discord.InputTextStyle.multiline,
                    ))

            async def callback(self, interaction: discord.Interaction):
                r = requests.post(
                    "https://emkc.org/api/v1/piston/execute",
                    json={
                        "language": language,
                        "source": self.children[0].value,
                    },
                )
                if r.status_code != 200:
                    raise commands.CommandError(r.text)
                data = r.json()
                embed = discord.Embed()
                embed.title = f"Uruchamianie kodu {language.capitalize()}"
                embed.description = f"```{data['output'][:4000] if data['output'] else 'Program wykonany pomyślnie.'}```"
                await interaction.response.send_message(embeds=[embed])

        modal = ExecModal()
        await ctx.interaction.response.send_modal(modal)

    base64_group = SlashCommandGroup(
        "base64",
        "Kodowanie/Dekodowanie tekstu/ciągu w Base64",
        guild_ids=config["guild_ids"],
    )

    @base64_group.command(
        name="encode",
        description="Kodowanie tekstu w Base64",
    )
    async def base64_encode(
            self,
            ctx: discord.ApplicationContext,
            content: Option(str, "Wprowadź tekst"),
    ):
        await ctx.defer()
        embed = discord.Embed()
        embed.title = "Base64"
        encoded = base64.b64encode(content.encode("utf-8", "ignore")).decode(
            "utf-8", "ignore")
        embed.add_field(name="📋 Tekst", value=f"```{content}```", inline=False)
        embed.add_field(name="🔠 Base64",
                        value=f"```{encoded}```",
                        inline=False)
        await ctx.send_followup(embed=embed)

    @base64_group.command(
        name="decode",
        description="Dekodowanie ciągu w Base64",
    )
    async def base64_decode(
            self,
            ctx: discord.ApplicationContext,
            content: Option(str, "Wprowadź ciąg"),
    ):
        await ctx.defer()
        embed = discord.Embed()
        embed.title = "Base64"
        decoded = base64.b64decode(content.encode("utf-8", "ignore")).decode(
            "utf-8", "ignore")
        embed.add_field(name="🔠 Base64",
                        value=f"```{content}```",
                        inline=False)
        embed.add_field(name="📋 Tekst", value=f"```{decoded}```", inline=False)
        await ctx.send_followup(embed=embed)
コード例 #6
0
class Sov(commands.Cog):
    """
    All about sov!
    """
    def __init__(self, bot):
        self.bot = bot

    sov_commands = SlashCommandGroup(
        "sov",
        "Commands for Managing/Attacking Sov",
        guild_ids=[int(settings.DISCORD_GUILD_ID)])

    @sov_commands.command(name='lowadm',
                          guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def lowadm(
        self, ctx, adm: Option(float,
                               description="Optional ADM Level to flag under.",
                               required=False)):
        """
        Systems with low ADMs.
        """
        if not adm:
            adm = app_settings.get_low_adm()
        #    @commands.command(pass_context=True)
        #    @message_in_channels(settings.SOV_DISCORD_BOT_CHANNELS)

        if ctx.channel.id not in settings.SOV_DISCORD_BOT_CHANNELS:
            return await ctx.respond(
                f"You do not have permission to use this command here.",
                ephemeral=True)

        await ctx.defer()

        own_ids = settings.DISCORD_BOT_SOV_STRUCTURE_OWNER_IDS

        include_regions = settings.DISCORD_BOT_ADM_REGIONS
        include_systems = settings.DISCORD_BOT_ADM_SYSTEMS
        include_constel = settings.DISCORD_BOT_ADM_CONSTELLATIONS

        sov_structures = providers.esi.client.Sovereignty.get_sovereignty_structures(
        ).result()

        names = {}
        for s in sov_structures:
            if s.get('alliance_id') in own_ids:
                if s.get('vulnerability_occupancy_level'):
                    if s.get('vulnerability_occupancy_level') < adm:
                        names[s.get('solar_system_id')] = {
                            "system_name": s.get('solar_system_id'),
                            "adm": s.get('vulnerability_occupancy_level')
                        }

        if len(names) == 0:
            await ctx.respond(f"All above {adm} :ok_hand:")
            return True

        systems = [k for k, v in names.items()]
        constelations = {}
        for n in systems:
            system = providers.esi.client.Universe.get_universe_systems_system_id(
                system_id=n).result()
            names[n]["system_name"] = system.get("name")
            names[n]["system_id"] = system.get("system_id")
            names[n]["constellation_id"] = system.get("constellation_id")
            if system.get("constellation_id") not in constelations:
                constelations[system.get("constellation_id")] = {}

        for c, v in constelations.items():
            const = providers.esi.client.Universe.get_universe_constellations_constellation_id(
                constellation_id=c).result()
            region = providers.esi.client.Universe.get_universe_regions_region_id(
                region_id=const.get("region_id")).result()
            v["region_id"] = const.get("region_id")
            v["region_name"] = region.get("name")
            v["constellation_name"] = const.get("name")

        out_array = {}
        for k, v in names.items():
            out_array[k] = {**v, **constelations[v["constellation_id"]]}

        output = {}
        base_str = "**{}** ADM:{}"
        urls = {}
        for k, h in sorted(out_array.items(), key=lambda e: e[1]['adm']):
            show = False
            if h['region_id'] in include_regions:
                show = True
            elif h['constellation_id'] in include_constel:
                show = True
            elif h['system_id'] in include_systems:
                show = True
            if show:
                if h['region_name'] not in output:
                    output[h['region_name']] = []
                output[h['region_name']].append(
                    base_str.format(h['system_name'], h['adm']))
                if h['region_name'].replace(" ", "_") not in urls:
                    urls[h['region_name'].replace(" ", "_")] = []
                urls[h['region_name'].replace(" ", "_")].append(
                    h['system_name'].replace(" ", "_"))
        url = "https://evemaps.dotlan.net/map/{}/{}#adm"

        if len(output) > 0:
            embed = Embed(title="Low ADMs!")
            embed.set_thumbnail(
                url=
                "https://avatars3.githubusercontent.com/u/39349660?s=200&v=4")
            embed.colour = Color.red()
            embed.description = f"Showing systems with ADMs below {adm}. Due to an ESI bug this data might only update once a day at around 2200-2300 Eve Time. **YMMY**\n[For more info please see this issue](https://github.com/esi/esi-issues/issues/1092)"

            await ctx.respond(embed=embed)

            for k, v in output.items():
                n = 25
                chunks = [
                    list(v[i * n:(i + 1) * n])
                    for i in range((len(v) + n - 1) // n)
                ]
                for chunk in chunks:
                    await ctx.send("__{}__\n{}".format(k, "\n".join(chunk)))
            _urls = []
            for r, s in urls.items():
                _urls.append(url.format(r, ",".join(s)))
            await ctx.send("\n\n".join(_urls))
        else:
            await ctx.respond(f"No Systems with ADM below {adm}!")

        return True

    @sov_commands.command(name='vulnerable',
                          guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def vuln(self, ctx, name_search: Option(
        str, description="String to search against the sov database.")):
        """
        Vulnerable Sov Structures for region/constelation/system/alliance
        """
        if ctx.channel.id not in settings.SOV_DISCORD_BOT_CHANNELS:
            return await ctx.respond(
                f"You do not have permission to use this command here.",
                ephemeral=True)

        await ctx.defer()

        name_ids = providers.esi.client.Search.get_search(
            categories=['constellation', 'solar_system', 'region', 'alliance'],
            search=name_search).result()

        hit_ids = {
            "a": name_ids.get("alliance") or [],
            "c": name_ids.get("constellation") or [],
            "s": name_ids.get("solar_system") or [],
            "r": name_ids.get("region") or [],
        }

        for r in hit_ids['r']:
            constellations = providers.esi.client.Universe.get_universe_regions_region_id(
                region_id=r).result()["constellations"]
            for c in constellations:
                if c not in hit_ids["c"]:
                    hit_ids["c"].append(c)

        for c in hit_ids['c']:
            systems = providers.esi.client.Universe.get_universe_constellations_constellation_id(
                constellation_id=c).result()["systems"]
            for s in systems:
                if s not in hit_ids["s"]:
                    hit_ids["s"].append(s)

        sov_structures = providers.esi.client.Sovereignty.get_sovereignty_structures(
        ).result()

        hits = []
        names = []
        alliances = []
        dt_comp = datetime.datetime.utcnow().replace(tzinfo=timezone.utc) + \
            datetime.timedelta(hours=1)

        for s in sov_structures:
            start = s.get('vulnerable_start_time', False)
            if start:
                if start < dt_comp:
                    if s.get('solar_system_id') in hit_ids["s"] or s.get(
                            'alliance_id') in hit_ids["a"]:
                        alliances.append(s.get('alliance_id'))
                        names.append(s.get('solar_system_id'))
                        names.append(s.get('structure_type_id'))
                        hits.append(s)

        if len(names) == 0:
            await ctx.respond(
                ":sad: Nothing found for '{}'".format(name_search))
            return True

        names_alli = {}
        for a in set(alliances):
            res = providers.esi.client.Alliance.get_alliances_alliance_id(
                alliance_id=a).result()
            names_alli[a] = res.get("ticker")

        names = providers.esi.client.Universe.post_universe_names(
            ids=list(set(names))).result()

        nms = {}
        for n in names:
            nms[n.get("id")] = n.get("name")

        for hit in hits:
            hit['system_name'] = nms[hit.get('solar_system_id')]
            if hit.get("structure_type_id") == 32226:
                hit['structure'] = "TCU"
            elif hit.get("structure_type_id") == 32458:
                hit['structure'] = "IHUB"
            else:
                hit['structure'] = "¯\\_(ツ)_/¯"

            hit['alliance_name'] = names_alli[hit.get('alliance_id')]

        output = []
        base_str = "**{}** {} (ADM {})[**{}**] Vulnerable{}"
        dt_now = pendulum.now(tz="UTC")
        for h in sorted(hits, key=lambda k: k['vulnerable_start_time']):
            time = ""
            if h['vulnerable_start_time'] > dt_now:
                time = " in **{}**".format(
                    pendulum.now(tz="UTC").diff_for_humans(
                        h['vulnerable_start_time'], absolute=True))
            else:
                time = " for **{}**".format(
                    pendulum.now(tz="UTC").diff_for_humans(
                        h['vulnerable_end_time'], absolute=True))
            output.append(
                base_str.format(h['system_name'], h['structure'],
                                h['vulnerability_occupancy_level'],
                                h['alliance_name'], time))

        n = 10
        chunks = [
            list(output[i * n:(i + 1) * n])
            for i in range((len(output) + n - 1) // n)
        ]
        overflow = ""
        if len(output) > 50:
            overflow = "Only showing first 50..."
        await ctx.respond(
            "Found {} Vunerable Structures for `{}`\n{}\n".format(
                len(output), name_search, overflow))

        for c in chunks[:5]:
            await ctx.send("\n".join(c))

    @sov_commands.command(name='search',
                          guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def sov(self, ctx, name_search: Option(
        str, description="String to search against the sov database.")):
        """
        Sov Details for region/constelation/system/alliance
        """
        if ctx.channel.id not in settings.SOV_DISCORD_BOT_CHANNELS:
            return await ctx.respond(
                f"You do not have permission to use this command here.",
                ephemeral=True)

        await ctx.defer()

        name_ids = providers.esi.client.Search.get_search(
            categories=['constellation', 'solar_system', 'region', 'alliance'],
            search=name_search).result()

        hit_ids = {
            "a": name_ids.get("alliance") or [],
            "c": name_ids.get("constellation") or [],
            "s": name_ids.get("solar_system") or [],
            "r": name_ids.get("region") or [],
        }

        for r in hit_ids['r']:
            constellations = providers.esi.client.Universe.get_universe_regions_region_id(
                region_id=r).result()["constellations"]
            for c in constellations:
                if c not in hit_ids["c"]:
                    hit_ids["c"].append(c)

        for c in hit_ids['c']:
            systems = providers.esi.client.Universe.get_universe_constellations_constellation_id(
                constellation_id=c).result()["systems"]
            for s in systems:
                if s not in hit_ids["s"]:
                    hit_ids["s"].append(s)

        sov_structures = providers.esi.client.Sovereignty.get_sovereignty_structures(
        ).result()

        hits = []
        names = []
        alliances = []

        for s in sov_structures:
            start = s.get('vulnerable_start_time', False)
            if start:
                if s.get('solar_system_id') in hit_ids["s"] or s.get(
                        'alliance_id') in hit_ids["a"]:
                    alliances.append(s.get('alliance_id'))
                    names.append(s.get('solar_system_id'))
                    names.append(s.get('structure_type_id'))
                    hits.append(s)

        if len(names) == 0:
            await ctx.respond(
                ":sad: Nothing found for '{}'".format(name_search))
            return True

        names_alli = {}
        for a in set(alliances):
            res = providers.esi.client.Alliance.get_alliances_alliance_id(
                alliance_id=a).result()
            names_alli[a] = res.get("ticker")

        names = providers.esi.client.Universe.post_universe_names(
            ids=list(set(names))).result()

        nms = {}
        for n in names:
            nms[n.get("id")] = n.get("name")

        for hit in hits:
            hit['system_name'] = nms[hit.get('solar_system_id')]
            if hit.get("structure_type_id") == 32226:
                hit['structure'] = "TCU"
            elif hit.get("structure_type_id") == 32458:
                hit['structure'] = "IHUB"
            else:
                hit['structure'] = "¯\\_(ツ)_/¯"

            hit['alliance_name'] = names_alli[hit.get('alliance_id')]

        output = []
        base_str = "**{}** {} (ADM {})[**{}**] Vulnerable{}"
        dt_now = pendulum.now(tz="UTC")
        for h in sorted(hits, key=lambda k: k['vulnerable_start_time']):
            time = ""
            time = " for **{}**".format(
                pendulum.now(tz="UTC").diff_for_humans(
                    h['vulnerable_end_time'], absolute=True))

            if h['vulnerable_start_time']:
                if h['vulnerable_start_time'] > dt_now:
                    time = " in **{}**".format(
                        pendulum.now(tz="UTC").diff_for_humans(
                            h['vulnerable_start_time'], absolute=True))
            output.append(
                base_str.format(h['system_name'], h['structure'],
                                h['vulnerability_occupancy_level'],
                                h['alliance_name'], time))

        n = 15
        chunks = [
            list(output[i * n:(i + 1) * n])
            for i in range((len(output) + n - 1) // n)
        ]
        overflow = ""
        if len(output) > 50:
            overflow = "Only showing first 50..."

        await ctx.respond("Found {} Sov structures for `{}`\n{}\n".format(
            len(output), name_search, overflow))

        for c in chunks[:5]:
            await ctx.send("\n".join(c))
コード例 #7
0
class MoonsCog(commands.Cog):
    """
    All about Moons!
    """
    def __init__(self, bot):
        self.bot = bot

    pinger_commands = SlashCommandGroup(
        "moons",
        "Moon Module Commands",
        guild_ids=[int(settings.DISCORD_GUILD_ID)])

    def sender_has_moon_perm(self, ctx):
        id = ctx.author.id
        try:
            has_perm = DiscordUser.objects.get(
                uid=id).user.has_perm("moons.view_all")
            if has_perm:
                return True
            else:
                return False
        except Exception as e:
            return False

    def sender_has_corp_moon_perm(self, ctx):
        id = ctx.author.id
        try:
            has_perm = DiscordUser.objects.get(
                uid=id).user.has_perm("moons.view_corp")
            if has_perm:
                return True
            else:
                return False
        except Exception as e:
            return False

    @pinger_commands.command(name='print_stats',
                             guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def info_slash(self, ctx):
        """
        Print the Uninvocied Mining Stats!
        """

        if not self.sender_has_moon_perm(ctx):
            return await ctx.respond(
                f"You do not have permision to use this command.",
                ephemeral=True)

        await ctx.respond(f"Calculating the Moon Stats.")

        last_date = InvoiceRecord.get_last_invoice_date()
        date_str = last_date.strftime('%Y/%m/%d')
        e = Embed(title=f"Last Invoice {date_str}")
        accounts_seen = 0
        locations = set()
        data = InvoiceRecord.generate_invoice_data()
        total_mined = 0
        total_taxed = 0
        # run known people
        for u, d in data['knowns'].items():
            try:
                total_mined += d['total_value']
                total_taxed += d['tax_value']

                accounts_seen += 1
                for l in d['locations']:
                    locations.add(l)
            except KeyError:
                pass  # probably wanna ping admin about it.

        for u, d in data['unknowns'].items():
            try:
                total_mined += d['totals_isk']
                total_taxed += d['tax_isk']
                for l in d['seen_at']:
                    locations.add(l)
            except KeyError:
                pass  # probably wanna ping admin about it.

        e.add_field(name="Known Members",
                    value=f"{accounts_seen}",
                    inline=False)
        e.add_field(name="Unknown Characters",
                    value=f"{len(data['unknowns'])}",
                    inline=False)
        e.add_field(name="Total Mined",
                    value=f"${total_mined:,}",
                    inline=False)
        e.add_field(name="Total Tax", value=f"${total_taxed:,}", inline=False)
        locations = "\n ".join(list(locations))
        e.description = f'Locations tracked so far ({len(list(locations))})\n\n {locations}'

        await ctx.channel.send(embed=e)

    @pinger_commands.command(name='inactive',
                             guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def inactive_moons(self, ctx, own_corp: Optional[bool] = False):
        """
        Print inactive Moons!
        """
        if own_corp:
            if not self.sender_has_corp_moon_perm(ctx):
                return await ctx.respond(
                    f"You do not have permission to use this command.",
                    ephemeral=True)
            user = DiscordUser.objects.get(
                uid=ctx.author.id).user.profile.main_character
            corps = CorporationAudit.objects.filter(
                corporation__corporation_id=user.corporation_id)
            corp_names = [f"{c.corporation.corporation_name}" for c in corps]
            if corps.count() > 0:
                await ctx.respond(
                    f"Printing Inactive Drills for {', '.join(corp_names)}",
                    ephemeral=True)
                await ctx.author.send(
                    f"Printing Inactive Drills for {', '.join(corp_names)}")
            else:
                await ctx.respond(
                    f"Your corp is not setup in Audit, please contact an admin.",
                    ephemeral=True)

        else:
            if not self.sender_has_moon_perm(ctx):
                return await ctx.respond(
                    f"You do not have permission to use this command.",
                    ephemeral=True)
            corps = CorporationAudit.objects.filter(
                corporation__corporation_id__in=app_settings.PUBLIC_MOON_CORPS)
            corp_names = [f"{c.corporation.corporation_name}" for c in corps]
            if corps.count() > 0:
                await ctx.respond(
                    f"Printing Inactive Drills for {', '.join(corp_names)}")
            else:
                await ctx.respond(
                    f"Public corp is not setup, please contact an admin.")

        tzactive = timezone.now()
        fracks = MoonFrack.objects.filter(
            arrival_time__gte=tzactive,
            corporation__in=corps).values_list('structure_id')
        structures = Structure.objects.filter(
            structureservice__name__in=["Moon Drilling"],
            corporation__in=corps).exclude(structure_id__in=fracks)
        messages = [f"{s.name}" for s in structures]
        n = 10
        chunks = [
            list(messages[i * n:(i + 1) * n])
            for i in range((len(messages) + n - 1) // n)
        ]
        for chunk in chunks:
            message = "\n".join(chunk)
            if own_corp:
                await ctx.author.send(f"```{message}```")
            else:
                await ctx.send(f"```{message}```")
コード例 #8
0
class Admin(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    admin_commands = SlashCommandGroup(
        "admin",
        "Server Admin Commands",
        guild_ids=[int(settings.DISCORD_GUILD_ID)])

    @admin_commands.command(name='add_role',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def add_role_slash(self, ctx, channel: TextChannel, role: Role):
        """
        Add a role as read/write to a channel....
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        await channel.set_permissions(role,
                                      read_messages=True,
                                      send_messages=True)

        await ctx.respond(f"Set Read/Write `{role.name}` in `{channel.name}`")

    @admin_commands.command(name='add_role_read',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def add_role_read_slash(self, ctx, channel: TextChannel, role: Role):
        """
        Add a role as read only to a channel....
        """

        # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
        if ctx.author.id not in app_settings.get_admins():
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        await channel.set_permissions(role,
                                      read_messages=True,
                                      send_messages=False)

        await ctx.respond(f"Set Readonly `{role.name}` in `{channel.name}`")

    @admin_commands.command(name='rem_role',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def rem_role_slash(self, ctx, channel: TextChannel, role: Role):
        """
        Remove a role from a channel....
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        await channel.set_permissions(role,
                                      read_messages=False,
                                      send_messages=False)

        await ctx.respond(f"Removed `{role.name}` from `{channel.name}`")

    @admin_commands.command(name='new_channel',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def new_channel_slash(self, ctx, category: CategoryChannel,
                                channel_name: str, first_role: Role):
        """
        Create a new channel and add a role....
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        found_channel = False

        for channel in ctx.guild.channels:  # TODO replace with channel lookup not loop
            if channel.name.lower() == channel_name.lower():
                found_channel = True

        if not found_channel:
            channel = await ctx.guild.create_text_channel(channel_name.lower(),
                                                          category=category
                                                          )  # make channel
            await channel.set_permissions(ctx.guild.default_role,
                                          read_messages=False,
                                          send_messages=False)

            await channel.set_permissions(first_role,
                                          read_messages=True,
                                          send_messages=True)

            await ctx.respond(
                f"Created New Channel `{channel.name}` and added the `{first_role.name}` Role"
            )

    @admin_commands.command(name='promote_to_god',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def promote_role_to_god(self, ctx, role: Role):
        """
        set role as admin....
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer(ephemeral=True)

        perms = role.permissions
        perms.administrator = True
        await role.edit(permissions=perms)
        await ctx.respond(f"Set `{role.name}` as admin", ephemeral=True)

    @admin_commands.command(name='demote_from_god',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def demote_role_from_god(self, ctx, role: Role):
        """
        revoke role admin....
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer(ephemeral=True)

        perms = role.permissions
        perms.administrator = False
        await role.edit(permissions=perms)
        await ctx.respond(f"Removed admin from `{role.name}`", ephemeral=True)

    @admin_commands.command(name='empty_roles',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def empty_roles(self, ctx):
        """
        dump all roles with no members.
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        empties = []
        for role_model in ctx.guild.roles:
            if len(role_model.members) == 0:
                empties.append(role_model.name)

        await ctx.respond("\n".join(empties))

    @admin_commands.command(name='clear_empty_roles',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def clear_empty_roles(self, ctx):
        """
        delete all roles with no members.
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        empties = 0
        fails = []
        for role_model in ctx.guild.roles:
            if len(role_model.members) == 0:
                try:
                    await role_model.delete()
                    empties += 1
                except Exception as e:
                    fails.append(role_model.name)

        await ctx.respond(f"Deleted {empties} Roles.")
        chunks = [fails[x:x + 50] for x in range(0, len(fails), 50)]
        for c in chunks:
            await ctx.respond("\n".join(c))

    @admin_commands.command(name='orphans',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def orphans_slash(self, ctx):
        """
        Returns a list of users on this server, who are not known to AA
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer()

        payload = "The following Users cannot be located in Alliance Auth \n"

        member_list = ctx.guild.members
        for member in member_list:
            id = member.id
            try:
                discord_exists = DiscordUser.objects.get(uid=id)
                discord_is_bot = member.bot
            except Exception as e:
                discord_exists = False
                discord_is_bot = False

            try:
                discord_is_bot = member.bot
            except Exception as e:
                discord_is_bot = False

            if discord_exists is not False:
                # nothing to do, the user exists. Move on with ur life dude.
                pass

            elif discord_is_bot is True:
                # lets also ignore bots here
                pass
            else:
                payload = payload + member.mention + "\n"

        try:
            await ctx.respond(payload)
        except Exception as e:
            await ctx.respond(payload[0:1999])

    @admin_commands.command(name='get_webhooks',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def get_webhooks(self, ctx):
        """
        Returns the webhooks for the channel
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)

        await ctx.defer(ephemeral=True)

        hooks = await ctx.channel.webhooks()
        if len(hooks) == 0:
            name = "{}_webhook".format(ctx.channel.name.replace(" ", "_"))
            hook = await ctx.channel.create_webhook(name=name)
            await ctx.respond("{} - {}".format(hook.name, hook.url),
                              ephemeral=True)

        else:
            strs = []
            for hook in hooks:
                strs.append("{} - {}".format(hook.name, hook.url))

            await ctx.respond("\n".join(strs), ephemeral=True)

    @admin_commands.command(name='uptime',
                            guild_ids=[int(settings.DISCORD_GUILD_ID)])
    async def uptime(self, ctx):
        """
        Returns the uptime of the bot
        """
        if ctx.author.id not in app_settings.get_admins(
        ):  # https://media1.tenor.com/images/1796f0fa0b4b07e51687fad26a2ce735/tenor.gif
            return await ctx.respond(
                f"You do not have permission to use this command",
                ephemeral=True)
        try:
            await ctx.respond(pendulum.now(tz="UTC").diff_for_humans(
                self.bot.currentuptime, absolute=True),
                              ephemeral=True)
        except AttributeError:
            await ctx.respond("Still Booting up!", ephemeral=True)
コード例 #9
0
class Admin(commands.Cog):
    def __init__(self, bot: Client):
        self.bot = bot
        self.init()
        self.votumTask.start()

        for server in session.query(Server):
            guilds.append(server.Id)

    settings = SlashCommandGroup(
        "setting",
        "Настройки бота. Admin only!",
        permissions=[CommandPermission("owner", 2, True)],
        guild_ids=guilds)

    @staticmethod
    def init():
        for votum in session.query(Votum):
            votumList[votum.ServerId, votum.MessageId] = votum

    @tasks.loop(seconds=60, reconnect=True)
    async def votumTask(self):
        keys = votumList.keys()
        for i in keys:
            votum = votumList[i]
            if datetime.datetime.utcnow() >= votum.EndTime:
                try:
                    channel = await self.bot.fetch_channel(votum.ChannelId)
                    message = await channel.fetch_message(votum.MessageId)
                    await message.delete()
                except discord.errors.NotFound:
                    pass
                session.delete(votum)
                session.commit()
                votumList.pop(i)

    @slash_command(
        name='votum',
        description=
        "Начинает голосование по выдачи Вотума недовольства (Мута) пользователю.",
    )
    async def votum(self, ctx, member: Option(
        discord.Member, "Выберите пользователя, которому выдаём Вотум")):
        if member.bot:
            emb = discord.Embed(
                title="Некорректный вызов",
                description="Пользователь {0} - это Бот".format(member.name))
            return await ctx.send(embed=emb)

        # Проверяем не идёт ли уже голосование за мут
        votum = session.query(Votum) \
            .filter(Votum.ServerId == ctx.guild.id) \
            .filter(Votum.MemberId == member.id).first()
        if votum:
            emb = discord.Embed(
                title="Некорректный вызов",
                description=
                "{1}, голосование по выдачи Вотума пользователю {0} уже идёт".
                format(member.name, ctx.author.name))
            return await ctx.send(embed=emb)

        # Создаём голование
        emb = discord.Embed(
            title="Голосование за выдачу Вотума Недовольства пользователю {0}".
            format(member.name),
            description=
            "Если это собщение наберёт 6 голосов (:thumbsup:) в течении 1 часа, тогда пользователю {0} "
            "будет выдан мут на 24 часа".format(member.name))
        msg = await ctx.send(embed=emb)
        votum = Votum(channelId=ctx.channel.id,
                      serverId=ctx.guild.id,
                      memberId=member.id,
                      messageId=msg.id)
        session.add(votum)
        session.commit()
        votumList[ctx.guild.id, msg.id] = votum
        await msg.add_reaction('\N{THUMBS UP SIGN}')
        return msg

    @commands.Cog.listener()
    async def on_reaction_add(self, reaction: discord.Reaction, user):
        if reaction.count >= 6:
            hours = 24
            message = reaction.message
            votum = votumList[reaction.message.guild.id, reaction.message.id]

            member = await message.guild.fetch_member(votum.MemberId)
            await member.timeout(datetime.datetime.now() +
                                 datetime.timedelta(days=1),
                                 reason="Большинство проголосовало за мут")
            votumList.pop((votum.ServerId, votum.MessageId))
            session.delete(votum)
            session.commit()
            await message.delete()
            return await message.channel.send(
                content="Пользователь {} заглушен на {} часа".format(
                    member.name, hours))

    # Кол-во пришедших
    @slash_command(
        name='count',
        description=
        'Выводит статистику посещения сервера, а сколько пришло или ушло')
    async def count(self, ctx):
        members = session.query(Member).filter(Member.ServerId == ctx.guild.id)
        all = members.count()
        alive = members.filter(Member.IsAlive).count()
        dead = members.filter(Member.IsAlive == False).count()

        embed = discord.Embed(title="Я запомнила " + str(all) + " чел.",
                              description="На данный момент")
        embed.add_field(name="Ушло", value=str(dead) + " чел.")
        embed.add_field(name="Осталось", value=str(alive) + " чел.")
        await ctx.send(embed=embed)

    # Устанавливает информационный канал
    @settings.command(
        name="info",
        guild_id=guilds,
        default_permission=False,
        permissions=[CommandPermission("owner", 2, True)],
        description=
        "Задаёт канал для вывода сообщений об приходе/уходе/возвращение пользователей."
    )
    async def setInfo(self, ctx, channel: Option(discord.TextChannel,
                                                 "Выбрите текстовый канал",
                                                 required=False,
                                                 default=None)):
        server = session.query(Server).filter(
            Server.Id == ctx.guild.id).first()
        if channel:
            server.InfoChannel = channel.id
        else:
            server.InfoChannel = ""
        session.commit()
        await ctx.send("InfoChannel: {}".format(channel.name))

    # Устанавливает роль новичков
    @settings.command(
        name="joinrole",
        guild_id=guilds,
        permissions=[CommandPermission("owner", 2, True)],
        default_permission=False,
        description=
        "Задаёт роль для пользовтелей который только-что присоединились.")
    async def setJoinRole(self, ctx, role: Option(discord.Role,
                                                  "Выберите роль для новичков",
                                                  required=False,
                                                  default=None)):
        server = session.query(Server).filter(
            Server.Id == ctx.guild.id).first()
        if role:
            server.JoinRole = role.id
            await ctx.send("Join role changed to: {}".format(role.name))
        else:
            server.JoinRole = ""
            await ctx.send("Join role cleared")
        session.commit()

    # Устанавливает название участника сервера
    @settings.command(
        name="memname",
        guild_id=guilds,
        permissions=[CommandPermission("owner", 2, True)],
        default_permission=False,
        description=
        "Устанавливает называние при приходе/уходе/возвращение пользователей на сервер."
    )
    async def setMemName(self, ctx, name: Option(
        str,
        "Строка обозначающее имя участника канала",
        default="Member",
        required=False)):
        server = session.query(Server).filter(
            Server.Id == ctx.guild.id).first()
        server.MemberName = name
        session.commit()
        await ctx.send("Member name changed to: {}".format(name))

    # Устанавливает текст при бане пользователя на сервере
    @slash_command(
        name="bantext",
        permissions=[CommandPermission("owner", 2, True)],
        guild_id=guilds,
        default_permission=False,
        description="Устанавливает текст при бане пользователя на сервере.")
    @permissions.is_owner()
    async def setBanText(self, ctx, bantext: Option(
        str,
        "Сроки обозначающие, что пользовтатель был забанен",
        default="has been banned.",
        required=False)):
        server = session.query(Server).filter(
            Server.Id == ctx.guild.id).first()
        server.BanText = bantext
        session.commit()
        await ctx.send("Ban text changed for: {}".format(bantext))

    # Подключение к серверу
    @commands.Cog.listener()
    async def on_guild_join(self, guild):
        logging.info("Join to: {} {}".format(guild.id, guild.name))
        server = session.query(Server).filter(Server.Id == guild.id).first()
        if not server:
            common.createServerFolder(guild)
            server = Server(id=guild.id)
            session.add(server)
            session.commit()
            common.addMembersOnServer(guild)
            guilds.append(guild.id)
        else:
            common.checkMembersOnServer(guild)
        common.addRoles(guild)
        common.addEmojies(guild)

    # аudit
    @settings.command(
        name="audit",
        guild_id=guilds,
        permissions=[CommandPermission("owner", 2, True)],
        default_permission=False,
        description=
        "Производит аудит пользователей сервера и синхронизирует с бд бота.")
    async def audit(self, ctx):
        server = session.query(Server).filter(
            Server.Id == ctx.guild.id).first()
        if not server:
            common.createServerFolder(ctx.guild)
            server = Server(id=ctx.guild.id)
            session.add(server)
            session.commit()
            common.addMembersOnServer(ctx.guild)
        else:
            await common.checkMembersOnServer(ctx.guild)
        common.addRoles(ctx.guild)
        common.addEmojies(ctx.guild)
        await ctx.send("Audit completed!")

    @settings.command(
        name="ignor",
        guild_id=guilds,
        permissions=[CommandPermission("owner", 2, True)],
        default_permission=False,
        description=
        "Игнор-лист, для того чтобы бот не защитывал XP, упоминания или эмодзи в каналах."
    )
    async def ignor(self, ctx,
                    action: Option(str,
                                   "Выберите раздел",
                                   required=True,
                                   choices=["Список", "Добавить", "Удалить"],
                                   default="Список"),
                    channel: Option(discord.TextChannel,
                                    "Канал который добавить/удалить из списка",
                                    required=False,
                                    default=None)):
        if action == "Список":
            embed = await ignorChannels.list(ctx)
            await ctx.send(embed=embed)
        elif action == "Добавить":
            if channel:
                embed = await ignorChannels.add(ctx, channel)
                await ctx.send(embed=embed)
            else:
                await ctx.send("Не указан канал!")
        elif action == "Удалить":
            if channel:
                embed = await ignorChannels.remove(ctx, channel)
                await ctx.send(embed=embed)
            else:
                await ctx.send("Не указан канал!")
        else:
            await ctx.send("Неизвестное действие.")

    @settings.command(
        name="boost",
        guild_id=guilds,
        permissions=[CommandPermission("owner", 2, True)],
        default_permission=False,
        description="Boost-лист каналов где присваивается х2 опыт.")
    async def boost(self, ctx,
                    action: Option(str,
                                   "Выберите раздел",
                                   required=True,
                                   choices=["Список", "Добавить", "Удалить"],
                                   default="Список"),
                    channel: Option(discord.TextChannel,
                                    "Канал который добавить/удалить из списка",
                                    required=False,
                                    default=None)):
        if action == "Список":
            embed = await boostChannels.list(ctx)
            await ctx.send(embed=embed)
        elif action == "Добавить":
            if channel:
                embed = await boostChannels.add(ctx, channel)
                await ctx.send(embed=embed)
            else:
                await ctx.send("Не указан канал!")
        elif action == "Удалить":
            if channel:
                embed = await boostChannels.remove(ctx, channel)
                await ctx.send(embed=embed)
            else:
                await ctx.send("Не указан канал!")
        else:
            await ctx.send("Неизвестное действие.")

    @slash_command(
        name="emojistat",
        description="Выводит статистику использования серверных эмоджи.")
    async def emojiStat(self, ctx: discord.ApplicationContext):
        pages = []

        emojies = {}
        for i in ctx.guild.emojis:
            emojies.update({i.id: i})

        iter = 0

        for emojie in session.query(Emojie).filter(
                Emojie.ServerId == ctx.guild.id).order_by(
                    desc(Emojie.CountUsage)):
            emoji = emojies.get(emojie.Id)
            if emoji:
                iter += 1
                embed = discord.Embed(title=emoji.name)
                embed.set_thumbnail(url=emoji.url)
                embed.add_field(name="Кол-во:",
                                value=emojie.CountUsage,
                                inline=True)
                embed.add_field(name="Последнее использование:",
                                value=str(emojie.LastUsage),
                                inline=True)
                if iter == 1:
                    page = Page(embeds=[embed])
                else:
                    page.embeds.append(embed)
                if iter == 5:
                    pages.append(page)
                    iter = 0
        try:
            if pages.count(page) == 0:
                pages.append(page)
        except UnboundLocalError:
            return

        if len(pages) == 0:
            return

        paginator = Paginator(pages=pages,
                              loop_pages=True,
                              disable_on_timeout=True,
                              timeout=360)
        await paginator.respond(ctx.interaction)