removed xml2dict.py

use xpath instead of Xml2dict
added event.py and geo.py
made appropriate modifications in album.py, api.py and artist.py
master
Abhinav Sarkar 2008-07-10 10:32:13 +00:00
parent 63470dc254
commit 305e49bc11
6 changed files with 400 additions and 88 deletions

View File

@ -85,43 +85,46 @@ class Album(object):
artist = None,
album = None,
mbid = None):
apiKey = api.getApiKey()
params = {'method': 'album.getinfo', 'api_key': apiKey}
params = {'method': 'album.getinfo'}
if not ((artist and album) or mbid):
raise LastfmError("either (artist and album) or mbid has to be given as argument.")
if artist and album:
params.update({'artist': artist, 'album': album})
elif mbid:
params.update({'mbid': mbid})
xml = api.fetchUrl(Api.API_ROOT_URL, params)
data = Xml2Dict(ElementTree.XML(xml))
if data['@status'] != "ok":
raise LastfmError("Error code: %s (%s)" % (data['error']['@code'], data['error']['text']))
data = api.fetchData(params).find('album')
return Album(
api,
name = data['album']['name'],
name = data.findtext('name'),
artist = Artist(
api,
name = data['album']['artist']
),
id = int(data['album']['id']),
mbid = data['album']['mbid'],
url = data['album']['url'],
releaseDate = data['album']['releasedate'] and
datetime(*(time.strptime(data['album']['releasedate'], '%d %b %Y, 00:00')[0:6])),
image = dict([(i['@size'],i['text']) for i in data['album']['image']]),
listeners = int(data['album']['listeners']),
playcount = int(data['album']['playcount']),
topTags = [Tag(api, name = t['name'], url = t['url']) for t in data['album']['toptags']['tag']]
)
api,
name = data.findtext('artist'),
),
id = int(data.findtext('id')),
mbid = data.findtext('mbid'),
url = data.findtext('url'),
releaseDate = data.findtext('releasedate') and
datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6])),
image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
listeners = int(data.findtext('listeners')),
playcount = int(data.findtext('playcount')),
topTags = [
Tag(
api,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('toptags/tag')
]
)
import cElementTree as ElementTree
def __eq__(self, other):
return self.id == other.id
from datetime import datetime
import time
from xml2dict import Xml2Dict
from error import LastfmError
from api import Api
from tag import Tag

View File

