# mixi-photo v0.0.4 (2007/12/08 2:30) # mixi photo upload library # # (C) Satoshi Kojima 2007 # http://www.skoji.jp/blog/ require 'digest/sha1' require 'Base64' require 'net/http' require 'uri' require 'time' require 'rexml/document' class MixiPhoto attr_accessor :albums def initialize(username, password) @wsseHeaderFunc = Proc.new { nonce=Array.new(10){rand(256)}.pack('C*') timenow=Time.now.iso8601 digest = Base64.encode64(Digest::SHA1.digest(nonce+timenow+password)).strip { 'X-WSSE' => "UsernameToken Username=\"#{username}\", PasswordDigest=\"#{digest}\", Nonce=\"#{Base64.encode64(nonce).strip}\", Created=\"#{timenow}\"" } } connect end # mode="public", "protected" or "friends". when mode=protected, parameter key is required. def createAlbum(albumName, description, mode="public", key="") http = Net::HTTP.new(@photo_uri.host) response = http.post(@photo_uri.path, self.albumRequestXml(albumName, description, mode, key), @wsseHeaderFunc.call.update({'Content-Type' => 'text/xml'})) raise "#{response.body}" unless response.is_a?(Net::HTTPCreated) return MixiPhotoAlbum.new(albumName, URI.parse(response["location"]), @wsseHeaderFunc) end def connect server = 'photo.mixi.jp' path = '/atom/r=4/' http = Net::HTTP.new(server) response = http.get(path, @wsseHeaderFunc.call) raise "#{response.body}" unless response.is_a?(Net::HTTPSuccess) # get album data @albums = [] doc = REXML::Document.new response.body doc.elements.each('/service/workspace/collection') { |e| accept = e.elements['accept'].nil? ? "" : e.elements['accept'].text if accept == 'image/jpeg' @albums << MixiPhotoAlbum.new(e.elements["atom:title"].text,URI.parse(e.attributes["href"]), @wsseHeaderFunc) else @photo_uri = URI.parse(e.attributes["href"]) end } end def albumRequestXml(albumName, description, mode, key) if (mode=="protected") keytag="#{key}" else keytag = "" end return %Q( #{albumName} #{description} #{Time.now.iso8601} #{mode} #{keytag} ) end protected :connect, :albumRequestXml end class MixiPhotoAlbum attr_accessor :title def initialize(title, uri, wsseHeaderFunc) @title = title @uri = uri @wsseHeaderFunc = wsseHeaderFunc end def uploadPhoto(photoPath) mimetype = 'image/jpeg' http = Net::HTTP.new(@uri.host) response = http.post(@uri.path, open(photoPath, "rb").read, @wsseHeaderFunc.call().update({'Content-Type' => mimetype})) raise "#{response.body}" unless response.is_a?(Net::HTTPCreated) return response.body end end