appnexusapi 1.0.0 → 1.1.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +71 -39
- data/appnexusapi.gemspec +1 -2
- data/lib/appnexusapi.rb +21 -10
- data/lib/appnexusapi/configuration.rb +12 -0
- data/lib/appnexusapi/connection.rb +83 -90
- data/lib/appnexusapi/error.rb +3 -0
- data/lib/appnexusapi/faraday/raise_http_error.rb +15 -1
- data/lib/appnexusapi/read_only_service.rb +8 -0
- data/lib/appnexusapi/resource.rb +19 -15
- data/lib/appnexusapi/service.rb +35 -48
- data/lib/appnexusapi/services/ad_server_service.rb +9 -0
- data/lib/appnexusapi/{advertiser_service.rb → services/advertiser_service.rb} +0 -0
- data/lib/appnexusapi/{bidder_instance_service.rb → services/bidder_instance_service.rb} +0 -6
- data/lib/appnexusapi/{bidder_profile_service.rb → services/bidder_profile_service.rb} +0 -6
- data/lib/appnexusapi/{bidder_service.rb → services/bidder_service.rb} +0 -0
- data/lib/appnexusapi/services/brand_service.rb +2 -0
- data/lib/appnexusapi/services/browser_service.rb +2 -0
- data/lib/appnexusapi/{campaign_service.rb → services/campaign_service.rb} +0 -0
- data/lib/appnexusapi/services/category_service.rb +5 -0
- data/lib/appnexusapi/{content_category_service.rb → services/content_category_service.rb} +0 -1
- data/lib/appnexusapi/{creative_service.rb → services/creative_service.rb} +0 -0
- data/lib/appnexusapi/{creative_template_service.rb → services/creative_template_service.rb} +1 -6
- data/lib/appnexusapi/services/device_model_service.rb +2 -0
- data/lib/appnexusapi/{domain_list_service.rb → services/domain_list_service.rb} +0 -0
- data/lib/appnexusapi/services/inventory_attribute_service.rb +2 -0
- data/lib/appnexusapi/{inventory_source_service.rb → services/inventory_source_service.rb} +0 -0
- data/lib/appnexusapi/services/language_service.rb +2 -0
- data/lib/appnexusapi/{line_item_service.rb → services/line_item_service.rb} +0 -0
- data/lib/appnexusapi/services/log_level_data_download_service.rb +13 -0
- data/lib/appnexusapi/services/log_level_data_service.rb +105 -0
- data/lib/appnexusapi/services/media_type_service.rb +2 -0
- data/lib/appnexusapi/{member_service.rb → services/member_service.rb} +0 -0
- data/lib/appnexusapi/{object_limit_service.rb → services/object_limit_service.rb} +0 -0
- data/lib/appnexusapi/{operating_system_extended_service.rb → services/operating_system_extended_service.rb} +1 -6
- data/lib/appnexusapi/services/operating_system_service.rb +2 -0
- data/lib/appnexusapi/{payment_rule_service.rb → services/payment_rule_service.rb} +0 -0
- data/lib/appnexusapi/{placement_service.rb → services/placement_service.rb} +0 -0
- data/lib/appnexusapi/services/platform_member_service.rb +2 -0
- data/lib/appnexusapi/{profile_service.rb → services/profile_service.rb} +0 -0
- data/lib/appnexusapi/{publisher_service.rb → services/publisher_service.rb} +0 -0
- data/lib/appnexusapi/{segment_service.rb → services/segment_service.rb} +0 -2
- data/lib/appnexusapi/{site_service.rb → services/site_service.rb} +0 -0
- data/lib/appnexusapi/services/technical_attribute_service.rb +2 -0
- data/lib/appnexusapi/{tiny_tag_service.rb → services/tiny_tag_service.rb} +0 -6
- data/lib/appnexusapi/{user_service.rb → services/user_service.rb} +0 -0
- data/lib/appnexusapi/version.rb +1 -1
- data/spec/connection_spec.rb +46 -10
- data/spec/fixtures/vcr/content_category_crud.yml +188 -69
- data/spec/fixtures/vcr/log_level_data_service_download.yml +213 -0
- data/spec/integration/content_category_spec.rb +4 -0
- data/spec/{creative_service_spec.rb → integration/creative_service_spec.rb} +0 -0
- data/spec/integration/log_level_data_service_spec.rb +13 -0
- data/spec/{object_limit_service_spec.rb → integration/object_limit_service_spec.rb} +0 -0
- data/spec/integration/placement_spec.rb +0 -1
- data/spec/spec_helper.rb +2 -3
- metadata +52 -94
- data/lib/appnexusapi/ad_server_resource.rb +0 -2
- data/lib/appnexusapi/ad_server_service.rb +0 -20
- data/lib/appnexusapi/advertiser_resource.rb +0 -2
- data/lib/appnexusapi/bidder_instance_resource.rb +0 -2
- data/lib/appnexusapi/bidder_profile_resource.rb +0 -2
- data/lib/appnexusapi/bidder_resource.rb +0 -2
- data/lib/appnexusapi/brand_resource.rb +0 -2
- data/lib/appnexusapi/brand_service.rb +0 -8
- data/lib/appnexusapi/browser_resource.rb +0 -2
- data/lib/appnexusapi/browser_service.rb +0 -8
- data/lib/appnexusapi/campaign_resource.rb +0 -2
- data/lib/appnexusapi/category_resource.rb +0 -2
- data/lib/appnexusapi/category_service.rb +0 -12
- data/lib/appnexusapi/content_category_resource.rb +0 -2
- data/lib/appnexusapi/creative_resource.rb +0 -2
- data/lib/appnexusapi/creative_template_resource.rb +0 -2
- data/lib/appnexusapi/device_model_resource.rb +0 -2
- data/lib/appnexusapi/device_model_service.rb +0 -6
- data/lib/appnexusapi/domain_list_resource.rb +0 -2
- data/lib/appnexusapi/inventory_attribute_resource.rb +0 -2
- data/lib/appnexusapi/inventory_attribute_service.rb +0 -8
- data/lib/appnexusapi/inventory_source_resource.rb +0 -2
- data/lib/appnexusapi/language_resource.rb +0 -2
- data/lib/appnexusapi/language_service.rb +0 -8
- data/lib/appnexusapi/line_item_resource.rb +0 -2
- data/lib/appnexusapi/log_level_data_download_service.rb +0 -68
- data/lib/appnexusapi/log_level_data_resource.rb +0 -19
- data/lib/appnexusapi/log_level_data_service.rb +0 -26
- data/lib/appnexusapi/media_type_resource.rb +0 -2
- data/lib/appnexusapi/media_type_service.rb +0 -8
- data/lib/appnexusapi/member_resource.rb +0 -2
- data/lib/appnexusapi/object_limit_resource.rb +0 -2
- data/lib/appnexusapi/operating_system_extended_resource.rb +0 -2
- data/lib/appnexusapi/operating_system_resource.rb +0 -2
- data/lib/appnexusapi/operating_system_service.rb +0 -8
- data/lib/appnexusapi/payment_rule_resource.rb +0 -2
- data/lib/appnexusapi/placement_resource.rb +0 -2
- data/lib/appnexusapi/platform_member_resource.rb +0 -2
- data/lib/appnexusapi/platform_member_service.rb +0 -8
- data/lib/appnexusapi/profile_resource.rb +0 -2
- data/lib/appnexusapi/publisher_resource.rb +0 -2
- data/lib/appnexusapi/segment_resource.rb +0 -2
- data/lib/appnexusapi/site_resource.rb +0 -2
- data/lib/appnexusapi/technical_attribute_resource.rb +0 -2
- data/lib/appnexusapi/technical_attribute_service.rb +0 -8
- data/lib/appnexusapi/tiny_tag_resource.rb +0 -2
- data/lib/appnexusapi/user_resource.rb +0 -2
data/lib/appnexusapi/resource.rb
CHANGED
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
class AppnexusApi::Resource
|
|
2
2
|
|
|
3
|
-
attr_reader :dbg_info
|
|
3
|
+
attr_reader :dbg_info, :raw_json
|
|
4
4
|
|
|
5
5
|
def initialize(json, service, dbg_info = nil)
|
|
6
|
-
@
|
|
6
|
+
@raw_json = json
|
|
7
7
|
@service = service
|
|
8
8
|
@dbg_info = dbg_info
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def update(route_params={}, body_params={})
|
|
12
|
-
|
|
13
|
-
@json = resource.raw_json
|
|
11
|
+
def update(route_params = {}, body_params = {})
|
|
12
|
+
@raw_json = @service.update(id, route_params, body_params).raw_json
|
|
14
13
|
self
|
|
15
14
|
end
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
# If you have modified the @raw_json hash in place, you can just do resource.save
|
|
17
|
+
def save
|
|
18
|
+
@service.update(id, {}, @raw_json).raw_json
|
|
19
|
+
self
|
|
19
20
|
end
|
|
20
21
|
|
|
21
|
-
def
|
|
22
|
-
@
|
|
22
|
+
def delete(route_params = {})
|
|
23
|
+
@service.delete(id, route_params)
|
|
23
24
|
end
|
|
24
25
|
|
|
25
26
|
def method_missing(sym, *args, &block)
|
|
26
|
-
if @
|
|
27
|
-
@
|
|
28
|
-
elsif @
|
|
29
|
-
|
|
27
|
+
if @raw_json.respond_to?(sym)
|
|
28
|
+
@raw_json.send(sym, *args, &block)
|
|
29
|
+
elsif @raw_json.key?(sym.to_s)
|
|
30
|
+
@raw_json[sym.to_s]
|
|
30
31
|
else
|
|
31
32
|
super(sym, *args, &block)
|
|
32
33
|
end
|
|
33
34
|
end
|
|
34
35
|
|
|
35
|
-
def
|
|
36
|
-
@
|
|
36
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
37
|
+
@raw_json.respond_to?(method_name) || @raw_json.key?(method_name.to_s) || super
|
|
37
38
|
end
|
|
38
39
|
|
|
40
|
+
def to_s
|
|
41
|
+
@raw_json.inspect
|
|
42
|
+
end
|
|
39
43
|
end
|
data/lib/appnexusapi/service.rb
CHANGED
|
@@ -7,7 +7,7 @@ class AppnexusApi::Service
|
|
|
7
7
|
|
|
8
8
|
def name
|
|
9
9
|
@name ||= begin
|
|
10
|
-
str = self.class.name.split(
|
|
10
|
+
str = self.class.name.split('::').last.sub(/Service\z/, '')
|
|
11
11
|
str.gsub(/(.)([A-Z])/, '\1_\2').downcase
|
|
12
12
|
end
|
|
13
13
|
end
|
|
@@ -16,13 +16,6 @@ class AppnexusApi::Service
|
|
|
16
16
|
name + 's'
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
def resource_class
|
|
20
|
-
@resource_class ||= begin
|
|
21
|
-
resource_name = name.capitalize.gsub(/(_(.))/) { |c| $2.upcase }
|
|
22
|
-
AppnexusApi.const_get(resource_name + "Resource")
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
19
|
def uri_name
|
|
27
20
|
name.gsub('_', '-')
|
|
28
21
|
end
|
|
@@ -35,20 +28,12 @@ class AppnexusApi::Service
|
|
|
35
28
|
uri_name
|
|
36
29
|
end
|
|
37
30
|
|
|
38
|
-
def get(params={})
|
|
39
|
-
|
|
40
|
-
params
|
|
41
|
-
"num_elements" => DEFAULT_NUMBER_OF_ELEMENTS,
|
|
42
|
-
"start_element" => 0
|
|
43
|
-
}.merge(params)
|
|
44
|
-
response = @connection.get(uri_suffix, params).body['response']
|
|
45
|
-
if return_response
|
|
46
|
-
response
|
|
47
|
-
else
|
|
48
|
-
parse_response(response)
|
|
49
|
-
end
|
|
31
|
+
def get(params = {})
|
|
32
|
+
params = { 'num_elements' => DEFAULT_NUMBER_OF_ELEMENTS, 'start_element' => 0 }.merge(params)
|
|
33
|
+
parse_response(@connection.get(uri_suffix, params).body['response'])
|
|
50
34
|
end
|
|
51
35
|
|
|
36
|
+
# Page through all available elements automatically
|
|
52
37
|
def get_all(params = {})
|
|
53
38
|
responses = []
|
|
54
39
|
last_responses = get(params)
|
|
@@ -61,54 +46,56 @@ class AppnexusApi::Service
|
|
|
61
46
|
responses
|
|
62
47
|
end
|
|
63
48
|
|
|
64
|
-
def create(route_params={}, body={})
|
|
65
|
-
|
|
66
|
-
body = { uri_name => body }
|
|
49
|
+
def create(route_params = {}, body = {})
|
|
50
|
+
check_read_only!
|
|
67
51
|
route = @connection.build_url(uri_suffix, route_params)
|
|
68
|
-
response = @connection.post(route, body).body['response']
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
raise AppnexusApi::BadRequest.new(response.inspect)
|
|
72
|
-
end
|
|
52
|
+
response = @connection.post(route, { uri_name => body }).body['response']
|
|
53
|
+
validate_response!(response)
|
|
54
|
+
|
|
73
55
|
parse_response(response).first
|
|
74
56
|
end
|
|
75
57
|
|
|
76
|
-
def update(id, route_params={}, body={})
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
response
|
|
81
|
-
|
|
82
|
-
response.delete('dbg')
|
|
83
|
-
raise AppnexusApi::BadRequest.new(response.inspect)
|
|
84
|
-
end
|
|
58
|
+
def update(id, route_params = {}, body = {})
|
|
59
|
+
check_read_only!
|
|
60
|
+
route = @connection.build_url(uri_suffix, route_params.merge('id' => id))
|
|
61
|
+
response = @connection.put(route, { uri_name => body }).body['response']
|
|
62
|
+
validate_response!(response)
|
|
63
|
+
|
|
85
64
|
parse_response(response).first
|
|
86
65
|
end
|
|
87
66
|
|
|
88
67
|
def delete(id, route_params)
|
|
89
|
-
|
|
90
|
-
route = @connection.build_url(uri_suffix, route_params.merge(
|
|
68
|
+
check_read_only!
|
|
69
|
+
route = @connection.build_url(uri_suffix, route_params.merge('id' => id))
|
|
91
70
|
response = @connection.delete(route).body['response']
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
raise AppnexusApi::BadRequest.new(response.inspect)
|
|
95
|
-
end
|
|
71
|
+
validate_response!(response)
|
|
72
|
+
|
|
96
73
|
response
|
|
97
74
|
end
|
|
98
75
|
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
def check_read_only!
|
|
79
|
+
raise(AppnexusApi::NotImplemented, "Service is read-only.") if @read_only
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def validate_response!(response)
|
|
83
|
+
return unless response['error_id']
|
|
84
|
+
|
|
85
|
+
response.delete('dbg')
|
|
86
|
+
raise AppnexusApi::BadRequest.new(response.inspect)
|
|
87
|
+
end
|
|
88
|
+
|
|
99
89
|
def parse_response(response)
|
|
100
90
|
case key = resource_name(response)
|
|
101
91
|
when plural_name, plural_uri_name
|
|
102
|
-
response[key].map
|
|
103
|
-
resource_class.new(json, self, response['dbg'])
|
|
104
|
-
end
|
|
92
|
+
response[key].map { |json| AppnexusApi::Resource.new(json, self, response['dbg']) }
|
|
105
93
|
when name, uri_name
|
|
106
|
-
[
|
|
94
|
+
[AppnexusApi::Resource.new(response[key], self, response['dbg'])]
|
|
107
95
|
end
|
|
108
96
|
end
|
|
109
97
|
|
|
110
98
|
def resource_name(response)
|
|
111
99
|
[plural_name, plural_uri_name, name, uri_name].detect { |n| response.key?(n) }
|
|
112
100
|
end
|
|
113
|
-
|
|
114
101
|
end
|
|
File without changes
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
class AppnexusApi::BidderInstanceService < AppnexusApi::Service
|
|
2
|
-
|
|
3
2
|
def initialize(connection, bidder_id)
|
|
4
3
|
@bidder_id = bidder_id
|
|
5
4
|
super(connection)
|
|
@@ -9,10 +8,6 @@ class AppnexusApi::BidderInstanceService < AppnexusApi::Service
|
|
|
9
8
|
"instance"
|
|
10
9
|
end
|
|
11
10
|
|
|
12
|
-
def resource_class
|
|
13
|
-
AppnexusApi::BidderInstanceResource
|
|
14
|
-
end
|
|
15
|
-
|
|
16
11
|
def uri_suffix
|
|
17
12
|
"bidder-instance/#{@bidder_id}"
|
|
18
13
|
end
|
|
@@ -20,5 +15,4 @@ class AppnexusApi::BidderInstanceService < AppnexusApi::Service
|
|
|
20
15
|
def delete(id)
|
|
21
16
|
raise AppnexusApi::NotImplemented, "To remove an instance, please set it to inactive."
|
|
22
17
|
end
|
|
23
|
-
|
|
24
18
|
end
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
class AppnexusApi::BidderProfileService < AppnexusApi::Service
|
|
2
|
-
|
|
3
2
|
def initialize(connection, bidder_id)
|
|
4
3
|
@bidder_id = bidder_id
|
|
5
4
|
super(connection)
|
|
@@ -9,10 +8,6 @@ class AppnexusApi::BidderProfileService < AppnexusApi::Service
|
|
|
9
8
|
"profile"
|
|
10
9
|
end
|
|
11
10
|
|
|
12
|
-
def resource_class
|
|
13
|
-
AppnexusApi::BidderProfileResource
|
|
14
|
-
end
|
|
15
|
-
|
|
16
11
|
def uri_suffix
|
|
17
12
|
"profile/#{@bidder_id}"
|
|
18
13
|
end
|
|
@@ -20,5 +15,4 @@ class AppnexusApi::BidderProfileService < AppnexusApi::Service
|
|
|
20
15
|
def delete(id)
|
|
21
16
|
raise AppnexusApi::NotImplemented
|
|
22
17
|
end
|
|
23
|
-
|
|
24
18
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -3,16 +3,11 @@ class AppnexusApi::CreativeTemplateService < AppnexusApi::Service
|
|
|
3
3
|
"template"
|
|
4
4
|
end
|
|
5
5
|
|
|
6
|
-
def resource_class
|
|
7
|
-
AppnexusApi::CreativeTemplateResource
|
|
8
|
-
end
|
|
9
|
-
|
|
10
6
|
def uri_suffix
|
|
11
|
-
|
|
7
|
+
name
|
|
12
8
|
end
|
|
13
9
|
|
|
14
10
|
def delete(id)
|
|
15
11
|
raise AppnexusApi::NotImplemented
|
|
16
12
|
end
|
|
17
|
-
|
|
18
13
|
end
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require 'appnexusapi/services/log_level_data_service'
|
|
2
|
+
|
|
3
|
+
# TODO: Remove this class in v2.0
|
|
4
|
+
module AppnexusApi
|
|
5
|
+
class LogLevelDataDownloadService < LogLevelDataService
|
|
6
|
+
extend Gem::Deprecate
|
|
7
|
+
|
|
8
|
+
def initialize(connection, options = {})
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
deprecate :initialize, 'LogLevelDataService#initialize', 2017, 6
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
module AppnexusApi
|
|
2
|
+
class LogLevelDataService < AppnexusApi::ReadOnlyService
|
|
3
|
+
DEFAULT_FEED = 'standard_feed'.freeze
|
|
4
|
+
DOWNLOAD_URI = 'siphon-download'.freeze
|
|
5
|
+
RETRY_DOWNLOAD_PARAMS = {
|
|
6
|
+
base_interval: 30,
|
|
7
|
+
tries: 20,
|
|
8
|
+
max_elapsed_time: 3600,
|
|
9
|
+
on: [AppnexusApi::Error, ::Faraday::Error::ClientError],
|
|
10
|
+
on_retry: Proc.new do |exception, tries|
|
|
11
|
+
AppnexusApi.config.logger.warn("Retrying after #{exception.class}: #{tries} attempts.")
|
|
12
|
+
end
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
def initialize(connection, options = {})
|
|
16
|
+
@downloaded_files_path = options[:downloaded_files_path] || '.'
|
|
17
|
+
@siphon_name = options[:siphon_name] || DEFAULT_FEED
|
|
18
|
+
super(connection)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def download_new_files_since(time = nil)
|
|
22
|
+
since(time).map { |siphon| download_resource(siphon) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def uri_name
|
|
26
|
+
'siphon'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def since(time = nil)
|
|
30
|
+
params = {}
|
|
31
|
+
params[:siphon_name] = @siphon_name if @siphon_name
|
|
32
|
+
params[:updated_since] = time.strftime('%Y_%m_%d_%H') if time
|
|
33
|
+
siphons = get(params) || {}
|
|
34
|
+
|
|
35
|
+
# Anything with the same name and hour but with a newer timestamp is a republished replacement for an older file.
|
|
36
|
+
# When this happens appnexus is supposed to set the checksum for the old file to NULL but they do not always
|
|
37
|
+
# actually do this, so we have to manually reject invalid entries.
|
|
38
|
+
siphons.reject do |siphon|
|
|
39
|
+
(siphons - [siphon]).any? { |s| s.name == siphon.name && s.hour == siphon.hour && s.timestamp > siphon.timestamp }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
# Parameter is a LogLevelDataResource FKA a "Siphon"
|
|
46
|
+
# Downloads a gzipped file
|
|
47
|
+
# Returns an array of paths to downloaded files
|
|
48
|
+
def download_resource(siphon)
|
|
49
|
+
fail 'Missing necessary information!' unless siphon.name && siphon.hour && siphon.timestamp && siphon.splits
|
|
50
|
+
|
|
51
|
+
download_params = siphon.splits.map do |split_part|
|
|
52
|
+
# In the case of files that were later replaced, there should be no checksum and they shouldn't be downloaded
|
|
53
|
+
next nil if split_part['checksum'].nil? || split_part['checksum'].empty?
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
split_part: split_part['part'],
|
|
57
|
+
siphon_name: siphon.name,
|
|
58
|
+
timestamp: siphon.timestamp,
|
|
59
|
+
hour: siphon.hour,
|
|
60
|
+
checksum: split_part['checksum']
|
|
61
|
+
}
|
|
62
|
+
end.compact
|
|
63
|
+
|
|
64
|
+
download_params.map do |params|
|
|
65
|
+
uri = URI.parse(@connection.get(DOWNLOAD_URI, params.reject { |k, v| k == :checksum }).headers['location'])
|
|
66
|
+
filename = File.join(@downloaded_files_path, "#{params[:siphon_name]}_#{params[:hour]}_#{params[:split_part]}.gz")
|
|
67
|
+
|
|
68
|
+
Retriable.retriable(RETRY_DOWNLOAD_PARAMS) do
|
|
69
|
+
download_file(uri, filename)
|
|
70
|
+
calculated_checksum = Digest::MD5.hexdigest(File.read(filename))
|
|
71
|
+
if calculated_checksum != params[:checksum]
|
|
72
|
+
error_message = "Calculated checksum of #{calculated_checksum} doesn't match API provided checksum #{params[:checksum]}"
|
|
73
|
+
AppnexusApi.config.logger.fatal(error_message)
|
|
74
|
+
raise BadChecksumException, error_message
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
filename
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def download_file(uri, filename)
|
|
83
|
+
AppnexusApi.config.logger.debug("Starting HTTP download for: #{uri.to_s}...")
|
|
84
|
+
http_object = Net::HTTP.new(uri.host, uri.port)
|
|
85
|
+
http_object.use_ssl = true if uri.scheme == 'https'
|
|
86
|
+
|
|
87
|
+
begin
|
|
88
|
+
http_object.start do |http|
|
|
89
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
|
90
|
+
http.read_timeout = 500
|
|
91
|
+
|
|
92
|
+
http.request(request) do |response|
|
|
93
|
+
open(filename, 'wb') do |io|
|
|
94
|
+
response.read_body do |chunk|
|
|
95
|
+
io.write(chunk)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
AppnexusApi.config.logger.info("Stored download of #{uri.to_s} as #{filename}")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|