XDGFX / ultrasonics

Sync music playlists between all your music services. Do more with your music.
GNU General Public License v3.0
223 stars 18 forks source link

Spotify to .txt file #29

Open Captain-Wiggles opened 3 years ago

Captain-Wiggles commented 3 years ago

I'm trying to create a txt file via spotify and I keep getting the same error.

←[38m2021-09-06 18:08:27,640 - plugins - DEBUG - Running plugin custom file v0.1 (plugins.py:158)←[0m ←[31m2021-09-06 18:08:27,656 - plugins - ERROR - 'charmap' codec can't encode characters in position 174-178: character maps to <undefined> (plugins.py:291)←[0m Traceback (most recent call last): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 285, in applet_run plugin_run(*get_info(plugin), component="outputs", File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 162, in plugin_run response = found_plugins[name].run( File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_custom file.py", line 79, in run f.write("\n".join(write_lines)) File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\encodings\cp1252.py", line 19, in encode return codecs.charmap_encode(input,self.errors,encoding_table)[0] UnicodeEncodeError: 'charmap' codec can't encode characters in position 174-178: character maps to <undefined> ←[33m2021-09-06 18:08:27,688 - plugins - WARNING - Applet 47c6a149-0f5a-11ec-a40b-54424958cd16 failed in 0:00:04.828303 (plugins.py:299)←[0m ←[96m2021-09-06 18:08:27,706 - database - INFO - Applet lastrun updated (database.py:377)←[0m

I believe it's because my playlists includes songs with Asian characters (Japanese, Korean, Chinese) but I'm not 100% sure. I've tried using keywords to limit the playlists which only include English characters but it doesn't create the txt at all in some cases.

Any suggestions welcome

XDGFX commented 3 years ago

It looks like the plugin didn't specify to use utf8 when writing files. If you pull and run the 1.1.0 branch has it fixed the problem?

https://github.com/XDGFX/ultrasonics/tree/1.1.0

Captain-Wiggles commented 3 years ago

I pulled the latest and it still fails but has a different error this time:

←[38m2021-09-07 20:16:36,136 - plugins - DEBUG - Running plugin spotify v0.4 (plugins.py:158)←[0m 2021-09-07 20:16:36,147 - 🎧 spotify - INFO - Credentials will be cached in: C:\Program Files (x86)\ultrasonics\config\up_spotify\up_spotify.bz2 (up_spotify.py:104) 2021-09-07 20:16:36,152 - 🎧 spotify - DEBUG - Fetching your Spotify token (up_spotify.py:121) 2021-09-07 20:16:36,482 - 🎧 spotify - DEBUG - Token is valid. (up_spotify.py:152) 2021-09-07 20:16:36,485 - 🎧 spotify - DEBUG - Returning cached token (up_spotify.py:129) 2021-09-07 20:16:37,033 - 🎧 spotify - INFO - Found 74 playlist(s) on Spotify. (up_spotify.py:340) 2021-09-07 20:16:37,046 - 🎧 spotify - INFO - Building songs_dict for playlists... (up_spotify.py:558) 0it [00:00, ?it/s]2021-09-07 20:16:37,214 - 🎧 spotify - INFO - Converting tracks to ultrasonics format. (up_spotify.py:386) Converting tracks in 3dkGK79CdPrhhscnCLrx2r: 100%|█████████████████████████████████████████████████████████████████████████████████████████████████| 37/37 [00:00<?, ?it/s] 1it [00:00, 5.32it/s]2021-09-07 20:16:37,338 - 🎧 spotify - INFO - Converting tracks to ultrasonics format. (up_spotify.py:386) | 0/37 [00:00<?, ?it/s] Converting tracks in 5GXrkaWY7Iapyo7svDsQME: 0%| | 0/30 [00:00<?, ?it/s] 1it [00:00, 3.44it/s]GXrkaWY7Iapyo7svDsQME: 0%| | 0/30 [00:00<?, ?it/s] ←[31m2021-09-07 20:16:37,342 - plugins - ERROR - 'NoneType' object is not subscriptable (plugins.py:291)←[0m Traceback (most recent call last): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 273, in applet_run for item in plugin_run(*get_info(plugin), component="inputs", applet_id=applet_id): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 162, in plugin_run response = found_plugins[name].run( File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 560, in run tracks = s.playlist_tracks(playlist["id"]["spotify"]) File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 388, in playlist_tracks track_list.append(s.spotify_to_songs_dict(track)) File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 405, in spotify_to_songs_dict artists = [artist["name"] for artist in track["artists"]] TypeError: 'NoneType' object is not subscriptable ←[33m2021-09-07 20:16:37,344 - plugins - WARNING - Applet 47c6a149-0f5a-11ec-a40b-54424958cd16 failed in 0:00:01.220947 (plugins.py:299)←[0m ←[96m2021-09-07 20:16:37,357 - database - INFO - Applet lastrun updated (database.py:377)←[0m

XDGFX commented 3 years ago

It looks like maybe one of the songs in a playlist is missing an artist tag?

artists = [artist["name"] for artist in track["artists"]]
TypeError: 'NoneType' object is not subscriptable

This suggests the track["artists"] field is empty, and ultrasonics requires at least an artist and track title to work properly. Sorting your library by artist name should show blank fields either at the start or end!

Captain-Wiggles commented 3 years ago

So I've been trying to isolate the issues and there's two discoveries so far:

  1. I had invalid windows characters for file names in my playlists. I.e. : \ / | etc.
  2. Korean and Chinese(?) characters for Artists/Songs are read as 'none' value. I added a playlist where an artist had korean characters to force the error. Is there anyway to have the program simply skip that song that would cause an issue in the txt file?

Converting tracks in 1djHlnZ2iNlg4hd6lFnAiZ: 37%|████████████████▋ | 27/73 [00:00<?, ?it/s] 1it [00:00, 1.77it/s]djHlnZ2iNlg4hd6lFnAiZ: 0%| | 0/73 [00:00<?, ?it/s] ←[31m2021-09-15 22:12:09,196 - plugins - ERROR - 'NoneType' object is not subscriptable (plugins.py:291)←[0m Traceback (most recent call last): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 273, in applet_run for item in plugin_run(*get_info(plugin), component="inputs", applet_id=applet_id): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 162, in plugin_run response = found_plugins[name].run( File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 560, in run tracks = s.playlist_tracks(playlist["id"]["spotify"]) File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 388, in playlist_tracks track_list.append(s.spotify_to_songs_dict(track)) File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 405, in spotify_to_songs_dict artists = [artist["name"] for artist in track["artists"]] TypeError: 'NoneType' object is not subscriptable ←[33m2021-09-15 22:12:09,199 - plugins - WARNING - Applet 9dee98b2-1687-11ec-8e06-54424958cd16 failed in 0:00:23.171542 (plugins.py:299)←[0m ←[96m2021-09-15 22:12:09,211 - database - INFO - Applet lastrun updated (database.py:377)←[0m

XDGFX commented 3 years ago

Good idea, the latest 1.1.0 branch should skip any songs that it can't read properly. Give it a go and let me know if it works! If not, let me know an example song that it fails on for me to test

Captain-Wiggles commented 3 years ago

Updated to 1.1.0 branch by downloading the zip, then copying and pasting the files in my ultrasonics folder. Unfortunately, it still failed.

Here's a song that causes it to fail: https://open.spotify.com/track/4qzBepJAKtYu4T1GDtBZZc?si=cbeb47cc99054381

Traceback (most recent call last): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 273, in applet_run for item in plugin_run(*get_info(plugin), component="inputs", applet_id=applet_id): File "C:\Program Files (x86)\ultrasonics\ultrasonics\plugins.py", line 162, in plugin_run response = found_plugins[name].run( File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 568, in run tracks = s.playlist_tracks(playlist["id"]["spotify"]) File "C:\Program Files (x86)\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 396, in playlist_tracks f"Could not convert track {track['id']} to ultrasonics format." TypeError: 'NoneType' object is not subscriptable ←[33m2021-09-27 22:15:22,128 - plugins - WARNING - Applet 5c2de7b1-18a7-11ec-9eca-54424958cd16 failed in 0:00:13.169225 (plugins.py:299)←[0m ←[96m2021-09-27 22:15:22,147 - database - INFO - Applet lastrun updated (database.py:377)←[0m

XDGFX commented 3 years ago

It seems that one of the songs from Spotify hasn't got a valid ID. If you are able to run in debug mode, put a break point at line 396 of up_spotify.py, and have a look at the track variable for the failed song. I had assumed all Spotify songs have an ID, maybe fetching any information failed for this song for some reason.

XDGFX commented 3 years ago

Managed to test this myself with the song you supplied - I don't have the same error.

track seems fine.

{'album': {'name': 'RISE', 'release_date': '2014-06-13'}, 'artists': [{...}], 'external_ids': {'isrc': 'KRB471402723'}, 'id': '4qzBepJAKtYu4T1GDtBZZc', 'name': '눈,코,입 (Eyes, Nose, Lips)', 'track_number': 2}

And the plugin completes without issue.

Could I ask you to re-download ultrasonics (1.1.0 is now the main branch and latest release), and try again? My only thought is a glitch on spotify's end, maybe the song was missing something temporarily, but that's now been fixed?

Captain-Wiggles commented 3 years ago

Hey! thanks for looking into this again. I've been meaning to take a look myself as well just haven't had time (I bought some new equipment and have been re building my server). I should have time to give your suggestions a try tomorrow. will keep you posted!

Captain-Wiggles commented 3 years ago

So I tested it on multiple playlists and it works on 99% of them. There is only one or two playlists that causes the program to stop and I think it is the issue that you pointed out (on spotify's end) where the song doesn't have a valid ID. (The song that I sent to test works fine now. Other Korean songs now work also). Is there a way to have the program jump the song with no ID and let the program continue listing for that and other playlists?

Thanks for all of this btw. Knowing that I have a record of the 50-some playlists I've created really give me some peace of mind!

`Converting tracks in 1djHlnZ2iNlg4hd6lFnAiZ: 30%|█████████████▍ | 25/84 [00:00<?, ?it/s] 0it [00:00, ?it/s]in 1djHlnZ2iNlg4hd6lFnAiZ: 0%| | 0/84 [00:00<?, ?it/s] ←[31m2021-10-23 20:27:14,723 - plugins - ERROR - 'NoneType' object is not subscriptable (plugins.py:291)←[0m Traceback (most recent call last): File "C:\Program Files\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 393, in playlist_tracks track_list.append(s.spotify_to_songs_dict(track)) File "C:\Program Files\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 419, in spotify_to_songs_dict artists = [artist["name"] for artist in track["artists"]] TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "C:\Program Files\ultrasonics\ultrasonics\plugins.py", line 273, in applet_run for item in plugin_run(*get_info(plugin), component="inputs", applet_id=applet_id): File "C:\Program Files\ultrasonics\ultrasonics\plugins.py", line 162, in plugin_run response = found_plugins[name].run( File "C:\Program Files\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 568, in run tracks = s.playlist_tracks(playlist["id"]["spotify"]) File "C:\Program Files\ultrasonics\ultrasonics\official_plugins\up_spotify.py", line 396, in playlist_tracks f"Could not convert track {track['id']} to ultrasonics format."`

XDGFX commented 3 years ago

I could allow it to skip tracks without an ID, but I'm hesitant to do so - I feel like there is no reason a song wouldn't have an ID so I'd be concerned that skipping it would potentially mask other issues, maybe if the Spotify API updates and breaks something, I would rather dramatic failure over a silent warning ;)

I'm hoping that the cases you've discovered are temporary - either a glitch with the Spotify API or for some reason they are actually missing an ID, but would be updated soon.