implemented playlist related methods in album, tag and user modules. updated some methods to the latest API docs. The read-only part of API is complete.
This commit is contained in:
parent
a2320e6dd0
commit
27a1676c3b
@ -114,6 +114,10 @@ class Album(LastfmBase):
|
|||||||
"""top tag for the album"""
|
"""top tag for the album"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@LastfmBase.cachedProperty
|
||||||
|
def playlist(self):
|
||||||
|
return Playlist.fetch(self.__api, "lastfm://playlist/album/%s" % self.id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _fetchData(api,
|
def _fetchData(api,
|
||||||
artist = None,
|
artist = None,
|
||||||
@ -203,5 +207,6 @@ import time
|
|||||||
from api import Api
|
from api import Api
|
||||||
from artist import Artist
|
from artist import Artist
|
||||||
from error import LastfmInvalidParametersError
|
from error import LastfmInvalidParametersError
|
||||||
|
from playlist import Playlist
|
||||||
from stats import Stats
|
from stats import Stats
|
||||||
from tag import Tag
|
from tag import Tag
|
@ -13,7 +13,7 @@ class Api(object):
|
|||||||
SEARCH_XMLNS = "http://a9.com/-/spec/opensearch/1.1/"
|
SEARCH_XMLNS = "http://a9.com/-/spec/opensearch/1.1/"
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
apiKey = '23caa86333d2cb2055fa82129802780a',
|
apiKey,
|
||||||
input_encoding=None,
|
input_encoding=None,
|
||||||
request_headers=None,
|
request_headers=None,
|
||||||
no_cache = False,
|
no_cache = False,
|
||||||
@ -264,7 +264,6 @@ class Api(object):
|
|||||||
|
|
||||||
def _fetchData(self,
|
def _fetchData(self,
|
||||||
params,
|
params,
|
||||||
parse = True,
|
|
||||||
no_cache = False):
|
no_cache = False):
|
||||||
params.update({'api_key': self.__apiKey})
|
params.update({'api_key': self.__apiKey})
|
||||||
xml = self._fetchUrl(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
|
xml = self._fetchUrl(Api.API_ROOT_URL, params, no_cache = self._no_cache or no_cache)
|
||||||
@ -280,10 +279,7 @@ class Api(object):
|
|||||||
raise errorMap[code](message, code)
|
raise errorMap[code](message, code)
|
||||||
else:
|
else:
|
||||||
raise LastfmError(message, code)
|
raise LastfmError(message, code)
|
||||||
if parse:
|
return data
|
||||||
return data
|
|
||||||
else:
|
|
||||||
return xml
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<lastfm.Api: %s>" % self.__apiKey
|
return "<lastfm.Api: %s>" % self.__apiKey
|
||||||
|
62
src/geo.py
62
src/geo.py
@ -12,10 +12,15 @@ class Geo(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def getEvents(api,
|
def getEvents(api,
|
||||||
location,
|
location,
|
||||||
|
latitude = None,
|
||||||
|
longitude = None,
|
||||||
distance = None):
|
distance = None):
|
||||||
params = {'method': 'geo.getevents', 'location': location}
|
params = {'method': 'geo.getevents', 'location': location}
|
||||||
if distance is not None:
|
if distance is not None:
|
||||||
params.update({'distance': distance})
|
params.update({'distance': distance})
|
||||||
|
|
||||||
|
if latitude is not None and longitude is not None:
|
||||||
|
params.update({'latitude': latitude, 'longitude': longitude})
|
||||||
|
|
||||||
@lazylist
|
@lazylist
|
||||||
def gen(lst):
|
def gen(lst):
|
||||||
@ -58,8 +63,11 @@ class Geo(object):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getTopTracks(api, country):
|
def getTopTracks(api, country, location = None):
|
||||||
params = {'method': 'geo.gettoptracks', 'country': country}
|
params = {'method': 'geo.gettoptracks', 'country': country}
|
||||||
|
if location is not None:
|
||||||
|
params.update({'location': location})
|
||||||
|
|
||||||
data = api._fetchData(params).find('toptracks')
|
data = api._fetchData(params).find('toptracks')
|
||||||
return [
|
return [
|
||||||
Track(
|
Track(
|
||||||
@ -135,7 +143,6 @@ class Location(LastfmBase):
|
|||||||
|
|
||||||
def init(self,
|
def init(self,
|
||||||
api,
|
api,
|
||||||
name = None,
|
|
||||||
city = None,
|
city = None,
|
||||||
country = None,
|
country = None,
|
||||||
street = None,
|
street = None,
|
||||||
@ -146,7 +153,6 @@ class Location(LastfmBase):
|
|||||||
if not isinstance(api, Api):
|
if not isinstance(api, Api):
|
||||||
raise LastfmInvalidParametersError("api reference must be supplied as an argument")
|
raise LastfmInvalidParametersError("api reference must be supplied as an argument")
|
||||||
self.__api = api
|
self.__api = api
|
||||||
self.__name = name
|
|
||||||
self.__city = city
|
self.__city = city
|
||||||
self.__country = country
|
self.__country = country
|
||||||
self.__street = street
|
self.__street = street
|
||||||
@ -155,11 +161,6 @@ class Location(LastfmBase):
|
|||||||
self.__longitude = longitude
|
self.__longitude = longitude
|
||||||
self.__timezone = timezone
|
self.__timezone = timezone
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""name of the location"""
|
|
||||||
return self.__name
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def city(self):
|
def city(self):
|
||||||
"""city in which the location is situated"""
|
"""city in which the location is situated"""
|
||||||
@ -194,10 +195,26 @@ class Location(LastfmBase):
|
|||||||
def timezone(self):
|
def timezone(self):
|
||||||
"""timezone in which the location is situated"""
|
"""timezone in which the location is situated"""
|
||||||
return self.__timezone
|
return self.__timezone
|
||||||
|
|
||||||
|
@LastfmBase.cachedProperty
|
||||||
|
def topTracks(self):
|
||||||
|
"""top tracks of the location"""
|
||||||
|
if self.country is None or self.city is None:
|
||||||
|
raise LastfmInvalidParametersError("country and city of this location are required for calling this method")
|
||||||
|
return Geo.getTopTracks(self.__api, self.country.name, self.city)
|
||||||
|
|
||||||
|
@LastfmBase.topProperty("topTracks")
|
||||||
|
def topTrack(self):
|
||||||
|
"""top track of the location"""
|
||||||
|
pass
|
||||||
|
|
||||||
def getEvents(self,
|
def getEvents(self,
|
||||||
distance = None):
|
distance = None):
|
||||||
return Geo.getEvents(self.__api, self.name, distance)
|
return Geo.getEvents(self.__api,
|
||||||
|
self.city,
|
||||||
|
self.latitude,
|
||||||
|
self.longitude,
|
||||||
|
distance)
|
||||||
|
|
||||||
@LastfmBase.cachedProperty
|
@LastfmBase.cachedProperty
|
||||||
def events(self):
|
def events(self):
|
||||||
@ -210,9 +227,9 @@ class Location(LastfmBase):
|
|||||||
return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude']))
|
return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude']))
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
return hash("name%s" % kwds['name'])
|
return hash("name%s" % kwds['city'])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise LastfmInvalidParametersError("either latitude and longitude or name has to be provided for hashing")
|
raise LastfmInvalidParametersError("either latitude and longitude or city has to be provided for hashing")
|
||||||
|
|
||||||
def __hash__(self):
|
def __hash__(self):
|
||||||
if not self.name:
|
if not self.name:
|
||||||
@ -220,7 +237,7 @@ class Location(LastfmBase):
|
|||||||
latitude = self.latitude,
|
latitude = self.latitude,
|
||||||
longitude = self.longitude)
|
longitude = self.longitude)
|
||||||
else:
|
else:
|
||||||
return self.__class__.hashFunc(name = self.name)
|
return self.__class__.hashFunc(name = self.city)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
return self.latitude == other.latitude and self.longitude == other.longitude
|
return self.latitude == other.latitude and self.longitude == other.longitude
|
||||||
@ -232,10 +249,10 @@ class Location(LastfmBase):
|
|||||||
return self.city < other.city
|
return self.city < other.city
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
if self.name is None:
|
if self.city is None:
|
||||||
return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
|
return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
|
||||||
else:
|
else:
|
||||||
return "<lastfm.geo.Location: %s>" % self.name
|
return "<lastfm.geo.Location: %s>" % self.city
|
||||||
|
|
||||||
class Country(LastfmBase):
|
class Country(LastfmBase):
|
||||||
"""A class representing a country."""
|
"""A class representing a country."""
|
||||||
@ -262,21 +279,24 @@ class Country(LastfmBase):
|
|||||||
"""top artist of the country"""
|
"""top artist of the country"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def getTopTracks(self, location = None):
|
||||||
|
return Geo.getTopTracks(self.__api, self.name, location)
|
||||||
|
|
||||||
@LastfmBase.cachedProperty
|
@LastfmBase.cachedProperty
|
||||||
def topTracks(self):
|
def topTracks(self):
|
||||||
"""top tracks of the country"""
|
"""top tracks of the country"""
|
||||||
return Geo.getTopTracks(self.__api, self.name)
|
return self.getTopTracks()
|
||||||
|
|
||||||
@LastfmBase.cachedProperty
|
|
||||||
def events(self):
|
|
||||||
"""events taking place at/around the location"""
|
|
||||||
return Geo.getEvents(self.__api, self.name)
|
|
||||||
|
|
||||||
@LastfmBase.topProperty("topTracks")
|
@LastfmBase.topProperty("topTracks")
|
||||||
def topTrack(self):
|
def topTrack(self):
|
||||||
"""top track of the country"""
|
"""top track of the country"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@LastfmBase.cachedProperty
|
||||||
|
def events(self):
|
||||||
|
"""events taking place at/around the location"""
|
||||||
|
return Geo.getEvents(self.__api, self.name)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hashFunc(*args, **kwds):
|
def hashFunc(*args, **kwds):
|
||||||
try:
|
try:
|
||||||
|
@ -8,14 +8,18 @@ from base import LastfmBase
|
|||||||
|
|
||||||
class Playlist(LastfmBase):
|
class Playlist(LastfmBase):
|
||||||
"""A class representing an XPSF playlist."""
|
"""A class representing an XPSF playlist."""
|
||||||
def init(self, xpsfData, url):
|
def init(self, api, url):
|
||||||
self.__data = xpsfData
|
self.__api = api
|
||||||
|
self.__data = None
|
||||||
self.__url = url
|
self.__url = url
|
||||||
|
|
||||||
@property
|
@LastfmBase.cachedProperty
|
||||||
def data(self):
|
def data(self):
|
||||||
"""playlist's data"""
|
"""playlist's data"""
|
||||||
return self.__data
|
params = {'method': 'playlist.fetch', 'playlistURL': self.__url}
|
||||||
|
tmp = StringIO.StringIO()
|
||||||
|
ElementTree.ElementTree(self.__api._fetchData(params)[0]).write(tmp)
|
||||||
|
return tmp.getvalue()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self):
|
def url(self):
|
||||||
@ -24,8 +28,7 @@ class Playlist(LastfmBase):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fetch(api, url):
|
def fetch(api, url):
|
||||||
params = {'method': 'playlist.fetch', 'playlistURL': url}
|
return Playlist(api, url = url)
|
||||||
return Playlist(api._fetchData(params, parse = False), url = url)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hashFunc(*args, **kwds):
|
def hashFunc(*args, **kwds):
|
||||||
@ -45,5 +48,18 @@ class Playlist(LastfmBase):
|
|||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<lastfm.Playlist: %s>" % self.url
|
return "<lastfm.Playlist: %s>" % self.url
|
||||||
|
|
||||||
from error import LastfmInvalidParametersError
|
import StringIO
|
||||||
|
import sys
|
||||||
|
from error import LastfmInvalidParametersError
|
||||||
|
|
||||||
|
if sys.version.startswith('2.5'):
|
||||||
|
import xml.etree.cElementTree as ElementTree
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
import cElementTree as ElementTree
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
import ElementTree
|
||||||
|
except ImportError:
|
||||||
|
raise LastfmError("Install ElementTree package for using python-lastfm")
|
@ -163,6 +163,11 @@ class Tag(LastfmBase):
|
|||||||
"""top track for the tag"""
|
"""top track for the tag"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@LastfmBase.cachedProperty
|
||||||
|
def playlist(self):
|
||||||
|
return Playlist.fetch(self.__api,
|
||||||
|
"lastfm://playlist/tag/%s/freetracks" % self.name)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getTopTags(api):
|
def getTopTags(api):
|
||||||
params = {'method': 'tag.getTopTags'}
|
params = {'method': 'tag.getTopTags'}
|
||||||
@ -240,5 +245,6 @@ from album import Album
|
|||||||
from api import Api
|
from api import Api
|
||||||
from artist import Artist
|
from artist import Artist
|
||||||
from error import LastfmInvalidParametersError
|
from error import LastfmInvalidParametersError
|
||||||
|
from playlist import Playlist
|
||||||
from stats import Stats
|
from stats import Stats
|
||||||
from track import Track
|
from track import Track
|
@ -61,6 +61,6 @@ class Tasteometer(object):
|
|||||||
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<lastfm.Tasteometer>"
|
return "<lastfm.Tasteometer: %s%% match>" % (self.score*100)
|
||||||
|
|
||||||
from artist import Artist
|
from artist import Artist
|
71
src/user.py
71
src/user.py
@ -6,6 +6,7 @@ __license__ = "GNU Lesser General Public License"
|
|||||||
|
|
||||||
from base import LastfmBase
|
from base import LastfmBase
|
||||||
from lazylist import lazylist
|
from lazylist import lazylist
|
||||||
|
import playlist
|
||||||
|
|
||||||
class User(LastfmBase):
|
class User(LastfmBase):
|
||||||
"""A class representing an user."""
|
"""A class representing an user."""
|
||||||
@ -141,10 +142,27 @@ class User(LastfmBase):
|
|||||||
"""nearest neightbour of the user"""
|
"""nearest neightbour of the user"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@LastfmBase.cachedProperty
|
||||||
def playlists(self):
|
def playlists(self):
|
||||||
"""playlists of the user"""
|
"""playlists of the user"""
|
||||||
pass
|
params = {'method': 'user.getPlaylists', 'user': self.name}
|
||||||
|
data = self.__api._fetchData(params).find('playlists')
|
||||||
|
return [
|
||||||
|
User.Playlist(
|
||||||
|
self.__api,
|
||||||
|
id = int(p.findtext('id')),
|
||||||
|
title = p.findtext('title'),
|
||||||
|
date = datetime(*(
|
||||||
|
time.strptime(
|
||||||
|
p.findtext('date').strip(),
|
||||||
|
'%Y-%m-%dT%H:%M:%S'
|
||||||
|
)[0:6])
|
||||||
|
),
|
||||||
|
size = int(p.findtext('size')),
|
||||||
|
creator = self
|
||||||
|
)
|
||||||
|
for p in data.findall('playlist')
|
||||||
|
]
|
||||||
|
|
||||||
@LastfmBase.cachedProperty
|
@LastfmBase.cachedProperty
|
||||||
def lovedTracks(self):
|
def lovedTracks(self):
|
||||||
@ -451,6 +469,11 @@ class User(LastfmBase):
|
|||||||
pass
|
pass
|
||||||
return gen()
|
return gen()
|
||||||
|
|
||||||
|
def compare(self, other, limit = None):
|
||||||
|
return Tasteometer.compare(self.__api,
|
||||||
|
'user', 'user',
|
||||||
|
self.name, other.name,
|
||||||
|
limit)
|
||||||
@property
|
@property
|
||||||
def library(self):
|
def library(self):
|
||||||
return self.__lirary
|
return self.__lirary
|
||||||
@ -474,6 +497,49 @@ class User(LastfmBase):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<lastfm.User: %s>" % self.name
|
return "<lastfm.User: %s>" % self.name
|
||||||
|
|
||||||
|
class Playlist(playlist.Playlist):
|
||||||
|
"""A class representing a playlist belonging to the user."""
|
||||||
|
def init(self, api, id, title, date, size, creator):
|
||||||
|
super(User.Playlist, self).init(api, "lastfm://playlist/%s" % id)
|
||||||
|
self.__id = id
|
||||||
|
self.__title = title
|
||||||
|
self.__date = date
|
||||||
|
self.__size = size
|
||||||
|
self.__creator = creator
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
return self.__id
|
||||||
|
|
||||||
|
@property
|
||||||
|
def title(self):
|
||||||
|
return self.__title
|
||||||
|
|
||||||
|
@property
|
||||||
|
def date(self):
|
||||||
|
return self.__date
|
||||||
|
|
||||||
|
@property
|
||||||
|
def size(self):
|
||||||
|
return self.__size
|
||||||
|
|
||||||
|
@property
|
||||||
|
def creator(self):
|
||||||
|
return self.__creator
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def hashFunc(*args, **kwds):
|
||||||
|
try:
|
||||||
|
return hash(kwds['id'])
|
||||||
|
except KeyError:
|
||||||
|
raise LastfmInvalidParametersError("id has to be provided for hashing")
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return self.__class__.hashFunc(id = self.id)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "<lastfm.User.Playlist: %s>" % self.title
|
||||||
|
|
||||||
class Library(object):
|
class Library(object):
|
||||||
"""A class representing the music library of the user."""
|
"""A class representing the music library of the user."""
|
||||||
def __init__(self, api, user):
|
def __init__(self, api, user):
|
||||||
@ -649,5 +715,6 @@ from error import LastfmError, LastfmInvalidParametersError
|
|||||||
from event import Event
|
from event import Event
|
||||||
from stats import Stats
|
from stats import Stats
|
||||||
from tag import Tag
|
from tag import Tag
|
||||||
|
from tasteometer import Tasteometer
|
||||||
from track import Track
|
from track import Track
|
||||||
from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart
|
from weeklychart import WeeklyChart, WeeklyAlbumChart, WeeklyArtistChart, WeeklyTrackChart
|
Loading…
Reference in New Issue
Block a user