Created
June 21, 2011 05:40
-
-
Save filtersquad/1037308 to your computer and use it in GitHub Desktop.
A preliminary clicky client example built on api_smith
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'api_smith' | |
require 'date' | |
require 'ipaddr' | |
module GettinClickyWithIt | |
class Error < StandardError; end | |
SMART_NUMBER_TRANSFORMER = lambda { |v| Integer(v) rescue v } | |
class StatsCollection < APISmith::Smash | |
property :date | |
property :items | |
end | |
def self.collection_transformers | |
@collection_transformers ||= Hash.new do |h, k| | |
h[k] = Class.new(StatsCollection).tap do |klass| | |
klass.transformer_for :items, k | |
end | |
end | |
end | |
class TallyStat < APISmith::Smash | |
property :title | |
property :value, :transformer => SMART_NUMBER_TRANSFORMER | |
property :value_percent, :transformer => :to_f | |
property :url | |
property :clicky_url | |
# Goal Information | |
property :incompleted, :transformer => :to_i | |
property :conversion, :transformer => :to_f | |
property :revenue | |
property :cost | |
end | |
class ItemStat < APISmith::Smash | |
property :time, :transformer => lambda { |v| Time.at(v.to_i) } | |
property :time_pretty | |
property :item | |
property :clicky_url | |
alias query item | |
alias link item | |
end | |
class VisitStat < APISmith::Smash | |
property :time, :transformer => lambda { |v| Time.at(v.to_i) } | |
property :time_pretty | |
property :time_total, :transformer => :to_i | |
property :ip_address, :transformer => lambda { |v| IPAddr.new(v) } | |
property :session_id, :transformer => :to_i | |
property :actions, :transformer => :to_i | |
property :web_browser | |
property :operating_system | |
property :screen_resolution | |
property :javascript, :transformer => lambda { |v| v == '1' } | |
property :language | |
property :referrer_url | |
property :referrer_domain | |
property :referrer_search | |
property :referrer_type | |
property :geolocation | |
property :latitude, :transformer => :to_f | |
property :longitude, :transformer => :to_f | |
# These need a premium account fwiw. | |
property :hostname | |
property :organization | |
property :campaign | |
property :goals_incompleted | |
property :goals_completed | |
property :custom | |
property :clicky_url | |
alias javascript? javascript | |
end | |
class ActionStat < APISmith::Smash | |
property :time, :transformer => lambda { |v| Time.at(v.to_i) } | |
property :time_pretty | |
property :time_total, :transformer => :to_i | |
property :ip_address, :transformer => lambda { |v| IPAddr.new(v) } | |
property :session_id, :transformer => :to_i | |
property :action_type | |
property :action_title | |
property :action_url | |
property :referrer_url | |
property :referrer_domain | |
property :referrer_search | |
property :custom | |
property :clicky_url | |
%w(pageview download outbound).each do |v| | |
define_method(:"#{v}?") { action_type == v } | |
end | |
end | |
POPULAR_METHODS = %w(pages pages-entrance pages-exit downloads clicks links links-domains links-outbound searches searches-keywords searches-engines | |
goals split-tests campaigns countries cities regions languages web-browsers operating-systems screen-resolutions hostnames organizations | |
engagement-actions engagement-times visitors-most-active traffic-sources tweets shorturls) | |
TALLY_METHODS = %w(visitors visitors-unique actions actions-average time-average time-average-pretty bounce-rate visitors-online feedburner-statistics) | |
ITEM_LISTING_TYPES = %w(searches-recent searches-unique links-recent links-unique) | |
CUSTOM_METHODS = { | |
'visitors-list' => collection_transformers[VisitStat], | |
'actions-list' => collection_transformers[ActionStat] | |
} | |
AUTO_TRANSFORMER = lambda do |v| | |
type = v["type"] | |
if (transformer = CUSTOM_METHODS[type]) | |
transformer.call v['dates'] | |
elsif POPULAR_METHODS.include?(type) or TALLY_METHODS.include?(type) | |
collection_transformers[TallyStat].call v['dates'] | |
elsif ITEM_LISTING_TYPES.include?(type) | |
collection_transformers[ItemStat].call v['dates'] | |
else | |
v | |
end | |
end | |
class Client | |
include APISmith::Client | |
base_uri 'http://api.getclicky.com/' | |
endpoint 'api/stats/4' | |
attr_reader :site_id, :site_key | |
def initialize(site_id, site_key) | |
@site_key = site_key | |
@site_id = site_id | |
add_query_options! :site_id => site_id, :sitekey => site_key | |
end | |
(POPULAR_METHODS + ITEM_LISTING_TYPES + TALLY_METHODS + CUSTOM_METHODS.keys).each do |m| | |
define_method m.tr('-', '_') do |*args| | |
singular_api_call m, *args | |
end | |
end | |
private | |
def check_response_errors(response) | |
if response.first.is_a?(Hash) and (error = response.first['error']) | |
raise Error.new(error) | |
end | |
end | |
def base_query_options | |
{:output => 'json'} | |
end | |
def singular_api_call(type, options = {}) | |
response = get '/', :extra_query => normalise_options(type, options), | |
:response_container => [0], :transform => AUTO_TRANSFORMER | |
extract_item response, options | |
end | |
def normalise_options(type, options) | |
encode_parameters(options).merge 'type' => [*type].join(",") | |
end | |
def extract_item(response, options) | |
if options[:daily] or options[:hourly] | |
response | |
else | |
response.first.items | |
end | |
end | |
def encode_parameters(params) | |
encoded = {} | |
params.each_pair do |k, v| | |
case k.to_s | |
when 'custom' | |
v.each_pair do |name, value| | |
encoded["#{k}[#{name}]"] = value | |
end | |
when 'date' | |
encoded[k] = normalise_value(v) { |t| normalise_date t } | |
else | |
encoded[k] = normalise_value v | |
end | |
end | |
encoded | |
end | |
def normalise_value(value, &blk) | |
blk ||= :to_s.to_proc | |
case value | |
when Range | |
[blk.call(value.begin), blk.call(value.end)] * "," | |
when Array | |
value.map(&blk) * "|" | |
when true | |
'1' | |
when false | |
'0' | |
else | |
value.to_s | |
end | |
end | |
def normalise_date(date) | |
if date.respond_to?(:strftime) | |
date.strftime "%Y-%m-%d" | |
else | |
date.to_s | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment