Package lastfm :: Module album

[hide private]
[frames] | no frames]

# Source Code for Module lastfm.album

      1  #!/usr/bin/env python
      2  """Module for calling Album related last.fm web services API methods"""
      3
      4  __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
      5  __version__ = "0.2"
      6  __license__ = "GNU Lesser General Public License"
      7
      8  from lastfm.base import LastfmBase
      9  from lastfm.mixins import Cacheable, Searchable, Taggable
     10  from lastfm.decorators import cached_property, top_property
     11
     12 -class Album(LastfmBase, Cacheable, Searchable, Taggable):
     13      """A class representing an album."""
     14 -    def init(self,
     15                   api,
     16                   name = None,
     17                   artist = None,
     18                   id = None,
     19                   mbid = None,
     20                   url = None,
     21                   release_date = None,
     22                   image = None,
     23                   stats = None,
     24                   top_tags = None,
     25                   streamable = None,
     26                   subject = None):
     27          """
     28          Create an Album object by providing all the data related to it.
     29
     30          @param api:             an instance of L{Api}
     31          @type api:              L{Api}
     32          @param name:            the album name
     33          @type name:             L{str}
     34          @param artist:          the album artist name
     35          @type artist:           L{Artist}
     36          @param id:              the album ID
     37          @type id:               L{str}
     38          @param mbid:            MBID of the album
     39          @type mbid:             L{str}
     40          @param url:             URL of the album on last.fm
     41          @type url:              L{str}
     42          @param release_date:    release date of the album
     43          @type release_date:     C{datetime.datetime}
     44          @param image:           the cover images of the album in various sizes
     45          @type image:            L{dict}
     46          @param stats:           the album statistics
     47          @type stats:            L{Stats}
     48          @param top_tags:        top tags for the album
     49          @type top_tags:         L{list} of L{Tag}
     50          @param streamable:      flag indicating if the album is streamable from last.fm
     51          @type streamable:       L{bool}
     52          @param subject:         the subject to which this instance belongs to
     53          @type subject:          L{User} OR L{Artist} OR L{Tag} OR L{WeeklyChart}
     54
     55          @raise InvalidParametersError: If an instance of L{Api} is not provided as the first
     56                                         parameter then an Exception is raised.
     57          """
     58          if not isinstance(api, Api):
     59              raise InvalidParametersError("api reference must be supplied as an argument")
     60          Taggable.init(self, api)
     61          self._api = api
     62          self._name = name
     63          self._artist = artist
     64          self._id = id
     65          self._mbid = mbid
     66          self._url = url
     67          self._release_date = release_date
     68          self._image = image
     69          self._stats = stats and Stats(
     70                               subject = self,
     71                               listeners = stats.listeners,
     72                               playcount = stats.playcount,
     73                               match = stats.match,
     74                               rank = stats.rank
     75                              )
     76          self._top_tags = top_tags
     77          self._streamable = streamable
     78          self._subject = subject
     79
     80      @property
     81 -    def name(self):
     82          """
     83          name of the album
     84          @rtype: L{str}
     85          """
     86          return self._name
     87
     88      @property
     89 -    def artist(self):
     90          """
     91          artist of the album
     92          @rtype: L{Artist}
     93          """
     94          return self._artist
     95
     96      @property
     97 -    def id(self):
     98          """
     99          id of the album
    100          @rtype: L{int}
    101          """
    102          if self._id is None:
    103              self._fill_info()
    104          return self._id
    105
    106      @property
    107 -    def mbid(self):
    108          """
    109          MBID of the album
    110          @rtype: L{str}
    111          """
    112          if self._mbid is None:
    113              self._fill_info()
    114          return self._mbid
    115
    116      @property
    117 -    def url(self):
    118          """
    119          url of the album's page
    120          @rtype: L{str}
    121          """
    122          if self._url is None:
    123              self._fill_info()
    124          return self._url
    125
    126      @property
    127 -    def release_date(self):
    128          """
    129          release date of the album
    130          @rtype: C{datetime.datetime}
    131          """
    132          if self._release_date is None:
    133              self._fill_info()
    134          return self._release_date
    135
    136      @property
    137 -    def image(self):
    138          """
    139          cover images of the album
    140          @rtype: L{dict}
    141          """
    142          if self._image is None:
    143              self._fill_info()
    144          return self._image
    145
    146      @property
    147 -    def stats(self):
    148          """
    149          stats related to the album
    150          @rtype: L{Stats}
    151          """
    152          if self._stats is None:
    153              self._fill_info()
    154          return self._stats
    155
    156      @property
    157 -    def streamable(self):
    158          """
    159          is the album streamable on last.fm
    160          @rtype: L{bool}
    161          """
    162          return self._streamable
    163
    164      @cached_property
    165 -    def top_tags(self):
    166          """
    167          top tags for the album
    168          @rtype: L{list} of L{Tag}
    169          """
    170          params = {'method': 'album.getInfo'}
    171          if self.artist and self.name:
    172              params.update({'artist': self.artist.name, 'album': self.name})
    173          elif self.mbid:
    174              params.update({'mbid': self.mbid})
    175          data = self._api._fetch_data(params).find('album')
    176          return [
    177                  Tag(
    178                      self._api,
    179                      subject = self,
    180                      name = t.findtext('name'),
    181                      url = t.findtext('url')
    182                      )
    183                  for t in data.findall('toptags/tag')
    184                  ]
    185
    186      @top_property("top_tags")
    187 -    def top_tag(self):
    188          """
    189          top tag for the album
    190          @rtype: L{Tag}
    191          """
    192          pass
    193
    194      @cached_property
    195 -    def playlist(self):
    196          """
    197          playlist for the album
    198          @rtype: L{Playlist}
    199          """
    200          return Playlist.fetch(self._api, "lastfm://playlist/album/%s" % self.id)
    201
    202      @staticmethod
    203 -    def get_info(api, artist = None, album = None, mbid = None):
    204          """
    205          Get the data for the album.
    206
    207          @param api:      an instance of L{Api}
    208          @type api:       L{Api}
    209          @param artist:   the album artist name
    210          @type artist:    L{str} OR L{Artist}
    211          @param album:    the album name
    212          @type album:     L{str}
    213          @param mbid:     MBID of the album
    214          @type mbid:      L{str}
    215
    216          @return:         an Album object corresponding the provided album name
    217          @rtype:          L{Album}
    218
    219          @raise lastfm.InvalidParametersError: Either album and artist parameters or
    220                                                mbid parameter has to be provided.
    221                                                Otherwise exception is raised.
    222
    223          @note: Use the L{Api.get_album} method instead of using this method directly.
    224          """
    225          data = Album._fetch_data(api, artist, album, mbid)
    226          a = Album(
    227                    api,
    228                    name = data.findtext('name'),
    229                    artist = Artist(
    230                                    api,
    231                                    name = data.findtext('artist'),
    232                                    ),
    233                    )
    234          a._fill_info()
    235          return a
    236
    237 -    def _default_params(self, extra_params = {}):
    238          if not (self.artist and self.name):
    239              raise InvalidParametersError("artist and album have to be provided.")
    240          params = {'artist': self.artist.name, 'album': self.name}
    241          params.update(extra_params)
    242          return params
    243
    244      @staticmethod
    245 -    def _fetch_data(api,
    246                  artist = None,
    247                  album = None,
    248                  mbid = None):
    249          params = {'method': 'album.getInfo'}
    250          if not ((artist and album) or mbid):
    251              raise InvalidParametersError("either (artist and album) or mbid has to be given as argument.")
    252          if artist and album:
    253              params.update({'artist': artist, 'album': album})
    254          elif mbid:
    255              params.update({'mbid': mbid})
    256          return api._fetch_data(params).find('album')
    257
    258 -    def _fill_info(self):
    259          data = Album._fetch_data(self._api, self.artist.name, self.name)
    260          self._id = int(data.findtext('id'))
    261          self._mbid = data.findtext('mbid')
    262          self._url = data.findtext('url')
    263          self._release_date = data.findtext('releasedate') and data.findtext('releasedate').strip() and \
    264                              datetime(*(time.strptime(data.findtext('releasedate').strip(), '%d %b %Y, 00:00')[0:6]))
    265          self._image = dict([(i.get('size'), i.text) for i in data.findall('image')])
    266          if not self._stats:
    267              self._stats = Stats(
    268                         subject = self,
    269                         listeners = int(data.findtext('listeners')),
    270                         playcount = int(data.findtext('playcount')),
    271                         )
    272          self._top_tags = [
    273                      Tag(
    274                          self._api,
    275                          subject = self,
    276                          name = t.findtext('name'),
    277                          url = t.findtext('url')
    278                          )
    279                      for t in data.findall('toptags/tag')
    280                      ]
    281
    282      @staticmethod
    283 -    def _search_yield_func(api, album):
    284          return Album(
    285                        api,
    286                        name = album.findtext('name'),
    287                        artist = Artist(
    288                                        api,
    289                                        name = album.findtext('artist')
    290                                        ),
    291                        id = int(album.findtext('id')),
    292                        url = album.findtext('url'),
    293                        image = dict([(i.get('size'), i.text) for i in album.findall('image')]),
    294                        streamable = (album.findtext('streamable') == '1'),
    295                        )
    296
    297      @staticmethod
    298 -    def _hash_func(*args, **kwds):
    299          try:
    300              return hash("%s%s" % (kwds['name'], hash(kwds['artist'])))
    301          except KeyError:
    302              raise InvalidParametersError("name and artist have to be provided for hashing")
    303
    304 -    def __hash__(self):
    305          return self.__class__._hash_func(name = self.name, artist = self.artist)
    306
    307 -    def __eq__(self, other):
    308          if self.id and other.id:
    309              return self.id == other.id
    310          if self.mbid and other.mbid:
    311              return self.mbid == other.mbid
    312          if self.url and other.url:
    313              return self.url == other.url
    314          if (self.name and self.artist) and (other.name and other.artist):
    315              return (self.name == other.name) and (self.artist == other.artist)
    316          return super(Album, self).__eq__(other)
    317
    318 -    def __lt__(self, other):
    319          return self.name < other.name
    320
    321 -    def __repr__(self):
    322          return "<lastfm.Album: '%s' by %s>" % (self.name, self.artist.name)
    323
    324
    325  from datetime import datetime
    326  import time
    327
    328  from lastfm.api import Api
    329  from lastfm.artist import Artist
    330  from lastfm.error import InvalidParametersError
    331  from lastfm.playlist import Playlist
    332  from lastfm.stats import Stats
    333  from lastfm.tag import Tag
    334