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