lib/googlecalendar/service.rb in gcalapi-0.0.4 vs lib/googlecalendar/service.rb in gcalapi-0.1.0

- old
+ new

@@ -1,216 +1,66 @@ -require "cgi" -require "uri" -require "net/http" -require "net/https" -require "open-uri" -require "nkf" -require "time" +require "googlecalendar/service_base" -Net::HTTP.version_1_2 - module GoogleCalendar - - class AuthenticationFailed < StandardError; end #:nodoc: all - # - # This class interacts with google calendar service. + # This class interacts with google calendar service. + # If you want to use ClientLogin for authentication, use this class. + # If you want to use AuthSub, use ServiceAuthSub. # - class Service - # Server name to Authenticate - AUTH_SERVER = "www.google.com" + class Service < ServiceBase # Server Path to authenticate AUTH_PATH = "/accounts/ClientLogin" # URL to get calendar list CALENDAR_LIST_PATH = "http://www.google.com/calendar/feeds/" - # proxy server address - @@proxy_addr = nil - def self.proxy_addr - @@proxy_addr - end - - def self.proxy_addr=(addr) - @@proxy_addr=addr - end - - # proxy server port number - @@proxy_port = nil - def self.proxy_port - @@proxy_port - end - - def self.proxy_port=(port) - @@proxy_port = port - end - - # proxy server username - @@proxy_user = nil - def self.proxy_user - @@proxy_user - end - - def self.proxy_user=(user) - @@proxy_user = user - end - - # proxy server password - @@proxy_pass = nil - def self.proxy_pass - @@proxy_pass - end - - def self.proxy_pass=(pass) - @@proxy_pass = pass - end - - - def initialize(email, pass) - @email = email - @pass = pass - @session = nil - @cookie = nil - @auth = nil - end - # # get the list of user's calendars and returns http response object # def calendar_list + logger.info("-- calendar list st --") if logger auth unless @auth uri = URI.parse(CALENDAR_LIST_PATH + @email) - do_get(uri, "Authorization" => "GoogleLogin auth=#{@auth}") + res = do_get(uri, {}) + logger.info("-- calendar list en(#{res.message}) --") if logger + res end alias :calendars :calendar_list - # - # send query for events of a calendar and returns http response object. - # available condtions are - # * :q => query string - # * :max-results => max contents count. (default: 25) - # * :start-index => 1-based index of the first result to be retrieved - # * :orderby => the order of retrieved data. - # * :published-min => Bounds on the entry publication date(oldest) - # * :published-max => Bounds on the entry publication date(newest) - # * :updated-min => Bounds on the entry update date(oldest) - # * :updated-max => Bounds on the entry update date(newest) - # * :author => Entry author - # - # For detail, see http://code.google.com/apis/gdata/protocol.html#Queries - # - def query(cal_url, conditions) - auth unless @auth - uri = URI.parse(cal_url) - uri.query = conditions.map do |key, val| - "#{key}=#{URI.escape(val.kind_of?(Time) ? val.getutc.iso8601 : val.to_s)}" - end.join("&") - do_get(uri, "Authorization" => "GoogleLogin auth=#{@auth}") - end - - # - # delete an event. - # - def delete(feed) - auth unless @auth - uri = URI.parse(feed) - do_post(uri, - {"X-HTTP-Method-Override" => "DELETE", - "Authorization" => "GoogleLogin auth=#{@auth}"}, - "DELETE " + uri.path) - end - - # - # insert an event - # - def insert(feed, event) - auth unless @auth - uri = URI.parse(feed) - do_post(uri, - {"Authorization" => "GoogleLogin auth=#{@auth}", - "Content-Type" => "application/atom+xml", - "Content-Length" => event.length.to_s}, event) - end - - # - # update an event. - # - def update(feed, event) - auth unless @auth - uri = URI.parse(feed) - do_post(uri, - {"X-HTTP-Method-Override" => "PUT", - "Authorization" => "GoogleLogin auth=#{@auth}", - "Content-Type" => "application/atom+xml", - "Content-Length" => event.length.to_s}, event) - end - - private - - # authencate + def initialize(email, pass) + @email = email + @pass = pass + @session = nil + @cookie = nil + @auth = nil + end + + private def auth https = Net::HTTP.new(AUTH_SERVER, 443, @@proxy_addr, @@proxy_port, @@proxy_user, @@proxy_pass) https.use_ssl = true https.verify_mode = OpenSSL::SSL::VERIFY_NONE head = {'Content-Type' => 'application/x-www-form-urlencoded'} + logger.info "-- auth st --" if logger https.start do |w| res = w.post(AUTH_PATH, "Email=#{@email}&Passwd=#{@pass}&source=company-app-1&service=cl", head) + logger.debug res if logger if res.body =~ /Auth=(.+)/ @auth = $1 else + if logger + logger.fatal(res) + logger.fatal(res.body) + end raise AuthenticationFailed end end + logger.info "-- auth en --" if logger end - - def do_post(uri, header, content) - res = nil - try_http(uri, header, content) do |http,path,head,args| - cont = args[0] - res = http.post(path, cont, head) - end - res + + def add_authorize_header(header) + header["Authorization"] = "GoogleLogin auth=#{@auth}" end - - def do_get(uri, header) - res = nil - try_http(uri, header) do |http,path,head| - res = http.get(path, head) - end - res - end - - def try_http(uri, header, *args) - res = nil - Net::HTTP.start(uri.host, uri.port, @@proxy_addr, @@proxy_port, @@proxy_user, @@proxy_pass) do |http| - header["Cookie"] = @cookie if @cookie - res = yield(http, path_with_authorized_query(uri), header, args) - if res.code == "302" - ck = sess = nil - ck = res["set-cookie"] if res.key?("set-cookie") - uri = URI.parse(res["location"]) if res.key?("location") - if uri && uri.query - qr = CGI.parse(uri.query) - sess = qr["gsessionid"][0] if qr.key?("gsessionid") - end - if ck && sess - header["Cookie"] = @cookie = ck - @session = sess - res = yield(http, path_with_authorized_query(uri), header, args) - else - p res - end - end - end - res - end - - def path_with_authorized_query(uri) - query = CGI.parse(uri.query.nil? ? "" : uri.query) - query["gsessionid"] = [@session] if @session - qs = query.map do |k,v| "#{CGI.escape(k)}=#{CGI.escape(v[0])}" end.join("&") - qs.empty? ? uri.path : "#{uri.path}?#{qs}" - end - end # class Service -end # module + end # Service +end # GoogleCalendar