gooddata_eloqua 0.0.1

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 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: