Updated examples.
authorBob Aman <bobaman@google.com>
Thu, 12 May 2011 17:12:09 +0000 (17:12 +0000)
committerBob Aman <bobaman@google.com>
Thu, 12 May 2011 17:12:09 +0000 (17:12 +0000)
git-svn-id: https://google-api-ruby-client.googlecode.com/svn/trunk@153 c1d61fac-ed7f-fcc1-18f7-ff78120a04ef

examples/buzz.rb
examples/sinatra/explorer.rb [deleted file]

index 4e1dabf0802be10978dd525f579b0e0a9c73cd2f..cc172c1ae283a32ee9af6b3289ef5237c694ae34 100644 (file)
@@ -1,29 +1,78 @@
-#!/usr/bin/env ruby
+$:.unshift('lib')
+require 'rubygems'
+require 'sinatra'
+require 'datamapper'
+require 'google/api_client'
 
-# RUN
-#   ruby examples/buzz.rb
+use Rack::Session::Pool, :expire_after => 86400 # 1 day
 
-root_dir = File.expand_path("../../..", __FILE__)
-lib_dir = File.expand_path("./lib", root_dir)
+# Set up our token store
+DataMapper.setup(:default, 'sqlite::memory:')
+class TokenPair
+  include DataMapper::Resource
 
-$LOAD_PATH.unshift(lib_dir)
-$LOAD_PATH.uniq!
+  property :id, Serial
+  property :refresh_token, String
+  property :access_token, String
+  property :expires_at, Integer
 
-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)
+  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 (file)
index 7ca6998..0000000
+++ /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)
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>{{service_name}}</title>
-    <style type="text/css">
-      {{css}}
-    </style>
-  </head>
-  <body>
-    <h1>{{service_name}}</h1>
-    <ul>
-      {% for method in methods %}
-        <li>
-          <a href="/explore/{{service_name}}-{{service_version}}/{{method}}/">
-            {{method}}
-          </a>
-        </li>
-      {% endfor %}
-    </ul>
-  </body>
-</html>
-  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)
-<!DOCTYPE html>
-<html>
-  <head>
-    <title>{{service_name}} - {{method}}</title>
-    <style type="text/css">
-      {{css}}
-    </style>
-    <script
-      src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"
-      type="text/javascript">
-    </script>
-    <script type="text/javascript">
-      {{javascript}}
-    </script>
-  </head>
-  <body>
-    <h3 id="service-id">
-      <a href="/explore/{{service_name}}-{{service_version}}/">
-        {{service_name}}-{{service_version}}
-      </a>
-    </h3>
-    <h1 id="rpc-name">{{method}}</h1>
-    <h2>{{http_method}} <span id="uri-template">{{template}}</span></h2>
-    <form>
-      <ul>
-        {% for parameter in required_parameters %}
-          <li>
-            <label for="param-{{parameter}}">{{parameter}}</label>
-            <input id="param-{{parameter}}" name="param-{{parameter}}"
-              class="parameter" type="text" />
-          </li>
-        {% endfor %}
-        {% for parameter in optional_parameters %}
-          <li>
-            <label for="param-{{parameter}}">{{parameter}}</label>
-            <input id="param-{{parameter}}" name="param-{{parameter}}"
-              class="parameter" type="text" />
-          </li>
-        {% endfor %}
-        {% if http_method != 'GET' %}
-        <li>
-          <label for="http-body">body</label>
-          <textarea id="http-body" name="http-body"></textarea>
-        </li>
-        {% endif %}
-      </ul>
-      <button>Transmit</button>
-    </form>
-    <div id="output">
-      <h3>Request</h3>
-      <pre id="request"></pre>
-      <h3>Response</h3>
-      <pre id="response"></pre>
-    </div>
-  </body>
-</html>
-  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