rest-ftp-daemon 0.200 → 0.202
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/bin/rest-ftp-daemon +2 -2
- data/lib/rest-ftp-daemon.rb +4 -3
- data/lib/rest-ftp-daemon/api/dashboard.rb +7 -34
- data/lib/rest-ftp-daemon/api/jobs.rb +17 -1
- data/lib/rest-ftp-daemon/constants.rb +2 -1
- data/lib/rest-ftp-daemon/job.rb +40 -34
- data/lib/rest-ftp-daemon/job_queue.rb +21 -11
- data/lib/rest-ftp-daemon/{config.rb → settings.rb} +1 -2
- data/lib/rest-ftp-daemon/static/css/main.css +1 -0
- data/lib/rest-ftp-daemon/views/dashboard.haml +6 -40
- data/lib/rest-ftp-daemon/views/dashboard_headers.haml +14 -9
- data/lib/rest-ftp-daemon/views/dashboard_jobs.haml +35 -77
- data/lib/rest-ftp-daemon/views/dashboard_table.haml +84 -0
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb8cd253dc74ddd13d47f208a057dac0fd9d9010
|
4
|
+
data.tar.gz: cad450fab5d69069450e6e2ef569acaa768168e4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 543c89c37961fcc553660758cdca12d464d2c52e8c203d184fc034247a41550103574c94ccd7215e6cbd75392e6709c9bb66cf7d63f2a116e847cc77973c6888
|
7
|
+
data.tar.gz: f501f9e4203a23adcd969ead187d79314caac1b852fb62e7b83593f0d727317b2d151652627464c9a8c01ef8f8034d4a9ebb29aab587fc2367cc1180ba99799f
|
data/Gemfile.lock
CHANGED
data/bin/rest-ftp-daemon
CHANGED
@@ -57,7 +57,7 @@ abort "EXITING: cannot read configuration file: #{APP_CONF}" unless File.exists?
|
|
57
57
|
|
58
58
|
# Load config, and merge options from ARGV into settings
|
59
59
|
begin
|
60
|
-
require File.expand_path("#{app_root}/lib/rest-ftp-daemon/
|
60
|
+
require File.expand_path("#{app_root}/lib/rest-ftp-daemon/settings")
|
61
61
|
Settings.merge!(options)
|
62
62
|
rescue Psych::SyntaxError => e
|
63
63
|
abort "EXITING: config file syntax error: #{e.message}"
|
@@ -106,7 +106,7 @@ puts "PID file \t #{Settings.pidfile}"
|
|
106
106
|
puts "Daemonize \t #{Settings.daemonize ? 'YES' : "no"}"
|
107
107
|
puts "Namespace \t #{Settings.namespace}"
|
108
108
|
puts "Network port \t #{Settings.port}"
|
109
|
-
puts "User:group \t #{Settings.user}:#{Settings.group}" if Settings.
|
109
|
+
puts "User:group \t #{Settings.user}:#{Settings.group}" if (Settings.user || Settings.group)
|
110
110
|
puts Settings.dump
|
111
111
|
puts
|
112
112
|
puts "--- Thin ARGV"
|
data/lib/rest-ftp-daemon.rb
CHANGED
@@ -4,13 +4,14 @@ require 'json'
|
|
4
4
|
require 'grape'
|
5
5
|
require 'grape-entity'
|
6
6
|
require 'haml'
|
7
|
-
require
|
8
|
-
require
|
7
|
+
require 'facter'
|
8
|
+
require 'sys/cpu'
|
9
|
+
require 'syslog'
|
9
10
|
|
10
11
|
|
11
12
|
# My libs
|
12
13
|
require 'rest-ftp-daemon/constants'
|
13
|
-
require 'rest-ftp-daemon/
|
14
|
+
require 'rest-ftp-daemon/settings'
|
14
15
|
require 'rest-ftp-daemon/exceptions'
|
15
16
|
require 'rest-ftp-daemon/helpers'
|
16
17
|
require 'rest-ftp-daemon/uri'
|
@@ -2,54 +2,27 @@ module RestFtpDaemon
|
|
2
2
|
module API
|
3
3
|
class Root < Grape::API
|
4
4
|
|
5
|
+
|
5
6
|
####### DASHBOARD - GET /
|
6
7
|
|
7
8
|
# Server global status
|
8
9
|
get '/' do
|
9
10
|
info "GET /"
|
10
11
|
|
11
|
-
# Initialize
|
12
|
+
# Initialize Facter
|
12
13
|
Facter.loadfacts
|
13
|
-
@info_load = Sys::CPU.load_avg.first.to_f
|
14
|
-
@info_procs = (Facter.value :processorcount).to_i
|
15
|
-
@info_ipaddr = Facter.value(:ipaddress)
|
16
|
-
@info_memfree = Facter.value(:memoryfree)
|
17
|
-
|
18
|
-
# Compute normalized load
|
19
|
-
if @info_procs.zero?
|
20
|
-
@info_norm = "N/A"
|
21
|
-
else
|
22
|
-
@info_norm = (100 * @info_load / @info_procs).round(1)
|
23
|
-
end
|
24
|
-
|
25
|
-
# Jobs to display
|
26
|
-
popped_jobs = $queue.ordered_popped.reverse
|
27
|
-
@jobs_queued = $queue.ordered_queue.reverse
|
28
|
-
|
29
|
-
if params["only"].nil? || params["only"].blank?
|
30
|
-
@only = nil
|
31
|
-
else
|
32
|
-
@only = params["only"].to_sym
|
33
|
-
end
|
34
14
|
|
35
|
-
|
36
|
-
|
37
|
-
@jobs_current = popped_jobs
|
38
|
-
when JOB_STATUS_QUEUED
|
39
|
-
@jobs_current = @jobs_queued
|
40
|
-
else
|
41
|
-
@jobs_current = $queue.popped_reverse_sorted_by_status @only
|
42
|
-
end
|
15
|
+
# Detect QS filters
|
16
|
+
only = params["only"].to_s
|
43
17
|
|
44
|
-
#
|
45
|
-
|
46
|
-
@count_all = $queue.all_size
|
18
|
+
# Get jobs to display
|
19
|
+
jobs = $queue.sorted_by_status(only)
|
47
20
|
|
48
21
|
# Get workers status
|
49
22
|
@worker_vars = $pool.worker_vars
|
50
23
|
|
51
24
|
# Compile haml template
|
52
|
-
output = render :dashboard
|
25
|
+
output = render :dashboard, {jobs: jobs, only: only}
|
53
26
|
|
54
27
|
# Send response
|
55
28
|
env['api.format'] = :html
|
@@ -10,17 +10,22 @@ module RestFtpDaemon
|
|
10
10
|
end
|
11
11
|
get '/jobs/*id' do
|
12
12
|
info "GET /jobs/#{params[:id]}"
|
13
|
+
|
13
14
|
begin
|
15
|
+
# Get job to display
|
14
16
|
job = job_find params[:id]
|
15
17
|
raise RestFtpDaemon::JobNotFound if job.nil?
|
16
18
|
|
17
19
|
rescue RestFtpDaemon::JobNotFound => exception
|
20
|
+
info "EXCEPTION: JobNotFound: #{exception.message}"
|
18
21
|
status 404
|
19
22
|
api_error exception
|
20
23
|
rescue RestFtpDaemonException => exception
|
24
|
+
info "EXCEPTION: RestFtpDaemonException: #{exception.message}"
|
21
25
|
status 500
|
22
26
|
api_error exception
|
23
27
|
rescue Exception => exception
|
28
|
+
info "EXCEPTION: Exception: #{exception.message}"
|
24
29
|
status 501
|
25
30
|
api_error exception
|
26
31
|
else
|
@@ -37,12 +42,20 @@ module RestFtpDaemon
|
|
37
42
|
|
38
43
|
get '/jobs/' do
|
39
44
|
info "GET /jobs"
|
45
|
+
|
40
46
|
begin
|
41
|
-
|
47
|
+
# Detect QS filters
|
48
|
+
only = params["only"].to_s
|
49
|
+
|
50
|
+
# Get jobs to display
|
51
|
+
jobs = $queue.sorted_by_status(only)
|
52
|
+
|
42
53
|
rescue RestFtpDaemonException => exception
|
54
|
+
info "EXCEPTION: RestFtpDaemonException: #{exception.message}"
|
43
55
|
status 501
|
44
56
|
api_error exception
|
45
57
|
rescue Exception => exception
|
58
|
+
info "EXCEPTION: Exception: #{exception.message}"
|
46
59
|
status 501
|
47
60
|
api_error exception
|
48
61
|
else
|
@@ -88,12 +101,15 @@ module RestFtpDaemon
|
|
88
101
|
$queue.counter_inc :jobs_received
|
89
102
|
|
90
103
|
rescue JSON::ParserError => exception
|
104
|
+
info "EXCEPTION: JSON::ParserError: #{exception.message}"
|
91
105
|
status 406
|
92
106
|
api_error exception
|
93
107
|
rescue RestFtpDaemonException => exception
|
108
|
+
info "EXCEPTION: RestFtpDaemonException: #{exception.message}"
|
94
109
|
status 412
|
95
110
|
api_error exception
|
96
111
|
rescue Exception => exception
|
112
|
+
info "EXCEPTION: #{exception.message}"
|
97
113
|
status 501
|
98
114
|
api_error exception
|
99
115
|
else
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Terrific constants
|
2
2
|
APP_NAME = "rest-ftp-daemon"
|
3
|
-
APP_VER = "0.
|
3
|
+
APP_VER = "0.202"
|
4
4
|
|
5
5
|
|
6
6
|
# Logging
|
@@ -20,6 +20,7 @@ JOB_UPDATE_KB = 2048
|
|
20
20
|
JOB_STATUS_UPLOADING = :uploading
|
21
21
|
JOB_STATUS_FINISHED = :finished
|
22
22
|
JOB_STATUS_QUEUED = :queued
|
23
|
+
JOB_WEIGHTS = {queued: -10, uploading: 10, finished: 50}
|
23
24
|
|
24
25
|
# Notifications
|
25
26
|
NOTIFY_PREFIX = "rftpd"
|
data/lib/rest-ftp-daemon/job.rb
CHANGED
@@ -74,7 +74,7 @@ module RestFtpDaemon
|
|
74
74
|
# Prepare job
|
75
75
|
begin
|
76
76
|
info "Job.process prepare"
|
77
|
-
|
77
|
+
newstatus :preparing
|
78
78
|
prepare
|
79
79
|
|
80
80
|
rescue RestFtpDaemon::JobMissingAttribute => exception
|
@@ -103,7 +103,7 @@ module RestFtpDaemon
|
|
103
103
|
|
104
104
|
else
|
105
105
|
# Prepare done !
|
106
|
-
|
106
|
+
newstatus :prepared
|
107
107
|
info "Job.process notify: started"
|
108
108
|
client_notify :started
|
109
109
|
end
|
@@ -111,7 +111,7 @@ module RestFtpDaemon
|
|
111
111
|
# Process job
|
112
112
|
begin
|
113
113
|
info "Job.process transfer"
|
114
|
-
|
114
|
+
newstatus :starting
|
115
115
|
transfer
|
116
116
|
|
117
117
|
rescue SocketError => exception
|
@@ -170,7 +170,7 @@ module RestFtpDaemon
|
|
170
170
|
|
171
171
|
else
|
172
172
|
# All done !
|
173
|
-
|
173
|
+
newstatus JOB_STATUS_FINISHED
|
174
174
|
info "Job.process notify: ended"
|
175
175
|
client_notify :ended
|
176
176
|
end
|
@@ -186,7 +186,7 @@ module RestFtpDaemon
|
|
186
186
|
|
187
187
|
def set_queued
|
188
188
|
# Update job status
|
189
|
-
|
189
|
+
newstatus JOB_STATUS_QUEUED
|
190
190
|
end
|
191
191
|
|
192
192
|
def oops_after_crash exception
|
@@ -251,7 +251,7 @@ module RestFtpDaemon
|
|
251
251
|
|
252
252
|
def prepare
|
253
253
|
# Update job status
|
254
|
-
|
254
|
+
newstatus :preparing
|
255
255
|
|
256
256
|
# Init
|
257
257
|
@source_method = :file
|
@@ -286,7 +286,7 @@ module RestFtpDaemon
|
|
286
286
|
|
287
287
|
def transfer
|
288
288
|
# Update job status
|
289
|
-
|
289
|
+
newstatus = :checking_source
|
290
290
|
@started_at = Time.now
|
291
291
|
|
292
292
|
# Method assertions and init
|
@@ -355,6 +355,23 @@ module RestFtpDaemon
|
|
355
355
|
|
356
356
|
private
|
357
357
|
|
358
|
+
def info message, context = {}
|
359
|
+
return if @logger.nil?
|
360
|
+
|
361
|
+
# Inject context
|
362
|
+
context[:id] = @id
|
363
|
+
context[:origin] = self.class
|
364
|
+
|
365
|
+
# Forward to logger
|
366
|
+
@logger.info_with_id message, context
|
367
|
+
end
|
368
|
+
|
369
|
+
def newstatus name
|
370
|
+
# Update local status
|
371
|
+
@status = name
|
372
|
+
# push_job
|
373
|
+
end
|
374
|
+
|
358
375
|
def flag_default name, default
|
359
376
|
# build the flag instance var name
|
360
377
|
variable = "@#{name.to_s}"
|
@@ -368,7 +385,7 @@ module RestFtpDaemon
|
|
368
385
|
|
369
386
|
def ftp_init
|
370
387
|
# Update job status
|
371
|
-
|
388
|
+
newstatus :ftp_init
|
372
389
|
|
373
390
|
# Method assertions
|
374
391
|
raise RestFtpDaemon::JobAssertionFailed, "ftp_init/1" if @target_method.nil?
|
@@ -418,7 +435,7 @@ module RestFtpDaemon
|
|
418
435
|
end
|
419
436
|
|
420
437
|
# Update job status
|
421
|
-
|
438
|
+
newstatus :disconnecting
|
422
439
|
@finished_at = Time.now
|
423
440
|
|
424
441
|
# Update counters
|
@@ -428,7 +445,7 @@ module RestFtpDaemon
|
|
428
445
|
|
429
446
|
def ftp_connect
|
430
447
|
# Update job status
|
431
|
-
|
448
|
+
newstatus :ftp_connect
|
432
449
|
|
433
450
|
# Method assertions
|
434
451
|
host = @target_url.host
|
@@ -441,7 +458,7 @@ module RestFtpDaemon
|
|
441
458
|
|
442
459
|
def ftp_login
|
443
460
|
# Update job status
|
444
|
-
|
461
|
+
newstatus :ftp_login
|
445
462
|
|
446
463
|
# Method assertions
|
447
464
|
raise RestFtpDaemon::JobAssertionFailed, "ftp_login/1" if @ftp.nil?
|
@@ -456,7 +473,7 @@ module RestFtpDaemon
|
|
456
473
|
def ftp_chdir_or_buildpath path
|
457
474
|
# Method assertions
|
458
475
|
info "Job.ftp_chdir [#{path}] mkdir: #{@mkdir}"
|
459
|
-
|
476
|
+
newstatus :ftp_chdir
|
460
477
|
raise RestFtpDaemon::JobAssertionFailed, "ftp_chdir_or_buildpath/1" if path.nil?
|
461
478
|
|
462
479
|
# Extract directory from path
|
@@ -506,7 +523,7 @@ module RestFtpDaemon
|
|
506
523
|
|
507
524
|
def ftp_presence target_name
|
508
525
|
# Update job status
|
509
|
-
|
526
|
+
newstatus :ftp_presence
|
510
527
|
# FIXME / TODO: try with nlst
|
511
528
|
|
512
529
|
# Method assertions
|
@@ -534,7 +551,7 @@ module RestFtpDaemon
|
|
534
551
|
set :source_current, target_name
|
535
552
|
|
536
553
|
# Check for target file presence
|
537
|
-
|
554
|
+
newstatus :checking_target
|
538
555
|
present = ftp_presence target_name
|
539
556
|
if present
|
540
557
|
if @overwrite
|
@@ -563,7 +580,8 @@ module RestFtpDaemon
|
|
563
580
|
chunk_size = update_every_kb * 1024
|
564
581
|
t0 = tstart = Time.now
|
565
582
|
notified_at = Time.now
|
566
|
-
|
583
|
+
newstatus JOB_STATUS_UPLOADING
|
584
|
+
|
567
585
|
@ftp.putbinaryfile(source_filename, target_real, chunk_size) do |block|
|
568
586
|
# Update counters
|
569
587
|
@transfer_sent += block.bytesize
|
@@ -575,12 +593,12 @@ module RestFtpDaemon
|
|
575
593
|
set :transfer_bitrate, bitrate0
|
576
594
|
|
577
595
|
# Update job info
|
578
|
-
|
579
|
-
set :progress,
|
596
|
+
percent0 = (100.0 * @transfer_sent / @transfer_total).round(0)
|
597
|
+
set :progress, percent0
|
580
598
|
|
581
599
|
# Log progress
|
582
600
|
stack = []
|
583
|
-
stack << "#{
|
601
|
+
stack << "#{percent0} %"
|
584
602
|
stack << (Helpers.format_bytes @transfer_sent, "B")
|
585
603
|
stack << (Helpers.format_bytes @transfer_total, "B")
|
586
604
|
stack << (Helpers.format_bytes bitrate0, "bps")
|
@@ -592,7 +610,7 @@ module RestFtpDaemon
|
|
592
610
|
# Notify if requested
|
593
611
|
unless notify_after_sec.nil? || (notified_at + notify_after_sec > Time.now)
|
594
612
|
notif_status = {
|
595
|
-
progress:
|
613
|
+
progress: percent0,
|
596
614
|
transfer_sent: @transfer_sent,
|
597
615
|
transfer_total: @transfer_total,
|
598
616
|
transfer_bitrate: bitrate0
|
@@ -605,7 +623,7 @@ module RestFtpDaemon
|
|
605
623
|
|
606
624
|
# Rename temp file to target_temp
|
607
625
|
if @tempfile
|
608
|
-
|
626
|
+
newstatus :renaming
|
609
627
|
info "Job.ftp_transfer renaming: #{target_name}"
|
610
628
|
@ftp.rename target_real, target_name
|
611
629
|
end
|
@@ -633,19 +651,7 @@ module RestFtpDaemon
|
|
633
651
|
end
|
634
652
|
|
635
653
|
def get_bitrate total, last_timestamp
|
636
|
-
total.to_f / (Time.now - last_timestamp)
|
637
|
-
end
|
638
|
-
|
639
|
-
|
640
|
-
def info message, context = {}
|
641
|
-
return if @logger.nil?
|
642
|
-
|
643
|
-
# Inject context
|
644
|
-
context[:id] = @id
|
645
|
-
context[:origin] = self.class
|
646
|
-
|
647
|
-
# Forward to logger
|
648
|
-
@logger.info_with_id message, context
|
654
|
+
8*total.to_f / (Time.now - last_timestamp)
|
649
655
|
end
|
650
656
|
|
651
657
|
def oops event, exception, error = nil, include_backtrace = false
|
@@ -663,7 +669,7 @@ module RestFtpDaemon
|
|
663
669
|
@ftp.close unless @ftp.nil? || @ftp.welcome.nil?
|
664
670
|
|
665
671
|
# Update job's internal status
|
666
|
-
|
672
|
+
newstatus :failed
|
667
673
|
@error = error
|
668
674
|
set :error_exception, exception.class
|
669
675
|
set :error_message, exception.message
|
@@ -16,7 +16,7 @@ module RestFtpDaemon
|
|
16
16
|
self.taint
|
17
17
|
@mutex = Mutex.new
|
18
18
|
|
19
|
-
#
|
19
|
+
# Logger
|
20
20
|
@logger = RestFtpDaemon::LoggerPool.instance.get :queue
|
21
21
|
|
22
22
|
# Identifiers generator
|
@@ -76,11 +76,20 @@ module RestFtpDaemon
|
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
|
-
def
|
80
|
-
|
79
|
+
def sorted_by_status status
|
80
|
+
# Just use the base if filter is empty
|
81
|
+
if status.empty?
|
82
|
+
elements = all
|
83
|
+
else
|
84
|
+
elements = all.select { |item| item.status == status.to_sym }
|
85
|
+
end
|
86
|
+
|
87
|
+
# Sort these elements
|
88
|
+
elements.sort_by do |item|
|
89
|
+
w = JOB_WEIGHTS[item.status] || 0
|
90
|
+
[ w, item.wid.to_s, item.updated_at.to_s]
|
91
|
+
end
|
81
92
|
|
82
|
-
# Select jobs from the queue if their status is (status)
|
83
|
-
ordered_popped.reverse.select { |item| item.status == status.to_sym }
|
84
93
|
end
|
85
94
|
|
86
95
|
def counts_by_status
|
@@ -166,12 +175,12 @@ module RestFtpDaemon
|
|
166
175
|
end
|
167
176
|
end
|
168
177
|
|
169
|
-
def ordered_popped
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
178
|
+
# def ordered_popped
|
179
|
+
# @mutex_counters.synchronize do
|
180
|
+
# @popped.sort_by { |item| [ item.wid.to_s, item.updated_at] }
|
181
|
+
# # @popped.sort_by { |item| [item.status.to_s, item.wid.to_s, item.updated_at, - item.id.to_i] }
|
182
|
+
# end
|
183
|
+
# end
|
175
184
|
|
176
185
|
protected
|
177
186
|
|
@@ -182,6 +191,7 @@ module RestFtpDaemon
|
|
182
191
|
def conchita_loop
|
183
192
|
info "conchita starting with: #{@conchita.inspect}"
|
184
193
|
loop do
|
194
|
+
# Do the cleanup
|
185
195
|
conchita_clean JOB_STATUS_FINISHED
|
186
196
|
conchita_clean :failed
|
187
197
|
sleep @conchita[:timer]
|
@@ -2,7 +2,7 @@
|
|
2
2
|
begin
|
3
3
|
require "settingslogic"
|
4
4
|
rescue LoadError
|
5
|
-
raise "
|
5
|
+
raise "warning: Settingslogic is needed to provide configuration values to the Gemspec file"
|
6
6
|
end
|
7
7
|
|
8
8
|
# Configuration class
|
@@ -19,7 +19,6 @@ class Settings < Settingslogic
|
|
19
19
|
|
20
20
|
# Direct access to any depth
|
21
21
|
def at *path
|
22
|
-
#put "Settings.nested: wrong path [#{path.inspect}]" unless path.is_a? Hash
|
23
22
|
path.reduce(Settings) {|m,key| m && m[key.to_s] }
|
24
23
|
end
|
25
24
|
|
@@ -4,7 +4,7 @@
|
|
4
4
|
%meta{:charset => "utf-8"}/
|
5
5
|
%link{ href:"/css/bootstrap.css" , rel: "stylesheet"}
|
6
6
|
%link{ href:"/css/main.css" , rel: "stylesheet"}
|
7
|
-
%link{ href:"http://fonts.googleapis.com/css?family=Inconsolata:400,700" , rel: "stylesheet"}
|
7
|
+
-# %link{ href:"http://fonts.googleapis.com/css?family=Inconsolata:400,700" , rel: "stylesheet"}
|
8
8
|
%title="#{Settings.host} [#{Settings.namespace}] #{APP_NAME}"
|
9
9
|
|
10
10
|
%body
|
@@ -25,51 +25,17 @@
|
|
25
25
|
= render :dashboard_headers
|
26
26
|
|
27
27
|
.row
|
28
|
-
.col-md-12
|
29
|
-
|
30
|
-
%h2
|
31
|
-
Jobs
|
32
|
-
|
33
|
-
.btn-group.btn-group-md
|
34
|
-
- klass = @only.nil? ? "btn-info" : ""
|
35
|
-
%a.btn.btn-default{href: "?only=", class: klass}
|
36
|
-
ALL (#{@count_all})
|
37
|
-
.btn-group.btn-group-md
|
38
|
-
- @counts.each do |status, count|
|
39
|
-
- klass = (status == @only) ? "btn-info" : ""
|
40
|
-
%a.btn.btn-default{href: "?only=#{status}", class: klass}
|
41
|
-
#{status} (#{count})
|
42
|
-
|
43
|
-
%table.table.table-striped.table-hover.table-condensed
|
44
|
-
%tr
|
45
|
-
%th ID
|
46
|
-
%th label
|
47
|
-
%th source
|
48
|
-
%th <=>
|
49
|
-
%th target
|
50
|
-
%th date
|
51
|
-
%th status
|
52
|
-
%th error
|
53
|
-
%th.text-right size
|
54
|
-
%th.text-right bitrate
|
55
|
-
%th
|
56
|
-
|
57
|
-
- if @only.nil? && !@jobs_queued.empty?
|
58
|
-
= render :dashboard_jobs, {jobs: @jobs_queued, counts: @counts}
|
59
|
-
%tr
|
60
|
-
%th{colspan: 12}
|
61
|
-
|
62
|
-
= render :dashboard_jobs, {jobs: @jobs_current, counts: @counts}
|
63
|
-
|
28
|
+
#box-jobs.col-md-12
|
29
|
+
= render :dashboard_jobs, {jobs: jobs, only: only}
|
64
30
|
|
65
31
|
.row
|
66
|
-
.col-md-6
|
32
|
+
#box-tokens.col-md-6
|
67
33
|
= render :dashboard_tokens, {tokens: Settings.endpoints || {}}
|
68
34
|
|
69
|
-
.col-md-3
|
35
|
+
#box-workers.col-md-3
|
70
36
|
= render :dashboard_workers
|
71
37
|
|
72
|
-
.col-md-3
|
38
|
+
#box-counters.col-md-3
|
73
39
|
= render :dashboard_counters
|
74
40
|
|
75
41
|
%br
|
@@ -1,27 +1,32 @@
|
|
1
1
|
- trans = $queue.counter_get :transferred
|
2
|
+
- info_procs = Facter.value :processorcount
|
3
|
+
- info_load = Sys::CPU.load_avg.first.to_f
|
4
|
+
- info_norm = info_procs.zero? ? "N/A" : (100 * info_load / info_procs).round(1)
|
5
|
+
|
6
|
+
|
2
7
|
.btn-group.btn-group-sm
|
3
|
-
.btn.btn-default.btn-success
|
4
|
-
.btn.btn-default=
|
8
|
+
.btn.btn-default.btn-success CPUs
|
9
|
+
.btn.btn-default= info_procs
|
5
10
|
|
6
11
|
.btn-group.btn-group-sm
|
7
12
|
.btn.btn-default.btn-success IP
|
8
|
-
.btn.btn-default=
|
13
|
+
.btn.btn-default= Facter.value(:ipaddress)
|
9
14
|
|
10
15
|
.btn-group.btn-group-sm
|
11
16
|
.btn.btn-default.btn-success Host
|
12
17
|
.btn.btn-default= Settings.host
|
13
18
|
|
14
19
|
.btn-group.btn-group-sm
|
15
|
-
.btn.btn-default.btn-
|
16
|
-
.btn.btn-default=
|
20
|
+
.btn.btn-default.btn-info Load
|
21
|
+
.btn.btn-default= info_load.round(1)
|
17
22
|
|
18
23
|
.btn-group.btn-group-sm
|
19
|
-
.btn.btn-default.btn-
|
20
|
-
.btn.btn-default= "#{
|
24
|
+
.btn.btn-default.btn-info CPU
|
25
|
+
.btn.btn-default= "#{info_norm} %"
|
21
26
|
|
22
27
|
.btn-group.btn-group-sm
|
23
|
-
.btn.btn-default.btn-
|
24
|
-
.btn.btn-default=
|
28
|
+
.btn.btn-default.btn-info Free
|
29
|
+
.btn.btn-default= Facter.value(:memoryfree)
|
25
30
|
|
26
31
|
.btn-group.btn-group-sm
|
27
32
|
.btn.btn-default.btn-info Transferred
|
@@ -1,77 +1,35 @@
|
|
1
|
-
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
%
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
= Helpers.highlight_tokens job.target
|
37
|
-
|
38
|
-
%td
|
39
|
-
= Helpers.datetime_short(job.queued_at)
|
40
|
-
|
41
|
-
%td
|
42
|
-
= job.status
|
43
|
-
|
44
|
-
- if (source_processed < source_count)
|
45
|
-
= " (#{source_processed}/#{source_count})"
|
46
|
-
|
47
|
-
- unless progress.nil?
|
48
|
-
= "#{progress}%"
|
49
|
-
|
50
|
-
- if job.status != JOB_STATUS_FINISHED
|
51
|
-
%br
|
52
|
-
%b= source_current unless source_current.nil?
|
53
|
-
|
54
|
-
%td
|
55
|
-
- if !job.error && job.status != JOB_STATUS_FINISHED
|
56
|
-
-# unless progress.nil? ||
|
57
|
-
.progress
|
58
|
-
.progress-bar{style:"width: #{progress}%;"}
|
59
|
-
= "#{progress}%" unless progress.nil?
|
60
|
-
|
61
|
-
- else
|
62
|
-
.error{title: errmsg}
|
63
|
-
= Helpers.text_or_empty(job.error)
|
64
|
-
|
65
|
-
%td.nobr.text-right
|
66
|
-
= Helpers.format_bytes(size, "B")
|
67
|
-
|
68
|
-
%td.nobr.text-right
|
69
|
-
- if (bitrate = job.get :transfer_bitrate)
|
70
|
-
= Helpers.format_bytes(bitrate, "bps")
|
71
|
-
|
72
|
-
%td
|
73
|
-
- unless job.priority.nil?
|
74
|
-
.label.label-info.flag.worker-label= job.priority
|
75
|
-
|
76
|
-
- unless job.wid.nil?
|
77
|
-
.label.label-warning.flag.worker-label= job.wid
|
1
|
+
- count_all = $queue.all_size
|
2
|
+
- counts_by_status = $queue.counts_by_status
|
3
|
+
|
4
|
+
|
5
|
+
%h2
|
6
|
+
Jobs
|
7
|
+
|
8
|
+
.btn-group.btn-group-md
|
9
|
+
- klass = only.empty? ? "btn-info" : ""
|
10
|
+
%a.btn.btn-default{href: "?only=", class: klass}
|
11
|
+
ALL (#{count_all})
|
12
|
+
.btn-group.btn-group-md
|
13
|
+
- counts_by_status.each do |status, count|
|
14
|
+
- klass = (status.to_s == only) ? "btn-info" : ""
|
15
|
+
%a.btn.btn-default{href: "?only=#{status}", class: klass}
|
16
|
+
#{status} (#{count})
|
17
|
+
|
18
|
+
%table.table.table-striped.table-hover.table-condensed#jobs
|
19
|
+
%thead
|
20
|
+
%tr
|
21
|
+
%th ID
|
22
|
+
%th label
|
23
|
+
%th source
|
24
|
+
%th <=>
|
25
|
+
%th target
|
26
|
+
%th date
|
27
|
+
%th{width: 220} status
|
28
|
+
%th{width: 150} error
|
29
|
+
%th.text-right size
|
30
|
+
%th.text-right bitrate
|
31
|
+
%th info
|
32
|
+
|
33
|
+
- if true
|
34
|
+
%tbody.current
|
35
|
+
= render :dashboard_table, {jobs: jobs}
|
@@ -0,0 +1,84 @@
|
|
1
|
+
- jobs.each do |job|
|
2
|
+
- size = job.get :transfer_total
|
3
|
+
- sent = job.get :transfer_sent
|
4
|
+
- progress = job.get :progress
|
5
|
+
- source_count = job.get(:source_count) || 0
|
6
|
+
- source_processed = job.get(:source_processed) || 0
|
7
|
+
- source_current = job.get(:source_current)
|
8
|
+
- presented = present job, :with => RestFtpDaemon::API::Entities::JobPresenter, hide_params: true
|
9
|
+
- errmsg = job.get :error_message
|
10
|
+
- method = job.get(:target_method)
|
11
|
+
|
12
|
+
- if !job.error.nil?
|
13
|
+
- trclass = "danger"
|
14
|
+
- elsif job.status == JOB_STATUS_UPLOADING
|
15
|
+
- trclass = "info"
|
16
|
+
- elsif job.status == JOB_STATUS_FINISHED
|
17
|
+
- trclass = "success"
|
18
|
+
- elsif job.status == JOB_STATUS_QUEUED
|
19
|
+
- trclass = "active"
|
20
|
+
- else
|
21
|
+
- trclass = "warning"
|
22
|
+
|
23
|
+
%tr{class: trclass}
|
24
|
+
|
25
|
+
%td{title: presented.to_json}
|
26
|
+
%b= job.id
|
27
|
+
|
28
|
+
%td= job.label
|
29
|
+
|
30
|
+
%td{title: job.get(:source_path)}
|
31
|
+
= Helpers.highlight_tokens job.source
|
32
|
+
|
33
|
+
%td
|
34
|
+
= Helpers.job_method_label method
|
35
|
+
|
36
|
+
%td{title: job.get(:target_url)}
|
37
|
+
= Helpers.highlight_tokens job.target
|
38
|
+
|
39
|
+
%td
|
40
|
+
= Helpers.datetime_short(job.queued_at)
|
41
|
+
|
42
|
+
%td
|
43
|
+
%span.push-status
|
44
|
+
= job.status
|
45
|
+
|
46
|
+
- if (job.status != JOB_STATUS_FINISHED) && (source_processed < source_count)
|
47
|
+
= " (#{source_processed}/#{source_count})"
|
48
|
+
|
49
|
+
- if job.status == JOB_STATUS_UPLOADING
|
50
|
+
|
51
|
+
- unless progress.nil?
|
52
|
+
%span.push-progress
|
53
|
+
= "#{progress}%"
|
54
|
+
|
55
|
+
%br
|
56
|
+
%b
|
57
|
+
%span.push-filename
|
58
|
+
= source_current unless source_current.nil?
|
59
|
+
|
60
|
+
%td
|
61
|
+
- unless job.error || job.status == JOB_STATUS_FINISHED
|
62
|
+
.progress
|
63
|
+
.progress-bar{style:"width: #{progress}%;"}
|
64
|
+
=# "#{progress}%" unless progress.nil?
|
65
|
+
= Helpers.format_bytes(sent, "B")
|
66
|
+
|
67
|
+
- else
|
68
|
+
.error{title: errmsg}
|
69
|
+
= Helpers.text_or_empty(job.error)
|
70
|
+
|
71
|
+
%td.nobr.text-right
|
72
|
+
= Helpers.format_bytes(size, "B")
|
73
|
+
|
74
|
+
%td.nobr.text-right
|
75
|
+
- if (bitrate = job.get :transfer_bitrate)
|
76
|
+
%span.push-bitrate
|
77
|
+
= Helpers.format_bytes(bitrate, "bps")
|
78
|
+
|
79
|
+
%td
|
80
|
+
- unless job.priority.nil?
|
81
|
+
.label.label-info.flag.worker-label= job.priority
|
82
|
+
|
83
|
+
- unless job.wid.nil?
|
84
|
+
.label.label-warning.flag.worker-label= job.wid
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-ftp-daemon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.202'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno MEDICI
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-03-
|
11
|
+
date: 2015-03-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -203,7 +203,6 @@ files:
|
|
203
203
|
- lib/rest-ftp-daemon/api/root.rb
|
204
204
|
- lib/rest-ftp-daemon/api/routes.rb
|
205
205
|
- lib/rest-ftp-daemon/api/status.rb
|
206
|
-
- lib/rest-ftp-daemon/config.rb
|
207
206
|
- lib/rest-ftp-daemon/constants.rb
|
208
207
|
- lib/rest-ftp-daemon/exceptions.rb
|
209
208
|
- lib/rest-ftp-daemon/helpers.rb
|
@@ -212,6 +211,7 @@ files:
|
|
212
211
|
- lib/rest-ftp-daemon/logger.rb
|
213
212
|
- lib/rest-ftp-daemon/logger_pool.rb
|
214
213
|
- lib/rest-ftp-daemon/notification.rb
|
214
|
+
- lib/rest-ftp-daemon/settings.rb
|
215
215
|
- lib/rest-ftp-daemon/static/css/bootstrap.css
|
216
216
|
- lib/rest-ftp-daemon/static/css/main.css
|
217
217
|
- lib/rest-ftp-daemon/uri.rb
|
@@ -219,6 +219,7 @@ files:
|
|
219
219
|
- lib/rest-ftp-daemon/views/dashboard_counters.haml
|
220
220
|
- lib/rest-ftp-daemon/views/dashboard_headers.haml
|
221
221
|
- lib/rest-ftp-daemon/views/dashboard_jobs.haml
|
222
|
+
- lib/rest-ftp-daemon/views/dashboard_table.haml
|
222
223
|
- lib/rest-ftp-daemon/views/dashboard_tokens.haml
|
223
224
|
- lib/rest-ftp-daemon/views/dashboard_workers.haml
|
224
225
|
- lib/rest-ftp-daemon/worker_pool.rb
|