Ejemplo n.º 1
0
    async def seek(self, ctx, seconds: int = 15):
        """Fast-forwards 15 seconds or a given amount of seconds in the current song."""
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)

        if not player.is_playing:
            raise BadRequestException('I am currently not playing anything!')
        if player.current.is_stream:
            raise BadRequestException('You can\'t use seek in a stream!')

        await player.seek(player.position + seconds * 1000)
        await ctx.message.add_reaction("<:ok:746377326245445653>")
Ejemplo n.º 2
0
    async def seekto(self, ctx, seconds: int):
        """Fast-forwards to the given amount of seconds in the current song."""
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)

        if not player.is_playing:
            raise BadRequestException('I am currently not playing anything!')
        if seconds < 0:
            raise BadRequestException(
                'I can\'t start that song from the past, fam! Enter a value equal to or greater than 0.')
        if player.current.is_stream:
            raise BadRequestException('You can\'t use seekto in a stream!')

        await player.seek(seconds * 1000)
        await ctx.message.add_reaction("<:ok:746377326245445653>")
Ejemplo n.º 3
0
    async def join_(self, ctx, channel=None, suppress_warning=False):
        if not channel:
            try:
                channel = ctx.author.voice.channel
            except AttributeError:
                raise BadRequestException('No channel to join. Please join one.')
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)
        if player.channel_id == channel.id:
            if not suppress_warning:
                raise BadRequestException('I\'m already in this channel :)')
        else:
            await player.connect(channel.id)

        controller = self.get_controller(ctx)
        controller.channel = ctx.channel
Ejemplo n.º 4
0
    async def volume(self, ctx: Context, volume: int):
        if volume > 200 or volume < 3:
            raise BadRequestException("Volume has to be between 3 and 200!")

        player = self.bot.wavelink.get_player(ctx.guild.id)
        await player.set_volume(volume)
        await ctx.message.add_reaction("<:ok:746377326245445653>")
Ejemplo n.º 5
0
    async def jumpto(self, ctx: Context, position: int):
        """Jumps to the given position in the queue."""
        controller: MusicController = self.get_controller(ctx)
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)
        if position <= 0:
            raise BadRequestException("Invalid value. Try something greater.")

        try:
            _ = controller.queue[position - 1]  # Try to get the song at the position
            controller.current_index = position - 1  # If that worked, set the current index to the new position
            if player.is_playing:
                await player.seek(player.current.length)  # If a song is currently playing, skip that!
            await ctx.message.add_reaction("<:ok:746377326245445653>")  # gib ok
        except IndexError:
            raise BadRequestException(
                "The index I should jump to isn't part of the queue. Try to enter something lower.")
Ejemplo n.º 6
0
    async def playing(self, ctx):
        """Shows the song that's currently playing."""
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)
        if not player.is_playing:
            raise BadRequestException('I am currently not playing anything!')

        await ctx.send(embed=get_currently_playing_embed(player.current, player.position))
Ejemplo n.º 7
0
 async def unlike(self, ctx):
     """Removes the current song from your 'Liked' playlist"""
     current_track: Track = self.get_controller(ctx).current_track
     if not current_track:
         raise BadRequestException("No track is currently playing!")
     self.database.remove_from_playlist(ctx.author.id, "Liked",
                                        [current_track])
     await ctx.message.add_reaction("<:ok:746377326245445653>")
Ejemplo n.º 8
0
 async def resume(self, ctx):
     """Resumes current track."""
     player = self.bot.wavelink.get_player(ctx.guild.id)
     if player.is_playing and player.is_paused:
         await player.set_pause(False)
         await ctx.message.add_reaction("<:ok:746377326245445653>")
     else:
         raise BadRequestException("Currently, no track is loaded/paused")
