Skip to content

Instantly share code, notes, and snippets.

@hayesdavis
Created April 18, 2009 20:01
Show Gist options
  • Select an option

  • Save hayesdavis/97756 to your computer and use it in GitHub Desktop.

Select an option

Save hayesdavis/97756 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# This script performs an OAuth authorized POST with multipart encoding to
# http://twitter.com/account/update_profile_image.json
#
# This code is primarily taken from my Grackle library's implementation at
# https://github.com/hayesdavis/grackle
#
# RUNNING THIS WILL CHANGE AN ACCOUNT'S PROFILE IMAGE. BE CAREFUL.
#
# Instructions to run this script:
# 1) Install the OAuth gem if you don't have it (sudo gem install oauth)
# 2) Create an oauth.yml file in your working directory (see format below)
# 3) Run "ruby update_profile_image.rb /Path/to/image/file"
#
# oauth.yml format:
# consumer_key: APP_CONSUMER_KEY_FROM_TWITTER
# consumer_secret: APP_CONSUMER_SECRET_FROM_TWITTER
# token: ACCESS_TOKEN_FOR_A_USER_RETRIEVED_VIA_OAUTH_FLOW
# token_secret: ACCESS_TOKEN_SECRET_FOR_A_USER_RETRIEVED_VIA_OAUTH_FLOW
require 'rubygems'
require 'oauth'
require 'open-uri'
require 'net/http'
require 'yaml'
require 'cgi'
CRLF = "\r\n"
if ARGV.size < 1
puts "Usage: update_profile_image.rb path_to_image_file"
puts "e.g. update_profile_image.rb /Users/me/my_photo.jpg"
exit(1)
end
image_file = File.new(ARGV[0])
begin
oauth_config = YAML.load(IO.read('oauth.yml'))
#Make sure oauth_config contains symbol keys
oauth_config.replace(oauth_config.inject({}) {|h, (key,value)| h[key.to_sym] = value; h})
rescue
puts "You must have an oauth.yml file with your consumer and access info"
end
#Quick and dirty method for determining mime type of uploaded file
def mime_type(file)
case
when file =~ /\.jpg/ then 'image/jpg'
when file =~ /\.gif$/ then 'image/gif'
when file =~ /\.png$/ then 'image/png'
else 'application/octet-stream'
end
end
#Encodes the request as multipart
def add_multipart_data(req,params)
boundary = Time.now.to_i.to_s(16)
req["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
body = ""
params.each do |key,value|
esc_key = CGI.escape(key.to_s)
body << "--#{boundary}#{CRLF}"
if value.respond_to?(:read)
body << "Content-Disposition: form-data; name=\"#{esc_key}\"; filename=\"#{File.basename(value.path)}\"#{CRLF}"
body << "Content-Type: #{mime_type(value.path)}#{CRLF*2}"
body << value.read
else
body << "Content-Disposition: form-data; name=\"#{esc_key}\"#{CRLF*2}#{value}"
end
body << CRLF
end
body << "--#{boundary}--#{CRLF*2}"
req.body = body
req["Content-Length"] = req.body.size
end
#Uses the OAuth gem to add the signed Authorization header
def add_oauth(req,auth)
consumer = OAuth::Consumer.new(
auth[:consumer_key],auth[:consumer_secret],{:site=>'http://api.twitter.com'}
)
access_token = OAuth::AccessToken.new(consumer,auth[:token],auth[:token_secret])
consumer.sign!(req,access_token)
end
#Actually do the request and print out the response
url = URI.parse('http://api.twitter.com/1/account/update_profile_image.json')
Net::HTTP.new(url.host, url.port).start do |http|
req = Net::HTTP::Post.new(url.request_uri)
add_multipart_data(req,:image=>image_file)
add_oauth(req,oauth_config)
res = http.request(req)
puts res.body
end
@hayesdavis
Copy link
Copy Markdown
Author

@drewww, I merged in your changes. Thanks for updating that.

@hayesdavis
Copy link
Copy Markdown
Author

hayesdavis commented Aug 30, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment