adops_report_scrapper 0.2.44 → 0.2.45

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 511782172f619bbe1c7b0e969aceb11b6866f0d3
4
- data.tar.gz: 6a6abe3fb08919320422aad07248e301025c6b4f
3
+ metadata.gz: 6e398fac6bfeffceed28f29887aa913d02fd2942
4
+ data.tar.gz: 7498776ba363f9d5533ad8418641435274114718
5
5
  SHA512:
6
- metadata.gz: 440c7c86d225157fcec55fd5e7580494fdac2d32764571345d996a6a1e31672c17d1afe00311981b9686610fbbb049681906e0e245b3f0630869ff9402dcd408
7
- data.tar.gz: f231f1ebdf6dd5c7b4a346363333ab7193a7cb80c533ecbfba4b61132af487ba45347da990f10bb9fb16c0b69e284de0a39c05c0bedf80931e7d15dd4d4bba25
6
+ metadata.gz: 00493541a04fdbefd643278a45ab21c190ca71cb6eadafaf12346c8a1f5643b6179e72b4b573e9f4f2173955f1a214cb3d66f4c6105294b452fbc824f80e64fe
7
+ data.tar.gz: bf4723da5f70aeee4ea5ed12cc4728b6cf8fb34be7d72467242446723c98a5fb60770099cd78f526fa4da89fdbe3c3cf3936ba1d66970129a868d9dae8dc1bc5
data/CHANGELOG CHANGED
@@ -1,5 +1,8 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.2.45
4
+ reimplement openx with their API
5
+
3
6
  ## 0.2.41
4
7
  springserve client bug fix for account_id option. revcontent client refactor using their rest api
5
8
 
data/Gemfile CHANGED
@@ -18,3 +18,4 @@ gem 'cheddar'
18
18
  gem 'roo', '~> 2.4.0'
19
19
  gem 'selenium-webdriver', '~> 3.4.0'
20
20
  gem 'mail'
21
+ gem 'oauth'
@@ -1,165 +1,52 @@
1
1
  require 'date'
2
2
  require_relative 'base_client'
3
+ require_relative '../helpers/ox3client'
4
+ require 'csv'
3
5
 
4
6
  class AdopsReportScrapper::OpenxClient < AdopsReportScrapper::BaseClient
5
- REPORT_NAME = 'Ad Server Report for adops_report_scrapper'
7
+ def date_supported?(date = nil)
8
+ _date = date || @date
9
+ return true if _date >= Date.today - 2
10
+ false
11
+ end
6
12
 
7
13
  private
8
14
 
9
- def login
10
- @client.driver.resize 1920, 700
11
- fail 'please specify openx account prefix' unless @options['account_prefix']
12
- @account_prefix = @options['account_prefix']
13
- @client.visit "http://#{@account_prefix}.openx.net/"
14
- @client.fill_in 'Email', :with => @login
15
- @client.fill_in 'Password', :with => @secret
16
- @client.click_button 'Submit'
17
- begin
18
- @client.find :xpath, '//*[text()="Reports"]'
19
- rescue Exception => e
20
- raise e, 'Openx login error'
21
- end
22
- end
23
-
24
- def scrap
25
- request_report
15
+ def init_client
16
+ fail 'please specify openx consumer_key' unless @options['consumer_key']
17
+ fail 'please specify openx consumer_secret' unless @options['consumer_secret']
18
+ fail 'please specify openx realm' unless @options['realm']
19
+ fail 'please specify openx site_url' unless @options['site_url']
20
+ @consumer_key = @options['consumer_key']
21
+ @consumer_secret = @options['consumer_secret']
22
+ @realm = @options['realm']
23
+ @site_url = @options['site_url']
26
24
  end
27
25
 
28
- def request_report
29
- sleep 5
30
- @client.visit 'http://yahoo.com'
31
- sleep 5
32
- @client.visit "http://#{@account_prefix}.openx.net/#/reports?tab=my_reports"
33
- sleep 5
34
-
35
- begin
36
- tries ||= 6
37
- @client.find(:css, '#report_frame')
38
- rescue Exception => e
39
- retry unless (tries -= 1).zero?
40
- fail 'cannot find report frame'
41
- end
42
-
43
- create_report_if_not_exist
44
-
45
- @client.within_frame @client.find(:css, '#report_frame') do
46
- @client.find(:xpath, "//a[text()=\"#{REPORT_NAME}\"]").click
47
-
48
- begin
49
- tries ||= 6
50
- @client.find(:css, '.myFrame')
51
- rescue Exception => e
52
- retry unless (tries -= 1).zero?
53
- end
54
-
55
- @client.within_frame @client.find(:css, '.myFrame') do
56
- begin
57
- tries ||= 18
58
- @client.find(:xpath, '//option[text()="500"]')
59
- rescue Exception => e
60
- retry unless (tries -= 1).zero?
61
- end
62
-
63
- @client.find(:xpath, '//option[text()="500"]').select_option
64
- extract_data_from_report
65
- end
66
- end
67
- sleep 5
26
+ def before_quit_with_error
68
27
  end
69
28
 
70
- def create_report_if_not_exist
71
- @client.within_frame @client.find(:css, '#report_frame') do
72
- ready_elem = nil
73
- begin
74
- tries ||= 6
75
- ready_elem = @client.find(:xpath, '//*[text()="Preconfigured Reports"]')
76
- rescue Exception => e
77
- retry unless (tries -= 1).zero?
78
- end
79
-
80
- fail 'openx report page not ready' unless ready_elem
29
+ def scrap
30
+ start_date_str = @date.strftime('%Y-%m-%d 00:00:00')
31
+ end_date_str = @date.strftime('%Y-%m-%d 23:59:59')
81
32
 
82
- if @client.find_all(:xpath, "//a[text()=\"#{REPORT_NAME}\"]").count == 0
83
-
84
- # create report if not exist
85
- @client.find(:xpath, '//*[contains(text(),"Create Report")]').click
86
- @client.find(:xpath, '//li/*[text()="Ad Server Report"]').click
33
+ ox3 = OX3APIClient.new(@login, @secret, @site_url, @consumer_key, @consumer_secret, @realm)
87
34
 
88
- begin
89
- tries ||= 6
90
- @client.find(:css, '.myFrame')
91
- rescue Exception => e
92
- retry unless (tries -= 1).zero?
93
- end
94
-
95
- @client.within_frame @client.find(:css, '.myFrame') do
35
+ response = ox3.get("/report/run?report=inv_rev&start_date=#{URI.escape(start_date_str)}&end_date=#{URI.escape(end_date_str)}&report_format=csv&do_break=AdUnit,Country&saleschannel=SALESCHANNEL.OPENXMARKET")
36
+ report_pickup_url = @site_url + JSON.parse(response)['url']
37
+ report_csv_data = nil;
38
+ open(report_pickup_url) { |f| report_csv_data = f.read }
96
39
 
97
- @client.find(:xpath, '//*[text()="Last Seven Days"]').click
98
- @client.find(:xpath, '//*[text()="Yesterday"]').click
99
- @client.find(:xpath, '//*[@value="Next"]').trigger('click')
100
- sleep 2
40
+ @data = CSV.parse(report_csv_data)
101
41
 
102
- @client.find(:xpath, '//*[text()="Ad Unit"]').click
103
- @client.find(:xpath, '//img[../../td//*[text()="User"]]').click
104
- @client.find(:xpath, '//*[text()="Country"]').click
105
- @client.find(:xpath, '//*[text()="Device Category"]').click
106
- @client.find(:xpath, '//*[@value="Next"]').trigger('click')
107
- sleep 2
108
-
109
- @client.find(:xpath, '//*[text()="Paid Impressions"]').click
110
- @client.find(:xpath, '//*[text()="Impressions Delivered"]').click
111
- @client.find(:xpath, '//*[text()="Ad Requests"]').click
112
- @client.find(:xpath, '//img[../../td//*[text()="Revenue"]]').click
113
- @client.find(:xpath, '//*[text()="Publisher Revenue"]').click
114
- @client.find(:xpath, '//img[../../td//*[text()="Clicks"]]').click
115
- @client.find(:xpath, '//div[text()="Clicks"]').click
116
- @client.find(:xpath, '//*[@value="Next"]').trigger('click')
117
- sleep 2
118
-
119
- @client.find(:xpath, '//*[@value="Save"]').trigger('click')
120
-
121
- begin
122
- tries ||= 6
123
- @client.find(:xpath, '//*[text()="Save Report"]')
124
- rescue Exception => e
125
- retry unless (tries -= 1).zero?
126
- end
127
-
128
- @client.fill_in 'saveAsReportName', :with => REPORT_NAME
129
- @client.find(:xpath, '//*[@value="Save Report"]').trigger('click')
130
-
131
- begin
132
- tries ||= 6
133
- @client.find(:xpath, '//*[text()="Report Saved"]')
134
- rescue Exception => e
135
- retry unless (tries -= 1).zero?
136
- end
137
-
138
- @client.find(:xpath, '//*[text()="Back to My Reports"]').trigger('click')
139
- end
140
- sleep 2
141
- end
42
+ while @data.count > 0
43
+ row = @data.shift
44
+ break if row.first == 'Report Data:'
142
45
  end
143
- end
144
46
 
145
- def extract_data_from_report
146
- @data = []
147
- loop do
148
- 18.times do
149
- sleep 10
150
- break if @client.find_all(:xpath, '//table[@id="table_UniqueReportID"]/*/tr').count > 0
151
- end
152
- rows = @client.find_all :xpath, '//table[@id="table_UniqueReportID"]/*/tr'
153
- rows = rows.to_a
154
- header = rows.shift
155
- if @data.count == 0
156
- n_header = header.find_css('td,th').map { |td| td.visible_text }
157
- @data << n_header
158
- end
159
- @data += rows.map { |tr| tr.find_css('td,th').map { |td| td.visible_text } }.reject { |row| row[0] == 'Total' }
160
- pagee = @client.find(:xpath, '//*[contains(text(),"Showing rows")]').text.match(/-(\d+) of (\d+)\./).captures
161
- break if pagee[0] == pagee[1]
162
- @client.find_all(:css, '#paginationNext').first.trigger('click')
47
+ while @data.count > 0
48
+ break if @data.last.first == 'Real-time Buyer'
49
+ @data.pop
163
50
  end
164
51
  end
165
- end
52
+ end
@@ -1,3 +1,3 @@
1
1
  module AdopsReportScrapper
2
- VERSION = "0.2.44"
2
+ VERSION = "0.2.45"
3
3
  end