Ejemplo n.º 9
0
 async def queue_(self, ctx):
     """Shows the queue."""
     controller = self.get_controller(ctx)
     if len(controller.queue) == 0:
         raise BadRequestException("Queue is empty!")
     pagedlist = PagedListEmbed("Queue", [
         str(index + 1) + ".   **" + song.title + "**" if index == controller.current_index - 1 else str(
             index + 1) + ".   " + song.title for index, song in enumerate(controller.queue)], ctx, self.bot)
     await pagedlist.send(pagedlist.get())
Ejemplo n.º 10
0
    async def like(self, ctx):
        """Adds the current song to your 'Liked' playlist"""
        current_track: Track = self.get_controller(ctx).current_track
        if not current_track:
            raise BadRequestException("No track is currently playling!")

        self.database.create_if_non_existant(ctx.author.id, "Liked")
        self.database.add_to_playlist(ctx.author.id, "Liked", [current_track])
        await ctx.message.add_reaction("<:ok:746377326245445653>")
Ejemplo n.º 11
0
 async def pause(self, ctx):
     """Pauses the current track"""
     player = self.bot.wavelink.get_player(ctx.guild.id)
     if player.is_playing and not player.is_paused:
         await player.set_pause(True)
         await ctx.send(embed=StyledEmbed(description=f"Stopped song! Use `{prefix}resume` to resume it."),
                        delete_after=20.0)
     else:
         raise BadRequestException("I am currently not playing any track!")
Ejemplo n.º 12
0
 async def join_channel(self, ctx):
     player: Player = self.bot.wavelink.get_player(ctx.guild.id)
     try:
         if player.channel_id != ctx.author.voice.channel.id:
             await player.connect(ctx.author.voice.channel.id)
         controller = self.get_controller(ctx)
         controller.channel = ctx.channel
     except AttributeError:
         raise BadRequestException(
             "You are not connected to a voice channel.")
Ejemplo n.º 13
0
    async def skip(self, ctx):
        """Skips the current song."""
        player: Player = self.bot.wavelink.get_player(ctx.guild.id)
        controller = self.get_controller(ctx)

        if not player.is_playing:
            raise BadRequestException('I am currently not playing anything!')
        await player.stop()
        await ctx.message.add_reaction("<:ok:746377326245445653>")
        if controller.looping_mode == 1:
            await ctx.send("You are currently on loop mode: track. Skipping will just replay the song - turn looping off to play the next song in the queue.", delete_after=15)
Ejemplo n.º 14
0
 async def shutdown(self, ctx):
     """Shuts down the bot. Only available to the bot owner."""
     is_owner = await self.bot.is_owner(ctx.author)
     if is_owner:
         await ctx.message.add_reaction("👋")
         await self.bot.close()
         quit(0)
     else:
         raise BadRequestException(
             "You don't have sufficient permissions to execute this command."
         )
Ejemplo n.º 15
0
        async def success_callback_url(tracks):
            if not player.is_connected:
                await ctx.invoke(self.join)  # Join channel if not connected

            if isinstance(tracks, TrackPlaylist):
                tracks = tracks.tracks
                await ctx.send(embed=StyledEmbed(description=f"**Added** {len(tracks)} **tracks to queue.**"))
            else:
                try:
                    await ctx.send(embed=StyledEmbed(description=f"**Added** {tracks[0]} **to queue.**"))
                except TypeError:
                    raise BadRequestException("Couldn't add this item to the queue!")
            for track in tracks:
                self.get_controller(ctx).queue.append(track)
