gooddata_marketo 0.0.1-java

Sign up to get free protection for your applications and to get access to all the features.
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: