Skip to content

Instantly share code, notes, and snippets.

@rivernate
Last active March 10, 2016 21:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rivernate/97e4e6bc86c1ebd69f16 to your computer and use it in GitHub Desktop.
Save rivernate/97e4e6bc86c1ebd69f16 to your computer and use it in GitHub Desktop.
File Upload
Canvas File Upload Example
require 'faraday'
require 'faraday_middleware'
class CanvasFileUpload
attr_reader :access_token, :url, :file_path
def initialize(access_token:, url:)
@access_token = access_token
@url = url
@file_path = file_path
end
def upload_file(file_path)
params = declare_file(file_params(file_path))
confirm_url = post_file(params['upload_url'], params['upload_params'], file_path)
confirm_file_upload(confirm_url)
end
private
def declare_file(params)
response = canvas_connection.post(url, params)
raise 'DeclareFileFailedException' unless response.success?
response.body
end
def post_file(url, params, file_path)
puts params
params['Filename'] = File.basename(file_path)
params['file'] = Faraday::UploadIO.new(file_path, params['content-type'])
response = upload_connection.post(url, params)
if [302, 303].include? response.status #success if it is a redirect
response.headers['Location']
else
raise 'FailedFileUpload'
end
end
def confirm_file_upload(url)
uri = URI(url)
response = canvas_connection.post(url)
raise 'ConfirmFileFailedException' unless response.success?
response.body
end
def canvas_connection
@conn ||= Faraday.new do |faraday|
faraday.request :multipart # form-encode POST params
faraday.request :url_encoded
faraday.response :logger # log requests to STDOUT
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
faraday.authorization :Bearer, @access_token
faraday.response :json, :content_type => /\bjson$/
end
end
def base_url
@domain ||= URI.join(url, '/').to_s
end
def file_params(file_path)
{
size: File.open(file_path).size,
name: File.basename(file_path)
}
end
def upload_connection
Faraday.new do |f|
f.request :multipart
f.request :url_encoded
f.adapter :net_http
end
end
end
require_relative 'canvas_file_upload'
require 'webmock/rspec'
RSpec.describe CanvasFileUpload do
subject {CanvasFileUpload.new(access_token: 'token', url: 'http://uploader')}
it 'uploads a file to canvas' do
stub_request(:post, "http://uploader").
with(:body => {"name"=>"canvas_file_upload_spec.rb", "size"=>/.*/},
:headers => {'Authorization'=>'Bearer token', 'Content-Type'=>'application/x-www-form-urlencoded'}).
to_return(:status => 200,
:body => {upload_url: 'http://uploader-frd', upload_params: {a:'hi',b:'so neat'}}.to_json,
headers: {'Content-Type' => 'application/json'})
stub_request(:post, "http://uploader-frd/").
with(:headers => {'Content-Type'=>/multipart\/form-data/}).
to_return(:status => 302, :body => "", :headers => {'Location' => 'http://confirm-url'})
stub_request(:post, "http://confirm-url/").
with(:headers => {'Authorization'=>'Bearer token'}).
to_return(:status => 200, :body => "", :headers => {})
subject.upload_file(__FILE__)
end
end
source 'https://rubygems.org'
gem 'faraday'
gem 'faraday_middleware'
gem 'rspec'
gem 'webmock'
GEM
remote: https://rubygems.org/
specs:
addressable (2.4.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
diff-lcs (1.2.5)
faraday (0.9.1)
multipart-post (>= 1.2, < 3)
faraday_middleware (0.9.1)
faraday (>= 0.7.4, < 0.10)
hashdiff (0.3.0)
multipart-post (2.0.0)
rspec (3.2.0)
rspec-core (~> 3.2.0)
rspec-expectations (~> 3.2.0)
rspec-mocks (~> 3.2.0)
rspec-core (3.2.3)
rspec-support (~> 3.2.0)
rspec-expectations (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-mocks (3.2.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.2.0)
rspec-support (3.2.2)
safe_yaml (1.0.4)
webmock (1.24.2)
addressable (>= 2.3.6)
crack (>= 0.3.2)
hashdiff
PLATFORMS
ruby
DEPENDENCIES
faraday
faraday_middleware
rspec
webmock
BUNDLED WITH
1.11.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment