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 ret = None
00101 if m:
00102 filename = m.group(0)
00103 message = re.sub(filename,"",message)
00104 if os.path.exists(filename):
00105
00106 ret = Api.PostMedia(message[0:116], filename)
00107
00108 else:
00109 rospy.logerr(rospy.get_name() + " %s could not find", filename)
00110 else:
00111 ret = Api.PostUpdate(message[0:140])
00112
00113
00114 rospy.loginfo(rospy.get_name() + " receiving %s", ret)
00115 return
00116
00117 def load_oauth_settings():
00118 global CKEY, CSECRET, AKEY, ASECRET
00119 account_info = rospy.get_param('account_info', '/var/lib/robot/account.yaml')
00120
00121 try:
00122 key = yaml.load(open(account_info))
00123 CKEY = key['CKEY']
00124 CSECRET = key['CSECRET']
00125 AKEY = key['AKEY']
00126 ASECRET = key['ASECRET']
00127 except IOError as e:
00128 rospy.logerr('"%s" not found'%account_info)
00129 rospy.logerr("$ get access token from https://apps.twitter.com/")
00130 rospy.logerr("cat /var/lib/robot/%s <<EOF"%account_info)
00131 rospy.logerr("CKEY: xxx")
00132 rospy.logerr("CSECRET: xxx")
00133 rospy.logerr("AKEY: xxx")
00134 rospy.logerr("ASECRET: xxx")
00135 rospy.logerr("EOF")
00136 sys.exit(-1)
00137
00138 if __name__ == '__main__':
00139 global Api
00140 rospy.init_node('rostwitter', anonymous=True)
00141 load_oauth_settings()
00142 Api = twitter(consumer_key=CKEY,
00143 consumer_secret=CSECRET,
00144 access_token_key=AKEY,
00145 access_token_secret=ASECRET)
00146 rospy.Subscriber("tweet", String, tweet)
00147 rospy.spin()
00148
00149
00150
00151