Ejemplo n.º 16
0
 async def lyrics(self, ctx: Context, *, args=None):
     """Shows you the lyrics of the current or the specified song."""
     async with ctx.typing():
         if args:
             song = args
         else:
             song = self.get_controller(ctx).current_track
             player: Player = self.bot.wavelink.get_player(ctx.guild.id)
             if not song or not player.is_playing:
                 raise BadRequestException("No track is currently playling! You can enter the song's name as an argument.")
             song = song.title
             song = re.sub(r"(\(.*\)|\[.*\]|(.*)|[.*]|【.*】|\d{4}|-+)", "", song)  # Sanitize video title (remove text in parenthesis, for example (OFFICIAL VIDEO) or [MV])
             song = re.sub(r"[ ]{2,}", " ", song)  # replace two or more spaces with a single space
             song = song.lstrip().rstrip()  # remove trailing whitespace
             print(song)
         func = functools.partial(self.genius.search_song, song)
         song = await self.bot.loop.run_in_executor(None, func)
         if song is None:
             if not args:
                 raise BadRequestException("Couldn't find lyrics for the current song. Try entering the name of the song manually.")
             raise BadRequestException("Couldn't find lyrics for the requested song.")
         lyrics = song.lyrics
     pagedlist = PagedListEmbed(f"**Lyrics for** {song.title} - {song.artist}", lyrics.split("\n"), ctx, self.bot, show_per_page=30)
     await pagedlist.send(pagedlist.get())
Ejemplo n.º 17
0
    async def loop(self, ctx, looping_mode):
        """Sets the looping mode. Valid values: `off`, `track`, `queue`"""
        controller = self.get_controller(ctx)

        if looping_mode in ["off", "track", "queue"]:
            controller.prev_looping_mode = controller.looping_mode
            if looping_mode == "off":
                controller.looping_mode = 0
            elif looping_mode == "track":
                controller.looping_mode = 1
            elif looping_mode == "queue":
                controller.looping_mode = 2
            elif looping_mode == "shuffle":
                controller.looping_mode = 3
            await ctx.message.add_reaction("<:ok:746377326245445653>")
        else:
            raise BadRequestException("Invalid value for this command. Valid values: `off`, `track`, `queue`")
Ejemplo n.º 18
0
 async def success_callback_url(tracks):
     nonlocal tracks_to_add
     if isinstance(tracks, TrackPlaylist):
         tracks = tracks.tracks
         await ctx.send(embed=StyledEmbed(
             description=
             f"**Added** {len(tracks)} **tracks to playlist {playlist}.**"
         ),
                        delete_after=10.0)
     else:
         try:
             await ctx.send(embed=StyledEmbed(
                 description=
                 f"**Added** {tracks[0]} **to playlist {playlist}.**"
             ),
                            delete_after=10.0)
         except TypeError:
             raise BadRequestException(
                 "Couldn't add this item to the queue!")
     tracks_to_add = tracks
Ejemplo n.º 19
0
async def search_song(query, ctx, bot, success_callback, success_callback_url):
    from chime.misc.SongSelector import SongSelector

    if query == "^":  # set the query to the previous message
        x = await ctx.channel.history(limit=2).flatten()
        query = x[1].content
        print(query)
    if check_if_url(query):  # user provided an URL, play that
        tracks = await bot.wavelink.get_tracks(query)
        await success_callback_url(tracks)
        return
    else:  # user didn't provide an URL so search for the entered term
        i = 0
        tracks = False
        while not tracks and i < 5:  # try to find song 5 times
            tracks: List[Track] = await bot.wavelink.get_tracks(
                f'ytsearch:{query}')
            i += 1
    if not tracks:
        raise BadRequestException('Could not find any songs with that query.')

    songselector = SongSelector(tracks, bot, success_callback, ctx)
    await songselector.send(songselector.get())
