From 95fb03d80cb1e97e75b53dc01a6131f17150c59c Mon Sep 17 00:00:00 2001 From: Ryan McGrath Date: Sat, 16 Oct 2010 23:43:55 -0400 Subject: [PATCH] Removing useless files --- .../twitter/twitter_endpoints.py | 299 ------------- oauth_django_example/twitter/twython.py | 421 ------------------ 2 files changed, 720 deletions(-) delete mode 100644 oauth_django_example/twitter/twitter_endpoints.py delete mode 100644 oauth_django_example/twitter/twython.py diff --git a/oauth_django_example/twitter/twitter_endpoints.py b/oauth_django_example/twitter/twitter_endpoints.py deleted file mode 100644 index 42bd5a1..0000000 --- a/oauth_django_example/twitter/twitter_endpoints.py +++ /dev/null @@ -1,299 +0,0 @@ -""" - A huge map of every Twitter API endpoint to a function definition in Twython. - - Parameters that need to be embedded in the URL are treated with mustaches, e.g: - - {{version}}, etc - - When creating new endpoint definitions, keep in mind that the name of the mustache - will be replaced with the keyword that gets passed in to the function at call time. - - i.e, in this case, if I pass version = 47 to any function, {{version}} will be replaced - with 47, instead of defaulting to 1 (said defaulting takes place at conversion time). -""" - -# Base Twitter API url, no need to repeat this junk... -base_url = 'http://api.twitter.com/{{version}}' - -api_table = { - 'getRateLimitStatus': { - 'url': '/account/rate_limit_status.json', - 'method': 'GET', - }, - - # Timeline methods - 'getPublicTimeline': { - 'url': '/statuses/public_timeline.json', - 'method': 'GET', - }, - 'getHomeTimeline': { - 'url': '/statuses/home_timeline.json', - 'method': 'GET', - }, - 'getUserTimeline': { - 'url': '/statuses/user_timeline.json', - 'method': 'GET', - }, - 'getFriendsTimeline': { - 'url': '/statuses/friends_timeline.json', - 'method': 'GET', - }, - - # Interfacing with friends/followers - 'getUserMentions': { - 'url': '/statuses/mentions.json', - 'method': 'GET', - }, - 'getFriendsStatus': { - 'url': '/statuses/friends.json', - 'method': 'GET', - }, - 'getFollowersStatus': { - 'url': '/statuses/followers.json', - 'method': 'GET', - }, - 'createFriendship': { - 'url': '/friendships/create.json', - 'method': 'POST', - }, - 'destroyFriendship': { - 'url': '/friendships/destroy.json', - 'method': 'POST', - }, - 'getFriendsIDs': { - 'url': '/friends/ids.json', - 'method': 'GET', - }, - 'getFollowersIDs': { - 'url': '/followers/ids.json', - 'method': 'GET', - }, - - # Retweets - 'reTweet': { - 'url': '/statuses/retweet/{{id}}.json', - 'method': 'POST', - }, - 'getRetweets': { - 'url': '/statuses/retweets/{{id}}.json', - 'method': 'GET', - }, - 'retweetedOfMe': { - 'url': '/statuses/retweets_of_me.json', - 'method': 'GET', - }, - 'retweetedByMe': { - 'url': '/statuses/retweeted_by_me.json', - 'method': 'GET', - }, - 'retweetedToMe': { - 'url': '/statuses/retweeted_to_me.json', - 'method': 'GET', - }, - - # User methods - 'showUser': { - 'url': '/users/show.json', - 'method': 'GET', - }, - 'searchUsers': { - 'url': '/users/search.json', - 'method': 'GET', - }, - - # Status methods - showing, updating, destroying, etc. - 'showStatus': { - 'url': '/statuses/show/{{id}}.json', - 'method': 'GET', - }, - 'updateStatus': { - 'url': '/statuses/update.json', - 'method': 'POST', - }, - 'destroyStatus': { - 'url': '/statuses/destroy/{{id}}.json', - 'method': 'POST', - }, - - # Direct Messages - getting, sending, effing, etc. - 'getDirectMessages': { - 'url': '/direct_messages.json', - 'method': 'GET', - }, - 'getSentMessages': { - 'url': '/direct_messages/sent.json', - 'method': 'GET', - }, - 'sendDirectMessage': { - 'url': '/direct_messages/new.json', - 'method': 'POST', - }, - 'destroyDirectMessage': { - 'url': '/direct_messages/destroy/{{id}}.json', - 'method': 'POST', - }, - - # Friendship methods - 'checkIfFriendshipExists': { - 'url': '/friendships/exists.json', - 'method': 'GET', - }, - 'showFriendship': { - 'url': '/friendships/show.json', - 'method': 'GET', - }, - - # Profile methods - 'updateProfile': { - 'url': '/account/update_profile.json', - 'method': 'POST', - }, - 'updateProfileColors': { - 'url': '/account/update_profile_colors.json', - 'method': 'POST', - }, - - # Favorites methods - 'getFavorites': { - 'url': '/favorites.json', - 'method': 'GET', - }, - 'createFavorite': { - 'url': '/favorites/create/{{id}}.json', - 'method': 'POST', - }, - 'destroyFavorite': { - 'url': '/favorites/destroy/{{id}}.json', - 'method': 'POST', - }, - - # Blocking methods - 'createBlock': { - 'url': '/blocks/create/{{id}}.json', - 'method': 'POST', - }, - 'destroyBlock': { - 'url': '/blocks/destroy/{{id}}.json', - 'method': 'POST', - }, - 'getBlocking': { - 'url': '/blocks/blocking.json', - 'method': 'GET', - }, - 'getBlockedIDs': { - 'url': '/blocks/blocking/ids.json', - 'method': 'GET', - }, - 'checkIfBlockExists': { - 'url': '/blocks/exists.json', - 'method': 'GET', - }, - - # Trending methods - 'getCurrentTrends': { - 'url': '/trends/current.json', - 'method': 'GET', - }, - 'getDailyTrends': { - 'url': '/trends/daily.json', - 'method': 'GET', - }, - 'getWeeklyTrends': { - 'url': '/trends/weekly.json', - 'method': 'GET', - }, - 'availableTrends': { - 'url': '/trends/available.json', - 'method': 'GET', - }, - 'trendsByLocation': { - 'url': '/trends/{{woeid}}.json', - 'method': 'GET', - }, - - # Saved Searches - 'getSavedSearches': { - 'url': '/saved_searches.json', - 'method': 'GET', - }, - 'showSavedSearch': { - 'url': '/saved_searches/show/{{id}}.json', - 'method': 'GET', - }, - 'createSavedSearch': { - 'url': '/saved_searches/create.json', - 'method': 'GET', - }, - 'destroySavedSearch': { - 'url': '/saved_searches/destroy/{{id}}.json', - 'method': 'GET', - }, - - # List API methods/endpoints. Fairly exhaustive and annoying in general. ;P - 'createList': { - 'url': '/{{username}}/lists.json', - 'method': 'POST', - }, - 'updateList': { - 'url': '/{{username}}/lists/{{list_id}}.json', - 'method': 'POST', - }, - 'showLists': { - 'url': '/{{username}}/lists.json', - 'method': 'GET', - }, - 'getListMemberships': { - 'url': '/{{username}}/lists/followers.json', - 'method': 'GET', - }, - 'deleteList': { - 'url': '/{{username}}/lists/{{list_id}}.json', - 'method': 'DELETE', - }, - 'getListTimeline': { - 'url': '/{{username}}/lists/{{list_id}}/statuses.json', - 'method': 'GET', - }, - 'getSpecificList': { - 'url': '/{{username}}/lists/{{list_id}}/statuses.json', - 'method': 'GET', - }, - 'addListMember': { - 'url': '/{{username}}/{{list_id}}/members.json', - 'method': 'POST', - }, - 'getListMembers': { - 'url': '/{{username}}/{{list_id}}/members.json', - 'method': 'GET', - }, - 'deleteListMember': { - 'url': '/{{username}}/{{list_id}}/members.json', - 'method': 'DELETE', - }, - 'subscribeToList': { - 'url': '/{{username}}/{{list_id}}/following.json', - 'method': 'POST', - }, - 'unsubscribeFromList': { - 'url': '/{{username}}/{{list_id}}/following.json', - 'method': 'DELETE', - }, - - # The one-offs - 'notificationFollow': { - 'url': '/notifications/follow/follow.json', - 'method': 'POST', - }, - 'notificationLeave': { - 'url': '/notifications/leave/leave.json', - 'method': 'POST', - }, - 'updateDeliveryService': { - 'url': '/account/update_delivery_device.json', - 'method': 'POST', - }, - 'reportSpam': { - 'url': '/report_spam.json', - 'method': 'POST', - }, -} diff --git a/oauth_django_example/twitter/twython.py b/oauth_django_example/twitter/twython.py deleted file mode 100644 index eb96be7..0000000 --- a/oauth_django_example/twitter/twython.py +++ /dev/null @@ -1,421 +0,0 @@ -#!/usr/bin/python - -""" - Twython is a library for Python that wraps the Twitter API. - It aims to abstract away all the API endpoints, so that additions to the library - and/or the Twitter API won't cause any overall problems. - - Questions, comments? ryan@venodesigns.net -""" - -__author__ = "Ryan McGrath " -__version__ = "1.3" - -import urllib -import urllib2 -import urlparse -import httplib -import httplib2 -import mimetypes -import mimetools -import re - -import oauth2 as oauth - -# Twython maps keyword based arguments to Twitter API endpoints. The endpoints -# table is a file with a dictionary of every API endpoint that Twython supports. -from twitter_endpoints import base_url, api_table - -from urllib2 import HTTPError - -# There are some special setups (like, oh, a Django application) where -# simplejson exists behind the scenes anyway. Past Python 2.6, this should -# never really cause any problems to begin with. -try: - # Python 2.6 and up - import json as simplejson -except ImportError: - try: - # Python 2.6 and below (2.4/2.5, 2.3 is not guranteed to work with this library to begin with) - import simplejson - except ImportError: - try: - # This case gets rarer by the day, but if we need to, we can pull it from Django provided it's there. - from django.utils import simplejson - except: - # Seriously wtf is wrong with you if you get this Exception. - raise Exception("Twython requires the simplejson library (or Python 2.6) to work. http://www.undefined.org/python/") - -class TwythonError(Exception): - """ - Generic error class, catch-all for most Twython issues. - Special cases are handled by APILimit and AuthError. - - Note: To use these, the syntax has changed as of Twython 1.3. To catch these, - you need to explicitly import them into your code, e.g: - - from twython import TwythonError, APILimit, AuthError - """ - def __init__(self, msg, error_code=None): - self.msg = msg - if error_code == 400: - raise APILimit(msg) - - def __str__(self): - return repr(self.msg) - - -class APILimit(TwythonError): - """ - Raised when you've hit an API limit. Try to avoid these, read the API - docs if you're running into issues here, Twython does not concern itself with - this matter beyond telling you that you've done goofed. - """ - def __init__(self, msg): - self.msg = msg - - def __str__(self): - return repr(self.msg) - - -class AuthError(TwythonError): - """ - Raised when you try to access a protected resource and it fails due to some issue with - your authentication. - """ - def __init__(self, msg): - self.msg = msg - - def __str__(self): - return repr(self.msg) - - -class Twython(object): - def __init__(self, twitter_token = None, twitter_secret = None, oauth_token = None, oauth_token_secret = None, headers=None): - """setup(self, oauth_token = None, headers = None) - - Instantiates an instance of Twython. Takes optional parameters for authentication and such (see below). - - Parameters: - twitter_token - Given to you when you register your application with Twitter. - twitter_secret - Given to you when you register your application with Twitter. - oauth_token - If you've gone through the authentication process and have a token for this user, - pass it in and it'll be used for all requests going forward. - oauth_token_secret - see oauth_token; it's the other half. - headers - User agent header, dictionary style ala {'User-Agent': 'Bert'} - - ** Note: versioning is not currently used by search.twitter functions; when Twitter moves their junk, it'll be supported. - """ - # Needed for hitting that there API. - self.request_token_url = 'http://twitter.com/oauth/request_token' - self.access_token_url = 'http://twitter.com/oauth/access_token' - self.authorize_url = 'http://twitter.com/oauth/authorize' - self.authenticate_url = 'http://twitter.com/oauth/authenticate' - self.twitter_token = twitter_token - self.twitter_secret = twitter_secret - self.oauth_token = oauth_token - self.oauth_secret = oauth_token_secret - - # If there's headers, set them, otherwise be an embarassing parent for their own good. - self.headers = headers - if self.headers is None: - headers = {'User-agent': 'Twython Python Twitter Library v1.3'} - - consumer = None - token = None - - if self.twitter_token is not None and self.twitter_secret is not None: - consumer = oauth.Consumer(self.twitter_token, self.twitter_secret) - - if self.oauth_token is not None and self.oauth_secret is not None: - token = oauth.Token(oauth_token, oauth_token_secret) - - # Filter down through the possibilities here - if they have a token, if they're first stage, etc. - if consumer is not None and token is not None: - self.client = oauth.Client(consumer, token) - elif consumer is not None: - self.client = oauth.Client(consumer) - else: - # If they don't do authentication, but still want to request unprotected resources, we need an opener. - self.client = httplib2.Http() - - def __getattr__(self, api_call): - """ - The most magically awesome block of code you'll see in 2010. - - Rather than list out 9 million damn methods for this API, we just keep a table (see above) of - every API endpoint and their corresponding function id for this library. This pretty much gives - unlimited flexibility in API support - there's a slight chance of a performance hit here, but if this is - going to be your bottleneck... well, don't use Python. ;P - - For those who don't get what's going on here, Python classes have this great feature known as __getattr__(). - It's called when an attribute that was called on an object doesn't seem to exist - since it doesn't exist, - we can take over and find the API method in our table. We then return a function that downloads and parses - what we're looking for, based on the keywords passed in. - - I'll hate myself for saying this, but this is heavily inspired by Ruby's "method_missing". - """ - def get(self, **kwargs): - # Go through and replace any mustaches that are in our API url. - fn = api_table[api_call] - base = re.sub( - '\{\{(?P[a-zA-Z]+)\}\}', - lambda m: "%s" % kwargs.get(m.group(1), '1'), # The '1' here catches the API version. Slightly hilarious. - base_url + fn['url'] - ) - - # Then open and load that shiiit, yo. TODO: check HTTP method and junk, handle errors/authentication - if fn['method'] == 'POST': - resp, content = self.client.request(base, fn['method'], urllib.urlencode(kwargs)) - else: - url = base + "?" + "&".join(["%s=%s" %(key, value) for (key, value) in kwargs.iteritems()]) - resp, content = self.client.request(url, fn['method']) - - return simplejson.loads(content) - - if api_call in api_table: - return get.__get__(self) - else: - raise AttributeError, api_call - - def get_authentication_tokens(self): - """ - get_auth_url(self) - - Returns an authorization URL for a user to hit. - """ - resp, content = self.client.request(self.request_token_url, "GET") - - if resp['status'] != '200': - raise AuthError("Seems something couldn't be verified with your OAuth junk. Error: %s, Message: %s" % (resp['status'], content)) - - request_tokens = dict(urlparse.parse_qsl(content)) - request_tokens['auth_url'] = "%s?oauth_token=%s" % (self.authenticate_url, request_tokens['oauth_token']) - return request_tokens - - def get_authorized_tokens(self): - """ - get_authorized_tokens - - Returns authorized tokens after they go through the auth_url phase. - """ - resp, content = self.client.request(self.access_token_url, "GET") - return dict(urlparse.parse_qsl(content)) - - - @staticmethod - def shortenURL(url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"): - """shortenURL(url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl") - - Shortens url specified by url_to_shorten. - - Parameters: - url_to_shorten - URL to shorten. - shortener - In case you want to use a url shortening service other than is.gd. - """ - try: - resp, content = self.client.request( - shortener + "?" + urllib.urlencode({query: self.unicode2utf8(url_to_shorten)}), - "GET" - ) - return content - except HTTPError, e: - raise TwythonError("shortenURL() failed with a %s error code." % `e.code`) - - def bulkUserLookup(self, ids = None, screen_names = None, version = None): - """ bulkUserLookup(self, ids = None, screen_names = None, version = None) - - A method to do bulk user lookups against the Twitter API. Arguments (ids (numbers) / screen_names (strings)) should be flat Arrays that - contain their respective data sets. - - Statuses for the users in question will be returned inline if they exist. Requires authentication! - """ - version = version or self.apiVersion - if self.authenticated is True: - apiURL = "http://api.twitter.com/%d/users/lookup.json?lol=1" % version - if ids is not None: - apiURL += "&user_id=" - for id in ids: - apiURL += `id` + "," - if screen_names is not None: - apiURL += "&screen_name=" - for name in screen_names: - apiURL += name + "," - try: - return simplejson.load(self.opener.open(apiURL)) - except HTTPError, e: - raise TwythonError("bulkUserLookup() failed with a %s error code." % `e.code`, e.code) - else: - raise AuthError("bulkUserLookup() requires you to be authenticated.") - - def searchTwitter(self, **kwargs): - """searchTwitter(search_query, **kwargs) - - Returns tweets that match a specified query. - - Parameters: - See the documentation at http://dev.twitter.com/doc/get/search. Pass in the API supported arguments as named parameters. - - e.g x.searchTwitter(q="jjndf", page="2") - """ - searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.urlencode({"q": self.unicode2utf8(search_query)}) - try: - return simplejson.load(self.opener.open(searchURL)) - except HTTPError, e: - raise TwythonError("getSearchTimeline() failed with a %s error code." % `e.code`, e.code) - - def searchTwitterGen(self, **kwargs): - """searchTwitterGen(search_query, **kwargs) - - Returns a generator of tweets that match a specified query. - - Parameters: - See the documentation at http://dev.twitter.com/doc/get/search. Pass in the API supported arguments as named parameters. - - e.g x.searchTwitter(q="jjndf", page="2") - """ - searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.urlencode({"q": self.unicode2utf8(search_query)}) - try: - data = simplejson.load(self.opener.open(searchURL)) - except HTTPError, e: - raise TwythonError("searchTwitterGen() failed with a %s error code." % `e.code`, e.code) - - if not data['results']: - raise StopIteration - - for tweet in data['results']: - yield tweet - - if 'page' not in kwargs: - kwargs['page'] = 2 - else: - kwargs['page'] += 1 - - for tweet in self.searchTwitterGen(search_query, **kwargs): - yield tweet - - def isListMember(self, list_id, id, username, version = None): - """ isListMember(self, list_id, id, version) - - Check if a specified user (id) is a member of the list in question (list_id). - - **Note: This method may not work for private/protected lists, unless you're authenticated and have access to those lists. - - Parameters: - list_id - Required. The slug of the list to check against. - id - Required. The ID of the user being checked in the list. - username - User who owns the list you're checking against (username) - version (number) - Optional. API version to request. Entire Twython class defaults to 1, but you can override on a function-by-function or class basis - (version=2), etc. - """ - version = version or self.apiVersion - try: - return simplejson.load(self.opener.open("http://api.twitter.com/%d/%s/%s/members/%s.json" % (version, username, list_id, `id`))) - except HTTPError, e: - raise TwythonError("isListMember() failed with a %d error code." % e.code, e.code) - - def isListSubscriber(self, list_id, id, version = None): - """ isListSubscriber(self, list_id, id, version) - - Check if a specified user (id) is a subscriber of the list in question (list_id). - - **Note: This method may not work for private/protected lists, unless you're authenticated and have access to those lists. - - Parameters: - list_id - Required. The slug of the list to check against. - id - Required. The ID of the user being checked in the list. - username - Required. The username of the owner of the list that you're seeing if someone is subscribed to. - version (number) - Optional. API version to request. Entire Twython class defaults to 1, but you can override on a function-by-function or class basis - (version=2), etc. - """ - version = version or self.apiVersion - try: - return simplejson.load(self.opener.open("http://api.twitter.com/%d/%s/%s/following/%s.json" % (version, username, list_id, `id`))) - except HTTPError, e: - raise TwythonError("isListMember() failed with a %d error code." % e.code, e.code) - - # The following methods are apart from the other Account methods, because they rely on a whole multipart-data posting function set. - def updateProfileBackgroundImage(self, filename, tile="true", version = None): - """ updateProfileBackgroundImage(filename, tile="true") - - Updates the authenticating user's profile background image. - - Parameters: - image - Required. Must be a valid GIF, JPG, or PNG image of less than 800 kilobytes in size. Images with width larger than 2048 pixels will be forceably scaled down. - tile - Optional (defaults to true). If set to true the background image will be displayed tiled. The image will not be tiled otherwise. - ** Note: It's sad, but when using this method, pass the tile value as a string, e.g tile="false" - version (number) - Optional. API version to request. Entire Twython class defaults to 1, but you can override on a function-by-function or class basis - (version=2), etc. - """ - version = version or self.apiVersion - if self.authenticated is True: - try: - files = [("image", filename, open(filename, 'rb').read())] - fields = [] - content_type, body = self.encode_multipart_formdata(fields, files) - headers = {'Content-Type': content_type, 'Content-Length': str(len(body))} - r = urllib2.Request("http://api.twitter.com/%d/account/update_profile_background_image.json?tile=%s" % (version, tile), body, headers) - return self.opener.open(r).read() - except HTTPError, e: - raise TwythonError("updateProfileBackgroundImage() failed with a %d error code." % e.code, e.code) - else: - raise AuthError("You realize you need to be authenticated to change a background image, right?") - - def updateProfileImage(self, filename, version = None): - """ updateProfileImage(filename) - - Updates the authenticating user's profile image (avatar). - - Parameters: - image - Required. Must be a valid GIF, JPG, or PNG image of less than 700 kilobytes in size. Images with width larger than 500 pixels will be scaled down. - version (number) - Optional. API version to request. Entire Twython class defaults to 1, but you can override on a function-by-function or class basis - (version=2), etc. - """ - version = version or self.apiVersion - if self.authenticated is True: - try: - files = [("image", filename, open(filename, 'rb').read())] - fields = [] - content_type, body = Twython.encode_multipart_formdata(fields, files) - headers = {'Content-Type': content_type, 'Content-Length': str(len(body))} - r = urllib2.Request("http://api.twitter.com/%d/account/update_profile_image.json" % version, body, headers) - return self.opener.open(r).read() - except HTTPError, e: - raise TwythonError("updateProfileImage() failed with a %d error code." % e.code, e.code) - else: - raise AuthError("You realize you need to be authenticated to change a profile image, right?") - - @staticmethod - def encode_multipart_formdata(fields, files): - BOUNDARY = mimetools.choose_boundary() - CRLF = '\r\n' - L = [] - for (key, value) in fields: - L.append('--' + BOUNDARY) - L.append('Content-Disposition: form-data; name="%s"' % key) - L.append('') - L.append(value) - for (key, filename, value) in files: - L.append('--' + BOUNDARY) - L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) - L.append('Content-Type: %s' % Twython.get_content_type(filename)) - L.append('') - L.append(value) - L.append('--' + BOUNDARY + '--') - L.append('') - body = CRLF.join(L) - content_type = 'multipart/form-data; boundary=%s' % BOUNDARY - return content_type, body - - @staticmethod - def get_content_type(filename): - """ get_content_type(self, filename) - - Exactly what you think it does. :D - """ - return mimetypes.guess_type(filename)[0] or 'application/octet-stream' - - @staticmethod - def unicode2utf8(text): - try: - if isinstance(text, unicode): - text = text.encode('utf-8') - except: - pass - return text