rest-ftp-daemon 0.410.2 → 0.410.4
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/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
|