rest-ftp-daemon 0.242.2 → 0.242.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|