adzerk 0.13 → 0.18

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.
Files changed (54) hide show
  1. checksums.yaml +5 -5
  2. data/lib/adzerk.rb +7 -0
  3. data/lib/adzerk/advertiser.rb +11 -0
  4. data/lib/adzerk/api_endpoint.rb +6 -5
  5. data/lib/adzerk/campaign.rb +15 -0
  6. data/lib/adzerk/category.rb +3 -3
  7. data/lib/adzerk/channel.rb +9 -0
  8. data/lib/adzerk/channel_site_map.rb +1 -1
  9. data/lib/adzerk/client.rb +100 -27
  10. data/lib/adzerk/creative.rb +2 -2
  11. data/lib/adzerk/creative_map.rb +7 -2
  12. data/lib/adzerk/creative_template.rb +30 -0
  13. data/lib/adzerk/day_parting.rb +23 -0
  14. data/lib/adzerk/distance_targeting.rb +33 -0
  15. data/lib/adzerk/errors.rb +0 -0
  16. data/lib/adzerk/flight.rb +25 -3
  17. data/lib/adzerk/geo_targeting.rb +0 -0
  18. data/lib/adzerk/instant_count.rb +21 -0
  19. data/lib/adzerk/invitation.rb +0 -0
  20. data/lib/adzerk/priority.rb +0 -0
  21. data/lib/adzerk/publisher.rb +14 -0
  22. data/lib/adzerk/reporting.rb +0 -0
  23. data/lib/adzerk/scheduled_reporting.rb +24 -0
  24. data/lib/adzerk/site_zone_targeting.rb +0 -0
  25. data/lib/adzerk/util.rb +7 -2
  26. data/lib/adzerk/version.rb +1 -1
  27. data/test/adtype_api_spec.rb +0 -0
  28. data/test/advertiser_api_spec.rb +8 -0
  29. data/test/campaign_api_spec.rb +16 -4
  30. data/test/category_api_spec.rb +7 -3
  31. data/test/channel_api_spec.rb +6 -1
  32. data/test/channel_site_map_api_spec.rb +0 -0
  33. data/test/creative_api_spec.rb +0 -0
  34. data/test/creative_map_api_spec.rb +10 -33
  35. data/test/creative_template_spec.rb +100 -0
  36. data/test/day_parting_api_spec.rb +102 -0
  37. data/test/distance_targeting_api_spec.rb +138 -0
  38. data/test/flight_api_spec.rb +28 -1
  39. data/test/geo_targeting_api_spec.rb +1 -1
  40. data/test/instant_count_api_spec.rb +55 -0
  41. data/test/invitation_api_spec.rb +0 -0
  42. data/test/login_api_spec.rb +0 -1
  43. data/test/priority_api_spec.rb +0 -0
  44. data/test/publisher_api_spec.rb +0 -0
  45. data/test/rakefile.rb +0 -0
  46. data/test/report_api_spec.rb +2 -2
  47. data/test/scheduled_reporting_api_spec.rb +60 -0
  48. data/test/security_api_spec.rb +0 -0
  49. data/test/site_api_spec.rb +0 -0
  50. data/test/site_zone_targeting_api_spec.rb +1 -1
  51. data/test/spec_helper.rb +0 -0
  52. data/test/util_spec.rb +0 -0
  53. data/test/zone_api_spec.rb +0 -0
  54. metadata +17 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 45256e26c1df6bc024eb079d454aa60403c11578
4
- data.tar.gz: 3ee03c68d83208ff84b71a2331b15041ba822b56
2
+ SHA256:
3
+ metadata.gz: b525a552892d3f147e720f80fe005ce713dbcce9901df753827532f10ca52b6d
4
+ data.tar.gz: e518839ef615fb2b444b2f324ea7eddd2fedd5c36426a28b01d65ef2b04e1bca
5
5
  SHA512:
6
- metadata.gz: f3e19e1997bdfe16fa887c5834716de82fcddc76b47f86e4d7af7f3f51690ce105e95f76d7e88be4fed3446642792115e4819963d4b167cf1b4741e5f885f6e5
7
- data.tar.gz: 23fe705e697ca32fc9ebc3dc1c5ef5162fd5921ae7c6c8b58c8051e2358d7fdc2b5e3f94801cc1bb93f68689980bd5e62c6f9d6fe2125393d73f5e29922e17bc
6
+ metadata.gz: 7902d331dcc69911d7a8e8273e3f913678443366367f691d15f234918d7ea31b084df045e13f869b52440b48c89aeec7852cb540fa9247512c7c0237b3b74f6e
7
+ data.tar.gz: 23b51f2303b6d091105bca619d885ff05dc5649c4e2332b7cdc4d59c6ea35b7dc381b7625528d0e1d3f640cadea71d7a74d6afbeeac97c5f64b92630c85fdd02
data/lib/adzerk.rb CHANGED
@@ -13,8 +13,15 @@ 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"
19
20
  require "adzerk/client"
