adzerk 0.12 → 0.17

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 (52) hide show
  1. checksums.yaml +5 -5
  2. data/lib/adzerk.rb +6 -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 +92 -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/errors.rb +0 -0
  15. data/lib/adzerk/flight.rb +25 -3
  16. data/lib/adzerk/geo_targeting.rb +0 -0
  17. data/lib/adzerk/instant_count.rb +21 -0
  18. data/lib/adzerk/invitation.rb +0 -0
  19. data/lib/adzerk/priority.rb +0 -0
  20. data/lib/adzerk/publisher.rb +14 -0
  21. data/lib/adzerk/reporting.rb +0 -0
  22. data/lib/adzerk/scheduled_reporting.rb +24 -0
  23. data/lib/adzerk/site_zone_targeting.rb +0 -0
  24. data/lib/adzerk/util.rb +7 -2
  25. data/lib/adzerk/version.rb +1 -1
  26. data/test/adtype_api_spec.rb +0 -0
  27. data/test/advertiser_api_spec.rb +8 -0
  28. data/test/campaign_api_spec.rb +19 -5
  29. data/test/category_api_spec.rb +7 -3
  30. data/test/channel_api_spec.rb +6 -1
  31. data/test/channel_site_map_api_spec.rb +0 -0
  32. data/test/creative_api_spec.rb +0 -0
  33. data/test/creative_map_api_spec.rb +10 -33
  34. data/test/creative_template_spec.rb +100 -0
  35. data/test/day_parting_api_spec.rb +102 -0
  36. data/test/flight_api_spec.rb +28 -1
  37. data/test/geo_targeting_api_spec.rb +1 -1
  38. data/test/instant_count_api_spec.rb +55 -0
  39. data/test/invitation_api_spec.rb +0 -0
  40. data/test/login_api_spec.rb +10 -3
  41. data/test/priority_api_spec.rb +0 -0
  42. data/test/publisher_api_spec.rb +0 -0
  43. data/test/rakefile.rb +0 -0
  44. data/test/report_api_spec.rb +2 -2
  45. data/test/scheduled_reporting_api_spec.rb +60 -0
  46. data/test/security_api_spec.rb +0 -0
  47. data/test/site_api_spec.rb +0 -0
  48. data/test/site_zone_targeting_api_spec.rb +1 -1
  49. data/test/spec_helper.rb +0 -0
  50. data/test/util_spec.rb +0 -0
  51. data/test/zone_api_spec.rb +0 -0
  52. metadata +17 -8
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f22414a06756a78f2e6d8ee07568be6e99ba7a91
4
- data.tar.gz: 1674c74ef8ce38b9e307eb51897c18c396eccea6
2
+ SHA256:
3
+ metadata.gz: 81c206b72f16aa47a2968e4f6fcc1143bd44d8ead4585e8c65e70e14a1b2541f
4
+ data.tar.gz: a61cfe82cbd4fe8a2899307fbc4844da2ae974257891e97b9c7336427c3d3989
5
5
  SHA512:
6
- metadata.gz: b959885a659a94db14a5ea8e520314cc18f20bada0c7f1d005e05b974c35aeb963df396d190ea648509ddcbfc951532eaa2d56743ca15e40b806b5bf16286d5d
7
- data.tar.gz: a65125e6343526b18933b7fe547a59118305472f486d73edc13643a7cb35ffab5eb1ba3c9a0e6a8d34ac1cf94a0acdd2561d5be8741f64da40b953a9f29d9717
6
+ metadata.gz: 44611cee6e3f78945dae45e86f286cbfb964c603933587191798df9c9b810bfd214c7b110edae97ff46968fca5ee74d0a7ef8dee87ccaca0ef47ef01672b7e6f
7
+ data.tar.gz: 0fab0586f87c62820036ef226b2c27bf2ee8c9a7ca38075ba17429c8269bed5e9e2e51649fcc3c722e968416006454533a6e5b44ea55b8ac67f35d8e9616df0b
data/lib/adzerk.rb CHANGED
@@ -13,8 +13,14 @@ 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"
@@ -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
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,74 +29,129 @@ 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')
38
52
  end
39
53
 
40
- def get_request(url)
41
- uri = URI.parse(@config[:host] + url)
54
+ def get_request(url, version: 'v1')
55
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
42
56
  request = Net::HTTP::Get.new(uri.request_uri)
43
57
  request.add_field(@config[:header], @api_key)
58
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
44
59
  send_request(request, uri)
45
60
  end
46
61
 
47
- def post_request(url, data)
48
- uri = URI.parse(@config[:host] + url)
62
+ def post_request(url, data, version: 'v1')
63
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
49
64
  request = Net::HTTP::Post.new(uri.request_uri)
50
65
  request.add_field(@config[:header], @api_key)
66
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
51
67
  request.set_form_data(data)
52
68
  send_request(request, uri)
53
69
  end
54
70
 
55
- def put_request(url, data)
56
- uri = URI.parse(@config[:host] + url)
71
+ def post_json_request(url, data, version: 'v1')
72
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
73
+ request = Net::HTTP::Post.new(uri.request_uri, 'Content-Type' => 'application/json')
74
+ request.add_field(@config[:header], @api_key)
75
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
76
+ request.body = data.to_json
77
+ send_request(request, uri)
78
+ end
79
+
80
+ def put_request(url, data, version: 'v1')
81
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
57
82
  request = Net::HTTP::Put.new(uri.request_uri)
58
83
  request.add_field(@config[:header], @api_key)
84
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
59
85
  request.set_form_data(data)
60
86
  send_request(request, uri)
61
87
  end
62
88
 
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)
89
+ def put_json_request(url, data, version: 'v1')
90
+ uri = URI.parse("#{@config[:host]}#{version}/#{url}")
91
+ request = Net::HTTP::Put.new(uri.request_uri, 'Content-Type' => 'application/json')
92
+ request.add_field(@config[:header], @api_key)
93
+ request.add_field(SDK_HEADER_NAME, SDK_HEADER_VALUE)
94
+ request.body = data.to_json
95
+ send_request(request, uri)
96
+ end
97
+
98
+ def create_creative(data={}, image_path='', version: 'v1')
99
+ response = nil
100
+ attempt = 0
101
+
102
+ loop do
103
+ response = RestClient.post(@config[:host] + version + '/creative',
104
+ {:creative => camelize_data(data).to_json},
105
+ :X_Adzerk_ApiKey => @api_key,
106
+ :X_Adzerk_Sdk_Version => SDK_HEADER_VALUE,
107
+ :accept => :json)
108
+ break if response.code != 429 or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
109
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
110
+ attempt += 1
111
+ end
68
112
  response = upload_creative(JSON.parse(response)["Id"], image_path) unless image_path.empty?
69
113
  response
70
114
  end
71
115
 
72
- def upload_creative(id, image_path, size_override: false)
116
+ def upload_creative(id, image_path, size_override: false, version: 'v1')
117
+ response = nil
118
+ attempt = 0
73
119
  image = File.new(image_path, 'rb')
74
- url = @config[:host] + 'creative/' + id.to_s + '/upload'
120
+ url = @config[:host] + version + '/creative/' + id.to_s + '/upload'
75
121
  url += '?sizeOverride=true' if size_override
76
- RestClient.post(url,
77
- {:image => image},
78
- "X-Adzerk-ApiKey" => @api_key,
79
- :accept => :mime)
122
+ loop do
123
+ response = RestClient.post(url,
124
+ {:image => image},
125
+ "X-Adzerk-ApiKey" => @api_key,
126
+ SDK_HEADER_NAME => SDK_HEADER_VALUE,
127
+ :accept => :mime)
128
+
129
+ break if response.code != 429 or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
130
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
131
+ attempt += 1
132
+ end
133
+ response
80
134
  end
81
135
 
82
136
  def send_request(request, uri)
137
+ response = nil
138
+ attempt = 0
83
139
  http = Net::HTTP.new(uri.host, uri.port)
84
140
  http.use_ssl = uri.scheme == 'https'
85
- response = http.request(request)
86
- if response.kind_of? Net::HTTPClientError
141
+
142
+ loop do
143
+ response = http.request(request)
144
+ break if response.code != "429" or attempt >= (@config[:max_attempts] || MAX_ATTEMPTS)
145
+ sleep(rand(0.0..[MAX_SLEEP, BASE_SLEEP * 2 ** attempt].min()))
146
+ attempt += 1
147
+ end
148
+
149
+ if response.kind_of? Net::HTTPClientError or response.kind_of? Net::HTTPServerError
87
150
  error_response = JSON.parse(response.body)
88
- raise Adzerk::ApiError.new(error_response["message"])
151
+ msg = error_response["message"] || error_response["Error"] || response.body
152
+ raise Adzerk::ApiError.new(msg)
89
153
  end
154
+
90
155
  response
91
156
  end
92
157
 
@@ -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
data/lib/adzerk/errors.rb CHANGED
File without changes
data/lib/adzerk/flight.rb CHANGED
@@ -1,12 +1,34 @@
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)
12
+ end
13
+
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}"
23
+ parse_response(client.get_request(url))
24
+ end
25
+
26
+ def list_for_campaign(campaign_id, is_active = nil)
27
+ url = "campaign/#{campaign_id}/flight"
28
+ if !is_active.nil?
29
+ url = "#{url}?isActive=#{is_active}"
30
+ end
31
+ parse_response(@client.get_request(url))
10
32
  end
11
33
  end
12
34
  end