332 lines
13 KiB
Python
332 lines
13 KiB
Python
#!/usr/bin/env python
|
|
|
|
__author__ = "Abhinav Sarkar"
|
|
__version__ = "0.1"
|
|
__license__ = "GNU Lesser General Public License"
|
|
|
|
from base import LastfmBase
|
|
|
|
class Geo(object):
|
|
"""A class representing an geographic location."""
|
|
@staticmethod
|
|
def getEvents(api,
|
|
location,
|
|
distance = None,
|
|
page = None):
|
|
params = {'method': 'geo.getevents', 'location': location}
|
|
data = api._fetchData(params).find('events')
|
|
|
|
return SearchResult(
|
|
type = 'event',
|
|
searchTerms = data.attrib['location'],
|
|
startPage = int(data.attrib['page']),
|
|
totalResults = int(data.attrib['total']),
|
|
itemsPerPage = int(math.ceil(float(data.attrib['total']))/float(data.attrib['totalpages'])),
|
|
matches = [
|
|
Event(
|
|
api,
|
|
id = int(e.findtext('id')),
|
|
title = e.findtext('title'),
|
|
artists = [Artist(api, name = a.text) for a in e.findall('artists/artist')],
|
|
headliner = Artist(api, name = e.findtext('artists/headliner')),
|
|
venue = Venue(
|
|
name = e.findtext('venue/name'),
|
|
location = Location(
|
|
api,
|
|
city = e.findtext('venue/location/city'),
|
|
country = Country(
|
|
api,
|
|
name = e.findtext('venue/location/country')
|
|
),
|
|
street = e.findtext('venue/location/street'),
|
|
postalCode = e.findtext('venue/location/postalcode'),
|
|
latitude = float(e.findtext(
|
|
'venue/location/{%s}point/{%s}lat' % ((Location.xmlns,)*2)
|
|
)),
|
|
longitude = float(e.findtext(
|
|
'venue/location/{%s}point/{%s}long' % ((Location.xmlns,)*2)
|
|
)),
|
|
timezone = e.findtext('venue/location/timezone')
|
|
),
|
|
url = e.findtext('venue/url')
|
|
),
|
|
startDate = e.findtext('startDate') and
|
|
datetime(*(time.strptime(e.findtext('startDate').strip(), '%a, %d %b %Y')[0:6])) or
|
|
None,
|
|
startTime = e.findtext('startTime') and
|
|
datetime(*(time.strptime(e.findtext('startTime').strip(), '%H:%M')[0:6])) or
|
|
None,
|
|
description = e.findtext('description'),
|
|
image = dict([(i.get('size'), i.text) for i in e.findall('image')]),
|
|
url = e.findtext('url')
|
|
)
|
|
for e in data.findall('event')
|
|
]
|
|
)
|
|
|
|
@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):
|
|
params = {'method': 'geo.gettoptracks', 'country': country}
|
|
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 LastfmError("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 "<lastfm.geo.Venue: %s, %s>" % (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,
|
|
name = None,
|
|
city = None,
|
|
country = None,
|
|
street = None,
|
|
postalCode = None,
|
|
latitude = None,
|
|
longitude = None,
|
|
timezone = None):
|
|
if not isinstance(api, Api):
|
|
raise LastfmError("api reference must be supplied as an argument")
|
|
self.__api = api
|
|
self.__name = name
|
|
self.__city = city
|
|
self.__country = country
|
|
self.__street = street
|
|
self.__postalCode = postalCode
|
|
self.__latitude = latitude
|
|
self.__longitude = longitude
|
|
self.__timezone = timezone
|
|
|
|
@property
|
|
def name(self):
|
|
"""name of the location"""
|
|
return self.__name
|
|
|
|
@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
|
|
|
|
def getEvents(self,
|
|
distance = None,
|
|
page = None):
|
|
return Geo.getEvents(self.__api, self.name, distance, page).matches
|
|
|
|
@property
|
|
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['name'])
|
|
except KeyError:
|
|
raise LastfmError("either latitude and longitude or name 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.name)
|
|
|
|
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.name is None:
|
|
return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
|
|
else:
|
|
return "<lastfm.geo.Location: %s>" % self.name
|
|
|
|
class Country(LastfmBase):
|
|
"""A class representing a country."""
|
|
def init(self,
|
|
api,
|
|
name = None):
|
|
if not isinstance(api, Api):
|
|
raise LastfmError("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
|
|
|
|
@property
|
|
def topArtists(self):
|
|
"""top artists of the country"""
|
|
return Geo.getTopArtists(self.__api, self.name)
|
|
|
|
@property
|
|
def topArtist(self):
|
|
"""top artist of the country"""
|
|
return (len(self.topArtists) and self.topArtists[0] or None)
|
|
|
|
@property
|
|
def topTracks(self):
|
|
"""top tracks of the country"""
|
|
return Geo.getTopTracks(self.__api, self.name)
|
|
|
|
@property
|
|
def topTrack(self):
|
|
"""top track of the country"""
|
|
return (len(self.topTracks) and self.topTracks[0] or None)
|
|
|
|
@staticmethod
|
|
def hashFunc(*args, **kwds):
|
|
try:
|
|
return hash(kwds['name'])
|
|
except KeyError:
|
|
raise LastfmError("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 "<lastfm.geo.Country: %s>" % self.name
|
|
|
|
import math
|
|
from datetime import datetime
|
|
import time
|
|
|
|
from api import Api
|
|
from error import LastfmError
|
|
from artist import Artist
|
|
from track import Track
|
|
from event import Event
|
|
from search import SearchResult
|
|
from stats import Stats |