# HG changeset patch # User dclinton@b35c0ba3-1128-0410-9219-0b39014e361d # Date 1242504387 0 # Branch dclinton # Node ID 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b # Parent 737a5a105dcf4ef16aaec0c1550757900e3dfa64 Implemented the twitter Search API. Based partly on the hameed.u.khan changes in r145 and r151. diff -r 737a5a105dcf4ef16aaec0c1550757900e3dfa64 -r 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b CHANGES --- a/CHANGES Sat May 16 19:32:54 2009 +0000 +++ b/CHANGES Sat May 16 20:06:27 2009 +0000 @@ -1,3 +1,7 @@ +2009-05-16 + + Implemented Search API + 2009-05-10 Replaced hand-written Status, User, and DirectMessage objects with auto-generated Protocol Buffer objects diff -r 737a5a105dcf4ef16aaec0c1550757900e3dfa64 -r 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b README --- a/README Sat May 16 19:32:54 2009 +0000 +++ b/README Sat May 16 20:06:27 2009 +0000 @@ -163,7 +163,8 @@ Additional thanks to Pierre-Jean Coudert, Omar Kilani, Jodok Batlogg, edleaf,glen.tregoning, Brad Choate, Jim Cortez, Jason Lemoine, Thomas -Dyson, Robert Laquey, and the rest of the python-twitter mailing list. +Dyson, Robert Laquey, Hameedullah Khan, and the rest of the +python-twitter mailing list. ==License== diff -r 737a5a105dcf4ef16aaec0c1550757900e3dfa64 -r 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b testdata/search.json --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testdata/search.json Sat May 16 20:06:27 2009 +0000 @@ -0,0 +1,1 @@ +{"results":[{"text":"Real Life Twitter by College Humor: http:\/\/www.youtube.com\/user\/collegehumor","to_user_id":null,"from_user":"HuskyHustler","id":1819288528,"from_user_id":6731810,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/197889055\/andy_normal.jpg","created_at":"Sat, 16 May 2009 19:55:51 +0000"},{"text":"New TwittX Twitter Desktop Client","to_user_id":null,"from_user":"HeathersCool","id":1819288452,"from_user_id":15734090,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Sat, 16 May 2009 19:55:51 +0000"},{"text":"framtida f\u00f6rol\u00e4mpningar: men du har bara 5 followers p\u00e5 twitter!","to_user_id":null,"from_user":"alfnilsson","id":1819288441,"from_user_id":9505432,"iso_language_code":"sv","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/70991808\/ansikte_normal.jpg","created_at":"Sat, 16 May 2009 19:55:51 +0000"},{"text":"Maybe i have to twitter in english so everyone worldwide can see that i'm busy with nothing!?!?!?","to_user_id":null,"from_user":"hood1409","id":1819288385,"from_user_id":17403638,"iso_language_code":"en","source":"<a href="http:\/\/twitterfon.net\/">TwitterFon<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Sat, 16 May 2009 19:55:50 +0000"},{"text":"Twitter at age 104 http:\/\/tinyurl.com\/pdrd9h","to_user_id":null,"from_user":"tech_update","id":1819288179,"from_user_id":8362394,"iso_language_code":"en","source":"<a href="http:\/\/twitterfeed.com">twitterfeed<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/108461837\/Exquisite-binary_normal.png","created_at":"Sat, 16 May 2009 19:55:49 +0000"},{"text":"Utforsker twitter for f\u00f8rste gang.... Yeah, "n00b"...!","to_user_id":null,"from_user":"westlast","id":1819288162,"from_user_id":17405078,"iso_language_code":"no","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Sat, 16 May 2009 19:55:49 +0000"},{"text":"is trying to find more of her friends on twitter but can't. doing homework","to_user_id":null,"from_user":"PageMaxwell","id":1819288005,"from_user_id":17263492,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/static.twitter.com\/images\/default_profile_normal.png","created_at":"Sat, 16 May 2009 19:55:48 +0000"},{"text":"It costs me like 80p a time to use twitter on mobile web. Fuck off!","to_user_id":null,"from_user":"livxrpi","id":1819287997,"from_user_id":11274615,"iso_language_code":"en","source":"<a href="http:\/\/help.twitter.com\/index.php?pg=kb.page&id=75">txt<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/201683468\/DSC00322_normal.JPG","created_at":"Sat, 16 May 2009 19:55:48 +0000"},{"text":"How about this twitter...send me stuff on my phone and then i wont have to kill you","to_user_id":null,"from_user":"carmenritos","id":1819287994,"from_user_id":5666780,"iso_language_code":"en","source":"<a href="http:\/\/www.tweetdeck.com\/">TweetDeck<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/87713055\/102_0002_normal.JPG","created_at":"Sat, 16 May 2009 19:55:48 +0000"},{"text":"@RockShrimp Stupid twitter. Misunderstd u. Thought u meant bnl had something in Philly. Figured it out & said so but it never went thru. Sry","to_user_id":12289422,"to_user":"RockShrimp","from_user":"witchybitch","id":1819287992,"from_user_id":6026036,"iso_language_code":"en","source":"<a href="http:\/\/twitter.com\/">web<\/a>","profile_image_url":"http:\/\/s3.amazonaws.com\/twitter_production\/profile_images\/86916651\/meorangeshirt2_normal.jpg","created_at":"Sat, 16 May 2009 19:55:48 +0000"}],"since_id":0,"max_id":1819288528,"refresh_url":"?since_id=1819288528&q=twitter","results_per_page":10,"next_page":"?page=2&max_id=1819288528&rpp=10&q=twitter","completed_in":0.020112,"page":1,"query":"twitter"} \ No newline at end of file diff -r 737a5a105dcf4ef16aaec0c1550757900e3dfa64 -r 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b twitter.py --- a/twitter.py Sat May 16 19:32:54 2009 +0000 +++ b/twitter.py Sat May 16 20:06:27 2009 +0000 @@ -820,6 +820,72 @@ self._CheckForTwitterError(data) return NewUserFromJsonDict(data) + def Search(self, + query, + lang=None, + rpp=None, + page=None, + since_id=None, + geocode=None, + show_user=None): + '''Returns tweets that match a specified query. + + Args: + query: The search query string, must be less than 140 characters + lang: + Restricts tweets to the given language, given by an ISO 639-1 + code. [Optional] + rpp: + The number of tweets to return per page, up to a max of 100. [Optional] + page: + The page number (starting at 1) to return, up to a max of + roughly 1500 results (based on rpp * page. Note: there are + pagination limits. [Optional] + since_id: + Returns tweets with status ids greater than the given id. [Optional] + geocode: + Returns tweets by users located within a given radius of the + given latitude/longitude, where the user's location is taken + from their Twitter profile. The parameter value is specified + by "latitide,longitude,radius", where radius units must be + specified as either "mi" (miles) or "km" (kilometers). Note + that you cannot use the near operator via the API to geocode + arbitrary locations; however you can use this geocode + parameter to search near geocodes directly. [Optional] + show_user: + When true, prepends ":" to the beginning of the + tweet. This is useful for readers that do not display Atom's + author field. The default is false. [Optional] + Returns: + A Results instance representing the search results + ''' + url = 'http://search.twitter.com/search.json' + + parameters = {'q': query} + if len(query) > 140: + raise TwitterError('query must be <= 140 characters') + if lang: + parameters['lang'] = lang + if rpp is not None: + try: + if int(rpp) > 100: + raise TwitterError("'rpp' may not be greater than 100") + except ValueError: + raise TwitterError("'rpp' must be an integer") + parameters['rpp'] = rpp + if page: + parameters['page'] = page + if since_id: + parameters['since_id'] = since_id + if geocode: + parameters['geocode'] = geocode + if show_user: + parameters['show_user'] = show_user + json = self._FetchUrl(url, parameters=parameters) + data = simplejson.loads(json) + self._CheckForTwitterError(data) + return NewResultsFromJsonDict(data) + def SetCredentials(self, username, password): '''Set the username and password for this instance diff -r 737a5a105dcf4ef16aaec0c1550757900e3dfa64 -r 19260f87c32ad0e1d2168f5bf29bd8fa4dfeae4b twitter_test.py --- a/twitter_test.py Sat May 16 19:32:54 2009 +0000 +++ b/twitter_test.py Sat May 16 20:06:27 2009 +0000 @@ -454,6 +454,13 @@ self.assertEqual('dewitt', user.screen_name) self.assertEqual(89586072, user.status.id) + def testSearch(self): + '''Test the Twitter.Api Search method''' + self._AddHandler('http://search.twitter.com/search.json?q=twitter', + curry(self._OpenTestData, 'search.json')) + results = self._api.Search('twitter') + self.assertEqual(10, len(results.results)) + def _AddHandler(self, url, callback): self._urllib.AddHandler(url, callback)