#!/usr/bin/env python __author__ = "Abhinav Sarkar " __version__ = "0.2" __license__ = "GNU Lesser General Public License" from base import LastfmBase from lazylist import lazylist class Geo(object): """A class representing an geographic location.""" @staticmethod def getEvents(api, location, latitude = None, longitude = None, distance = None): params = {'method': 'geo.getevents', 'location': location} if distance is not None: params.update({'distance': distance}) if latitude is not None and longitude is not None: params.update({'latitude': latitude, 'longitude': longitude}) @lazylist def gen(lst): data = api._fetchData(params).find('events') totalPages = int(data.attrib['totalpages']) @lazylist def gen2(lst, data): for e in data.findall('event'): yield Event.createFromData(api, e) for e in gen2(data): yield e for page in xrange(2, totalPages+1): params.update({'page': page}) data = api._fetchData(params).find('events') for e in gen2(data): yield e return gen() @staticmethod def getTopArtists(api, country): params = {'method': 'geo.gettopartists', 'country': country} data = api._fetchData(params).find('topartists') return [ Artist( api, name = a.findtext('name'), mbid = a.findtext('mbid'), stats = Stats( subject = a.findtext('name'), rank = int(a.attrib['rank']), playcount = int(a.findtext('playcount')) ), url = 'http://' + a.findtext('url'), image = {'large': a.findtext('image')} ) for a in data.findall('artist') ] @staticmethod def getTopTracks(api, country, location = None): params = {'method': 'geo.gettoptracks', 'country': country} if location is not None: params.update({'location': location}) data = api._fetchData(params).find('toptracks') return [ Track( api, name = t.findtext('name'), mbid = t.findtext('mbid'), artist = Artist( api, name = t.findtext('artist/name'), mbid = t.findtext('artist/mbid'), url = t.findtext('artist/url') ), stats = Stats( subject = t.findtext('name'), rank = int(t.attrib['rank']), playcount = int(t.findtext('playcount')) ), streamable = (t.findtext('streamable') == '1'), fullTrack = (t.find('streamable').attrib['fulltrack'] == '1'), url = 'http://' + t.findtext('url'), image = {'large': t.findtext('image')} ) for t in data.findall('track') ] class Venue(LastfmBase): """A class representing a venue of an event""" def init(self, name = None, location = None, url = None): self.__name = name self.__location = location self.__url = url @property def name(self): """name of the venue""" return self.__name @property def location(self): """location of the event""" return self.__location @property def url(self): """url of the event's page""" return self.__url @staticmethod def hashFunc(*args, **kwds): try: return hash(kwds['url']) except KeyError: raise LastfmInvalidParametersError("url has to be provided for hashing") def __hash__(self): return self.__class__.hashFunc(url = self.url) def __eq__(self, other): return self.url == other.url def __lt__(self, other): return self.name < other.name def __repr__(self): return "" % (self.name, self.location.city) class Location(LastfmBase): """A class representing a location of an event""" xmlns = "http://www.w3.org/2003/01/geo/wgs84_pos#" def init(self, api, city = None, country = None, street = None, postalCode = None, latitude = None, longitude = None, timezone = None): if not isinstance(api, Api): raise LastfmInvalidParametersError("api reference must be supplied as an argument") self.__api = api self.__city = city self.__country = country self.__street = street self.__postalCode = postalCode self.__latitude = latitude self.__longitude = longitude self.__timezone = timezone @property def city(self): """city in which the location is situated""" return self.__city @property def country(self): """country in which the location is situated""" return self.__country @property def street(self): """street in which the location is situated""" return self.__street @property def postalCode(self): """postal code of the location""" return self.__postalCode @property def latitude(self): """latitude of the location""" return self.__latitude @property def longitude(self): """longitude of the location""" return self.__longitude @property def timezone(self): """timezone in which the location is situated""" 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, distance = None): return Geo.getEvents(self.__api, self.city, self.latitude, self.longitude, distance) @LastfmBase.cachedProperty def events(self): """events taking place at/around the location""" return self.getEvents() @staticmethod def hashFunc(*args, **kwds): try: return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude'])) except KeyError: try: return hash("name%s" % kwds['city']) except KeyError: raise LastfmInvalidParametersError("either latitude and longitude or city has to be provided for hashing") def __hash__(self): if not self.name: return self.__class__.hashFunc( latitude = self.latitude, longitude = self.longitude) else: return self.__class__.hashFunc(name = self.city) def __eq__(self, other): return self.latitude == other.latitude and self.longitude == other.longitude def __lt__(self, other): if self.country != other.country: return self.country < other.country else: return self.city < other.city def __repr__(self): if self.city is None: return "" % (self.latitude, self.longitude) else: return "" % self.city class Country(LastfmBase): """A class representing a country.""" def init(self, api, name = None): if not isinstance(api, Api): raise LastfmInvalidParametersError("api reference must be supplied as an argument") self.__api = api self.__name = name @property def name(self): """name of the country""" return self.__name @LastfmBase.cachedProperty def topArtists(self): """top artists of the country""" return Geo.getTopArtists(self.__api, self.name) @LastfmBase.topProperty("topArtists") def topArtist(self): """top artist of the country""" pass def getTopTracks(self, location = None): return Geo.getTopTracks(self.__api, self.name, location) @LastfmBase.cachedProperty def topTracks(self): """top tracks of the country""" return self.getTopTracks() @LastfmBase.topProperty("topTracks") def topTrack(self): """top track of the country""" pass @LastfmBase.cachedProperty def events(self): """events taking place at/around the location""" return Geo.getEvents(self.__api, self.name) @staticmethod def hashFunc(*args, **kwds): try: return hash(kwds['name']) except KeyError: raise LastfmInvalidParametersError("name has to be provided for hashing") def __hash__(self): return self.__class__.hashFunc(name = self.name) def __eq__(self, other): return self.name == other.name def __lt__(self, other): return self.name < other.name def __repr__(self): return "" % self.name from api import Api from artist import Artist from error import LastfmInvalidParametersError from event import Event from stats import Stats from track import Track