Example #1
0
class YaMusic:

    cache_path = "ya_cache.json"

    def __init__(self):
        logger.level = logging.ERROR
        self.client = Client()
        self.cache = {}
        self.load_cache()
        self.i = 0

    def load_cache(self):
        if not os.path.exists(self.cache_path):
            return
        with open(self.cache_path, "r") as file:
            d = json.load(file)
        for key, value in d.items():
            self.cache[key] = Music.from_json(value)

    def save_cache(self):
        d = {}
        for key, value in self.cache.items():
            d[key] = value.to_json()
        with open(self.cache_path, "w") as file:
            json.dump(d, file)

    def get_song(self, name, author):
        title = "{} - {}".format(author, name)
        song = self.cache.get(title, None)
        if song:
            return song

        self.i += 1
        if self.i > 50:
            self.save_cache()
            self.i = 0

        song = self.client.search(title).best
        if song is None or type(song.result) is not Track:
            music = Music()
            music.name = name
            music.author = [author]
            self.cache[title] = music
            return music
        song = song.result

        music = Music()
        music.duration = song.duration_ms
        music.name = song.title
        music.author = [a.name for a in song.artists]
        music.year = song.albums[0].year or song.albums[
            0].release_date if song.albums else None
        music.genres = [a.genre for a in song.albums if a.genre]
        for i in music.genres:
            if i not in all_genres:
                print(i)
        self.cache[title] = music
        return music
Example #2
0
    async def yaplay(self, ctx, arg: str = None):
        if arg == None:
            if await MusicBot.langueg(ctx) == "RUS":
                embed = discord.Embed(
                    title=f"Вы должны указать название трэка", color=0xff7606)
            elif await MusicBot.langueg(ctx) == "ENG":
                embed = discord.Embed(
                    title=f"You must indicate the name of the track.",
                    color=0xff7606)
            await ctx.send(embed=embed)
            return
        vol = 50
        self.vol = vol
        voice = get(self.bot.voice_clients, guild=ctx.guild)
        try:
            channel = ctx.author.voice.channel
        except:
            if await MusicBot.langueg(ctx) == "RUS":
                embed = discord.Embed(
                    title=f"**{ctx.author.name} Вы не в голосовом канале**",
                    color=0xff7606)
            elif await MusicBot.langueg(ctx) == "ENG":
                embed = discord.Embed(
                    title=
                    f"**{ctx.author.name} You are not in the voice channel**",
                    color=0xff7606)
            await ctx.send(embed=embed)
            return

        if voice and voice.is_connected():
            await voice.move_to(channel)
        else:
            voice = await channel.connect()

        #Логирование (отключение)
        logger = logging.getLogger()
        logger.setLevel(logging.CRITICAL)

        #Подключенеи к акку
        request = Request(proxy_url="https://*****:*****@217.29.62.232:6333")
        client = Client(token=MusicBot.YANDEX_TOKEN, request=request)

        #Делаем поисковой запрос
        search = client.search(arg)

        #Получаем треки
        tracks = search.tracks

        #Сортируем треки в list
        results = tracks.results

        #Получаем первый трек
        track = results[0]

        #Получаем всю инфу по загрузке
        info = track.get_download_info(get_direct_links=True)
        #get_direct_links=True - обязательно надо, а то х*йня получается!!!!!!!!!

        try:
            #Получаем полный путь к музыкальному файлу (поток)
            self.playurl = info[0].direct_link
            self.voice = voice

            self.voice.play(discord.FFmpegPCMAudio(self.playurl))

            self.voice.source = discord.PCMVolumeTransformer(voice.source)
            self.voice.source.volume = self.vol
        except:
            if await MusicBot.langueg(ctx) == "RUS":
                embed = discord.Embed(
                    title=
                    f"**{ctx.author.name} На данный момент песня уже играет**",
                    color=0xff7606)
            elif await MusicBot.langueg(ctx) == "ENG":
                embed = discord.Embed(
                    title=
                    f"**{ctx.author.name} At the moment the song is already playing**",
                    color=0xff7606)
            await ctx.send(embed=embed)
            return
        #Вызываем плеер

        if await MusicBot.langueg(ctx) == "RUS":
            embed = discord.Embed(
                title=f"**{track.title}**",
                description=
                f":white_small_square: **ID:  {track.id} :game_die:**\n\n"
                f":white_small_square: **Регион: {track.regions[0]} :globe_with_meridians:**\n\n"
                f":white_small_square: **[Поделится](https://music.yandex.ru/track/{track.id}) :trumpet:**\n\n",
                color=0xf2a20d)
            # ~ embed.set_thumbnail(url=f"{cover_uri}")
            # ~ embed.set_image(url=f'{track.og_image}')
            embed.set_thumbnail(
                url=
                f"https://cdn.dribbble.com/users/851627/screenshots/2270820/record-player.gif"
            )

            embed.set_footer(
                text=
                f"•Длительность трека: {int((track.duration_ms)/1000/60)} минут\n•Исполнитель: {track.artists[0].name}"
            )
        elif await MusicBot.langueg(ctx) == "ENG":
            embed = discord.Embed(
                title=f"**{track.title}**",
                description=
                f":white_small_square: **ID:  {track.id} :game_die:**\n\n"
                f":white_small_square: **Region: {track.regions[0]} :globe_with_meridians:**\n\n"
                f":white_small_square: **[Share](https://music.yandex.ru/track/{track.id}) :trumpet:**\n\n",
                color=0xf2a20d)
            # ~ embed.set_thumbnail(url=f"{cover_uri}")
            # ~ embed.set_image(url=f'{track.og_image}')
            embed.set_thumbnail(
                url=
                f"https://cdn.dribbble.com/users/851627/screenshots/2270820/record-player.gif"
            )

        msg = await ctx.send(embed=embed)

        await msg.add_reaction(str("▶"))
        await msg.add_reaction(str("⏸"))
        await msg.add_reaction(str("🔊"))
        await msg.add_reaction(str("🔉"))
        await msg.add_reaction(str("⏹"))
        await msg.add_reaction(str("❤️"))
        self.msg_play = msg
