class MealTicket

Public Class Methods

new(app) click to toggle source
# File lib/meal_ticket.rb, line 64
def initialize(app)
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/meal_ticket.rb, line 68
def call(env)
  @env = env
  if env["PATH_INFO"] =~ /^\/meal_ticket\/facebook_callback/
    facebook_callback
  elsif env["PATH_INFO"] =~ /^\/meal_ticket\/flickr_callback/
    flickr_callback
  else
    @app.call(env)
  end
end
facebook_callback() click to toggle source
# File lib/meal_ticket.rb, line 79
def facebook_callback
  if get_query_string_parameter("code")
    response = get facebook_exchange_url(get_root_url, get_query_string_parameter("code"))

    if response.body.include? "access_token"
      response.body =~ /access_token=([^&]+)(?:&expires=(.*))?/ # TODO: genericize get_query_string_parameter to handle this?
      token = $1 || ""
      expires = $2 || ""
      query_string = "facebook[token]=#{CGI.escape(token)}&facebook[expires]=#{CGI.escape(expires)}"
    else
      parsed = JSON.parse(response.body)
      query_string = to_params({:facebook => parsed})
    end
  else
    query_string = "facebook[error]=#{get_query_string_parameter("error")}"
  end

  body = %(<html><body>You are being redirected.</body></html>)
  headers = {
        'Location' => "#{get_root_url}#{MealTicket::Config.facebook_callback}?#{query_string}",
        'Content-Type' => 'text/html',
        'Content-Length' => body.length.to_s
  }
  [302, headers, [body]]
end
flickr_callback() click to toggle source
# File lib/meal_ticket.rb, line 105
def flickr_callback

  xml = get flickr_frob_url(get_query_string_parameter("frob"))

  parsed = Crack::XML.parse(xml.body)
  if parsed["rsp"]["stat"] == "ok"
    remote_id = parsed["rsp"]["auth"]["user"]["nsid"] || ""
    token = parsed["rsp"]["auth"]["token"] || ""
    query_string = "flickr[token]=#{CGI.escape(token)}&flickr[user_id]=#{CGI.escape(remote_id)}"
  else
    code = parsed["rsp"]["err"]["code"]
    msg = parsed["rsp"]["err"]["msg"]
    query_string = "flickr[error][code]=#{CGI.escape code}&flickr[error][msg]=#{CGI.escape msg}"
  end

  body = %(<html><body>You are being redirected.</body></html>)
  headers = {
        'Location' => "#{get_root_url}#{MealTicket::Config.flickr_callback}?#{query_string}",
        'Content-Type' => 'text/html',
        'Content-Length' => body.length.to_s
  }
  [302, headers, [body]]
end

Private Instance Methods

get(url) click to toggle source
# File lib/meal_ticket.rb, line 130
def get(url)
  use_ssl = url.include? 'https'
  url = URI.parse(url)

  path = url.query.blank? ? url.path : "#{url.path}?#{url.query}"

  http = Net::HTTP.new(url.host, use_ssl ? 443 : nil)
  http.use_ssl = use_ssl
  res = http.get(path)

  if res.code == '302'
    return get(res['location']) # follow redirects
  end
  res
end
get_query_string_parameter(param) click to toggle source
# File lib/meal_ticket.rb, line 147
def get_query_string_parameter(param)
  @env["QUERY_STRING"] =~ Regexp.new("#{param}=(.*)&|#{param}=(.*)$")
  return $1 || $2 # whichever one worked
end
get_root_url() click to toggle source
# File lib/meal_ticket.rb, line 152
def get_root_url
  @env["REQUEST_URI"] =~ /(^.*?:\/\/.*?\/)/ # looking for the form .....://.........../
  return $1
end
to_params(obj) click to toggle source

stolen from merb, according to StackOverflow

# File lib/meal_ticket.rb, line 159
def to_params(obj)
  params = ''
  stack = []

  obj.each do |k, v|
    if v.is_a?(Hash)
      stack << [k, v]
    else
      params << "#{CGI.escape k}=#{CGI.escape v}&"
    end
  end

  stack.each do |parent, hash|
    hash.each do |k, v|
      if v.is_a?(Hash)
        stack << ["#{parent}[#{k}]", v]
      else
        params << "#{parent}[#{CGI.escape k}]=#{CGI.escape v}&"
      end
    end
  end

  params.chop! # trailing &
  params
end