Created
April 18, 2009 20:01
-
-
Save hayesdavis/97756 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 | |
# http://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 |
yes ,I see. thank you!
Updated version that uses the current API resource URIs here: https://gist.github.com/1181291
@drewww, I merged in your changes. Thanks for updating that.
Thanks for the update. I merged in your changes so no one else ends up on
this gist and has trouble.
Hayes
…On Tue, Aug 30, 2011 at 9:27 AM, drewww < ***@***.***>wrote:
Updated version that uses the current API resource URIs here:
https://gist.github.com/1181291
##
Reply to this email directly or view it on GitHub:
https://gist.github.com/97756
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I haven't looked at this gist in a while... I create image_file on line #37 which is a File object created from ARGV[0] passed in on the command line. I pass that object into add_multipart_data on line #92. Let me know if I'm missing something.