diff --git a/.cache b/.cache index 8c0fd19..5c88449 100644 --- a/.cache +++ b/.cache @@ -1 +1 @@ -{"access_token": "BQBH29kwm5mcADwR9i0rL8Wu_xiI9H2HRRLXUMWFMRf8jvRFXLvXXLitv2MzZAx3VcKyDlKz_zdWHHyWqJqPJ2S41_MaVngikw6EXwYFoi2vudlNqViSiLaUOvi8XRbNcrKqqQDLbuJDGh791iuB7JNAOSV166bDLwpOA_k_JAZme2HtxZ1aUyfPc24ldJc", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1676101304, "refresh_token": "AQCOARNKfmTOZ0eINGRwD7Yo5JWarv7bH5LnTvoz_mMEDhXR_luBWsl8wq010xTTbLO3c4XLeCqIKUwmPsJX5uQn4mUP-JWKgETATkkii6vlKTS7xR3DntNwfquOIjV-9CQ"} \ No newline at end of file +{"access_token": "BQDrxTAIyV04s8ELEHxjvK118srmPFqciwk8FVd15twhg-Vh3LOY1sBzU3M6_K6oRH7sODe4740H3SnBZ-aDDSombJOFVCi26WaEEtUM0v8mgTJQvabM1yacXLOUC3uGtWXzZ5twdBfllOJD0sqMRvllkbwvfOsi09QiUifN50vcpaL0uLWHBIZ7SbBoUN4", "token_type": "Bearer", "expires_in": 3600, "scope": "user-modify-playback-state user-read-playback-state", "expires_at": 1677924835, "refresh_token": "AQCOARNKfmTOZ0eINGRwD7Yo5JWarv7bH5LnTvoz_mMEDhXR_luBWsl8wq010xTTbLO3c4XLeCqIKUwmPsJX5uQn4mUP-JWKgETATkkii6vlKTS7xR3DntNwfquOIjV-9CQ"} \ No newline at end of file diff --git a/icons/next-black.png b/icons/next-black.png new file mode 100644 index 0000000..18e1915 Binary files /dev/null and b/icons/next-black.png differ diff --git a/icons/next.png b/icons/next.png new file mode 100644 index 0000000..51563a3 Binary files /dev/null and b/icons/next.png differ diff --git a/icons/pause-black.png b/icons/pause-black.png new file mode 100644 index 0000000..c705662 Binary files /dev/null and b/icons/pause-black.png differ diff --git a/icons/pause.png b/icons/pause.png new file mode 100644 index 0000000..a1dd5d6 Binary files /dev/null and b/icons/pause.png differ diff --git a/icons/play-black.png b/icons/play-black.png new file mode 100644 index 0000000..0daa8d9 Binary files /dev/null and b/icons/play-black.png differ diff --git a/icons/play-circle-x2.png b/icons/play-circle-x2.png index 07e58e0..0d796d0 100644 Binary files a/icons/play-circle-x2.png and b/icons/play-circle-x2.png differ diff --git a/icons/play.png b/icons/play.png new file mode 100644 index 0000000..2044bb4 Binary files /dev/null and b/icons/play.png differ diff --git a/icons/previous-black.png b/icons/previous-black.png new file mode 100644 index 0000000..d8ad4a0 Binary files /dev/null and b/icons/previous-black.png differ diff --git a/icons/previous.png b/icons/previous.png new file mode 100644 index 0000000..1c5ea0b Binary files /dev/null and b/icons/previous.png differ diff --git a/json.json b/json.json new file mode 100644 index 0000000..01635a2 --- /dev/null +++ b/json.json @@ -0,0 +1 @@ +{"device": {"id": "3e20a2964c1151e118255b819e12e57836e32c1b", "is_active": true, "is_private_session": false, "is_restricted": false, "name": "SILVERHAND", "type": "Computer", "volume_percent": 13}, "shuffle_state": false, "repeat_state": "context", "timestamp": 1677383950362, "context": {"external_urls": {"spotify": "https://open.spotify.com/artist/2CmaKO2zEGJ1NWpS1yfVGz"}, "href": "https://api.spotify.com/v1/artists/2CmaKO2zEGJ1NWpS1yfVGz", "type": "artist", "uri": "spotify:artist:2CmaKO2zEGJ1NWpS1yfVGz"}, "progress_ms": 110281, "item": {"album": {"album_type": "single", "artists": [{"external_urls": {"spotify": "https://open.spotify.com/artist/2CmaKO2zEGJ1NWpS1yfVGz"}, "href": "https://api.spotify.com/v1/artists/2CmaKO2zEGJ1NWpS1yfVGz", "id": "2CmaKO2zEGJ1NWpS1yfVGz", "name": "Falling In Reverse", "type": "artist", "uri": "spotify:artist:2CmaKO2zEGJ1NWpS1yfVGz"}], "available_markets": ["AD", "AE", "AG", "AL", "AM", "AO", "AR", "AT", "AU", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BN", "BO", "BR", "BS", "BT", "BW", "BY", "BZ", "CA", "CD", "CG", "CH", "CI", "CL", "CM", "CO", "CR", "CV", "CW", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "ES", "ET", "FI", "FJ", "FM", "FR", "GA", "GB", "GD", "GE", "GH", "GM", "GN", "GQ", "GR", "GT", "GW", "GY", "HK", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", "IQ", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KR", "KW", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MG", "MH", "MK", "ML", "MN", "MO", "MR", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NE", "NG", "NI", "NL", "NO", "NP", "NR", "NZ", "OM", "PA", "PE", "PG", "PH", "PK", "PL", "PS", "PT", "PW", "PY", "QA", "RO", "RS", "RW", "SA", "SB", "SC", "SE", "SG", "SI", "SK", "SL", "SM", "SN", "SR", "ST", "SV", "SZ", "TD", "TG", "TH", "TJ", "TL", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "US", "UY", "UZ", "VC", "VE", "VN", "VU", "WS", "XK", "ZA", "ZM", "ZW"], "external_urls": {"spotify": "https://open.spotify.com/album/4RAskRcPGU9RuCIZVRl5Gb"}, "href": "https://api.spotify.com/v1/albums/4RAskRcPGU9RuCIZVRl5Gb", "id": "4RAskRcPGU9RuCIZVRl5Gb", "images": [{"height": 640, "url": "https://i.scdn.co/image/ab67616d0000b273f9d64ac5b0e042252e3a561a", "width": 640}, {"height": 300, "url": "https://i.scdn.co/image/ab67616d00001e02f9d64ac5b0e042252e3a561a", "width": 300}, {"height": 64, "url": "https://i.scdn.co/image/ab67616d00004851f9d64ac5b0e042252e3a561a", "width": 64}], "name": "Drugs", "release_date": "2019-04-08", "release_date_precision": "day", "total_tracks": 3, "type": "album", "uri": "spotify:album:4RAskRcPGU9RuCIZVRl5Gb"}, "artists": [{"external_urls": {"spotify": "https://open.spotify.com/artist/2CmaKO2zEGJ1NWpS1yfVGz"}, "href": "https://api.spotify.com/v1/artists/2CmaKO2zEGJ1NWpS1yfVGz", "id": "2CmaKO2zEGJ1NWpS1yfVGz", "name": "Falling In Reverse", "type": "artist", "uri": "spotify:artist:2CmaKO2zEGJ1NWpS1yfVGz"}], "available_markets": ["AR", "AU", "AT", "BE", "BO", "BR", "BG", "CA", "CL", "CO", "CR", "CY", "CZ", "DK", "DO", "DE", "EC", "EE", "SV", "FI", "FR", "GR", "GT", "HN", "HK", "HU", "IS", "IE", "IT", "LV", "LT", "LU", "MY", "MT", "MX", "NL", "NZ", "NI", "NO", "PA", "PY", "PE", "PH", "PL", "PT", "SG", "SK", "ES", "SE", "CH", "TW", "TR", "UY", "US", "GB", "AD", "LI", "MC", "ID", "JP", "TH", "VN", "RO", "IL", "ZA", "SA", "AE", "BH", "QA", "OM", "KW", "EG", "MA", "DZ", "TN", "LB", "JO", "PS", "IN", "BY", "KZ", "MD", "UA", "AL", "BA", "HR", "ME", "MK", "RS", "SI", "KR", "BD", "PK", "LK", "GH", "KE", "NG", "TZ", "UG", "AG", "AM", "BS", "BB", "BZ", "BT", "BW", "BF", "CV", "CW", "DM", "FJ", "GM", "GE", "GD", "GW", "GY", "HT", "JM", "KI", "LS", "LR", "MW", "MV", "ML", "MH", "FM", "NA", "NR", "NE", "PW", "PG", "WS", "SM", "ST", "SN", "SC", "SL", "SB", "KN", "LC", "VC", "SR", "TL", "TO", "TT", "TV", "VU", "AZ", "BN", "BI", "KH", "CM", "TD", "KM", "GQ", "SZ", "GA", "GN", "KG", "LA", "MO", "MR", "MN", "NP", "RW", "TG", "UZ", "ZW", "BJ", "MG", "MU", "MZ", "AO", "CI", "DJ", "ZM", "CD", "CG", "IQ", "LY", "TJ", "VE", "ET", "XC", "XK"], "disc_number": 1, "duration_ms": 231920, "explicit": true, "external_ids": {"isrc": "USEP41915001"}, "external_urls": {"spotify": "https://open.spotify.com/track/5BkCDt5w0WOGgBgDC7T39i"}, "href": "https://api.spotify.com/v1/tracks/5BkCDt5w0WOGgBgDC7T39i", "id": "5BkCDt5w0WOGgBgDC7T39i", "is_local": false, "name": "Drugs", "popularity": 61, "preview_url": "https://p.scdn.co/mp3-preview/7f962f70f7d2dba2e83e4f2e0847a517afa7be5e?cid=69b82a34d0fb40be80b020eae8e80f25", "track_number": 1, "type": "track", "uri": "spotify:track:5BkCDt5w0WOGgBgDC7T39i"}, "currently_playing_type": "track", "actions": {"disallows": {"resuming": true}}, "is_playing": true} \ No newline at end of file diff --git a/spotifycontroller.py b/spotifycontroller.py index 7475e8d..c87afc8 100644 --- a/spotifycontroller.py +++ b/spotifycontroller.py @@ -16,11 +16,12 @@ import queue # SpotifyGUI - Made by Brandon Brunson # import speech_recognition as sr - -if os.path.isfile("updated.cfg"): - print("A new update was downloaded and installed. Starting in 5 seconds...") - os.remove("updated.cfg") - sleep(5) +if os.name == 'posix': + os.system("xset -display :0 s 21600") + if os.path.isfile("updated.cfg"): + print("A new update was downloaded and installed. Starting in 5 seconds...") + os.remove("updated.cfg") + sleep(5) q = queue.Queue() @@ -65,12 +66,11 @@ spotify = spotipy.Spotify(auth_manager=oauth) # print(SpotifyOAuth.refresh_access_token(refresh_token=access_token)) bg_color = "#000000" -count = 0 -wait_time = 6500 +# count = 0 +# wait_time = 6500 # hotword = "magical" -if os.name == 'posix': - os.system("xset -display :0 s 21600") + # Create the tkinter window root = ttk.Tk() @@ -94,9 +94,15 @@ def controlNext(): def controlPrevious(): spotify.previous_track() +def likeSong(): + print(spotify.current_playback()["item"]["id"]) + spotify.current_user_saved_tracks_add(tracks=(spotify.current_playback()["item"]["id"])) def start_playback_on_device(): - wakeup() + # global count + # global wait_time + # count = 0 + # wait_time = 6500 device_selections = devices_list.curselection() list_of_devices = spotify.devices() list_of_devices = spotify.devices() @@ -104,17 +110,13 @@ def start_playback_on_device(): spotify.transfer_playback(device_id=device_id) def get_devices(): - global count - global wait_time - count +=1 - if count < 69: - wait_time = 6500 - elif count >= 69: - wait_time = 300000 - elif count >= 138: - wait_time = 600000 - elif count >= 277: - wait_time = 3600000 + # global count + # global wait_time + # count +=1 + # if count < 69: + # wait_time = 6500 + # elif count >= 69: + # wait_time = 3600000 list_of_devices = spotify.devices() unloadNow_playing() if list_of_devices == "{'devices': []}": @@ -122,12 +124,11 @@ def get_devices(): loadSearching_Devices() root.after(1000, get_devices) else: - current_playback = spotify.current_playback() - if current_playback != None: + if spotify.current_playback() != None: unloadSearching_Devices() unloadDevices_list() loadNow_playing() - update_song_label() + return else: unloadSearching_Devices() loadDevices_list() @@ -135,13 +136,13 @@ def get_devices(): list_of_devices = spotify.devices() for num_of_device, garbage in enumerate(list_of_devices["devices"]): devices_list.insert(num_of_device, list_of_devices["devices"][num_of_device]["name"]) - root.after(wait_time, get_devices) + root.after(6500, get_devices) -def wakeup(): - global count - global wait_time - count = 0 - wait_time = 6500 +# def wakeup(): +# global count +# global wait_time +# count = 0 +# wait_time = 6500 def addCorners(im, rad): circle = Image.new('L', (rad * 2, rad * 2), 0) @@ -224,14 +225,14 @@ def getLyrics(artist_name, track_name): # def rgb_to_hex(r, g, b): # return ('{:X}{:X}{:X}').format(r, g, b) -play_img = ttk.PhotoImage(file="icons/play-circle-x2.png") -pause_img = ttk.PhotoImage(file="icons/pause-circle-x2.png") -next_img = ttk.PhotoImage(file="icons/skip-next-x2.png") -previous_img = ttk.PhotoImage(file="icons/skip-previous-x2.png") -play_img_black = ttk.PhotoImage(file="icons/play-circle-x2-black.png") -pause_img_black = ttk.PhotoImage(file="icons/pause-circle-x2-black.png") -next_img_black = ttk.PhotoImage(file="icons/skip-next-x2-black.png") -previous_img_black = ttk.PhotoImage(file="icons/skip-previous-x2-black.png") +play_img = ttk.PhotoImage(file="icons/play.png") +pause_img = ttk.PhotoImage(file="icons/pause.png") +next_img = ttk.PhotoImage(file="icons/next.png") +previous_img = ttk.PhotoImage(file="icons/previous.png") +play_img_black = ttk.PhotoImage(file="icons/play-black.png") +pause_img_black = ttk.PhotoImage(file="icons/pause-black.png") +next_img_black = ttk.PhotoImage(file="icons/next-black.png") +previous_img_black = ttk.PhotoImage(file="icons/previous-black.png") album_art_img = "" @@ -267,13 +268,16 @@ device_name_label = tk.Label(frame_artist_song, text="", font=("Helvetica", 12)) lyrics_label = tk.Label(lyrics_label_frame, text="", font=("Helvetica", 32), wraplength=(1280/3), justify=ttk.CENTER, background=bg_color) album_art_label = tk.Label(album_art_frame, image=album_art_img) +play_button.configure() + play_button.bind("", lambda e:controlPlay()) pause_button.bind("", lambda e:controlPause()) next_button.bind("", lambda e:controlNext()) previous_button.bind("", lambda e:controlPrevious()) -devices_list.bind("", lambda e:wakeup()) - +album_art_label.bind("", lambda e:likeSong()) +# devices_list.bind("", lambda e:wakeup()) +import json # Function to update the song label with the current track's name def update_song_label(): global lrc @@ -283,17 +287,25 @@ def update_song_label(): # If there is no current playback, set the text of the song label to "No playback" if current_playback is None: get_devices() + root.after(100, update_song_label) # Update the song label every 1 second else: - track_name = current_playback["item"]["name"] - artist_name = current_playback["item"]["artists"][0]["name"] - track_duration = current_playback["item"]["duration_ms"] - track_progress = current_playback["progress_ms"] - playing_status = current_playback["is_playing"] - device_name = current_playback["device"]["name"] - album_art_url = current_playback["item"]["album"]["images"][0]["url"] - track_progress_min = track_progress//(1000*60)%60 - track_progress_sec = (track_progress//1000)%60 + if current_playback.get("item"): + track_name = current_playback["item"]["name"] + artist_name = current_playback["item"]["artists"][0]["name"] + track_duration = current_playback["item"]["duration_ms"] + track_progress = current_playback["progress_ms"] + playing_status = current_playback["is_playing"] + device_name = current_playback["device"]["name"] + album_art_url = current_playback["item"]["album"]["images"][0]["url"] + track_progress_min = track_progress//(1000*60)%60 + track_progress_sec = (track_progress//1000)%60 + else: + track_name = "Loading..." + artist_name = "Loading..." + track_duration = 1 + track_progress = 1 + if track_name == song_label.cget("text"): track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec)) progress_bar.config(maximum=track_duration) @@ -361,6 +373,7 @@ def update_song_label(): elif playing_status == False: pause_button.grid_forget() play_button.grid(row=3, column=1, pady=(100,0)) + else: pass diff --git a/todo.txt b/todo.txt index edcf680..33ab659 100644 --- a/todo.txt +++ b/todo.txt @@ -32,4 +32,38 @@ add canvas videos to background if available. USE: https://github.com/Delitefull need to find out what the protobud error parsing message with type' error is about, probably use a try and except as e statement then print e to figure out the full error SpotifyOAuthError -SpotifyException \ No newline at end of file +SpotifyException + +02/23/2023: +Make try statement for update_song_label to get around this + +Traceback (most recent call last): + File "C:\Users\spong\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__ + return self.func(*args) + File "C:\Users\spong\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 839, in callit + func(*args) + File "c:\Users\spong\Documents\Python Programs\Spotify\spotifycontroller.py", line 287, in update_song_label + track_name = current_playback["item"]["name"] +TypeError: 'NoneType' object is not subscriptable + + +02/23/2023: +add ability to like songs, by icon somewhere or maybe by double tapping or holding on track title... animation?? when adding to liked + +is calling the functions directly causing the issues? ex. get_devices() should be root.after(0, get_devices) or root(get_devices) ??????? +Exception in Tkinter callback +Traceback (most recent call last): + File "/usr/lib/python3.9/tkinter/__init__.py", line 1892, in __call__ + return self.func(*args) + File "/usr/lib/python3.9/tkinter/__init__.py", line 814, in callit + func(*args) + File "", line 287, in update_song_label +TypeError: 'NoneType' object is not subscriptable + +03/04/2023: +switch to spotify web api for track information to avoid api limit??? + +03/04/2023: +new updater, use version numbering to pull updates if server has a newer version and dont update if newer version isnt available. +create a single json file that has a version list with download links to each version. have updater.py download the json file, read and compare to currently downloaded version. +if newer version is in json file, follow link in json file to download, otherwise continue to start the program. \ No newline at end of file