From 2d11699df0feec62097303165ce210df9ac26420 Mon Sep 17 00:00:00 2001 From: hugovk Date: Tue, 4 Mar 2014 15:46:00 +0200 Subject: [PATCH] Implement firs Geo function, for #44 --- pylast.py | 63 ++++++++++++++++++++++++++++++++++++++++++-------- test_pylast.py | 40 ++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/pylast.py b/pylast.py index 1a365d5..91b9bb6 100644 --- a/pylast.py +++ b/pylast.py @@ -374,6 +374,49 @@ class _Network(object): return seq + def get_geo_events(self, long=None, lat=None, location=None, distance=None, tag=None, festivalsonly=None, limit=None, cacheable=True): + """ + Returns all events in a specific location by country or city name. + Parameters: + long (Optional) : Specifies a longitude value to retrieve events for (service returns nearby events by default) + lat (Optional) : Specifies a latitude value to retrieve events for (service returns nearby events by default) + location (Optional) : Specifies a location to retrieve events for (service returns nearby events by default) + distance (Optional) : Find events within a specified radius (in kilometres) + tag (Optional) : Specifies a tag to filter by. + festivalsonly[0|1] (Optional) : Whether only festivals should be returned, or all events. + limit (Optional) : The number of results to fetch per page. Defaults to 10. + (page number not implemented) + """ + + params = {} + + if long: params["long"] = long + if lat: params["lat"] = lat + if location: params["location"] = location + if limit: params["limit"] = limit + if distance: params["distance"] = distance + if tag: params["tag"] = tag + if festivalsonly: + params["festivalsonly"] = 1 + elif not festivalsonly: + params["festivalsonly"] = 0 + + doc = _Request(self, "geo.getEvents", params).execute(cacheable) + + return _extract_events_from_doc(doc, self) + + # TODO? + # geo.getMetroArtistChart + # geo.getMetroHypeArtistChart + # geo.getMetroHypeTrackChart + # geo.getMetroTrackChart + # geo.getMetroUniqueArtistChart + # geo.getMetroUniqueTrackChart + # geo.getMetroWeeklyChartlist + # geo.getMetros + # geo.getTopArtists + # geo.getTopTracks + def enable_proxy(self, host, port): """Enable a default web proxy""" @@ -1040,12 +1083,6 @@ class _BaseObject(object): return hash(self.network) + \ hash(str(type(self)) + "".join(list(self._get_params().keys()) + list(values)).lower()) - def _extract_events_from_doc(self, doc): - events = [] - for node in doc.getElementsByTagName("event"): - events.append(Event(_extract(node, "id"), self.network)) - return events - def _extract_cdata_from_request(self, method_name, tag_name, params): doc = self._request(method_name, True, params) @@ -1519,7 +1556,7 @@ class Artist(_BaseObject, _Taggable): doc = self._request('artist.getEvents', True) - return self._extract_events_from_doc(doc) + return _extract_events_from_doc(doc, self.network) def get_similar(self, limit = None): """Returns the similar artists on the network.""" @@ -2964,7 +3001,7 @@ class User(_BaseObject): doc = self._request('user.getEvents', True) - return self._extract_events_from_doc(doc) + return _extract_events_from_doc(doc, self.network) def get_artist_tracks(self, artist, cacheable=False): """Get a list of tracks by a given artist scrobbled by this user, including scrobble time.""" @@ -3676,14 +3713,14 @@ class Venue(_BaseObject): doc = self._request("venue.getEvents", True) - return self._extract_events_from_doc(doc) + return _extract_events_from_doc(doc, self.network) def get_past_events(self): """Returns the past events held in this venue.""" doc = self._request("venue.getEvents", True) - return self._extract_events_from_doc(doc) + return _extract_events_from_doc(doc, self.network) def md5(text): """Returns the md5 hash of a string.""" @@ -3818,6 +3855,12 @@ def _extract_all(node, name, limit_count = None): return seq +def _extract_events_from_doc(doc, network): + events = [] + for node in doc.getElementsByTagName("event"): + events.append(Event(_extract(node, "id"), network)) + return events + def _url_safe(text): """Does all kinds of tricks on a text to make it safe to use in a url.""" diff --git a/test_pylast.py b/test_pylast.py index d2e03a2..4527387 100755 --- a/test_pylast.py +++ b/test_pylast.py @@ -346,7 +346,7 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreater(len(tags), 0) - self.assertTrue(type(tags[0]) == pylast.TopItem) + self.assertEqual(type(tags[0]), pylast.TopItem) def test_album_tags_are_topitems(self): @@ -358,7 +358,7 @@ class TestPyLast(unittest.TestCase): # Assert self.assertGreater(len(tags), 0) - self.assertTrue(type(tags[0]) == pylast.TopItem) + self.assertEqual(type(tags[0]), pylast.TopItem) def helper_is_thing_hashable(self, thing): @@ -860,6 +860,42 @@ class TestPyLast(unittest.TestCase): self.helper_validate_cacheable(lastfm_user, "get_shouts") + def test_geo_get_events_in_location(self): + # Arrange + # Act + events = self.network.get_geo_events(location = "London", tag = "blues", limit = 1) + + # Assert + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(type(event), pylast.Event) + self.assertEqual(event.get_venue().location['city'], "London") + + + def test_geo_get_events_in_latlong(self): + # Arrange + # Act + events = self.network.get_geo_events(lat = 40.67, long = -73.94, distance = 5, limit = 1) + + # Assert + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(type(event), pylast.Event) + self.assertEqual(event.get_venue().location['city'], "New York") + + + def test_geo_get_events_festival(self): + # Arrange + # Act + events = self.network.get_geo_events(location = "Reading", festivalsonly = True, limit = 1) + + # Assert + self.assertEqual(len(events), 1) + event = events[0] + self.assertEqual(type(event), pylast.Event) + self.assertEqual(event.get_venue().location['city'], "Reading") + + if __name__ == '__main__': # For quick testing of a single case (eg. test = "test_scrobble")