mem leak fix
new icons! higher qual miscelanous code cleanup
2
.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"}
|
{"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"}
|
||||||
BIN
icons/next-black.png
Normal file
|
After Width: | Height: | Size: 514 B |
BIN
icons/next.png
Normal file
|
After Width: | Height: | Size: 619 B |
BIN
icons/pause-black.png
Normal file
|
After Width: | Height: | Size: 826 B |
BIN
icons/pause.png
Normal file
|
After Width: | Height: | Size: 1019 B |
BIN
icons/play-black.png
Normal file
|
After Width: | Height: | Size: 892 B |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
icons/play.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/previous-black.png
Normal file
|
After Width: | Height: | Size: 565 B |
BIN
icons/previous.png
Normal file
|
After Width: | Height: | Size: 661 B |
1
json.json
Normal file
@@ -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}
|
||||||
@@ -16,8 +16,9 @@ import queue
|
|||||||
# SpotifyGUI - Made by Brandon Brunson
|
# SpotifyGUI - Made by Brandon Brunson
|
||||||
|
|
||||||
# import speech_recognition as sr
|
# import speech_recognition as sr
|
||||||
|
if os.name == 'posix':
|
||||||
if os.path.isfile("updated.cfg"):
|
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...")
|
print("A new update was downloaded and installed. Starting in 5 seconds...")
|
||||||
os.remove("updated.cfg")
|
os.remove("updated.cfg")
|
||||||
sleep(5)
|
sleep(5)
|
||||||
@@ -65,12 +66,11 @@ spotify = spotipy.Spotify(auth_manager=oauth)
|
|||||||
# print(SpotifyOAuth.refresh_access_token(refresh_token=access_token))
|
# print(SpotifyOAuth.refresh_access_token(refresh_token=access_token))
|
||||||
|
|
||||||
bg_color = "#000000"
|
bg_color = "#000000"
|
||||||
count = 0
|
# count = 0
|
||||||
wait_time = 6500
|
# wait_time = 6500
|
||||||
# hotword = "magical"
|
# hotword = "magical"
|
||||||
|
|
||||||
if os.name == 'posix':
|
|
||||||
os.system("xset -display :0 s 21600")
|
|
||||||
|
|
||||||
# Create the tkinter window
|
# Create the tkinter window
|
||||||
root = ttk.Tk()
|
root = ttk.Tk()
|
||||||
@@ -94,9 +94,15 @@ def controlNext():
|
|||||||
def controlPrevious():
|
def controlPrevious():
|
||||||
spotify.previous_track()
|
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():
|
def start_playback_on_device():
|
||||||
wakeup()
|
# global count
|
||||||
|
# global wait_time
|
||||||
|
# count = 0
|
||||||
|
# wait_time = 6500
|
||||||
device_selections = devices_list.curselection()
|
device_selections = devices_list.curselection()
|
||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
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)
|
spotify.transfer_playback(device_id=device_id)
|
||||||
|
|
||||||
def get_devices():
|
def get_devices():
|
||||||
global count
|
# global count
|
||||||
global wait_time
|
# global wait_time
|
||||||
count +=1
|
# count +=1
|
||||||
if count < 69:
|
# if count < 69:
|
||||||
wait_time = 6500
|
# wait_time = 6500
|
||||||
elif count >= 69:
|
# elif count >= 69:
|
||||||
wait_time = 300000
|
# wait_time = 3600000
|
||||||
elif count >= 138:
|
|
||||||
wait_time = 600000
|
|
||||||
elif count >= 277:
|
|
||||||
wait_time = 3600000
|
|
||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
unloadNow_playing()
|
unloadNow_playing()
|
||||||
if list_of_devices == "{'devices': []}":
|
if list_of_devices == "{'devices': []}":
|
||||||
@@ -122,12 +124,11 @@ def get_devices():
|
|||||||
loadSearching_Devices()
|
loadSearching_Devices()
|
||||||
root.after(1000, get_devices)
|
root.after(1000, get_devices)
|
||||||
else:
|
else:
|
||||||
current_playback = spotify.current_playback()
|
if spotify.current_playback() != None:
|
||||||
if current_playback != None:
|
|
||||||
unloadSearching_Devices()
|
unloadSearching_Devices()
|
||||||
unloadDevices_list()
|
unloadDevices_list()
|
||||||
loadNow_playing()
|
loadNow_playing()
|
||||||
update_song_label()
|
return
|
||||||
else:
|
else:
|
||||||
unloadSearching_Devices()
|
unloadSearching_Devices()
|
||||||
loadDevices_list()
|
loadDevices_list()
|
||||||
@@ -135,13 +136,13 @@ def get_devices():
|
|||||||
list_of_devices = spotify.devices()
|
list_of_devices = spotify.devices()
|
||||||
for num_of_device, garbage in enumerate(list_of_devices["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"])
|
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():
|
# def wakeup():
|
||||||
global count
|
# global count
|
||||||
global wait_time
|
# global wait_time
|
||||||
count = 0
|
# count = 0
|
||||||
wait_time = 6500
|
# wait_time = 6500
|
||||||
|
|
||||||
def addCorners(im, rad):
|
def addCorners(im, rad):
|
||||||
circle = Image.new('L', (rad * 2, rad * 2), 0)
|
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):
|
# def rgb_to_hex(r, g, b):
|
||||||
# return ('{:X}{:X}{:X}').format(r, g, b)
|
# return ('{:X}{:X}{:X}').format(r, g, b)
|
||||||
|
|
||||||
play_img = ttk.PhotoImage(file="icons/play-circle-x2.png")
|
play_img = ttk.PhotoImage(file="icons/play.png")
|
||||||
pause_img = ttk.PhotoImage(file="icons/pause-circle-x2.png")
|
pause_img = ttk.PhotoImage(file="icons/pause.png")
|
||||||
next_img = ttk.PhotoImage(file="icons/skip-next-x2.png")
|
next_img = ttk.PhotoImage(file="icons/next.png")
|
||||||
previous_img = ttk.PhotoImage(file="icons/skip-previous-x2.png")
|
previous_img = ttk.PhotoImage(file="icons/previous.png")
|
||||||
play_img_black = ttk.PhotoImage(file="icons/play-circle-x2-black.png")
|
play_img_black = ttk.PhotoImage(file="icons/play-black.png")
|
||||||
pause_img_black = ttk.PhotoImage(file="icons/pause-circle-x2-black.png")
|
pause_img_black = ttk.PhotoImage(file="icons/pause-black.png")
|
||||||
next_img_black = ttk.PhotoImage(file="icons/skip-next-x2-black.png")
|
next_img_black = ttk.PhotoImage(file="icons/next-black.png")
|
||||||
previous_img_black = ttk.PhotoImage(file="icons/skip-previous-x2-black.png")
|
previous_img_black = ttk.PhotoImage(file="icons/previous-black.png")
|
||||||
album_art_img = ""
|
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)
|
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)
|
album_art_label = tk.Label(album_art_frame, image=album_art_img)
|
||||||
|
|
||||||
|
play_button.configure()
|
||||||
|
|
||||||
|
|
||||||
play_button.bind("<Button-1>", lambda e:controlPlay())
|
play_button.bind("<Button-1>", lambda e:controlPlay())
|
||||||
pause_button.bind("<Button-1>", lambda e:controlPause())
|
pause_button.bind("<Button-1>", lambda e:controlPause())
|
||||||
next_button.bind("<Button-1>", lambda e:controlNext())
|
next_button.bind("<Button-1>", lambda e:controlNext())
|
||||||
previous_button.bind("<Button-1>", lambda e:controlPrevious())
|
previous_button.bind("<Button-1>", lambda e:controlPrevious())
|
||||||
devices_list.bind("<Button-1>", lambda e:wakeup())
|
album_art_label.bind("<Double-Button-1>", lambda e:likeSong())
|
||||||
|
# devices_list.bind("<Button-1>", lambda e:wakeup())
|
||||||
|
import json
|
||||||
# Function to update the song label with the current track's name
|
# Function to update the song label with the current track's name
|
||||||
def update_song_label():
|
def update_song_label():
|
||||||
global lrc
|
global lrc
|
||||||
@@ -283,8 +287,10 @@ def update_song_label():
|
|||||||
# If there is no current playback, set the text of the song label to "No playback"
|
# If there is no current playback, set the text of the song label to "No playback"
|
||||||
if current_playback is None:
|
if current_playback is None:
|
||||||
get_devices()
|
get_devices()
|
||||||
|
root.after(100, update_song_label)
|
||||||
# Update the song label every 1 second
|
# Update the song label every 1 second
|
||||||
else:
|
else:
|
||||||
|
if current_playback.get("item"):
|
||||||
track_name = current_playback["item"]["name"]
|
track_name = current_playback["item"]["name"]
|
||||||
artist_name = current_playback["item"]["artists"][0]["name"]
|
artist_name = current_playback["item"]["artists"][0]["name"]
|
||||||
track_duration = current_playback["item"]["duration_ms"]
|
track_duration = current_playback["item"]["duration_ms"]
|
||||||
@@ -294,6 +300,12 @@ def update_song_label():
|
|||||||
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
album_art_url = current_playback["item"]["album"]["images"][0]["url"]
|
||||||
track_progress_min = track_progress//(1000*60)%60
|
track_progress_min = track_progress//(1000*60)%60
|
||||||
track_progress_sec = (track_progress//1000)%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"):
|
if track_name == song_label.cget("text"):
|
||||||
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
track_progress_formatted = ("{}:{:02d}".format(track_progress_min, track_progress_sec))
|
||||||
progress_bar.config(maximum=track_duration)
|
progress_bar.config(maximum=track_duration)
|
||||||
@@ -361,6 +373,7 @@ def update_song_label():
|
|||||||
elif playing_status == False:
|
elif playing_status == False:
|
||||||
pause_button.grid_forget()
|
pause_button.grid_forget()
|
||||||
play_button.grid(row=3, column=1, pady=(100,0))
|
play_button.grid(row=3, column=1, pady=(100,0))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
34
todo.txt
@@ -33,3 +33,37 @@ need to find out what the protobud error parsing message with type' error is abo
|
|||||||
|
|
||||||
SpotifyOAuthError
|
SpotifyOAuthError
|
||||||
SpotifyException
|
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 "<string>", 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.
|
||||||