Ejemplo n.º 20
0
    async def playlist(self,
                       ctx: Context,
                       action: str,
                       playlist: str = None,
                       *,
                       additional_args=None):
        """Manage all your personal playlists. You can also manage them on [chime's web app](https://chime.realmayus.xyz)"""
        if action == "create":
            if not additional_args:  # if the playlist name contained spaces, the individual parts would be in additional_args
                self.database.create_playlist(ctx.author.id, playlist)
                await ctx.message.add_reaction("<:ok:746377326245445653>")
            else:
                raise BadRequestException(
                    "If you want spaces in your playlist's name, you have to wrap it in quotation marks!"
                )

        elif action == "show" or action == "view":
            if playlist is not None:
                contents = self.database.get_playlist_contents(
                    ctx.author.id, playlist)
                if len(contents) == 0:
                    raise BadRequestException("Playlist is empty!")

                embed = PagedListEmbed(f"Contents of `{playlist}`", [
                    f"{i + 1}.  {song['title']}"
                    for i, song in enumerate(contents)
                ], ctx, self.bot)
                await embed.send(embed.get())
            else:
                raise BadRequestException("Please enter a playlist name!")

        elif action == "play":
            if playlist is not None:
                contents = self.database.get_playlist_contents(
                    ctx.author.id, playlist)
                await self.join_channel(ctx)
                if len(contents) == 0:
                    raise BadRequestException("Playlist is empty!")

                index = 0
                failed = 0
                for index, song_data_raw in enumerate(contents):
                    try:
                        track = await self.bot.wavelink.build_track(
                            song_data_raw["data"])
                        controller = self.get_controller(ctx)
                        controller.queue.append(track)
                    except BuildTrackError:
                        failed += 1
                        print("Failed to reconstruct track with data " +
                              song_data_raw["data"])
                await ctx.send(embed=StyledEmbed(
                    description=f"**Added** {index + 1} **tracks to queue**."))
                if failed > 0:
                    raise BadRequestException(
                        f"**Failed to add** {failed} **track(s)**!")
            else:
                raise BadRequestException("Please enter a playlist name!")

        elif action == "list":
            await ctx.invoke(self.playlists)

        elif action == "add":
            tracks_to_add = []
            if playlist is None:
                raise BadRequestException("Please enter a playlist name!")

            async def success_callback(track_, last_msg: Message):
                await last_msg.clear_reactions()
                await last_msg.edit(embed=StyledEmbed(
                    description=
                    f"**Added** {track_} **to playlist {playlist}.**"),
                                    delete_after=10.0)
                tracks_to_add.append(track_)

            async def success_callback_url(tracks):
                nonlocal tracks_to_add
                if isinstance(tracks, TrackPlaylist):
                    tracks = tracks.tracks
                    await ctx.send(embed=StyledEmbed(
                        description=
                        f"**Added** {len(tracks)} **tracks to playlist {playlist}.**"
                    ),
                                   delete_after=10.0)
                else:
                    try:
                        await ctx.send(embed=StyledEmbed(
                            description=
                            f"**Added** {tracks[0]} **to playlist {playlist}.**"
                        ),
                                       delete_after=10.0)
                    except TypeError:
                        raise BadRequestException(
                            "Couldn't add this item to the queue!")
                tracks_to_add = tracks

            if not additional_args:
                raise BadRequestException(
                    "You have to provide either a search term or a URL!")

            await search_song(additional_args, ctx, self.bot, success_callback,
                              success_callback_url)

            if len(tracks_to_add) > 0:
                self.database.add_to_playlist(ctx.author.id, playlist,
                                              tracks_to_add)
                await ctx.message.add_reaction("<:ok:746377326245445653>")
            else:
                raise BadRequestException("No track selected!")
        elif action == "share":
            if playlist is None:
                raise BadRequestException("Please enter a playlist name!")
            playlist_id = self.database.raise_if_not_exists(
                ctx.author.id, playlist)
            message = f"{ctx.author.id}:{playlist_id}:{playlist}:{ctx.author.name}"
            message_bytes = message.encode("utf8")
            base64_bytes = base64.b64encode(message_bytes)
            base64_message = base64_bytes.decode("ascii")
            await ctx.send(embed=StyledEmbed(
                title="Share this link",
                description=f"https://chime.realmayus.xyz/view/{base64_message}"
            ))
        elif action == "delete":
            raise BadRequestException(
                "This feature has not been implemented yet.")
        else:
            raise BadRequestException(
                "This action does not exist. Valid actions are: `create`, `list`, `add`, `show`, `play`, `delete` and `share`."
            )