Package lastfm :: Module geo

[hide private]
[frames] | no frames]

# Source Code for Module lastfm.geo

      1  #!/usr/bin/env python
      2
      3  __author__ = "Abhinav Sarkar <abhinav@abhinavsarkar.net>"
      4  __version__ = "0.2"
      5  __license__ = "GNU Lesser General Public License"
      6
      7  from lastfm.base import LastfmBase
      8  from lastfm.mixins import Cacheable
      9  from lastfm.lazylist import lazylist
     10  from lastfm.decorators import cached_property, top_property
     11
     12 -class Geo(object):
     13      """A class representing an geographic location."""
     14      @staticmethod
     15 -    def get_events(api,
     16                    location,
     17                    latitude = None,
     18                    longitude = None,
     19                    distance = None):
     20          params = {'method': 'geo.getEvents', 'location': location}
     21          if distance is not None:
     22              params.update({'distance': distance})
     23
     24          if latitude is not None and longitude is not None:
     25              params.update({'latitude': latitude, 'longitude': longitude})
     26
     27          @lazylist
     28          def gen(lst):
     29              data = api._fetch_data(params).find('events')
     30              total_pages = int(data.attrib['totalpages'])
     31
     32              @lazylist
     33              def gen2(lst, data):
     34                  for e in data.findall('event'):
     35                      yield Event.create_from_data(api, e)
     36
     37              for e in gen2(data):
     38                  yield e
     39
     40              for page in xrange(2, total_pages+1):
     41                  params.update({'page': page})
     42                  data = api._fetch_data(params).find('events')
     43                  for e in gen2(data):
     44                      yield e
     45          return gen()
     46
     47      @staticmethod
     48 -    def get_top_artists(api, country):
     49          params = {'method': 'geo.getTopArtists', 'country': country}
     50          data = api._fetch_data(params).find('topartists')
     51          return [
     52                  Artist(
     53                         api,
     54                         name = a.findtext('name'),
     55                         mbid = a.findtext('mbid'),
     56                         stats = Stats(
     57                                       subject = a.findtext('name'),
     58                                       rank = int(a.attrib['rank']),
     59                                       playcount = int(a.findtext('playcount'))
     60                                       ),
     61                         url = 'http://' + a.findtext('url'),
     62                         image = {'large': a.findtext('image')}
     63                         )
     64                  for a in data.findall('artist')
     65                  ]
     66
     67      @staticmethod
     68 -    def get_top_tracks(api, country, location = None):
     69          params = {'method': 'geo.getTopTracks', 'country': country}
     70          if location is not None:
     71              params.update({'location': location})
     72
     73          data = api._fetch_data(params).find('toptracks')
     74          return [
     75                  Track(
     76                         api,
     77                         name = t.findtext('name'),
     78                         mbid = t.findtext('mbid'),
     79                         artist = Artist(
     80                                         api,
     81                                         name = t.findtext('artist/name'),
     82                                         mbid = t.findtext('artist/mbid'),
     83                                         url = t.findtext('artist/url')
     84                                         ),
     85                         stats = Stats(
     86                                       subject = t.findtext('name'),
     87                                       rank = int(t.attrib['rank']),
     88                                       playcount = int(t.findtext('playcount'))
     89                                       ),
     90                         streamable = (t.findtext('streamable') == '1'),
     91                         full_track = (t.find('streamable').attrib['fulltrack'] == '1'),
     92                         url = 'http://' + t.findtext('url'),
     93                         image = {'large': t.findtext('image')}
     94                         )
     95                  for t in data.findall('track')
     96                  ]
     97
     98 -class Location(LastfmBase, Cacheable):
     99      """A class representing a location of an event"""
    100      XMLNS = "http://www.w3.org/2003/01/geo/wgs84_pos#"
    101
    102 -    def init(self,
    103                   api,
    104                   city = None,
    105                   country = None,
    106                   street = None,
    107                   postal_code = None,
    108                   latitude = None,
    109                   longitude = None,
    110                   timezone = None,
    111                   **kwargs):
    112          if not isinstance(api, Api):
    113              raise InvalidParametersError("api reference must be supplied as an argument")
    114          self._api = api
    115          self._city = city
    116          self._country = country
    117          self._street = street
    118          self._postal_code = postal_code
    119          self._latitude = latitude
    120          self._longitude = longitude
    121          self._timezone = timezone
    122
    123      @property
    124 -    def city(self):
    125          """city in which the location is situated"""
    126          return self._city
    127
    128      @property
    129 -    def country(self):
    130          """country in which the location is situated"""
    131          return self._country
    132
    133      @property
    134 -    def street(self):
    135          """street in which the location is situated"""
    136          return self._street
    137
    138      @property
    139 -    def postal_code(self):
    140          """postal code of the location"""
    141          return self._postal_code
    142
    143      @property
    144 -    def latitude(self):
    145          """latitude of the location"""
    146          return self._latitude
    147
    148      @property
    149 -    def longitude(self):
    150          """longitude of the location"""
    151          return self._longitude
    152
    153      @property
    154 -    def timezone(self):
    155          """timezone in which the location is situated"""
    156          return self._timezone
    157
    158      @cached_property
    159 -    def top_tracks(self):
    160          """top tracks of the location"""
    161          if self.country is None or self.city is None:
    162              raise InvalidParametersError("country and city of this location are required for calling this method")
    163          return Geo.get_top_tracks(self._api, self.country.name, self.city)
    164
    165      @top_property("top_tracks")
    166 -    def top_track(self):
    167          """top track of the location"""
    168          pass
    169
    170 -    def get_events(self,
    171                    distance = None):
    172          return Geo.get_events(self._api,
    173                               self.city,
    174                               self.latitude,
    175                               self.longitude,
    176                               distance)
    177
    178      @cached_property
    179 -    def events(self):
    180          """events taking place at/around the location"""
    181          return self.get_events()
    182
    183      @staticmethod
    184 -    def _hash_func(*args, **kwds):
    185          try:
    186              return hash("latlong%s%s" % (kwds['latitude'], kwds['longitude']))
    187          except KeyError:
    188              try:
    189                  return hash("name%s" % kwds['city'])
    190              except KeyError:
    191                  raise InvalidParametersError("either latitude and longitude or city has to be provided for hashing")
    192
    193 -    def __hash__(self):
    194          if not self.city:
    195              return self.__class__._hash_func(
    196                                             latitude = self.latitude,
    197                                             longitude = self.longitude)
    198          else:
    199              return self.__class__._hash_func(name = self.city)
    200
    201 -    def __eq__(self, other):
    202          return self.latitude == other.latitude and self.longitude == other.longitude
    203
    204 -    def __lt__(self, other):
    205          if self.country != other.country:
    206              return self.country < other.country
    207          else:
    208              return self.city < other.city
    209
    210 -    def __repr__(self):
    211          if self.city is None:
    212              return "<lastfm.geo.Location: (%s, %s)>" % (self.latitude, self.longitude)
    213          else:
    214              return "<lastfm.geo.Location: %s>" % self.city
    215
    216 -class Country(LastfmBase, Cacheable):
    217      """A class representing a country."""
    218      ISO_CODES = {
    219           'AD': 'Andorra',
    220           'AE': 'United Arab Emirates',
    221           'AF': 'Afghanistan',
    222           'AG': 'Antigua and Barbuda',
    223           'AI': 'Anguilla',
    224           'AL': 'Albania',
    225           'AM': 'Armenia',
    226           'AN': 'Netherlands Antilles',
    227           'AO': 'Angola',
    228           'AQ': 'Antarctica',
    229           'AR': 'Argentina',
    230           'AS': 'American Samoa',
    231           'AT': 'Austria',
    232           'AU': 'Australia',
    233           'AW': 'Aruba',
    234           'AX': 'land Islands',
    235           'AZ': 'Azerbaijan',
    236           'BA': 'Bosnia and Herzegovina',
    237           'BB': 'Barbados',
    238           'BD': 'Bangladesh',
    239           'BE': 'Belgium',
    240           'BF': 'Burkina Faso',
    241           'BG': 'Bulgaria',
    242           'BH': 'Bahrain',
    243           'BI': 'Burundi',
    244           'BJ': 'Benin',
    245           'BL': 'Saint Barthlemy',
    246           'BM': 'Bermuda',
    247           'BN': 'Brunei Darussalam',
    248           'BO': 'Bolivia',
    249           'BR': 'Brazil',
    250           'BS': 'Bahamas',
    251           'BT': 'Bhutan',
    252           'BV': 'Bouvet Island',
    253           'BW': 'Botswana',
    254           'BY': 'Belarus',
    255           'BZ': 'Belize',
    256           'CA': 'Canada',
    257           'CC': 'Cocos (Keeling) Islands',
    258           'CD': 'Congo, The Democratic Republic of the',
    259           'CF': 'Central African Republic',
    260           'CG': 'Congo',
    261           'CH': 'Switzerland',
    262           'CI': "Cte d'Ivoire",
    263           'CK': 'Cook Islands',
    264           'CL': 'Chile',
    265           'CM': 'Cameroon',
    266           'CN': 'China',
    267           'CO': 'Colombia',
    268           'CR': 'Costa Rica',
    269           'CU': 'Cuba',
    270           'CV': 'Cape Verde',
    271           'CX': 'Christmas Island',
    272           'CY': 'Cyprus',
    273           'CZ': 'Czech Republic',
    274           'DE': 'Germany',
    275           'DJ': 'Djibouti',
    276           'DK': 'Denmark',
    277           'DM': 'Dominica',
    278           'DO': 'Dominican Republic',
    279           'DZ': 'Algeria',
    280           'EC': 'Ecuador',
    281           'EE': 'Estonia',
    282           'EG': 'Egypt',
    283           'EH': 'Western Sahara',
    284           'ER': 'Eritrea',
    285           'ES': 'Spain',
    286           'ET': 'Ethiopia',
    287           'FI': 'Finland',
    288           'FJ': 'Fiji',
    289           'FK': 'Falkland Islands (Malvinas)',
    290           'FM': 'Micronesia, Federated States of',
    291           'FO': 'Faroe Islands',
    292           'FR': 'France',
    293           'GA': 'Gabon',
    294           'GB': 'United Kingdom',
    295           'GD': 'Grenada',
    296           'GE': 'Georgia',
    297           'GF': 'French Guiana',
    298           'GG': 'Guernsey',
    299           'GH': 'Ghana',
    300           'GI': 'Gibraltar',
    301           'GL': 'Greenland',
    302           'GM': 'Gambia',
    303           'GN': 'Guinea',
    304           'GP': 'Guadeloupe',
    305           'GQ': 'Equatorial Guinea',
    306           'GR': 'Greece',
    307           'GS': 'South Georgia and the South Sandwich Islands',
    308           'GT': 'Guatemala',
    309           'GU': 'Guam',
    310           'GW': 'Guinea-Bissau',
    311           'GY': 'Guyana',
    312           'HK': 'Hong Kong',
    313           'HM': 'Heard Island and McDonald Islands',
    314           'HN': 'Honduras',
    315           'HR': 'Croatia',
    316           'HT': 'Haiti',
    317           'HU': 'Hungary',
    318           'ID': 'Indonesia',
    319           'IE': 'Ireland',
    320           'IL': 'Israel',
    321           'IM': 'Isle of Man',
    322           'IN': 'India',
    323           'IO': 'British Indian Ocean Territory',
    324           'IQ': 'Iraq',
    325           'IR': 'Iran, Islamic Republic of',
    326           'IS': 'Iceland',
    327           'IT': 'Italy',
    328           'JE': 'Jersey',
    329           'JM': 'Jamaica',
    330           'JO': 'Jordan',
    331           'JP': 'Japan',
    332           'KE': 'Kenya',
    333           'KG': 'Kyrgyzstan',
    334           'KH': 'Cambodia',
    335           'KI': 'Kiribati',
    336           'KM': 'Comoros',
    337           'KN': 'Saint Kitts and Nevis',
    338           'KP': "Korea, Democratic People's Republic of",
    339           'KR': 'Korea, Republic of',
    340           'KW': 'Kuwait',
    341           'KY': 'Cayman Islands',
    342           'KZ': 'Kazakhstan',
    343           'LA': "Lao People's Democratic Republic",
    344           'LB': 'Lebanon',
    345           'LC': 'Saint Lucia',
    346           'LI': 'Liechtenstein',
    347           'LK': 'Sri Lanka',
    348           'LR': 'Liberia',
    349           'LS': 'Lesotho',
    350           'LT': 'Lithuania',
    351           'LU': 'Luxembourg',
    352           'LV': 'Latvia',
    353           'LY': 'Libyan Arab Jamahiriya',
    354           'MA': 'Morocco',
    355           'MC': 'Monaco',
    356           'MD': 'Moldova',
    357           'ME': 'Montenegro',
    358           'MF': 'Saint Martin',
    359           'MG': 'Madagascar',
    360           'MH': 'Marshall Islands',
    361           'MK': 'Macedonia, The Former Yugoslav Republic of',
    362           'ML': 'Mali',
    363           'MM': 'Myanmar',
    364           'MN': 'Mongolia',
    365           'MO': 'Macao',
    366           'MP': 'Northern Mariana Islands',
    367           'MQ': 'Martinique',
    368           'MR': 'Mauritania',
    369           'MS': 'Montserrat',
    370           'MT': 'Malta',
    371           'MU': 'Mauritius',
    372           'MV': 'Maldives',
    373           'MW': 'Malawi',
    374           'MX': 'Mexico',
    375           'MY': 'Malaysia',
    376           'MZ': 'Mozambique',
    377           'NA': 'Namibia',
    378           'NC': 'New Caledonia',
    379           'NE': 'Niger',
    380           'NF': 'Norfolk Island',
    381           'NG': 'Nigeria',
    382           'NI': 'Nicaragua',
    383           'NL': 'Netherlands',
    384           'NO': 'Norway',
    385           'NP': 'Nepal',
    386           'NR': 'Nauru',
    387           'NU': 'Niue',
    388           'NZ': 'New Zealand',
    389           'OM': 'Oman',
    390           'PA': 'Panama',
    391           'PE': 'Peru',
    392           'PF': 'French Polynesia',
    393           'PG': 'Papua New Guinea',
    394           'PH': 'Philippines',
    395           'PK': 'Pakistan',
    396           'PL': 'Poland',
    397           'PM': 'Saint Pierre and Miquelon',
    398           'PN': 'Pitcairn',
    399           'PR': 'Puerto Rico',
    400           'PS': 'Palestinian Territory, Occupied',
    401           'PT': 'Portugal',
    402           'PW': 'Palau',
    403           'PY': 'Paraguay',
    404           'QA': 'Qatar',
    405           'RE': 'Runion',
    406           'RO': 'Romania',
    407           'RS': 'Serbia',
    408           'RU': 'Russian Federation',
    409           'RW': 'Rwanda',
    410           'SA': 'Saudi Arabia',
    411           'SB': 'Solomon Islands',
    412           'SC': 'Seychelles',
    413           'SD': 'Sudan',
    414           'SE': 'Sweden',
    415           'SG': 'Singapore',
    416           'SH': 'Saint Helena',
    417           'SI': 'Slovenia',
    418           'SJ': 'Svalbard and Jan Mayen',
    419           'SK': 'Slovakia',
    420           'SL': 'Sierra Leone',
    421           'SM': 'San Marino',
    422           'SN': 'Senegal',
    423           'SO': 'Somalia',
    424           'SR': 'Suriname',
    425           'ST': 'Sao Tome and Principe',
    426           'SV': 'El Salvador',
    427           'SY': 'Syrian Arab Republic',
    428           'SZ': 'Swaziland',
    429           'TC': 'Turks and Caicos Islands',
    430           'TD': 'Chad',
    431           'TF': 'French Southern Territories',
    432           'TG': 'Togo',
    433           'TH': 'Thailand',
    434           'TJ': 'Tajikistan',
    435           'TK': 'Tokelau',
    436           'TL': 'Timor-Leste',
    437           'TM': 'Turkmenistan',
    438           'TN': 'Tunisia',
    439           'TO': 'Tonga',
    440           'TR': 'Turkey',
    441           'TT': 'Trinidad and Tobago',
    442           'TV': 'Tuvalu',
    443           'TW': 'Taiwan, Province of China',
    444           'TZ': 'Tanzania, United Republic of',
    445           'UA': 'Ukraine',
    446           'UG': 'Uganda',
    447           'UM': 'United States Minor Outlying Islands',
    448           'US': 'United States',
    449           'UY': 'Uruguay',
    450           'UZ': 'Uzbekistan',
    451           'VA': 'Holy See (Vatican City State)',
    452           'VC': 'Saint Vincent and the Grenadines',
    453           'VE': 'Venezuela',
    454           'VG': 'Virgin Islands, British',
    455           'VI': 'Virgin Islands, U.S.',
    456           'VN': 'Viet Nam',
    457           'VU': 'Vanuatu',
    458           'WF': 'Wallis and Futuna',
    459           'WS': 'Samoa',
    460           'YE': 'Yemen',
    461           'YT': 'Mayotte',
    462           'ZA': 'South Africa',
    463           'ZM': 'Zambia',
    464           'ZW': 'Zimbabwe'}
    465 -    def init(self,
    466                   api,
    467                   name = None,
    468                   **kwargs):
    469          if not isinstance(api, Api):
    470              raise InvalidParametersError("api reference must be supplied as an argument")
    471          self._api = api
    472          self._name = name
    473
    474      @property
    475 -    def name(self):
    476          """name of the country"""
    477          return self._name
    478
    479      @cached_property
    480 -    def top_artists(self):
    481          """top artists of the country"""
    482          return Geo.get_top_artists(self._api, self.name)
    483
    484      @top_property("top_artists")
    485 -    def top_artist(self):
    486          """top artist of the country"""
    487          pass
    488
    489 -    def get_top_tracks(self, location = None):
    490          return Geo.get_top_tracks(self._api, self.name, location)
    491
    492      @cached_property
    493 -    def top_tracks(self):
    494          """top tracks of the country"""
    495          return self.get_top_tracks()
    496
    497      @top_property("top_tracks")
    498 -    def top_track(self):
    499          """top track of the country"""
    500          pass
    501
    502      @cached_property
    503 -    def events(self):
    504          """events taking place at/around the location"""
    505          return Geo.get_events(self._api, self.name)
    506
    507      @staticmethod
    508 -    def _hash_func(*args, **kwds):
    509          try:
    510              return hash(kwds['name'].lower())
    511          except KeyError:
    512              raise InvalidParametersError("name has to be provided for hashing")
    513
    514 -    def __hash__(self):
    515          return self.__class__._hash_func(name = self.name)
    516
    517 -    def __eq__(self, other):
    518          return self.name.lower() == other.name.lower()
    519
    520 -    def __lt__(self, other):
    521          return self.name < other.name
    522
    523 -    def __repr__(self):
    524          return "<lastfm.geo.Country: %s>" % self.name
    525
    526  from lastfm.api import Api
    527  from lastfm.artist import Artist
    528  from lastfm.error import InvalidParametersError
    529  from lastfm.event import Event
    530  from lastfm.stats import Stats
    531  from lastfm.track import Track
    532