Skip to content

Commit

Permalink
Merge 257463a into 058bd82
Browse files Browse the repository at this point in the history
  • Loading branch information
fx committed Jun 23, 2015
2 parents 058bd82 + 257463a commit 113b927
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 6 deletions.
17 changes: 13 additions & 4 deletions lib/twitter/rest/request.rb
Expand Up @@ -34,18 +34,27 @@ def initialize(client, request_method, path, options = {})
def perform
options_key = @request_method == :get ? :params : :form
response = http_client.with(@headers).public_send(@request_method, @uri.to_s, options_key => @options)
response_body = symbolize_keys!(response.parse)
response_body = response.body.empty? ? '' : symbolize_keys!(response.parse)
response_headers = response.headers
fail_or_return_response_body(response.code, response_body, response_headers)
end

private

def merge_multipart_file!(options)
key = options.delete(:key)
file = options.delete(:file)

if file.is_a?(StringIO)
options.merge!(key => HTTP::FormData::File.new(file, mime_type: 'video/mp4'))
else
options.merge!(key => HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file))))
end
end

def set_multipart_options!(request_method, options)
if request_method == :multipart_post
key = options.delete(:key)
file = options.delete(:file)
options.merge!(key => HTTP::FormData::File.new(file, filename: File.basename(file), mime_type: mime_type(File.basename(file))))
merge_multipart_file!(options)
@request_method = :post
@headers = Twitter::Headers.new(@client, @request_method, @uri).request_headers
else
Expand Down
31 changes: 29 additions & 2 deletions lib/twitter/rest/tweets.rb
Expand Up @@ -296,8 +296,35 @@ def retweeters_ids(*args)

private

def upload(media)
Twitter::REST::Request.new(self, :multipart_post, 'https://upload.twitter.com/1.1/media/upload.json', key: :media, file: media).perform
# Uploads images and videos. Videos require multiple requests and uploads in chunks of 5 Megabytes.
# The only supported video format is mp4.
#
# @see https://dev.twitter.com/rest/public/uploading-media
def upload(media) # rubocop:disable MethodLength, AbcSize
if !(File.basename(media) =~ /\.mp4$/)
Twitter::REST::Request.new(self, :multipart_post, 'https://upload.twitter.com/1.1/media/upload.json', key: :media, file: media).perform
else
init = Twitter::REST::Request.new(self, :post, 'https://upload.twitter.com/1.1/media/upload.json',
command: 'INIT',
media_type: 'video/mp4',
total_bytes: media.size).perform

until media.eof?
chunk = media.read(5_000_000)
seg ||= -1
Twitter::REST::Request.new(self, :multipart_post, 'https://upload.twitter.com/1.1/media/upload.json',
command: 'APPEND',
media_id: init[:media_id],
segment_index: seg += 1,
key: :media,
file: StringIO.new(chunk)).perform
end

media.close

Twitter::REST::Request.new(self, :post, 'https://upload.twitter.com/1.1/media/upload.json',
command: 'FINALIZE', media_id: init[:media_id]).perform
end
end

def array_wrap(object)
Expand Down
Binary file added spec/fixtures/1080p.mp4
Binary file not shown.
7 changes: 7 additions & 0 deletions spec/twitter/rest/tweets_spec.rb
Expand Up @@ -445,6 +445,13 @@
expect(a_post('/1.1/statuses/update.json')).to have_been_made
end
end
context 'with a mp4 video' do
it 'requests the correct resources' do
@client.update_with_media('You always have options', fixture('1080p.mp4'))
expect(a_request(:post, 'https://upload.twitter.com/1.1/media/upload.json')).to have_been_made.times(3)
expect(a_post('/1.1/statuses/update.json')).to have_been_made
end
end
context 'with a Tempfile' do
it 'requests the correct resource' do
@client.update_with_media('You always have options', Tempfile.new('tmp'))
Expand Down

0 comments on commit 113b927

Please sign in to comment.