Fairly large commit - this should fix a slew of issues with passing results from functions (follower ids, for instance) to other functions. Before, they were returned as Numbers, but most functions expect Strings, so there's an extra conversion layer now which should help out on that front. urlencode also properly encodes to utf-8 now (major thanks to contributions from Maatsu on this). Password is also no longer stored as an instance variable. These changes are mirrored in Twython3k, but I've not yet had time to test that in full - as with anything Python3k related, proceed with caution. (There are also some changes relating to how string concatenation is done, but that's all minor in scope)
This commit is contained in:
parent
6ab69d4636
commit
90789b73eb
2 changed files with 207 additions and 200 deletions
195
twython.py
195
twython.py
|
|
@ -1,8 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NOTE: Tango is being renamed to Twython; all basic strings have been changed below, but there's still work ongoing in this department.
|
|
||||||
|
|
||||||
Twython is an up-to-date library for Python that wraps the Twitter API.
|
Twython is an up-to-date library for Python that wraps the Twitter API.
|
||||||
Other Python Twitter libraries seem to have fallen a bit behind, and
|
Other Python Twitter libraries seem to have fallen a bit behind, and
|
||||||
Twitter's API has evolved a bit. Here's hoping this helps.
|
Twitter's API has evolved a bit. Here's hoping this helps.
|
||||||
|
|
@ -18,7 +16,7 @@ from urlparse import urlparse
|
||||||
from urllib2 import HTTPError
|
from urllib2 import HTTPError
|
||||||
|
|
||||||
__author__ = "Ryan McGrath <ryan@venodesigns.net>"
|
__author__ = "Ryan McGrath <ryan@venodesigns.net>"
|
||||||
__version__ = "0.6"
|
__version__ = "0.7a"
|
||||||
|
|
||||||
"""Twython - Easy Twitter utilities in Python"""
|
"""Twython - Easy Twitter utilities in Python"""
|
||||||
|
|
||||||
|
|
@ -55,18 +53,11 @@ class AuthError(TwythonError):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.msg)
|
return repr(self.msg)
|
||||||
|
|
||||||
# A simple decorator to clean up some authentication checks that exist all over.
|
|
||||||
# Not implemented yet -
|
|
||||||
def requires_authentication(func):
|
|
||||||
print func
|
|
||||||
# raise AuthError("This function requires you to be authenticated. Double check that and try again!")
|
|
||||||
|
|
||||||
class setup:
|
class setup:
|
||||||
def __init__(self, authtype = "OAuth", username = None, password = None, consumer_secret = None, consumer_key = None, headers = None):
|
def __init__(self, authtype = "OAuth", username = None, password = None, consumer_secret = None, consumer_key = None, headers = None):
|
||||||
self.authtype = authtype
|
self.authtype = authtype
|
||||||
self.authenticated = False
|
self.authenticated = False
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
|
||||||
# OAuth specific variables below
|
# OAuth specific variables below
|
||||||
self.request_token_url = 'https://twitter.com/oauth/request_token'
|
self.request_token_url = 'https://twitter.com/oauth/request_token'
|
||||||
self.access_token_url = 'https://twitter.com/oauth/access_token'
|
self.access_token_url = 'https://twitter.com/oauth/access_token'
|
||||||
|
|
@ -77,11 +68,11 @@ class setup:
|
||||||
self.request_token = None
|
self.request_token = None
|
||||||
self.access_token = None
|
self.access_token = None
|
||||||
# Check and set up authentication
|
# Check and set up authentication
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and password is not None:
|
||||||
if self.authtype == "Basic":
|
if self.authtype == "Basic":
|
||||||
# Basic authentication ritual
|
# Basic authentication ritual
|
||||||
self.auth_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
self.auth_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
||||||
self.auth_manager.add_password(None, "http://twitter.com", self.username, self.password)
|
self.auth_manager.add_password(None, "http://twitter.com", self.username, password)
|
||||||
self.handler = urllib2.HTTPBasicAuthHandler(self.auth_manager)
|
self.handler = urllib2.HTTPBasicAuthHandler(self.auth_manager)
|
||||||
self.opener = urllib2.build_opener(self.handler)
|
self.opener = urllib2.build_opener(self.handler)
|
||||||
if headers is not None:
|
if headers is not None:
|
||||||
|
|
@ -121,7 +112,7 @@ class setup:
|
||||||
# URL Shortening function huzzah
|
# URL Shortening function huzzah
|
||||||
def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
|
def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
|
||||||
try:
|
try:
|
||||||
return urllib2.urlopen(shortener + "?" + urllib.urlencode({query: url_to_shorten})).read()
|
return urllib2.urlopen(shortener + "?" + urllib.urlencode({query: self.unicode2utf8(url_to_shorten)})).read()
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("shortenURL() failed with a %s error code." % `e.code`)
|
raise TwythonError("shortenURL() failed with a %s error code." % `e.code`)
|
||||||
|
|
||||||
|
|
@ -154,7 +145,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getHomeTimeline() failed with a %s error code. (This is an upcoming feature in the Twitter API, and may not be implemented yet)" % `e.code`)
|
raise TwythonError("getHomeTimeline() failed with a %s error code. (This is an upcoming feature in the Twitter API, and may not be implemented yet)" % `e.code`)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getHomeTimeline() requires you to be authenticated.")
|
raise AuthError("getHomeTimeline() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFriendsTimeline(self, **kwargs):
|
def getFriendsTimeline(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -164,13 +155,13 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getFriendsTimeline() failed with a %s error code." % `e.code`)
|
raise TwythonError("getFriendsTimeline() failed with a %s error code." % `e.code`)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getFriendsTimeline() requires you to be authenticated.")
|
raise AuthError("getFriendsTimeline() requires you to be authenticated.")
|
||||||
|
|
||||||
def getUserTimeline(self, id = None, **kwargs):
|
def getUserTimeline(self, id = None, **kwargs):
|
||||||
if id is not None and kwargs.has_key("user_id") is False and kwargs.has_key("screen_name") is False:
|
if id is not None and kwargs.has_key("user_id") is False and kwargs.has_key("screen_name") is False:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/" + id + ".json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/%s.json" % `id`, kwargs)
|
||||||
elif id is None and kwargs.has_key("user_id") is False and kwargs.has_key("screen_name") is False and self.authenticated is True:
|
elif id is None and kwargs.has_key("user_id") is False and kwargs.has_key("screen_name") is False and self.authenticated is True:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/" + self.username + ".json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/%s.json" % self.username, kwargs)
|
||||||
else:
|
else:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline.json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline.json", kwargs)
|
||||||
try:
|
try:
|
||||||
|
|
@ -191,7 +182,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getUserMentions() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getUserMentions() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getUserMentions() requires you to be authenticated.")
|
raise AuthError("getUserMentions() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedOfMe(self, **kwargs):
|
def retweetedOfMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -201,7 +192,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("retweetedOfMe() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("retweetedOfMe() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedOfMe() requires you to be authenticated.")
|
raise AuthError("retweetedOfMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedByMe(self, **kwargs):
|
def retweetedByMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -211,7 +202,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("retweetedByMe() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("retweetedByMe() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedByMe() requires you to be authenticated.")
|
raise AuthError("retweetedByMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedToMe(self, **kwargs):
|
def retweetedToMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -221,7 +212,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("retweetedToMe() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("retweetedToMe() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedToMe() requires you to be authenticated.")
|
raise AuthError("retweetedToMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def showStatus(self, id):
|
def showStatus(self, id):
|
||||||
try:
|
try:
|
||||||
|
|
@ -237,7 +228,7 @@ class setup:
|
||||||
if len(list(status)) > 140:
|
if len(list(status)) > 140:
|
||||||
raise TwythonError("This status message is over 140 characters. Trim it down!")
|
raise TwythonError("This status message is over 140 characters. Trim it down!")
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/statuses/update.json?", urllib.urlencode({"status": status, "in_reply_to_status_id": in_reply_to_status_id})))
|
return simplejson.load(self.opener.open("http://twitter.com/statuses/update.json?", urllib.urlencode({"status": self.unicode2utf8(status), "in_reply_to_status_id": in_reply_to_status_id})))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateStatus() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateStatus() failed with a %s error code." % `e.code`, e.code)
|
||||||
|
|
||||||
|
|
@ -248,7 +239,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroyStatus() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroyStatus() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyStatus() requires you to be authenticated.")
|
raise AuthError("destroyStatus() requires you to be authenticated.")
|
||||||
|
|
||||||
def reTweet(self, id):
|
def reTweet(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -257,7 +248,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("reTweet() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("reTweet() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("reTweet() requires you to be authenticated.")
|
raise AuthError("reTweet() requires you to be authenticated.")
|
||||||
|
|
||||||
def endSession(self):
|
def endSession(self):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -267,41 +258,41 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("endSession failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("endSession failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You can't end a session when you're not authenticated to begin with.")
|
raise AuthError("You can't end a session when you're not authenticated to begin with.")
|
||||||
|
|
||||||
def getDirectMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
def getDirectMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = "http://twitter.com/direct_messages.json?page=" + page
|
apiURL = "http://twitter.com/direct_messages.json?page=%s" % `page`
|
||||||
if since_id is not None:
|
if since_id is not None:
|
||||||
apiURL += "&since_id=" + since_id
|
apiURL += "&since_id=%s" % `since_id`
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
apiURL += "&max_id=" + max_id
|
apiURL += "&max_id=%s" % `max_id`
|
||||||
if count is not None:
|
if count is not None:
|
||||||
apiURL += "&count=" + count
|
apiURL += "&count=%s" % `count`
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getDirectMessages() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getDirectMessages() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getDirectMessages() requires you to be authenticated.")
|
raise AuthError("getDirectMessages() requires you to be authenticated.")
|
||||||
|
|
||||||
def getSentMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
def getSentMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = "http://twitter.com/direct_messages/sent.json?page=" + page
|
apiURL = "http://twitter.com/direct_messages/sent.json?page=%s" % `page`
|
||||||
if since_id is not None:
|
if since_id is not None:
|
||||||
apiURL += "&since_id=" + since_id
|
apiURL += "&since_id=%s" % `since_id`
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
apiURL += "&max_id=" + max_id
|
apiURL += "&max_id=%s" % `max_id`
|
||||||
if count is not None:
|
if count is not None:
|
||||||
apiURL += "&count=" + count
|
apiURL += "&count=%s" % `count`
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getSentMessages() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getSentMessages() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getSentMessages() requires you to be authenticated.")
|
raise AuthError("getSentMessages() requires you to be authenticated.")
|
||||||
|
|
||||||
def sendDirectMessage(self, user, text):
|
def sendDirectMessage(self, user, text):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -313,7 +304,7 @@ class setup:
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Your message must not be longer than 140 characters")
|
raise TwythonError("Your message must not be longer than 140 characters")
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You must be authenticated to send a new direct message.")
|
raise AuthError("You must be authenticated to send a new direct message.")
|
||||||
|
|
||||||
def destroyDirectMessage(self, id):
|
def destroyDirectMessage(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -322,17 +313,17 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroyDirectMessage() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroyDirectMessage() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You must be authenticated to destroy a direct message.")
|
raise AuthError("You must be authenticated to destroy a direct message.")
|
||||||
|
|
||||||
def createFriendship(self, id = None, user_id = None, screen_name = None, follow = "false"):
|
def createFriendship(self, id = None, user_id = None, screen_name = None, follow = "false"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create/" + id + ".json" + "?follow=" + follow
|
apiURL = "http://twitter.com/friendships/create/%s.json?follow=%s" %(id, follow)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create.json?user_id=" + user_id + "&follow=" + follow
|
apiURL = "http://twitter.com/friendships/create.json?user_id=%s&follow=%s" %(`user_id`, follow)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create.json?screen_name=" + screen_name + "&follow=" + follow
|
apiURL = "http://twitter.com/friendships/create.json?screen_name=%s&follow=%s" %(screen_name, follow)
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
|
|
@ -341,23 +332,23 @@ class setup:
|
||||||
raise TwythonError("You've hit the update limit for this method. Try again in 24 hours.")
|
raise TwythonError("You've hit the update limit for this method. Try again in 24 hours.")
|
||||||
raise TwythonError("createFriendship() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("createFriendship() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createFriendship() requires you to be authenticated.")
|
raise AuthError("createFriendship() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyFriendship(self, id = None, user_id = None, screen_name = None):
|
def destroyFriendship(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy/" + id + ".json"
|
apiURL = "http://twitter.com/friendships/destroy/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy.json?user_id=" + user_id
|
apiURL = "http://twitter.com/friendships/destroy.json?user_id=%s" % `user_id`
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/friendships/destroy.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroyFriendship() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroyFriendship() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyFriendship() requires you to be authenticated.")
|
raise AuthError("destroyFriendship() requires you to be authenticated.")
|
||||||
|
|
||||||
def checkIfFriendshipExists(self, user_a, user_b):
|
def checkIfFriendshipExists(self, user_a, user_b):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -366,16 +357,16 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("checkIfFriendshipExists() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("checkIfFriendshipExists() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("checkIfFriendshipExists(), oddly, requires that you be authenticated.")
|
raise AuthError("checkIfFriendshipExists(), oddly, requires that you be authenticated.")
|
||||||
|
|
||||||
def updateDeliveryDevice(self, device_name = "none"):
|
def updateDeliveryDevice(self, device_name = "none"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return self.opener.open("http://twitter.com/account/update_delivery_device.json?", urllib.urlencode({"device": device_name}))
|
return self.opener.open("http://twitter.com/account/update_delivery_device.json?", urllib.urlencode({"device": self.unicode2utf8(device_name)}))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateDeliveryDevice() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateDeliveryDevice() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateDeliveryDevice() requires you to be authenticated.")
|
raise AuthError("updateDeliveryDevice() requires you to be authenticated.")
|
||||||
|
|
||||||
def updateProfileColors(self, **kwargs):
|
def updateProfileColors(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -384,7 +375,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateProfileColors() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateProfileColors() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateProfileColors() requires you to be authenticated.")
|
raise AuthError("updateProfileColors() requires you to be authenticated.")
|
||||||
|
|
||||||
def updateProfile(self, name = None, email = None, url = None, location = None, description = None):
|
def updateProfile(self, name = None, email = None, url = None, location = None, description = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -408,27 +399,27 @@ class setup:
|
||||||
if url is not None:
|
if url is not None:
|
||||||
if len(list(url)) < 100:
|
if len(list(url)) < 100:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.urlencode({"url": url})
|
updateProfileQueryString += "&" + urllib.urlencode({"url": self.unicode2utf8(url)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.urlencode({"url": url})
|
updateProfileQueryString += urllib.urlencode({"url": self.unicode2utf8(url)})
|
||||||
useAmpersands = True
|
useAmpersands = True
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 100 for all urls. Try again.")
|
raise TwythonError("Twitter has a character limit of 100 for all urls. Try again.")
|
||||||
if location is not None:
|
if location is not None:
|
||||||
if len(list(location)) < 30:
|
if len(list(location)) < 30:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.urlencode({"location": location})
|
updateProfileQueryString += "&" + urllib.urlencode({"location": self.unicode2utf8(location)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.urlencode({"location": location})
|
updateProfileQueryString += urllib.urlencode({"location": self.unicode2utf8(location)})
|
||||||
useAmpersands = True
|
useAmpersands = True
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 30 for all locations. Try again.")
|
raise TwythonError("Twitter has a character limit of 30 for all locations. Try again.")
|
||||||
if description is not None:
|
if description is not None:
|
||||||
if len(list(description)) < 160:
|
if len(list(description)) < 160:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.urlencode({"description": description})
|
updateProfileQueryString += "&" + urllib.urlencode({"description": self.unicode2utf8(description)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.urlencode({"description": description})
|
updateProfileQueryString += urllib.urlencode({"description": self.unicode2utf8(description)})
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 160 for all descriptions. Try again.")
|
raise TwythonError("Twitter has a character limit of 160 for all descriptions. Try again.")
|
||||||
|
|
||||||
|
|
@ -438,75 +429,75 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateProfile() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateProfile() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateProfile() requires you to be authenticated.")
|
raise AuthError("updateProfile() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFavorites(self, page = "1"):
|
def getFavorites(self, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites.json?page=" + page))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites.json?page=%s" % `page`))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getFavorites() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getFavorites() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getFavorites() requires you to be authenticated.")
|
raise AuthError("getFavorites() requires you to be authenticated.")
|
||||||
|
|
||||||
def createFavorite(self, id):
|
def createFavorite(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites/create/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites/create/%s.json" % `id`, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("createFavorite() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("createFavorite() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createFavorite() requires you to be authenticated.")
|
raise AuthError("createFavorite() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyFavorite(self, id):
|
def destroyFavorite(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites/destroy/%s.json" % `id`, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroyFavorite() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroyFavorite() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyFavorite() requires you to be authenticated.")
|
raise AuthError("destroyFavorite() requires you to be authenticated.")
|
||||||
|
|
||||||
def notificationFollow(self, id = None, user_id = None, screen_name = None):
|
def notificationFollow(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/" + id + ".json"
|
apiURL = "http://twitter.com/notifications/follow/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/follow.json?user_id=" + user_id
|
apiURL = "http://twitter.com/notifications/follow/follow.json?user_id=%s" % `user_id`
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/follow.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/notifications/follow/follow.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL, ""))
|
return simplejson.load(self.opener.open(apiURL, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("notificationFollow() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("notificationFollow() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("notificationFollow() requires you to be authenticated.")
|
raise AuthError("notificationFollow() requires you to be authenticated.")
|
||||||
|
|
||||||
def notificationLeave(self, id = None, user_id = None, screen_name = None):
|
def notificationLeave(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/" + id + ".json"
|
apiURL = "http://twitter.com/notifications/leave/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/leave.json?user_id=" + user_id
|
apiURL = "http://twitter.com/notifications/leave/leave.json?user_id=%s" % `user_id`
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/leave.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/notifications/leave/leave.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL, ""))
|
return simplejson.load(self.opener.open(apiURL, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("notificationLeave() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("notificationLeave() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("notificationLeave() requires you to be authenticated.")
|
raise AuthError("notificationLeave() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFriendsIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
def getFriendsIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids/" + id + ".json" + "?page=" + page
|
apiURL = "http://twitter.com/friends/ids/%s.json?page=%s" %(id, `page`)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids.json?user_id=" + user_id + "&page=" + page
|
apiURL = "http://twitter.com/friends/ids.json?user_id=%s&page=%s" %(`user_id`, `page`)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids.json?screen_name=" + screen_name + "&page=" + page
|
apiURL = "http://twitter.com/friends/ids.json?screen_name=%s&page=%s" %(screen_name, `page`)
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib2.urlopen(apiURL))
|
return simplejson.load(urllib2.urlopen(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
|
|
@ -515,11 +506,11 @@ class setup:
|
||||||
def getFollowersIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
def getFollowersIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids/" + id + ".json" + "?page=" + page
|
apiURL = "http://twitter.com/followers/ids/%s.json?page=%s" %(`id`, `page`)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids.json?user_id=" + user_id + "&page=" + page
|
apiURL = "http://twitter.com/followers/ids.json?user_id=%s&page=%s" %(`user_id`, `page`)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids.json?screen_name=" + screen_name + "&page=" + page
|
apiURL = "http://twitter.com/followers/ids.json?screen_name=%s&page=%s" %(screen_name, `page`)
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib2.urlopen(apiURL))
|
return simplejson.load(urllib2.urlopen(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
|
|
@ -528,29 +519,29 @@ class setup:
|
||||||
def createBlock(self, id):
|
def createBlock(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/create/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/create/%s.json" % `id`, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("createBlock() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("createBlock() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createBlock() requires you to be authenticated.")
|
raise AuthError("createBlock() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyBlock(self, id):
|
def destroyBlock(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/destroy/%s.json" % `id`, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroyBlock() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroyBlock() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyBlock() requires you to be authenticated.")
|
raise AuthError("destroyBlock() requires you to be authenticated.")
|
||||||
|
|
||||||
def checkIfBlockExists(self, id = None, user_id = None, screen_name = None):
|
def checkIfBlockExists(self, id = None, user_id = None, screen_name = None):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists/" + id + ".json"
|
apiURL = "http://twitter.com/blocks/exists/%s.json" % `id`
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists.json?user_id=" + user_id
|
apiURL = "http://twitter.com/blocks/exists.json?user_id=%s" % `user_id`
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/blocks/exists.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib2.urlopen(apiURL))
|
return simplejson.load(urllib2.urlopen(apiURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
|
|
@ -559,11 +550,11 @@ class setup:
|
||||||
def getBlocking(self, page = "1"):
|
def getBlocking(self, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/blocking.json?page=" + page))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/blocking.json?page=%s" % `page`))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getBlocking() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getBlocking() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getBlocking() requires you to be authenticated")
|
raise AuthError("getBlocking() requires you to be authenticated")
|
||||||
|
|
||||||
def getBlockedIDs(self):
|
def getBlockedIDs(self):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -572,10 +563,10 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getBlockedIDs() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getBlockedIDs() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getBlockedIDs() requires you to be authenticated.")
|
raise AuthError("getBlockedIDs() requires you to be authenticated.")
|
||||||
|
|
||||||
def searchTwitter(self, search_query, **kwargs):
|
def searchTwitter(self, search_query, **kwargs):
|
||||||
searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.urlencode({"q": search_query})
|
searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.urlencode({"q": self.unicode2utf8(search_query)})
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib2.urlopen(searchURL))
|
return simplejson.load(urllib2.urlopen(searchURL))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
|
|
@ -594,7 +585,7 @@ class setup:
|
||||||
apiURL = "http://search.twitter.com/trends/daily.json"
|
apiURL = "http://search.twitter.com/trends/daily.json"
|
||||||
questionMarkUsed = False
|
questionMarkUsed = False
|
||||||
if date is not None:
|
if date is not None:
|
||||||
apiURL += "?date=" + date
|
apiURL += "?date=%s" % date
|
||||||
questionMarkUsed = True
|
questionMarkUsed = True
|
||||||
if exclude is True:
|
if exclude is True:
|
||||||
if questionMarkUsed is True:
|
if questionMarkUsed is True:
|
||||||
|
|
@ -610,7 +601,7 @@ class setup:
|
||||||
apiURL = "http://search.twitter.com/trends/daily.json"
|
apiURL = "http://search.twitter.com/trends/daily.json"
|
||||||
questionMarkUsed = False
|
questionMarkUsed = False
|
||||||
if date is not None:
|
if date is not None:
|
||||||
apiURL += "?date=" + date
|
apiURL += "?date=%s" % date
|
||||||
questionMarkUsed = True
|
questionMarkUsed = True
|
||||||
if exclude is True:
|
if exclude is True:
|
||||||
if questionMarkUsed is True:
|
if questionMarkUsed is True:
|
||||||
|
|
@ -629,34 +620,34 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("getSavedSearches() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("getSavedSearches() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getSavedSearches() requires you to be authenticated.")
|
raise AuthError("getSavedSearches() requires you to be authenticated.")
|
||||||
|
|
||||||
def showSavedSearch(self, id):
|
def showSavedSearch(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/show/" + id + ".json"))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/show/%s.json" % `id`))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("showSavedSearch() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("showSavedSearch() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("showSavedSearch() requires you to be authenticated.")
|
raise AuthError("showSavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
def createSavedSearch(self, query):
|
def createSavedSearch(self, query):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/create.json?query=" + query, ""))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/create.json?query=%s" % query, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("createSavedSearch() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("createSavedSearch() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createSavedSearch() requires you to be authenticated.")
|
raise AuthError("createSavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroySavedSearch(self, id):
|
def destroySavedSearch(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/destroy/%s.json" % `id`, ""))
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("destroySavedSearch() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("destroySavedSearch() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroySavedSearch() requires you to be authenticated.")
|
raise AuthError("destroySavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
# The following methods are apart from the other Account methods, because they rely on a whole multipart-data posting function set.
|
# 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"):
|
def updateProfileBackgroundImage(self, filename, tile="true"):
|
||||||
|
|
@ -671,7 +662,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateProfileBackgroundImage() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateProfileBackgroundImage() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You realize you need to be authenticated to change a background image, right?")
|
raise AuthError("You realize you need to be authenticated to change a background image, right?")
|
||||||
|
|
||||||
def updateProfileImage(self, filename):
|
def updateProfileImage(self, filename):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -685,7 +676,7 @@ class setup:
|
||||||
except HTTPError, e:
|
except HTTPError, e:
|
||||||
raise TwythonError("updateProfileImage() failed with a %s error code." % `e.code`, e.code)
|
raise TwythonError("updateProfileImage() failed with a %s error code." % `e.code`, e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You realize you need to be authenticated to change a profile image, right?")
|
raise AuthError("You realize you need to be authenticated to change a profile image, right?")
|
||||||
|
|
||||||
def encode_multipart_formdata(self, fields, files):
|
def encode_multipart_formdata(self, fields, files):
|
||||||
BOUNDARY = mimetools.choose_boundary()
|
BOUNDARY = mimetools.choose_boundary()
|
||||||
|
|
@ -710,3 +701,11 @@ class setup:
|
||||||
|
|
||||||
def get_content_type(self, filename):
|
def get_content_type(self, filename):
|
||||||
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
||||||
|
|
||||||
|
def unicode2utf8(self, text):
|
||||||
|
try:
|
||||||
|
if isinstance(text, unicode):
|
||||||
|
text = text.encode('utf-8')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return text
|
||||||
|
|
|
||||||
198
twython3k.py
198
twython3k.py
|
|
@ -1,8 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
"""
|
"""
|
||||||
NOTE: Tango is being renamed to Twython; all basic strings have been changed below, but there's still work ongoing in this department.
|
|
||||||
|
|
||||||
Twython is an up-to-date library for Python that wraps the Twitter API.
|
Twython is an up-to-date library for Python that wraps the Twitter API.
|
||||||
Other Python Twitter libraries seem to have fallen a bit behind, and
|
Other Python Twitter libraries seem to have fallen a bit behind, and
|
||||||
Twitter's API has evolved a bit. Here's hoping this helps.
|
Twitter's API has evolved a bit. Here's hoping this helps.
|
||||||
|
|
@ -18,7 +16,7 @@ from urllib.parse import urlparse
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
|
|
||||||
__author__ = "Ryan McGrath <ryan@venodesigns.net>"
|
__author__ = "Ryan McGrath <ryan@venodesigns.net>"
|
||||||
__version__ = "0.6"
|
__version__ = "0.7a"
|
||||||
|
|
||||||
"""Twython - Easy Twitter utilities in Python"""
|
"""Twython - Easy Twitter utilities in Python"""
|
||||||
|
|
||||||
|
|
@ -49,12 +47,17 @@ class APILimit(TwythonError):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return repr(self.msg)
|
return repr(self.msg)
|
||||||
|
|
||||||
|
class AuthError(TwythonError):
|
||||||
|
def __init__(self, msg):
|
||||||
|
self.msg = msg
|
||||||
|
def __str__(self):
|
||||||
|
return repr(self.msg)
|
||||||
|
|
||||||
class setup:
|
class setup:
|
||||||
def __init__(self, authtype = "OAuth", username = None, password = None, consumer_secret = None, consumer_key = None, headers = None):
|
def __init__(self, authtype = "OAuth", username = None, password = None, consumer_secret = None, consumer_key = None, headers = None):
|
||||||
self.authtype = authtype
|
self.authtype = authtype
|
||||||
self.authenticated = False
|
self.authenticated = False
|
||||||
self.username = username
|
self.username = username
|
||||||
self.password = password
|
|
||||||
# OAuth specific variables below
|
# OAuth specific variables below
|
||||||
self.request_token_url = 'https://twitter.com/oauth/request_token'
|
self.request_token_url = 'https://twitter.com/oauth/request_token'
|
||||||
self.access_token_url = 'https://twitter.com/oauth/access_token'
|
self.access_token_url = 'https://twitter.com/oauth/access_token'
|
||||||
|
|
@ -65,11 +68,11 @@ class setup:
|
||||||
self.request_token = None
|
self.request_token = None
|
||||||
self.access_token = None
|
self.access_token = None
|
||||||
# Check and set up authentication
|
# Check and set up authentication
|
||||||
if self.username is not None and self.password is not None:
|
if self.username is not None and password is not None:
|
||||||
if self.authtype == "Basic":
|
if self.authtype == "Basic":
|
||||||
# Basic authentication ritual
|
# Basic authentication ritual
|
||||||
self.auth_manager = urllib.request.HTTPPasswordMgrWithDefaultRealm()
|
self.auth_manager = urllib.request.HTTPPasswordMgrWithDefaultRealm()
|
||||||
self.auth_manager.add_password(None, "http://twitter.com", self.username, self.password)
|
self.auth_manager.add_password(None, "http://twitter.com", self.username, password)
|
||||||
self.handler = urllib.request.HTTPBasicAuthHandler(self.auth_manager)
|
self.handler = urllib.request.HTTPBasicAuthHandler(self.auth_manager)
|
||||||
self.opener = urllib.request.build_opener(self.handler)
|
self.opener = urllib.request.build_opener(self.handler)
|
||||||
if headers is not None:
|
if headers is not None:
|
||||||
|
|
@ -109,7 +112,7 @@ class setup:
|
||||||
# URL Shortening function huzzah
|
# URL Shortening function huzzah
|
||||||
def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
|
def shortenURL(self, url_to_shorten, shortener = "http://is.gd/api.php", query = "longurl"):
|
||||||
try:
|
try:
|
||||||
return urllib.request.urlopen(shortener + "?" + urllib.urlencode({query: url_to_shorten})).read()
|
return urllib.request.urlopen(shortener + "?" + urllib.urlencode({query: self.unicode2utf8(url_to_shorten)})).read()
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("shortenURL() failed with a %s error code." % repr(e.code))
|
raise TwythonError("shortenURL() failed with a %s error code." % repr(e.code))
|
||||||
|
|
||||||
|
|
@ -142,7 +145,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getHomeTimeline() failed with a %s error code. (This is an upcoming feature in the Twitter API, and may not be implemented yet)" % repr(e.code))
|
raise TwythonError("getHomeTimeline() failed with a %s error code. (This is an upcoming feature in the Twitter API, and may not be implemented yet)" % repr(e.code))
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getHomeTimeline() requires you to be authenticated.")
|
raise AuthError("getHomeTimeline() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFriendsTimeline(self, **kwargs):
|
def getFriendsTimeline(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -152,13 +155,13 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getFriendsTimeline() failed with a %s error code." % repr(e.code))
|
raise TwythonError("getFriendsTimeline() failed with a %s error code." % repr(e.code))
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getFriendsTimeline() requires you to be authenticated.")
|
raise AuthError("getFriendsTimeline() requires you to be authenticated.")
|
||||||
|
|
||||||
def getUserTimeline(self, id = None, **kwargs):
|
def getUserTimeline(self, id = None, **kwargs):
|
||||||
if id is not None and ("user_id" in kwargs) is False and ("screen_name" in kwargs) is False:
|
if id is not None and ("user_id" in kwargs) is False and ("screen_name" in kwargs) is False:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/" + id + ".json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/%s.json" % repr(id), kwargs)
|
||||||
elif id is None and ("user_id" in kwargs) is False and ("screen_name" in kwargs) is False and self.authenticated is True:
|
elif id is None and ("user_id" in kwargs) is False and ("screen_name" in kwargs) is False and self.authenticated is True:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/" + self.username + ".json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline/%s.json" % self.username, kwargs)
|
||||||
else:
|
else:
|
||||||
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline.json", kwargs)
|
userTimelineURL = self.constructApiURL("http://twitter.com/statuses/user_timeline.json", kwargs)
|
||||||
try:
|
try:
|
||||||
|
|
@ -179,7 +182,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getUserMentions() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getUserMentions() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getUserMentions() requires you to be authenticated.")
|
raise AuthError("getUserMentions() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedOfMe(self, **kwargs):
|
def retweetedOfMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -189,7 +192,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("retweetedOfMe() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("retweetedOfMe() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedOfMe() requires you to be authenticated.")
|
raise AuthError("retweetedOfMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedByMe(self, **kwargs):
|
def retweetedByMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -199,7 +202,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("retweetedByMe() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("retweetedByMe() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedByMe() requires you to be authenticated.")
|
raise AuthError("retweetedByMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def retweetedToMe(self, **kwargs):
|
def retweetedToMe(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -209,7 +212,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("retweetedToMe() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("retweetedToMe() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("retweetedToMe() requires you to be authenticated.")
|
raise AuthError("retweetedToMe() requires you to be authenticated.")
|
||||||
|
|
||||||
def showStatus(self, id):
|
def showStatus(self, id):
|
||||||
try:
|
try:
|
||||||
|
|
@ -222,15 +225,12 @@ class setup:
|
||||||
% repr(e.code), e.code)
|
% repr(e.code), e.code)
|
||||||
|
|
||||||
def updateStatus(self, status, in_reply_to_status_id = None):
|
def updateStatus(self, status, in_reply_to_status_id = None):
|
||||||
if self.authenticated is True:
|
|
||||||
if len(list(status)) > 140:
|
if len(list(status)) > 140:
|
||||||
raise TwythonError("This status message is over 140 characters. Trim it down!")
|
raise TwythonError("This status message is over 140 characters. Trim it down!")
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/statuses/update.json?", urllib.parse.urlencode({"status": status, "in_reply_to_status_id": in_reply_to_status_id})))
|
return simplejson.load(self.opener.open("http://twitter.com/statuses/update.json?", urllib.parse.urlencode({"status": self.unicode2utf8(status), "in_reply_to_status_id": in_reply_to_status_id})))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateStatus() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateStatus() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
|
||||||
raise TwythonError("updateStatus() requires you to be authenticated.")
|
|
||||||
|
|
||||||
def destroyStatus(self, id):
|
def destroyStatus(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -239,7 +239,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroyStatus() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroyStatus() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyStatus() requires you to be authenticated.")
|
raise AuthError("destroyStatus() requires you to be authenticated.")
|
||||||
|
|
||||||
def reTweet(self, id):
|
def reTweet(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -248,7 +248,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("reTweet() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("reTweet() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("reTweet() requires you to be authenticated.")
|
raise AuthError("reTweet() requires you to be authenticated.")
|
||||||
|
|
||||||
def endSession(self):
|
def endSession(self):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -258,41 +258,41 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("endSession failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("endSession failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You can't end a session when you're not authenticated to begin with.")
|
raise AuthError("You can't end a session when you're not authenticated to begin with.")
|
||||||
|
|
||||||
def getDirectMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
def getDirectMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = "http://twitter.com/direct_messages.json?page=" + page
|
apiURL = "http://twitter.com/direct_messages.json?page=%s" % repr(page)
|
||||||
if since_id is not None:
|
if since_id is not None:
|
||||||
apiURL += "&since_id=" + since_id
|
apiURL += "&since_id=%s" % repr(since_id)
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
apiURL += "&max_id=" + max_id
|
apiURL += "&max_id=%s" % repr(max_id)
|
||||||
if count is not None:
|
if count is not None:
|
||||||
apiURL += "&count=" + count
|
apiURL += "&count=%s" % repr(count)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getDirectMessages() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getDirectMessages() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getDirectMessages() requires you to be authenticated.")
|
raise AuthError("getDirectMessages() requires you to be authenticated.")
|
||||||
|
|
||||||
def getSentMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
def getSentMessages(self, since_id = None, max_id = None, count = None, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = "http://twitter.com/direct_messages/sent.json?page=" + page
|
apiURL = "http://twitter.com/direct_messages/sent.json?page=%s" % repr(page)
|
||||||
if since_id is not None:
|
if since_id is not None:
|
||||||
apiURL += "&since_id=" + since_id
|
apiURL += "&since_id=%s" % repr(since_id)
|
||||||
if max_id is not None:
|
if max_id is not None:
|
||||||
apiURL += "&max_id=" + max_id
|
apiURL += "&max_id=%s" % repr(max_id)
|
||||||
if count is not None:
|
if count is not None:
|
||||||
apiURL += "&count=" + count
|
apiURL += "&count=%s" % repr(count)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getSentMessages() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getSentMessages() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getSentMessages() requires you to be authenticated.")
|
raise AuthError("getSentMessages() requires you to be authenticated.")
|
||||||
|
|
||||||
def sendDirectMessage(self, user, text):
|
def sendDirectMessage(self, user, text):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -304,7 +304,7 @@ class setup:
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Your message must not be longer than 140 characters")
|
raise TwythonError("Your message must not be longer than 140 characters")
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You must be authenticated to send a new direct message.")
|
raise AuthError("You must be authenticated to send a new direct message.")
|
||||||
|
|
||||||
def destroyDirectMessage(self, id):
|
def destroyDirectMessage(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -313,17 +313,17 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroyDirectMessage() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroyDirectMessage() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You must be authenticated to destroy a direct message.")
|
raise AuthError("You must be authenticated to destroy a direct message.")
|
||||||
|
|
||||||
def createFriendship(self, id = None, user_id = None, screen_name = None, follow = "false"):
|
def createFriendship(self, id = None, user_id = None, screen_name = None, follow = "false"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create/" + id + ".json" + "?follow=" + follow
|
apiURL = "http://twitter.com/friendships/create/%s.json?follow=%s" %(id, follow)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create.json?user_id=" + user_id + "&follow=" + follow
|
apiURL = "http://twitter.com/friendships/create.json?user_id=%s&follow=%s" %(repr(user_id), follow)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friendships/create.json?screen_name=" + screen_name + "&follow=" + follow
|
apiURL = "http://twitter.com/friendships/create.json?screen_name=%s&follow=%s" %(screen_name, follow)
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|
@ -332,23 +332,23 @@ class setup:
|
||||||
raise TwythonError("You've hit the update limit for this method. Try again in 24 hours.")
|
raise TwythonError("You've hit the update limit for this method. Try again in 24 hours.")
|
||||||
raise TwythonError("createFriendship() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("createFriendship() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createFriendship() requires you to be authenticated.")
|
raise AuthError("createFriendship() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyFriendship(self, id = None, user_id = None, screen_name = None):
|
def destroyFriendship(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy/" + id + ".json"
|
apiURL = "http://twitter.com/friendships/destroy/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy.json?user_id=" + user_id
|
apiURL = "http://twitter.com/friendships/destroy.json?user_id=%s" % repr(user_id)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friendships/destroy.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/friendships/destroy.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL))
|
return simplejson.load(self.opener.open(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroyFriendship() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroyFriendship() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyFriendship() requires you to be authenticated.")
|
raise AuthError("destroyFriendship() requires you to be authenticated.")
|
||||||
|
|
||||||
def checkIfFriendshipExists(self, user_a, user_b):
|
def checkIfFriendshipExists(self, user_a, user_b):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -357,16 +357,16 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("checkIfFriendshipExists() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("checkIfFriendshipExists() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("checkIfFriendshipExists(), oddly, requires that you be authenticated.")
|
raise AuthError("checkIfFriendshipExists(), oddly, requires that you be authenticated.")
|
||||||
|
|
||||||
def updateDeliveryDevice(self, device_name = "none"):
|
def updateDeliveryDevice(self, device_name = "none"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return self.opener.open("http://twitter.com/account/update_delivery_device.json?", urllib.parse.urlencode({"device": device_name}))
|
return self.opener.open("http://twitter.com/account/update_delivery_device.json?", urllib.parse.urlencode({"device": self.unicode2utf8(device_name)}))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateDeliveryDevice() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateDeliveryDevice() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateDeliveryDevice() requires you to be authenticated.")
|
raise AuthError("updateDeliveryDevice() requires you to be authenticated.")
|
||||||
|
|
||||||
def updateProfileColors(self, **kwargs):
|
def updateProfileColors(self, **kwargs):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -375,7 +375,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateProfileColors() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateProfileColors() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateProfileColors() requires you to be authenticated.")
|
raise AuthError("updateProfileColors() requires you to be authenticated.")
|
||||||
|
|
||||||
def updateProfile(self, name = None, email = None, url = None, location = None, description = None):
|
def updateProfile(self, name = None, email = None, url = None, location = None, description = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -399,27 +399,27 @@ class setup:
|
||||||
if url is not None:
|
if url is not None:
|
||||||
if len(list(url)) < 100:
|
if len(list(url)) < 100:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.parse.urlencode({"url": url})
|
updateProfileQueryString += "&" + urllib.parse.urlencode({"url": self.unicode2utf8(url)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.parse.urlencode({"url": url})
|
updateProfileQueryString += urllib.parse.urlencode({"url": self.unicode2utf8(url)})
|
||||||
useAmpersands = True
|
useAmpersands = True
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 100 for all urls. Try again.")
|
raise TwythonError("Twitter has a character limit of 100 for all urls. Try again.")
|
||||||
if location is not None:
|
if location is not None:
|
||||||
if len(list(location)) < 30:
|
if len(list(location)) < 30:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.parse.urlencode({"location": location})
|
updateProfileQueryString += "&" + urllib.parse.urlencode({"location": self.unicode2utf8(location)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.parse.urlencode({"location": location})
|
updateProfileQueryString += urllib.parse.urlencode({"location": self.unicode2utf8(location)})
|
||||||
useAmpersands = True
|
useAmpersands = True
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 30 for all locations. Try again.")
|
raise TwythonError("Twitter has a character limit of 30 for all locations. Try again.")
|
||||||
if description is not None:
|
if description is not None:
|
||||||
if len(list(description)) < 160:
|
if len(list(description)) < 160:
|
||||||
if useAmpersands is True:
|
if useAmpersands is True:
|
||||||
updateProfileQueryString += "&" + urllib.parse.urlencode({"description": description})
|
updateProfileQueryString += "&" + urllib.parse.urlencode({"description": self.unicode2utf8(description)})
|
||||||
else:
|
else:
|
||||||
updateProfileQueryString += urllib.parse.urlencode({"description": description})
|
updateProfileQueryString += urllib.parse.urlencode({"description": self.unicode2utf8(description)})
|
||||||
else:
|
else:
|
||||||
raise TwythonError("Twitter has a character limit of 160 for all descriptions. Try again.")
|
raise TwythonError("Twitter has a character limit of 160 for all descriptions. Try again.")
|
||||||
|
|
||||||
|
|
@ -429,75 +429,75 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateProfile() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateProfile() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("updateProfile() requires you to be authenticated.")
|
raise AuthError("updateProfile() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFavorites(self, page = "1"):
|
def getFavorites(self, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites.json?page=" + page))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites.json?page=%s" % repr(page)))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getFavorites() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getFavorites() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getFavorites() requires you to be authenticated.")
|
raise AuthError("getFavorites() requires you to be authenticated.")
|
||||||
|
|
||||||
def createFavorite(self, id):
|
def createFavorite(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites/create/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites/create/%s.json" % repr(id), ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("createFavorite() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("createFavorite() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createFavorite() requires you to be authenticated.")
|
raise AuthError("createFavorite() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyFavorite(self, id):
|
def destroyFavorite(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/favorites/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/favorites/destroy/%s.json" % repr(id), ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroyFavorite() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroyFavorite() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyFavorite() requires you to be authenticated.")
|
raise AuthError("destroyFavorite() requires you to be authenticated.")
|
||||||
|
|
||||||
def notificationFollow(self, id = None, user_id = None, screen_name = None):
|
def notificationFollow(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/" + id + ".json"
|
apiURL = "http://twitter.com/notifications/follow/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/follow.json?user_id=" + user_id
|
apiURL = "http://twitter.com/notifications/follow/follow.json?user_id=%s" % repr(user_id)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/notifications/follow/follow.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/notifications/follow/follow.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL, ""))
|
return simplejson.load(self.opener.open(apiURL, ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("notificationFollow() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("notificationFollow() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("notificationFollow() requires you to be authenticated.")
|
raise AuthError("notificationFollow() requires you to be authenticated.")
|
||||||
|
|
||||||
def notificationLeave(self, id = None, user_id = None, screen_name = None):
|
def notificationLeave(self, id = None, user_id = None, screen_name = None):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/" + id + ".json"
|
apiURL = "http://twitter.com/notifications/leave/%s.json" % id
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/leave.json?user_id=" + user_id
|
apiURL = "http://twitter.com/notifications/leave/leave.json?user_id=%s" % repr(user_id)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/notifications/leave/leave.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/notifications/leave/leave.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open(apiURL, ""))
|
return simplejson.load(self.opener.open(apiURL, ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("notificationLeave() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("notificationLeave() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("notificationLeave() requires you to be authenticated.")
|
raise AuthError("notificationLeave() requires you to be authenticated.")
|
||||||
|
|
||||||
def getFriendsIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
def getFriendsIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids/" + id + ".json" + "?page=" + page
|
apiURL = "http://twitter.com/friends/ids/%s.json?page=%s" %(id, repr(page))
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids.json?user_id=" + user_id + "&page=" + page
|
apiURL = "http://twitter.com/friends/ids.json?user_id=%s&page=%s" %(repr(user_id), repr(page))
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/friends/ids.json?screen_name=" + screen_name + "&page=" + page
|
apiURL = "http://twitter.com/friends/ids.json?screen_name=%s&page=%s" %(screen_name, repr(page))
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib.request.urlopen(apiURL))
|
return simplejson.load(urllib.request.urlopen(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|
@ -506,11 +506,11 @@ class setup:
|
||||||
def getFollowersIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
def getFollowersIDs(self, id = None, user_id = None, screen_name = None, page = "1"):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids/" + id + ".json" + "?page=" + page
|
apiURL = "http://twitter.com/followers/ids/%s.json?page=%s" %(repr(id), repr(page))
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids.json?user_id=" + user_id + "&page=" + page
|
apiURL = "http://twitter.com/followers/ids.json?user_id=%s&page=%s" %(repr(user_id), repr(page))
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/followers/ids.json?screen_name=" + screen_name + "&page=" + page
|
apiURL = "http://twitter.com/followers/ids.json?screen_name=%s&page=%s" %(screen_name, repr(page))
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib.request.urlopen(apiURL))
|
return simplejson.load(urllib.request.urlopen(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|
@ -519,29 +519,29 @@ class setup:
|
||||||
def createBlock(self, id):
|
def createBlock(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/create/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/create/%s.json" % repr(id), ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("createBlock() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("createBlock() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createBlock() requires you to be authenticated.")
|
raise AuthError("createBlock() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroyBlock(self, id):
|
def destroyBlock(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/destroy/%s.json" % repr(id), ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroyBlock() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroyBlock() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroyBlock() requires you to be authenticated.")
|
raise AuthError("destroyBlock() requires you to be authenticated.")
|
||||||
|
|
||||||
def checkIfBlockExists(self, id = None, user_id = None, screen_name = None):
|
def checkIfBlockExists(self, id = None, user_id = None, screen_name = None):
|
||||||
apiURL = ""
|
apiURL = ""
|
||||||
if id is not None:
|
if id is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists/" + id + ".json"
|
apiURL = "http://twitter.com/blocks/exists/%s.json" % repr(id)
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists.json?user_id=" + user_id
|
apiURL = "http://twitter.com/blocks/exists.json?user_id=%s" % repr(user_id)
|
||||||
if screen_name is not None:
|
if screen_name is not None:
|
||||||
apiURL = "http://twitter.com/blocks/exists.json?screen_name=" + screen_name
|
apiURL = "http://twitter.com/blocks/exists.json?screen_name=%s" % screen_name
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib.request.urlopen(apiURL))
|
return simplejson.load(urllib.request.urlopen(apiURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|
@ -550,11 +550,11 @@ class setup:
|
||||||
def getBlocking(self, page = "1"):
|
def getBlocking(self, page = "1"):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/blocks/blocking.json?page=" + page))
|
return simplejson.load(self.opener.open("http://twitter.com/blocks/blocking.json?page=%s" % repr(page)))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getBlocking() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getBlocking() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getBlocking() requires you to be authenticated")
|
raise AuthError("getBlocking() requires you to be authenticated")
|
||||||
|
|
||||||
def getBlockedIDs(self):
|
def getBlockedIDs(self):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -563,10 +563,10 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getBlockedIDs() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getBlockedIDs() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getBlockedIDs() requires you to be authenticated.")
|
raise AuthError("getBlockedIDs() requires you to be authenticated.")
|
||||||
|
|
||||||
def searchTwitter(self, search_query, **kwargs):
|
def searchTwitter(self, search_query, **kwargs):
|
||||||
searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.parse.urlencode({"q": search_query})
|
searchURL = self.constructApiURL("http://search.twitter.com/search.json", kwargs) + "&" + urllib.parse.urlencode({"q": self.unicode2utf8(search_query)})
|
||||||
try:
|
try:
|
||||||
return simplejson.load(urllib.request.urlopen(searchURL))
|
return simplejson.load(urllib.request.urlopen(searchURL))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
|
|
@ -585,7 +585,7 @@ class setup:
|
||||||
apiURL = "http://search.twitter.com/trends/daily.json"
|
apiURL = "http://search.twitter.com/trends/daily.json"
|
||||||
questionMarkUsed = False
|
questionMarkUsed = False
|
||||||
if date is not None:
|
if date is not None:
|
||||||
apiURL += "?date=" + date
|
apiURL += "?date=%s" % date
|
||||||
questionMarkUsed = True
|
questionMarkUsed = True
|
||||||
if exclude is True:
|
if exclude is True:
|
||||||
if questionMarkUsed is True:
|
if questionMarkUsed is True:
|
||||||
|
|
@ -601,7 +601,7 @@ class setup:
|
||||||
apiURL = "http://search.twitter.com/trends/daily.json"
|
apiURL = "http://search.twitter.com/trends/daily.json"
|
||||||
questionMarkUsed = False
|
questionMarkUsed = False
|
||||||
if date is not None:
|
if date is not None:
|
||||||
apiURL += "?date=" + date
|
apiURL += "?date=%s" % date
|
||||||
questionMarkUsed = True
|
questionMarkUsed = True
|
||||||
if exclude is True:
|
if exclude is True:
|
||||||
if questionMarkUsed is True:
|
if questionMarkUsed is True:
|
||||||
|
|
@ -620,34 +620,34 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("getSavedSearches() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("getSavedSearches() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("getSavedSearches() requires you to be authenticated.")
|
raise AuthError("getSavedSearches() requires you to be authenticated.")
|
||||||
|
|
||||||
def showSavedSearch(self, id):
|
def showSavedSearch(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/show/" + id + ".json"))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/show/%s.json" % repr(id)))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("showSavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("showSavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("showSavedSearch() requires you to be authenticated.")
|
raise AuthError("showSavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
def createSavedSearch(self, query):
|
def createSavedSearch(self, query):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/create.json?query=" + query, ""))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/create.json?query=%s" % query, ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("createSavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("createSavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("createSavedSearch() requires you to be authenticated.")
|
raise AuthError("createSavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
def destroySavedSearch(self, id):
|
def destroySavedSearch(self, id):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
try:
|
try:
|
||||||
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/destroy/" + id + ".json", ""))
|
return simplejson.load(self.opener.open("http://twitter.com/saved_searches/destroy/%s.json" % repr(id), ""))
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("destroySavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("destroySavedSearch() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("destroySavedSearch() requires you to be authenticated.")
|
raise AuthError("destroySavedSearch() requires you to be authenticated.")
|
||||||
|
|
||||||
# The following methods are apart from the other Account methods, because they rely on a whole multipart-data posting function set.
|
# 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"):
|
def updateProfileBackgroundImage(self, filename, tile="true"):
|
||||||
|
|
@ -662,7 +662,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateProfileBackgroundImage() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateProfileBackgroundImage() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You realize you need to be authenticated to change a background image, right?")
|
raise AuthError("You realize you need to be authenticated to change a background image, right?")
|
||||||
|
|
||||||
def updateProfileImage(self, filename):
|
def updateProfileImage(self, filename):
|
||||||
if self.authenticated is True:
|
if self.authenticated is True:
|
||||||
|
|
@ -676,7 +676,7 @@ class setup:
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
raise TwythonError("updateProfileImage() failed with a %s error code." % repr(e.code), e.code)
|
raise TwythonError("updateProfileImage() failed with a %s error code." % repr(e.code), e.code)
|
||||||
else:
|
else:
|
||||||
raise TwythonError("You realize you need to be authenticated to change a profile image, right?")
|
raise AuthError("You realize you need to be authenticated to change a profile image, right?")
|
||||||
|
|
||||||
def encode_multipart_formdata(self, fields, files):
|
def encode_multipart_formdata(self, fields, files):
|
||||||
BOUNDARY = mimetools.choose_boundary()
|
BOUNDARY = mimetools.choose_boundary()
|
||||||
|
|
@ -701,3 +701,11 @@ class setup:
|
||||||
|
|
||||||
def get_content_type(self, filename):
|
def get_content_type(self, filename):
|
||||||
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
||||||
|
|
||||||
|
def unicode2utf8(self, text):
|
||||||
|
try:
|
||||||
|
if isinstance(text, str):
|
||||||
|
text = text.encode('utf-8')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return text
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue