comscore_ruby 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/comscore_ruby.gemspec +27 -0
- data/lib/comscore_ruby/client.rb +160 -0
- data/lib/comscore_ruby/constants.rb +61 -0
- data/lib/comscore_ruby/core_ext/date.rb +11 -0
- data/lib/comscore_ruby/version.rb +3 -0
- data/lib/comscore_ruby.rb +23 -0
- metadata +105 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "comscore_ruby/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "comscore_ruby"
|
7
|
+
s.version = ComScore::VERSION
|
8
|
+
s.authors = ["Mike Sukmanowsky"]
|
9
|
+
s.email = ["mike.sukmanowsky@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/msukmanowsky/comscore_ruby/wiki"
|
11
|
+
s.summary = "Use comScore's SOAP API in a manner that does not require you to bang your head against a wall."
|
12
|
+
s.description = "Basic support for things like finding media, media sets (AKA categories), and fetching reports. Documentation is...well...missing so far."
|
13
|
+
|
14
|
+
s.rubyforge_project = s.name
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency "savon", ">= 0.9.7"
|
22
|
+
s.add_runtime_dependency "activesupport", ">= 3.1.0"
|
23
|
+
|
24
|
+
# specify any dependencies here; for example:
|
25
|
+
# s.add_development_dependency "rspec"
|
26
|
+
# s.add_runtime_dependency "rest-client"
|
27
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
module ComScore
|
2
|
+
class Client
|
3
|
+
BASE_URI = "https://api.comscore.com/"
|
4
|
+
SERVICES = {
|
5
|
+
:key_measures => {:wsdl => "#{BASE_URI}KeyMeasures.asmx?WSDL"},
|
6
|
+
:audience_duplication => {:wsdl => "#{BASE_URI}DigitalCalc.asmx?WSDL"},
|
7
|
+
:percent_media_trend => {:wsdl => "#{BASE_URI}PercentMediaTrend.asmx?WSDL"},
|
8
|
+
:percent_target_trend => {:wsdl => "#{BASE_URI}PercentTargetTrend.asmx?WSDL"},
|
9
|
+
:demographic_profile => {:wsdl => "#{BASE_URI}DemographicProfile.asmx?WSDL"},
|
10
|
+
:media_trend => {:wsdl => "#{BASE_URI}MediaTrend.asmx?WSDL"},
|
11
|
+
:target_trend => {:wsdl => "#{BASE_URI}TargetTrend.asmx?WSDL"},
|
12
|
+
:cross_visit => {:wsdl => "#{BASE_URI}CrossVisit.asmx?WSDL"},
|
13
|
+
:video_key_measures => {:wsdl => "#{BASE_URI}VideoMetrix/VideoMetrixKeyMeasures.asmx?WSDL"},
|
14
|
+
:video_media_trend => {:wsdl => "#{BASE_URI}VideoMetrix/VideoMetrixMediaTrend.asmx?WSDL"},
|
15
|
+
:video_demographic_profile => {:wsdl => "#{BASE_URI}VideoMetrix/VideoMetrixDemographicProfile.asmx?WSDL"},
|
16
|
+
:mobilens_audience_profile => {:wsdl => "#{BASE_URI}MobiLens/AudienceProfile.asmx?WSDL"},
|
17
|
+
:mobilens_trend => {:wsdl => "#{BASE_URI}MobiLens/Trend.asmx?WSDL"}
|
18
|
+
}
|
19
|
+
|
20
|
+
def initialize(uname, pw)
|
21
|
+
@username, @password = [uname, pw]
|
22
|
+
end
|
23
|
+
|
24
|
+
def log=(value)
|
25
|
+
raise ArgumentError, "Parameter must be of type Boolean." unless !!value == value
|
26
|
+
@log = value
|
27
|
+
Savon.configure do |config|
|
28
|
+
config.log = value
|
29
|
+
config.log_level = :info if value == false
|
30
|
+
end
|
31
|
+
HTTPI.log = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def log
|
35
|
+
@log
|
36
|
+
end
|
37
|
+
|
38
|
+
def media_sets
|
39
|
+
@client = Savon::Client.new(SERVICES[:key_measures][:wsdl])
|
40
|
+
@client.http.auth.basic(@username, @password)
|
41
|
+
|
42
|
+
response = @client.request(:discover_parameter_values) do
|
43
|
+
soap.xml do |xml|
|
44
|
+
xml.soap(:Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/") {
|
45
|
+
xml.soap(:Body) {
|
46
|
+
xml.DiscoverParameterValues(:xmlns => "http://comscore.com/") {
|
47
|
+
xml.parameterId("mediaSet")
|
48
|
+
xml.query(:xmlns => "http://comscore.com/ReportQuery") {
|
49
|
+
xml.Parameter(:KeyId => "geo", :Value => "124")
|
50
|
+
xml.Parameter(:KeyId => "timeType", :Value => "1")
|
51
|
+
xml.Parameter(:KeyId => "timePeriod", :Value => DateTime.now.to_date.to_comscore_time_period - 2)
|
52
|
+
xml.Parameter(:KeyId => "mediaSetType", :Value => "1")
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
response.to_hash()[:discover_parameter_values_response][:discover_parameter_values_result][:enum_value]
|
61
|
+
end
|
62
|
+
|
63
|
+
def find_media(criterion = [])
|
64
|
+
@client = Savon::Client.new(SERVICES[:key_measures][:wsdl])
|
65
|
+
@client.http.auth.basic(@username, @password)
|
66
|
+
response = @client.request(:fetch_media) do
|
67
|
+
soap.xml do |xml|
|
68
|
+
xml.soap(:Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/") {
|
69
|
+
xml.soap(:Body) {
|
70
|
+
xml.FetchMedia("xmlns" => "http://comscore.com/") {
|
71
|
+
xml.parameterId("media")
|
72
|
+
xml.fetchMediaQuery("xmlns" => "http://comscore.com/FetchMedia") {
|
73
|
+
criterion.each do |criteria|
|
74
|
+
xml.SearchCritera(:ExactMatch => "false", :Critera => criteria)
|
75
|
+
end
|
76
|
+
} if criterion.count > 0
|
77
|
+
xml.reportQuery("xmlns" => "http://comscore.com/ReportQuery") {
|
78
|
+
xml.Parameter(:KeyId => "geo", :Value => "124")
|
79
|
+
xml.Parameter(:KeyId => "loc", :Value => "0")
|
80
|
+
xml.Parameter(:KeyId => "timeType", :Value => "1")
|
81
|
+
xml.Parameter(:KeyId => "timePeriod", :Value => DateTime.now.to_date.to_comscore_time_period - 2)
|
82
|
+
xml.Parameter(:KeyId => "mediaSetType", :Value => "1")
|
83
|
+
}
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
response.to_hash()[:fetch_media_response][:fetch_media_result][:media_item]
|
91
|
+
end
|
92
|
+
|
93
|
+
# Requires: geo, loc, timeType, timePeriod, mediaSetType
|
94
|
+
# Usage: find_media(:geo => "Canada", :loc => "")
|
95
|
+
def get_report(report_type, opts = {})
|
96
|
+
@client = Savon::Client.new(SERVICES[report_type][:wsdl])
|
97
|
+
@client.http.auth.basic(@username, @password)
|
98
|
+
job_queue_response = @client.request(:submit_report) do
|
99
|
+
soap.xml do |xml|
|
100
|
+
xml.soap(:Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/") {
|
101
|
+
xml.soap(:Body) {
|
102
|
+
xml.SubmitReport("xmlns" => "http://comscore.com/") {
|
103
|
+
xml.query("xmlns" => "http://comscore.com/ReportQuery") {
|
104
|
+
opts.each { |key, value|
|
105
|
+
if value.is_a?(Array)
|
106
|
+
value.each do |v|
|
107
|
+
xml.Parameter(:KeyId => key, :Value => v)
|
108
|
+
end
|
109
|
+
elsif value.is_a?(Date)
|
110
|
+
xml.Parameter(:KeyId => key, :Value => value.to_comscore_time_period)
|
111
|
+
else
|
112
|
+
xml.Parameter(:KeyId => key, :Value => value)
|
113
|
+
end
|
114
|
+
}
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
}
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
job_id = job_queue_response.to_hash()[:submit_report_response][:submit_report_result][:job_id]
|
123
|
+
|
124
|
+
job_status = "Starting"
|
125
|
+
begin
|
126
|
+
sleep(2) if job_status == "Starting"
|
127
|
+
job_status_response = @client.request(:ping_report_status) do
|
128
|
+
soap.xml do |xml|
|
129
|
+
xml.soap(:Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/") {
|
130
|
+
xml.soap(:Body) {
|
131
|
+
xml.PingReportStatus("xmlns" => "http://comscore.com/") {
|
132
|
+
xml.jobId(job_id)
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
job_status = job_status_response.to_hash()[:ping_report_status_response][:ping_report_status_result][:status]
|
139
|
+
end while (job_status != "Completed" && job_status != "Failed")
|
140
|
+
|
141
|
+
if (job_status == "Completed")
|
142
|
+
result = @client.request(:fetch_report) do
|
143
|
+
soap.xml do |xml|
|
144
|
+
xml.soap(:Envelope, "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", "xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", "xmlns:soap" => "http://schemas.xmlsoap.org/soap/envelope/") {
|
145
|
+
xml.soap(:Body) {
|
146
|
+
xml.FetchReport("xmlns" => "http://comscore.com/") {
|
147
|
+
xml.jobId(job_id)
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
151
|
+
end
|
152
|
+
end
|
153
|
+
return result.to_hash()[:fetch_report_response][:fetch_report_result]
|
154
|
+
else
|
155
|
+
raise "The job with id #{job_id} failed to complete. Last known status was #{job_status}."
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ComScore
|
2
|
+
GEOGRAPHIES = {
|
3
|
+
"Canada" => "124"
|
4
|
+
}
|
5
|
+
LOCATIONS = {
|
6
|
+
"Home and Work" => "0",
|
7
|
+
"Home" => 1,
|
8
|
+
"Work" => 2
|
9
|
+
}
|
10
|
+
TIME_TYPES = {
|
11
|
+
"Months" => "1",
|
12
|
+
"3 Month Avg" => "5"
|
13
|
+
}
|
14
|
+
MEDIA_SET_TYPES = {
|
15
|
+
"Ranked Categories" => "1",
|
16
|
+
"Expanded Categories" => "2",
|
17
|
+
"Alternate Rollups" => "3"
|
18
|
+
}
|
19
|
+
TARGET_TYPES = {
|
20
|
+
"Simple" => "0",
|
21
|
+
"Advanced" => "1",
|
22
|
+
"Custom" => "2"
|
23
|
+
}
|
24
|
+
TARGET_GROUPS = {
|
25
|
+
"Total Audience" => 15,
|
26
|
+
"Persons - Age" => 23,
|
27
|
+
"Males - Age" => 24,
|
28
|
+
"Females - Age" => 25,
|
29
|
+
"HH Income (CA)" => 6,
|
30
|
+
"Region (CA)" => 7,
|
31
|
+
"Children" => 8,
|
32
|
+
"HH Size" => 9,
|
33
|
+
"Connection Speed" => 12
|
34
|
+
}
|
35
|
+
MEDIA_FILTERS = {
|
36
|
+
"Top 5" => "0",
|
37
|
+
"All Entries" => "-1"
|
38
|
+
}
|
39
|
+
MEASURES = {
|
40
|
+
"Total Unique Visitors (000)" => 1,
|
41
|
+
"% Reach" => 9,
|
42
|
+
"% Composition Unique Visitors" => 10,
|
43
|
+
"Composition Index UV" => 70,
|
44
|
+
"Composition Index PV" => 71,
|
45
|
+
"Average Daily Visitors (000)" => 7,
|
46
|
+
"Total Minutes (MM)" => 2,
|
47
|
+
"Average Minutes per Usage Day" => 14,
|
48
|
+
"Total Pages Viewed (MM)" => 3,
|
49
|
+
"Average Pages per Usage Day" => 16,
|
50
|
+
"Average Minutes per Page" => 15,
|
51
|
+
"Average Usage Days per Visitor" => 8,
|
52
|
+
"Average Minutes per Visitor" => 6,
|
53
|
+
"Average Pages per Visitor" => 5,
|
54
|
+
"% Composition Pages" => 11,
|
55
|
+
"% Composition Minutes" => 12,
|
56
|
+
"Total Visits (000)" => 143,
|
57
|
+
"Average Minutes per Visit" => 144,
|
58
|
+
"Average Visits per Visitor" => 145,
|
59
|
+
"Average Visits per Usage Day" => 146
|
60
|
+
}
|
61
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Date
|
2
|
+
def to_comscore_time_period
|
3
|
+
initial_d = Date.new(2000, 1, 1)
|
4
|
+
if self.to_time.to_i < initial_d.to_time.to_i
|
5
|
+
raise "#{self.strftime("%Y-%m")} is before #{self.strftime("%Y-%m")}"
|
6
|
+
end
|
7
|
+
year_difference = self.year - initial_d.year
|
8
|
+
month_difference = (self.month - initial_d.month).modulo(12)
|
9
|
+
return (year_difference * 12) + month_difference + 1
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'comscore_ruby/version'
|
2
|
+
require 'comscore_ruby/client'
|
3
|
+
require 'comscore_ruby/constants'
|
4
|
+
require 'comscore_ruby/core_ext/date'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'savon'
|
8
|
+
require 'active_support/core_ext/date_time/acts_like'
|
9
|
+
require 'active_support/core_ext/date_time/calculations'
|
10
|
+
require 'active_support/core_ext/date_time/conversions'
|
11
|
+
require 'active_support/core_ext/date_time/zones'
|
12
|
+
|
13
|
+
require 'active_support/core_ext/date/acts_like'
|
14
|
+
require 'active_support/core_ext/date/calculations'
|
15
|
+
require 'active_support/core_ext/date/conversions'
|
16
|
+
require 'active_support/core_ext/date/freeze'
|
17
|
+
require 'active_support/core_ext/date/zones'
|
18
|
+
|
19
|
+
require 'active_support/core_ext/time/calculations'
|
20
|
+
|
21
|
+
module ComScore
|
22
|
+
|
23
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: comscore_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 5
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 13
|
10
|
+
version: 0.0.13
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mike Sukmanowsky
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-09-02 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: savon
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 53
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 9
|
32
|
+
- 7
|
33
|
+
version: 0.9.7
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: activesupport
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
hash: 3
|
45
|
+
segments:
|
46
|
+
- 3
|
47
|
+
- 1
|
48
|
+
- 0
|
49
|
+
version: 3.1.0
|
50
|
+
type: :runtime
|
51
|
+
version_requirements: *id002
|
52
|
+
description: Basic support for things like finding media, media sets (AKA categories), and fetching reports. Documentation is...well...missing so far.
|
53
|
+
email:
|
54
|
+
- mike.sukmanowsky@gmail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files: []
|
60
|
+
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- Rakefile
|
65
|
+
- comscore_ruby.gemspec
|
66
|
+
- lib/comscore_ruby.rb
|
67
|
+
- lib/comscore_ruby/client.rb
|
68
|
+
- lib/comscore_ruby/constants.rb
|
69
|
+
- lib/comscore_ruby/core_ext/date.rb
|
70
|
+
- lib/comscore_ruby/version.rb
|
71
|
+
homepage: https://github.com/msukmanowsky/comscore_ruby/wiki
|
72
|
+
licenses: []
|
73
|
+
|
74
|
+
post_install_message:
|
75
|
+
rdoc_options: []
|
76
|
+
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
hash: 3
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
hash: 3
|
94
|
+
segments:
|
95
|
+
- 0
|
96
|
+
version: "0"
|
97
|
+
requirements: []
|
98
|
+
|
99
|
+
rubyforge_project: comscore_ruby
|
100
|
+
rubygems_version: 1.8.4
|
101
|
+
signing_key:
|
102
|
+
specification_version: 3
|
103
|
+
summary: Use comScore's SOAP API in a manner that does not require you to bang your head against a wall.
|
104
|
+
test_files: []
|
105
|
+
|