gooddata_eloqua 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 833a93676772e7e93b3745dd7f9e7ba9a9633f91
4
+ data.tar.gz: 6e1e320b6553360d9a1d0f14606cbe36d90b2284
5
+ SHA512:
6
+ metadata.gz: 4847d22bd39cbfbf285039a989753a769d9c70fbf346bbd469a8eead823405fe1b2b5febb1044d0404711f91ec8f9eee611a2833a6c6ba3aa00977fe41b592b2
7
+ data.tar.gz: 0fa933a67e09c8353b9ae74592087e61bbad434f4b29ddc01f891ed3a9102e01b7fe4f629fddc2f3681f875f362571ca8c6bb5983665f4b79d91a6d9f2e54d50
@@ -0,0 +1,12 @@
1
+
2
+ module GoodDataEloqua
3
+ class << self
4
+ def connect eloqua_interface
5
+ GoodDataEloqua::Client.new(:eloqua => eloqua_interface)
6
+ end
7
+
8
+ alias :client :connect
9
+ end
10
+ end
11
+
12
+ require_relative 'gooddata_eloqua/client'
@@ -0,0 +1,49 @@
1
+ require 'csv'
2
+ require 'securerandom'
3
+ require 'fileutils'
4
+ require 'pmap'
5
+ require 'eloqua_api'
6
+ require 'pry'
7
+ require 'base64'
8
+ require 'rest_client'
9
+
10
+ class GoodDataEloqua::Client
11
+
12
+ def initialize(config={})
13
+ $global_id = SecureRandom.hex
14
+ $client = config[:eloqua] || config[:client]
15
+
16
+ self.system_check
17
+
18
+ end
19
+
20
+ def campaigns(config={})
21
+ GoodDataEloqua::Campaigns.new(config)
22
+ end
23
+
24
+ def emails(config={})
25
+ GoodDataEloqua::Emails.new(config)
26
+ end
27
+
28
+ def contacts(config={})
29
+ GoodDataEloqua::Contacts.new(config)
30
+ end
31
+
32
+ def system_check(refresh = false)
33
+
34
+ if refresh
35
+ FileUtils.rm_rf('downloads')
36
+ end
37
+
38
+ FileUtils.mkdir_p 'downloads'
39
+
40
+ end
41
+
42
+ end
43
+
44
+ require_relative 'helpers/pool'
45
+ require_relative 'helpers/request'
46
+
47
+ require_relative 'models/campaigns'
48
+ require_relative 'models/emails'
49
+ require_relative 'models/contacts'
@@ -0,0 +1,32 @@
1
+ class Pool
2
+
3
+ attr_accessor :running
4
+
5
+ def initialize
6
+ @group = ThreadGroup.new
7
+ @running = true
8
+ end
9
+
10
+ def thread(&thread)
11
+ @group.add(Thread.new(&thread))
12
+ end
13
+
14
+ alias :fork :thread
15
+
16
+ def active_threads
17
+ @group.list.length
18
+ end
19
+
20
+ def list
21
+ @group.list
22
+ end
23
+
24
+ def exit
25
+
26
+ @group.pmap { |thread|
27
+ thread.exit
28
+ } unless @group.empty?
29
+
30
+ end
31
+
32
+ end
@@ -0,0 +1,264 @@
1
+ class GoodDataEloqua::Request
2
+
3
+ attr_accessor :asset_type
4
+
5
+ def initialize(config = {})
6
+
7
+ @client = $client
8
+ @asset_type_plural = nil
9
+ @asset_type_singular = nil
10
+
11
+ end
12
+
13
+ def get_all(config = {})
14
+ end_point = @asset_type_plural || config[:end_point] || config[:url] || @parent
15
+ page = config[:page] || config[:page_number]
16
+
17
+ raise ':end_point and :page_number must be defined.' unless end_point && page
18
+
19
+ @client.get(end_point, "?page=#{page}")
20
+
21
+ end
22
+
23
+ def get_all_by_page(page, config ={})
24
+
25
+ default = Hash.new
26
+ default[:end_point] = @asset_type_plural || config[:end_point]
27
+ default[:page] = page
28
+ self.get_all(default)
29
+
30
+ end
31
+
32
+ def write_all_ids_return_csv(file_name, config={})
33
+
34
+ if file_name
35
+ fd = IO.sysopen("./downloads/#{file_name}", 'w+')
36
+ end
37
+
38
+ csv = CSV.new(IO.new(fd))
39
+ analyze = self.get_all_by_page(0)
40
+ pages = analyze['total'].to_i
41
+ total = (pages/1000).round
42
+
43
+ total = 1 if total == 0
44
+
45
+ self.get_all_distributed total, csv
46
+ puts "\n#{Time.now} => Flushing IO (#{@session_csv}.id)..."
47
+
48
+
49
+ file_name
50
+
51
+ end
52
+
53
+ def ids_to_eloqua_return_csv(csv, config = {})
54
+
55
+ if csv
56
+ fd = IO.sysopen("./downloads/#{csv}", 'r')
57
+ end
58
+
59
+ started_method = Time.now
60
+
61
+ write_path = "./downloads/#{@session_id}_complete.csv"
62
+ write_fd = IO.sysopen(write_path, 'w+')
63
+ csv = CSV.new(IO.new(write_fd))
64
+ pool = Pool.new
65
+
66
+ CSV.open(fd) do |read_csv|
67
+
68
+ ids = read_csv.map { |row|
69
+ row[0]
70
+ }
71
+
72
+ puts "#{Time.now} => Extracted from CSV: #{ids.length}\n"
73
+
74
+ elapsed_times = []
75
+
76
+ loop do
77
+
78
+ batch = ids.slice!(1..20)
79
+
80
+ started_batch = Time.now
81
+
82
+ if elapsed_times.length > 5
83
+ estimated_time = elapsed_times.inject{ |sum, el| sum + el }.to_f / elapsed_times.size
84
+ else
85
+ estimated_time = 0
86
+ end
87
+
88
+ if (estimated_time/60) > 60 && estimated_time != 0
89
+ time_readable = "#{((estimated_time/60)/60).round(2)} hours"
90
+
91
+ elsif (estimated_time/60) < 60 && (estimated_time/60) > 1 && estimated_time != 0
92
+ time_readable = "#{(estimated_time/60).round(2)} minutes"
93
+
94
+ elsif (estimated_time/60) > 0 && estimated_time != 0
95
+ time_readable = "#{(estimated_time).round(2)} seconds"
96
+
97
+ else
98
+ time_readable = 'Estimating...'
99
+
100
+ end
101
+
102
+ break unless batch.length > 0 && pool.list.length
103
+
104
+ #
105
+ batch.each { |i|
106
+ pool.thread {
107
+ response = self.get_one_by_id(i)
108
+ csv << response.values
109
+ csv.flush
110
+ print "\r#{Time.now} => IDs Remaing: #{ids.length} - Complete: #{time_readable} - Thread Pool: #{pool.active_threads} \s\s\s\s"
111
+ }
112
+ }
113
+
114
+ ended_batch = Time.now
115
+
116
+ elapsed_time = ended_batch - started_batch
117
+ number_of_estimated_chunks = ids.length/20
118
+ estimated_batch_time = (elapsed_time*number_of_estimated_chunks).round
119
+
120
+ if elapsed_times.length < 10
121
+ elapsed_times << estimated_batch_time
122
+ elsif elapsed_times.length > 50
123
+ 40.times do
124
+ elapsed_times.pop
125
+ end
126
+ end
127
+
128
+
129
+ if pool.active_threads > 21
130
+ sleep 3
131
+ end
132
+
133
+ break if ids.length == 0 && pool.list.length
134
+
135
+
136
+ end
137
+
138
+
139
+
140
+ puts "#{Time.now} => Complete. CSV written to \"./downloads/#{@session_id}_complete.csv\""
141
+
142
+ end
143
+
144
+ write_path
145
+
146
+ end
147
+
148
+
149
+ def get_all_distributed num_iterations, csv
150
+
151
+ iterations = []
152
+ num_iterations.times { |i| iterations << i }
153
+ iterations << num_iterations
154
+
155
+ pool = Pool.new
156
+
157
+ while pool.running do
158
+
159
+ batch = iterations.slice!(1..20)
160
+
161
+ break unless batch
162
+
163
+ batch.each { |i|
164
+ pool.thread {
165
+ response = self.get_all_by_page(i)
166
+ response['elements'].each { |element|
167
+ csv << [element['id']]
168
+ }
169
+ csv.flush
170
+ print "\r#{Time.now} => Pages #{iterations.length} of #{num_iterations} - Workers: #{pool.active_threads}\s"
171
+ }
172
+ }
173
+
174
+ if pool.active_threads > 20
175
+ sleep 2
176
+ end
177
+
178
+ if iterations.length == 0 && pool.active_threads == 0
179
+ pool.running = false
180
+ else
181
+ next
182
+ end
183
+
184
+ end
185
+
186
+ end
187
+
188
+ def set_asset_type asset
189
+
190
+ case asset
191
+ when 'contact', 'contacts'
192
+
193
+ if asset[-1] == 's'
194
+ @asset_type_plural = "/data/#{asset}"
195
+ @asset_type_singular = "/data/#{asset[0..-2]}"
196
+ elsif asset[-1] != 's'
197
+ @asset_type_plural = "/data/#{asset}s"
198
+ @asset_type_singular = "/data/#{asset}"
199
+ else
200
+ raise "Unable to parse \"#{asset}\" please make sure it is a string."
201
+ end
202
+
203
+ when 'email', 'emails'
204
+
205
+ if asset[-1] == 's'
206
+ @asset_type_plural = "/assets/#{asset}"
207
+ @asset_type_singular = "/assets/#{asset[0..-2]}"
208
+ elsif asset[-1] != 's'
209
+ @asset_type_plural = "/assets/#{asset}s"
210
+ @asset_type_singular = "/assets/#{asset}"
211
+ else
212
+ raise "Unable to parse \"#{asset}\" please make sure it is a string."
213
+ end
214
+
215
+ when 'campaign', 'campaigns'
216
+
217
+ if asset[-1] == 's'
218
+ @asset_type_plural = "/assets/#{asset}"
219
+ @asset_type_singular = "/assets/#{asset[0..-2]}"
220
+ elsif asset[-1] != 's'
221
+ @asset_type_plural = "/assets/#{asset}s"
222
+ @asset_type_singular = "/assets/#{asset}"
223
+ else
224
+ raise "Unable to parse \"#{asset}\" please make sure it is a string."
225
+ end
226
+
227
+ else
228
+
229
+ if asset[-1] == 's'
230
+ @asset_type_plural = "/assets/#{asset}"
231
+ @asset_type_singular = "/assets/#{asset[0..-2]}"
232
+ elsif asset[-1] != 's'
233
+ @asset_type_plural = "/assets/#{asset}s"
234
+ @asset_type_singular = "/assets/#{asset}"
235
+ else
236
+ raise "Unable to parse \"#{asset}\" please make sure it is a string."
237
+ end
238
+
239
+ end
240
+
241
+ end
242
+
243
+ alias :get_all_from_page :get_all_by_page
244
+
245
+ def get_one(config={})
246
+ #lookup_key = @asset_type_singular.gsub("/assets/","").downcase.to_sym
247
+ sym_key = config[:id]
248
+ depth = config[:depth] || 'complete'
249
+ end_point = @asset_type_singular+"/"+sym_key
250
+ @client.get(end_point, depth)
251
+ end
252
+
253
+ def get_one_by_id(id, config={})
254
+ default = Hash.new
255
+ default[:depth] = config[:depth] || 'complete'
256
+ default[:id] = id
257
+ self.get_one(default)
258
+ end
259
+
260
+ def clean
261
+ FileUtils.rm_f("/downloads/#{@session_csv}")
262
+ end
263
+
264
+ end
@@ -0,0 +1,15 @@
1
+
2
+ class GoodDataEloqua::Campaigns < GoodDataEloqua::Request
3
+
4
+ def initialize(config={})
5
+ @client = $client
6
+
7
+ @client = $client
8
+ @session_id = SecureRandom.hex+"_campaigns"
9
+ @session_csv = @session_id+".csv"
10
+ self.set_asset_type('campaigns')
11
+
12
+ end
13
+
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+ class GoodDataEloqua::Contacts < GoodDataEloqua::Request
2
+
3
+ attr_accessor :session_csv
4
+
5
+ def initialize(config={})
6
+
7
+ @client = $client
8
+ @session_id ||= SecureRandom.hex+"_contacts"
9
+ @session_csv = @session_id+".csv"
10
+ self.set_asset_type('contacts')
11
+
12
+ #""/data/contact/100002'
13
+ end
14
+
15
+ end
@@ -0,0 +1,15 @@
1
+
2
+ class GoodDataEloqua::Emails < GoodDataEloqua::Request
3
+
4
+ attr_accessor :session_csv
5
+
6
+ def initialize(config={})
7
+
8
+ @client = $client
9
+ @session_id ||= SecureRandom.hex+"_emails"
10
+ @session_csv = @session_id+".csv"
11
+ self.set_asset_type('emails')
12
+
13
+ end
14
+
15
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gooddata_eloqua
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Patrick McConlogue
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: eloqua_api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.11
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.11
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.7.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.7.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: aws-sdk
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.61.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.61.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: pmap
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.2
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.0.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: gooddata
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.6.12
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.6.12
83
+ description: Eloqua REST API to CSV
84
+ email: patrick.mcconlogue@gooddata.com
85
+ executables: []
86
+ extensions: []
87
+ extra_rdoc_files: []
88
+ files:
89
+ - lib/gooddata_eloqua.rb
90
+ - lib/gooddata_eloqua/client.rb
91
+ - lib/gooddata_eloqua/helpers/pool.rb
92
+ - lib/gooddata_eloqua/helpers/request.rb
93
+ - lib/gooddata_eloqua/models/campaigns.rb
94
+ - lib/gooddata_eloqua/models/contacts.rb
95
+ - lib/gooddata_eloqua/models/emails.rb
96
+ homepage: https://github.com/thnkr/connectors/tree/master/eloqua
97
+ licenses:
98
+ - MIT
99
+ metadata: {}
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 1.9.3
109
+ required_rubygems_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ requirements: []
115
+ rubyforge_project:
116
+ rubygems_version: 2.2.2
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Eloqua to CSV
120
+ test_files: []
121
+ has_rdoc: