rest-ftp-daemon 0.410.2 → 0.410.4
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/lib/rest-ftp-daemon/api/jobs.rb +2 -2
- data/lib/rest-ftp-daemon/exceptions.rb +1 -0
- data/lib/rest-ftp-daemon/helpers/common.rb +1 -7
- data/lib/rest-ftp-daemon/helpers/views.rb +2 -4
- data/lib/rest-ftp-daemon/job.rb +43 -65
- data/lib/rest-ftp-daemon/jobs/dummy.rb +7 -7
- data/lib/rest-ftp-daemon/jobs/errors.rb +52 -0
- data/lib/rest-ftp-daemon/jobs/transfer.rb +13 -79
- data/lib/rest-ftp-daemon/jobs/video.rb +23 -19
- data/lib/rest-ftp-daemon/location.rb +19 -2
- data/lib/rest-ftp-daemon/notification.rb +3 -3
- data/lib/rest-ftp-daemon/remote_ftp.rb +3 -3
- data/lib/rest-ftp-daemon/remote_sftp.rb +5 -5
- data/lib/rest-ftp-daemon/views/dashboard_jobs.haml +2 -2
- data/lib/rest-ftp-daemon.rb +18 -5
- data/rest-ftp-daemon.gemspec +1 -1
- metadata +2 -2
- data/lib/rest-ftp-daemon/path.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: be7b4ae68db6b95a7bc9752ad7ebbbd08dbaf826
|
4
|
+
data.tar.gz: 45f205479d718def98f02d90bb2d6f42021106c5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2edcf302d49057d7fd0b443d340b273264d785232ab4df259e51fb3877a70f8fde480abe5aaf3e7282b79e59c3dd0edf77f679a3268e3f6e2467259270acafb7
|
7
|
+
data.tar.gz: 43decf57d56dba500de038195f609877cb67eb920427d48adf57a870d9bf15d42ce984f3e1814a1dceb66254fe0eb88837f446e404ffdffe813bd73475c8cb36
|
data/Gemfile.lock
CHANGED
@@ -76,11 +76,11 @@ module RestFtpDaemon
|
|
76
76
|
optional :video_vc,
|
77
77
|
type: String,
|
78
78
|
desc: "video: video codec",
|
79
|
-
default:
|
79
|
+
default: nil
|
80
80
|
optional :video_ac,
|
81
81
|
type: String,
|
82
82
|
desc: "video: audio codec",
|
83
|
-
default:
|
83
|
+
default: nil
|
84
84
|
optional :video_custom,
|
85
85
|
type: Hash,
|
86
86
|
desc: "video: custom options passed to FFMPEG encoder",
|
@@ -17,6 +17,7 @@ module RestFtpDaemon
|
|
17
17
|
class UnresolvedTokens < RestFtpDaemonException; end
|
18
18
|
class LocationParseError < RestFtpDaemonException; end
|
19
19
|
class UnsupportedScheme < RestFtpDaemonException; end
|
20
|
+
class MissingFfmpegLibraries < RestFtpDaemonException; end
|
20
21
|
|
21
22
|
class SourceNotSupported < RestFtpDaemonException; end
|
22
23
|
class SourceNotFound < RestFtpDaemonException; end
|
@@ -30,14 +30,8 @@ module RestFtpDaemon
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def exception_to_error exception
|
33
|
-
underscore exception.class.name.split('::').last
|
33
|
+
underscore 'err_' + exception.class.name.split('::').last
|
34
34
|
end
|
35
35
|
|
36
|
-
# Dates and times: date with time generator
|
37
|
-
# def datetime_full datetime
|
38
|
-
# return "-" if datetime.nil?
|
39
|
-
# datetime.to_datetime.strftime("%d.%m.%Y %H:%M:%S")
|
40
|
-
# end
|
41
|
-
|
42
36
|
end
|
43
37
|
end
|
@@ -33,12 +33,10 @@ module RestFtpDaemon
|
|
33
33
|
def location_style uri
|
34
34
|
case uri
|
35
35
|
when URI::FILE
|
36
|
-
"
|
36
|
+
"info"
|
37
37
|
when URI::FTP
|
38
38
|
"warning"
|
39
|
-
when URI::FTPS
|
40
|
-
"success"
|
41
|
-
when URI::SFTP
|
39
|
+
when URI::FTPES, URI::FTPS, URI::SFTP
|
42
40
|
"success"
|
43
41
|
else
|
44
42
|
"default"
|
data/lib/rest-ftp-daemon/job.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# FIXME: prepare files list ar prepare_common
|
2
2
|
# FIXME: scope classes in submodules like Worker::Transfer, Job::Video
|
3
|
+
# FIXME: restore HostKeyMismatch and other NEt::SFTP exceptions
|
3
4
|
|
4
5
|
# Represents work to be done along with parameters to process it
|
5
6
|
require "securerandom"
|
@@ -16,7 +17,7 @@ module RestFtpDaemon
|
|
16
17
|
# Class constants
|
17
18
|
FIELDS = [:type, :source, :target, :label, :priority, :pool, :notify,
|
18
19
|
:overwrite, :mkdir, :tempfile,
|
19
|
-
:video_vc, :video_ac, :video_custom
|
20
|
+
:video_vc, :video_ac, :video_custom,
|
20
21
|
]
|
21
22
|
|
22
23
|
# Class options
|
@@ -119,54 +120,31 @@ module RestFtpDaemon
|
|
119
120
|
|
120
121
|
# Notify we start working
|
121
122
|
log_info "Job.process notify [started]"
|
123
|
+
current_signal = :started
|
124
|
+
set_status JOB_STATUS_WORKING
|
122
125
|
client_notify :started
|
123
126
|
|
124
127
|
# Before work
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
rescue RestFtpDaemon::SourceNotSupported => exception
|
129
|
-
return oops :started, exception
|
130
|
-
rescue Net::FTPConnectionError => exception
|
131
|
-
return oops :started, exception, "ftp_connection_error"
|
132
|
-
rescue StandardError => exception
|
133
|
-
return oops :started, exception, "unexpected_before_error"
|
134
|
-
end
|
128
|
+
log_debug "Job.process do_before"
|
129
|
+
current_signal = :started
|
130
|
+
do_before
|
135
131
|
|
136
132
|
# Do the hard work
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
work
|
141
|
-
|
142
|
-
rescue RestFtpDaemon::SourceNotFound => exception
|
143
|
-
return oops :ended, exception
|
144
|
-
|
145
|
-
rescue RestFtpDaemon::TargetFileExists => exception
|
146
|
-
return oops :ended, exception
|
147
|
-
|
148
|
-
rescue RestFtpDaemon::TargetDirectoryError => exception
|
149
|
-
return oops :ended, exception
|
150
|
-
|
151
|
-
rescue RestFtpDaemon::TargetPermissionError => exception
|
152
|
-
return oops :ended, exception
|
153
|
-
|
154
|
-
rescue RestFtpDaemon::AssertionFailed => exception
|
155
|
-
return oops :ended, exception
|
156
|
-
|
157
|
-
rescue StandardError => exception
|
158
|
-
return oops :started, exception, "unexpected_work_error"
|
159
|
-
end
|
133
|
+
log_debug "Job.process do_work"
|
134
|
+
current_signal = :ended
|
135
|
+
do_work
|
160
136
|
|
161
137
|
# Finalize all this
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
138
|
+
log_debug "Job.process do_after"
|
139
|
+
current_signal = :ended
|
140
|
+
do_after
|
141
|
+
|
142
|
+
rescue StandardError => exception
|
143
|
+
log_debug "Job.process caught #{exception.class} #{exception.message}"
|
144
|
+
return oops current_signal, exception
|
168
145
|
|
169
|
-
|
146
|
+
else
|
147
|
+
# All done !
|
170
148
|
set_status JOB_STATUS_FINISHED
|
171
149
|
log_info "JobVideo.process notify [ended]"
|
172
150
|
client_notify :ended
|
@@ -268,14 +246,6 @@ module RestFtpDaemon
|
|
268
246
|
[@wid, @id, nil]
|
269
247
|
end
|
270
248
|
|
271
|
-
def scan_local_paths path
|
272
|
-
Dir.glob(path).collect do |file|
|
273
|
-
next unless File.readable? file
|
274
|
-
next unless File.file? file
|
275
|
-
Path.new file
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
249
|
def touch_job
|
280
250
|
now = Time.now
|
281
251
|
@updated_at = now
|
@@ -317,38 +287,46 @@ module RestFtpDaemon
|
|
317
287
|
value.to_s.encode("UTF-8")
|
318
288
|
end
|
319
289
|
|
320
|
-
def flag_prepare name
|
290
|
+
def flag_prepare name
|
321
291
|
# build the flag instance var name
|
322
292
|
variable = "@#{name}"
|
323
293
|
|
324
|
-
|
325
|
-
|
326
|
-
return if [true, false].include? instance_variable_get(variable)
|
294
|
+
# If it's already true or false, that's ok
|
295
|
+
return if [true, false].include? instance_variable_get(variable)
|
327
296
|
|
328
|
-
|
329
|
-
|
330
|
-
end
|
297
|
+
# Otherwise, set it to the new alt_value
|
298
|
+
instance_variable_set variable, config[name]
|
331
299
|
end
|
332
300
|
|
333
|
-
def client_notify
|
301
|
+
def client_notify signal, payload = {}
|
334
302
|
# Skip if no URL given
|
335
303
|
return unless @notify
|
336
304
|
|
337
305
|
# Ok, create a notification!
|
338
306
|
payload[:id] = @id
|
339
|
-
payload[:
|
307
|
+
payload[:signal] = signal
|
340
308
|
RestFtpDaemon::Notification.new @notify, payload
|
341
309
|
|
342
310
|
rescue StandardError => ex
|
343
311
|
log_error "Job.client_notify EXCEPTION: #{ex.inspect}"
|
344
312
|
end
|
345
313
|
|
346
|
-
def oops
|
347
|
-
#
|
348
|
-
|
349
|
-
|
314
|
+
def oops signal, exception, error = nil#, include_backtrace = false
|
315
|
+
# Find error code in ERRORS table
|
316
|
+
if error.nil?
|
317
|
+
error = ERRORS.key(exception.class)
|
318
|
+
# log_debug "Job.oops ERRORS: #{exception.class} > #{error}"
|
319
|
+
end
|
320
|
+
|
321
|
+
# Default error code derived from exception name
|
322
|
+
if error.nil?
|
323
|
+
error = exception_to_error(exception)
|
324
|
+
# log_debug "Job.oops derivated: #{exception.class} > #{error}"
|
325
|
+
include_backtrace = true
|
326
|
+
end
|
350
327
|
|
351
|
-
#
|
328
|
+
# Log backtrace ?
|
329
|
+
message = "Job.oops signal[#{signal}] exception[#{exception.class}] error[#{error}] #{exception.message}"
|
352
330
|
if include_backtrace
|
353
331
|
log_error message, exception.backtrace
|
354
332
|
else
|
@@ -378,8 +356,8 @@ module RestFtpDaemon
|
|
378
356
|
RestFtpDaemon::Counters.instance.increment :jobs, :failed
|
379
357
|
|
380
358
|
# Prepare notification if signal given
|
381
|
-
return unless
|
382
|
-
client_notify
|
359
|
+
return unless signal
|
360
|
+
client_notify signal, error: error, status: notif_status, message: "#{exception.class} | #{exception.message}"
|
383
361
|
end
|
384
362
|
|
385
363
|
# NewRelic instrumentation
|
@@ -1,19 +1,19 @@
|
|
1
1
|
module RestFtpDaemon
|
2
2
|
class JobDummy < Job
|
3
3
|
|
4
|
-
|
5
|
-
# super
|
6
|
-
# end
|
4
|
+
protected
|
7
5
|
|
8
|
-
def
|
6
|
+
def do_before
|
7
|
+
log_info "JobDummy.do_before"
|
9
8
|
end
|
10
9
|
|
11
|
-
def
|
12
|
-
log_info "JobDummy.
|
10
|
+
def do_work
|
11
|
+
log_info "JobDummy.do_work"
|
13
12
|
sleep 5
|
14
13
|
end
|
15
14
|
|
16
|
-
def
|
15
|
+
def do_after
|
16
|
+
log_info "JobDummy.do_after"
|
17
17
|
end
|
18
18
|
|
19
19
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require "securerandom"
|
2
|
+
require "double_bag_ftps"
|
3
|
+
require "net/ssh"
|
4
|
+
require "net/ftp"
|
5
|
+
require "net/sftp"
|
6
|
+
require 'streamio-ffmpeg'
|
7
|
+
|
8
|
+
module RestFtpDaemon
|
9
|
+
class Job
|
10
|
+
|
11
|
+
# Common errors
|
12
|
+
ERRORS = {
|
13
|
+
invalid_argument: Errno::EINVAL,
|
14
|
+
|
15
|
+
source_not_supported: RestFtpDaemon::SourceNotSupported,
|
16
|
+
source_not_found: RestFtpDaemon::SourceNotFound,
|
17
|
+
target_file_exists: RestFtpDaemon::TargetFileExists,
|
18
|
+
target_directory_error: RestFtpDaemon::TargetDirectoryError,
|
19
|
+
target_permission_error: RestFtpDaemon::TargetPermissionError,
|
20
|
+
assertion_failed: RestFtpDaemon::AssertionFailed,
|
21
|
+
|
22
|
+
conn_socket_error: SocketError,
|
23
|
+
conn_eof: EOFError,
|
24
|
+
conn_failed: Errno::ENOTCONN,
|
25
|
+
conn_host_is_down: Errno::EHOSTDOWN,
|
26
|
+
conn_broken_pipe: Errno::EPIPE,
|
27
|
+
conn_unreachable: Errno::ENETUNREACH,
|
28
|
+
conn_reset_by_peer: Errno::ECONNRESET,
|
29
|
+
conn_refused: Errno::ECONNREFUSED,
|
30
|
+
conn_timed_out_1: Timeout::Error,
|
31
|
+
conn_timed_out_2: Net::ReadTimeout,
|
32
|
+
conn_timed_out_3: Errno::ETIMEDOUT,
|
33
|
+
|
34
|
+
ftp_connection_error: Net::FTPConnectionError,
|
35
|
+
ftp_perm_error: Net::FTPPermError,
|
36
|
+
ftp_reply_error: Net::FTPReplyError,
|
37
|
+
ftp_temp_error: Net::FTPTempError,
|
38
|
+
ftp_proto_error: Net::FTPProtoError,
|
39
|
+
ftp_error: Net::FTPError,
|
40
|
+
|
41
|
+
ffmpeg_error: FFMPEG::Error,
|
42
|
+
|
43
|
+
# sftp_exception: Net::SFTP::StatusException,
|
44
|
+
# sftp_key_mismatch: Net::SFTP::HostKeyMismatch,
|
45
|
+
# sftp_auth_failed: Net::SFTP::AuthenticationFailed,
|
46
|
+
sftp_openssl_error: OpenSSL::SSL::SSLError,
|
47
|
+
# rescue Encoding::UndefinedConversionError => exception
|
48
|
+
# return oops :ended, exception, "encoding_error", true
|
49
|
+
}
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -5,11 +5,11 @@ module RestFtpDaemon
|
|
5
5
|
|
6
6
|
protected
|
7
7
|
|
8
|
-
def
|
8
|
+
def do_before
|
9
9
|
# Prepare flags
|
10
|
-
flag_prepare :mkdir
|
11
|
-
flag_prepare :overwrite
|
12
|
-
flag_prepare :tempfile
|
10
|
+
flag_prepare :mkdir
|
11
|
+
flag_prepare :overwrite
|
12
|
+
flag_prepare :tempfile
|
13
13
|
|
14
14
|
# Some init
|
15
15
|
@transfer_sent = 0
|
@@ -35,20 +35,18 @@ module RestFtpDaemon
|
|
35
35
|
raise RestFtpDaemon::TargetNotSupported, @target_loc.scheme
|
36
36
|
end
|
37
37
|
|
38
|
-
rescue RestFtpDaemon::AssertionFailed => exception
|
39
|
-
return oops :started, exception
|
40
|
-
|
41
38
|
# rescue URI::InvalidURIError => exception
|
42
39
|
# return oops :started, exception, "target_invalid"
|
43
40
|
end
|
44
41
|
|
45
|
-
def
|
42
|
+
def do_work
|
46
43
|
# Scan local source files from disk
|
47
44
|
set_status JOB_STATUS_CHECKING_SRC
|
48
|
-
sources =
|
49
|
-
|
50
|
-
set_info :source, :
|
51
|
-
|
45
|
+
sources = @source_loc.scan_files
|
46
|
+
log_debug "JobTransfer.work sources result #{sources.inspect}"
|
47
|
+
set_info :source, :count, sources.size
|
48
|
+
set_info :source, :files, sources.collect(&:name)
|
49
|
+
log_info "JobTransfer.work sources names #{sources.collect(&:name)}"
|
52
50
|
raise RestFtpDaemon::SourceNotFound if sources.empty?
|
53
51
|
|
54
52
|
# Guess target file name, and fail if present while we matched multiple sources
|
@@ -78,7 +76,7 @@ module RestFtpDaemon
|
|
78
76
|
target_final = @target_loc.clone
|
79
77
|
|
80
78
|
# Add the source file name if none found in the target path
|
81
|
-
unless
|
79
|
+
unless target_final.name
|
82
80
|
target_final.name = source.name
|
83
81
|
end
|
84
82
|
|
@@ -92,71 +90,9 @@ module RestFtpDaemon
|
|
92
90
|
# Update counters
|
93
91
|
set_info :source, :processed, source_processed += 1
|
94
92
|
end
|
95
|
-
|
96
|
-
rescue SocketError => exception
|
97
|
-
return oops :ended, exception, "conn_socket_error"
|
98
|
-
|
99
|
-
rescue EOFError => exception
|
100
|
-
return oops :ended, exception, "conn_eof"
|
101
|
-
|
102
|
-
rescue Errno::EHOSTDOWN => exception
|
103
|
-
return oops :ended, exception, "conn_host_is_down"
|
104
|
-
|
105
|
-
rescue Errno::EPIPE=> exception
|
106
|
-
return oops :ended, exception, "conn_broken_pipe"
|
107
|
-
|
108
|
-
rescue Errno::ENETUNREACH => exception
|
109
|
-
return oops :ended, exception, "conn_unreachable"
|
110
|
-
|
111
|
-
rescue Errno::ECONNRESET => exception
|
112
|
-
return oops :ended, exception, "conn_reset_by_peer"
|
113
|
-
|
114
|
-
rescue Errno::ENOTCONN => exception
|
115
|
-
return oops :ended, exception, "conn_failed"
|
116
|
-
|
117
|
-
rescue Errno::ECONNREFUSED => exception
|
118
|
-
return oops :ended, exception, "conn_refused"
|
119
|
-
|
120
|
-
rescue Timeout::Error, Errno::ETIMEDOUT, Net::ReadTimeout => exception
|
121
|
-
return oops :ended, exception, "conn_timed_out"
|
122
|
-
|
123
|
-
rescue OpenSSL::SSL::SSLError => exception
|
124
|
-
return oops :ended, exception, "conn_openssl_error"
|
125
|
-
|
126
|
-
rescue Net::FTPReplyError => exception
|
127
|
-
return oops :ended, exception, "ftp_reply_error"
|
128
|
-
|
129
|
-
rescue Net::FTPTempError => exception
|
130
|
-
return oops :ended, exception, "ftp_temp_error"
|
131
|
-
|
132
|
-
rescue Net::FTPPermError => exception
|
133
|
-
return oops :ended, exception, "ftp_perm_error"
|
134
|
-
|
135
|
-
rescue Net::FTPProtoError => exception
|
136
|
-
return oops :ended, exception, "ftp_proto_error"
|
137
|
-
|
138
|
-
rescue Net::FTPError => exception
|
139
|
-
return oops :ended, exception, "ftp_error"
|
140
|
-
|
141
|
-
rescue Net::SFTP::StatusException => exception
|
142
|
-
return oops :ended, exception, "sftp_exception"
|
143
|
-
|
144
|
-
rescue Net::SSH::HostKeyMismatch => exception
|
145
|
-
return oops :ended, exception, "sftp_key_mismatch"
|
146
|
-
|
147
|
-
rescue Net::SSH::AuthenticationFailed => exception
|
148
|
-
return oops :ended, exception, "sftp_auth_failed"
|
149
|
-
|
150
|
-
rescue Errno::EMFILE => exception
|
151
|
-
return oops :ended, exception, "too_many_open_files"
|
152
|
-
|
153
|
-
rescue Errno::EINVAL => exception
|
154
|
-
return oops :ended, exception, "invalid_argument", true
|
155
|
-
# rescue Encoding::UndefinedConversionError => exception
|
156
|
-
# return oops :ended, exception, "encoding_error", true
|
157
93
|
end
|
158
94
|
|
159
|
-
def
|
95
|
+
def do_after
|
160
96
|
# Close FTP connexion and free up memory
|
161
97
|
log_info "JobTransfer.after"
|
162
98
|
@remote.close
|
@@ -180,7 +116,7 @@ module RestFtpDaemon
|
|
180
116
|
raise RestFtpDaemon::AssertionFailed, "remote_push/target" if target.nil?
|
181
117
|
|
182
118
|
# Use source filename if target path provided none (typically with multiple sources)
|
183
|
-
log_info "JobTransfer.remote_push [#{source.name}]: [#{source.
|
119
|
+
log_info "JobTransfer.remote_push [#{source.name}]: [#{source.path}] > [#{target.path}]"
|
184
120
|
set_info :source, :current, source.name
|
185
121
|
|
186
122
|
# Compute temp target name
|
@@ -222,8 +158,6 @@ module RestFtpDaemon
|
|
222
158
|
end
|
223
159
|
|
224
160
|
def progress transferred, name = ""
|
225
|
-
|
226
|
-
|
227
161
|
# What's current time ?
|
228
162
|
now = Time.now
|
229
163
|
notify_after = @config[:notify_after]
|
@@ -8,20 +8,28 @@ require 'streamio-ffmpeg'
|
|
8
8
|
module RestFtpDaemon
|
9
9
|
class JobVideo < Job
|
10
10
|
|
11
|
+
protected
|
12
|
+
|
11
13
|
# Process job
|
12
|
-
def
|
14
|
+
def do_before
|
13
15
|
log_info "JobVideo.before source_loc.path: #{@source_loc.path}"
|
14
16
|
log_info "JobVideo.before target_loc.path: #{@target_loc.path}"
|
15
17
|
|
18
|
+
# Ensure FFMPEG lib is available
|
19
|
+
ffmpeg_binary_path = FFMPEG.ffmpeg_binary
|
20
|
+
unless ffmpeg_binary_path && File.exists?(ffmpeg_binary_path)
|
21
|
+
raise RestFtpDaemon::MissingFfmpegLibraries, ffmpeg_binary_path
|
22
|
+
end
|
23
|
+
|
16
24
|
# Ensure source and target are FILE
|
17
25
|
raise RestFtpDaemon::SourceNotSupported, @source_loc.scheme unless source_uri.is_a? URI::FILE
|
18
26
|
raise RestFtpDaemon::TargetNotSupported, @target.scheme unless target_uri.is_a? URI::FILE
|
19
27
|
end
|
20
28
|
|
21
|
-
def
|
29
|
+
def do_work
|
22
30
|
# Guess source files from disk
|
23
31
|
set_status JOB_STATUS_TRANSFORMING
|
24
|
-
sources =
|
32
|
+
sources = @source_loc.scan_files
|
25
33
|
raise RestFtpDaemon::SourceNotFound if sources.empty?
|
26
34
|
|
27
35
|
# Add the source file name if none found in the target path
|
@@ -35,39 +43,35 @@ module RestFtpDaemon
|
|
35
43
|
|
36
44
|
# Do the work, for each file
|
37
45
|
set_info :source, :current, @source_loc.name
|
38
|
-
|
46
|
+
ffmpeg_command @source_loc, target_final
|
39
47
|
|
40
48
|
# Done
|
41
49
|
set_info :source, :current, nil
|
42
|
-
|
43
|
-
rescue FFMPEG::Error => exception
|
44
|
-
return oops :ended, exception, "ffmpeg_error"
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
52
|
+
def do_after
|
48
53
|
# Done
|
49
54
|
set_info :source, :current, nil
|
50
55
|
end
|
51
56
|
|
52
|
-
|
53
|
-
|
54
|
-
def video_command source, target
|
55
|
-
log_info "JobVideo.video_command [#{source.name}]: [#{source.path}] > [#{target.path}]"
|
57
|
+
def ffmpeg_command source, target
|
56
58
|
set_info :source, :current, source.name
|
57
59
|
|
58
60
|
# Read info about source file
|
59
61
|
movie = FFMPEG::Movie.new(source.path)
|
60
62
|
|
61
63
|
# Build options
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
options = {}
|
65
|
+
options[:audio_codec] = @video_ac unless @video_ac.to_s.empty?
|
66
|
+
options[:video_codec] = @video_vc unless @video_vc.to_s.empty?
|
67
|
+
options[:custom] = @ffmpeg_custom_option_array if @ffmpeg_custom_option_array
|
68
|
+
set_info :work, :ffmpeg_options, options
|
69
|
+
|
70
|
+
# Announce contexte
|
71
|
+
log_info "JobVideo.ffmpeg_command [#{FFMPEG.ffmpeg_binary}] [#{source.name}] > [#{target.name}]", options
|
68
72
|
|
69
73
|
# Build command
|
70
|
-
movie.transcode(target.path,
|
74
|
+
movie.transcode(target.path, options) do |ffmpeg_progress|
|
71
75
|
set_info :work, :ffmpeg_progress, ffmpeg_progress
|
72
76
|
|
73
77
|
percent0 = (100.0 * ffmpeg_progress).round(0)
|
@@ -19,7 +19,8 @@ module RestFtpDaemon
|
|
19
19
|
def initialize path
|
20
20
|
#@logger = BmcDaemonLib::LoggerPool.instance.get :transfer
|
21
21
|
#log_debug "Location.initialize path[#{path}]"
|
22
|
-
|
22
|
+
# Strip spaces before/after, copying original "path" at the same time
|
23
|
+
location_uri = path.strip
|
23
24
|
|
24
25
|
# Replace tokens, fix scheme for local paths
|
25
26
|
resolve_tokens! location_uri
|
@@ -50,7 +51,23 @@ module RestFtpDaemon
|
|
50
51
|
end
|
51
52
|
|
52
53
|
def path
|
53
|
-
File.join
|
54
|
+
File.join(@dir.to_s, @name.to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
def scan_files
|
58
|
+
Dir.glob(path).collect do |file|
|
59
|
+
next unless File.readable? file
|
60
|
+
next unless File.file? file
|
61
|
+
# Create a new location object
|
62
|
+
self.class.new(file)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def size
|
67
|
+
return unless uri.is_a? URI::FILE
|
68
|
+
local_fil_path = path
|
69
|
+
return unless File.exist? local_fil_path
|
70
|
+
return File.size local_fil_path
|
54
71
|
end
|
55
72
|
|
56
73
|
private
|
@@ -41,15 +41,15 @@ module RestFtpDaemon
|
|
41
41
|
if @url.nil?
|
42
42
|
log_error "skipping (missing url)", params
|
43
43
|
return
|
44
|
-
elsif @params[:
|
45
|
-
log_error "skipping (missing
|
44
|
+
elsif @params[:signal].nil?
|
45
|
+
log_error "skipping (missing signal)", params
|
46
46
|
return
|
47
47
|
end
|
48
48
|
|
49
49
|
# Build body and extract job ID if provided
|
50
50
|
flags = {
|
51
51
|
id: @params[:id].to_s,
|
52
|
-
signal: "#{NOTIFY_PREFIX}.#{@params[:
|
52
|
+
signal: "#{NOTIFY_PREFIX}.#{@params[:signal]}",
|
53
53
|
error: @params[:error],
|
54
54
|
host: Conf.host.to_s,
|
55
55
|
}
|
@@ -36,7 +36,7 @@ module RestFtpDaemon
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def present? target
|
39
|
-
size = @ftp.size target.
|
39
|
+
size = @ftp.size target.path
|
40
40
|
log_debug "RemoteFTP.present? [#{target.name}]"
|
41
41
|
|
42
42
|
rescue Net::FTPPermError
|
@@ -47,7 +47,7 @@ module RestFtpDaemon
|
|
47
47
|
|
48
48
|
def remove! target
|
49
49
|
log_debug "RemoteFTP.remove! [#{target.name}]"
|
50
|
-
@ftp.delete target.
|
50
|
+
@ftp.delete target.path
|
51
51
|
rescue Net::FTPPermError
|
52
52
|
log_debug "#{LOG_INDENT}[#{target.name}] file not found"
|
53
53
|
else
|
@@ -97,7 +97,7 @@ module RestFtpDaemon
|
|
97
97
|
# Do the transfer
|
98
98
|
log_debug "RemoteFTP.push to [#{destination.name}]"
|
99
99
|
|
100
|
-
@ftp.putbinaryfile source.
|
100
|
+
@ftp.putbinaryfile source.path, target.name, @chunk_size do |data|
|
101
101
|
# Update job status after this block transfer
|
102
102
|
yield data.bytesize, destination.name
|
103
103
|
end
|
@@ -35,7 +35,7 @@ module RestFtpDaemon
|
|
35
35
|
|
36
36
|
def present? target
|
37
37
|
log_debug "RemoteSFTP.present? [#{target.name}]"
|
38
|
-
stat = @sftp.stat! target.
|
38
|
+
stat = @sftp.stat! target.path
|
39
39
|
|
40
40
|
rescue Net::SFTP::StatusException
|
41
41
|
return false
|
@@ -45,7 +45,7 @@ module RestFtpDaemon
|
|
45
45
|
|
46
46
|
def remove! target
|
47
47
|
log_debug "RemoteSFTP.remove! [#{target.name}]"
|
48
|
-
@sftp.remove target.
|
48
|
+
@sftp.remove target.path
|
49
49
|
|
50
50
|
rescue Net::SFTP::StatusException
|
51
51
|
log_debug "#{LOG_INDENT}[#{target.name}] file not found"
|
@@ -100,8 +100,8 @@ module RestFtpDaemon
|
|
100
100
|
destination.name = tempname if tempname
|
101
101
|
|
102
102
|
# Do the transfer
|
103
|
-
log_debug "RemoteSFTP.push [#{destination.
|
104
|
-
@sftp.upload! source.
|
103
|
+
log_debug "RemoteSFTP.push [#{destination.path}]"
|
104
|
+
@sftp.upload! source.path, destination.path do |event, _uploader, *args|
|
105
105
|
case event
|
106
106
|
when :open then
|
107
107
|
# args[0] : file metadata
|
@@ -129,7 +129,7 @@ module RestFtpDaemon
|
|
129
129
|
# Rename if needed
|
130
130
|
if tempname
|
131
131
|
log_debug "RemoteSFTP.push rename to\t[#{target.name}]"
|
132
|
-
@sftp.rename! destination.
|
132
|
+
@sftp.rename! destination.path, target.path, flags
|
133
133
|
end
|
134
134
|
|
135
135
|
# progress:
|
@@ -37,8 +37,8 @@
|
|
37
37
|
%th target
|
38
38
|
%th queued
|
39
39
|
%th.error status
|
40
|
-
%th{"min-width" => 120}
|
41
|
-
%th.text-right
|
40
|
+
%th{"min-width" => 120} detail
|
41
|
+
%th.text-right size
|
42
42
|
%th.text-right bitrate
|
43
43
|
%th{title: "Worker ID"} W
|
44
44
|
%th{title: "Priority"} P
|
data/lib/rest-ftp-daemon.rb
CHANGED
@@ -9,12 +9,10 @@ require "syslog"
|
|
9
9
|
require "thread"
|
10
10
|
require "newrelic_rpm"
|
11
11
|
|
12
|
-
|
13
12
|
# Shared libs / monkey-patching
|
14
13
|
require_relative "shared/patch_array"
|
15
14
|
require_relative "shared/patch_haml"
|
16
15
|
|
17
|
-
|
18
16
|
# Project's libs
|
19
17
|
require_relative "rest-ftp-daemon/constants"
|
20
18
|
require_relative "rest-ftp-daemon/exceptions"
|
@@ -27,28 +25,32 @@ require_relative "rest-ftp-daemon/uri"
|
|
27
25
|
require_relative "rest-ftp-daemon/job_queue"
|
28
26
|
require_relative "rest-ftp-daemon/counters"
|
29
27
|
require_relative "rest-ftp-daemon/notification"
|
30
|
-
|
31
|
-
require_relative "rest-ftp-daemon/path"
|
32
28
|
require_relative "rest-ftp-daemon/location"
|
33
29
|
|
30
|
+
# Remotes
|
34
31
|
require_relative "rest-ftp-daemon/remote"
|
35
32
|
require_relative "rest-ftp-daemon/remote_ftp"
|
36
33
|
require_relative "rest-ftp-daemon/remote_sftp"
|
37
34
|
|
35
|
+
# Jobs
|
38
36
|
require_relative "rest-ftp-daemon/job"
|
37
|
+
require_relative "rest-ftp-daemon/jobs/errors"
|
39
38
|
require_relative "rest-ftp-daemon/jobs/dummy"
|
40
39
|
require_relative "rest-ftp-daemon/jobs/transfer"
|
41
40
|
require_relative "rest-ftp-daemon/jobs/video"
|
42
41
|
|
43
42
|
require_relative "rest-ftp-daemon/worker_pool"
|
43
|
+
|
44
|
+
# Workers
|
45
|
+
# require_from :workers
|
44
46
|
require_relative "rest-ftp-daemon/workers/worker"
|
45
47
|
require_relative "rest-ftp-daemon/workers/conchita"
|
46
48
|
require_relative "rest-ftp-daemon/workers/reporter"
|
47
49
|
require_relative "rest-ftp-daemon/workers/transfer"
|
48
50
|
|
51
|
+
# API
|
49
52
|
require_relative "rest-ftp-daemon/api/entities/options"
|
50
53
|
require_relative "rest-ftp-daemon/api/entities/job"
|
51
|
-
|
52
54
|
require_relative "rest-ftp-daemon/api/jobs"
|
53
55
|
require_relative "rest-ftp-daemon/api/dashboard"
|
54
56
|
require_relative "rest-ftp-daemon/api/status"
|
@@ -56,3 +58,14 @@ require_relative "rest-ftp-daemon/api/config"
|
|
56
58
|
require_relative "rest-ftp-daemon/api/debug"
|
57
59
|
require_relative "rest-ftp-daemon/api/root"
|
58
60
|
|
61
|
+
# def require_from subdir
|
62
|
+
# path = sprintf(
|
63
|
+
# '%s/rest-ftp-daemon/%s/*.rb',
|
64
|
+
# File.dirname(__FILE__),
|
65
|
+
# subdir.to_s
|
66
|
+
# )
|
67
|
+
# Dir.glob(path).each do |file|
|
68
|
+
# puts "loading: #{file}"
|
69
|
+
# require_relative file
|
70
|
+
# end
|
71
|
+
# end
|
data/rest-ftp-daemon.gemspec
CHANGED
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.410.
|
4
|
+
version: 0.410.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno MEDICI
|
@@ -414,6 +414,7 @@ files:
|
|
414
414
|
- lib/rest-ftp-daemon/job.rb
|
415
415
|
- lib/rest-ftp-daemon/job_queue.rb
|
416
416
|
- lib/rest-ftp-daemon/jobs/dummy.rb
|
417
|
+
- lib/rest-ftp-daemon/jobs/errors.rb
|
417
418
|
- lib/rest-ftp-daemon/jobs/transfer.rb
|
418
419
|
- lib/rest-ftp-daemon/jobs/video.rb
|
419
420
|
- lib/rest-ftp-daemon/launcher.rb
|
@@ -421,7 +422,6 @@ files:
|
|
421
422
|
- lib/rest-ftp-daemon/metrics.rb
|
422
423
|
- lib/rest-ftp-daemon/notification.rb
|
423
424
|
- lib/rest-ftp-daemon/paginate.rb
|
424
|
-
- lib/rest-ftp-daemon/path.rb
|
425
425
|
- lib/rest-ftp-daemon/remote.rb
|
426
426
|
- lib/rest-ftp-daemon/remote_ftp.rb
|
427
427
|
- lib/rest-ftp-daemon/remote_sftp.rb
|
data/lib/rest-ftp-daemon/path.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
module RestFtpDaemon
|
2
|
-
class Path
|
3
|
-
|
4
|
-
# Class options
|
5
|
-
attr_accessor :name
|
6
|
-
attr_accessor :dir
|
7
|
-
|
8
|
-
def initialize full, strip_leading_slash = false
|
9
|
-
# Extract path parts
|
10
|
-
@name = extract_filename full.to_s
|
11
|
-
|
12
|
-
@dir = extract_dirname full.to_s
|
13
|
-
# puts "Path full.to_s: #{full.to_s}"
|
14
|
-
# puts "Path extract_dirname: #{@dir}"
|
15
|
-
|
16
|
-
# Remove leading slash if needed
|
17
|
-
strip_leading_slash_from_dir! if strip_leading_slash
|
18
|
-
end
|
19
|
-
|
20
|
-
def full
|
21
|
-
if @dir.nil? || @dir.empty?
|
22
|
-
return @name
|
23
|
-
else
|
24
|
-
return File.join @dir, @name
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def size
|
29
|
-
File.size full if File.exist? full
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def extract_filename path
|
35
|
-
# match everything that's after a slash at the end of the string
|
36
|
-
m = path.match(/\/?([^\/]+)$/)
|
37
|
-
return m[1].to_s unless m.nil?
|
38
|
-
end
|
39
|
-
|
40
|
-
def extract_dirname path
|
41
|
-
# match all the beginning of the string up to the last slash
|
42
|
-
m = path.match(/^(.*)\/[^\/]*$/)
|
43
|
-
return m[1].to_s unless m.nil?
|
44
|
-
end
|
45
|
-
|
46
|
-
def strip_leading_slash_from_dir!
|
47
|
-
@dir.to_s.gsub!(/^\//, '')
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
51
|
-
end
|