appnexusapi 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dcb81e6d6e3e396e606b8f5f34133564bb1e23d4
4
+ data.tar.gz: c818e90587d6ea29f0732b4e0d26e6b4632c2a73
5
+ SHA512:
6
+ metadata.gz: fbf3d7e3efe189261e35340b03ed7b06f34c5e99f8a11a3c3b1d0de6a93738a034dab5f7cbc867419dc03a027a01e97c2da35dbfbe53c762e7ad47c0ff69a467
7
+ data.tar.gz: 4a09f2255dc0e823f18b4c436ea959959afd087842389f125d5785dec9a18816a5fa5ad7396fb99091db7fd16c7761146cb5f16da58bdc0511fbecfb80d2f7a4
data/README.md CHANGED
@@ -20,13 +20,14 @@ Or install it yourself as:
20
20
 
21
21
  Establish a connection:
22
22
 
23
- connection = AppnexusApi::Connection.new({
24
- # optionally pass a uri for the staging site
25
- # defaults to "http://api.adnxs.com/"
26
- # uri => "http://api.sand-08.adnxs.net",
27
- "username" => 'username',
28
- "password" => 'password'
29
- })
23
+ connection = AppnexusApi::Connection.new(
24
+ 'username' => 'username',
25
+ 'password' => 'password'
26
+
27
+ # Defaults to connecting to https://api.appnexus.com/ but you can optionally pass a uri to
28
+ # connect to another endpoint, e.g. the staging site could be
29
+ # uri: 'http://api.sand-08.adnxs.net'
30
+ )
30
31
 
31
32
  Use a Service:
32
33
 
@@ -47,6 +48,16 @@ Use a Service:
47
48
  creative = creative_service.create(new_creative)
48
49
  creative.update("campaign" => "Testing")
49
50
 
51
+ ## Debugging
52
+
53
+ The APPNEXUS_API_DEBUG environment variable will trigger full printouts of Faraday's debug output to STDERR.
54
+
55
+ ```bash
56
+ cd /my/app
57
+ export APPNEXUS_API_DEBUG=true
58
+ bundle exec rails whatever
59
+ ```
60
+
50
61
  ## Contributing
51
62
 
52
63
  1. Fork it
@@ -15,7 +15,10 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = AppnexusApi::VERSION
17
17
 
18
- gem.add_dependency 'faraday', '~>0.8.7'
19
- gem.add_dependency "multi_json", "~> 1.7.2"
18
+ gem.add_dependency 'faraday', '~> 0.9'
19
+ gem.add_dependency 'faraday_middleware'
20
+ gem.add_dependency 'multi_json'
21
+ gem.add_dependency 'pester'
22
+
20
23
  gem.add_development_dependency 'bundler', '>= 1.2.0'
21
24
  end
@@ -1,4 +1,4 @@
1
- class AppnexusApi::BidderProfileResource < AppnexusApi::Service
1
+ class AppnexusApi::BidderProfileService < AppnexusApi::Service
2
2
 
3
3
  def initialize(connection, bidder_id)
4
4
  @bidder_id = bidder_id
@@ -14,7 +14,7 @@ class AppnexusApi::BidderProfileResource < AppnexusApi::Service
14
14
  end
15
15
 
16
16
  def uri_suffix
17
- "bidder-profile/#{@bidder_id}"
17
+ "profile/#{@bidder_id}"
18
18
  end
19
19
 
20
20
  def delete(id)
@@ -1,16 +1,19 @@
1
- require 'appnexusapi/faraday/encode_json'
2
- require 'appnexusapi/faraday/parse_json'
1
+ require 'faraday_middleware'
3
2
  require 'appnexusapi/faraday/raise_http_error'
4
3
 
5
4
  class AppnexusApi::Connection
6
5
  def initialize(config)
7
- config["uri"] = "http://api.adnxs.com/" unless config.has_key?("uri")
8
6
  @config = config