20
21
  require "adzerk/priority"
22
+ require "adzerk/campaign"
23
+ require "adzerk/instant_count"
24
+ require "adzerk/creative_template"
25
+ require "adzerk/scheduled_reporting"
26
+ require "adzerk/day_parting"
27
+ require "adzerk/distance_targeting"
@@ -5,5 +5,16 @@ module Adzerk
5
5
  data = { 'advertiserName' => advertiser_name }
6
6
  parse_response(client.post_request(url, data))
7
7
  end
8
+
9
+ def instant_counts(advertiser_id, data={})
10
+ query_string = URI.encode_www_form(data)
11
+ url = "instantcounts/#{endpoint}/#{advertiser_id}?#{query_string}"
12
+ parse_response(client.get_request(url))
13
+ end
14
+
15
+ def list_creatives(advertiser_id, page: 1, pageSize: 500)
16
+ url = "advertiser/#{advertiser_id}/creatives?page=#{page}&pageSize=#{pageSize}"
17
+ parse_response(@client.get_request(url))
18
+ end
8
19
  end
9
20
  end
@@ -14,8 +14,8 @@ module Adzerk
14
14
 
15
15
  def create(opts={}, subid=nil)
16
16
  e = (subid && subendpoint) ? "#{subendpoint}/#{subid}/#{endpoint}" : endpoint
17
- data = { datakey => camelize_data(opts).to_json }
18
- response = @client.post_request(e, data)
17
+ data = camelize_data(opts)
18
+ response = @client.post_json_request(e, data)
19
19
  parse_response(response)
20
20
  end
21
21
 
@@ -24,16 +24,17 @@ module Adzerk
24
24
  parse_response(response)
25
25
  end
26
26
 
27
- def list(subid=nil)
27
+ def list(subid=nil, page: 1, pageSize: 500)
28
28
  e = (subid && subendpoint) ? "#{subendpoint}/#{subid}/#{endpoint}" : endpoint
29
+ e = "#{e}?page=#{page}&pageSize=#{pageSize}"
29
30
  response = @client.get_request(e)
30
31
  parse_response(response)
31
32
  end
32
33
 
33
34
  def update(opts={})
34
35
  id = opts[:id].to_s
35
- data = { datakey => camelize_data(opts).to_json }
36
- response = @client.put_request("#{endpoint}/#{id}", data)
36
+ data = camelize_data(opts)
37
+ response = @client.put_json_request("#{endpoint}/#{id}", data)
37
38
  parse_response(response)
38
39
  end
39
40
 
@@ -0,0 +1,15 @@
1
+ module Adzerk
2
+ class Campaign < ApiEndpoint
3
+ def instant_counts(campaign_id, data={})
4
+ query_string = URI.encode_www_form(data)
5
+ url = "instantcounts/#{endpoint}/#{campaign_id}?#{query_string}"
6
+ parse_response(client.get_request(url))
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
14
+ end
15
+ end
@@ -20,13 +20,13 @@ module Adzerk
20
20
  @client.get_request(url)
21
21
  end
22
22
 
23
- def listAll
23
+ def listAll(page: 1, pageSize: 500)
24
24
  response = client.get_request('categories')
25
25
  parse_response(response)
26
26
  end
27
27
 
28
- def list(flight_id)
29
- url = "flight/#{flight_id}/categories"
28
+ def list(flight_id, page: 1, pageSize: 500)
29
+ url = "flight/#{flight_id}/categories?page=#{page}&pageSize=#{pageSize}"
30
30
  response = client.get_request(url)
31
31
  parse_response(response)
32
32
  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
@@ -21,7 +21,7 @@ module Adzerk
21
21
  response = parse_response(response)
22
22
  end
23
23
 
24
- def list
24
+ def list(page: 1, pageSize: 500)
25
25
  response = client.get_request('channelSite')
26
26
  parse_response(response)
27
27
  end
data/lib/adzerk/client.rb CHANGED
@@ -6,11 +6,21 @@ module Adzerk
6
6
  attr_reader :sites, :ad_types, :zones, :campaigns, :channels, :priorities,
7
7
  :advertisers, :flights, :creatives, :creative_maps,
8
8
  :publishers, :invitations, :reports, :channel_site_maps,
9
- :logins, :geotargetings, :sitezonetargetings, :categories
9
+ :logins, :geotargetings, :sitezonetargetings, :categories,
10
+ :instant_counts, :ads, :creative_templates, :scheduled_reports,
11
+ :day_parts, :distance_targetings
12
+
13
+ VERSION = Gem.loaded_specs['adzerk'].version.to_s
14
+ SDK_HEADER_NAME = 'X-Adzerk-Sdk-Version'
15
+ SDK_HEADER_VALUE = "adzerk-management-sdk-ruby:#{VERSION}"
16
+ BASE_SLEEP = 0.25
17
+ MAX_SLEEP = 5
18
+ MAX_ATTEMPTS = 10
10
19
 
11
20
  DEFAULTS = {
12
- :host => ENV["ADZERK_API_HOST"] || 'https://api.adzerk.net/v1/',
13
- :header => 'X-Adzerk-ApiKey'
21
+ :host => ENV["ADZERK_API_HOST"] || 'https://api.adzerk.net/',
22
+ :header => 'X-Adzerk-ApiKey',
23
+ :include_creative_templates => true
14
24
  }
15
25
 
16
26
  def initialize(key, opts = {})
@@ -19,75 +29,138 @@ module Adzerk
19
29
  @logins = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'login')
20
30
  @sites = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'site')
21
31
  @ad_types = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'adtypes', :subendpoint => 'channel', :datakey => 'adtype')
22
- @flights = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'flight')
32
+ @flights = Adzerk::Flight.new(:client => self, :endpoint => 'flight')
23
33
  @zones = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'zone')
24
- @campaigns = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'campaign')
25
- @channels = Adzerk::ApiEndpoint.new(:client => self, :endpoint => 'channel')
34
+ @campaigns = Adzerk::Campaign.new(:client => self, :endpoint => 'campaign')
35
+ @channels = Adzerk::Channel.new(:client => self, :endpoint => 'channel')
26
36
  @priorities = Adzerk::Priority.new(:client => self, :endpoint => 'priority')
27
37
  @advertisers = Adzerk::Advertiser.new(:client => self, :endpoint => 'advertiser')
28
38
  @publishers = Adzerk::Publisher.new(:client => self, :endpoint => 'publisher')
29
39
  @creatives = Adzerk::Creative.new(:client => self, :endpoint => 'creative')
30
40
  @creative_maps = Adzerk::CreativeMap.new(:client => self)
41
+ @ads = @creative_maps
31
42
  @invitations = Adzerk::Invitation.new(:client => self)
32
43
  @reports = Adzerk::Reporting.new(:client => self)
33
44
  @channel_site_maps = Adzerk::ChannelSiteMap.new(:client => self)
34
45
  @geotargetings = Adzerk::GeoTargeting.new(:client => self, :endpoint => 'geotargeting')
35
46
  @sitezonetargetings = Adzerk::SiteZoneTargeting.new(:client => self, :endpoint => 'sitezone')
36
47
  @categories = Adzerk::Category.new(:client => self, :endpoint => 'category')
37
-
48
+ @instant_counts = Adzerk::InstantCount.new(:client => self)
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')
38
53
  end
39
54
 
40
- def get_request(url)
41
- uri = URI.parse(@config[:host] + url)
55
+ def get_request(url, version: 'v1')
56
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
42
57
  request = Net::HTTP::Get.new(uri.request_uri)
43
58
  request.add_field(@config[:header], @api_key)
59
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
60
+ send_request(request, uri)
61
+ end
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)
44
68
  send_request(request, uri)
45
69
  end
46
70
 
47
- def post_request(url, data)
48
- uri = URI.parse(@config[:host] + url)
71
+ def post_request(url, data, version: 'v1')
72
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
49
73
  request = Net::HTTP::Post.new(uri.request_uri)
50
74
  request.add_field(@config[:header], @api_key)
75
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
51
76
  request.set_form_data(data)
52
77
  send_request(request, uri)
53
78
  end
54
79
 
55
- def put_request(url, data)
56
- uri = URI.parse(@config[:host] + url)
80
+ def post_json_request(url, data, version: 'v1')
81
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
82
+ request = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
83
+ request.add_field(@config[:header], @api_key)
84
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
85
+ request.body = data.to_json
86
+ send_request(request, uri)
87
+ end
88
+
89
+ def put_request(url, data, version: 'v1')
90
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
57
91
  request = Net::HTTP::Put.new(uri.request_uri)
58
92
  request.add_field(@config[:header], @api_key)
