7 from requests_oauthlib
import OAuth1
10 MEDIA_ENDPOINT_URL
= 'https://upload.twitter.com/1.1/media/upload.json'
11 POST_TWEET_URL
= 'https://api.twitter.com/1.1/statuses/update.json'
13 CONSUMER_KEY
= 'hJHyPhuU7nSVHrKTVsGVDM4Lw'
14 CONSUMER_SECRET
= '8UCYePqc1y9DY6mg0yQzLoTuq57AIysype2Si63714uACGMCbO'
16 with
open(os
.path
.expanduser('~') + '/.rainbow_oauth') as fp
:
17 ACCESS_TOKEN
= fp
.readline().rstrip('\n')
18 ACCESS_TOKEN_SECRET
= fp
.readline().rstrip('\n')
20 oauth
= OAuth1(CONSUMER_KEY
,
21 client_secret
=CONSUMER_SECRET
,
22 resource_owner_key
=ACCESS_TOKEN
,
23 resource_owner_secret
=ACCESS_TOKEN_SECRET
)
26 class VideoTweet(object):
28 def __init__(self
, file_name
):
30 Defines video tweet properties
32 self
.video_filename
= file_name
33 self
.total_bytes
= os
.path
.getsize(self
.video_filename
)
35 self
.processing_info
= None
38 def upload_init(self
):
46 'media_type': 'video/mp4',
47 'total_bytes': self
.total_bytes
,
48 'media_category': 'tweet_video'
51 req
= requests
.post(url
=MEDIA_ENDPOINT_URL
, data
=request_data
, auth
=oauth
)
52 media_id
= req
.json()['media_id']
54 self
.media_id
= media_id
56 print('Media ID: %s' % str(media_id
))
59 def upload_append(self
):
61 Uploads media in chunks and appends to chunks uploaded
65 file = open(self
.video_filename
, 'rb')
67 while bytes_sent
< self
.total_bytes
:
68 chunk
= file.read(4*1024*1024)
74 'media_id': self
.media_id
,
75 'segment_index': segment_id
82 req
= requests
.post(url
=MEDIA_ENDPOINT_URL
, data
=request_data
, files
=files
, auth
=oauth
)
84 if req
.status_code
< 200 or req
.status_code
> 299:
85 print(req
.status_code
)
89 segment_id
= segment_id
+ 1
90 bytes_sent
= file.tell()
92 print('%s of %s bytes uploaded' % (str(bytes_sent
), str(self
.total_bytes
)))
94 print('Upload chunks complete.')
97 def upload_finalize(self
):
99 Finalizes uploads and starts video processing
104 'command': 'FINALIZE',
105 'media_id': self
.media_id
108 req
= requests
.post(url
=MEDIA_ENDPOINT_URL
, data
=request_data
, auth
=oauth
)
111 self
.processing_info
= req
.json().get('processing_info', None)
115 def check_status(self
):
117 Checks video processing status
119 if self
.processing_info
is None:
122 state
= self
.processing_info
['state']
124 print('Media processing status is %s ' % state
)
126 if state
== u
'succeeded':
129 if state
== u
'failed':
132 check_after_secs
= self
.processing_info
['check_after_secs']
134 print('Checking after %s seconds' % str(check_after_secs
))
135 time
.sleep(check_after_secs
)
141 'media_id': self
.media_id
144 req
= requests
.get(url
=MEDIA_ENDPOINT_URL
, params
=request_params
, auth
=oauth
)
146 self
.processing_info
= req
.json().get('processing_info', None)
152 Publishes Tweet with attached video
155 'status': tweet_text
,
156 'media_ids': self
.media_id
159 req
= requests
.post(url
=POST_TWEET_URL
, data
=request_data
, auth
=oauth
)
163 if __name__
== '__main__':
164 if (len(sys
.argv
) < 2):
165 print('error: expected 2+ arguments, path to video (no spaces) and tweet text')
167 VIDEO_FILENAME
= sys
.argv
[1]
169 tweet_text
= ' '.join(sys
.argv
[2:])
171 videoTweet
= VideoTweet(VIDEO_FILENAME
)
172 videoTweet
.upload_init()
173 videoTweet
.upload_append()
174 videoTweet
.upload_finalize()