Skip to content

Instantly share code, notes, and snippets.

@barmstrong
Created June 30, 2011 01:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save barmstrong/1055459 to your computer and use it in GitHub Desktop.
Save barmstrong/1055459 to your computer and use it in GitHub Desktop.
sample code for setting up the Google Prediction API in a background process using OAuth2 and the google-api-ruby-client
class CreateOauth2s < ActiveRecord::Migration
def self.up
create_table :oauth2s do |t|
t.string :api
t.string :refresh_token
t.string :access_token
t.datetime :expires_at
t.timestamps
end
add_index :oauth2s, :api
end
def self.down
drop_table :oauth2s
end
end
require 'gstore'
require 'fastercsv'
require 'google/api_client'
class GooglePrediction
include ActionView::Helpers::NumberHelper
@message_fields = [:spam_or_ham, :message, :ips, :email, :rating, ... ]
@training_set = []
@test_set = []
BUCKET = 'messages'
API = 'google-prediction'
def self.client
if @client.nil?
@client = Google::APIClient.new
@client.authorization.client_id = "MY_CLIENT_ID"
@client.authorization.client_secret = "MY_CLIENT_SECRET"
@client.authorization.scope = 'https://www.googleapis.com/auth/prediction'
@client.authorization.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
# authenticate!
if oauth2 = Oauth2.find_by_api(API) and oauth2.access_token.present?
@client.authorization.update_token!(oauth2.token_hash)
if oauth2.expired?
puts "REFRESHING ACCESS TOKEN"
@client.authorization.redirect_uri = nil
@client.authorization.fetch_access_token!
oauth2.update_token! @client.authorization
end
end
end
@client
end
def self.setup code=nil
oauth2 = Oauth2.find_by_api(API)
if oauth2.nil?
oauth2 = Oauth2.create!(:api => API)
end
if code.nil?
puts "Authorize the API in the browser at: \n\n#{client.authorization.authorization_uri.to_s}\n\n"
puts 'Then call again with script/runner "GooglePrediction.setup \'CODE\'"'
return
else
client.authorization.code = code
client.authorization.fetch_access_token!
oauth2.update_token! client.authorization
puts "You are now authenticated!"
end
end
def self.run
# generate CSV to upload
csv_string = FasterCSV.generate do |csv|
Message.find_each(:include => :user) do |message|
next if message.user.nil?
if rand > 0.5
@training_set << post.id
else
@test_set << post.id
csv << @message_fields.collect {|f| post.send(f)}
end
end
end
filename = store_in_google(csv_string)
prediction = client.discovered_api('prediction', 'v1.2')
puts "Training..."
response = client.execute(prediction.training.insert,{'data' => "#{BUCKET}/#{filename}"})
while true
sleep 4
response = client.execute(prediction.training.get, {'data' => "#{BUCKET}/#{filename}"})
response = JSON.parse(response[2][0])
if response['trainingStatus'] == "DONE"
puts response
break
end
end
# training done!
ensure
delete_from_google filename
end
def self.gstore_client
@gstore_client ||= GStore::Client.new(
:access_key => "My Google Storage Legacy Access Key",
:secret_key => "My Google Storage Legacy Secret Key"
)
end
def self.store_in_google data
puts "Uploading #{data.length / 1000 / 1000}MB to google storage..."
gstore_client.create_bucket(BUCKET) #in case it doesn't exist
filename = "#{BUCKET}-#{Time.now.to_i}.csv"
gstore_client.put_object(BUCKET, filename, :data => data)
filename
end
def self.delete_from_google filename
gstore_client.delete_object(BUCKET, filename)
end
end
class Oauth2 < ActiveRecord::Base
def update_token! authorization
self.refresh_token = authorization.refresh_token if authorization.refresh_token.present?
self.access_token = authorization.access_token
self.expires_at = authorization.expires_at
save!
end
def token_hash
{
:refresh_token => refresh_token,
:access_token => access_token,
:expires_at => expires_at
}
end
def expired?
return true if expires_at.nil?
Time.now > expires_at
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment