Skip to content

Commit 523c5bd

Browse files
committed
added a spotify automation script
1 parent 9a572de commit 523c5bd

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

web_programming/spotiauto.py

+199
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
import subprocess
2+
import sys
3+
import logging
4+
from typing import Optional
5+
6+
logging.basicConfig(level=logging.INFO)
7+
8+
def get_mood() -> Optional[str]:
9+
"""
10+
Display a pop-up dialog to ask the user for their mood (happy, sad, etc.).
11+
Returns the mood as a string or None if the user cancels.
12+
"""
13+
script = '''
14+
set mood to choose from list {"Happy", "Sad", "Chill", "Energetic"} with prompt "How are you feeling today?"
15+
if mood is false then return "None" -- If the user cancels, return "None"
16+
return item 1 of mood
17+
'''
18+
try:
19+
mood = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, check=True).stdout.strip()
20+
return mood if mood != "None" else None
21+
except subprocess.CalledProcessError as e:
22+
logging.error(f"Error in getting mood: {e}")
23+
return None
24+
25+
def get_shuffle_preference() -> bool:
26+
"""
27+
Ask the user if they want to enable shuffle mode.
28+
Returns True if they choose "Yes", False otherwise.
29+
"""
30+
script = '''
31+
set shuffle_pref to choose from list {"Yes", "No"} with prompt "Do you want shuffle mode enabled?"
32+
if shuffle_pref is false then return "No" -- Default to "No" if user cancels
33+
return item 1 of shuffle_pref
34+
'''
35+
try:
36+
shuffle_response = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, check=True).stdout.strip()
37+
return shuffle_response == "Yes"
38+
except subprocess.CalledProcessError as e:
39+
logging.error(f"Error in getting shuffle preference: {e}")
40+
return False # Default to shuffle off in case of error
41+
42+
def check_spotify_running() -> bool:
43+
"""
44+
Check if the Spotify application is currently running.
45+
Returns True if Spotify is running, False otherwise.
46+
"""
47+
script = 'tell application "System Events" to (name of processes) contains "Spotify"'
48+
try:
49+
result = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, check=True).stdout.strip()
50+
return result == 'true'
51+
except subprocess.CalledProcessError as e:
52+
logging.error(f"Error checking Spotify running status: {e}")
53+
return False
54+
55+
def offer_to_open_spotify() -> bool:
56+
"""
57+
Ask the user if they want to open Spotify if it's not running.
58+
Returns True if the user wants to open Spotify, False otherwise.
59+
"""
60+
script = '''
61+
display dialog "Spotify is not running. Do you want to open it?" buttons {"Yes", "No"} default button "Yes"
62+
set user_choice to button returned of result
63+
return user_choice
64+
'''
65+
try:
66+
user_choice = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, check=True).stdout.strip()
67+
return user_choice == "Yes"
68+
except subprocess.CalledProcessError as e:
69+
logging.error(f"Error in getting user's choice to open Spotify: {e}")
70+
return False
71+
72+
def open_spotify() -> None:
73+
"""
74+
Open the Spotify application.
75+
"""
76+
try:
77+
subprocess.run(['open', '-a', 'Spotify'], check=True)
78+
logging.info("Spotify is now opening...")
79+
except subprocess.CalledProcessError as e:
80+
logging.error(f"Failed to open Spotify: {e}")
81+
sys.exit(1)
82+
83+
def control_spotify(command: str) -> None:
84+
"""
85+
Use AppleScript to control the Spotify desktop app on macOS.
86+
"""
87+
script = f'tell application "Spotify" to {command}'
88+
try:
89+
subprocess.run(['osascript', '-e', script], check=True)
90+
except subprocess.CalledProcessError as e:
91+
logging.error(f"Failed to send command to Spotify: {e}")
92+
sys.exit(1)
93+
94+
def set_spotify_volume(volume: int) -> None:
95+
"""
96+
Set the volume level for Spotify.
97+
"""
98+
control_spotify(f'set sound volume to {volume}')
99+
100+
def play_playlist(playlist_uri: str, shuffle: bool) -> None:
101+
"""
102+
Play a specific playlist on Spotify based on its URI, with the option to enable shuffle.
103+
"""
104+
control_spotify(f'set shuffling to {str(shuffle).lower()}') # Enable or disable shuffle
105+
control_spotify(f'play track "{playlist_uri}"') # Play the playlist
106+
107+
def get_volume_for_mood(mood: str) -> int:
108+
"""
109+
Get the volume level based on the user's mood.
110+
"""
111+
volume_levels = {
112+
"Happy": 70,
113+
"Sad": 60,
114+
"Chill": 50,
115+
"Energetic": 100
116+
}
117+
return volume_levels.get(mood, 50) # Default to 50 if mood is not found
118+
119+
def get_current_track() -> Optional[str]:
120+
"""
121+
Retrieve the currently playing track's name, artist, and album in Spotify.
122+
Returns a formatted string with the track information, or None if no track is playing.
123+
"""
124+
script = '''
125+
tell application "Spotify"
126+
if player state is playing then
127+
set track_name to name of current track
128+
set track_artist to artist of current track
129+
set track_album to album of current track
130+
return track_name & " by " & track_artist & " from the album " & track_album
131+
else
132+
return "No track is currently playing."
133+
end if
134+
end tell
135+
'''
136+
try:
137+
track_info = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, check=True).stdout.strip()
138+
return track_info if track_info else None
139+
except subprocess.CalledProcessError as e:
140+
logging.error(f"Error retrieving current track: {e}")
141+
return None
142+
143+
def validate_mood_and_play_playlist(mood: Optional[str], mood_playlists: dict) -> None:
144+
"""
145+
Validate the mood and play the corresponding playlist.
146+
Set shuffle mode and adjust the volume based on the user's preferences and mood.
147+
Display the currently playing track.
148+
"""
149+
if mood:
150+
playlist_uri = mood_playlists.get(mood)
151+
if playlist_uri:
152+
logging.info(f"Playing {mood} playlist...")
153+
154+
# Check if Spotify is running
155+
if not check_spotify_running():
156+
logging.warning("Spotify is not running.")
157+
if offer_to_open_spotify():
158+
open_spotify()
159+
else:
160+
logging.info("Spotify is not opened. Exiting.")
161+
sys.exit(0)
162+
163+
# Get the shuffle preference
164+
shuffle = get_shuffle_preference()
165+
166+
# Get the volume level based on the mood
167+
volume = get_volume_for_mood(mood)
168+
logging.info(f"Setting volume to {volume} for mood {mood}")
169+
set_spotify_volume(volume)
170+
171+
# Play the playlist with the appropriate shuffle setting
172+
play_playlist(playlist_uri, shuffle)
173+
174+
# Get and display the currently playing track
175+
track_info = get_current_track()
176+
if track_info:
177+
logging.info(f"Currently playing: {track_info}")
178+
else:
179+
logging.warning("No track is currently playing.")
180+
else:
181+
logging.warning(f"No playlist found for mood: {mood}")
182+
else:
183+
logging.info("No mood selected. Exiting.")
184+
sys.exit(0)
185+
186+
if __name__ == "__main__":
187+
# Define playlists for each mood
188+
mood_playlists = {
189+
"Happy": "spotify:playlist:37i9dQZF1DXdPec7aLTmlC", # Replace with your playlist URI
190+
"Sad": "spotify:playlist:37i9dQZF1DWVrtsSlLKzro", # Replace with your playlist URI
191+
"Chill": "spotify:playlist:37i9dQZF1DX4WYpdgoIcn6", # Replace with your playlist URI
192+
"Energetic": "spotify:playlist:37i9dQZF1DX76Wlfdnj7AP" # Replace with your playlist URI
193+
}
194+
195+
# Get the user's mood
196+
user_mood = get_mood()
197+
198+
# Validate mood and play the corresponding playlist
199+
validate_mood_and_play_playlist(user_mood, mood_playlists)

0 commit comments

Comments
 (0)