Class: Gattica::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/gattica.rb

Overview

The real meat of Gattica, deals with talking to GA, returning and parsing results. You actually get an instance of this when you go Gattica.new()

Constant Summary collapse

SERVER =
'www.google.com'
PORT =
443
SECURE =
true
DEFAULT_ARGS =
{ :start_date => nil, :end_date => nil, :dimensions => [], :metrics => [], :filters => [], :sort => [], :start_index => 1, :max_results => 10000, :page => false }
DEFAULT_OPTIONS =
{ :email => nil, :password => nil, :token => nil, :profile_id => nil, :debug => false, :headers => {}, :logger => Logger.new(STDOUT) }
FILTER_METRIC_OPERATORS =
%w{ == != > < >= <= }
FILTER_DIMENSION_OPERATORS =
%w{ == != =~ !~ =@ ~@ }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Engine

Create a user, and get them authorized. If you’re making a web app you’re going to want to save the token that’s retrieved by Gattica so that you can use it later (Google recommends not re-authenticating the user for each and every request)

ga = Gattica.new({:email => '[email protected]', :password => 'password', :profile_id => 123456})
ga.token => 'DW9N00wenl23R0...' (really long string)

Or if you already have the token (because you authenticated previously and now want to reuse that session):

ga = Gattica.new({:token => '23ohda09hw...', :profile_id => 123456})


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/gattica.rb', line 66

def initialize(options={})
  @options = DEFAULT_OPTIONS.merge(options)
  @logger = @options[:logger]
  @logger.level = Logger::INFO


  @profile_id = @options[:profile_id]     # if you don't include the profile_id now, you'll have to set it manually later via Gattica::Engine#profile_id=
  @user_accounts = nil                    # filled in later if the user ever calls Gattica::Engine#accounts
  @headers = {}.merge(@options[:headers]) # headers used for any HTTP requests (Google requires a special 'Authorization' header which is set any time @token is set)

  # save a proxy-aware http connection for everyone to use
  proxy_host = nil
  proxy_port = nil
  proxy_var  = SECURE ? 'https_proxy' : 'http_proxy'
  [proxy_var, proxy_var.upcase].each do |pxy|
    if ENV[pxy]
      uri = URI::parse(ENV[pxy])
      proxy_host = uri.host
      proxy_port = uri.port
    end
  end
  @http = Net::HTTP::Proxy(proxy_host,proxy_port).new(SERVER, PORT)
  @http.use_ssl = SECURE
  @http.set_debug_output $stdout if @options[:debug]

  # authenticate
  if @options[:email] && @options[:password]      # email and password: authenticate, get a token from Google's ClientLogin, save it for later
    @user = User.new(@options[:email], @options[:password])
    @auth = Auth.new(@http, user)
    self.token = @auth.tokens[:auth]
  elsif @options[:token]                          # use an existing token
    self.token = @options[:token]
  else                                            # no login or token, you can't do anything
    raise GatticaError::NoLoginOrToken, 'You must provide an email and password, or authentication token'
  end

  # TODO: check that the user has access to the specified profile and show an error here rather than wait for Google to respond with a message
end

Instance Attribute Details

#profile_idObject

Returns the value of attribute profile_id.



53
54
55
# File 'lib/gattica.rb', line 53

def profile_id
  @profile_id
end

#tokenObject

Returns the value of attribute token.



53
54
55
# File 'lib/gattica.rb', line 53

def token
  @token
end

#userObject (readonly)

Returns the value of attribute user.



52
53
54
# File 'lib/gattica.rb', line 52

def user
  @user
end

Instance Method Details

#accountsObject

Returns the list of accounts the user has access to. A user may have multiple accounts on Google Analytics and each account may have multiple profiles. You need the profile_id in order to get info from GA. If you don’t know the profile_id then use this method to get a list of all them. Then set the profile_id of your instance and you can make regular calls from then on.

ga = Gattica.new({:email => '[email protected]', :password => 'password'})
ga.get_accounts
# you parse through the accounts to find the profile_id you need
ga.profile_id = 12345678
# now you can perform a regular search, see Gattica::Engine#get

If you pass in a profile id when you instantiate Gattica::Search then you won’t need to get the accounts and find a profile_id - you apparently already know it!

See Gattica::Engine#get to see how to get some data.



122
123
124
125
126
127
128
129
130
# File 'lib/gattica.rb', line 122

def accounts
  # if we haven't retrieved the user's accounts yet, get them now and save them
  if @user_accounts.nil?
    data = do_http_get('/analytics/feeds/accounts/default')
    xml = Hpricot(data)
    @user_accounts = xml.search(:entry).collect { |entry| Account.new(entry) }
  end
  return @user_accounts
end

#get(args = {}) ⇒ Object

This is the method that performs the actual request to get data.

Usage

gs = Gattica.new({:email => '[email protected]', :password => 'password', :profile_id => 123456})
gs.get({ :start_date => '2008-01-01',
         :end_date => '2008-02-01',
         :dimensions => 'browser',
         :metrics => 'pageviews',
         :sort => 'pageviews',
         :filters => ['browser == Firefox']})

Input

When calling get you’ll pass in a hash of options. For a description of what these mean to Google Analytics, see code.google.com/apis/analytics/docs

Required values are:

  • start_date => Beginning of the date range to search within

  • end_date => End of the date range to search within

Optional values are:

  • dimensions => an array of GA dimensions (without the ga: prefix)

  • metrics => an array of GA metrics (without the ga: prefix)

  • filter => an array of GA dimensions/metrics you want to filter by (without the ga: prefix)

  • sort => an array of GA dimensions/metrics you want to sort by (without the ga: prefix)

  • page => true|false Does the paging to create a single set of all of the data

  • start_index => Beginning offset of the query (default 1)

  • max_results => How many results to grab (maximum 10,000)

Exceptions

If a user doesn’t have access to the profile_id you specified, you’ll receive an error. Likewise, if you attempt to access a dimension or metric that doesn’t exist, you’ll get an error back from Google Analytics telling you so.



190
191
192
# File 'lib/gattica.rb', line 190

def get(args={})
  return results(args)
end

#get_to_csv(args = {}, fh = nil, format = :long) ⇒ Object

Performs a Gattica::Engine#get but instead of returning the dataset streams it to the file handle in a CSV format

Usage

gs = Gattica.new({:email => '[email protected]', :password => 'password', :profile_id => 123456})
fh = File.new("file.csv", "w")
gs.get_to_csv({ :start_date => '2008-01-01',
         :end_date => '2008-02-01',
         :dimensions => 'browser',
         :metrics => 'pageviews',
         :sort => 'pageviews',
         :filters => ['browser == Firefox']}, fh, :short)

See Gattica::Engine#get to see details of arguments



147
148
149
150
# File 'lib/gattica.rb', line 147

def get_to_csv(args={}, fh = nil, format = :long)
  raise GatticaError::InvalidFileType, "Invalid file handle" unless !fh.nil?
  results(args, fh, :csv, format)
end