gooddata_marketo 0.0.1-java

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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +131 -0
  4. data/README.md +207 -0
  5. data/bin/Gemfile +10 -0
  6. data/bin/auth.json +16 -0
  7. data/bin/main.rb +24 -0
  8. data/bin/process.rbx +541 -0
  9. data/examples/all_lead_changes.rb +119 -0
  10. data/examples/all_leads.rb +249 -0
  11. data/examples/lead_changes_to_ads.rb +63 -0
  12. data/gooddata_marketo.gemspec +25 -0
  13. data/lib/gooddata_marketo/adapters/rest.rb +287 -0
  14. data/lib/gooddata_marketo/client.rb +373 -0
  15. data/lib/gooddata_marketo/data/activity_types.rb +104 -0
  16. data/lib/gooddata_marketo/data/reserved_sql_keywords.rb +205 -0
  17. data/lib/gooddata_marketo/helpers/s3.rb +141 -0
  18. data/lib/gooddata_marketo/helpers/stringwizard.rb +32 -0
  19. data/lib/gooddata_marketo/helpers/table.rb +323 -0
  20. data/lib/gooddata_marketo/helpers/webdav.rb +118 -0
  21. data/lib/gooddata_marketo/loads.rb +235 -0
  22. data/lib/gooddata_marketo/models/campaigns.rb +57 -0
  23. data/lib/gooddata_marketo/models/channels.rb +30 -0
  24. data/lib/gooddata_marketo/models/child/activity.rb +104 -0
  25. data/lib/gooddata_marketo/models/child/criteria.rb +17 -0
  26. data/lib/gooddata_marketo/models/child/lead.rb +118 -0
  27. data/lib/gooddata_marketo/models/child/mobj.rb +68 -0
  28. data/lib/gooddata_marketo/models/etl.rb +75 -0
  29. data/lib/gooddata_marketo/models/leads.rb +493 -0
  30. data/lib/gooddata_marketo/models/load.rb +17 -0
  31. data/lib/gooddata_marketo/models/mobjects.rb +121 -0
  32. data/lib/gooddata_marketo/models/streams.rb +137 -0
  33. data/lib/gooddata_marketo/models/tags.rb +35 -0
  34. data/lib/gooddata_marketo/models/validate.rb +46 -0
  35. data/lib/gooddata_marketo.rb +24 -0
  36. data/process.rb +517 -0
  37. metadata +177 -0