9
- @connection = Faraday::Connection.new(:url => config["uri"]) do |builder|
10
- builder.use AppnexusApi::Faraday::Request::JsonEncode
11
- builder.use AppnexusApi::Faraday::Response::RaiseHttpError
12
- builder.use AppnexusApi::Faraday::Response::ParseJson
13
- builder.adapter Faraday.default_adapter
7
+ @config['uri'] ||= 'https://api.appnexus.com/'
8
+ @connection = Faraday.new(@config['uri']) do |conn|
9
+ if ENV['APPNEXUS_API_DEBUG'].to_s =~ /^(true|1)$/i
10
+ conn.response :logger, Logger.new(STDERR), bodies: true
11
+ end
12
+
13
+ conn.request :json
14
+ conn.response :json, :content_type => /\bjson$/
15
+ conn.use AppnexusApi::Faraday::Response::RaiseHttpError
16
+ conn.adapter Faraday.default_adapter
14
17
  end
15
18
  end
16
19
 
@@ -19,8 +22,11 @@ class AppnexusApi::Connection
19
22
  end
20
23
 
21
24
  def login
22
- response = @connection.run_request(:post, 'auth', { "auth" => { "username" => @config["username"], "password" => @config["password"] } }, {})
23
- @token = response.body["token"]
25
+ response = @connection.run_request(:post, 'auth', { 'auth' => { 'username' => @config['username'], 'password' => @config['password'] } }, {})
26
+ if response.body['response']['error_code']
27
+ fail "#{response.body['response']['error_code']}/#{response.body['response']['error_description']}"
28
+ end
29
+ @token = response.body['response']['token']
24
30
  end
25
31
 
26
32
  def logout
@@ -29,25 +35,25 @@ class AppnexusApi::Connection
29
35
 
30
36
  def get(route, params={}, headers={})
31
37
  params = params.delete_if {|key, value| value.nil? }
32
- run_request(:get, @connection.build_url(route, params), nil, headers).body
38
+ run_request(:get, @connection.build_url(route, params), nil, headers)
33
39
  end
34
40
 
35
41
  def post(route, body=nil, headers={})
36
- run_request(:post, route, body, headers).body
42
+ run_request(:post, route, body, headers)
37
43
  end
38
44
 
39
45
  def put(route, body=nil, headers={})
40
- run_request(:put, route, body, headers).body
46
+ run_request(:put, route, body, headers)
41
47
  end
42
48
 
43
49
  def delete(route, body=nil, headers={})
44
- run_request(:delete, route, body, headers).body
50
+ run_request(:delete, route, body, headers)
45
51
  end
46
52
 
47
53
  def run_request(method, route, body, headers)
48
54
  login if !is_authorized?
49
55
  begin
50
- @connection.run_request(method, route, body, { "Authorization" => @token }.merge(headers))
56
+ @connection.run_request(method, route, body, { 'Authorization' => @token }.merge(headers))
51
57
  rescue AppnexusApi::Unauthorized => e
52
58
  if @retry == true
53
59
  raise AppnexusApi::Unauthorized, e
@@ -57,7 +63,7 @@ class AppnexusApi::Connection
57
63
  run_request(method, route, body, headers)
58
64
  end
59
65
  rescue Faraday::Error::TimeoutError => e
60
- raise AppnexusApi::Timeout, "Timeout"
66
+ raise AppnexusApi::Timeout, 'Timeout'
61
67
  ensure
62
68
  @retry = false
63
69
  end
@@ -0,0 +1,2 @@
1
+ class AppnexusApi::CreativeTemplateResource < AppnexusApi::Resource
2
+ end
@@ -0,0 +1,18 @@
1
+ class AppnexusApi::CreativeTemplateService < AppnexusApi::Service
2
+ def name
3
+ "template"
4
+ end
5
+
6
+ def resource_class
7
+ AppnexusApi::CreativeTemplateResource
8
+ end
9
+
10
+ def uri_suffix
11
+ "template"
12
+ end
13
+
14
+ def delete(id)
15
+ raise AppnexusApi::NotImplemented
16
+ end
17
+
18
+ end
@@ -0,0 +1,68 @@
1
+ class AppnexusApi::LogLevelDataDownloadService < AppnexusApi::Service
2
+ class BadChecksumException < Exception
3
+ end
4
+
5
+ def initialize(connection, options = {})
6
+ @read_only = true
7
+ @downloaded_files_path = options[:downloaded_files_path] || '.'
8
+ super(connection)
9
+ end
10
+
11
+ def download_location(params = {})
12
+ @connection.get(uri_suffix, params).headers['location']
13
+ end
14
+
15
+ # Parameter is a LogLevelDataResource
16
+ # Downloads a gzipped file
17
+ # Returns an array of paths to downloaded files
18
+ def download_resource(data_resource)
19
+ data_resource.download_params.map do |params|
20
+ uri = URI.parse(download_location(params.reject { |k,v| k == :checksum }))
21
+ filename = File.join(@downloaded_files_path, "#{params[:siphon_name]}_#{params[:hour]}_#{params[:split_part]}.gz")
22
+ Pester.retry_with_exponential_backoff do
23
+ download_file(uri, filename)
24
+ calculated_checksum = Digest::MD5.hexdigest(File.read(filename))
25
+ if calculated_checksum != params[:checksum]
26
+ error_message = "Calculated checksum of #{calculated_checksum} doesn't match API provided checksum #{params[:checksum]}"
27
+ puts error_message
28
+ fail(BadChecksumException, error_message)
29
+ end
30
+ end
31
+
32
+ filename
33
+ end
34
+ end
35
+
36
+ def get
37
+ fail(AppnexusApi::NotImplemented, 'This service is designed to work through download_location method.')
38
+ end
39
+
40
+ def uri_name
41
+ 'siphon-download'
42
+ end
43
+
44
+ private
45
+
46
+ def download_file(uri, filename)
47
+ puts "Starting HTTP download for: #{uri.to_s}..."
48
+ http_object = Net::HTTP.new(uri.host, uri.port)
49
+ http_object.use_ssl = true if uri.scheme == 'https'
50
+ begin
51
+ http_object.start do |http|
52
+ request = Net::HTTP::Get.new(uri.request_uri)
53
+ http.read_timeout = 500
54
+ http.request(request) do |response|
55
+ open(filename, 'wb') do |io|
56
+ response.read_body do |chunk|
57
+ io.write(chunk)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ rescue StandardError => e
63
+ puts "=> Exception: '#{e}'. Skipping download."
64
+ return
65
+ end
66
+ puts "Stored download as #{filename}"
67
+ end
68
+ end
@@ -0,0 +1,20 @@
1
+ class AppnexusApi::LogLevelDataResource < AppnexusApi::Resource
2
+ # Extract an array of hashes of params to pass to the LogLevelDownloadService
3
+ def download_params
4
+ fail 'Missing necessaray information!' unless name && hour && timestamp && splits
5
+ splits.map do |split_part|
6
+ if split_part['checksum'].blank?
7
+ # In the case of regenerated files, there can be no checksum. These replaced hourly files should not be downloaded.
8
+ nil
9
+ else
10
+ {
11
+ split_part: split_part['part'],
12
+ siphon_name: name,
13
+ timestamp: timestamp,
14
+ hour: hour,
15
+ checksum: split_part['checksum']
16
+ }
17
+ end
18
+ end.compact
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ class AppnexusApi::LogLevelDataService < AppnexusApi::Service
2
+ def initialize(connection, options = {})
3
+ @read_only = true
4
+ @siphon_name = options[:siphon_name]
5
+
6
+ super(connection)
7
+ end
8
+
9
+ def since(time = nil)
10
+ params = {}
11
+ params[:siphon_name] = @siphon_name if @siphon_name
12
+ params[:updated_since] = time.strftime('%Y_%m_%d_%H') if time
13
+
14
+ get(params)
15
+ end
16
+
17
+ def uri_name
18
+ 'siphon'
19
+ end
20
+ end
@@ -21,15 +21,15 @@ class AppnexusApi::Service
21
21
  AppnexusApi.const_get(resource_name + "Resource")
22
22
  end
23
23
  end
24
-
24
+
25
25
  def uri_name
26
26
  name.gsub('_', '-')
27
27
  end
28
-
28
+
29
29
  def plural_uri_name
30
30
  uri_name + 's'
31
31
  end
32
-
32
+
33
33
  def uri_suffix
34
34
  uri_name
35
35
  end
@@ -40,7 +40,7 @@ class AppnexusApi::Service
40
40
  "num_elements" => 100,
41
41
  "start_element" => 0
42
42
  }.merge(params)
43
- response = @connection.get(uri_suffix, params)
43
+ response = @connection.get(uri_suffix, params).body['response']
44
44
  if return_response
45
45
  response
46
46
  elsif response.has_key?(plural_name) || response.has_key?(plural_uri_name)
@@ -57,20 +57,28 @@ class AppnexusApi::Service
57
57
  def create(attributes={})
58
58
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
59
59
  attributes = { name => attributes }
60
- response = @connection.post(uri_suffix, attributes)
60
+ response = @connection.post(uri_suffix, attributes).body['response']
61
+ if response['error_id']
62
+ response.delete('dbg')
63
+ raise AppnexusApi::BadRequest.new(response.inspect)
64
+ end
61
65
  get("id" => response["id"]).first
62
66
  end
63
67
 
64
68
  def update(id, attributes={})
65
69
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
66
70
  attributes = { name => attributes }
67
- response = @connection.put([uri_suffix, id].join('/'), attributes)
71
+ response = @connection.put([uri_suffix, id].join('/'), attributes).body['response']
72
+ if response['error_id']
73
+ response.delete('dbg')
74
+ raise AppnexusApi::BadRequest.new(response.inspect)
75
+ end
68
76
  get("id" => response["id"]).first
69
77
  end
70
78
 
71
79
  def delete(id)
72
80
  raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
73
- @connection.delete([uri_suffix, id].join('/'))
81
+ @connection.delete([uri_suffix, id].join('/')).body['response']
74
82
  end
75
83
 
76
84
  end
@@ -1,3 +1,3 @@
1
1
  module AppnexusApi
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  end
metadata CHANGED
@@ -1,49 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: appnexusapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
5
- prerelease:
4
+ version: 0.0.6
6
5
  platform: ruby
7
6
  authors:
8
7
  - Brandon Aaron
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-04-10 00:00:00.000000000Z
11
+ date: 2016-06-16 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: faraday
16
- requirement: &2168053620 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
- version: 0.8.7
19
+ version: '0.9'
22
20
  type: :runtime
23
21
  prerelease: false
24
- version_requirements: *2168053620
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
25
41
  - !ruby/object:Gem::Dependency
26
42
  name: multi_json
27
- requirement: &2168052460 !ruby/object:Gem::Requirement
28
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
29
44
  requirements:
30
- - - ~>
45
+ - - ">="
31
46
  - !ruby/object:Gem::Version
32
- version: 1.7.2
47
+ version: '0'
33
48
  type: :runtime
34
49
  prerelease: false
35
- version_requirements: *2168052460
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pester
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
36
69
  - !ruby/object:Gem::Dependency
37
70
  name: bundler
38
- requirement: &2168051640 !ruby/object:Gem::Requirement
39
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
40
72
  requirements:
41
- - - ! '>='
73
+ - - ">="
42
74
  - !ruby/object:Gem::Version
43
75
  version: 1.2.0
44
76
  type: :development
45
77
  prerelease: false
46
- version_requirements: *2168051640
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.2.0
47
83
  description: ''
48
84
  email:
49
85
  - brandon.aaron@gmail.com
@@ -51,7 +87,7 @@ executables: []
51
87
  extensions: []
52
88
  extra_rdoc_files: []
53
89
  files:
54
- - .gitignore
90
+ - ".gitignore"
55
91
  - Gemfile
56
92
  - LICENSE
57
93
  - README.md
@@ -77,11 +113,11 @@ files:
77
113
  - lib/appnexusapi/content_category_service.rb
78
114
  - lib/appnexusapi/creative_resource.rb
79
115
  - lib/appnexusapi/creative_service.rb
116
+ - lib/appnexusapi/creative_template_resource.rb
117
+ - lib/appnexusapi/creative_template_service.rb
80
118
  - lib/appnexusapi/domain_list_resource.rb
81
119
  - lib/appnexusapi/domain_list_service.rb
82
120
  - lib/appnexusapi/error.rb
83
- - lib/appnexusapi/faraday/encode_json.rb
84
- - lib/appnexusapi/faraday/parse_json.rb
85
121
  - lib/appnexusapi/faraday/raise_http_error.rb
86
122
  - lib/appnexusapi/inventory_attribute_resource.rb
87
123
  - lib/appnexusapi/inventory_attribute_service.rb
@@ -91,6 +127,9 @@ files:
91
127
  - lib/appnexusapi/language_service.rb
92
128
  - lib/appnexusapi/line_item_resource.rb
93
129
  - lib/appnexusapi/line_item_service.rb
130
+ - lib/appnexusapi/log_level_data_download_service.rb
131
+ - lib/appnexusapi/log_level_data_resource.rb
132
+ - lib/appnexusapi/log_level_data_service.rb
94
133
  - lib/appnexusapi/member_resource.rb
95
134
  - lib/appnexusapi/member_service.rb
96
135
  - lib/appnexusapi/operating_system_service.rb
@@ -109,27 +148,26 @@ files:
109
148
  - lib/appnexusapi/version.rb
110
149
  homepage: http://simpli.fi
111
150
  licenses: []
151
+ metadata: {}
112
152
  post_install_message:
113
153
  rdoc_options: []
114
154
  require_paths:
115
155
  - lib
116
156
  required_ruby_version: !ruby/object:Gem::Requirement
117
- none: false
118
157
  requirements:
119
- - - ! '>='
158
+ - - ">="
120
159
  - !ruby/object:Gem::Version
121
160
  version: '0'
122
161
  required_rubygems_version: !ruby/object:Gem::Requirement
123
- none: false
124
162
  requirements:
125
- - - ! '>='
163
+ - - ">="
126
164
  - !ruby/object:Gem::Version
127
165
  version: '0'
128
166
  requirements: []
129
167
  rubyforge_project:
130
- rubygems_version: 1.8.10
168
+ rubygems_version: 2.2.3
131
169
  signing_key:
132
- specification_version: 3
170
+ specification_version: 4
133
171
  summary: Unofficial Ruby API Wrapper for Appnexus
134
172
  test_files: []
135
173
  has_rdoc:
@@ -1,15 +0,0 @@
1
- module AppnexusApi
2
- module Faraday
3
- module Request
4
- class JsonEncode < ::Faraday::Middleware
5
- def call(env)
6
- if env[:request_headers]["Content-Type"] == nil
7
- env[:body] = MultiJson.encode(env[:body]) if env[:body] != nil
8
- env[:request_headers]["Content-Type"] = "application/json"
9
- end
10
- @app.call(env)
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,61 +0,0 @@
1
- module AppnexusApi
2
- module Faraday
3
- module Response
4
- class ParseJson < ::Faraday::Middleware
5
- dependency 'multi_json'
6
-
7
- def call(env)
8
- @app.call(env).on_complete do
9
- if env[:response_headers]["content-type"].include?("application/json")
10
- env[:body] = convert_to_json(env[:body])["response"]
11
- check_for_error(env)
12
- end
13
- end
14
- end
15
-
16
- protected
17
-
18
- def convert_to_json(body)
19
- case body.strip
20
- when ''
21
- nil
22
- when 'true'
23
- true
24
- when 'false'
25
- false
26
- else
27
- begin
28
- ::MultiJson.decode(body)
29
- rescue Exception => exception
30
- raise AppnexusApi::InvalidJson
31
- end
32
- end
33
- end
34
-
35
- def check_for_error(env)
36
- if env[:body].has_key?("error")
37
- case env[:body]["error_id"]
38
- when "NOAUTH"
39
- raise AppnexusApi::Unauthorized, error_message(env)
40
- when "UNAUTH"
41
- raise AppnexusApi::Forbidden, error_message(env)
42
- when "SYNTAX"
43
- raise AppnexusApi::UnprocessableEntity, error_message(env)
44
- when "SYSTEM"
45
- raise AppnexusApi::InternalServerError, error_message(env)
46
- when "INTEGRITY"
47
- raise AppnexusApi::UnprocessableEntity, error_message(env)
48
- else
49
- raise AppnexusApi::Error, error_message(env)
50
- end
51
- end
52
- end
53
-
54
- def error_message(env)
55
- "#{env[:method].to_s.upcase} #{env[:url].to_s} (#{env[:body]["error_id"]}): #{env[:body]["error"]}"
56
- end
57
-
58
- end
59
- end
60
- end
61
- end