rest-ftp-daemon 0.242.2 → 0.242.3
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +1 -1
- data/config.ru +2 -2
- data/lib/rest-ftp-daemon/api/job_presenter.rb +1 -1
- data/lib/rest-ftp-daemon/api/root.rb +32 -0
- data/lib/rest-ftp-daemon/constants.rb +1 -1
- data/lib/rest-ftp-daemon/job.rb +71 -53
- data/lib/rest-ftp-daemon/worker_job.rb +1 -1
- data/rest-ftp-daemon.gemspec +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ecbe20206a3af518da510a31113cf02b3e198cf
|
|
4
|
+
data.tar.gz: bcae2929dc73d34920c7730a04c4c51836e58f17
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: da5f0d7ecde70351eea2a3857b3b0726953b3a1134b5023076b86ecadd5067859fa611bcec67613e0544f13bc9da8f561d722ecb6813aa855c01e0fcf084b6eb
|
|
7
|
+
data.tar.gz: ebc98fb0f9d944678cafa24253817f6e6d9669891356fd63037d5ba4bfb8682c18c49a213278ab624a9403ac7cafda746aea87fe391f59ae417a98f530febeef
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -136,7 +136,7 @@ Those tokens will be expanded when the job is run:
|
|
|
136
136
|
|
|
137
137
|
```
|
|
138
138
|
curl -H "Content-Type: application/json" -X POST -D /dev/stdout -d \
|
|
139
|
-
'{"source":"~/file.dmg","priority":"3",
|
|
139
|
+
'{"source":"~/file.dmg","priority":"3","target":"ftp://anonymous@localhost/incoming/dest4.dmg","notify":"http://requestb.in/1321axg1"}' "http://localhost:3000/jobs"
|
|
140
140
|
```
|
|
141
141
|
|
|
142
142
|
|
data/config.ru
CHANGED
|
@@ -29,8 +29,8 @@ unless Settings.namespace == "production"
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
# Set up encodings
|
|
32
|
-
Encoding.default_internal = "utf-8"
|
|
33
|
-
Encoding.default_external = "utf-8"
|
|
32
|
+
# Encoding.default_internal = "utf-8"
|
|
33
|
+
# Encoding.default_external = "utf-8"
|
|
34
34
|
|
|
35
35
|
# Launch the main daemon
|
|
36
36
|
run RestFtpDaemon::API::Root
|
|
@@ -14,6 +14,7 @@ module RestFtpDaemon
|
|
|
14
14
|
do_not_route_options!
|
|
15
15
|
|
|
16
16
|
format :json
|
|
17
|
+
content_type :json, 'application/json; charset=utf-8'
|
|
17
18
|
|
|
18
19
|
mount RestFtpDaemon::API::Jobs => "/jobs"
|
|
19
20
|
mount RestFtpDaemon::API::Dashbaord => "/"
|
|
@@ -87,6 +88,37 @@ module RestFtpDaemon
|
|
|
87
88
|
end
|
|
88
89
|
|
|
89
90
|
|
|
91
|
+
desc "List all Jobs params encodings"
|
|
92
|
+
get "/encodings" do
|
|
93
|
+
# Get jobs to display
|
|
94
|
+
encodings = {}
|
|
95
|
+
jobs = $queue.jobs
|
|
96
|
+
|
|
97
|
+
jobs.each do |job|
|
|
98
|
+
# here = out[job.id] = {}
|
|
99
|
+
me = encodings[job.id] = {}
|
|
100
|
+
|
|
101
|
+
me[:error] = job.error.encoding.to_s unless job.error.nil?
|
|
102
|
+
me[:status] = job.status.encoding.to_s unless job.status.nil?
|
|
103
|
+
|
|
104
|
+
Job::FIELDS.each do |name|
|
|
105
|
+
value = job.send(name)
|
|
106
|
+
me[name] = value.encoding.to_s if value.is_a? String
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
job.infos.each do |name, value|
|
|
110
|
+
me["infos_#{name}"] = value.encoding.to_s if value.is_a? String
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# # Computed fields
|
|
114
|
+
# expose :age
|
|
115
|
+
# expose :exectime
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
encodings
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
90
122
|
### RELOAD CONFIG
|
|
91
123
|
|
|
92
124
|
desc "Reload daemon config"
|
data/lib/rest-ftp-daemon/job.rb
CHANGED
|
@@ -25,7 +25,7 @@ module RestFtpDaemon
|
|
|
25
25
|
attr_reader :started_at
|
|
26
26
|
attr_reader :finished_at
|
|
27
27
|
|
|
28
|
-
attr_reader :
|
|
28
|
+
attr_reader :infos
|
|
29
29
|
|
|
30
30
|
FIELDS.each do |name|
|
|
31
31
|
attr_reader name
|
|
@@ -37,7 +37,7 @@ module RestFtpDaemon
|
|
|
37
37
|
|
|
38
38
|
# Init context
|
|
39
39
|
@id = job_id.to_s
|
|
40
|
-
@
|
|
40
|
+
@infos = {}
|
|
41
41
|
@updated_at = nil
|
|
42
42
|
@started_at = nil
|
|
43
43
|
@finished_at = nil
|
|
@@ -81,7 +81,7 @@ module RestFtpDaemon
|
|
|
81
81
|
|
|
82
82
|
# Prepare job
|
|
83
83
|
begin
|
|
84
|
-
|
|
84
|
+
set_status :prepare
|
|
85
85
|
prepare
|
|
86
86
|
|
|
87
87
|
rescue RestFtpDaemon::JobMissingAttribute => exception
|
|
@@ -104,14 +104,14 @@ module RestFtpDaemon
|
|
|
104
104
|
|
|
105
105
|
else
|
|
106
106
|
# Prepare done !
|
|
107
|
-
|
|
107
|
+
set_status JOB_STATUS_PREPARED
|
|
108
108
|
log_info "Job.process notify [started]"
|
|
109
109
|
client_notify :started
|
|
110
110
|
end
|
|
111
111
|
|
|
112
112
|
# Process job
|
|
113
113
|
begin
|
|
114
|
-
|
|
114
|
+
set_status :starting
|
|
115
115
|
transfer
|
|
116
116
|
|
|
117
117
|
rescue SocketError => exception
|
|
@@ -182,7 +182,7 @@ module RestFtpDaemon
|
|
|
182
182
|
|
|
183
183
|
else
|
|
184
184
|
# All done !
|
|
185
|
-
|
|
185
|
+
set_status JOB_STATUS_FINISHED
|
|
186
186
|
log_info "Job.process notify [ended]"
|
|
187
187
|
client_notify :ended
|
|
188
188
|
end
|
|
@@ -190,8 +190,8 @@ module RestFtpDaemon
|
|
|
190
190
|
|
|
191
191
|
def get attribute
|
|
192
192
|
@mutex.synchronize do
|
|
193
|
-
@
|
|
194
|
-
@
|
|
193
|
+
@infos || {}
|
|
194
|
+
@infos[attribute]
|
|
195
195
|
end
|
|
196
196
|
end
|
|
197
197
|
|
|
@@ -210,7 +210,7 @@ module RestFtpDaemon
|
|
|
210
210
|
|
|
211
211
|
def set_queued
|
|
212
212
|
# Update job status
|
|
213
|
-
|
|
213
|
+
set_status JOB_STATUS_QUEUED
|
|
214
214
|
end
|
|
215
215
|
|
|
216
216
|
def oops_after_crash exception
|
|
@@ -228,14 +228,6 @@ module RestFtpDaemon
|
|
|
228
228
|
|
|
229
229
|
protected
|
|
230
230
|
|
|
231
|
-
def set attribute, value
|
|
232
|
-
@mutex.synchronize do
|
|
233
|
-
@params || {}
|
|
234
|
-
@updated_at = Time.now
|
|
235
|
-
@params[attribute] = value
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
231
|
def expand_path path
|
|
240
232
|
File.expand_path replace_tokens(path)
|
|
241
233
|
end
|
|
@@ -272,7 +264,7 @@ module RestFtpDaemon
|
|
|
272
264
|
|
|
273
265
|
def prepare
|
|
274
266
|
# Update job status
|
|
275
|
-
|
|
267
|
+
set_status :prepare
|
|
276
268
|
@runs += 1
|
|
277
269
|
|
|
278
270
|
# Init
|
|
@@ -283,34 +275,34 @@ module RestFtpDaemon
|
|
|
283
275
|
# Prepare source
|
|
284
276
|
raise RestFtpDaemon::JobMissingAttribute unless @source
|
|
285
277
|
@source_path = expand_path @source
|
|
286
|
-
|
|
287
|
-
|
|
278
|
+
set_info :source_path, @source_path
|
|
279
|
+
set_info :source_method, :file
|
|
288
280
|
|
|
289
281
|
# Prepare target
|
|
290
282
|
raise RestFtpDaemon::JobMissingAttribute unless @target
|
|
291
283
|
target_uri = expand_url @target
|
|
292
|
-
|
|
284
|
+
set_info :target_uri, target_uri.to_s
|
|
293
285
|
@target_path = Path.new target_uri.path, true
|
|
294
286
|
|
|
295
287
|
#puts "@target_path: #{@target_path.inspect}"
|
|
296
288
|
|
|
297
289
|
# Prepare remote
|
|
298
|
-
|
|
290
|
+
set_status :remote_init
|
|
299
291
|
#FIXME: use a "case" statement on @target_url.class
|
|
300
292
|
|
|
301
293
|
if target_uri.is_a? URI::FTP
|
|
302
294
|
log_info "Job.prepare target_method FTP"
|
|
303
|
-
|
|
295
|
+
set_info :target_method, :ftp
|
|
304
296
|
@remote = RemoteFTP.new target_uri, log_context
|
|
305
297
|
|
|
306
298
|
elsif (target_uri.is_a? URI::FTPES) || (target_uri.is_a? URI::FTPS)
|
|
307
299
|
log_info "Job.prepare target_method FTPES"
|
|
308
|
-
|
|
300
|
+
set_info :target_method, :ftpes
|
|
309
301
|
@remote = RemoteFTP.new target_uri, log_context, ftpes: true
|
|
310
302
|
|
|
311
303
|
elsif target_uri.is_a? URI::SFTP
|
|
312
304
|
log_info "Job.prepare target_method SFTP"
|
|
313
|
-
|
|
305
|
+
set_info :target_method, :sftp
|
|
314
306
|
@remote = RemoteSFTP.new target_uri, log_context
|
|
315
307
|
|
|
316
308
|
else
|
|
@@ -328,13 +320,13 @@ module RestFtpDaemon
|
|
|
328
320
|
raise RestFtpDaemon::JobAssertionFailed, "transfer/1" unless @source_path
|
|
329
321
|
raise RestFtpDaemon::JobAssertionFailed, "transfer/2" unless @target_path
|
|
330
322
|
@transfer_sent = 0
|
|
331
|
-
|
|
323
|
+
set_info :source_processed, 0
|
|
332
324
|
|
|
333
325
|
# Guess source files from disk
|
|
334
|
-
|
|
326
|
+
set_status :checking_source
|
|
335
327
|
sources = find_local @source_path
|
|
336
|
-
|
|
337
|
-
|
|
328
|
+
set_info :source_count, sources.count
|
|
329
|
+
set_info :source_files, sources.collect(&:full)
|
|
338
330
|
log_info "Job.transfer sources #{sources.collect(&:name)}"
|
|
339
331
|
raise RestFtpDaemon::JobSourceNotFound if sources.empty?
|
|
340
332
|
|
|
@@ -342,16 +334,16 @@ module RestFtpDaemon
|
|
|
342
334
|
raise RestFtpDaemon::JobTargetDirectoryError if @target_path.name && sources.count>1
|
|
343
335
|
|
|
344
336
|
# Connect to remote server and login
|
|
345
|
-
|
|
337
|
+
set_status :remote_connect
|
|
346
338
|
@remote.connect
|
|
347
339
|
|
|
348
340
|
# Prepare target path or build it if asked
|
|
349
|
-
|
|
341
|
+
set_status :remote_chdir
|
|
350
342
|
@remote.chdir_or_create @target_path.dir, @mkdir
|
|
351
343
|
|
|
352
344
|
# Compute total files size
|
|
353
345
|
@transfer_total = sources.collect(&:size).sum
|
|
354
|
-
|
|
346
|
+
set_info :transfer_total, @transfer_total
|
|
355
347
|
|
|
356
348
|
# Reset counters
|
|
357
349
|
@last_data = 0
|
|
@@ -372,7 +364,7 @@ module RestFtpDaemon
|
|
|
372
364
|
remote_push source, full_target
|
|
373
365
|
|
|
374
366
|
# Update counters
|
|
375
|
-
|
|
367
|
+
set_info :source_processed, source_processed += 1
|
|
376
368
|
end
|
|
377
369
|
|
|
378
370
|
# FTP transfer finished
|
|
@@ -397,13 +389,37 @@ module RestFtpDaemon
|
|
|
397
389
|
end
|
|
398
390
|
end
|
|
399
391
|
|
|
400
|
-
def
|
|
401
|
-
|
|
392
|
+
def touch_job
|
|
393
|
+
now = Time.now
|
|
394
|
+
@updated_at = now
|
|
395
|
+
Thread.current.thread_variable_set :updated_at, now
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
def set_info attribute, value
|
|
399
|
+
@mutex.synchronize do
|
|
400
|
+
@infos || {}
|
|
401
|
+
@infos[attribute] = utf8_if_string value
|
|
402
|
+
touch_job
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def set_error value
|
|
407
|
+
@mutex.synchronize do
|
|
408
|
+
@error = utf8_if_string value
|
|
409
|
+
touch_job
|
|
410
|
+
end
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
def set_status value
|
|
414
|
+
@mutex.synchronize do
|
|
415
|
+
@status = utf8_if_string value
|
|
416
|
+
touch_job
|
|
417
|
+
end
|
|
402
418
|
end
|
|
403
419
|
|
|
404
|
-
def
|
|
405
|
-
|
|
406
|
-
|
|
420
|
+
def utf8_if_string value
|
|
421
|
+
return value unless (value.is_a? String) || (value.is_a? Symbol)
|
|
422
|
+
return value.to_s.encode("UTF-8")
|
|
407
423
|
end
|
|
408
424
|
|
|
409
425
|
def flag_default name, default
|
|
@@ -426,7 +442,7 @@ module RestFtpDaemon
|
|
|
426
442
|
@remote = nil
|
|
427
443
|
|
|
428
444
|
# Update job status
|
|
429
|
-
|
|
445
|
+
set_status :disconnecting
|
|
430
446
|
@finished_at = Time.now
|
|
431
447
|
|
|
432
448
|
# Update counters
|
|
@@ -442,7 +458,7 @@ module RestFtpDaemon
|
|
|
442
458
|
|
|
443
459
|
# Use source filename if target path provided none (typically with multiple sources)
|
|
444
460
|
log_info "Job.remote_push [#{source.name}]: [#{source.full}] > [#{target.full}]"
|
|
445
|
-
|
|
461
|
+
set_info :source_current, source.name
|
|
446
462
|
|
|
447
463
|
# Compute temp target name
|
|
448
464
|
tempname = nil
|
|
@@ -463,24 +479,24 @@ module RestFtpDaemon
|
|
|
463
479
|
transfer_started_at = Time.now
|
|
464
480
|
@progress_at = 0
|
|
465
481
|
@notified_at = transfer_started_at
|
|
466
|
-
|
|
482
|
+
set_status JOB_STATUS_UPLOADING
|
|
467
483
|
|
|
468
484
|
# Start the transfer, update job status after each block transfer
|
|
469
|
-
|
|
485
|
+
set_status :uploading
|
|
470
486
|
@remote.push source, target, tempname do |transferred, name|
|
|
471
487
|
# Update transfer statistics
|
|
472
488
|
progress transferred, name
|
|
473
489
|
|
|
474
490
|
# Touch my worker status
|
|
475
|
-
|
|
491
|
+
touch_job
|
|
476
492
|
end
|
|
477
493
|
|
|
478
494
|
# Compute final bitrate
|
|
479
495
|
global_transfer_bitrate = get_bitrate @transfer_total, (Time.now - transfer_started_at)
|
|
480
|
-
|
|
496
|
+
set_info :transfer_bitrate, global_transfer_bitrate.round(0)
|
|
481
497
|
|
|
482
498
|
# Done
|
|
483
|
-
|
|
499
|
+
set_info :source_current, nil
|
|
484
500
|
end
|
|
485
501
|
|
|
486
502
|
def progress transferred, name = ""
|
|
@@ -489,17 +505,17 @@ module RestFtpDaemon
|
|
|
489
505
|
|
|
490
506
|
# Update counters
|
|
491
507
|
@transfer_sent += transferred
|
|
492
|
-
|
|
508
|
+
set_info :transfer_sent, @transfer_sent
|
|
493
509
|
|
|
494
510
|
# Update job info
|
|
495
511
|
percent0 = (100.0 * @transfer_sent / @transfer_total).round(0)
|
|
496
|
-
|
|
512
|
+
set_info :progress, percent0
|
|
497
513
|
|
|
498
514
|
# Update job status after each NOTIFY_UPADE_STATUS
|
|
499
515
|
progressed_ago = (now.to_f - @progress_at.to_f)
|
|
500
516
|
if (!JOB_UPDATE_INTERVAL.to_f.zero?) && (progressed_ago > JOB_UPDATE_INTERVAL.to_f)
|
|
501
517
|
@current_bitrate = running_bitrate @transfer_sent
|
|
502
|
-
|
|
518
|
+
set_info :transfer_bitrate, @current_bitrate.round(0)
|
|
503
519
|
|
|
504
520
|
# Log progress
|
|
505
521
|
stack = []
|
|
@@ -568,7 +584,9 @@ module RestFtpDaemon
|
|
|
568
584
|
|
|
569
585
|
def oops event, exception, error = nil, include_backtrace = false
|
|
570
586
|
# Log this error
|
|
587
|
+
# error = exception.class.to_s.encoding.to_s if error.nil?
|
|
571
588
|
error = exception.class if error.nil?
|
|
589
|
+
# error = "DEF #{exception.class}" if error.nil?
|
|
572
590
|
|
|
573
591
|
message = "Job.oops event[#{event}] error[#{error}] ex[#{exception.class}] #{exception.message}"
|
|
574
592
|
if include_backtrace
|
|
@@ -581,15 +599,15 @@ module RestFtpDaemon
|
|
|
581
599
|
@remote.close unless @remote.nil? || !@remote.connected?
|
|
582
600
|
|
|
583
601
|
# Update job's internal status
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
602
|
+
set_status JOB_STATUS_FAILED
|
|
603
|
+
set_error error
|
|
604
|
+
set_info :error_exception, exception.class.to_s
|
|
605
|
+
set_info :error_message, exception.message
|
|
588
606
|
|
|
589
607
|
# Build status stack
|
|
590
608
|
notif_status = nil
|
|
591
609
|
if include_backtrace
|
|
592
|
-
|
|
610
|
+
set_info :error_backtrace, exception.backtrace
|
|
593
611
|
notif_status = {
|
|
594
612
|
backtrace: exception.backtrace,
|
|
595
613
|
}
|
|
@@ -45,7 +45,7 @@ module RestFtpDaemon
|
|
|
45
45
|
log_error "not retrying: max_age reached (#{max_age} s)"
|
|
46
46
|
|
|
47
47
|
elsif max_runs && (job.runs >= max_runs)
|
|
48
|
-
log_error "not retrying: max_runs reached (#{max_runs}
|
|
48
|
+
log_error "not retrying: max_runs reached (#{max_runs} tries)"
|
|
49
49
|
|
|
50
50
|
else
|
|
51
51
|
# Delay cannot be negative, and will be 1s minimum
|
data/rest-ftp-daemon.gemspec
CHANGED
|
@@ -22,7 +22,7 @@ Gem::Specification.new do |spec|
|
|
|
22
22
|
spec.require_paths = ["lib"]
|
|
23
23
|
spec.version = APP_VER
|
|
24
24
|
|
|
25
|
-
spec.required_ruby_version = ">= 2.
|
|
25
|
+
spec.required_ruby_version = ">= 2.2"
|
|
26
26
|
|
|
27
27
|
# spec.add_development_dependency "rack-mini-profiler"
|
|
28
28
|
# spec.add_development_dependency "stackprof"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rest-ftp-daemon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.242.
|
|
4
|
+
version: 0.242.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Bruno MEDICI
|
|
@@ -338,7 +338,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
338
338
|
requirements:
|
|
339
339
|
- - ">="
|
|
340
340
|
- !ruby/object:Gem::Version
|
|
341
|
-
version: 2.
|
|
341
|
+
version: '2.2'
|
|
342
342
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
343
343
|
requirements:
|
|
344
344
|
- - ">="
|
|
@@ -346,7 +346,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
346
346
|
version: '0'
|
|
347
347
|
requirements: []
|
|
348
348
|
rubyforge_project:
|
|
349
|
-
rubygems_version: 2.
|
|
349
|
+
rubygems_version: 2.4.5
|
|
350
350
|
signing_key:
|
|
351
351
|
specification_version: 4
|
|
352
352
|
summary: RESTful FTP client daemon
|