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/bin/process.rbx ADDED
@@ -0,0 +1,541 @@
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
+ # Load the authorization keys.
17
+ auth = JSON.parse(IO.read('auth.json'), :symbolize_names => true)
18
+
19
+ MARKETO_SOAP_USER = auth[:MARKETO_SOAP_USER]
20
+ MARKETO_SOAP_KEY = auth[:MARKETO_SOAP_KEY]
21
+ MARKETO_REST_ID = auth[:MARKETO_REST_ID]
22
+ MARKETO_REST_SECRET = auth[:MARKETO_REST_SECRET]
23
+ MARKETO_SUBDOMAIN = auth[:MARKETO_SUBDOMAIN]
24
+ MARKETO_API_LIMIT = auth[:MARKETO_API_LIMIT]
25
+ LEAD_LIST_DUMP_CSV = auth[:LEAD_LIST_DUMP_CSV]
26
+ GOODDATA_USER = auth[:GOODDATA_USER]
27
+ GOODDATA_PASSWORD = auth[:GOODDATA_PASSWORD]
28
+ GOODDATA_PROJECT = auth[:GOODDATA_PROJECT]
29
+ GOODDATA_ADS = auth[:GOODDATA_ADS]
30
+
31
+ S3_PUBLIC_KEY = auth[:S3_PUBLIC_KEY]
32
+ S3_PRIVATE_KEY = auth[:S3_PRIVATE_KEY]
33
+ S3_BUCKET = auth[:S3_BUCKET]
34
+
35
+ # No need to configure beyond this point. #
36
+ @s3 = S3Helper.new :public_key => S3_PUBLIC_KEY,
37
+ :private_key => S3_PRIVATE_KEY,
38
+ :bucket => S3_BUCKET
39
+
40
+ @webdav = WebDAV.new(:user => GOODDATA_USER,
41
+ :pass => GOODDATA_PASSWORD,
42
+ :project => GOODDATA_PROJECT)
43
+
44
+ @dwh = GoodData::Datawarehouse.new(GOODDATA_USER,
45
+ GOODDATA_PASSWORD,
46
+ GOODDATA_ADS)
47
+
48
+ @marketo = GoodDataMarketo.connect(:user_id => MARKETO_SOAP_USER,
49
+ :encryption_key => MARKETO_SOAP_KEY,
50
+ :api_subdomain => MARKETO_SUBDOMAIN,
51
+ :webdav => @webdav)
52
+
53
+ GoodDataMarketo.logging = true
54
+
55
+ # Test services
56
+ # @marketo.test_rest
57
+ # @marketo.test_soap
58
+ # @s3.test
59
+ # @dwh.test
60
+ # @webdav.test
61
+
62
+ def run_load config = {}
63
+
64
+ index = config[:index] || 1
65
+ @increment = config[:increment] || (12*60*60)
66
+ @marketo = config[:marketo_client]
67
+ @ads_target_table_name = config[:ads_table]
68
+ @lead_dump_file = "get_load_chunk_#{index}"
69
+
70
+ if @s3.exists? 'queue.json'
71
+
72
+ @queue = JSON.parse(@s3.download('queue.json'))
73
+ # Cancel the load if the queue is empty and delete the object.
74
+ if @queue.empty?
75
+ puts 'WARNING: Empty queue array was extracted from S3. Using queue passed in method.' if GoodDataMarketo.logging
76
+ @s3.delete('queue.json')
77
+ @queue = config[:queue]
78
+
79
+ end
80
+
81
+ else
82
+ @queue = config[:queue]
83
+ end
84
+
85
+ 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
86
+ raise ":ads_table param is required with using run_load." unless @ads_target_table_name
87
+
88
+ loop do
89
+
90
+ loads = @marketo.loads(:user => GOODDATA_USER,
91
+ :pass => GOODDATA_PASSWORD,
92
+ :project => GOODDATA_PROJECT,
93
+ :marketo_client => @marketo)
94
+
95
+ if loads.available?
96
+
97
+ file = loads.available.first
98
+
99
+ load = loads.create :name => file
100
+
101
+ @job_name = file
102
+ @id = load.id
103
+ @ads_table = load.json[:ads_table]
104
+ # Run the load from local or remote.
105
+ load.execute
106
+ # Data from the job can now be accessed ARRAY load.storage
107
+ # load.storage
108
+
109
+ if !load.storage.empty?
110
+
111
+ # Join all of the columns from the sample to all other columns.
112
+
113
+ @columns_load_aggregate = ['sys_capture_date']
114
+ load.storage.each { |raw_json_lead|
115
+
116
+ lead = GoodDataMarketo::Activity.new raw_json_lead if load.json[:method] == 'get_changes'
117
+ lead = GoodDataMarketo::Lead.new raw_json_lead if load.json[:method] == 'get_multiple'
118
+
119
+ print "\r#{Time.now} => Resolving columns: #{lead.id}\s" if GoodDataMarketo.logging
120
+
121
+ @columns_load_aggregate = @columns_load_aggregate | lead.columns
122
+ }
123
+ @columns_load_aggregate.map! { |column|
124
+ column.downcase.gsub('-','_')
125
+ }
126
+
127
+ # DEFAULTS: Use the correct ADS table.
128
+ if load.json[:method] == "get_multiple"
129
+ ads_target_table_name = 'marketo_leads'
130
+ elsif load.json[:method] = 'get_changes'
131
+ ads_target_table_name = 'marketo_changes'
132
+ else
133
+ ads_target_table_name = 'dump'
134
+ end
135
+
136
+ # Set up a new Table/Automatically loads current table if exists.
137
+
138
+ table = Table.new :client => @dwh, :name => @ads_table || ads_target_table_name, :columns => ['id','sys_capture_date']
139
+
140
+ if @columns_load_aggregate.length > 0
141
+ table.merge_columns :merge_with => @columns_load_aggregate
142
+
143
+ end
144
+ @csv = CSV.open("#{@id}.csv", 'w')
145
+
146
+ updated_columns = table.columns
147
+
148
+ if @columns_load_aggregate.length > 0
149
+ @csv << updated_columns
150
+ end
151
+
152
+ count = 0
153
+
154
+ ids_for_get_multiple_load = []
155
+
156
+ puts "#{Time.now} => Building objects from stream cache." if GoodDataMarketo.logging
157
+
158
+ total_leads = load.storage.length
159
+ total_leads_index = 0
160
+ load.storage.pmap do |lead|
161
+
162
+ lead = GoodDataMarketo::Activity.new lead if load.json[:method] == 'get_changes'
163
+ lead = GoodDataMarketo::Lead.new lead if load.json[:method] == 'get_multiple'
164
+
165
+ total_leads_index += 1
166
+ percentage = ((100*total_leads_index.to_f)/total_leads.to_f).round(1)
167
+ print "\r#{Time.now} => Transforming #{lead.id} #{percentage}%\s" if GoodDataMarketo.logging
168
+
169
+ # Get any new lead or merge lead ids and queue them for a load with get multiple.
170
+ ids_for_get_multiple_load << lead.values['merge_id'] if lead.values['merge_id']
171
+ ids_for_get_multiple_load << lead.values['lead_id'] if lead.values['lead_id']
172
+
173
+ row_to_save_csv = []
174
+
175
+ row_with_columns = updated_columns.map { |column|
176
+ if lead.columns.include? column
177
+ { column => lead.values[column] }
178
+ elsif lead.columns.include? "#{column}_m" # Check for anything that was removed by SQL
179
+ { "#{column}_m" => lead.values["#{column}_m"] }
180
+ elsif column == 'sys_capture_date'
181
+ { 'sys_capture_date' => Time.now.to_s }
182
+ else
183
+ { column => nil }
184
+ end
185
+ }
186
+
187
+ row_with_columns.each { |item|
188
+ c = item.to_a.flatten
189
+ if c[1] == nil
190
+ row_to_save_csv << nil
191
+ else
192
+ row_to_save_csv << c[1]
193
+ end
194
+
195
+ }
196
+
197
+ count += 1
198
+ @csv << row_to_save_csv
199
+
200
+ end
201
+
202
+ # Prepare (flush) the CSV for upload.
203
+ @csv.flush
204
+
205
+ table.import_csv("#{@id}.csv")
206
+
207
+ puts "#{Time.now} => #{@dwh.execute_select("SELECT id FROM #{@ads_table}").length} rows in ADS." if GoodDataMarketo.logging
208
+ puts "#{Time.now} => Rows extracted from CSV: #{count}" if GoodDataMarketo.logging
209
+ puts "#{Time.now} => New and merged ids queued: #{ids_for_get_multiple_load.length}" if GoodDataMarketo.logging
210
+
211
+ save_ids_for_get_multiple ids_for_get_multiple_load, 'a'
212
+
213
+ File.delete("#{load.json[:name]}_load.json") if File.exists? ("#{load.json[:name]}_load.json")
214
+ File.delete("#{@id}.csv") if File.exists? ("#{@id}.csv")
215
+
216
+ puts "#{Time.now} => Ads import of \"#{@lead_dump_file}\" complete." if GoodDataMarketo.logging
217
+ puts "#{Time.now} => Arguments: #{load.arguments}" if GoodDataMarketo.logging
218
+
219
+ end
220
+
221
+ case load.json[:method]
222
+
223
+ when 'get_changes'
224
+
225
+ # Increment the load by one day if it is time related.
226
+
227
+ oca = load.arguments[:oldest_created_at]
228
+ lca = load.arguments[:latest_created_at]
229
+
230
+ increment = Time.parse(lca) - Time.parse(oca)
231
+ total_time_range = Time.now - Time.parse(oca)
232
+
233
+ load.arguments[:oldest_created_at] = Time.parse(lca).to_s
234
+ load.arguments[:latest_created_at] = (Time.parse(lca) + increment).to_s
235
+
236
+ puts "#{Time.now} => API calls until current time: #{(total_time_range/increment).round}" if GoodDataMarketo.logging
237
+
238
+ # If the latest time is later then today kill the load.
239
+
240
+ if Time.parse(load.arguments[:latest_created_at]) > Time.now
241
+
242
+
243
+ load.terminate
244
+
245
+ next
246
+
247
+ # Otherwise save the load and resume additional loads.
248
+ else
249
+
250
+ load.save
251
+
252
+ next
253
+
254
+ end
255
+
256
+ when 'get_multiple'
257
+
258
+ determine_loads_state
259
+
260
+ else
261
+
262
+ raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
263
+
264
+ break
265
+
266
+ end
267
+
268
+ else
269
+
270
+ load = @queue.pop
271
+
272
+ puts "#{Time.now} => #{@queue.length} loads remaining."
273
+
274
+ if @queue.length > 0
275
+ File.open('queue.json','w'){ |f| JSON.dump(@queue, f) }
276
+ @s3.upload('queue.json')
277
+ end
278
+
279
+ if load
280
+
281
+ loads.create load
282
+
283
+ next
284
+
285
+ else
286
+
287
+ @s3.delete('queue.json')
288
+ File.delete('queue.json') if File.exists?('queue.json')
289
+
290
+ break
291
+
292
+ end
293
+
294
+
295
+ end
296
+
297
+
298
+ end
299
+
300
+ end
301
+
302
+ #####################################
303
+ # #
304
+ # INITIAL GET ALL MULTIPLE LEADS #
305
+ # #
306
+ #####################################
307
+ # Downloads all current lead ids with REST ID.
308
+ # Uses SOAP API to rotate through ids with get multiple.
309
+ # Runs once, boolean value set in initial_load_get_multiple at marketo_connector_config.json
310
+
311
+ def initial_load_get_multiple
312
+
313
+ @marketo.write_all_lead_ids_to_csv # Large bulk download to CSV of leads over REST API.
314
+
315
+ ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
316
+
317
+ puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
318
+
319
+ counter = 0
320
+
321
+ loop do
322
+
323
+ counter += 1
324
+
325
+ batch = ids.slice!(1..1000)
326
+
327
+ break if batch.length <= 0
328
+
329
+ get_multiple_leads_configuration = {
330
+ :name => "get_all_leads_chunk",
331
+ :type => 'leads',
332
+ :method => 'get_multiple',
333
+ :ads_table => 'marketo_leads',
334
+ :arguments => {
335
+ :ids => batch, # Notice the addition of the IDS box
336
+ :type => 'IDNUM'
337
+ }
338
+ }
339
+
340
+ puts "#{Time.now} => Id count in batch:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
341
+
342
+ run_load :batch => batch,
343
+ :counter => counter,
344
+ :ads_table => 'marketo_leads',
345
+ :marketo_client => @marketo,
346
+ :queue => [get_multiple_leads_configuration]
347
+
348
+ save_ids_for_get_multiple ids, 'w'
349
+
350
+ end
351
+ end
352
+
353
+ ########################################
354
+ # #
355
+ # INITIAL GET ALL LEAD CHANGES #
356
+ # #
357
+ ########################################
358
+ # Starts January 1st 2000 and increments by the day until present day.
359
+ # All Activity Types included unless specified.
360
+ # Runs once, boolean value set in initial_load_get_changes at marketo_connector_config.json
361
+
362
+ def initial_load_get_changes
363
+
364
+ get_lead_changes_configuration = {
365
+ :name => 'get_lead_changes_chunk',
366
+ :type => 'leads',
367
+ :method => 'get_changes',
368
+ :ads_table => 'marketo_changes',
369
+ :arguments => {
370
+ # "oldest_created_at" and "latest_created_at" is the size of the increment it will to current time.
371
+ :oldest_created_at => 'January 1st 2004',
372
+ :latest_created_at => 'January 2nd 2004',
373
+ :filters => []
374
+ }
375
+ }
376
+
377
+ # Create a new configuration object for each activity type.
378
+ get_lead_changes_configuration.freeze
379
+
380
+ queue = []
381
+
382
+ @marketo.activity_types.each { |type|
383
+
384
+ g = {
385
+ :filters => [type]
386
+ }
387
+
388
+ m = get_lead_changes_configuration.dup
389
+ c = m.dup
390
+ c[:arguments] = m[:arguments].merge(g)
391
+
392
+ queue << c
393
+
394
+ }
395
+
396
+ run_load :ads_table => get_lead_changes_configuration[:ads_table],
397
+ :queue => queue,
398
+ :marketo_client => @marketo,
399
+ :index => 1,
400
+ :counter => 1
401
+
402
+ puts "#{Time.now} => Updating initial load changes to true in connector configuration." if GoodDataMarketo.logging
403
+
404
+ @s3.set_config(:initial_load_get_changes => true)
405
+
406
+ end
407
+
408
+ ########################################
409
+ # #
410
+ # SYNC MULTIPLE LEADS #
411
+ # #
412
+ ########################################
413
+
414
+ def update_get_multiple_leads
415
+
416
+ file = File.open(LEAD_LIST_DUMP_CSV, 'w')
417
+ file.puts @s3.download(LEAD_LIST_DUMP_CSV)
418
+
419
+ ids = CSV.open(LEAD_LIST_DUMP_CSV).map { |m| m[0] }
420
+
421
+ puts "#{Time.now} => #{ids.length} imported from local CSV." if GoodDataMarketo.logging
422
+
423
+ counter = 0
424
+
425
+ loop do
426
+
427
+ counter += 1
428
+
429
+ batch = ids.slice!(1..1000)
430
+
431
+ break if batch.length <= 0
432
+
433
+ get_multiple_leads_configuration = {
434
+ :name => "get_all_leads_chunk",
435
+ :type => 'leads',
436
+ :method => 'get_multiple',
437
+ :ads_table => 'marketo_leads',
438
+ :arguments => {
439
+ :ids => batch, # Notice the addition of the IDS box
440
+ :type => 'IDNUM'
441
+ }
442
+ }
443
+
444
+ puts "#{Time.now} => Id count in batch:#{batch.length} (Req:#{counter})" if GoodDataMarketo.logging
445
+
446
+ run_load :batch => batch,
447
+ :counter => counter,
448
+ :ads_table => 'marketo_leads',
449
+ :marketo_client => @marketo,
450
+ :queue => [get_multiple_leads_configuration]
451
+
452
+ save_ids_for_get_multiple ids, 'w'
453
+
454
+ end
455
+ end
456
+
457
+ ########################################
458
+ # #
459
+ # SYNC LEAD CHANGES #
460
+ # #
461
+ ########################################
462
+ # Synchronizes last 12 hours from process execution.
463
+ # Runs continuously.
464
+
465
+ def update_lead_changes
466
+
467
+ # Changing activity types from the default set to just Visit Webpage type.
468
+ #@marketo.activity_types = ['Visit Webpage']
469
+ #@marketo.activity_types = ['New SFDC Opportunity','Remove from Opportunity','Add to Opportunity', 'Update Opportunity']
470
+
471
+ fourty_eight_hours_ago = (Time.now - (48*60*60)).to_s
472
+ twenty_four_hours_ago = (Time.now - (24*60*60)).to_s
473
+ twelve_hours_ago = (Time.now - (12*60*60)).to_s
474
+ six_hours_ago = (Time.now - (6*60*60)).to_s
475
+
476
+ get_lead_changes_configuration = {
477
+ :name => 'get_lead_changes_chunk',
478
+ :type => 'leads',
479
+ :method => 'get_changes',
480
+ :ads_table => 'marketo_changes_date',
481
+ :arguments => {
482
+ # "oldest_created_at" and "latest_created_at" is the size of the increment it will to current time.
483
+ :oldest_created_at => twelve_hours_ago,
484
+ :latest_created_at => six_hours_ago,
485
+ :filters => []
486
+ }
487
+ }
488
+
489
+ # Create a new configuration object for each activity type.
490
+ get_lead_changes_configuration.freeze
491
+
492
+ queue = []
493
+
494
+ @marketo.activity_types.each { |type|
495
+
496
+ g = {
497
+ :filters => [type]
498
+ }
499
+
500
+ m = get_lead_changes_configuration.dup
501
+ c = m.dup
502
+ c[:arguments] = m[:arguments].merge(g)
503
+
504
+ queue << c
505
+
506
+ }
507
+
508
+ run_load :ads_table => get_lead_changes_configuration[:ads_table],
509
+ :queue => queue,
510
+ :marketo_client => @marketo,
511
+ :increment => (24*60*60),
512
+ :counter => 1
513
+
514
+ end
515
+
516
+ def save_ids_for_get_multiple ids, write_type
517
+ csv = CSV.open(LEAD_LIST_DUMP_CSV, write_type)
518
+ ids.each { |row| csv << [row] }
519
+ csv.flush
520
+ @s3.upload(LEAD_LIST_DUMP_CSV)
521
+ end
522
+
523
+ # Download the configuration file from S3. If there is not one, one will be created.
524
+ config = @s3.get_config
525
+
526
+ if !config[:initial_load_get_multiple]
527
+
528
+ initial_load_get_multiple
529
+
530
+ elsif !config[:initial_load_get_changes]
531
+
532
+ initial_load_get_changes
533
+
534
+ else
535
+
536
+ update_lead_changes
537
+
538
+ #Once the most recent changes downloaded, create and save a load for update_get_multiple_leads
539
+ update_get_multiple_leads
540
+
541
+ end
@@ -0,0 +1,119 @@
1
+ require 'gooddata_marketo'
2
+
3
+ MARKETO_USER = ''
4
+ MARKETO_KEY = ''
5
+ MARKETO_SUBDOMAIN = ''
6
+
7
+ GOODDATA_USER = ''
8
+ GOODDATA_PASSWORD = ''
9
+ GOODDATA_PROJECT = ''
10
+
11
+ @marketo = GoodDataMarketo.connect(:user_id => MARKETO_USER, :encryption_key => MARKETO_KEY, :api_subdomain => MARKETO_SUBDOMAIN)
12
+
13
+ # The specific parameters used in the method.
14
+
15
+ #################
16
+ # #
17
+ # CONFIGURATION #
18
+ # #
19
+ #################
20
+
21
+ get_lead_changes_from_march = {
22
+ :name => 'get_lead_changes_from_march',
23
+ :type => 'leads',
24
+ :method => 'get_changes',
25
+ :arguments => {
26
+ :oldest_created_at => 'March 26th 2014',
27
+ :latest_created_at => 'March 27th 2014',
28
+ :filters => ['Merge Leads']
29
+ }
30
+ }
31
+
32
+ get_multiple_from_january = {
33
+ :name => 'get_all_leads_january',
34
+ :type => 'leads',
35
+ :method => 'get_multiple',
36
+ :arguments => {
37
+ :ids => ['23849090','23849091'], # Notice the addition of the IDS box
38
+ :type => 'IDNUM'
39
+ }
40
+ }
41
+
42
+ @queue = [get_lead_changes_from_march, get_multiple_from_january]
43
+
44
+ ###################################
45
+ # #
46
+ # DO NOT EDIT BELOW: LOAD MANAGER #
47
+ # #
48
+ ###################################
49
+
50
+
51
+ def determine_loads_state
52
+
53
+ loads = @marketo.loads(:user => GOODDATA_USER,
54
+ :pass => GOODDATA_PASSWORD,
55
+ :project => GOODDATA_PROJECT,
56
+ :marketo_client => @marketo)
57
+
58
+ if loads.available?
59
+
60
+ file = loads.available.first
61
+ load = loads.create :name => file
62
+
63
+ load.execute
64
+
65
+ # Data from the job can now be accessed ARRAY load.storage
66
+ # load.storage
67
+
68
+ # Increment the load by one day if it is time related.
69
+
70
+ case load.json[:method]
71
+
72
+ when 'get_changes'
73
+
74
+ one_day = (24*60*60)
75
+ oca = load.arguments[:oldest_created_at]
76
+ lca = load.arguments[:latest_created_at]
77
+
78
+ load.arguments[:oldest_created_at] = (Time.parse(oca) + one_day).to_s
79
+ load.arguments[:latest_created_at] = (Time.parse(lca) + one_day).to_s
80
+
81
+ # If the latest time is later then today kill the load.
82
+ if Time.parse(lca) > Time.now
83
+
84
+ load.terminate
85
+
86
+ determine_loads_state
87
+
88
+ # Otherwise save the load and resume additional loads.
89
+ else
90
+
91
+ load.save
92
+
93
+ determine_loads_state
94
+
95
+ end
96
+
97
+ when 'get_multiple'
98
+
99
+ determine_loads_state
100
+
101
+ else
102
+ raise 'Unable to determine lead type ("get_multiple"/"get_changes")!'
103
+
104
+ end
105
+
106
+ else
107
+
108
+ load = @queue.pop
109
+ loads.create load
110
+
111
+ determine_loads_state
112
+
113
+ end
114
+
115
+ end
116
+
117
+ # Run once, recursive until no loads are available.
118
+ determine_loads_state
119
+