fixed sqlite caching
This commit is contained in:
parent
6acb1bfd38
commit
8d8063afe8
3
INSTALL
3
INSTALL
|
@ -1,5 +1,4 @@
|
||||||
Installation Instructions
|
Installation Instructions
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
1. cd into this directory
|
Execute "python setup.py install" as a super user.
|
||||||
2. Execute "python setup.py install". you'll probably need to add sudo to the beginning.
|
|
||||||
|
|
80
pylast.py
80
pylast.py
|
@ -45,6 +45,7 @@ __last_call_time = 0
|
||||||
import hashlib
|
import hashlib
|
||||||
import httplib
|
import httplib
|
||||||
import urllib
|
import urllib
|
||||||
|
import codecs
|
||||||
import threading
|
import threading
|
||||||
from xml.dom import minidom
|
from xml.dom import minidom
|
||||||
import os
|
import os
|
||||||
|
@ -137,15 +138,15 @@ class _SqliteCacheBackend(object):
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
|
|
||||||
def get_xml(self, key):
|
def get_xml(self, key):
|
||||||
row = self.connection.execute("SELECT xml FROM cache WHERE key='%s'" %key).fetchone()
|
row = self.connection.execute("SELECT xml FROM cache WHERE key=?", (key,)).fetchone()
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
def set_xml(self, key, xml_string):
|
def set_xml(self, key, xml_string):
|
||||||
self.connection.execute("INSERT INTO cache VALUES('%s', '%s')" %(key, xml_string))
|
self.connection.execute("INSERT INTO cache VALUES(?, ?)", (key, xml_string))
|
||||||
self.connection.commit()
|
self.connection.commit()
|
||||||
|
|
||||||
def has_key(self, key):
|
def has_key(self, key):
|
||||||
row = self.connection.execute("SELECT COUNT(*) FROM cache WHERE key='%s'" %key).fetchone()
|
row = self.connection.execute("SELECT COUNT(*) FROM cache WHERE key=?", (key,)).fetchone()
|
||||||
return row[0] > 0
|
return row[0] > 0
|
||||||
|
|
||||||
class _ThreadedCall(threading.Thread):
|
class _ThreadedCall(threading.Thread):
|
||||||
|
@ -275,9 +276,10 @@ class _Request(object):
|
||||||
conn = httplib.HTTPConnection(host=self.HOST_NAME)
|
conn = httplib.HTTPConnection(host=self.HOST_NAME)
|
||||||
conn.request(method='POST', url=self.HOST_SUBDIR, body=data, headers=headers)
|
conn.request(method='POST', url=self.HOST_SUBDIR, body=data, headers=headers)
|
||||||
|
|
||||||
response = conn.getresponse().read()
|
response = conn.getresponse()
|
||||||
self._check_response_for_errors(response)
|
response_text = unicode(response.read(), "utf-8")
|
||||||
return response
|
self._check_response_for_errors(response_text)
|
||||||
|
return response_text
|
||||||
|
|
||||||
def execute(self, cacheable = False):
|
def execute(self, cacheable = False):
|
||||||
"""Returns the XML DOM response of the POST Request from the server"""
|
"""Returns the XML DOM response of the POST Request from the server"""
|
||||||
|
@ -287,12 +289,12 @@ class _Request(object):
|
||||||
else:
|
else:
|
||||||
response = self._download_response()
|
response = self._download_response()
|
||||||
|
|
||||||
return minidom.parseString(response)
|
return minidom.parseString(response.encode("utf-8"))
|
||||||
|
|
||||||
def _check_response_for_errors(self, response):
|
def _check_response_for_errors(self, response):
|
||||||
"""Checks the response for errors and raises one if any exists."""
|
"""Checks the response for errors and raises one if any exists."""
|
||||||
|
|
||||||
doc = minidom.parseString(response)
|
doc = minidom.parseString(response.encode("utf-8"))
|
||||||
e = doc.getElementsByTagName('lfm')[0]
|
e = doc.getElementsByTagName('lfm')[0]
|
||||||
|
|
||||||
if e.getAttribute('status') != "ok":
|
if e.getAttribute('status') != "ok":
|
||||||
|
@ -384,7 +386,7 @@ class SessionKeyGenerator(object):
|
||||||
class _BaseObject(object):
|
class _BaseObject(object):
|
||||||
"""An abstract webservices object."""
|
"""An abstract webservices object."""
|
||||||
|
|
||||||
def __init__(self, api_key, api_secret, session_key):
|
def __init__(self, api_key, api_secret, session_key=""):
|
||||||
|
|
||||||
self.api_key = api_key
|
self.api_key = api_key
|
||||||
self.api_secret = api_secret
|
self.api_secret = api_secret
|
||||||
|
@ -639,7 +641,7 @@ class PlayedTrack (object):
|
||||||
class Album(_BaseObject, _Taggable):
|
class Album(_BaseObject, _Taggable):
|
||||||
"""A Last.fm album."""
|
"""A Last.fm album."""
|
||||||
|
|
||||||
def __init__(self, artist, title, api_key, api_secret, session_key):
|
def __init__(self, artist, title, api_key, api_secret, session_key=""):
|
||||||
"""
|
"""
|
||||||
Create an album instance.
|
Create an album instance.
|
||||||
# Parameters:
|
# Parameters:
|
||||||
|
@ -763,7 +765,7 @@ class Album(_BaseObject, _Taggable):
|
||||||
class Artist(_BaseObject, _Taggable):
|
class Artist(_BaseObject, _Taggable):
|
||||||
"""A Last.fm artist."""
|
"""A Last.fm artist."""
|
||||||
|
|
||||||
def __init__(self, name, api_key, api_secret, session_key):
|
def __init__(self, name, api_key, api_secret, session_key=""):
|
||||||
"""Create an artist object.
|
"""Create an artist object.
|
||||||
# Parameters:
|
# Parameters:
|
||||||
* name str: The artist's name.
|
* name str: The artist's name.
|
||||||
|
@ -981,7 +983,7 @@ class Artist(_BaseObject, _Taggable):
|
||||||
class Event(_BaseObject):
|
class Event(_BaseObject):
|
||||||
"""A Last.fm event."""
|
"""A Last.fm event."""
|
||||||
|
|
||||||
def __init__(self, event_id, api_key, api_secret, session_key):
|
def __init__(self, event_id, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.id = unicode(event_id)
|
self.id = unicode(event_id)
|
||||||
|
@ -1143,7 +1145,7 @@ class Event(_BaseObject):
|
||||||
class Country(_BaseObject):
|
class Country(_BaseObject):
|
||||||
"""A country at Last.fm."""
|
"""A country at Last.fm."""
|
||||||
|
|
||||||
def __init__(self, name, api_key, api_secret, session_key):
|
def __init__(self, name, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -1228,7 +1230,7 @@ class Country(_BaseObject):
|
||||||
class Library(_BaseObject):
|
class Library(_BaseObject):
|
||||||
"""A user's Last.fm library."""
|
"""A user's Last.fm library."""
|
||||||
|
|
||||||
def __init__(self, user, api_key, api_secret, session_key):
|
def __init__(self, user, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
if isinstance(user, User):
|
if isinstance(user, User):
|
||||||
|
@ -1418,7 +1420,7 @@ class Library(_BaseObject):
|
||||||
class Playlist(_BaseObject):
|
class Playlist(_BaseObject):
|
||||||
"""A Last.fm user playlist."""
|
"""A Last.fm user playlist."""
|
||||||
|
|
||||||
def __init__(self, user, id, api_key, api_secret, session_key):
|
def __init__(self, user, id, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
if isinstance(user, User):
|
if isinstance(user, User):
|
||||||
|
@ -1550,7 +1552,7 @@ class Tag(_BaseObject):
|
||||||
|
|
||||||
# TODO: getWeeklyArtistChart (too lazy, i'll wait for when someone requests it)
|
# TODO: getWeeklyArtistChart (too lazy, i'll wait for when someone requests it)
|
||||||
|
|
||||||
def __init__(self, name, api_key, api_secret, session_key):
|
def __init__(self, name, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.name = name
|
self.name = name
|
||||||
|
@ -1685,7 +1687,7 @@ class Tag(_BaseObject):
|
||||||
class Track(_BaseObject, _Taggable):
|
class Track(_BaseObject, _Taggable):
|
||||||
"""A Last.fm track."""
|
"""A Last.fm track."""
|
||||||
|
|
||||||
def __init__(self, artist, title, api_key, api_secret, session_key):
|
def __init__(self, artist, title, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
_Taggable.__init__(self, 'track')
|
_Taggable.__init__(self, 'track')
|
||||||
|
|
||||||
|
@ -1914,7 +1916,7 @@ class Track(_BaseObject, _Taggable):
|
||||||
class Group(_BaseObject):
|
class Group(_BaseObject):
|
||||||
"""A Last.fm group."""
|
"""A Last.fm group."""
|
||||||
|
|
||||||
def __init__(self, group_name, api_key, api_secret, session_key):
|
def __init__(self, group_name, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.name = group_name
|
self.name = group_name
|
||||||
|
@ -2026,7 +2028,7 @@ class Group(_BaseObject):
|
||||||
class XSPF(_BaseObject):
|
class XSPF(_BaseObject):
|
||||||
"A Last.fm XSPF playlist."""
|
"A Last.fm XSPF playlist."""
|
||||||
|
|
||||||
def __init__(self, uri, api_key, api_secret, session_key):
|
def __init__(self, uri, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.uri = uri
|
self.uri = uri
|
||||||
|
@ -2065,7 +2067,7 @@ class XSPF(_BaseObject):
|
||||||
class User(_BaseObject):
|
class User(_BaseObject):
|
||||||
"""A Last.fm user."""
|
"""A Last.fm user."""
|
||||||
|
|
||||||
def __init__(self, user_name, api_key, api_secret, session_key):
|
def __init__(self, user_name, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.name = user_name
|
self.name = user_name
|
||||||
|
@ -2476,7 +2478,7 @@ class User(_BaseObject):
|
||||||
return Library(self, *self.auth_data)
|
return Library(self, *self.auth_data)
|
||||||
|
|
||||||
class AuthenticatedUser(User):
|
class AuthenticatedUser(User):
|
||||||
def __init__(self, api_key, api_secret, session_key):
|
def __init__(self, api_key, api_secret, session_key=""):
|
||||||
User.__init__(self, "", api_key, api_secret, session_key);
|
User.__init__(self, "", api_key, api_secret, session_key);
|
||||||
|
|
||||||
def _get_params(self):
|
def _get_params(self):
|
||||||
|
@ -2630,7 +2632,7 @@ class AuthenticatedUser(User):
|
||||||
class _Search(_BaseObject):
|
class _Search(_BaseObject):
|
||||||
"""An abstract class. Use one of its derivatives."""
|
"""An abstract class. Use one of its derivatives."""
|
||||||
|
|
||||||
def __init__(self, ws_prefix, search_terms, api_key, api_secret, session_key):
|
def __init__(self, ws_prefix, search_terms, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self._ws_prefix = ws_prefix
|
self._ws_prefix = ws_prefix
|
||||||
|
@ -2669,7 +2671,7 @@ class _Search(_BaseObject):
|
||||||
class AlbumSearch(_Search):
|
class AlbumSearch(_Search):
|
||||||
"""Search for an album by name."""
|
"""Search for an album by name."""
|
||||||
|
|
||||||
def __init__(self, album_name, api_key, api_secret, session_key):
|
def __init__(self, album_name, api_key, api_secret, session_key=""):
|
||||||
|
|
||||||
_Search.__init__(self, "album", {"album": album_name}, api_key, api_secret, session_key)
|
_Search.__init__(self, "album", {"album": album_name}, api_key, api_secret, session_key)
|
||||||
|
|
||||||
|
@ -2687,7 +2689,7 @@ class AlbumSearch(_Search):
|
||||||
class ArtistSearch(_Search):
|
class ArtistSearch(_Search):
|
||||||
"""Search for an artist by artist name."""
|
"""Search for an artist by artist name."""
|
||||||
|
|
||||||
def __init__(self, artist_name, api_key, api_secret, session_key):
|
def __init__(self, artist_name, api_key, api_secret, session_key=""):
|
||||||
_Search.__init__(self, "artist", {"artist": artist_name}, api_key, api_secret, session_key)
|
_Search.__init__(self, "artist", {"artist": artist_name}, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def get_next_page(self):
|
def get_next_page(self):
|
||||||
|
@ -2704,7 +2706,7 @@ class ArtistSearch(_Search):
|
||||||
class TagSearch(_Search):
|
class TagSearch(_Search):
|
||||||
"""Search for a tag by tag name."""
|
"""Search for a tag by tag name."""
|
||||||
|
|
||||||
def __init__(self, tag_name, api_key, api_secret, session_key):
|
def __init__(self, tag_name, api_key, api_secret, session_key=""):
|
||||||
|
|
||||||
_Search.__init__(self, "tag", {"tag": tag_name}, api_key, api_secret, session_key)
|
_Search.__init__(self, "tag", {"tag": tag_name}, api_key, api_secret, session_key)
|
||||||
|
|
||||||
|
@ -2723,7 +2725,7 @@ class TrackSearch(_Search):
|
||||||
"""Search for a track by track title. If you don't wanna narrow the results down
|
"""Search for a track by track title. If you don't wanna narrow the results down
|
||||||
by specifying the artist name, set it to empty string."""
|
by specifying the artist name, set it to empty string."""
|
||||||
|
|
||||||
def __init__(self, artist_name, track_title, api_key, api_secret, session_key):
|
def __init__(self, artist_name, track_title, api_key, api_secret, session_key=""):
|
||||||
|
|
||||||
_Search.__init__(self, "track", {"track": track_title, "artist": artist_name}, api_key, api_secret, session_key)
|
_Search.__init__(self, "track", {"track": track_title, "artist": artist_name}, api_key, api_secret, session_key)
|
||||||
|
|
||||||
|
@ -2742,7 +2744,7 @@ class VenueSearch(_Search):
|
||||||
"""Search for a venue by its name. If you don't wanna narrow the results down
|
"""Search for a venue by its name. If you don't wanna narrow the results down
|
||||||
by specifying a country, set it to empty string."""
|
by specifying a country, set it to empty string."""
|
||||||
|
|
||||||
def __init__(self, venue_name, country_name, api_key, api_secret, session_key):
|
def __init__(self, venue_name, country_name, api_key, api_secret, session_key=""):
|
||||||
|
|
||||||
_Search.__init__(self, "venue", {"venue": venue_name, "country": country_name}, api_key, api_secret, session_key)
|
_Search.__init__(self, "venue", {"venue": venue_name, "country": country_name}, api_key, api_secret, session_key)
|
||||||
|
|
||||||
|
@ -2762,7 +2764,7 @@ class Venue(_BaseObject):
|
||||||
|
|
||||||
# TODO: waiting for a venue.getInfo web service to use.
|
# TODO: waiting for a venue.getInfo web service to use.
|
||||||
|
|
||||||
def __init__(self, id, api_key, api_secret, session_key):
|
def __init__(self, id, api_key, api_secret, session_key=""):
|
||||||
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
_BaseObject.__init__(self, api_key, api_secret, session_key)
|
||||||
|
|
||||||
self.id = _number(id)
|
self.id = _number(id)
|
||||||
|
@ -2803,7 +2805,7 @@ class Venue(_BaseObject):
|
||||||
|
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def create_new_playlist(title, description, api_key, api_secret, session_key):
|
def create_new_playlist(title, description, api_key, api_secret, session_key=""):
|
||||||
"""Creates a playlist for the authenticated user and returns it.
|
"""Creates a playlist for the authenticated user and returns it.
|
||||||
* title: The title of the new playlist.
|
* title: The title of the new playlist.
|
||||||
* description: The description of the new playlist.
|
* description: The description of the new playlist.
|
||||||
|
@ -2820,7 +2822,7 @@ def create_new_playlist(title, description, api_key, api_secret, session_key):
|
||||||
|
|
||||||
return Playlist(user, id, api_key, api_secret, session_key)
|
return Playlist(user, id, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def get_authenticated_user(api_key, api_secret, session_key):
|
def get_authenticated_user(api_key, api_secret, session_key=""):
|
||||||
"""Returns the authenticated user."""
|
"""Returns the authenticated user."""
|
||||||
|
|
||||||
return AuthenticatedUser(api_key, api_secret, session_key)
|
return AuthenticatedUser(api_key, api_secret, session_key)
|
||||||
|
@ -2955,32 +2957,32 @@ def _number(string):
|
||||||
else:
|
else:
|
||||||
return int(string)
|
return int(string)
|
||||||
|
|
||||||
def search_for_album(album_name, api_key, api_secret, session_key):
|
def search_for_album(album_name, api_key, api_secret, session_key=""):
|
||||||
"""Searches for an album by its name. Returns a AlbumSearch object.
|
"""Searches for an album by its name. Returns a AlbumSearch object.
|
||||||
Use get_next_page() to retreive sequences of results."""
|
Use get_next_page() to retreive sequences of results."""
|
||||||
|
|
||||||
return AlbumSearch(album_name, api_key, api_secret, session_key)
|
return AlbumSearch(album_name, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def search_for_artist(artist_name, api_key, api_secret, session_key):
|
def search_for_artist(artist_name, api_key, api_secret, session_key=""):
|
||||||
"""Searches of an artist by its name. Returns a ArtistSearch object.
|
"""Searches of an artist by its name. Returns a ArtistSearch object.
|
||||||
Use get_next_page() to retreive sequences of results."""
|
Use get_next_page() to retreive sequences of results."""
|
||||||
|
|
||||||
return ArtistSearch(artist_name, api_key, api_secret, session_key)
|
return ArtistSearch(artist_name, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def search_for_tag(tag_name, api_key, api_secret, session_key):
|
def search_for_tag(tag_name, api_key, api_secret, session_key=""):
|
||||||
"""Searches of a tag by its name. Returns a TagSearch object.
|
"""Searches of a tag by its name. Returns a TagSearch object.
|
||||||
Use get_next_page() to retreive sequences of results."""
|
Use get_next_page() to retreive sequences of results."""
|
||||||
|
|
||||||
return TagSearch(tag_name, api_key, api_secret, session_key)
|
return TagSearch(tag_name, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def search_for_track(artist_name, track_name, api_key, api_secret, session_key):
|
def search_for_track(artist_name, track_name, api_key, api_secret, session_key=""):
|
||||||
"""Searches of a track by its name and its artist. Set artist to an empty string if not available.
|
"""Searches of a track by its name and its artist. Set artist to an empty string if not available.
|
||||||
Returns a TrackSearch object.
|
Returns a TrackSearch object.
|
||||||
Use get_next_page() to retreive sequences of results."""
|
Use get_next_page() to retreive sequences of results."""
|
||||||
|
|
||||||
return TrackSearch(artist_name, track_name, api_key, api_secret, session_key)
|
return TrackSearch(artist_name, track_name, api_key, api_secret, session_key)
|
||||||
|
|
||||||
def search_for_venue(venue_name, country_name, api_key, api_secret, session_key):
|
def search_for_venue(venue_name, country_name, api_key, api_secret, session_key=""):
|
||||||
"""Searches of a venue by its name and its country. Set country_name to an empty string if not available.
|
"""Searches of a venue by its name and its country. Set country_name to an empty string if not available.
|
||||||
Returns a VenueSearch object.
|
Returns a VenueSearch object.
|
||||||
Use get_next_page() to retreive sequences of results."""
|
Use get_next_page() to retreive sequences of results."""
|
||||||
|
@ -2996,7 +2998,7 @@ def extract_items(topitems_or_libraryitems):
|
||||||
|
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def get_top_tags(api_key, api_secret, session_key):
|
def get_top_tags(api_key, api_secret, session_key=""):
|
||||||
"""Returns a sequence of the most used Last.fm tags as a sequence of TopItem objects."""
|
"""Returns a sequence of the most used Last.fm tags as a sequence of TopItem objects."""
|
||||||
|
|
||||||
doc = _Request("tag.getTopTags", dict(), api_key, api_secret, session_key).execute(True)
|
doc = _Request("tag.getTopTags", dict(), api_key, api_secret, session_key).execute(True)
|
||||||
|
@ -3009,7 +3011,7 @@ def get_top_tags(api_key, api_secret, session_key):
|
||||||
|
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def get_track_by_mbid(mbid, api_key, api_secret, session_key):
|
def get_track_by_mbid(mbid, api_key, api_secret, session_key=""):
|
||||||
"""Looks up a track by its MusicBrainz ID."""
|
"""Looks up a track by its MusicBrainz ID."""
|
||||||
|
|
||||||
params = {"mbid": unicode(mbid)}
|
params = {"mbid": unicode(mbid)}
|
||||||
|
@ -3018,7 +3020,7 @@ def get_track_by_mbid(mbid, api_key, api_secret, session_key):
|
||||||
|
|
||||||
return Track(_extract(doc, "name", 1), _extract(doc, "name"), api_key, api_secret, session_key)
|
return Track(_extract(doc, "name", 1), _extract(doc, "name"), api_key, api_secret, session_key)
|
||||||
|
|
||||||
def get_artist_by_mbid(mbid, api_key, api_secret, session_key):
|
def get_artist_by_mbid(mbid, api_key, api_secret, session_key=""):
|
||||||
"""Loooks up an artist by its MusicBrainz ID."""
|
"""Loooks up an artist by its MusicBrainz ID."""
|
||||||
|
|
||||||
params = {"mbid": unicode(mbid)}
|
params = {"mbid": unicode(mbid)}
|
||||||
|
@ -3027,7 +3029,7 @@ def get_artist_by_mbid(mbid, api_key, api_secret, session_key):
|
||||||
|
|
||||||
return Artist(_extract(doc, "name"), api_key, api_secret, session_key)
|
return Artist(_extract(doc, "name"), api_key, api_secret, session_key)
|
||||||
|
|
||||||
def get_album_by_mbid(mbid, api_key, api_secret, session_key):
|
def get_album_by_mbid(mbid, api_key, api_secret, session_key=""):
|
||||||
"""Looks up an album by its MusicBrainz ID."""
|
"""Looks up an album by its MusicBrainz ID."""
|
||||||
|
|
||||||
params = {"mbid": unicode(mbid)}
|
params = {"mbid": unicode(mbid)}
|
||||||
|
|
Loading…
Reference in a new issue