Spothiefy: how to move from Yandex.Music quickly, for free

So, in July, life in the country finally began to change for the better, because something happened that many people were looking forward to: Spotify was launched in Russia and several other countries.



But streaming music did not appear yesterday, and there are probably those who are hooked on Yandex and use a subscription to Yandex.Music, which later became Yandex.Plus.



It became convenient to listen to songs, the selectors learned to select good tracks, and this led to the accumulation of a library with playlists and other convenient things that need to be added anew in the new service.



If you want to try, but you are too lazy, then I will tell you how to move your belongings quickly, for free. You just need a few pythons with batteries.



Peter and the Spotifai cover



Attention!
, .



, . , . .

.



Spotify , . , . , - .



— , . - ., - Spotify. , - , 144 / Ogg Vorbis.



, .



/ .



With the help of simple devices, in a couple of days I managed to make an importer of tracks in Spotify and not spend money on soundiiz, which for some reason suddenly increased the load.



But there are nuances.



API



Spotify provides some kind of documentation for its Web API service, including an API for adding both playlists and favorites to its library.



In turn, Yandex.Music does not have a public API , but perhaps competition will spur them on to provide access for third-party developers, because it is necessary, convenient and useful.

Therefore, here we will go a little along a curved path, and use tricks with a dubious reputation.



And what about Deezer?
Deezer, , API . Python, .





Spotify



Everything is simple here. To become a developer, you need to get the application key in the console .

They will offer to add Redirect URIfor OAuth, which can be installed by anyone, since it is needed only for services that serve a bunch of people at once, but in our case everything happens locally.



Yandex.Music



You need a username and password for your account, but if two-factor authentication is enabled, you need to specify Yandex.Password from Yandex.Key.



Application operation



I don’t want to stop at running Python applications, deploying a virtual environment, etc., so I’ll describe how the import works. Link to the repository with the program code at the end of the article .



Tracks from APIs of all platforms come in a different format, so they are converted to the same presentation with the minimum required set of properties:



class Track:
    title = property(lambda self: self.__title)
    album = property(lambda self: self.__albums[0] if len(self.__albums) > 0 else None)
    artist = property(lambda self: self.__artists[0] if len(self.__artists) > 0 else None)

    albums = property(lambda self: self.__albums)
    artists = property(lambda self: self.__artists)


Playlists (including favorites) also have the same format, and include an iterator of tracks for easy use in loops:



class Playlist:
    class __iterator:
        def __init__(self, playlist):
            pass  #   
        def __next__(self):
            pass  #   

    title = property(lambda self: self.__title)
    tracks = property(lambda self: self.__tracks)
    is_public = property(lambda self: self.__is_public)

    def __len__(self):
        return len(self.__tracks)

    def __iter__(self):
        return Playlist.__iterator(self)

    def __getitem__(self, index):
        return self.__tracks[index]


The class is responsible for interacting with services MusicProvider:



class MusicProvider:
    favorites = property(lambda self: self.__favorites)
    playlists = property(lambda self: self.__playlists)


YandexMusic (MusicProvider)At initialization, the class loads information on all playlists and all tracks in the "I liked" playlist.



Spotify (MusicProvider)it doesn't, but contains methods for importing:



class Spotify(MusicProvider):
    def import_playlist(self, playlist):
        pass  #   

    def import_favorites(self, playlist):
        pass  #   


Inside, it searches for tracks in the Spotify database using song data obtained from Yandex.Music.



After all the tracks in the playlist are found, it is created (if it is not "Liked Songs") with the same name and all found melodies are added to it.



Playlists and saved tracks require different permissions:



  • playlist-modify-private - to create / modify playlists
  • user-library-modify - to add audio tracks to favorites


There is a problem: the length of the query string is limited, so when there is a huge number of songs in the playlist, the query fails without even starting. To avoid this situation, the list of tracks is cut into pieces of 50 pieces and the addition is made with several requests.



The searchSpotify API method supports keywords to search for albums / artists / titles, which we will shamelessly use.



Search Spotify



Spotify has a large track database, but not all of the music is there. You can easily guess that a lot of music missing from Spotify overlaps with a lot of Yandex.Music song database. Some of the music tracks may be covers / remixes and other perversions, and some may just be incorrect: the wrong album, or the order of the musicians is different.



Another problem is added by a different approach to compiling information about tracks: Spotify can have only one album, and Yandex.Music sends an array of albums. There may already be several performers both there and there.



Deezer provides one album and one artist, but that's another story.



Therefore, the following approach is used to eat both the fish and sit on the chair :



  • For all albums are searched for exact match keywords track:, artist:, album:.

    More often than not, this is enough.
  • If the track is not found (or the album is not specified in Yandex.Music), an attempt is made to search without an album.
  • If no track is found, it searches with the next artist.


Not found melodies and non-standard audio track search conditions are displayed in the log. You can see what exactly has been added and, if necessary, process it manually.



Note



This project is by and large necessary for a one-time task, it was developed in free time, not for use in industrial applications, so for a seasoned specialist the code may seem disgusting.



However, while developing the practice, PEP8 has more or less tried to be followed, and the overall size of the program is quite small.



Source codes of the program



Current Python version at the time of writing: 3.8.4



Used materials:



  • Illustration by Peter the Pig: The book "Peter the Pig and the Machine", Petrushevskaya Ludmila
  • Yandex.Music logo: YANDEX LLC
  • Spotify logo: Spotify AB



All Articles