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/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
+