You are on page 1of 6

require 'cgi

'
require 'net/http'
require 'rexml/document'
include REXML

begin
require 'md5'
rescue LoadError
end

module Flickr

class Flickr

attr_reader :nsid, :username, :fullname

def initialize(options = {})
@auth_url = 'http://flickr.com/services/auth/'
@interface = 'http://www.flickr.com/services/rest/'
@secret = options[:secret]
@api_key = options[:api_key]
end

def do_get(uri)
begin
resp =
Net::HTTP.Proxy(ENV['proxy_host'],ENV['proxy_port']).get_response(uri)
doc = Document.new(resp.body.to_s)
if doc.elements['rsp'].attributes['stat'] != 'ok'
error_code =
doc.elements['rsp'].elements['err'].attributes['code']
error_msg = doc.elements['rsp'].elements['err'].attributes['msg']
p "ERROR[#{error_code}]: #{error_msg}"
return false
end
rescue
return false
end
doc
end

def api_sig(hash)
Digest::MD5.hexdigest(@secret + hash.to_a.map.sort_by {|i| i.first.to_s}.join)
end

def query_with_api_sig(request = {})
request[:api_key] = @api_key
request[:api_sig] = api_sig(request)
request.map {|i| i.join '=' }.join('&')
end

def to_query(request = {})
request[:api_key] = @api_key
request.map {|i| i.join '=' }.join('&')
end

def get_login_url(frob='', perms='write')
uri = URI.parse(@auth_url)
uri.query = query_with_api_sig(:frob => frob, :perms => perms,:api_key =>
@api_key)
uri
end

def get_frob
method = 'flickr.auth.getFrob'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method)
frob = nil
doc = do_get(uri)
return nil if !doc
doc.elements.each('rsp/frob') { |f| frob = f.text }
frob
end

def get_token(frob)
method = 'flickr.auth.getToken'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:frob => frob)
token_user = nil
doc = do_get(uri)
return nil if !doc
doc.elements.each('rsp/auth') { |auth|
token_user = {:token => auth.elements['token'].text ,:user =>
auth.elements['user'].attributes}
}
token_user
end

def check_token(auth_token)
method = 'flickr.auth.checkToken'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token => auth_token)

token_user_perms = nil
doc = do_get(uri)
return nil if !doc
doc.elements.each('rsp/auth') { |auth|
token_user_perms = {:perms => auth.elements['perms'].text,:token =>
auth.elements['token'].text ,:user => auth.elements['user'].attributes}
}
token_user_perms
end

def contacts_get_list(auth_token, filters='')
method = 'flickr.contacts.getList'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:filter => filters)
contacts = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/contacts/contact') { |contact| contacts <<
contact.attributes }
return contacts
end
def contacts_get_public_list(nsid)
method = 'flickr.contacts.getPublicList'
uri = URI.parse(@interface)
uri.query = to_query(:method => method,:auth_token => auth_token,:user_id =>
nsid)
contacts = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/contacts/contact') { |contact| contacts <<
contacts.attributes }
contacts
end

def favorites_add(auth_token, photo_id)
method = 'flickr.favorites.add'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:photo_id => photo_id)
return true if do_get(uri)
return false
end

def favorites_remove(auth_token, photo_id)
method = 'flickr.favorites.remove'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:photo_id => photo_id)
return true if do_get(uri)
return false
end

def favorites_get_list(auth_token, nsid='', extras=[], per_page=10, page=1)
method = 'flickr.favorites.getList'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:user_id => user_id,:estras => extras.join(','),:per_page =>
per_page,:page => page)
photos = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/photos/photo') { |photo| photos <<
photo.attributes }
photos
end

def favorites_get_public_list(nsid, extras=[], per_page=100, page=1)
method = 'flickr.favorites.getPublicList'
uri = URI.parse(@interface)
uri.query = to_query(:method => method,:auth_token => auth_token,:user_id =>
user_id,:estras => extras.join(','),:per_page => per_page,:page => page)
photos = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/photos/photo') { |photo| photos <<
photo.attributes }
return photos
end
def photos_add_tags(auth_token, photo_id, tags)
method = 'flickr.photos.addTags'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:photo_id => photo_id,:tags => tags.join(","))
return true if do_get(uri)
return false
end

def photos_set_meta(auth_token, photo_id,title,description)
method = 'flickr.photos.setMeta'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:photo_id => photo_id,:title => title.sub(" ","+"),:description =>
description.sub(" ","+"))
return true if do_get(uri)
return false
end

def photos_get_contacts_photos(auth_token, count=10, just_friends=0,
single_photo=0, include_self=0)
method = 'flickr.photos.getContactsPhotos'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:count => count,:just_friends => just_friends,:single_photo =>
single_photo,:include_self => include_self)
photos = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/photos/photo') { |photo| photos <<
photo.attributes }
return photos
end

def photos_get_contacts_public_photos(nsid, count=10, just_friends=0,
single_photo=0, include_self=0)
method = 'flickr.photos.getContactsPublicPhotos'
uri = URI.parse(@interface)
uri.query = to_query(:method => method,:user_id=> nsid,:count =>
count,:just_friends => just_friends,:single_photo => single_photo,:include_self
=> include_self)
photos = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/photos/photo') { |photo|photos <<
photo.attributes }
photos
end

def photos_search(auth_token,tags, page=1,user_id="",tag_mode='any',
license=5, per_page=10, sort="interestingness-desc")
method = 'flickr.photos.search'
uri = URI.parse(@interface)
uri.query = query_with_api_sig(:method => method,:auth_token =>
auth_token,:tags => tags.join(","),:user_id => user_id,:tag_mode=>
tag_mode,:license => license,:per_page => per_page,:page => page,:sort =>
sort)
photo_ids = []
doc = do_get(uri)
return [] if !doc
doc.elements.each('rsp/photos/photo') { |x| photo_ids <<
x.attributes['id'] }
photo_ids
end

def photos_get_info(photo_id)
method = 'flickr.photos.getInfo'
uri = URI.parse(@interface)
uri.query = to_query(:photo_id=> nsid)
photo_info = {}
doc = do_get(uri)
return false if !doc
doc.elements.each('rsp/photo') { |photo|
photo_info[:id] = photo.attributes['id']
photo_info[:owner] = photo.elements['owner'].attributes
photo_info[:date] = photo.elements['dates'].attributes
photo_info[:isfavorite] = photo.attributes['isfavorite']
photo_info[:license] = photo.attributes['license']
photo_info[:title] = photo.elements['title'].text
photo_info[:description] = photo.elements['description'].text
photo_info[:urls] = photo.elements['urls']
tags = []
photo.elements['tags'].each('tags/tag'){ tags_arr << tag.text }
photo_info[:tags] = tags
urls = []
photo.elements.each('urls/url') { |url| urls_arr << url.text }
photo_info[:urls] = urls
}
photo_info
end

def photos_get_sizes(photo_id)
method = 'flickr.photos.getSizes'
uri = URI.parse(@interface)
uri.query = to_query(:photo_id=> nsid)
doc = do_get(uri)
return false if !doc
doc.elements.each('rsp/sizes/size') { |sizes| return sizes.attributes }
end

end

class Upload < Flickr

def initialize(options = {})
super(options = {})
end

def _to_multipart(name, value)
return "Content-Disposition: form-data;
name=\"#{CGI::escape(name)}\"\r\n\r\n#{value}\r\n"
end

def _file_to_multipart(name, file, content)
return "Content-Disposition: form-data; name=\"#{CGI::escape(name)}\";
filename=\"#{file}\"\r\n" +
"Content-Transfer-Encoding: binary\r\n" +
"Content-Type: image/jpeg\r\n\r\n" + content + "\r\n"
end

def _prepare_query(params)
query = params.collect { |k, v|
if v.respond_to?(:read)
q = _file_to_multipart(k, v.path, v.read)
else
q = _to_multipart(k, v)
end
"--" + @boundary + "\r\n" + q
}.join("") + "--" + @boundary + "--"
header = {"Content-type" => "multipart/form-data, boundary=" +
@boundary + " "}
return query, header
end

def upload(auth_token, photo, title='', description='', tags=[],
is_public=1,\
is_friend=0, is_family=0)
@flickr_host = 'www.flickr.com'
@upload_action = '/services/upload/'
@boundary = MD5.md5(photo).to_s
file = File.new(photo, 'rb')
params = {
'auth_token' => auth_token,
'title' => title,
'description' => description,
'tags' => tags.join(','),
'is_public' => is_public,
'is_family' => is_family,
'is_friend' => is_friend
}
params['api_sig'] = api_sig(params)

query, header = _prepare_query(params)

file.close
Net::HTTP.Proxy(ENV['proxy_host'],ENV['proxy_port']).start(@flickr_host, 80) {
|http|
response = http.post(@upload_action, query, header)
doc = Document.new(response.body)
status = doc.elements['rsp'].attributes['stat']
if status == "ok"
photoid = doc.elements['rsp/photoid'].text
return photoid
else
return false
end
}
end
end

end