From d91ddd752f1f48dec7ebf25004bdb9b4c2e26261 Mon Sep 17 00:00:00 2001 From: Bob Aman Date: Thu, 12 May 2011 17:12:09 +0000 Subject: [PATCH] Updated examples. git-svn-id: https://google-api-ruby-client.googlecode.com/svn/trunk@153 c1d61fac-ed7f-fcc1-18f7-ff78120a04ef --- examples/buzz.rb | 101 +++++-- examples/sinatra/explorer.rb | 522 ----------------------------------- 2 files changed, 75 insertions(+), 548 deletions(-) delete mode 100644 examples/sinatra/explorer.rb diff --git a/examples/buzz.rb b/examples/buzz.rb index 4e1dabf08..cc172c1ae 100644 --- a/examples/buzz.rb +++ b/examples/buzz.rb @@ -1,29 +1,78 @@ -#!/usr/bin/env ruby - -# RUN -# ruby examples/buzz.rb - -root_dir = File.expand_path("../../..", __FILE__) -lib_dir = File.expand_path("./lib", root_dir) - -$LOAD_PATH.unshift(lib_dir) -$LOAD_PATH.uniq! - +$:.unshift('lib') require 'rubygems' -begin - require 'signet/oauth_1/client' - require 'google/api_client' -rescue LoadError - STDERR.puts "Missing dependencies." - STDERR.puts "sudo gem install signet google-api-client" - exit(1) +require 'sinatra' +require 'datamapper' +require 'google/api_client' + +use Rack::Session::Pool, :expire_after => 86400 # 1 day + +# Set up our token store +DataMapper.setup(:default, 'sqlite::memory:') +class TokenPair + include DataMapper::Resource + + property :id, Serial + property :refresh_token, String + property :access_token, String + property :expires_at, Integer + + def update_token!(object) + self.refresh_token = object.refresh_token + self.access_token = object.access_token + self.expires_at = object.expires_at + end + + def to_hash + return { + :refresh_token => refresh_token, + :access_token => access_token, + :expires_at => expires_at + } + end +end +TokenPair.auto_migrate! + +before do + @client = Google::APIClient.new + @client.authorization.client_id = '245083617981.apps.googleusercontent.com' + @client.authorization.client_secret = 'pYelZCRjSa+iMezYENVScXFk' + @client.authorization.scope = 'https://www.googleapis.com/auth/buzz' + @client.authorization.redirect_uri = to('/oauth2callback') + @client.authorization.code = params[:code] if params[:code] + if session[:token_id] + # Load the access token here if it's available + token_pair = TokenPair.get(session[:token_id]) + @client.authorization.update_token!(token_pair.to_hash) + end + @buzz = @client.discovered_api('buzz') + unless @client.authorization.access_token || request.path_info =~ /^\/oauth2/ + redirect to('/oauth2authorize') + end end -client = Google::APIClient.new(:service => 'buzz') -response = client.execute( - 'chili.activities.list', - 'userId' => 'googlebuzz', 'scope' => '@public', 'alt' => 'json', 'pp' => '1' -) -status, headers, body = response -puts body -exit(0) +get '/oauth2authorize' do + redirect @client.authorization.authorization_uri.to_s, 303 +end + +get '/oauth2callback' do + @client.authorization.fetch_access_token! + # Persist the token here + token_pair = if session[:token_id] + TokenPair.get(session[:token_id]) + else + TokenPair.new + end + token_pair.update_token!(@client.authorization) + token_pair.save() + session[:token_id] = token_pair.id + redirect to('/') +end + +get '/' do + response = @client.execute( + @buzz.activities.list, + 'userId' => '@me', 'scope' => '@consumption', 'alt'=> 'json' + ) + status, headers, body = response + [status, {'Content-Type' => 'application/json'}, body] +end diff --git a/examples/sinatra/explorer.rb b/examples/sinatra/explorer.rb deleted file mode 100644 index 7ca699853..000000000 --- a/examples/sinatra/explorer.rb +++ /dev/null @@ -1,522 +0,0 @@ -#!/usr/bin/env ruby - -# RUN -# ruby examples/sinatra/explorer.rb -# navigate a browser to http://localhost:4567/explore/buzz-v1/ - -root_dir = File.expand_path("../../..", __FILE__) -lib_dir = File.expand_path("./lib", root_dir) - -$LOAD_PATH.unshift(lib_dir) -$LOAD_PATH.uniq! - -require 'rubygems' -begin - gem 'rack', '= 1.2.0' - require 'rack' -rescue LoadError - STDERR.puts "Missing dependencies." - STDERR.puts "sudo gem install rack -v 1.2.0" - exit(1) -end -begin - require 'sinatra' - require 'liquid' - require 'signet/oauth_1/client' - require 'google/api_client' -rescue LoadError - STDERR.puts "Missing dependencies." - STDERR.puts "sudo gem install sinatra liquid signet google-api-client" - exit(1) -end - -enable :sessions - -CSS = <<-CSS -/* http://meyerweb.com/eric/tools/css/reset/ */ -/* v1.0 | 20080212 */ - -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, font, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td { - margin: 0; - padding: 0; - border: 0; - outline: 0; - font-size: 100%; - vertical-align: baseline; - background: transparent; -} -body { - line-height: 1; -} -ol, ul { - list-style: none; -} -blockquote, q { - quotes: none; -} -blockquote:before, blockquote:after, -q:before, q:after { - content: ''; - content: none; -} - -/* remember to define focus styles! */ -:focus { - outline: 0; -} - -/* remember to highlight inserts somehow! */ -ins { - text-decoration: none; -} -del { - text-decoration: line-through; -} - -/* tables still need 'cellspacing="0"' in the markup */ -table { - border-collapse: collapse; - border-spacing: 0; -} - -/* End Reset */ - -body { - color: #555555; - background-color: #ffffff; - font-family: 'Helvetica', 'Arial', sans-serif; - font-size: 18px; - line-height: 27px; - padding: 27px 72px; -} -p { - margin-bottom: 27px; -} -h1 { - font-style: normal; - font-variant: normal; - font-weight: normal; - font-family: 'Helvetica', 'Arial', sans-serif; - font-size: 36px; - line-height: 54px; - margin-bottom: 0px; -} -h2 { - font-style: normal; - font-variant: normal; - font-weight: normal; - font-family: 'Monaco', 'Andale Mono', 'Consolas', 'Inconsolata', 'Courier New', monospace; - font-size: 14px; - line-height: 27px; - margin-top: 0px; - margin-bottom: 54px; - letter-spacing: 0.1em; - text-transform: none; - text-shadow: rgba(204, 204, 204, 0.75) 0px 1px 0px; -} -#output h3 { - font-style: normal; - font-variant: normal; - font-weight: bold; - font-size: 18px; - line-height: 27px; - margin: 27px 0px; -} -#output h3:first-child { - margin-top: 0px; -} -ul, ol, dl { - margin-bottom: 27px; -} -li { - margin: 0px 0px; -} -form { - float: left; - display: block; -} -form label, form input, form textarea { - font-family: 'Monaco', 'Andale Mono', 'Consolas', 'Inconsolata', 'Courier New', monospace; - display: block; -} -form label { - margin-bottom: 5px; -} -form input { - width: 300px; - font-size: 14px; - padding: 5px; -} -form textarea { - height: 150px; - min-height: 150px; - width: 300px; - min-width: 300px; - max-width: 300px; -} -#output { - font-family: 'Monaco', 'Andale Mono', 'Consolas', 'Inconsolata', 'Courier New', monospace; - display: inline-block; - margin-left: 27px; - padding: 27px; - border: 1px dotted #555555; - width: 1120px; - max-width: 100%; - min-height: 600px; -} -#output pre { - overflow: auto; -} -a { - color: #000000; - text-decoration: none; - border-bottom: 1px dotted rgba(112, 56, 56, 0.0); -} -a:hover { - -webkit-transition: all 0.3s linear; - color: #703838; - border-bottom: 1px dotted rgba(112, 56, 56, 1.0); -} -p a { - border-bottom: 1px dotted rgba(0, 0, 0, 1.0); -} -h1, h2 { - color: #000000; -} -h3, h4, h5, h6 { - color: #333333; -} -.block { - display: block; -} -button { - margin-bottom: 72px; - padding: 7px 11px; - font-size: 14px; -} -CSS - -JAVASCRIPT = <<-JAVASCRIPT - var uriTimeout = null; - $(document).ready(function () { - $('#output').hide(); - var rpcName = $('#rpc-name').text().trim(); - var serviceId = $('#service-id').text().trim(); - var getParameters = function() { - var parameters = {}; - var fields = $('.parameter').parents('li'); - for (var i = 0; i < fields.length; i++) { - var input = $(fields[i]).find('input'); - var label = $(fields[i]).find('label'); - if (input.val() && input.val() != "") { - parameters[label.text()] = input.val(); - } - } - return parameters; - } - var updateOutput = function (event) { - var request = $('#request').text().trim(); - var response = $('#response').text().trim(); - if (request != '' || response != '') { - $('#output').show(); - } else { - $('#output').hide(); - } - } - var handleUri = function (event) { - updateOutput(event); - if (uriTimeout) { - clearTimeout(uriTimeout); - } - uriTimeout = setTimeout(function () { - $.ajax({ - "url": "/template/" + serviceId + "/" + rpcName + "/", - "data": getParameters(), - "dataType": "text", - "ifModified": true, - "success": function (data, textStatus, xhr) { - updateOutput(event); - if (textStatus == 'success') { - $('#uri-template').html(data); - if (uriTimeout) { - clearTimeout(uriTimeout); - } - } - } - }); - }, 350); - } - var getResponse = function (event) { - $.ajax({ - "url": "/response/" + serviceId + "/" + rpcName + "/", - "type": "POST", - "data": getParameters(), - "dataType": "html", - "ifModified": true, - "success": function (data, textStatus, xhr) { - if (textStatus == 'success') { - $('#response').text(data); - } - updateOutput(event); - } - }); - } - var getRequest = function (event) { - $.ajax({ - "url": "/request/" + serviceId + "/" + rpcName + "/", - "type": "GET", - "data": getParameters(), - "dataType": "html", - "ifModified": true, - "success": function (data, textStatus, xhr) { - if (textStatus == 'success') { - $('#request').text(data); - updateOutput(event); - getResponse(event); - } - } - }); - } - var transmit = function (event) { - $('#request').html(''); - $('#response').html(''); - handleUri(event); - updateOutput(event); - getRequest(event); - } - $('form').submit(function (event) { event.preventDefault(); }); - $('button').click(transmit); - $('.parameter').keyup(handleUri); - $('.parameter').blur(handleUri); - }); -JAVASCRIPT - -def client - @client ||= Google::APIClient.new( - :service => 'buzz', - :authorization => Signet::OAuth1::Client.new( - :temporary_credential_uri => - 'https://www.google.com/accounts/OAuthGetRequestToken', - :authorization_uri => - 'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken', - :token_credential_uri => - 'https://www.google.com/accounts/OAuthGetAccessToken', - :client_credential_key => 'anonymous', - :client_credential_secret => 'anonymous' - ) - ) -end - -def service(service_name, service_version) - unless service_version - service_version = client.latest_service_version(service_name).version - end - client.discovered_api(service_name, service_version) -end - -get '/template/:service/:method/' do - service_name, service_version = params[:service].split("-", 2) - method = service(service_name, service_version).to_h[params[:method].to_s] - parameters = method.parameters.inject({}) do |accu, parameter| - accu[parameter] = params[parameter.to_sym] if params[parameter.to_sym] - accu - end - uri = Addressable::URI.parse( - method.uri_template.partial_expand(parameters).pattern - ) - template_variables = method.uri_template.variables - query_parameters = method.normalize_parameters(parameters).reject do |k, v| - template_variables.include?(k) - end - if query_parameters.size > 0 - uri.query_values = (uri.query_values || {}).merge(query_parameters) - end - # Normalization is necessary because of undesirable percent-escaping - # during URI template expansion - return uri.normalize.to_s.gsub('%7B', '{').gsub('%7D', '}') -end - -get '/request/:service/:method/' do - service_name, service_version = params[:service].split("-", 2) - method = service(service_name, service_version).to_h[params[:method].to_s] - parameters = method.parameters.inject({}) do |accu, parameter| - accu[parameter] = params[parameter.to_sym] if params[parameter.to_sym] - accu - end - body = '' - request = client.generate_request( - method, parameters.merge("pp" => "1"), body, [], {:signed => false} - ) - method, uri, headers, body = request - merged_body = StringIO.new - body.each do |chunk| - merged_body << chunk - end - merged_body.rewind - <<-REQUEST.strip -#{method} #{uri} HTTP/1.1 - -#{(headers.map { |k,v| "#{k}: #{v}" }).join('\n')} - -#{merged_body.string} -REQUEST -end - -post '/response/:service/:method/' do - require 'rack/utils' - service_name, service_version = params[:service].split("-", 2) - method = service(service_name, service_version).to_h[params[:method].to_s] - parameters = method.parameters.inject({}) do |accu, parameter| - accu[parameter] = params[parameter.to_sym] if params[parameter.to_sym] - accu - end - body = '' - response = client.execute( - method, parameters.merge("pp" => "1"), body, [], {:signed => false} - ) - status, headers, body = response - status_message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] - merged_body = StringIO.new - body.each do |chunk| - merged_body << chunk - end - merged_body.rewind - <<-RESPONSE.strip -#{status} #{status_message} - -#{(headers.map { |k,v| "#{k}: #{v}" }).join("\n")} - -#{merged_body.string} -RESPONSE -end - -get '/explore/:service/' do - service_name, service_version = params[:service].split("-", 2) - service_version = service(service_name, service_version).version - variables = { - "css" => CSS, - "service_name" => service_name, - "service_version" => service_version, - "methods" => service(service_name, service_version).to_h.keys.sort - } - Liquid::Template.parse(<<-HTML).render(variables) - - - - {{service_name}} - - - -

{{service_name}}

- - - - HTML -end - -get '/explore/:service/:method/' do - service_name, service_version = params[:service].split("-", 2) - service_version = service(service_name, service_version).version - method = service(service_name, service_version).to_h[params[:method].to_s] - variables = { - "css" => CSS, - "javascript" => JAVASCRIPT, - "http_method" => (method.description['httpMethod'] || 'GET'), - "service_name" => service_name, - "service_version" => service_version, - "method" => params[:method].to_s, - "required_parameters" => - method.required_parameters, - "optional_parameters" => - method.optional_parameters.sort, - "template" => method.uri_template.pattern - } - Liquid::Template.parse(<<-HTML).render(variables) - - - - {{service_name}} - {{method}} - - - - - -

- - {{service_name}}-{{service_version}} - -

-

{{method}}

-

{{http_method}} {{template}}

-
- - -
-
-

Request

-

-      

Response

-

-    
- - - HTML -end - -get '/favicon.ico' do - require 'httpadapter' - HTTPAdapter.transmit( - ['GET', 'http://www.google.com/favicon.ico', [], ['']], - HTTPAdapter::NetHTTPRequestAdapter - ) -end - -get '/' do - redirect '/explore/buzz/' -end