adzerk 0.15 → 0.20

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b08fcf724937ddb370874ccdf50506ca1f6e16be79cde06dc8777d1e1d99bfd6
4
- data.tar.gz: 28776f7247b58b93c4590fa1689737288a738240403e0d0af18bebd381f9b97d
3
+ metadata.gz: 3b868368f7ff6b9f3691cce1f3d7b947c69fd510e8669c882f023533ff25f408
4
+ data.tar.gz: 392459714b4aa029c1b64e885e120870065138429cbf2426bf1f24faa106cd2e
5
5
  SHA512:
6
- metadata.gz: 4763be769dac520c65beb9e7e6049089633635a75fc20f9480428d1b286cbeaa2bd543d5a16e4ae4d4a40c5674ae3e6963e2f2d5f5141ab574686829d8511630
7
- data.tar.gz: 5e6e08ec68228782bf1acdecc0c035ac66567f0886adcbde45ba77e03a073321d375287b1e4e316aee2a6d65ba7cb20c4812d1a4597567ae0eeb8a6dbc783090
6
+ metadata.gz: 889c331be8101a3dad887414b0773ecac75257cba58d095fd39f5259617c5ee1adbd28f72e71234e0cd9b4a1b1bfe7e77e8add9b9e13d14a10f88b3e7018f5f7
7
+ data.tar.gz: 2fedbe4e56f4de4c5dcb28b296241a64e8a5f3bc68619cc3a2627d90bf09b368ad013b1ddacb72631f2a816d9c35e23b6c9a43442adf6002330b7672c19af015
data/lib/adzerk.rb CHANGED
@@ -13,6 +13,7 @@ require "adzerk/publisher"
13
13
  require "adzerk/invitation"
14
14
  require "adzerk/reporting"
15
15
  require "adzerk/channel_site_map"
16
+ require "adzerk/channel"
16
17
  require "adzerk/geo_targeting"
17
18
  require "adzerk/site_zone_targeting"
18
19
  require "adzerk/category"
@@ -20,4 +21,7 @@ require "adzerk/client"
20
21
  require "adzerk/priority"
21
22
  require "adzerk/campaign"
22
23
  require "adzerk/instant_count"
23
- require "adzerk/creative_template"
24
+ require "adzerk/creative_template"
25
+ require "adzerk/scheduled_reporting"
26
+ require "adzerk/day_parting"
27
+ require "adzerk/distance_targeting"
@@ -6,8 +6,9 @@ module Adzerk
6
6
  parse_response(client.post_request(url, data))
7
7
  end
8
8
 
9
- def instant_counts(advertiser_id)
10
- url = "instantcounts/#{endpoint}/#{advertiser_id}?page=#{page}&pageSize=#{pageSize}"
9
+ def instant_counts(advertiser_id, data={})
10
+ query_string = URI.encode_www_form(data)
11
+ url = "instantcounts/#{endpoint}/#{advertiser_id}?#{query_string}"
11
12
  parse_response(client.get_request(url))
12
13
  end
13
14
 
@@ -1,8 +1,15 @@
1
1
  module Adzerk
2
2
  class Campaign < ApiEndpoint
3
- def instant_counts(campaign_id)
4
- url = "instantcounts/#{endpoint}/#{campaign_id}"
3
+ def instant_counts(campaign_id, data={})
4
+ query_string = URI.encode_www_form(data)
5
+ url = "instantcounts/#{endpoint}/#{campaign_id}?#{query_string}"
5
6
  parse_response(client.get_request(url))
6
7
  end
8
+
9
+ def search(campaign_name)
10
+ url = 'campaign/search'
11
+ data = { 'campaignName' => campaign_name }
12
+ parse_response(client.post_request(url, data))
13
+ end
7
14
  end
8
15
  end
@@ -0,0 +1,9 @@
1
+ module Adzerk
2
+ class Channel < ApiEndpoint
3
+ def get_priorities(channel_id)
4
+ url = "channel/#{channel_id}/priorities"
5
+ response = client.get_request(url)
6
+ parse_response(response)
7
+ end
8
+ end
9
+ end
data/lib/adzerk/client.rb CHANGED
@@ -7,11 +7,15 @@ module Adzerk
7
7
  :advertisers, :flights, :creatives, :creative_maps,
8
8
  :publishers, :invitations, :reports, :channel_site_maps,
9
9
  :logins, :geotargetings, :sitezonetargetings, :categories,
10
- :instant_counts, :ads, :creative_templates
10
+ :instant_counts, :ads, :creative_templates, :scheduled_reports,
11
+ :day_parts, :distance_targetings
11
12
 
12
13
  VERSION = Gem.loaded_specs['adzerk'].version.to_s
13
14
  SDK_HEADER_NAME = 'X-Adzerk-Sdk-Version'
14
15
  SDK_HEADER_VALUE = "adzerk-management-sdk-ruby:#{VERSION}"
16
+ BASE_SLEEP = 0.25
17
+ MAX_SLEEP = 5
18
+ MAX_ATTEMPTS = 10
15
19
 
16
20
  DEFAULTS = {
17
21
  :host => ENV["ADZERK_API_HOST"] || 'https://api.adzerk.net/',
@@ -28,7 +32,7 @@ module Adzerk
28
32
  @flights = Adzerk::Flight.new(:client => self, :endpoint => 'flight')
29
33
  @zones = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'zone')
30
34
  @campaigns = Adzerk::Campaign.new(:client => self, :endpoint => 'campaign')
31
- @channels = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'channel')
35
+ @channels = Adzerk::Channel.new(:client => self, :endpoint => 'channel')
32
36
  @priorities = Adzerk::Priority.new(:client => self, :endpoint => 'priority')
33
37
  @advertisers = Adzerk::Advertiser.new(:client => self, :endpoint => 'advertiser')
34
38
  @publishers = Adzerk::Publisher.new(:client => self, :endpoint => 'publisher')
@@ -43,6 +47,9 @@ module Adzerk
43
47
  @categories = Adzerk::Category.new(:client => self, :endpoint => 'category')
44
48
  @instant_counts = Adzerk::InstantCount.new(:client => self)
45
49
  @creative_templates = Adzerk::CreativeTemplate.new(:client => self)
50
+ @scheduled_reports = Adzerk::ScheduledReporting.new(:client => self, :endpoint => 'report')
51
+ @day_parts = Adzerk::DayParting.new(:client => self, :endpoint => 'dayparting')
52
+ @distance_targetings = Adzerk::DistanceTargeting.new(:client => self, :endpoint => 'distancetargeting')
46
53
  end
47
54
 
48
55
  def get_request(url, version: 'v1')
@@ -53,6 +60,14 @@ module Adzerk
53
60
  send_request(request, uri)
54
61
  end
55
62
 
63
+ def delete_request(url, version: 'v1')
64
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
65
+ request = Net::HTTP::Delete.new(uri.request_uri)
66
+ request.add_field(@config[:header], @api_key)
67
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
68
+ send_request(request, uri)
69
+ end
70
+
56
71
  def post_request(url, data, version: 'v1')
57
72
  uri = URI.parse("#{@config[:host]}#{version}/#{url}")
58
73
  request = Net::HTTP::Post.new(uri.request_uri)
@@ -90,35 +105,62 @@ module Adzerk
90
105
  end
91
106
 
92
107
  def create_creative(data={}, image_path='', version: 'v1')
93
- response = RestClient.post(@config[:host] + version + '/creative',
94
- {:creative => camelize_data(data).to_json},
95
- :X_Adzerk_ApiKey => @api_key,
96
- :X_Adzerk_Sdk_Version => SDK_HEADER_VALUE,
97
- :accept => :json)
108
+ response = nil
109
+ attempt = 0
110
+
111
+ loop do
112
+ response = RestClient.post(@config[:host] + version + '/creative',
113
+ {:creative => camelize_data(data).to_json},
114
+ :X_Adzerk_ApiKey => @api_key,
115
+ :X_Adzerk_Sdk_Version => SDK_HEADER_VALUE,
116
+ :accept => :json)
117
+ break if response.code != 429 or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
118
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
119
+ attempt += 1
120
+ end
98
121
  response = upload_creative(JSON.parse(response)["Id"], image_path) unless image_path.empty?
99
122
  response
100
123
  end
101
124
 
102
125
  def upload_creative(id, image_path, size_override: false, version: 'v1')
126
+ response = nil
127
+ attempt = 0
103
128
  image = File.new(image_path, 'rb')
104
129
  url = @config[:host] + version + '/creative/' + id.to_s + '/upload'
105
130
  url += '?sizeOverride=true' if size_override
106
- RestClient.post(url,
107
- {:image => image},
108
- "X-Adzerk-ApiKey" => @api_key,
109
- SDK_HEADER_NAME => SDK_HEADER_VALUE,
110
- :accept => :mime)
131
+ loop do
132
+ response = RestClient.post(url,
133
+ {:image => image},
134
+ "X-Adzerk-ApiKey" => @api_key,
135
+ SDK_HEADER_NAME => SDK_HEADER_VALUE,
136
+ :accept => :mime)
137
+
138
+ break if response.code != 429 or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
139
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
140
+ attempt += 1
141
+ end
142
+ response
111
143
  end
112
144
 
113
145
  def send_request(request, uri)
146
+ response = nil
147
+ attempt = 0
114
148
  http = Net::HTTP.new(uri.host, uri.port)
115
149
  http.use_ssl = uri.scheme == 'https'
116
- response = http.request(request)
150
+
151
+ loop do
152
+ response = http.request(request)
153
+ break if response.code != "429" or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
154
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
155
+ attempt += 1
156
+ end
157
+
117
158
  if response.kind_of? Net::HTTPClientError or response.kind_of? Net::HTTPServerError
118
159
  error_response = JSON.parse(response.body)
119
160
  msg = error_response["message"] || error_response["Error"] || response.body
120
161
  raise Adzerk::ApiError.new(msg)
121
162
  end
163
+
122
164
  response
123
165
  end
124
166
 
@@ -34,10 +34,10 @@ module Adzerk
34
34
  @client.get_request(url)
35
35
  end
36
36
 
37
- def instant_counts(creative_map_id)
38
- url = "instantcounts/#{endpoint}/#{creative_map_id}"
39
- parse_response(client.get_request(url))
37
+ def instant_counts(creative_map_id, data={})
38
+ query_string = URI.encode_www_form(data)
39
+ url = "instantcounts/ad/#{creative_map_id}?#{query_string}"
40
+ parse_response(@client.get_request(url))
40
41
  end
41
-
42
42
  end
43
43
  end
@@ -0,0 +1,23 @@
1
+ module Adzerk
2
+ class DayParting < ApiEndpoint
3
+ def create(flight_id, data={})
4
+ url = "flight/#{flight_id}/dayparting"
5
+ parse_response(@client.post_json_request(url, camelize_data(data)))
6
+ end
7
+
8
+ def get(flight_id, timepart_id)
9
+ url = "flight/#{flight_id}/dayparting/#{timepart_id}"
10
+ parse_response(@client.get_request(url))
11
+ end
12
+
13
+ def list(flight_id)
14
+ url = "flight/#{flight_id}/dayparting"
15
+ parse_response(@client.get_request(url))
16
+ end
17
+
18
+ def delete(flight_id, timepart_id)
19
+ url = "flight/#{flight_id}/dayparting/#{timepart_id}/delete"
20
+ @client.post_request(url, data={})
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ module Adzerk
2
+ class DistanceTargeting < ApiEndpoint
3
+ def create(flight_id, data={})
4
+ url = "flight/#{flight_id}/distance"
5
+ parse_response(@client.post_json_request(url, camelize_data(data)))
6
+ end
7
+
8
+ def batch_upload(flight_id, data={})
9
+ url = "flight/#{flight_id}/distance/batch"
10
+ parse_response(@client.post_json_request(url, camelize_data(data)))
11
+ end
12
+
13
+ def update(flight_id, geometry_id, data={})
14
+ url = "flight/#{flight_id}/distance/#{geometry_id}"
15
+ parse_response(@client.put_json_request(url, camelize_data(data)))
16
+ end
17
+
18
+ def get(flight_id, geometry_id)
19
+ url = "flight/#{flight_id}/distance/#{geometry_id}"
20
+ parse_response(@client.get_request(url))
21
+ end
22
+
23
+ def list(flight_id)
24
+ url = "flight/#{flight_id}/distance"
25
+ parse_response(@client.get_request(url))
26
+ end
27
+
28
+ def delete(flight_id, geometry_id)
29
+ url = "flight/#{flight_id}/distance/#{geometry_id}"
30
+ @client.delete_request(url)
31
+ end
32
+ end
33
+ end
data/lib/adzerk/flight.rb CHANGED
@@ -1,16 +1,25 @@
1
1
  module Adzerk
2
2
  class Flight < ApiEndpoint
3
3
  def countries
4
- parse_response(@client.get_request('countries'))
4
+ response = @client.get_request('countries')
5
+ parse_response(response)
5
6
  end
6
7
 
7
8
  def regions(region)
8
- url = 'region/' + region
9
- parse_reponse(@client.get_request(url))
9
+ url = "region/#{region}"
10
+ response = @client.get_request(url)
11
+ parse_response(response)
10
12
  end
11
13
 
12
- def instant_counts(flight_id)
13
- url = "instantcounts/#{endpoint}/#{flight_id}"
14
+ def list_regions_for_country(country_code)
15
+ url = "country/#{country_code}/regions?version=2"
16
+ response = @client.get_request(url)
17
+ parse_response(response)
18
+ end
19
+
20
+ def instant_counts(flight_id, data={})
21
+ query_string = URI.encode_www_form(data)
22
+ url = "instantcounts/#{endpoint}/#{flight_id}?#{query_string}"
14
23
  parse_response(client.get_request(url))
15
24
  end
16
25
 
@@ -11,5 +11,11 @@ module Adzerk
11
11
  response = @client.post_json_request(url, data)
12
12
  parse_response(response)
13
13
  end
14
+
15
+ def network_counts(data={})
16
+ query_string = URI.encode_www_form(data)
17
+ url = "instantcounts/network?#{query_string}"
18
+ parse_response(@client.get_request(url))
19
+ end
14
20
  end
15
21
  end
@@ -0,0 +1,24 @@
1
+ module Adzerk
2
+ class ScheduledReporting < ApiEndpoint
3
+ def create(data)
4
+ url = "report/schedule"
5
+ formatted_data = data.transform_keys{ |key| key.downcase }
6
+ parse_response(@client.post_json_request(url, camelize_data(formatted_data)))
7
+ end
8
+
9
+ def get(report_id)
10
+ url = "report/schedule/#{report_id}"
11
+ parse_response(@client.get_request(url))
12
+ end
13
+
14
+ def list()
15
+ url = "report/schedule"
16
+ parse_response(@client.get_request(url))
17
+ end
18
+
19
+ def delete(report_id)
20
+ url = "report/schedule/#{report_id}/delete"
21
+ parse_response(@client.get_request(url))
22
+ end
23
+ end
24
+ end
data/lib/adzerk/util.rb CHANGED
@@ -19,7 +19,7 @@ module Adzerk
19
19
  # stop condition for the recursion
20
20
  return data unless data.respond_to?(:reduce)
21
21
  data.reduce({}) do |acc, (key, val)|
22
- acc[key.underscore.to_sym] = case val
22
+ acc[/[a-zA-Z]/.match?(key) ? key.underscore.to_sym : key] = case val
23
23
  when Hash then uncamelize_data(val)
24
24
  when Array then val.map {|elem| uncamelize_data(elem) }
25
25
  else val
@@ -29,7 +29,12 @@ module Adzerk
29
29
  end
30
30
 
31
31
  def parse_response(response)
32
- uncamelize_data(JSON.parse(response.body))
32
+ parsed_body = JSON.parse(response.body)
33
+ case parsed_body
34
+ when Hash then uncamelize_data(parsed_body)
35
+ when Array then parsed_body.map {|elem| uncamelize_data(elem)}
36
+ else parsed_body
37
+ end
33
38
  end
34
39
  end
35
40
  end
@@ -1,3 +1,3 @@
1
1
  module Adzerk
2
- VERSION = "0.15"
2
+ VERSION = "0.20"
3
3
  end
@@ -50,6 +50,14 @@ describe "Advertiser API" do
50
50
  expect(advertiser[:total_items]).to be > 0
51
51
  end
52
52
 
53
+ it "should get advertiser instant counts" do
54
+ data = {
55
+ days: 5
56
+ }
57
+ count = @advertisers.instant_counts($advertiser_id, data)
58
+ expect(count.length).to be > 0
59
+ end
60
+
53
61
  it "should delete a new advertiser" do
54
62
  response = @advertisers.delete($advertiser_id)
55
63
  expect(response.body).to eq('"Successfully deleted."')
@@ -140,6 +140,19 @@ describe "Campaign API" do
140
140
  expect(campaigns.length).to be > 0
141
141
  end
142
142
 
143
+ it "should get campaign instant counts" do
144
+ data = {
145
+ days: 5
146
+ }
147
+ count = @campaigns.instant_counts($campaign_id, data)
148
+ expect(count.length).to be > 0
149
+ end
150
+
151
+ it "should search campaign based on name" do
152
+ campaign = @campaigns.search("Test%")
153
+ expect(campaign[:total_items]).to be > 0
154
+ end
155
+
143
156
  it "should not create/update a campaign with a advertiserId that doesn't belong to it" do
144
157
  new_campaign = {
145
158
  :name => 'Test campaign ' + rand(1000000).to_s,
@@ -172,7 +185,7 @@ describe "Campaign API" do
172
185
  end
173
186
 
174
187
  it "should not retrieve a campaign with a advertiserId that doesn't belong to it" do
175
- expect { @campaigns.get('123') }.to raise_error("This campaign is not part of your network")
188
+ expect { @campaigns.get('123') }.to raise_error("Campaign not found.")
176
189
  end
177
190
 
178
191
  it "should delete a new campaign" do
@@ -39,6 +39,11 @@ describe "Channel API" do
39
39
  expect($channel_ad_types).to eq(channel[:ad_types])
40
40
  end
41
41
 
42
+ it "should get priorities for channel" do
43
+ count = @channels.get_priorities($channel_id)
44
+ expect(count.length).to be > 0
45
+ end
46
+
42
47
  it "should update a channel" do
43
48
  $u_channel_title = 'Test Channel ' + rand(1000000).to_s + 'test'
44
49
  $u_channel_commission = '1.0'
@@ -74,7 +79,7 @@ describe "Channel API" do
74
79
  expect(last_channel[:engine]).to eq($u_channel_engine)
75
80
  expect(last_channel[:keywords]).to eq($u_channel_keywords)
76
81
  expect(last_channel[:cpm]).to eq($u_channel_CPM.to_f)
77
- expect(last_channel[:ad_types]).to eq($u_channel_AdTypes)
82
+ expect(last_channel[:ad_types]).to match_array($u_channel_AdTypes)
78
83
  end
79
84
 
80
85
  it "should delete a new channel" do
@@ -169,7 +169,7 @@ describe "Creative Flight API" do
169
169
  it "should list all creatives maps for a flight" do
170
170
  creative_maps = @creative_maps.list(@flight_id)
171
171
  creative_map = creative_maps[:items].last
172
- $map_id= creative_map[:id]
172
+ $map_id = creative_map[:id]
173
173
 
174
174
  expect(creative_map[:campaign_id]).to eq(@campaign_id)
175
175
  expect(creative_map[:flight_id]).to eq(@flight_id)
@@ -195,6 +195,14 @@ describe "Creative Flight API" do
195
195
  expect(creative_map[:creative][:is_sync]).to eq($IsSync)
196
196
  end
197
197
 
198
+ it "should get creative map instant counts" do
199
+ data = {
200
+ days: 5
201
+ }
202
+ count = @creative_maps.instant_counts($map_id, data)
203
+ expect(count.length).to be > 0
204
+ end
205
+
198
206
  it "should get a specific creative map" do
199
207
  creative_map = @creative_maps.get($map_id, @flight_id)
200
208
 
@@ -17,12 +17,14 @@ describe "Creative Template API" do
17
17
  type: 'String',
18
18
  variable: 'ctTitle',
19
19
  required: true,
20
+ ad_query: false
20
21
  }, {
21
22
  name: 'Thumbnail',
22
23
  description: 'The URL of a Thumbnail Image',
23
24
  type: 'String',
24
25
  variable: 'ctThumbnailUrl',
25
26
  required: false,
27
+ ad_query: true
26
28
  }],
27
29
  contents: [{
28
30
  type: 'Raw',
@@ -60,12 +62,14 @@ describe "Creative Template API" do
60
62
  type: 'String',
61
63
  variable: 'ctTitle',
62
64
  required: true,
65
+ ad_query: false,
63
66
  }, {
64
67
  name: 'Thumbnail',
65
68
  description: 'The URL of a Thumbnail Image',
66
69
  type: 'String',
67
70
  variable: 'ctThumbnailUrl',
68
71
  required: false,
72
+ ad_query: true,
69
73
  }],
70
74
  contents: [{
71
75
  type: 'Raw',
@@ -0,0 +1,102 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "DayParting API" do
4
+ before(:all) do
5
+ client = Adzerk::Client.new(API_KEY)
6
+ @day_partings = client.day_parts
7
+ @flights = client.flights
8
+ @advertisers = client.advertisers
9
+ @channels = client.channels
10
+ @campaigns = client.campaigns
11
+ @priorities = client.priorities
12
+
13
+ advertiser = @advertisers.create(:title => "test")
14
+ $advertiserId = advertiser[:id].to_s
15
+
16
+ channel = @channels.create(:title => 'Test Channel ' + rand(1000000).to_s,
17
+ :commission => '0.0',
18
+ :engine => 'CPM',
19
+ :keywords => 'test',
20
+ 'CPM' => '10.00',
21
+ :ad_types => [1,2,3,4])
22
+ $channel_id = channel[:id].to_s
23
+
24
+ priority = @priorities.create(:name => "High Priority Test",
25
+ :channel_id => $channel_id,
26
+ :weight => 1,
27
+ :is_deleted => false)
28
+ $priority_id = priority[:id].to_s
29
+
30
+ campaign = @campaigns.
31
+ create(:name => 'Test campaign ' + rand(1000000).to_s,
32
+ :start_date => "1/1/2011",
33
+ :end_date => "12/31/2011",
34
+ :is_active => false,
35
+ :price => '10.00',
36
+ :advertiser_id => $advertiserId,
37
+ :flights => [],
38
+ :is_deleted => false)
39
+ $campaign_id = campaign[:id]
40
+
41
+ new_flight = {
42
+ :priority_id => $priority_id,
43
+ :name => 'Test flight ' + rand(1000000).to_s,
44
+ :start_date => "1/1/2011",
45
+ :end_date => "12/31/2011",
46
+ :no_end_date => false,
47
+ :price => '15.00',
48
+ :option_type => 1,
49
+ :impressions => 10000,
50
+ :is_unlimited => false,
51
+ :is_full_speed => false,
52
+ :keywords => "test, test2",
53
+ :user_agent_keywords => nil,
54
+ :weight_override => nil,
55
+ :campaign_id => $campaign_id,
56
+ :is_active => true,
57
+ :is_deleted => false,
58
+ :goal_type => 1
59
+ }
60
+ flight = @flights.create(new_flight)
61
+ $flight_id = flight[:id].to_s
62
+ end
63
+
64
+ after(:all) do
65
+ @flights.delete($flight_id)
66
+ @campaigns.delete($campaign_id)
67
+ @advertisers.delete($advertiserId)
68
+ @priorities.delete($priority_id)
69
+ @channels.delete($channel_id)
70
+ end
71
+
72
+ it "should create a day part entity" do
73
+ data = {
74
+ :start_time => '09:30:00',
75
+ :end_time => '17:00:00',
76
+ :week_days => ['MO','TU']
77
+ }
78
+
79
+ response = @day_partings.create($flight_id, data)
80
+ expect(response[:timepart_id]).to_not eq(nil)
81
+ $timepart_id = response[:timepart_id].to_s
82
+ end
83
+
84
+ it "should get a day parting entity associated with a flight" do
85
+ response = @day_partings.get($flight_id, $timepart_id)
86
+ expect(response[:id].to_s).to eq($timepart_id)
87
+ expect(response[:flight_id].to_s).to eq($flight_id)
88
+ expect(response[:start_time]).to_not eq(nil)
89
+ expect(response[:end_time]).to_not eq(nil)
90
+ expect(response[:week_days]).to_not eq(nil)
91
+ end
92
+
93
+ it "should list all the day part entities in a flight" do
94
+ response = @day_partings.list($flight_id)
95
+ expect(response[:items].length).to be > 0
96
+ end
97
+
98
+ it "should delete a day part entity associated with a flight" do
99
+ response = @day_partings.delete($flight_id, $timepart_id)
100
+ expect(response.code).to eq('204')
101
+ end
102
+ end
@@ -0,0 +1,138 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "DistanceTargeting API" do
4
+ before(:all) do
5
+ client = Adzerk::Client.new(API_KEY)
6
+ @distance_targeting = client.distance_targetings
7
+ @flights = client.flights
8
+ @advertisers = client.advertisers
9
+ @channels = client.channels
10
+ @campaigns = client.campaigns
11
+ @priorities = client.priorities
12
+
13
+ advertiser = @advertisers.create(:title => "test")
14
+ $advertiserId = advertiser[:id].to_s
15
+
16
+ channel = @channels.create(:title => 'Test Channel ' + rand(1000000).to_s,
17
+ :commission => '0.0',
18
+ :engine => 'CPM',
19
+ :keywords => 'test',
20
+ 'CPM' => '10.00',
21
+ :ad_types => [1,2,3,4])
22
+ $channel_id = channel[:id].to_s
23
+
24
+ priority = @priorities.create(:name => "High Priority Test",
25
+ :channel_id => $channel_id,
26
+ :weight => 1,
27
+ :is_deleted => false)
28
+ $priority_id = priority[:id].to_s
29
+
30
+ campaign = @campaigns.
31
+ create(:name => 'Test campaign ' + rand(1000000).to_s,
32
+ :start_date => "1/1/2011",
33
+ :end_date => "12/31/2011",
34
+ :is_active => false,
35
+ :price => '10.00',
36
+ :advertiser_id => $advertiserId,
37
+ :flights => [],
38
+ :is_deleted => false)
39
+ $campaign_id = campaign[:id]
40
+
41
+ new_flight = {
42
+ :priority_id => $priority_id,
43
+ :name => 'Test flight ' + rand(1000000).to_s,
44
+ :start_date => "1/1/2011",
45
+ :end_date => "12/31/2011",
46
+ :no_end_date => false,
47
+ :price => '15.00',
48
+ :option_type => 1,
49
+ :impressions => 10000,
50
+ :is_unlimited => false,
51
+ :is_full_speed => false,
52
+ :keywords => "test, test2",
53
+ :user_agent_keywords => nil,
54
+ :weight_override => nil,
55
+ :campaign_id => $campaign_id,
56
+ :is_active => true,
57
+ :is_deleted => false,
58
+ :goal_type => 1
59
+ }
60
+ flight = @flights.create(new_flight)
61
+ $flight_id = flight[:id].to_s
62
+ end
63
+
64
+ after(:all) do
65
+ @flights.delete($flight_id)
66
+ @campaigns.delete($campaign_id)
67
+ @advertisers.delete($advertiserId)
68
+ @priorities.delete($priority_id)
69
+ @channels.delete($channel_id)
70
+ end
71
+
72
+ it "should create a Distance Targeting Geometry object with a street address" do
73
+ distance = 42
74
+ address = "1600 Pennsylvania Avenue NW, Washington DC 20500"
75
+ data = {
76
+ :distance => distance,
77
+ :street_address => address
78
+ }
79
+
80
+ response = @distance_targeting.create($flight_id, data)
81
+ expect(response[:flight_id].to_s).to eq($flight_id)
82
+ expect(response[:distance]).to eq(distance)
83
+ expect(response[:street_address]).to eq(address)
84
+ $geometry_id = response[:id]
85
+ end
86
+
87
+ it "should upload a batch of Distance Targeting Geometries" do
88
+ data = {
89
+ :replace_existing => false,
90
+ :geometries => [
91
+ {
92
+ :latitude => -89.05,
93
+ :longitude => 57.1,
94
+ :distance => 5
95
+ },
96
+ {
97
+ :latitude => 14,
98
+ :longitude => 57.1,
99
+ :distance => 5
100
+ }
101
+ ]
102
+ }
103
+
104
+ response = @distance_targeting.batch_upload($flight_id, data)
105
+ expect(response[:inserted_geometries]).to_not eq(nil)
106
+ end
107
+
108
+ it "should update a Distance Targeting Geometry" do
109
+ new_distance = 43
110
+ new_address = "701 N 1st Ave, Minneapolis MN 55403"
111
+ data = {
112
+ :distance => new_distance,
113
+ :street_address => new_address
114
+ }
115
+
116
+ response = @distance_targeting.update($flight_id, $geometry_id, data)
117
+ expect(response[:flight_id].to_s).to eq($flight_id)
118
+ expect(response[:id]).to eq($geometry_id)
119
+ expect(response[:distance]).to eq(new_distance)
120
+ expect(response[:street_address]).to eq(new_address)
121
+ end
122
+
123
+ it "should get a specific Distance Targeting Geometry" do
124
+ response = @distance_targeting.get($flight_id, $geometry_id)
125
+ expect(response[:flight_id].to_s).to eq($flight_id)
126
+ expect(response[:id]).to eq($geometry_id)
127
+ end
128
+
129
+ it "should list Distance Targeting Geometry objects associated with a flight" do
130
+ response = @distance_targeting.list($flight_id)
131
+ expect(response.length).to be > 0
132
+ end
133
+
134
+ it "should delete a specific Distance Targeting Geometry" do
135
+ response = @distance_targeting.delete($flight_id, $geometry_id)
136
+ expect(response.code).to eq('204')
137
+ end
138
+ end
@@ -170,6 +170,15 @@ describe "Flight API" do
170
170
  expect(flights.length).to be > 0
171
171
  end
172
172
 
173
+ it "should get flight instant counts" do
174
+ data = {
175
+ start: "2021-04-04",
176
+ end: "2021-04-20"
177
+ }
178
+ count = @flights.instant_counts($flight_id, data)
179
+ expect(count.length).to be > 0
180
+ end
181
+
173
182
  it "should delete a new flight" do
174
183
  response = @flights.delete($flight_id)
175
184
  expect(response.body).to eq('"Successfully deleted"')
@@ -250,4 +259,21 @@ describe "Flight API" do
250
259
  )
251
260
  }.to raise_error "This campaign is not part of your network"
252
261
  end
262
+
263
+ it "should list countries" do
264
+ response = @flights.countries()
265
+ expect(response.length).to be > 0
266
+ end
267
+
268
+ it "should list metro codes for region" do
269
+ region_code = "MN"
270
+ response = @flights.regions(region_code)
271
+ expect(response.length).to be > 0
272
+ end
273
+
274
+ it "should list regions for a country" do
275
+ country_code = "US"
276
+ response = @flights.list_regions_for_country(country_code)
277
+ expect(response.length).to be > 0
278
+ end
253
279
  end
@@ -5,11 +5,32 @@ describe "Instant Count API" do
5
5
  before(:all) do
6
6
  client = Adzerk::Client.new(API_KEY)
7
7
  @instant_counts = client.instant_counts
8
+ @advertisers = client.advertisers
9
+ @campaigns = client.campaigns
10
+
11
+ advertiser = @advertisers.create(:title => "test")
12
+ @advertiser_id = advertiser[:id]
13
+
14
+ campaign = @campaigns.
15
+ create(:name => 'Test campaign ' + rand(1000000).to_s,
16
+ :start_date => "1/1/2011",
17
+ :end_date => "12/31/2011",
18
+ :is_active => false,
19
+ :price => '10.00',
20
+ :advertiser_id => @advertiser_id,
21
+ :flights => [],
22
+ :is_deleted => false)
23
+ @campaign_id = campaign[:id]
24
+ end
25
+
26
+ after(:all) do
27
+ @campaigns.delete(@campaign_id)
28
+ @advertisers.delete(@advertiser_id)
8
29
  end