data/process.rb ADDED
@@ -0,0 +1,517 @@
1
+ #!/usr/bin/ruby
2
+
3
+ ###################################################################
4
+ # #
5
+ # #
6
+ # GOODDATA MARKETO CONNECTOR #
7
+ # #
8
+ # Ruby process for download client data from Marketo. #
9
+ # https://github.com/gooddata/app_store/marketo_connector #
10
+ # #
11
+ # #
12
+ ###################################################################
13
+
14
+ require 'gooddata_marketo'
15
+
16
+
17
+ MARKETO_SOAP_USER = ''
18
+ MARKETO_SOAP_KEY = ''
19
+ MARKETO_REST_ID = ''
20
+ MARKETO_REST_SECRET = ''
21
+ MARKETO_SUBDOMAIN = ''
22
+ GOODDATA_USER = ''
23
+ GOODDATA_PASSWORD = ''
24
+ GOODDATA_PROJECT = ''
25
+ GOODDATA_ADS = ''
26
+ S3_PUBLIC_KEY = ''
27
+ S3_PRIVATE_KEY = ''
28
+ S3_BUCKET = 'marketo_connector'
29
+ MARKETO_API_LIMIT = 10000
30
+ LEAD_LIST_DUMP_CSV = 'marketo_leads_dump.csv'
31
+
32
+ @s3 = S3Helper.new :public_key => S3_PUBLIC_KEY,
33
+ :private_key => S3_PRIVATE_KEY,
34
+ :bucket => S3_BUCKET
35
+
36
+ @webdav = WebDAV.new(:user => GOODDATA_USER,
37
+ :pass => GOODDATA_PASSWORD,
38
+ :project => GOODDATA_PROJECT)
39
+
40
+ @dwh = GoodData::Datawarehouse.new(GOODDATA_USER,
41
+ GOODDATA_PASSWORD,
42
+ GOODDATA_ADS)
43
+
44
+ @marketo = GoodDataMarketo.connect(:user_id => MARKETO_SOAP_USER,
45
+ :encryption_key => MARKETO_SOAP_KEY,
46
+ :api_subdomain => MARKETO_SUBDOMAIN,
47
+ :webdav => @webdav)
48
+
49
+ GoodDataMarketo.logging = true
50
+
51
+ binding.pry
52
+
53
+ # Test services
54
+ # @marketo.test_rest
55
+ # @marketo.test_soap
56
+ # @s3.test
57
+ # @dwh.test
58
+ # @webdav.test
59
+
60
+
61
+ def run_load config = {}
62
+
63
+ index = config[:index] || 1
64
+ @increment = config[:increment] || (12*60*60)
65
+ @marketo = config[:marketo_client]
66
+ @ads_target_table_name = config[:ads_table]
67
+ @lead_dump_file = "get_load_chunk_#{index}"
68
+
69
+ if @s3.exists? 'queue.json'
70
+
71
+ @queue = JSON.parse(@s3.download('queue.json'))
72
+ # Cancel the load if the queue is empty and delete the object.
73
+ if @queue.empty?
74
+ puts 'WARNING: Empty queue array was extracted from S3. Using queue passed in method.' if GoodDataMarketo.logging
75
+ @s3.delete('queue.json')
76
+ @queue = config[:queue]
77
+
78
+ end
79
+
80
+ else
81
+ @queue = config[:queue]
82
+ end
83
+
84
+ raise "You must pass an array of job hashs :queue_array when using run_load AND define a :marketo_client." unless @queue.length > 0 && @marketo
85
+ raise ":ads_table param is required with using run_load." unless @ads_target_table_name
86
+
87
+
88
+
89
+ def determine_loads_state config = {}
90
+
91
+ loads = @marketo.loads(:user => GOODDATA_USER,
92
+ :pass => GOODDATA_PASSWORD,
93
+ :project => GOODDATA_PROJECT,
94
+ :marketo_client => @marketo)
95
+
96
+ if loads.available?
97
+
98
+ file = loads.available.first
99
+
100
+ load = loads.create :name => file
101
+
102
+ @job_name = file
103
+ @id = load.id
104
+ @ads_table = load.json[:ads_table]
105
+ # Run the load from local or remote.
106
+ load.execute
107
+ # Data from the job can now be accessed ARRAY load.storage
108
+ # load.storage
109
+
110
+ if !load.storage.empty?
111
+
112
+ # Join all of the columns from the sample to all other columns.
113
+ @columns_load_aggregate = ['sys_capture_date']
114
+ load.storage.each { |lead| @columns_load_aggregate = @columns_load_aggregate | lead.columns }
115
+ @columns_load_aggregate.map! { |column|
116
+ column.downcase.gsub('-','_')
117
+ }
118
+
119
+ # DEFAULTS: Use the correct ADS table.
120
+ if load.json[:method] == "get_multiple"
121
+ ads_target_table_name = 'marketo_leads'
122
+ elsif load.json[:method] = 'get_changes'
123
+ ads_target_table_name = 'marketo_changes'
124
+ else
125
+ ads_target_table_name = 'dump'
126
+ end
127
+
128
+ # Set up a new Table/Automatically loads current table if exists.
129
+ table = Table.new :client => @dwh, :name => @ads_table || ads_target_table_name, :columns => ['sys_capture_date']
130
+
131
+ if @columns_load_aggregate.length > 0
132
+ table.merge_columns :merge_with => @columns_load_aggregate
133
+ @csv = CSV.open("#{@id}.csv", 'wb')
134
+ else
135
+ @csv = CSV.open("#{@id}.csv", 'wb')
136
+ end
137
+
138
+ updated_columns = table.columns
139
+
140
+ if @columns_load_aggregate.length > 0
141
+ @csv << updated_columns.uniq
142
+ end
143
+
144
+ count = 0
145
+
146
+ ids_for_get_multiple_load = []
147
+
148
+ load.storage.each do |lead|
149
+
150
+ # Get any new lead or merge lead ids and queue them for a load with get multiple.
151
+ ids_for_get_multiple_load << lead.values['merge_id'] if lead.values['merge_id']
152
+ ids_for_get_multiple_load << lead.values['lead_id'] if lead.values['lead_id']
153
+
154
+ row_to_save_csv = []
155
+
156
+ row_with_columns = updated_columns.map { |column|
157
+ if lead.columns.include? column
158
+ { column => lead.values[column] }
159
+ elsif lead.columns.include? "#{column}_m" # Check for anything that was removed by SQL
160
+ { "#{column}_m" => lead.values["#{column}_m"] }
161
+ elsif column == 'sys_capture_date'
162
+ { 'sys_capture_date' => Time.now.to_s }
163
+ else
164
+ { column => nil }
165
+ end
166
+ }
167
+
168
+ row_with_columns.each { |item|
169
+ c = item.to_a.flatten
170
+ if c[1] == nil
171
+ row_to_save_csv << nil
172
+ else
173
+ row_to_save_csv << c[1]
174
+ end
175
+
176
+ }
177
+
178
+ count += 1
179
+ @csv << row_to_save_csv
180
+
181
+ end
182
+
183
+ # Prepare (flush) the CSV for upload.
184
+ @csv.flush
185
+
186
+ puts "#{Time.now} => ADS:LoadingCSV \"#{@id}.csv\"" if GoodDataMarketo.logging
187
+ table.import_csv("#{@id}.csv")
188
+
189
+ puts "#{Time.now} => CSV:Rows:#{count}"
190
+
191
+ puts "#{Time.now} => CSV:Merged&New:#{ids_for_get_multiple_load.length}"
192
+
193
+ save_ids_for_get_multiple ids_for_get_multiple_load, 'a'
194
+
195
+ File.delete("#{load.json[:name]}_load.json") if File.exists? ("#{load.json[:name]}_load.json")
196
+ #File.delete("#{@id}.csv") if File.exists? ("#{@id}.csv")
197
+
198
+ puts "#{Time.now} => ADS:TableComplete:#{@lead_dump_file}" if GoodDataMarketo.logging
199
+ puts "#{Time.now} => LastARGS:#{load.arguments}" if GoodDataMarketo.logging
200
+
201
+ end
202
+
203
+ case load.json[:method]
204
+
205
+ when 'get_changes'
206
+
207
+ # Increment the load by one day if it is time related.
208
+
209
+ oca = load.arguments[:oldest_created_at]
210
+ lca = load.arguments[:latest_created_at]
211
+
212
+ increment = Time.parse(lca) - Time.parse(oca)
213
+ total_time_range = Time.now - Time.parse(oca)
214
+
215
+ load.arguments[:oldest_created_at] = Time.parse(lca).to_s
216
+ load.arguments[:latest_created_at] = (Time.parse(lca) + increment).to_s
217
+
218
+ puts "#{Time.now} => (est.) API_CALLS until CURRENT TIME: #{(total_time_range/increment).round}" if GoodDataMarketo.logging
219
+
220
+ # If the latest time is later then today kill the load.
221
+
222
+ if Time.parse(load.arguments[:latest_created_at]) > Time.now
223
+
224
+ load.terminate
225
+
226
+ determine_loads_state
227
+
228
+ # Otherwise save the load and resume additional loads.
229
+ else
230
+
231
+ load.save
232
+
233
+ determine_loads_state
234
+
235
+ end
236
+
237
+ when 'get_multiple'
238
+
239
+ determine_loads_state
240
+
241
+ else
242
+
243
+ raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
244
+
245
+ end
246
+
247
+ else
248
+
249
+ load = @queue.pop
250
+
251
+ if @queue.length > 0
252
+ File.open('queue.json','w'){ |f| JSON.dump(@queue, f) }
253
+ @s3.upload('queue.json')
254
+ end
255
+
256
+ if load
257
+
258
+ loads.create load
259
+
260
+ determine_loads_state
261
+
262
+ else
263
+
264
+ @s3.delete('queue.json')
265
+ File.delete('queue.json') if File.exists?('queue.json')
266
+
267
+ end
268
+
269
+
270
+ end
271
+
272
+ end
273
+
274
+ # Run once, recursive until no loads are available.
275
+ determine_loads_state
276
+
277
+ end
278
+
279
+ #####################################
280
+ # #
281
+ # GET ALL LEADS INITIAL BEGINS HERE #
282
+ # #
283
+ #####################################
284
+ # Downloads all current lead ids with REST ID.
285
+ # Uses SOAP API to rotate through ids with get multiple.
286
+ # Runs once, boolean value set in initial_load_get_multiple at marketo_connector_config.json
287
+
288
+ def initial_load_get_multiple
289
+
290
+ @marketo.write_all_lead_ids_to_csv # Large bulk download to CSV of leads over REST API.
291
+
292
+ ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
293
+
294
+ puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
295
+
296
+ counter = 0
297
+
298
+ loop do
299
+
300
+ counter += 1
301
+
302
+ batch = ids.slice!(1..1000)
303
+
304
+ break if batch.length <= 0
305
+
306
+ get_multiple_leads_configuration = {
307
+ :name => "get_all_leads_chunk",
308
+ :type => 'leads',
309
+ :method => 'get_multiple',
310
+ :ads_table => 'marketo_leads',
311
+ :arguments => {
312
+ :ids => batch, # Notice the addition of the IDS box
313
+ :type => 'IDNUM'
314
+ }
315
+ }
316
+
317
+ puts "#{Time.now} => Batch:Downloader:Length:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
318
+
319
+ run_load :batch => batch,
320
+ :counter => counter,
321
+ :ads_table => 'marketo_leads',
322
+ :marketo_client => @marketo,
323
+ :queue => [get_multiple_leads_configuration]
324
+
325
+ save_ids_for_get_multiple ids, 'w'
326
+
327
+ end
328
+ end
329
+
330
+ def update_get_multiple_leads
331
+
332
+ file = File.open(LEAD_LIST_DUMP_CSV, 'w')
333
+ file.puts @s3.download(LEAD_LIST_DUMP_CSV)
334
+
335
+ ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
336
+
337
+ puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
338
+
339
+ counter = 0
340
+
341
+ loop do
342
+
343
+ counter += 1
344
+
345
+ batch = ids.slice!(1..1000)
346
+
347
+ break if batch.length <= 0
348
+
349
+ get_multiple_leads_configuration = {
350
+ :name => "get_all_leads_chunk",
351
+ :type => 'leads',
352
+ :method => 'get_multiple',
353
+ :ads_table => 'marketo_leads',
354
+ :arguments => {
355
+ :ids => batch, # Notice the addition of the IDS box
356
+ :type => 'IDNUM'
357
+ }
358
+ }
359
+
360
+ puts "#{Time.now} => Batch:Downloader:Length:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
361
+
362
+ run_load :batch => batch,
363
+ :counter => counter,
364
+ :ads_table => 'marketo_leads',
365
+ :marketo_client => @marketo,
366
+ :queue => [get_multiple_leads_configuration]
367
+
368
+ save_ids_for_get_multiple ids, 'w'
369
+
370
+ end
371
+ end
372
+
373
+ ########################################
374
+ # #
375
+ # GET LEAD CHANGES INITIAL BEGINS HERE #
376
+ # #
377
+ ########################################
378
+ # Starts January 1st 2000 and increments by the day until present day.
379
+ # All Activity Types included unless specified.
380
+ # Runs once, boolean value set in initial_load_get_changes at marketo_connector_config.json
381
+
382
+ def initial_load_get_changes
383
+
384
+ get_lead_changes_configuration = {
385
+ :name => 'get_lead_changes_chunk',
386
+ :type => 'leads',
387
+ :method => 'get_changes',
388
+ :ads_table => 'marketo_changes',
389
+ :arguments => {
390
+ # "oldest_created_at" and "latest_created_at" is the size of the increment it will to current time.
391
+ # :oldest_created_at => 'January 1st 2000',
392
+ # :latest_created_at => 'January 2nd 2000',
393
+ :oldest_created_at => 'January 1st 2015',
394
+ :latest_created_at => 'January 4th 2015',
395
+ :filters => []
396
+ }
397
+ }
398
+
399
+ # Create a new configuration object for each activity type.
400
+ get_lead_changes_configuration.freeze
401
+
402
+ queue = []
403
+
404
+ @marketo.activity_types.each { |type|
405
+
406
+ g = {
407
+ :filters => [type]
408
+ }
409
+
410
+ m = get_lead_changes_configuration.dup
411
+ c = m.dup
412
+ c[:arguments] = m[:arguments].merge(g)
413
+
414
+ queue << c
415
+
416
+ }
417
+
418
+ run_load :ads_table => get_lead_changes_configuration[:ads_table],
419
+ :queue => queue,
420
+ :marketo_client => @marketo,
421
+ :index => 1,
422
+ :counter => 1
423
+
424
+ puts "#{Time.now} => Updating initial load changes to true in connector configuration." if GoodDataMarketo.logging
425
+
426
+ @s3.set_config(:initial_load_get_changes => true)
427
+
428
+ end
429
+
430
+ ########################################
431
+ # #
432
+ # UPDATE LEAD CHANGES #
433
+ # #
434
+ ########################################
435
+ # Synchronizes last 12 hours from process execution.
436
+ # Runs continuously.
437
+
438
+ def update_lead_changes
439
+
440
+ # Changing activity types from the default set to just merged leads.
441
+ #@marketo.activity_types = ['Visit Webpage']
442
+ #@marketo.activity_types = ['New SFDC Opportunity','Remove from Opportunity','Add to Opportunity', 'Update Opportunity']
443
+
444
+ fourty_eight_hours_ago = (Time.now - (48*60*60)).to_s
445
+ twenty_four_hours_ago = (Time.now - (24*60*60)).to_s
446
+ twelve_hours_ago = (Time.now - (12*60*60)).to_s
447
+ six_hours_ago = (Time.now - (6*60*60)).to_s
448
+
449
+ get_lead_changes_configuration = {
450
+ :name => 'get_lead_changes_chunk',
451
+ :type => 'leads',
452
+ :method => 'get_changes',
453
+ :ads_table => 'marketo_changes',
454
+ :arguments => {
455
+ # "latest_created_at subtracted by "oldest_created_at" the size of the increment it will to current time.
456
+ :oldest_created_at => twelve_hours_ago,
457
+ :latest_created_at => six_hours_ago,
458
+ :filters => []
459
+ }
460
+ }
461
+
462
+ # Create a new configuration object for each activity type.
463
+ get_lead_changes_configuration.freeze
464
+
465
+ queue = []
466
+
467
+ @marketo.activity_types.each { |type|
468
+
469
+ g = {
470
+ :filters => [type]
471
+ }
472
+
473
+ m = get_lead_changes_configuration.dup
474
+ c = m.dup
475
+ c[:arguments] = m[:arguments].merge(g)
476
+
477
+ queue << c
478
+
479
+ }
480
+
481
+ run_load :ads_table => get_lead_changes_configuration[:ads_table],
482
+ :queue => queue,
483
+ :marketo_client => @marketo,
484
+ :increment => (24*60*60),
485
+ #:increment => (12*60*60), # Every twelve hours.
486
+ :counter => 1
487
+
488
+ end
489
+
490
+ def save_ids_for_get_multiple ids, write_type
491
+ csv = CSV.open(LEAD_LIST_DUMP_CSV, write_type)
492
+ ids.each { |row| csv << [row] }
493
+ csv.flush
494
+ @s3.upload(LEAD_LIST_DUMP_CSV)
495
+ end
496
+
497
+ # Download the configuration file from S3. If there is not one, one will be created.
498
+ config = @s3.get_config
499
+
500
+ if !config[:initial_load_get_multiple]
501
+
502
+ initial_load_get_multiple
503
+
504
+ # elsif !config[:initial_load_get_changes]
505
+ #
506
+ # initial_load_get_changes
507
+
508
+ else
509
+
510
+ update_lead_changes
511
+ # Once the most recent changes downloaded, create and save a load for update_get_multiple_leads
512
+ # update_get_multiple_leads
513
+
514
+ end
515
+
516
+
517
+ binding.pry
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gooddata_marketo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: java
6
+ authors:
7
+ - Patrick McConlogue
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 1.61.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 1.61.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rubyntlm
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.3.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.3.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: rest-client
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.7.2
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.7.2
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: :development
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: savon
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 2.8.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 2.8.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: gooddata
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 0.6.11
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 0.6.11
97
+ - !ruby/object:Gem::Dependency
98
+ name: gooddata_datawarehouse
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 0.0.5
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 0.0.5
111
+ description: A gem.
112
+ email: patrick.mcconlogue@gooddata.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - Gemfile
118
+ - Gemfile.lock
119
+ - README.md
120
+ - bin/Gemfile
121
+ - bin/auth.json
122
+ - bin/main.rb
123
+ - bin/process.rbx
124
+ - examples/all_lead_changes.rb
125
+ - examples/all_leads.rb
126
+ - examples/lead_changes_to_ads.rb
127
+ - gooddata_marketo.gemspec
128
+ - lib/gooddata_marketo.rb
129
+ - lib/gooddata_marketo/adapters/rest.rb
130
+ - lib/gooddata_marketo/client.rb
131
+ - lib/gooddata_marketo/data/activity_types.rb
132
+ - lib/gooddata_marketo/data/reserved_sql_keywords.rb
133
+ - lib/gooddata_marketo/helpers/s3.rb
134
+ - lib/gooddata_marketo/helpers/stringwizard.rb
135
+ - lib/gooddata_marketo/helpers/table.rb
136
+ - lib/gooddata_marketo/helpers/webdav.rb
137
+ - lib/gooddata_marketo/loads.rb
138
+ - lib/gooddata_marketo/models/campaigns.rb
139
+ - lib/gooddata_marketo/models/channels.rb
140
+ - lib/gooddata_marketo/models/child/activity.rb
141
+ - lib/gooddata_marketo/models/child/criteria.rb
142
+ - lib/gooddata_marketo/models/child/lead.rb
143
+ - lib/gooddata_marketo/models/child/mobj.rb
144
+ - lib/gooddata_marketo/models/etl.rb
145
+ - lib/gooddata_marketo/models/leads.rb
146
+ - lib/gooddata_marketo/models/load.rb
147
+ - lib/gooddata_marketo/models/mobjects.rb
148
+ - lib/gooddata_marketo/models/streams.rb
149
+ - lib/gooddata_marketo/models/tags.rb
150
+ - lib/gooddata_marketo/models/validate.rb
151
+ - process.rb
152
+ homepage: https://github.com/thnkr/connectors/tree/master/marketo
153
+ licenses:
154
+ - MIT
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 1.9.3
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.2.2
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Marketo SOAP/REST wrapper to CSV/GoodData ADS
176
+ test_files: []
177
+ has_rdoc: