00001
00002 import imp
00003 try:
00004 imp.find_module('rostwitter')
00005
00006
00007
00008
00009
00010
00011
00012
00013 except:
00014 import roslib; roslib.load_manifest('rostwitter')
00015
00016 import rospy
00017 import yaml,sys
00018 import re, os
00019 from io import BytesIO
00020 from StringIO import StringIO
00021
00022 from std_msgs.msg import String
00023
00024 global Api, CKEY, CSECRET, AKEY, ASECRET
00025
00026 import requests
00027 import oauth2 as oauth
00028 import base64
00029 import json as simplejson
00030
00031
00032
00033 class twitter(object):
00034 def __init__(self,
00035 consumer_key=None,
00036 consumer_secret=None,
00037 access_token_key=None,
00038 access_token_secret=None):
00039 self._consumer_key = consumer_key
00040 self._consumer_secret = consumer_secret
00041 self._access_token_key = access_token_key
00042 self._access_token_secret = access_token_secret
00043
00044 self._signature_method_plaintext = oauth.SignatureMethod_PLAINTEXT()
00045 self._signature_method_hmac_sha1 = oauth.SignatureMethod_HMAC_SHA1()
00046
00047 self._oauth_token = oauth.Token(key=access_token_key, secret=access_token_secret)
00048 self._oauth_consumer = oauth.Consumer(key=consumer_key, secret=consumer_secret)
00049
00050 def _RequestUrl(self, url, verb, data=None):
00051 req = oauth.Request.from_consumer_and_token(self._oauth_consumer,
00052 token=self._oauth_token,
00053 http_method=verb,
00054 http_url=url)
00055 req.sign_request(self._signature_method_hmac_sha1, self._oauth_consumer, self._oauth_token)
00056
00057 headers = req.to_header()
00058
00059 if verb == 'POST':
00060 return requests.post(
00061 url,
00062 headers=headers,
00063 files=data
00064 )
00065 if verb == 'GET':
00066 url = self._BuildUrl(url, extra_params=data)
00067 return requests.get(
00068 url,
00069 headers=headers
00070 )
00071 return 0
00072
00073 def PostUpdate(self, status):
00074 url = 'https://api.twitter.com/1.1/statuses/update.json'
00075
00076 data = {'status': StringIO(status)}
00077 json = self._RequestUrl(url, 'POST', data=data)
00078 data = simplejson.loads(json.content)
00079 if 'error' in data:
00080 raise Exception(data)
00081 return data
00082
00083 def PostMedia(self, status, media):
00084 url = 'https://api.twitter.com/1.1/statuses/update_with_media.json'
00085
00086 data = {'status': StringIO(status)}
00087 data['media[]'] = open(str(media), 'rb')
00088 json = self._RequestUrl(url, 'POST', data=data)
00089 data = simplejson.loads(json.content)
00090 if 'errors' in data:
00091 raise Exception(data)
00092 return data
00093
00094 def tweet(dat):
00095 global Api
00096 message = dat.data
00097 rospy.loginfo(rospy.get_name() + " sending %s", message)
00098
00099 m = re.search('/\S+\.(jpeg|jpg|png|gif)', message)
00100 if m:
00101 filename = m.group(0)
00102 message = re.sub(filename,"",message)
00103 if os.path.exists(filename):
00104
00105 ret = Api.PostMedia(message, filename)
00106
00107 else:
00108 ret = Api.PostUpdate(message[0:140])
00109
00110
00111 rospy.loginfo(rospy.get_name() + " receiving %s", ret)
00112 return
00113
00114 def load_oauth_settings():
00115 global CKEY, CSECRET, AKEY, ASECRET
00116 account_info = rospy.get_param('account_info', '/var/lib/robot/account.yaml')
00117
00118 try:
00119 key = yaml.load(open(account_info))
00120 CKEY = key['CKEY']
00121 CSECRET = key['CSECRET']
00122 AKEY = key['AKEY']
00123 ASECRET = key['ASECRET']
00124 except IOError as e:
00125 rospy.logerr('"%s" not found'%account_info)
00126 rospy.logerr("$ rosrun rostwitter get_access_token.py")
00127 rospy.logerr("cat /var/lib/robot/%s <<EOF"%account_info)
00128 rospy.logerr("CKEY: xxx")
00129 rospy.logerr("CSECRET: xxx")
00130 rospy.logerr("AKEY: xxx")
00131 rospy.logerr("ASECRET: xxx")
00132 rospy.logerr("EOF")
00133 sys.exit(-1)
00134
00135 if __name__ == '__main__':
00136 global Api
00137 rospy.init_node('rostwitter', anonymous=True)
00138 load_oauth_settings()
00139 Api = twitter(consumer_key=CKEY,
00140 consumer_secret=CSECRET,
00141 access_token_key=AKEY,
00142 access_token_secret=ASECRET)
00143 rospy.Subscriber("tweet", String, tweet)
00144 rospy.spin()
00145
00146
00147
00148