timrae / spotify_to_tidal Goto Github PK
View Code? Open in Web Editor NEWA command line tool for importing your Spotify playlists into Tidal
License: GNU Affero General Public License v3.0
A command line tool for importing your Spotify playlists into Tidal
License: GNU Affero General Public License v3.0
Hi,
This is more a request than a bug warn, by the way:
if I submit the favourite tracks list url (https://open.spotify.com/collection/tracks) the script cannot manage it.
Best regards
Hi there,
seems that I am doing something wrong. On a headless Ubuntu 20 I run:
python3 sync.py
but nothing happens. I have to abort with ctrl-c to get back to the command line, where it then says:
Traceback (most recent call last):
File "/home/meiko/spotify_to_tidal/sync.py", line 297, in
spotify_session = open_spotify_session(config['spotify'])
File "/home/meiko/spotify_to_tidal/auth.py", line 16, in open_spotify_session
credentials_manager.get_access_token(as_dict=False)
File "/home/meiko/miniconda3/lib/python3.10/site-packages/spotipy/oauth2.py", line 535, in get_access_token
"code": code or self.get_auth_response(),
File "/home/meiko/miniconda3/lib/python3.10/site-packages/spotipy/oauth2.py", line 490, in get_auth_response
return self._get_auth_response_local_server(redirect_port)
File "/home/meiko/miniconda3/lib/python3.10/site-packages/spotipy/oauth2.py", line 459, in _get_auth_response_local_server
server.handle_request()
File "/home/meiko/miniconda3/lib/python3.10/socketserver.py", line 294, in handle_request
ready = selector.select(timeout)
File "/home/meiko/miniconda3/lib/python3.10/selectors.py", line 416, in select
fd_event_list = self._selector.poll(timeout)
KeyboardInterrupt
If I understand everything right, I should have get an URL for authorization, haven't I?
Thanks
meiko
Maybe this could create a csv with the columns title, artist, spotifyId, playlist maybe album.
To either help find the titles if they are just named slightly different or to at least know which songs you lost, without having create such a file from the console output.
Fixed this by simply changing it to pyyaml==6.0.1 in requirements.txt but if I'm honest I have no clue what I'm doing with Python, so I've no clue if that's the latest version or anything like that.
It seems songs with umlaut containing (Ä, Ö, Å) names are excluded in import.
For example CMX - Yöllisiä
https://open.spotify.com/track/0Kw4DHSo7hlZW6FHokdtdv?si=53f47d93724d464d
Maybe replace would work
Ä, Å--> A
Ö --> O
This has the potential to be significantly faster than the current implementation for spotify tracks with a known isrc:
https://apiref.developer.tidal.com/
We should of course fallback on the old implementation if no result was returned (or incorrect result)
@joshrmcdaniel
Did you perhaps forget to commit some files? I can't run the project on main
python3 -m pip install -e .
spotify_to_tidal
Traceback (most recent call last):
File "~/.pyenv/versions/3.10.12/bin/spotify_to_tidal", line 5, in <module>
from spotify_to_tidal.__main__ import main
File "src/spotify_to_tidal/__main__.py", line 5, in <module>
from . import sync as _sync
File "src/spotify_to_tidal/sync.py", line 16, in <module>
from .type import spotify as t_spotify
File "src/spotify_to_tidal/type/__init__.py", line 1, in <module>
from .config import SpotifyConfig, TidalConfig, PlaylistConfig, SyncConfig
ModuleNotFoundError: No module named 'spotify_to_tidal.type.config'
Traceback (most recent call last):
File "/Users/koraysels/PycharmProjects/spotify_to_tidal/sync.py", line 299, in <module>
tidal_session = open_tidal_session()
^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/PycharmProjects/spotify_to_tidal/auth.py", line 48, in open_tidal_session
future.result()
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/concurrent/futures/_base.py", line 456, in result
return self.__get_result()
^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/concurrent/futures/_base.py", line 401, in __get_result
raise self._exception
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/session.py", line 364, in _process_link_login
self.user = tidalapi.User(self, user_id=json['userId']).factory()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/user.py", line 48, in factory
return self.request.map_request('users/%s' % self.id, parse=self.parse)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/request.py", line 118, in map_request
return self.map_json(json_obj, parse=parse)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/request.py", line 125, in map_json
return parse(json_obj)
^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/user.py", line 65, in parse
return user.parse(json_obj)
^^^^^^^^^^^^^^^^^^^^
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/user.py", line 104, in parse
super(LoggedInUser, self).parse(json_obj)
File "/Users/koraysels/.pyenv/versions/3.11.1/lib/python3.11/site-packages/tidalapi/user.py", line 77, in parse
self.picture_id = json_obj['picture']
~~~~~~~~^^^^^^^^^^^
KeyError: 'picture'
cannot seem to get it working..
I give python3 sync.py (in my case with python sync.py it works)
It opens the verification windows for spotify and Tidal but when I open tidal after verifying the code, the subscription window pops up and I am tidal free user.
The console shows this message Login with the webbrowser: link.tidal.com/(berification code) but then nothing else is shown.
https://i.postimg.cc/XJ3m96Nt/Captura-de-pantalla-2023-06-07-122721.png
Just discovered this rather annoying bug, not sure when I introduced it, should have a fix soon!
After I fixed an error that the http exception does not have a method json ( I just removed the part from the print) I get another HTTPException after too many timeouts. Its probably the api hard limiting I guess?
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 449, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 444, in _make_request
httplib_response = conn.getresponse()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1374, in getresponse
response.begin()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 318, in begin
version, status, reason = self._read_status()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 287, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without response
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/requests/adapters.py", line 489, in send
resp = conn.urlopen(
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
retries = retries.increment(
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/util/retry.py", line 550, in increment
raise six.reraise(type(error), error, _stacktrace)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/packages/six.py", line 769, in reraise
raise value.with_traceback(tb)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 449, in _make_request
six.raise_from(e, None)
File "<string>", line 3, in raise_from
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 444, in _make_request
httplib_response = conn.getresponse()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 1374, in getresponse
response.begin()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 318, in begin
version, status, reason = self._read_status()
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/http/client.py", line 287, in _read_status
raise RemoteDisconnected("Remote end closed connection without"
urllib3.exceptions.ProtocolError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/pool.py", line 125, in worker
result = (True, func(*args, **kwds))
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 126, in _enumerate_wrapper
return (index, repeat_on_http_error(function, value, **kwargs))
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 121, in repeat_on_http_error
return repeat_on_http_error(function, *args, remaining=remaining-1, **kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 121, in repeat_on_http_error
return repeat_on_http_error(function, *args, remaining=remaining-1, **kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 121, in repeat_on_http_error
return repeat_on_http_error(function, *args, remaining=remaining-1, **kwargs)
[Previous line repeated 1 more time]
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 110, in repeat_on_http_error
return function(*args, **kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/sync.py", line 87, in tidal_search
album_result = tidal_session.search(simple(spotify_track['album']['name']) + " " + simple(spotify_track['album']['artists'][0]['name']), models=[tidalapi.album.Album])
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/tidalapi/session.py", line 446, in search
json_obj = self.request.request('GET', 'search', params=params).json()
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/tidalapi/request.py", line 97, in request
request = self.basic_request(method, path, params, data, headers)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/tidalapi/request.py", line 62, in basic_request
request = self.session.request_session.request(method, url, params=request_params, data=data, headers=headers)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/requests/sessions.py", line 587, in request
resp = self.send(prep, **send_kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/requests/sessions.py", line 701, in send
r = adapter.send(request, **kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/requests/adapters.py", line 547, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/secretunicorn/Downloads/spotify_to_tidal/./sync.py", line 292, in <module>
sync_list(spotify_session, tidal_session, get_user_playlist_mappings(spotify_session, tidal_session, config), config)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/./sync.py", line 228, in sync_list
repeat_on_http_error(sync_playlist, spotify_session, tidal_session, spotify_id, tidal_id, config)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/./sync.py", line 110, in repeat_on_http_error
return function(*args, **kwargs)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/./sync.py", line 210, in sync_playlist
tidal_tracks = call_async_with_progress(tidal_search, spotify_tracks, task_description, config.get('subprocesses', 50), tidal_session=tidal_session)
File "/Users/secretunicorn/Downloads/spotify_to_tidal/./sync.py", line 131, in call_async_with_progress
for index, result in tqdm(process_pool.imap_unordered(partial(_enumerate_wrapper, function=function, **kwargs),
File "/Users/secretunicorn/Downloads/spotify_to_tidal/venv/lib/python3.10/site-packages/tqdm/std.py", line 1195, in __iter__
for obj in iterable:
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/multiprocessing/pool.py", line 873, in next
raise value
requests.exceptions.ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
Hi,
first of all its an awesome project.
Could you please add an parameter for appending the tidal playlist?
It would be awesome if I could add more music to the tidal playlist without them getting removed by the script.
Thanks mate :)
Hi, I tried today the script, and after finish and check there were no errors I see on my tidal account, only the playlist created by me are sync, but not others playlist saved on my account.
Is there an error, or something I have to config?
Thank you anyway!
spotify_to_tidal\sync.py", line 10, in
from .tidalapi_patch import set_tidal_playlist
ImportError: attempted relative import with no known parent package
How to solve this?
Any chance to implement some kind of throttling?
Getting a lot of these:
"429 Client Error: Too Many Requests for url: https://api.tidal.com/v1/search?sessionId=XXX",
'X-Cache': 'Error from cloudfront'
('Connection aborted.', RemoteDisconnected('Remote end closed connection without response')) occurred, retrying 2 times
and then the script just hangs and the playlist created on Tidal has 0 tracks.
As of 2022-02-09, https://developer.spotify.com/documentation/general/guides/app-settings/#register-your-app gives a 404 error.
Hi,
When running sync.py
, after entering the url that I was redirected to, I get this error message:
Login failed: {"status":401,"error":"invalid_client","error_description":"Client with token 8SEZWa4J1NVC5U5Y not found","sub_status":1005}
Traceback (most recent call last):
File "/Users/davidkatchouni/Downloads/spotify_to_tidal-master/sync.py", line 288, in <module>
tidal_session = open_tidal_session()
File "/Users/davidkatchouni/Downloads/spotify_to_tidal-master/auth.py", line 40, in open_tidal_session
login, future = session.login_oauth_simple()
File "/usr/local/lib/python3.9/site-packages/tidalapi/__init__.py", line 213, in login_oauth_simple
login, future = self.login_oauth()
File "/usr/local/lib/python3.9/site-packages/tidalapi/__init__.py", line 226, in login_oauth
login, future = self._login_with_link()
File "/usr/local/lib/python3.9/site-packages/tidalapi/__init__.py", line 240, in _login_with_link
request.raise_for_status()
File "/usr/local/lib/python3.9/site-packages/requests/models.py", line 960, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 401 Client Error: Unauthorized for url: https://auth.tidal.com/v1/oauth2/device_authorization
I've followed all instructions, however getting this error when running the script. No ideas how to solve it...
File "sync.py", line 298, in <module>
tidal_session = open_tidal_session()
File "/Users/gediminas/WEB/learning/spotify_to_tidal/auth.py", line 48, in open_tidal_session
future.result()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 435, in result
return self.__get_result()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/_base.py", line 384, in __get_result
raise self._exception
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/concurrent/futures/thread.py", line 57, in run
result = self.fn(*self.args, **self.kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/session.py", line 364, in _process_link_login
self.user = tidalapi.User(self, user_id=json['userId']).factory()
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/user.py", line 48, in factory
return self.request.map_request('users/%s' % self.id, parse=self.parse)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/request.py", line 118, in map_request
return self.map_json(json_obj, parse=parse)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/request.py", line 125, in map_json
return parse(json_obj)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/user.py", line 65, in parse
return user.parse(json_obj)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/user.py", line 104, in parse
super(LoggedInUser, self).parse(json_obj)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/tidalapi/user.py", line 77, in parse
self.picture_id = json_obj['picture']
KeyError: 'picture'
Current Behavior: Syncing a playlist correctly syncs the tracks to a new playlist. However, when sorting the Tidal playlist, we actually get the inverse order as the Spotify playlist. For example, Tidal's playlist has to be in descending date order to match Spotify's ascending date order.
Desired Behavior: When sorting by the "Date Added" column, the Spotify and Tidal playlists should have an identical order.
Fix: Reverse the Tidal tracks before appending them to the playlist.
had a tidal login problem but it turns out that Tidal changed the secret values so tidalapi barfed.
I ended up hardcoding the secrets from here in tidalapi_init_.py and bob is my uncle
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.