""" scrobbler https://gist.github.com/mvrpl/53f1e377315e6db26c47 """ import applescript # py-applescript import time import pylast from dotenv import dotenv_values from tqdm import tqdm config = dotenv_values(".env") lfm = pylast.LastFMNetwork( api_key=config["LFM_KEY"], api_secret=config["LFM_SECRET"], username=config["USERNAME"], password_hash=pylast.md5(config["PASSWORD"]), ) tell_iTunes = applescript.AppleScript(""" on is_running(appName) tell application "System Events" to (name of processes) contains appName end is_running on Playing() set iTunesRunning to is_running("Music") if iTunesRunning then tell application "Music" set songState to the player state tell current track set songId to the database ID set songTitle to the name set songArtist to the artist set songAlbum to the album set songAlbumArtist to the album artist set songDuration to the duration set result to songId & songState & songArtist & songTitle & songAlbum & songDuration & songAlbumArtist return result end tell end tell end if end Playing """) old_id = tracked_id = -1 runtime = 0 progress = tqdm(dynamic_ncols=True) progress.set_postfix(scrobbled=False) def print(*args): progress.write(" ".join(map(str, args))) while True: time.sleep(1) try: out = tell_iTunes.call("Playing") except applescript.ScriptError as e: if e._errorinfo["NSAppleScriptErrorMessage"] == "Music got an error: Can’t get database ID of current track.": progress.set_description("?") progress.set_postfix(scrobbled=False) progress.display() continue print(e) continue except Exception as e: print("ERR", type(e), repr(e)) continue if not out: continue id, state, artist, song, album, duration, album_artist = out if hasattr(duration, "code"): continue if old_id != id: progress.set_description(song) progress.set_postfix(scrobbled=False) runtime = 0 old_id = id runtime += 1 progress.n = runtime progress.total = round(duration) if tracked_id == id: progress.display() continue if state.code != b"kPSP": continue if duration < 30: print("not tracking", duration) old_id = tracked_id = id continue if (runtime >= duration / 2 or runtime > 4 * 60) and tracked_id != id: progress.set_postfix(scrobbled=True) tracked_id = id lfm.scrobble( artist=artist, title=song, timestamp=int(time.time() - runtime), album=album, album_artist=album_artist, duration=duration, ) progress.display()