Example #3
0
class MusicClient:
    def __init__(self):
        self.token = None
        self.client = None
        self.loggedIn = False
        self.online = False
        self.ui = None

    def init(self):
        if os.path.isfile('token.txt'):
            try:
                tokenFile = open('token.txt', 'r')
                self.token = tokenFile.read()
                tokenFile.close()
                self.client = Client(self.token)
                self.loggedIn = True
                self.online = True
            except:
                return False

        else:
            return False

        return True

    def auth(self, login, password):
        try:
            self.client = Client.from_credentials(
                login, password, captcha_callback=self.proc_captcha)
            tokenFile = open('token.txt', 'w')
            tokenFile.write(self.client.token)
            tokenFile.close()
            self.loggedIn = True
            return True
        except Exception as e:
            return False

    def proc_captcha(self, captcha):
        captcha.download('captcha.png')
        if os.system("./captcha.png") != 0:
            os.system("xdg-open ./captcha.png")
        return input('Число с картинки: ')

    def getFeedPlaylists(self):
        playlists = self.client.feed().generated_playlists

        return storage.savePlaylists(playlists, is_feed=1)

    def getPlaylistTracks(self, playlist):
        p = self.client.playlists_list([playlist.id])
        if (len(p) == 0):
            return []

        clientPlaylist = p[0]
        return storage.saveTracks(clientPlaylist.fetchTracks(),
                                  playlist=playlist)

    def getUri(self, track):
        if not self.online:
            return None

        if (track._directLink != None):
            return track._directLink

        try:
            trackInfo = self.client.tracks_download_info(track.id, True)
            for info in trackInfo:
                if info.codec == "mp3" and info.bitrate_in_kbps == 192:
                    # info.get_direct_link()
                    track._directLink = info.direct_link
                    return track._directLink
        except Exception as e:
            raise e
            print("Cannot get track info. " + str(e))

        return None

    def downloadTrack(self, track):
        if not self.online:
            return None

        trackInfo = self.client.tracks_download_info(track.id, True)
        for info in trackInfo:
            if info.codec == "mp3" and info.bitrate_in_kbps == 192:
                info.download(track.getDownloadsDirectory() + '/' +
                              track.generateFilename())
                track.is_downloaded = 1
                track.filename = track.generateFilename()
                track.store()

    def getArtistTracks(self, artist, page=0, pageSize=20):
        data = self.client.artists_tracks(artist.id, page, pageSize)
        return storage.saveTracks(data.tracks)

    def getArtistAlbums(self, artist):
        albums = []
        page = 0
        pageSize = 20
        maxPage = 1

        while page < maxPage:
            data = self.client.artists_direct_albums(artist.id, page, pageSize)
            maxPage = (data.pager.total // pageSize) + 1
            albums.extend(data.albums)
            page = page + 1

        return storage.saveAlbums(albums)

    def getAlbumTracks(self, album):
        data = self.client.albums_with_tracks(album.id)
        tracks = []
        for arr in data.volumes:
            tracks.extend(arr)

        return storage.saveTracks(tracks)

    def search(self, query):
        data = self.client.search(query)
        response = {
            "best": None,
            "best_type": None,
            "tracks": [],
            "albums": [],
            "artists": [],
            "playlists": [],
        }

        tracks = data.tracks.results
        albums = data.albums.results
        artists = data.artists.results
        playlists = data.playlists.results

        print(list(tracks), file=open('a1.log', 'w'))

        response['tracks'] = storage.saveTracks(tracks)
        response['albums'] = storage.saveAlbums(albums)
        response['artists'] = storage.saveArtists(artists)
        response['playlists'] = storage.savePlaylists(playlists)

        best = None
        if (data.best.type == 'track'):
            best = storage.saveTracks([data.best.result])[0]
            response['best_type'] = 'track'

        if (data.best.type == 'artist'):
            best = storage.saveArtists([data.best.result])[0]
            response['best_type'] = 'artist'

        if (data.best.type == 'playlist'):
            best = storage.savePlaylists([data.best.result])[0]
            response['best_type'] = 'playlist'

        if (data.best.type == 'album'):
            best = storage.saveAlbums([data.best.result])[0]
            response['best_type'] = 'album'

        response['best'] = best

        return response

    def likeTrack(self, track):
        if (track.is_liked == 1):
            self.client.users_likes_tracks_remove(track.id)
            track.is_liked = 0
        else:
            self.client.users_likes_tracks_add(track.id)
            track.is_liked = 1

        track.is_disliked = 0
        track.store()

    def dislikeTrack(self, track):
        if (track.is_disliked == 1):
            self.client.users_dislikes_tracks_remove(track.id)
            track.is_disliked = 0
        else:
            self.client.users_dislikes_tracks_add(track.id)
            track.is_disliked = 1

        track.is_liked = 0
        track.store()

    def getLikedTracks(self):
        tracks = self.client.users_likes_tracks().fetch_tracks()
        return storage.saveTracks(tracks, isLiked=True)
Example #4
0
class Player:
    def __init__(self):
        self.token = None
        self.client = None
        self.loggedIn = False
        self.vlc = None
        self.vlcPlayer = None
        self.daemons = []
        self.download_daemons = []
        
        self.download_queue = Queue()
            
    
    def play_tracks(self, tracks):
        
        if self.vlc == None:
            self.vlc = vlc.Instance()
            self.vlcPlayer = self.vlc.media_list_player_new()
            
        media = []
        media_list = self.vlc.media_list_new()
        has_track = False
        
        try:
            for daemon in self.daemons:
                daemon._stop()
                            
        except:
            pass
        
        finally:
            self.daemons = []
        
        queue = Queue()                    
        t = TrackInfo(queue)
        t.setDaemon(True)
        t.start()
        self.daemons.append(t)
                    
        for track in tracks:            
            path = "music/" + self.track_name(track) + '.mp3'
            if os.path.isfile(path):
                #media.append(path)
                media_list.lock()
                media_list.add_media(path)
                media_list.unlock()
                has_track = True
            else:
                if has_track == False:
                    trackInfo = track.get_download_info()
                    for info in trackInfo:
                        if info.codec == "mp3" and info.bitrate_in_kbps == 192:
                            info.get_direct_link()
                            print(info)
                            #media.append(info.direct_link)
                            media_list.lock()
                            media_list.add_media(info.direct_link)
                            media_list.unlock()
                            has_track = True
                            break
                else:                    
                    queue.put({'track': track, 'list': media_list})
        print("Here!")      
        self.vlcPlayer.set_media_list(media_list)
        print("Here!1")
        self.vlcPlayer.play()
        print("Here!2")
        
        should_exit = False
        while not should_exit:
            try:
                selection = self.get_input("[P]lay / P[a]use / [S]top / [N]ext / P[r]ev / Ba[c]k \n>> ", ["P", "a", "S", "N", "r", "c"])
                if selection == "P":
                    self.vlcPlayer.play()
                elif selection == "a":
                    self.vlcPlayer.pause()
                elif selection == "S":
                    self.vlcPlayer.stop()
                    should_exit = True
                elif selection == "N":
                    self.vlcPlayer.next()
                elif selection == "r":
                    self.vlcPlayer.previous()
                elif selection == "c":
                    should_exit = True
            except Exception as e:
                print(e)
        
    def player_controls(self):
        if (self.vlcPlayer == None):
            print("Player not initialized")
            return;
        
        should_exit = False
        while not should_exit:
            try:
                selection = self.get_input("[P]lay / P[a]use / [S]top / [N]ext / P[r]ev / Ba[c]k \n>> ", ["P", "a", "S", "N", "r", "c"])
                if selection == "P":
                    self.vlcPlayer.play()
                elif selection == "a":
                    self.vlcPlayer.pause()
                elif selection == "S":
                    self.vlcPlayer.stop()
                    should_exit = True
                elif selection == "N":
                    self.vlcPlayer.next()
                elif selection == "r":
                    self.vlcPlayer.previous()
                elif selection == "c":
                    should_exit = True
            except Exception as e:
                print(e)
    
    def init(self):
        
        if os.path.isfile('token.txt'):
            try:
                tokenFile = open('token.txt', 'r')
                self.token = tokenFile.read()
                tokenFile.close();
                self.client = Client(self.token)
                self.loggedIn = True
            except:
                print("Failed to create client using saved token. Enter your login/password.")
                self.login()
                
        else:
            self.login()
            
        
        
    def login(self):
        self.loggedIn = False
        while not self.loggedIn:
            try:            
                login = input("Login: "******"Password: "******"Login failed!")
                print(e)
            
    def proc_captcha(self, captcha):
        captcha.download('captcha.png')
        if os.system("./captcha.png") != 0:
            os.system("xdg-open ./captcha.png")
        return input('Число с картинки: ')
    
    def get_status(self):
        data = self.client.account_status()
        print("Login: "******"Name: " + data.account.first_name)
        print("Surname: " + data.account.second_name)
        
    def playlists(self):
        playlists = player.client.feed().generated_playlists
                
        should_exit = False
        while not should_exit:
            try:
                index = 1        
                for playlist in playlists:
                    print(str(index) + ") " + playlist.data.title)
                    index = index + 1
                    
                selection = self.get_input('Playlist number / [B]ack \n>> ', ["B"])
                if (selection == "B"):
                    should_exit = True
                else:
                    self.playlist(playlists[int(selection) - 1])
            except Exception as e:
                print(e)
                
    def track_name(self, track):
        artists = ""
        for artist in track.artists:
            artists = artists + artist.name + " "
        return track.title + " ( " + artists + " )"
    
    def playlist(self, playlist):
        tracksShort = []
        
        if (hasattr(playlist, "data")):
            tracksShort = playlist.data.tracks
        else:            
            p = self.client.playlists_list( playlist.playlist_id )            
            tracksShort = p[0].tracks            
            
        track_ids = []
        for trackShort in tracksShort:
            track_ids.append(trackShort.track_id)
        
        if (len(track_ids) == 0):
            print("Tracks list is empty")
            return
        
        tracks = self.client.tracks(track_ids)                    
        should_exit = False
        while not should_exit:
            try:
                index = 1
                for track in tracks:            
                    print(str(index) + ") " + self.track_name(track))
                    index = index + 1
                    
                selection = self.get_input("Track number / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack\n>> ", ["D", "P", "L", "i", "B"])
                if selection == "D":
                    self.download_tracks(tracks)
                elif (selection == "L"):
                    playlist.like()
                elif (selection == "i"):
                    playlist.dislike()
                elif selection == "B":
                    should_exit = True
                elif selection == "P":
                    self.play_tracks(tracks)
                else:
                    self.track(tracks[selection - 1])
            except Exception as e:
                print(e)
            
    def get_input(self, prompt, allowed = [], numbers = True):
        valid = False 
        while not valid:
            selection = input(prompt)
            if selection in allowed:
                return selection
            if (numbers == True):
                try:
                    number = int(selection)
                    if (number > 0):
                        return number                
                except:
                    pass
    def download_tracks(self, tracks):
        if (len(self.download_daemons) == 0):
            for i in range(2):
                t = TrackDownloader(self.download_queue)
                t.setDaemon(True)
                t.start()
                self.download_daemons.append(t)
                
        print("Downloading " + str(len(tracks)) + " tracks")
                
        for track in tracks:
            self.download_queue.put(track.track_id)
        
    def track(self, track):
        print(self.track_name(track))
        should_exit = False
        while not should_exit:
            try:
                selection = self.get_input("[D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack\n>> ", ["D", "P", "L", "i", "B"], False)
                if selection == "D":
                    self.download_tracks([track])
                elif (selection == "L"):
                    track.like()
                elif (selection == "i"):
                    track.dislike()
                elif selection == "P":
                    self.play_tracks([track])
                else:
                    should_exit = True
            except Exception as e:
                print(e)
                
    def search(self):
        query = input("Search: ")
        data = self.client.search(text=query)
        print(data)
        results = []
        for track in data.tracks.results:
            results.append(track)
        for album in data.albums.results:
            results.append(album)
        for artist in data.artists.results:
            results.append(artist)
        for playlist in data.playlists.results:
            results.append(playlist)        
        
        best = data.best.result
        if (best != None):
            print("B) " + self.entity_name(best))      
        
        index = 1
        for result in results:
            print(str(index) + ") " + self.entity_name(result))
            index = index + 1
        
        should_exit = False
        while not should_exit:
            try:
                selection = self.get_input("Number / [B]est choice / [E]xit \n>> ", ["B", "E"])
                if selection == "B":
                    self.open_entity(best)
                elif selection == "E":
                    should_exit = True
                else:
                    self.open_entity(results[selection - 1])
            except Exception as e:
                print(e)
        
    def open_entity(self, entity):
        if (type(entity) is Track):
            self.track(entity)
        elif (type(entity) is Playlist):
            self.playlist(entity)
        elif (type(entity) is Artist):
            self.artist(entity)
        elif (type(entity) is Album):
            self.album(entity)
        
    def entity_name(self, result):
        if (type(result) is Artist):
            return ("(Artist) " + result.name)
        elif type(result) is Track:
            return ("(Track) " + self.track_name(result))
        elif type(result) is Album:
            artists = ""
            for artist in result.artists:
                artists = artists + " " + artist.name
            return ("(Album) " + result.title + " (" + artists + " )")
        elif type(result) is Playlist:
            return "(Playlist) " + result.title + " by " + result.owner.name
        else:            
            return (str(type(result)))
            
    def artist(self, artist):                    
        print(artist.name)
        print(artist.description)
        page = 0
        tracks = artist.get_tracks(page=page).tracks
        albums = artist.get_albums(page=page).albums
        
        entities = []        
        for track in tracks:
            entities.append(track)
            
        for album in albums:
            entities.append(album)
            
        should_exit = False
        while not should_exit:
            try:
                index = 1
                for e in entities:                    
                    print(str(index) + ") " + self.entity_name(e))
                    index = index + 1
                    
                selection = self.get_input("Number / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack / [M]ore / [A]ll\n>> ", ["D", "P", "L", "i", "B", "M", "A"])
                if selection == "D":
                    t = []
                    for e in entities:
                        if (type(e) is Track):
                            t.append(e)
                    self.download_tracks(t)
                elif (selection == "L"):
                    artist.like()
                elif (selection == "i"):
                    artist.dislike()
                elif selection == "P":
                    t = []
                    for e in entities:
                        if (type(e) is Track):
                            t.append(e)
                    self.play_tracks(t)
                elif selection == "B":
                    should_exit = True
                elif selection == "M":
                    page = page + 1
                    tracks = artist.get_tracks(page=page).tracks
                    albums = artist.get_albums(page=page).albums
                    for track in tracks:
                        entities.append(track)
                        
                    for album in albums:
                        entities.append(album)
                elif selection == "A":
                    tPage = page
                    aPage = page
                    while True:
                        tPage = tPage + 1
                        tracks = artist.get_tracks(page=tPage).tracks
                        for track in tracks:
                            entities.append(track)
                        sys.stdout.write('.')
                        if (len(tracks) == 0):
                            break
                    print('')
                    while True:
                        aPage = aPage + 1
                        albums = artist.get_albums(page=aPage).albums
                        for a in albums:
                            entities.append(a)
                        sys.stdout.write('.')
                        if (len(albums) == 0):
                            break
                    
                else:
                    self.open_entity(entities[selection - 1])
            except Exception as e:
                print(e)
            
        
        
    def get_all(self, func, prop):
        page = 0
        last_page = 1
        data = []
        while page < last_page:
            portion = func(page=page)
            for e in portion[prop]:
                data.append(e)
            last_page = portion.pager.total / portion.pager.per_page + 1
            page = page + 1
            print(page)
        return data
            
    
    def album(self, album):
        print(self.entity_name(album))
        album_tracks = album.with_tracks()
                        
        should_exit = False
        
        while not should_exit:
            try:
                index = 1
                for track in album_tracks.volumes[0]:
                    print(str(index) + ") " + self.track_name(track))
                    index = index + 1
                    
                selection = self.get_input("[A]rtist / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack \n>> ", ["A", "D", "P", "L", "i", "B"])
                if selection == "D":
                    self.download_tracks(album_tracks.volumes[0])
                elif selection == "A":
                    self.artist(album_tracks.artists[0])
                elif selection == "L":
                    album_tracks.like()
                elif selection == "i":
                    album_tracks.dislike()
                elif selection == "B":
                    should_exit = True
                elif selection == "P":
                    self.play_tracks(album_tracks.volumes[0])
                else:
                    self.track(album_tracks.volumes[0][selection - 1])
            except Exception as e:
                print(e)
        
    def menu(self):
        should_exit = False
        while not should_exit:
#            try:
                selection = self.get_input("[P]laylists / [M]e / [S]earch / P[l]ayer / [E]xit \n>> ", ["P", "M", "S", "E", "l"], False)
                if (selection == "P"):
                    self.playlists()
                elif selection == "M":
                    self.get_status()
                elif selection == "S":
                    self.search()
                elif selection == "E":
                    should_exit = True
                elif selection == "l":
                    self.player_controls()