9
30
 
10
31
  it "should fetch bulk instant counts" do
11
- advertiser_id = 1065290
12
- campaign_id = 1582611
32
+ advertiser_id = @advertiser_id
33
+ campaign_id = @campaign_id
13
34
 
14
35
  counts = @instant_counts.bulk({
15
36
  :advertisers => [advertiser_id],
@@ -22,4 +43,13 @@ describe "Instant Count API" do
22
43
  expect(counts).to have_key(:campaigns)
23
44
  expect(counts[:campaigns]).to have_key(campaign_id.to_s.to_sym)
24
45
  end
46
+
47
+ it "should get network instant counts" do
48
+ data = {
49
+ start: "2021-04-04",
50
+ end: "2021-04-20"
51
+ }
52
+ count = @instant_counts.network_counts(data)
53
+ expect(count.length).to be > 0
54
+ end
25
55
  end
@@ -38,7 +38,6 @@ describe "Login_API" do
38
38
  :name => "New Name",
39
39
  :email => new_email)
40
40
  expect(login[:name]).to eq("New Name")
41
- expect(login[:email]).to eq(new_email)
42
41
  end
43
42
 
44
43
  end
@@ -0,0 +1,60 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Reporting API" do
4
+ before(:all) do
5
+ client = Adzerk::Client.new(API_KEY)
6
+ @scheduled_reports = client.scheduled_reports
7
+ end
8
+
9
+ it "should create a scheduled report" do
10
+ $name = 'Test Report' + rand(1000000).to_s
11
+ $login_id = 25218
12
+ $kickoff_date = '2020-02-02T00:00:00'
13
+ $scheduling_window = 1
14
+ $recurrence_type = 2
15
+ data = {
16
+ :name => $name,
17
+ :login_id => $login_id,
18
+ :kickoff_date => $kickoff_date,
19
+ :scheduling_window => $scheduling_window,
20
+ :recurrence_type => $recurrence_type,
21
+ :criteria => {
22
+ :start_date_iso => '2020-01-01T00:00:00',
23
+ :end_date_iso => '2020-11-23T23:59:59',
24
+ :group_by => ['month'],
25
+ :parameters => [{
26
+ :country_code => 'US'
27
+ }],
28
+ },
29
+ :emails => ['cbensel@kevel.co'],
30
+ :show_events => true,
31
+ :show_click_bucketing => true,
32
+ :show_revenue => true,
33
+ :show_conversions => true,
34
+ }
35
+
36
+ response = @scheduled_reports.create(data)
37
+ expect($name).to eq(response[:name])
38
+ expect($login_id).to eq(response[:login_id])
39
+ expect($kickoff_date).to eq(response[:kickoff_date])
40
+ expect($scheduling_window).to eq(response[:scheduling_window])
41
+ expect($recurrence_type).to eq(response[:recurrence_type])
42
+ $report_id = response[:id]
43
+ end
44
+
45
+ it "should get a single report" do
46
+ response = @scheduled_reports.get($report_id)
47
+ expect($report_id).to eq(response[:id])
48
+ expect($name).to eq(response[:name])
49
+ end
50
+
51
+ it "should list all reports for account" do
52
+ response = @scheduled_reports.list()
53
+ expect(response.length).to be > 0
54
+ end
55
+
56
+ it "should delete a report" do
57
+ response = @scheduled_reports.delete($report_id)
58
+ expect(response).to eq('Successfully deleted')
59
+ end
60
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adzerk
3
3
  version: !ruby/object:Gem::Version
4
- version: '0.15'
4
+ version: '0.20'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kacy Fortner
@@ -17,7 +17,7 @@ authors:
17
17
  autorequire:
18
18
  bindir: bin
19
19
  cert_chain: []
20
- date: 2021-01-22 00:00:00.000000000 Z
20
+ date: 2021-06-23 00:00:00.000000000 Z
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
23
23
  name: rspec
@@ -65,16 +65,16 @@ dependencies:
65
65
  name: rest-client
66
66
  requirement: !ruby/object:Gem::Requirement
67
67
  requirements:
68
- - - '='
68
+ - - "~>"
69
69
  - !ruby/object:Gem::Version
70
- version: 2.0.1
70
+ version: '2.1'
71
71
  type: :runtime
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
74
74
  requirements:
75
- - - '='
75
+ - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: 2.0.1
77
+ version: '2.1'
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: activesupport
80
80
  requirement: !ruby/object:Gem::Requirement
@@ -100,11 +100,14 @@ files:
100
100
  - lib/adzerk/api_endpoint.rb
101
101
  - lib/adzerk/campaign.rb
102
102
  - lib/adzerk/category.rb
103
+ - lib/adzerk/channel.rb
103
104
  - lib/adzerk/channel_site_map.rb
104
105
  - lib/adzerk/client.rb
105
106
  - lib/adzerk/creative.rb
106
107
  - lib/adzerk/creative_map.rb
107
108
  - lib/adzerk/creative_template.rb
109
+ - lib/adzerk/day_parting.rb
110
+ - lib/adzerk/distance_targeting.rb
108
111
  - lib/adzerk/errors.rb
109
112
  - lib/adzerk/flight.rb
110
113
  - lib/adzerk/geo_targeting.rb
@@ -113,6 +116,7 @@ files:
113
116
  - lib/adzerk/priority.rb
114
117
  - lib/adzerk/publisher.rb
115
118
  - lib/adzerk/reporting.rb
119
+ - lib/adzerk/scheduled_reporting.rb
116
120
  - lib/adzerk/site_zone_targeting.rb
117
121
  - lib/adzerk/util.rb
118
122
  - lib/adzerk/version.rb
@@ -125,6 +129,8 @@ files:
125
129
  - test/creative_api_spec.rb
126
130
  - test/creative_map_api_spec.rb
127
131
  - test/creative_template_spec.rb
132
+ - test/day_parting_api_spec.rb
133
+ - test/distance_targeting_api_spec.rb
128
134
  - test/flight_api_spec.rb
129
135
  - test/geo_targeting_api_spec.rb
130
136
  - test/instant_count_api_spec.rb
@@ -134,6 +140,7 @@ files:
134
140
  - test/publisher_api_spec.rb
135
141
  - test/rakefile.rb
136
142
  - test/report_api_spec.rb
143
+ - test/scheduled_reporting_api_spec.rb
137
144
  - test/security_api_spec.rb
138
145
  - test/site_api_spec.rb
139
146
  - test/site_zone_targeting_api_spec.rb
@@ -159,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
159
166
  - !ruby/object:Gem::Version
160
167
  version: '0'
161
168
  requirements: []
162
- rubygems_version: 3.1.2
169
+ rubygems_version: 3.0.3.1
163
170
  signing_key:
164
171
  specification_version: 4
165
172
  summary: Adzerk API