70 lines
1.9 KiB
Python
70 lines
1.9 KiB
Python
"""
|
|
Last.fm integration using pylast.
|
|
"""
|
|
|
|
import pylast
|
|
from django.conf import settings
|
|
|
|
|
|
def get_network() -> pylast.LastFMNetwork:
|
|
"""Return a base LastFMNetwork (no session key attached)."""
|
|
return pylast.LastFMNetwork(
|
|
api_key=settings.LASTFM_API_KEY,
|
|
api_secret=settings.LASTFM_API_SECRET,
|
|
)
|
|
|
|
|
|
def get_auth_url(callback_url: str) -> tuple[str, str]:
|
|
"""
|
|
Start the Last.fm web auth flow.
|
|
|
|
Returns (auth_url, token). The caller should redirect the user to auth_url
|
|
and store the token in the session for use in the callback.
|
|
"""
|
|
network = get_network()
|
|
sg = pylast.SessionKeyGenerator(network)
|
|
token = sg.get_web_auth_token()
|
|
url = sg.get_web_auth_url(token)
|
|
return url, token
|
|
|
|
|
|
def get_session_key(token: str) -> str:
|
|
"""
|
|
Exchange an authorized token for a permanent session key.
|
|
|
|
Must be called after the user has visited the auth URL and clicked Allow.
|
|
"""
|
|
network = get_network()
|
|
sg = pylast.SessionKeyGenerator(network)
|
|
return sg.get_web_auth_session_key(token)
|
|
|
|
|
|
def get_username(session_key: str) -> str:
|
|
"""Return the Last.fm username for the given session key."""
|
|
network = get_network()
|
|
network.session_key = session_key
|
|
user = network.get_authenticated_user()
|
|
return user.name
|
|
|
|
|
|
def scrobble(session_key: str, artist: str, title: str, timestamp: int) -> None:
|
|
"""
|
|
Scrobble a track to Last.fm.
|
|
|
|
timestamp should be a Unix epoch integer (seconds since 1970-01-01 UTC).
|
|
"""
|
|
network = get_network()
|
|
network.session_key = session_key
|
|
network.scrobble(artist=artist, title=title, timestamp=timestamp)
|
|
|
|
|
|
def parse_track(raw: str) -> tuple[str, str]:
|
|
"""
|
|
Parse a raw 'Artist - Title' string into (artist, title).
|
|
|
|
Falls back to ('', raw) when no ' - ' separator is found.
|
|
"""
|
|
if ' - ' in raw:
|
|
parts = raw.split(' - ', 1)
|
|
return parts[0].strip(), parts[1].strip()
|
|
return '', raw.strip()
|