@@ -0,0 +1,184 @@
1
+ # https://raw.githubusercontent.com/openx/OX3-Ruby-API-Client/master/ox3client.rb
2
+
3
+ require 'oauth'
4
+ require 'yaml'
5
+
6
+ class OX3APIClient < OAuth::Consumer
7
+
8
+ def initialize(email, password, site_url, consumer_key, consumer_secret, realm,
9
+ version='v2', sso_domain='sso.openx.com', callback='oob', scheme='https', debug=false)
10
+
11
+ @version, @callback, @site, @debug = version, callback, site_url, debug
12
+ @site = @site.end_with?('/') ? @site.chop : @site
13
+
14
+ super(consumer_key, consumer_secret, {
15
+ :http_method => :post,
16
+ :scheme => :header,
17
+ :oauth_version => "1.0",
18
+ :signature_method => "HMAC-SHA1",
19
+ :site => @site,
20
+ :request_token_url => scheme + '://' + sso_domain + '/api/index/initiate',
21
+ :access_token_url => scheme + '://' + sso_domain + '/api/index/token',
22
+ :authorize_path => scheme + '://' + sso_domain + '/login/process',
23
+ :realm => realm
24
+ })
25
+
26
+ # Step 1. Fetch temporary request token.
27
+ fetch_request_token
28
+
29
+ # Step 2. Log in to SSO server and authorize token.
30
+ authorize_token(email, password)
31
+
32
+ # Step 3. Swap temporary request token for permanent access token.
33
+ fetch_access_token
34
+
35
+ # Step 4. Validate your access token.
36
+ validate_session
37
+ end
38
+
39
+ ################################################################################################################
40
+ def perform_request
41
+ http = self.create_http(@site)
42
+ http.open_timeout = 5 * 60
43
+ http.read_timeout = 15 * 60
44
+ params = Hash.new
45
+ params['Content-Type'] = 'application/json'
46
+ params['Cookie'] = 'openx3_access_token=' + @acccess_token.token + '; domain=' + get_domain + '; path=/'
47
+ prefix = "/ox/4.0"
48
+ response = http.request yield prefix, params
49
+ response.body
50
+ end
51
+
52
+ def get(path)
53
+ perform_request do |prefix, params|
54
+ self.create_http_request(
55
+ :get,
56
+ prefix + path,
57
+ params
58
+ )
59
+ end
60
+ end
61
+
62
+ def post(path, body = {})
63
+ if body.is_a?(Hash)
64
+ body = JSON.dump(body)
65
+ end
66
+ perform_request do |prefix, params|
67
+ self.create_http_request(
68
+ :post,
69
+ prefix + path,
70
+ body,
71
+ params
72
+ )
73
+ end
74
+ end
75
+
76
+ def put(path, body = {})
77
+ if body.is_a?(Hash)
78
+ body = JSON.dump(body)
79
+ end
80
+ perform_request do |prefix, params|
81
+ self.create_http_request(
82
+ :put,
83
+ prefix + path,
84
+ body,
85
+ params
86
+ )
87
+ end
88
+ end
89
+
90
+ def delete(path)
91
+ perform_request do |prefix, params|
92
+ self.create_http_request(
93
+ :delete,
94
+ prefix + path,
95
+ params
96
+ )
97
+ end
98
+ end
99
+
100
+ def logoff
101
+ get "/login/logout"
102
+ end
103
+ ################################################################################################################
104
+
105
+ private
106
+ def fetch_request_token
107
+ @request_token = self.get_request_token(
108
+ {:oauth_callback => @callback},
109
+ {'Content-Type' => 'application/x-www-form-urlencoded'}
110
+ )
111
+ if @debug
112
+ puts YAML::dump(@request_token)
113
+ end
114
+ end
115
+
116
+ def authorize_token(email, password)
117
+ authorize = self.request(:post, self.authorize_path, nil,
118
+ {:oauth_token => @request_token.token, :oauth_callback => @callback},
119
+ {:email => email, :password => password, :oauth_token => @request_token.token},
120
+ {'Content-Type' => 'application/x-www-form-urlencoded'}
121
+ )
122
+ if authorize.code.to_s == '200'
123
+ response = authorize
124
+ else
125
+ response = self.request(:post, authorize.header['Location'], nil,
126
+ {:oauth_token => @request_token.token, :oauth_callback => @callback}, nil,
127
+ {
128
+ 'Content-Type' => 'application/x-www-form-urlencoded',
129
+ 'Cookie' => authorize.get_fields('set-cookie')[0],
130
+ }
131
+ )
132
+ end
133
+ if @debug
134
+ puts YAML::dump(response)
135
+ end
136
+ @oauth_verifier = parse_tokens(response.body)[:oauth_verifier]
137
+ end
138
+
139
+ def fetch_access_token
140
+ @acccess_token = @request_token.get_access_token(
141
+ {:oauth_verifier => @oauth_verifier, :oauth_token => @request_token.token, :oauth_callback => @callback},
142
+ {'Content-Type' => 'application/x-www-form-urlencoded'}
143
+ )
144
+ if @debug
145
+ puts YAML::dump(@acccess_token)
146
+ end
147
+ end
148
+
149
+ def validate_session
150
+ =begin
151
+ path = "/ox/4.0/session"
152
+ method = :get
153
+ response = self.request(method.to_sym, @site + path, nil, {}, nil,
154
+ {
155
+ 'Content-Type' => 'application/json',
156
+ 'Cookie' => 'openx3_access_token=' + @acccess_token.token + '; domain=' + get_domain + '; path=/'
157
+ }
158
+ )
159
+ =end
160
+ response = perform_request do |prefix, params|
161
+ self.create_http_request(
162
+ :get,
163
+ prefix + "/session",
164
+ nil,
165
+ params
166
+ )
167
+ end
168
+ if @debug
169
+ puts YAML::dump(response)
170
+ end
171
+ end
172
+
173
+ def parse_tokens(keys)
174
+ keys.split("&").inject({}) do |hash, pair|
175
+ key, value = pair.split("=")
176
+ hash.merge({ key.to_sym => CGI.unescape(value) })
177
+ end
178
+ end
179
+
180
+ def get_domain
181
+ URI.parse(@site).host
182
+ end
183
+
184
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adops_report_scrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.44
4
+ version: 0.2.45
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stayman Hou
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-11-22 00:00:00.000000000 Z
11
+ date: 2017-11-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -291,6 +291,7 @@ files:
291
291
  - lib/adops_report_scrapper/undertone_client.rb
292
292
  - lib/adops_report_scrapper/version.rb
293
293
  - lib/adops_report_scrapper/zedo_client.rb
294
+ - lib/helpers/ox3client.rb
294
295
  - secret.sample.yml
295
296
  - tmp/.keep
296
297
  homepage: https://github.com/StaymanHou/adops_report_scrapper