232 lines
9.4 KiB
Python
232 lines
9.4 KiB
Python
#!/usr/bin/env python
|
|
"""Module for calling Event related last.fm web services API methods"""
|
|
|
|
__author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
|
|
__version__ = "0.2"
|
|
__license__ = "GNU Lesser General Public License"
|
|
__package__ = "lastfm"
|
|
|
|
from lastfm.base import LastfmBase
|
|
from lastfm.mixin import mixin
|
|
|
|
@mixin("crawlable", "shoutable", "sharable",
|
|
"cacheable", "property_adder")
|
|
class Event(LastfmBase):
|
|
"""A class representing an event."""
|
|
STATUS_ATTENDING = 0
|
|
STATUS_MAYBE = 1
|
|
STATUS_NOT = 2
|
|
|
|
class Meta(object):
|
|
properties = ["id", "title", "artists",
|
|
"headliner", "venue", "start_date",
|
|
"description", "image", "url",
|
|
"stats", "tag"]
|
|
|
|
def init(self, api, **kwargs):
|
|
"""
|
|
Create an Event object by providing all the data related to it.
|
|
|
|
@param api: an instance of L{Api}
|
|
@type api: L{Api}
|
|
@param id: ID of the event
|
|
@type id: L{int}
|
|
@param title: title of the event
|
|
@type title: L{str}
|
|
@param artists: artists performing in the event
|
|
@type artists: L{list} of L{Artist}
|
|
@param headliner: headliner artist of the event
|
|
@type headliner: L{Artist}
|
|
@param venue: venue of the event
|
|
@type venue: L{Venue}
|
|
@param start_date: start date and time of the event
|
|
@type start_date: C{datetime.datetime}
|
|
@param description: description of the event
|
|
@type description: L{str}
|
|
@param image: poster images of the event in various sizes
|
|
@type image: L{dict}
|
|
@param url: URL of the event on last.fm
|
|
@type url: L{str}
|
|
@param stats: the statistics of the event (attendance and no. of reviews)
|
|
@type stats: L{Stats}
|
|
@param tag: tag for the event
|
|
@type tag: L{str}
|
|
"""
|
|
if not isinstance(api, Api):
|
|
raise InvalidParametersError("api reference must be supplied as an argument")
|
|
|
|
self._api = api
|
|
super(Event, self).init(**kwargs)
|
|
self._stats = hasattr(self, "_stats") and Stats(
|
|
subject = self,
|
|
attendance = self._stats.attendance,
|
|
reviews = self._stats.reviews
|
|
) or None
|
|
|
|
def attend(self, status = STATUS_ATTENDING):
|
|
"""
|
|
Set the attendance status of the authenticated user for this event.
|
|
|
|
@param status: attendance status, should be one of:
|
|
L{Event.STATUS_ATTENDING} OR L{Event.STATUS_MAYBE} OR L{Event.STATUS_NOT}
|
|
@type status: L{int}
|
|
|
|
@raise InvalidParametersError: If status parameters is not one of the allowed values
|
|
then an exception is raised.
|
|
"""
|
|
if status not in [Event.STATUS_ATTENDING, Event.STATUS_MAYBE, Event.STATUS_NOT]:
|
|
InvalidParametersError("status has to be 0, 1 or 2")
|
|
params = self._default_params({'method': 'event.attend', 'status': status})
|
|
self._api._post_data(params)
|
|
|
|
@staticmethod
|
|
def get_info(api, event):
|
|
"""
|
|
Get the data for the event.
|
|
|
|
@param api: an instance of L{Api}
|
|
@type api: L{Api}
|
|
@param event: ID of the event
|
|
@type event: L{int}
|
|
|
|
@return: an Event object corresponding to the provided event id
|
|
@rtype: L{Event}
|
|
|
|
@note: Use the L{Api.get_event} method instead of using this method directly.
|
|
"""
|
|
params = {'method': 'event.getInfo', 'event': event}
|
|
data = api._fetch_data(params).find('event')
|
|
return Event.create_from_data(api, data)
|
|
|
|
@staticmethod
|
|
def create_from_data(api, data):
|
|
"""
|
|
Create the Event object from the provided XML element.
|
|
|
|
@param api: an instance of L{Api}
|
|
@type api: L{Api}
|
|
@param data: XML element
|
|
@type data: C{xml.etree.ElementTree.Element}
|
|
|
|
@return: an Event object corresponding to the provided XML element
|
|
@rtype: L{Event}
|
|
|
|
@note: Use the L{Api.get_event} method instead of using this method directly.
|
|
"""
|
|
start_date = None
|
|
|
|
if data.findtext('startTime') is not None:
|
|
start_date = datetime(*(
|
|
time.strptime(
|
|
"%s %s" % (
|
|
data.findtext('startDate').strip(),
|
|
data.findtext('startTime').strip()
|
|
),
|
|
'%a, %d %b %Y %H:%M'
|
|
)[0:6])
|
|
)
|
|
else:
|
|
try:
|
|
start_date = datetime(*(
|
|
time.strptime(
|
|
data.findtext('startDate').strip(),
|
|
'%a, %d %b %Y %H:%M:%S'
|
|
)[0:6])
|
|
)
|
|
except ValueError:
|
|
try:
|
|
start_date = datetime(*(
|
|
time.strptime(
|
|
data.findtext('startDate').strip(),
|
|
'%a, %d %b %Y'
|
|
)[0:6])
|
|
)
|
|
except ValueError:
|
|
pass
|
|
|
|
latitude = data.findtext('venue/location/{%s}point/{%s}lat' % ((Location.XMLNS,)*2))
|
|
longitude = data.findtext('venue/location/{%s}point/{%s}long' % ((Location.XMLNS,)*2))
|
|
|
|
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 = Artist(api, name = data.findtext('artists/headliner')),
|
|
venue = Venue(
|
|
api,
|
|
id = int(data.findtext('venue/url').split('/')[-1]),
|
|
name = data.findtext('venue/name'),
|
|
location = Location(
|
|
api,
|
|
city = data.findtext('venue/location/city'),
|
|
country = Country(
|
|
api,
|
|
name = data.findtext('venue/location/country')
|
|
),
|
|
street = data.findtext('venue/location/street'),
|
|
postal_code = data.findtext('venue/location/postalcode'),
|
|
latitude = (latitude.strip()!= '') and float(latitude) or None,
|
|
longitude = (longitude.strip()!= '') and float(longitude) or None,
|
|
#timezone = data.findtext('venue/location/timezone')
|
|
),
|
|
url = data.findtext('venue/url')
|
|
),
|
|
start_date = start_date,
|
|
description = data.findtext('description'),
|
|
image = dict([(i.get('size'), i.text) for i in data.findall('image')]),
|
|
url = data.findtext('url'),
|
|
stats = Stats(
|
|
subject = int(data.findtext('id')),
|
|
attendance = int(data.findtext('attendance')),
|
|
reviews = int(data.findtext('reviews')),
|
|
),
|
|
tag = data.findtext('tag')
|
|
)
|
|
|
|
@staticmethod
|
|
def _get_all(seed_event):
|
|
def gen():
|
|
for artist in Artist.get_all(seed_event.artists[0]):
|
|
for event in artist.events:
|
|
yield event
|
|
|
|
return (seed_event, ['id'], lambda api, hsh: gen())
|
|
|
|
def _default_params(self, extra_params = None):
|
|
if not self.id:
|
|
raise InvalidParametersError("id has to be provided.")
|
|
params = {'event': self.id}
|
|
if extra_params is not None:
|
|
params.update(extra_params)
|
|
return params
|
|
|
|
@staticmethod
|
|
def _hash_func(*args, **kwds):
|
|
try:
|
|
return hash(kwds['id'])
|
|
except KeyError:
|
|
raise InvalidParametersError("id has to be provided for hashing")
|
|
|
|
def __hash__(self):
|
|
return Event._hash_func(id = self.id)
|
|
|
|
def __eq__(self, other):
|
|
return self.id == other.id
|
|
|
|
def __lt__(self, other):
|
|
return self.start_date < other.start_date
|
|
|
|
def __repr__(self):
|
|
return "<lastfm.Event: %s at %s on %s>" % (self.title, self.venue.name, self.start_date.strftime("%x"))
|
|
|
|
from datetime import datetime
|
|
import time
|
|
|
|
from lastfm.api import Api
|
|
from lastfm.artist import Artist
|
|
from lastfm.error import InvalidParametersError
|
|
from lastfm.geo import Location, Country
|
|
from lastfm.stats import Stats
|
|
from lastfm.venue import Venue
|