@ -126,6 +126,14 @@ class Api(object):
album = None,
mbid = None):
return Album.getInfo(self, artist, album, mbid)
def getArtist(self,
artist = None,
mbid = None):
return Artist.getInfo(self, artist, mbid)
def getEvent(self, event):
return Event.getInfo(self, event)
def fetchUrl(self,
url,
@ -174,12 +182,26 @@ class Api(object):
# Always return the latest version
return url_data
def fetchData(self, params):
params.update({'api_key': self.__apiKey})
xml = self.fetchUrl(Api.API_ROOT_URL, params)
data = ElementTree.XML(xml)
if data.get('status') != "ok":
raise LastfmError("Error code: %s (%s)" % (data.find("error").get('code'), data.findtext('error')))
return data
import urllib
import urllib2
import urlparse
import cElementTree as ElementTree
import time
from datetime import datetime
import sys
if sys.version.startswith('2.5'):
import xml.etree.cElementTree as ElementTree
else:
import cElementTree as ElementTree
from album import Album
from artist import Artist
@ -190,5 +212,4 @@ from filecache import FileCache
#from tag import Tag
#from track import Track
#from user import User
from xml2dict import Xml2Dict
from error import LastfmError

View File

@ -23,10 +23,19 @@ class Artist(object):
self.___url = url
self.__image = image
self.__streamable = streamable
self.__stats = stats
self.__stats = stats and Stats(
artist = self,
listeners = stats.listeners,
plays = stats.plays
)
self.__similar = similar
self.__tags = tags
self.__bio = bio
self.__bio = bio and Bio(
artist = self,
published = bio.published,
summary = bio.summary,
content = bio.content
)
def getName(self):
return self.__name
@ -48,13 +57,13 @@ class Artist(object):
return self.__similar
else:
pass
def getTags(self):
return self.__tags
def getBio(self):
return self.__bio
name = property(getName, None, None, "Name's Docstring")
mbid = property(getMbid, None, None, "Mbid's Docstring")
@ -69,15 +78,64 @@ class Artist(object):
tags = property(getTags, None, None, "Tags's Docstring")
bio = property(getBio, None, None, "Bio's Docstring")
bio = property(getBio, None, None, "Bio's Docstring")
@staticmethod
def getInfo(api,
artist = None,
mbid = None):
pass
params = {'method': 'artist.getinfo'}
if not (artist or mbid):
raise LastfmError("either artist or mbid has to be given as argument.")
if artist:
params.update({'artist': artist})
elif mbid:
params.update({'mbid': mbid})
data = api.fetchData(params).find('artist')
return Artist(
api,
name = data.findtext('name'),
mbid = data.findtext('mbid'),
url = data.findtext('url'),
image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
streamable = (data.findtext('streamable') == 1),
stats = Stats(
artist,
listeners = int(data.findtext('stats/listeners')),
plays = int(data.findtext('stats/plays'))
),
similar = [
Artist(
api,
name = a.findtext('name'),
url = a.findtext('url'),
image = dict([(i.get('size'), i.text) for i in a.findall('image')])
)
for a in data.findall('similar/artist')
],
tags = [
Tag(
api,
name = t.findtext('name'),
url = t.findtext('url')
)
for t in data.findall('tags/tag')
],
bio = Bio(
artist,
published = datetime(*(time.strptime(
data.findtext('bio/published').strip(),
'%a, %d %b %Y %H:%M:%S +0000'
)[0:6])),
summary = data.findtext('bio/summary'),
content = data.findtext('bio/content')
)
)
def __eq__(self, other):
return self.name == other.name
class Stats(object):
"""A class representing the stats of an artist."""
def __init__(self,
@ -96,13 +154,13 @@ class Stats(object):
def getPlays(self):
return self.__plays
listeners = property(getListeners, None, None, "Listeners's Docstring")
plays = property(getPlays, None, None, "Plays's Docstring")
artist = property(getArtist, None, None, "Artist's Docstring")
class Bio(object):
"""A class representing the biography of an artist."""
def __init__(self,
@ -134,3 +192,11 @@ class Bio(object):
content = property(getContent, None, None, "Content's Docstring")
artist = property(getArtist, None, None, "Artist's Docstring")
from datetime import datetime
import time
import types
from error import LastfmError
from api import Api
from tag import Tag

156
lastfm/event.py Normal file
View File

@ -0,0 +1,156 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Event(object):
"""A class representing an event."""
def __init__(self,
api,
id = None,
title = None,
artists = None,
headliner = None,
venue = None,
startDate = None,
startTime = None,
description = None,
image = None,
url = None,
attendance = None,
reviews = None,
tag = None):
self.__api = api
self.__id = id
self.__title = title
self.__artists = artists
self.__headliner = headliner
self.__venue = venue and Venue(
self,
name = venue.name,
location = venue.location,
url = venue.url
)
self.__startDate = startDate
self.__startTime = startTime
self.__description = description
self.__image = image
self.__url = url
self.__attendance = attendance
self.__reviews = reviews
self.__tag = tag
def getId(self):
return self.__id
def getTitle(self):
return self.__title
def getArtists(self):
return self.__artists
def getHeadliner(self):
return self.__headliner
def getVenue(self):
return self.__venue
def getStartDate(self):
return self.__startDate
def getStartTime(self):
return self.__startTime
def getDescription(self):
return self.__description
def getImage(self):
return self.__image
def getUrl(self):
return self.__url
def getAttendance(self):
return self.__attendance
def getReviews(self):
return self.__reviews
def getTag(self):
return self.__tag
id = property(getId, None, None, "Id's Docstring")
title = property(getTitle, None, None, "Title's Docstring")
artists = property(getArtists, None, None, "Artists's Docstring")
headliner = property(getHeadliner, None, None, "headliner's Docstring")
venue = property(getVenue, None, None, "Venue's Docstring")
startDate = property(getStartDate, None, None, "StartDate's Docstring")
startTime = property(getStartTime, None, None, "StartTime's Docstring")
description = property(getDescription, None, None, "Description's Docstring")
image = property(getImage, None, None, "Image's Docstring")
url = property(getUrl, None, None, "Url's Docstring")
attendance = property(getAttendance, None, None, "Attendance's Docstring")
reviews = property(getReviews, None, None, "Reviews's Docstring")
tag = property(getTag, None, None, "Tag's Docstring")
@staticmethod
def getInfo(api, event):
params = {'method': 'event.getinfo', 'event': event}
data = api.fetchData(params).find('event')
return Event(
api,
id = int(data.findtext('id')),
title = data.findtext('title'),
artists = [Artist(api, name = a.text) for a in data.findall('artists/artist')],
headliner = data.findtext('artists/headliner'),
venue = Venue(
event = int(data.findtext('id')),
name = data.findtext('venue/name'),
location = Location(
event = int(data.findtext('id')),
city = data.findtext('venue/location/city'),
country = data.findtext('venue/location/country'),
street = data.findtext('venue/location/street'),
postalCode = data.findtext('venue/location/postalcode'),
latitude = float(data.findtext(
'venue/location/{%s}point/{%s}lat' % ((Location.xmlns,)*2)
)),
longitude = float(data.findtext(
'venue/location/{%s}point/{%s}long' % ((Location.xmlns,)*2)
)),
timezone = data.findtext('venue/location/timezone')
),
url = data.findtext('venue/url')
),
startDate = datetime(*(time.strptime(data.findtext('startDate').strip(), '%a, %d %b %Y')[0:6])),
startTime = datetime(*(time.strptime(data.findtext('startTime').strip(), '%H:%M')[0:6])),
description = data.findtext('description'),
image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
url = data.findtext('url'),
attendance = int(data.findtext('attendance')),
reviews = int(data.findtext('reviews')),
tag = data.findtext('tag')
)
def __eq__(self, other):
return self.id == other.id
from datetime import datetime
import time
from api import Api
from artist import Artist
from geo import Venue, Location

118
lastfm/geo.py Normal file
View File

@ -0,0 +1,118 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
class Geo(object):
"""A class representing an geographic location."""
pass
class Venue(object):
"""A class representing a venue of an event"""
def __init__(self,
event,
name = None,
location = None,
url = None):
self.__event = event
self.__name = name
self.__location = location and Location(
event,
city = location.city,
country = location.country,
street = location.street,
postalCode = location.postalCode,
latitude = location.latitude,
longitude = location.longitude,
timezone = location.timezone
)
self.__url = url
def getEvent(self):
return self.__event
def getName(self):
return self.__name
def getLocation(self):
return self.__location
def getUrl(self):
return self.__url
event = property(getEvent, None, None, "Event's Docstring")
name = property(getName, None, None, "Name's Docstring")
location = property(getLocation, None, None, "Location's Docstring")
url = property(getUrl, None, None, "Url's Docstring")
def __eq__(self, other):
return sefl.url == other.url
class Location(object):
"""A class representing a location of an event"""
xmlns = "http://www.w3.org/2003/01/geo/wgs84_pos#"
def __init__(self,
event,
city = None,
country = None,
street = None,
postalCode = None,
latitude = None,
longitude = None,
timezone = None):
self.__event = event
self.__city = city
self.__country = country
self.__street = street
self.__postalCode = postalCode
self.__latitude = latitude
self.__longitude = longitude
self.__timezone = timezone
def getEvent(self):
return self.__event
def getCity(self):
return self.__city
def getCountry(self):
return self.__country
def getStreet(self):
return self.__street
def getPostalCode(self):
return self.__postalCode
def getLatitude(self):
return self.__latitude
def getLongitude(self):
return self.__longitude
def getTimezone(self):
return self.__timezone
event = property(getEvent, None, None, "Event's Docstring")
city = property(getCity, None, None, "City's Docstring")
country = property(getCountry, None, None, "Country's Docstring")
street = property(getStreet, None, None, "Street's Docstring")
postalCode = property(getPostalCode, None, None, "PostalCode's Docstring")
latitude = property(getLatitude, None, None, "Latitude's Docstring")
longitude = property(getLongitude, None, None, "Longitude's Docstring")
timezone = property(getTimezone, None, None, "Timezone's Docstring")
def __eq__(self, other):
return self.latitude == other.latitude and self.longitude == other.longitude

View File

@ -1,52 +0,0 @@
#!/usr/bin/env python
__author__ = "Abhinav Sarkar"
__version__ = "0.1"
__license__ = "GNU Lesser General Public License"
import types
class Xml2Dict (dict):
def __init__(self, parent):
self.update(dict([('@' + item[0], item[1]) for item in parent.items()]))
for child in parent:
# print child.tag
if child:
if not child.tag in self:
self[child.tag] = Xml2Dict(child)
else:
if type(self[child.tag]) != types.ListType:
self[child.tag] = [self[child.tag]]
self[child.tag].append(Xml2Dict(child))
if not child and child.items():
if not child.tag in self:
self[child.tag] = dict([('@' + item[0], item[1]) for item in child.items()])
else:
if type(self[child.tag]) != types.ListType:
self[child.tag] = [self[child.tag]]
self[child.tag].append(
dict([('@' + item[0], item[1]) for item in child.items()])
)
if child.text:
if not child.tag in self:
self[child.tag] = child.text.strip() or None
elif child.text.strip():
if type(self[child.tag]) != types.ListType:
flag = False
for e in self[child.tag].keys():
if e.startswith('@'):
flag = True
if not flag:
self[child.tag] = [self[child.tag]]
self[child.tag][0].update({'text': child.text.strip()})
else:
self[child.tag].update({'text': child.text.strip()})
else:
self[child.tag][-1].update({'text': child.text.strip()})
if not child.tag in self:
self[child.tag] = None