93
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
59
94
  request.set_form_data(data)
60
95
  send_request(request, uri)
61
96
  end
62
97
 
63
- def create_creative(data={}, image_path='')
64
- response = RestClient.post(@config[:host] + 'creative',
65
- {:creative => camelize_data(data).to_json},
66
- :X_Adzerk_ApiKey => @api_key,
67
- :accept => :json)
98
+ def put_json_request(url, data, version: 'v1')
99
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
100
+ request = Net::HTTP::Put.new(uri.request_uri, 'Content-Type' => 'application/json')
101
+ request.add_field(@config[:header], @api_key)
102
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
103
+ request.body = data.to_json
104
+ send_request(request, uri)
105
+ end
106
+
107
+ def create_creative(data={}, image_path='', version: 'v1')
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
68
121
  response = upload_creative(JSON.parse(response)["Id"], image_path) unless image_path.empty?
69
122
  response
70
123
  end
71
124
 
72
- def upload_creative(id, image_path, size_override: false)
125
+ def upload_creative(id, image_path, size_override: false, version: 'v1')
126
+ response = nil
127
+ attempt = 0
73
128
  image = File.new(image_path, 'rb')
74
- url = @config[:host] + 'creative/' + id.to_s + '/upload'
129
+ url = @config[:host] + version + '/creative/' + id.to_s + '/upload'
75
130
  url += '?sizeOverride=true' if size_override
76
- RestClient.post(url,
77
- {:image => image},
78
- "X-Adzerk-ApiKey" => @api_key,
79
- :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
80
143
  end
81
144
 
82
145
  def send_request(request, uri)
146
+ response = nil
147
+ attempt = 0
83
148
  http = Net::HTTP.new(uri.host, uri.port)
84
149
  http.use_ssl = uri.scheme == 'https'
85
- response = http.request(request)
86
- if response.kind_of? Net::HTTPClientError
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
+
158
+ if response.kind_of? Net::HTTPClientError or response.kind_of? Net::HTTPServerError
87
159
  error_response = JSON.parse(response.body)
88
- msg = error_response["message"] || error_response["Error"]
160
+ msg = error_response["message"] || error_response["Error"] || response.body
89
161
  raise Adzerk::ApiError.new(msg)
90
162
  end
163
+
91
164
  response
92
165
  end
93
166
 
@@ -8,8 +8,8 @@ module Adzerk
8
8
  uncamelize_data(JSON.parse(response))
9
9
  end
10
10
 
11
- def list(advertiserId)
12
- url = 'advertiser/' + advertiserId.to_s + "/creatives"
11
+ def list(advertiserId, page: 1, pageSize: 500)
12
+ url = "advertiser/#{advertiserId}/creatives?page=#{page}&pageSize=#{pageSize}"
13
13
  parse_response(@client.get_request(url))
14
14
  end
15
15
 
@@ -18,8 +18,8 @@ module Adzerk
18
18
  parse_response(@client.get_request(url))
19
19
  end
20
20
 
21
- def list(flight_id)
22
- url = "flight/#{flight_id}/creatives"
21
+ def list(flight_id, page: 1, pageSize: 500)
22
+ url = "flight/#{flight_id}/creatives?page=#{page}&#pageSize=#{pageSize}"
23
23
  parse_response(@client.get_request(url))
24
24
  end
25
25
 
@@ -34,5 +34,10 @@ module Adzerk
34
34
  @client.get_request(url)
35
35
  end
36
36
 
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))
41
+ end
37
42
  end
38
43
  end
@@ -0,0 +1,30 @@
1
+ module Adzerk
2
+ class CreativeTemplate
3
+
4
+ include Adzerk::Util
5
+
6
+ attr_reader :client
7
+
8
+ def initialize(args={})
9
+ @client = args[:client]
10
+ end
11
+
12
+ def create(data={})
13
+ parse_response(@client.post_json_request("creative-templates", camelize_data(data), version: 'v2'))
14
+ end
15
+
16
+ def update(id, data={})
17
+ url = "creative-templates/#{id}/update"
18
+ parse_response(@client.post_json_request(url, camelize_data(data), version: 'v2'))
19
+ end
20
+
21
+ def get(id)
22
+ parse_response(@client.get_request("creative-templates/#{id}", version: 'v2'))
23
+ end
24
+
25
+ def list(page: 1, pageSize: 100)
26
+ url = "creative-templates?page=#{page}&pageSize=#{pageSize}"
27
+ parse_response(@client.get_request(url, version: 'v2'))
28
+ end
29
+ end
30
+ 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