rest-ftp-daemon 0.422.0 → 0.423.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b007f413aeb958a7261cf4b52ab1cc55e5090295
4
- data.tar.gz: a632d6c795c89047868b080308fdefc458887ed3
3
+ metadata.gz: ee5c41955196c0b319075e59701f5a4632239c7d
4
+ data.tar.gz: 7821497a1f9810b6c555e4f60c3c5e5ff5fa87c4
5
5
  SHA512:
6
- metadata.gz: 004961d712ba67aff69de7732f5d9bfb04ca66783860185670784498e400502704440e44b4c1368d4f652328ba3ad948f7ec8b37543536d4211c3674f5bd5e78
7
- data.tar.gz: 949d07757d921d4d6da41f5f67e7418de536d0e44c04673629b087585724105659e94709ab20178cf34166c017b83a7e265e7aee15391d18e910962ed37497b8
6
+ metadata.gz: 456fe58b0004eae8d1cca760dd19f9455ef6012c9352bcabcdb4e9431862c8e6a7ac673b5219b5769bbe780a05a6400f9aa694eb51813d8bbdc6b99855fbf072
7
+ data.tar.gz: 5aa70020d1461e97c256071281e616c6f10c297428d4111203fe624fb83c12ccc6d08c24109f3e311b3dd2035b44154601972788c4329573e792f3a1d687afd4
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source "http://rubygems.org"
2
2
 
3
3
  gemspec
4
- # gem 'bmc-daemon-lib', :path => '../bmc-daemon-lib'
4
+ gem 'bmc-daemon-lib', :path => '../bmc-daemon-lib'
data/Gemfile.lock CHANGED
@@ -1,7 +1,13 @@
1
+ PATH
2
+ remote: ../bmc-daemon-lib
3
+ specs:
4
+ bmc-daemon-lib (0.3.4)
5
+ chamber (~> 2.9)
6
+
1
7
  PATH
2
8
  remote: .
3
9
  specs:
4
- rest-ftp-daemon (0.422.0)
10
+ rest-ftp-daemon (0.423.0)
5
11
  activesupport (~> 4.2)
6
12
  api-auth
7
13
  aws-sdk-resources (~> 2)
@@ -47,8 +53,6 @@ GEM
47
53
  descendants_tracker (~> 0.0.4)
48
54
  ice_nine (~> 0.11.0)
49
55
  thread_safe (~> 0.3, >= 0.3.1)
50
- bmc-daemon-lib (0.3.4)
51
- chamber (~> 2.9)
52
56
  builder (3.2.2)
53
57
  chamber (2.9.1)
54
58
  hashie (~> 3.3)
@@ -144,7 +148,7 @@ GEM
144
148
  rspec-core (~> 3.5.0)
145
149
  rspec-expectations (~> 3.5.0)
146
150
  rspec-mocks (~> 3.5.0)
147
- rspec-core (3.5.2)
151
+ rspec-core (3.5.3)
148
152
  rspec-support (~> 3.5.0)
149
153
  rspec-expectations (3.5.0)
150
154
  diff-lcs (>= 1.2.0, < 2.0)
@@ -189,6 +193,7 @@ PLATFORMS
189
193
  ruby
190
194
 
191
195
  DEPENDENCIES
196
+ bmc-daemon-lib!
192
197
  bundler (~> 1.6)
193
198
  http
194
199
  pry
data/README.md CHANGED
@@ -353,7 +353,7 @@ Known bugs
353
353
 
354
354
  * As this project is based on Chamber, and it considers hyphens in filename as namespaces, the global /etc/rest-ftp-daemon.yml config file is not parsed (and thus, ignored). Until this is worked around, please specify a config filename on the commandline.
355
355
 
356
- * If you get ```fatal error: 'openssl/ssl.h' file not found when installing ```eventmachine``` on OSX El Capitan, you can try with:
356
+ * If you get ```fatal error: 'openssl/ssl.h' file not found when installing eventmachine``` on OSX El Capitan, you can try with:
357
357
  ```
358
358
  gem install eventmachine -v '1.0.8' -- --with-cppflags=-I/usr/local/opt/openssl/include
359
359
  bundle install
@@ -24,7 +24,7 @@ module RestFtpDaemon
24
24
  me[:error] = job.error.encoding.to_s unless job.error.nil?
25
25
  me[:status] = job.status.encoding.to_s unless job.status.nil?
26
26
 
27
- RestFtpDaemon::Job::FIELDS.each do |name|
27
+ RestFtpDaemon::Job::IMPORTED.each do |name|
28
28
  value = job.send(name)
29
29
  me[name] = value.encoding.to_s if value.is_a? String
30
30
  end
@@ -1,59 +1,57 @@
1
1
  require "grape-entity"
2
2
 
3
3
  module RestFtpDaemon
4
- module API
5
- module Entities
6
- class Job < Grape::Entity
4
+ module Entities
5
+ class Job < Grape::Entity
7
6
 
8
- # Job ID
9
- expose :id
10
-
11
- # Job specific attributes and flags
12
- RestFtpDaemon::Job::FIELDS.each { |name| expose name }
13
-
14
- # Technical fields
15
- expose :wid, unless: lambda { |object, _options| object.wid.nil? }
16
-
17
- # expose :error
18
- expose :json_error, as: :error
19
- expose :json_status, as: :status
20
- #expose :json_target, as: :target_method
7
+ # Some formatters
8
+ format_with(:utf8_filter) do |thing|
9
+ thing.to_s.encode("UTF-8") if thing
10
+ end
21
11
 
22
- expose :queued_at
23
- expose :updated_at
24
- expose :started_at
25
- expose :finished_at
12
+ # Job-execution related
13
+ expose :id
14
+ expose :wid, unless: lambda { |object, _options| object.wid.nil? }
26
15
 
27
- # Computed fields
28
- expose :age
29
- expose :exectime
16
+ # Attributes from API
17
+ RestFtpDaemon::Job::IMPORTED.each do |field|
18
+ expose field
19
+ end
30
20
 
31
- # Params
32
- expose :infos, unless: :hide_infos
21
+ # Work-specific options
22
+ expose :overwrite
23
+ expose :mkdir
24
+ expose :tempfile
25
+ expose :video_custom
33
26
 
34
- # Options
35
- # expose :options, using: API::Entities::Options
36
- # expose :video_ac
37
- # expose :video_custom
27
+ # Job/Video options
28
+ expose :video_options
29
+ #, using: Entities::VideoOptions
38
30
 
39
- # with_options(format_with: :iso_timestamp) do
40
- # expose :created_at
41
- # expose :updated_at
42
- # end
31
+ # Status and error
32
+ expose :status, format_with: :utf8_filter
33
+ expose :error, format_with: :utf8_filter
43
34
 
44
- # expose :age do
45
- # end
35
+ # Time stamps
36
+ expose :queued_at
37
+ expose :updated_at
38
+ expose :started_at
39
+ expose :finished_at
46
40
 
47
- # expose :slots do |station,options|
48
- # station.slots.map{ |slot| SlotEntity.new(slot).serializable_hash }
49
- # end
41
+ # Computed fields
42
+ expose :age #, safe: true
43
+ expose :exectime
50
44
 
51
- private
45
+ # Infos
46
+ expose :infos, unless: :hide_infos
52
47
 
53
- def priv_func
54
- end
48
+ # Source and target #, :unless => Proc.new {|g| g.source_loc.nil?}
49
+ expose :source_loc, using: Entities::Location#, as: :source
50
+ expose :target_loc, using: Entities::Location#, as: :target
55
51
 
56
- end
52
+ # expose :slots do |station,options|
53
+ # station.slots.map{ |slot| SlotEntity.new(slot).serializable_hash }
54
+ # end
57
55
  end
58
56
  end
59
57
  end
@@ -0,0 +1,25 @@
1
+ require "grape-entity"
2
+
3
+ module RestFtpDaemon
4
+ module Entities
5
+ class Location < Grape::Entity
6
+
7
+ expose :original, as: '_'
8
+ expose :uri
9
+ expose :scheme
10
+
11
+ expose :host, unless: Proc.new {|obj| obj.host.nil?}
12
+ expose :user, unless: Proc.new {|obj| obj.user.nil?}
13
+ expose :port, if: Proc.new {|obj| !obj.port.nil?}
14
+
15
+ expose :dir
16
+ expose :name
17
+ expose :path
18
+
19
+ expose :aws_region ,unless: Proc.new {|obj| obj.aws_region.nil?}
20
+ expose :aws_bucket, unless: Proc.new {|obj| obj.aws_bucket.nil?}
21
+ expose :aws_id, unless: Proc.new {|obj| obj.aws_id.nil?}
22
+
23
+ end
24
+ end
25
+ end
@@ -1,15 +1,13 @@
1
1
  require "grape-entity"
2
2
 
3
3
  module RestFtpDaemon
4
- module API
5
- module Entities
6
- class Options < Grape::Entity
4
+ module Entities
5
+ class Options < Grape::Entity
7
6
 
8
- # expose :opt1, documentation: { type: 'Boolean', desc: 'opt UN', required: false }
9
- expose :opt2
10
- # expose :opt6
7
+ # expose :opt1, documentation: { type: 'Boolean', desc: 'opt UN', required: false }
8
+ expose :opt2
9
+ # expose :opt6
11
10
 
12
- end
13
11
  end
14
12
  end
15
13
  end
@@ -33,7 +33,7 @@ module RestFtpDaemon
33
33
 
34
34
  else
35
35
  status 200
36
- present job, with: RestFtpDaemon::API::Entities::Job, type: "complete"
36
+ present job, with: RestFtpDaemon::Entities::Job, type: "complete"
37
37
 
38
38
  end
39
39
  end
@@ -53,7 +53,7 @@ module RestFtpDaemon
53
53
 
54
54
  else
55
55
  status 200
56
- present jobs, with: RestFtpDaemon::API::Entities::Job
56
+ present jobs, with: RestFtpDaemon::Entities::Job
57
57
 
58
58
  end
59
59
  end
@@ -63,30 +63,45 @@ module RestFtpDaemon
63
63
  requires :source, type: String, desc: "Source file pattern"
64
64
  requires :target, type: String, desc: "Target remote path"
65
65
 
66
- optional :label, type: String, desc: "Descriptive label for this job"
66
+ optional :label, type: String, desc: "Descriptive label (info only)"
67
67
  optional :notify, type: String, desc: "URL to get POST'ed notifications back"
68
- optional :priority, type: Integer, desc: "Priority level of the job (lower is stronger)"
69
- optional :pool, type: String, desc: "Pool of worker to be used"
70
68
  optional :type,
71
69
  type: String,
72
70
  desc: "Type of job",
73
71
  default: JOB_TYPE_TRANSFER,
74
72
  values: {value: JOB_TYPES, message: "should be one of: #{JOB_TYPES.join', '}"},
75
73
  allow_blank: { value: false, message: 'cannot be empty' }
76
-
77
- optional :video_vc,
78
- type: String,
79
- desc: "video: video codec",
80
- default: nil
81
- optional :video_ac,
74
+ optional :pool,
82
75
  type: String,
83
- desc: "video: audio codec",
84
- default: nil
76
+ desc: "Pool of worker to be used",
77
+ default: DEFAULT_POOL
78
+ optional :priority,
79
+ type: Integer,
80
+ desc: "Priority level of the job (lower is stronger)",
81
+ default: 0
82
+
83
+ # optional :video_options,
84
+ # type: Hash,
85
+ # type: Entities::VideoOptions,
86
+ # desc: "Video: standard options passed to FFMPEG encoder",
87
+ # default: {}
88
+
89
+ optional :video_options, type: Hash, desc: "Options passed to FFMPEG encoder" do
90
+ optional :video_codec, type: String
91
+ optional :video_bitrate, type: String
92
+ optional :video_bitrate_tolerance, type: String
93
+ optional :frame_rate, type: Integer
94
+ optional :resolution, type: String
95
+ optional :aspect, type: String
96
+ optional :keyframe_interval, type: String
97
+ optional :x264_vprofile, type: String
98
+ optional :x264_preset, type: String
99
+ optional :audio_codec, type: String
100
+ optional :audio_bitrate, type: String
101
+ optional :audio_sample_rate, type: Integer
102
+ optional :audio_channels, type: String
103
+ end
85
104
 
86
- optional :video_options,
87
- type: Hash,
88
- desc: "Video: standard options passed to FFMPEG encoder",
89
- default: {}
90
105
  optional :video_custom,
91
106
  type: Hash,
92
107
  desc: "video: custom options passed to FFMPEG encoder",
@@ -104,7 +119,6 @@ module RestFtpDaemon
104
119
  type: Boolean,
105
120
  desc: "Upload to a temp file before renaming it to the target filename",
106
121
  default: Conf.at(:transfer, :tempfile)
107
- # optional :options, desc: "Options passed to FFMPEG (video jobs)", type: API::Entities::Options
108
122
  end
109
123
 
110
124
  post "/" do
@@ -130,7 +144,7 @@ module RestFtpDaemon
130
144
 
131
145
  else
132
146
  status 201
133
- present job, with: RestFtpDaemon::API::Entities::Job, hide_params: true
147
+ present job, with: RestFtpDaemon::Entities::Job, hide_params: true
134
148
 
135
149
  end
136
150
  end
@@ -55,7 +55,7 @@ desc 'API Root'
55
55
  description: "API description for #{BmcDaemonLib::Conf.app_name} #{BmcDaemonLib::Conf.app_ver}",
56
56
  }
57
57
  # models: [
58
- # RestFtpDaemon::API::Entities::Job,
58
+ # RestFtpDaemon::Entities::Job,
59
59
  # ]
60
60
 
61
61
  ### GLOBAL EXCEPTION HANDLING
@@ -56,7 +56,7 @@ module RestFtpDaemon
56
56
 
57
57
  else
58
58
  status 200
59
- present jobs, with: RestFtpDaemon::API::Entities::Job
59
+ present jobs, with: RestFtpDaemon::Entities::Job
60
60
 
61
61
  end
62
62
  end
@@ -4,10 +4,8 @@ DEFAULT_SFTP_TIMEOUT = 600 # 10mn
4
4
  DEFAULT_FTP_CHUNK = 1024 # 1 MB
5
5
  DEFAULT_PAGE_SIZE = 50 # 50 lines
6
6
  DEFAULT_RETRY_AFTER = 10 # 10s
7
-
8
7
  TARGET_BLANK = "_blank"
9
8
 
10
-
11
9
  # Internal job constants
12
10
  JOB_RANDOM_LEN = 8
13
11
  JOB_IDENT_LEN = 4
@@ -17,9 +15,13 @@ JOB_UPDATE_INTERVAL = 1
17
15
  JOB_FFMPEG_THREADS = 2
18
16
  JOB_FFMPEG_ATTRIBUTES = [:video_codec, :video_bitrate, :video_bitrate_tolerance, :frame_rate, :resolution, :aspect, :keyframe_interval, :x264_vprofile, :x264_preset, :audio_codec, :audio_bitrate, :audio_sample_rate, :audio_channels]
19
17
 
18
+ # Internal job infos
19
+ INFO_PROGRESS = :work_progress
20
+ INFO_BITRATE = :transfer_bitrate
21
+
20
22
  # Constants: logger
21
23
  LOG_ROTATION = "daily"
22
- LOG_FORMAT_PROGNAME = "%d\t%s"
24
+ LOG_FORMAT_PROGNAME = "%d\t%s"
23
25
  LOG_HEADER_TIME = "%Y-%m-%d %H:%M:%S"
24
26
  LOG_HEADER_FORMAT = "%s \t%d\t%-8s %-10s "
25
27
  LOG_MESSAGE_TRIM = 200
@@ -14,15 +14,14 @@ module RestFtpDaemon
14
14
  attr_reader :logger
15
15
  include BmcDaemonLib::LoggerHelper
16
16
 
17
- # Class constants
18
- FIELDS = [:type, :source, :target, :label, :priority, :pool, :notify,
19
- :overwrite, :mkdir, :tempfile,
20
- :video_options, :video_custom
21
- ]
17
+ # Fields to be imported from params
18
+ IMPORTED = %w(type priority pool label priority source target overwrite mkdir tempfile video_options video_custom)
22
19
 
23
20
  # Class options
24
21
  attr_accessor :wid
25
- attr_accessor :type
22
+
23
+ attr_reader :source_loc
24
+ attr_reader :target_loc
26
25
 
27
26
  attr_reader :id
28
27
  attr_reader :error
@@ -35,12 +34,14 @@ module RestFtpDaemon
35
34
  attr_reader :finished_at
36
35
 
37
36
  attr_reader :infos
38
- attr_reader :pool
37
+ #attr_reader :config
39
38
 
40
- attr_accessor :config
39
+ # delegate :type, :pool, :label, :priority,
40
+ # to: :params
41
41
 
42
- FIELDS.each do |name|
43
- attr_reader name
42
+ # Define readers from imported fields
43
+ IMPORTED.each do |field|
44
+ attr_reader field
44
45
  end
45
46
 
46
47
  def initialize job_id = nil, params = {}
@@ -52,14 +53,14 @@ module RestFtpDaemon
52
53
  return if job_id.nil?
53
54
 
54
55
  # Init context
55
- @id = job_id.to_s
56
- #@updated_at = nil
57
- @started_at = nil
58
- @finished_at = nil
59
- @error = nil
60
- @status = nil
61
- @runs = 0
62
- @wid = nil
56
+ @id = job_id.to_s
57
+ @started_at = nil
58
+ @finished_at = nil
59
+ @updated_at = nil
60
+ @error = nil
61
+ @status = nil
62
+ @runs = 0
63
+ @wid = nil
63
64
 
64
65
  # Prepare configuration
65
66
  @config = Conf[:transfer] || {}
@@ -67,27 +68,33 @@ module RestFtpDaemon
67
68
  @pools = Conf[:pools] || {}
68
69
 
69
70
  # Logger
70
- @logger = BmcDaemonLib::LoggerPool.instance.get :transfer
71
+ @logger = BmcDaemonLib::LoggerPool.instance.get :transfer
71
72
 
72
73
  # Import query params
73
- FIELDS.each do |name|
74
- instance_variable_set "@#{name}", params[name]
74
+ set_info :params, params
75
+ IMPORTED.each do |field|
76
+ instance_variable_set "@#{field}", params[field]
75
77
  end
76
78
 
77
79
  # Check if pool name exists
78
- if (@pools.keys.include? params[:pool])
79
- @pool = params[:pool].to_s
80
- else
81
- @pool = DEFAULT_POOL
82
- end
80
+ @pool = DEFAULT_POOL unless @pools.keys.include?(@pool)
83
81
 
84
82
  # Prepare sources/target
85
- prepare_source
86
- prepare_target
83
+ raise RestFtpDaemon::AttributeMissing, "source" unless params[:source]
84
+ @source_loc = Location.new(params[:source])
85
+ #set_info :location_source, params[:source]
86
+ log_info "Job.initialize source #{@source_loc.uri}"
87
+
88
+ raise RestFtpDaemon::AttributeMissing, "target" unless params[:target]
89
+ @target_loc = Location.new(params[:target])
90
+ #set_info :location_target, params[:target]
91
+ log_info "Job.initialize target #{@target_loc.uri}"
87
92
 
88
93
  # Handle exceptions
89
- rescue RestFtpDaemon::UnsupportedScheme => exception
90
- return oops :started, exception
94
+ # rescue RestFtpDaemon::UnresolvedTokens => exception
95
+ # return oops :started, exception
96
+ # rescue RestFtpDaemon::UnsupportedScheme => exception
97
+ # return oops :started, exception
91
98
  end
92
99
 
93
100
  def reset
@@ -101,8 +108,6 @@ module RestFtpDaemon
101
108
  # Job has been prepared, reset infos
102
109
  set_status JOB_STATUS_PREPARED
103
110
  @infos = {}
104
- set_info_location :source, @source_loc
105
- set_info_location :target, @target_loc
106
111
 
107
112
  # Update job status, send first notification
108
113
  set_status JOB_STATUS_QUEUED
@@ -156,11 +161,11 @@ module RestFtpDaemon
156
161
  end
157
162
 
158
163
  def source_uri
159
- @source_loc.uri
164
+ @source_loc.uri if @source_loc
160
165
  end
161
166
 
162
167
  def target_uri
163
- @target_loc.uri
168
+ @target_loc.uri if @target_loc
164
169
  end
165
170
 
166
171
  def weight
@@ -190,41 +195,20 @@ module RestFtpDaemon
190
195
  end
191
196
 
192
197
  def targethost
193
- get_info :target, :host
194
- end
195
-
196
- # def json_target
197
- # utf8 get_info(:target, :method)
198
- # end
199
-
200
- def json_error
201
- utf8 @error unless @error.nil?
202
- end
203
-
204
- def json_status
205
- utf8 @status unless @status.nil?
198
+ @target_loc.host unless @target_loc.nil?
199
+ #get_info :target_host
206
200
  end
207
201
 
208
- def get_info level1, level2
202
+ def get_info name
209
203
  @mutex.synchronize do
210
- # @infos || {}
211
- @infos[level1][level2] if @infos[level1].is_a? Hash
204
+ @infos[name]
212
205
  end
213
206
  end
214
207
 
215
- def set_info level1, level2, value
208
+ def set_info name, value
216
209
  @mutex.synchronize do
217
210
  @infos || {}
218
- @infos[level1] ||= {}
219
-
220
- # Force strings to UTF8
221
- if value.is_a? Symbol
222
- @infos[level1][level2] = value.to_s.force_encoding(Encoding::UTF_8)
223
- elsif value.is_a? String
224
- @infos[level1][level2] = value.dup.force_encoding(Encoding::UTF_8)
225
- else
226
- @infos[level1][level2] = value
227
- end
211
+ @infos[name] = debug_value_utf8(value)
228
212
  end
229
213
  touch_job
230
214
  end
@@ -235,28 +219,6 @@ module RestFtpDaemon
235
219
  log_error "Job PLACEHOLDER METHOD CALLED"
236
220
  end
237
221
 
238
- def prepare_source
239
- raise RestFtpDaemon::AttributeMissing, "source" unless @source
240
- @source_loc = Location.new @source
241
- log_info "Job.prepare_source #{@source_loc.uri}"
242
- end
243
-
244
- def prepare_target
245
- raise RestFtpDaemon::AttributeMissing, "target" unless @target
246
- @target_loc = Location.new @target
247
- log_info "Job.prepare_target #{@target_loc.uri}"
248
- end
249
-
250
- def set_info_location prefix, location
251
- return unless location.is_a? Location
252
- fields = [:uri, :scheme, :user, :host, :port, :dir, :name, :path, :aws_region, :aws_bucket, :aws_id]
253
-
254
- # Add each field to @infos
255
- fields.each do |what|
256
- set_info prefix, "loc_#{what}".to_sym, location.send(what)
257
- end
258
- end
259
-
260
222
  private
261
223
 
262
224
  def log_prefix
@@ -269,6 +231,18 @@ module RestFtpDaemon
269
231
  Thread.current.thread_variable_set :updated_at, now
270
232
  end
271
233
 
234
+ # Force strings to UTF8
235
+ def debug_value_utf8 value
236
+ case value
237
+ when Symbol
238
+ return value.to_s.force_encoding(Encoding::UTF_8)
239
+ when String
240
+ return value.dup.force_encoding(Encoding::UTF_8) if value.is_a? String
241
+ else
242
+ return value
243
+ end
244
+ end
245
+
272
246
  def set_error value
273
247
  @mutex.synchronize do
274
248
  @error = value
@@ -283,10 +257,6 @@ module RestFtpDaemon
283
257
  touch_job
284
258
  end
285
259
 
286
- def utf8 value
287
- value.to_s.encode("UTF-8")
288
- end
289
-
290
260
  def flag_prepare name
291
261
  # build the flag instance var name
292
262
  variable = "@#{name}"
@@ -339,13 +309,13 @@ module RestFtpDaemon
339
309
  # Update job's internal status
340
310
  set_status JOB_STATUS_FAILED
341
311
  set_error error
342
- set_info :error, :exception, exception.class.to_s
343
- set_info :error, :message, exception.message
312
+ set_info :error_exception, exception.class.to_s
313
+ set_info :error_message, exception.message
344
314
 
345
315
  # Build status stack
346
316
  notif_status = nil
347
317
  if include_backtrace
348
- set_info :error, :backtrace, exception.backtrace
318
+ set_info :error_backtrace, exception.backtrace
349
319
  notif_status = {
350
320
  backtrace: exception.backtrace,
351
321
  }
@@ -102,10 +102,9 @@ module RestFtpDaemon
102
102
  next unless job.status == JOB_STATUS_UPLOADING
103
103
 
104
104
  # Extract current rate, next if not available
105
- rate = job.get_info :transfer, :bitrate
105
+ rate = job.get_info INFO_BITRATE
106
106
  next if rate.nil?
107
107
 
108
-
109
108
  # Add its current rate
110
109
  result[group] ||= 0
111
110
  result[group] += rate
@@ -13,7 +13,7 @@ module RestFtpDaemon
13
13
 
14
14
  # Some init
15
15
  @transfer_sent = 0
16
- set_info :source, :processed, 0
16
+ set_info :source_processed, 0
17
17
 
18
18
  # Ensure source is FILE
19
19
  raise RestFtpDaemon::SourceNotSupported, @source_loc.scheme unless @source_loc.is? URI::FILE
@@ -48,8 +48,8 @@ module RestFtpDaemon
48
48
  # Scan local source files from disk
49
49
  set_status JOB_STATUS_CHECKING_SRC
50
50
  sources = @source_loc.scan_files
51
- set_info :source, :count, sources.size
52
- set_info :source, :files, sources.collect(&:name)
51
+ set_info :source_count, sources.size
52
+ set_info :source_files, sources.collect(&:name)
53
53
  log_info "JobTransfer.work sources #{sources.collect(&:name)}"
54
54
  raise RestFtpDaemon::SourceNotFound if sources.empty?
55
55
 
@@ -66,7 +66,7 @@ module RestFtpDaemon
66
66
 
67
67
  # Compute total files size
68
68
  @transfer_total = sources.collect(&:size).sum
69
- set_info :work, :total, @transfer_total
69
+ set_info :transfer_total, @transfer_total
70
70
 
71
71
  # Reset counters
72
72
  @last_data = 0
@@ -85,10 +85,10 @@ module RestFtpDaemon
85
85
 
86
86
  # Add it to transferred target names
87
87
  targets << target.name
88
- set_info :target, :files, targets
88
+ set_info :target_files, targets
89
89
 
90
90
  # Update counters
91
- set_info :source, :processed, source_processed += 1
91
+ set_info :source_processed, source_processed += 1
92
92
  end
93
93
  end
94
94
 
@@ -116,7 +116,7 @@ module RestFtpDaemon
116
116
 
117
117
  # Use source filename if target path provided none (typically with multiple sources)
118
118
  log_info "JobTransfer.remote_upload [#{source.name}]: [#{source.path}] > [#{target.path}]"
119
- set_info :source, :current, source.name
119
+ set_info :source_current, source.name
120
120
 
121
121
  # Remove any existing version if present, or check if it's there
122
122
  if @overwrite
@@ -145,10 +145,10 @@ module RestFtpDaemon
145
145
 
146
146
  # Compute final bitrate
147
147
  global_transfer_bitrate = get_bitrate @transfer_total, (Time.now - transfer_started_at)
148
- set_info :work, :bitrate, global_transfer_bitrate.round(0)
148
+ set_info :transfer_bitrate, global_transfer_bitrate.round(0)
149
149
 
150
150
  # Done
151
- set_info :source, :current, nil
151
+ set_info :source_current, nil
152
152
  end
153
153
 
154
154
  def update_progress transferred, name = ""
@@ -158,17 +158,17 @@ module RestFtpDaemon
158
158
 
159
159
  # Update counters
160
160
  @transfer_sent += transferred
161
- set_info :work, :sent, @transfer_sent
161
+ set_info :work_sent, @transfer_sent
162
162
 
163
163
  # Update job info
164
164
  percent0 = (100.0 * @transfer_sent / @transfer_total).round(0)
165
- set_info :work, :progress, percent0
165
+ set_info INFO_PROGRESS, percent0
166
166
 
167
167
  # Update job status after each NOTIFY_UPADE_STATUS
168
168
  progressed_ago = (now.to_f - @progress_at.to_f)
169
169
  if (!JOB_UPDATE_INTERVAL.to_f.zero?) && (progressed_ago > JOB_UPDATE_INTERVAL.to_f)
170
170
  @current_bitrate = running_bitrate @transfer_sent
171
- set_info :work, :bitrate, @current_bitrate.round(0)
171
+ set_info :transfer_bitrate, @current_bitrate.round(0)
172
172
 
173
173
  # Log progress
174
174
  stack = []
@@ -42,29 +42,26 @@ module RestFtpDaemon
42
42
  FileUtils.mkdir_p @target_loc.dir
43
43
 
44
44
  # Do the work, for each file
45
- set_info :source, :current, @source_loc.name
45
+ set_info :source_current, @source_loc.name
46
46
  ffmpeg_command @source_loc, target_final
47
47
 
48
48
  # Done
49
- set_info :source, :current, nil
49
+ set_info :source_current, nil
50
50
  end
51
51
 
52
52
  def do_after
53
53
  # Done
54
- set_info :source, :current, nil
54
+ set_info :source_current, nil
55
55
  end
56
56
 
57
57
  def ffmpeg_command source, target
58
- set_info :source, :current, source.name
58
+ set_info :source_current, source.name
59
59
 
60
60
  # Read info about source file
61
61
  movie = FFMPEG::Movie.new(source.path)
62
- set_info :source, :ffmpeg_size, movie.size
63
- set_info :source, :ffmpeg_duration, movie.duration
64
- set_info :source, :ffmpeg_resolution, movie.resolution
65
-
66
-
67
-
62
+ set_info :ffmpeg_size, movie.size
63
+ set_info :ffmpeg_duration, movie.duration
64
+ set_info :ffmpeg_resolution, movie.resolution
68
65
 
69
66
  # Build options
70
67
  options = {
@@ -74,7 +71,7 @@ module RestFtpDaemon
74
71
  JOB_FFMPEG_ATTRIBUTES.each do |name|
75
72
  options[name] = @video_options[name] unless @video_options[name].nil?
76
73
  end
77
- set_info :work, :ffmpeg_options, options
74
+ set_info :work_ffmpeg_options, options
78
75
 
79
76
  # Announce context
80
77
  log_info "JobVideo.ffmpeg_command [#{FFMPEG.ffmpeg_binary}] [#{source.name}] > [#{target.name}]", options
@@ -82,7 +79,7 @@ module RestFtpDaemon
82
79
  # Build command
83
80
  movie.transcode(target.path, options) do |ffmpeg_progress|
84
81
  # set_info :work, :ffmpeg_progress, ffmpeg_progress
85
- set_info :work, :progress, (100.0 * ffmpeg_progress).round(1)
82
+ set_info INFO_PROGRESS, (100.0 * ffmpeg_progress).round(1)
86
83
  log_debug "progress #{ffmpeg_progress}"
87
84
  end
88
85
  end
@@ -8,6 +8,7 @@ module RestFtpDaemon
8
8
  # Accessors
9
9
  attr_accessor :name
10
10
 
11
+ attr_reader :original
11
12
  attr_reader :uri
12
13
  attr_reader :scheme
13
14
  attr_reader :dir
@@ -25,9 +26,10 @@ module RestFtpDaemon
25
26
  delegate :scheme, :host, :port, :user, :password, :to_s,
26
27
  to: :uri
27
28
 
28
- def initialize path
29
+ def initialize original
29
30
  # Strip spaces before/after, copying original "path" at the same time
30
- location_uri = path.strip
31
+ @original = original
32
+ location_uri = original.strip
31
33
 
32
34
  # Replace tokens, fix scheme for local paths
33
35
  resolve_tokens! location_uri
@@ -60,6 +62,7 @@ module RestFtpDaemon
60
62
  return @name if @dir.nil?
61
63
  File.join(@dir.to_s, @name.to_s)
62
64
  end
65
+ alias :to_s :path
63
66
 
64
67
  def scan_files
65
68
  Dir.glob(path).collect do |file|
@@ -114,7 +117,7 @@ module RestFtpDaemon
114
117
  @uri = URI.parse path # rescue nil
115
118
  raise RestFtpDaemon::LocationParseError, location_path unless @uri
116
119
 
117
- # Sanitize path
120
+ # Path cleanup
118
121
  cleaned = @uri.path.clone
119
122
 
120
123
  # remove_leading_slashes
@@ -6,7 +6,6 @@ module RestFtpDaemon
6
6
  # Class options
7
7
  attr_reader :logger
8
8
  attr_reader :log_prefix
9
-
10
9
  attr_accessor :job
11
10
 
12
11
  # Delegate set_info info to Job
@@ -16,7 +16,7 @@ module RestFtpDaemon
16
16
  prepare_ftp
17
17
  end
18
18
  @ftp.passive = true
19
- @ftp.debug_mode = @debug
19
+ @ftp.debug_mode = @debug
20
20
 
21
21
  # Config
22
22
  @chunk_size = DEFAULT_FTP_CHUNK.to_i * 1024
@@ -4,12 +4,15 @@ require 'aws-sdk-resources'
4
4
  module RestFtpDaemon
5
5
  class RemoteS3 < Remote
6
6
 
7
+ MULTIPART_THRESHOLD_MB = 4
8
+
7
9
  # Class options
8
10
  attr_reader :client
9
11
  attr_reader :target
10
12
 
11
13
  def prepare
12
- log_debug "RemoteS3.prepare target[#{@target.inspect}]"
14
+ @multipart_threshold = MULTIPART_THRESHOLD_MB.to_i * 1024 * 1024
15
+ log_debug "RemoteS3.prepare target[#{@target.inspect}] #{@multipart_threshold}"
13
16
  end
14
17
 
15
18
  def connect
@@ -18,14 +21,13 @@ module RestFtpDaemon
18
21
  # Connect init
19
22
  log_debug "RemoteS3.connect region[#{target.aws_region}] id[#{target.aws_id}]"
20
23
 
21
- # Debug level
22
- verbosity = @debug ? Logger::DEBUG : false
23
-
24
24
  # Connect remote server
25
25
  @client = Aws::S3::Resource.new(
26
26
  region: @target.aws_region,
27
- credentials: Aws::Credentials.new(@target.aws_id, @target.aws_secret)
27
+ credentials: Aws::Credentials.new(@target.aws_id, @target.aws_secret),
28
+ http_wire_trace: @debug
28
29
  )
30
+ #s3 = Aws::S3::Client.new(http_wire_trace: true)
29
31
  end
30
32
 
31
33
  def upload source, target, use_temp_name = false, &callback
@@ -35,12 +37,25 @@ module RestFtpDaemon
35
37
 
36
38
  # Update progress before
37
39
  #yield 0, target.name
38
-
39
- # Do the transfer
40
+ # Point to the right bucket and object
40
41
  bucket = @client.bucket(target.aws_bucket)
41
42
  object = bucket.object(target.name)
42
- object.upload_file source.path do |progress, total|
43
- log_debug "- progress[#{progress}] total[#{total}]"
43
+
44
+ # Do the transfer
45
+ object.upload_file(source.path, {
46
+ multipart_threshold: @multipart_threshold
47
+ })
48
+
49
+ # Wait for transfer to complete
50
+ object.wait_until_exists do |waiter|
51
+ # waiter.delay = 1
52
+ # # log_debug "- progress[#{progress}] total[#{total}]"
53
+ # waiter.before_wait do |attempts, response|
54
+ # puts "#{attempts} made"
55
+ # puts response.error.inspect
56
+ # puts response.data.inspect
57
+ # end
58
+ # log_debug "- progress[] #{waiter.inspect}"
44
59
  end
45
60
 
46
61
  # Update progress after
@@ -49,8 +64,8 @@ module RestFtpDaemon
49
64
  # Dump information about this file
50
65
  log_debug "RemoteS3.upload url[#{object.public_url}]"
51
66
  log_debug "RemoteS3.upload etag[#{object.etag}]"
52
- set_info :target, :aws_public_url, object.public_url
53
- set_info :target, :aws_etag, object.etag
67
+ set_info :target_aws_public_url, object.public_url
68
+ set_info :target_aws_etag, object.etag
54
69
  end
55
70
 
56
71
  def connected?
@@ -1,5 +1,11 @@
1
1
  module URI
2
2
 
3
+ class FILE < Generic
4
+ end
5
+
6
+ class S3 < Generic
7
+ end
8
+
3
9
  class FTPS < Generic
4
10
  DEFAULT_PORT = 21
5
11
  end
@@ -12,12 +18,6 @@ module URI
12
18
  DEFAULT_PORT = 22
13
19
  end
14
20
 
15
- class S3 < Generic
16
- end
17
-
18
- class FILE < Generic
19
- DEFAULT_PORT = 22
20
- end
21
21
 
22
22
  @@schemes["FTPS"] = FTPS
23
23
  @@schemes["FTPES"] = FTPES
@@ -1,12 +1,14 @@
1
1
  -# coding: utf-8
2
2
  - jobs.each do |job|
3
- - work_progress = job.get_info(:work, :progress)
4
- - work_bitrate = job.get_info(:work, :bitrate)
5
- - work_sent = job.get_info(:work, :sent)
3
+ - work_progress = job.get_info(INFO_PROGRESS)
4
+ - error_message = job.get_info(:error_message)
5
+ - transfer_total = job.get_info(:transfer_total)
6
+ - transfer_bitrate = job.get_info(:transfer_bitrate)
7
+ - work_sent = job.get_info(:work_sent)
6
8
 
7
- - source_count = job.get_info(:source, :count) || 0
8
- - source_processed = job.get_info(:source, :processed) || 0
9
- - source_current = job.get_info(:source, :current)
9
+ - source_count = job.get_info(:source_count) || 0
10
+ - source_processed = job.get_info(:source_processed) || 0
11
+ - source_current = job.get_info(:source_current)
10
12
 
11
13
  - job_working = [JOB_STATUS_UPLOADING, JOB_STATUS_TRANSFORMING].include? job.status
12
14
 
@@ -59,16 +61,16 @@
59
61
  = "#{work_progress} %"
60
62
 
61
63
  - else
62
- .error{title: job.get_info(:error, :message)}
64
+ .error{title: error_message}
63
65
  = text_or_empty(job.error)
64
66
 
65
67
  %td.nobr.text-right
66
- = format_bytes(job.get_info(:transfer, :total), "B")
68
+ = format_bytes(transfer_total, "B")
67
69
 
68
70
  %td.nobr.text-right{title: "time: #{job.exectime} s"}
69
- - if work_bitrate
71
+ - if transfer_bitrate
70
72
  %span.push-bitrate
71
- = format_bytes(work_bitrate, "bps")
73
+ = format_bytes(transfer_bitrate, "bps")
72
74
 
73
75
  %td
74
76
  - unless job.wid.nil?
@@ -50,6 +50,7 @@ require_relative "rest-ftp-daemon/workers/reporter"
50
50
  require_relative "rest-ftp-daemon/workers/transfer"
51
51
 
52
52
  # API
53
+ require_relative "rest-ftp-daemon/api/entities/location"
53
54
  require_relative "rest-ftp-daemon/api/entities/options"
54
55
  require_relative "rest-ftp-daemon/api/entities/job"
55
56
  require_relative "rest-ftp-daemon/api/jobs"
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  # Project version
5
- spec.version = "0.422.0"
5
+ spec.version = "0.423.0"
6
6
 
7
7
  # Project description
8
8
  spec.name = "rest-ftp-daemon"
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.422.0
4
+ version: 0.423.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruno MEDICI
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-02 00:00:00.000000000 Z
11
+ date: 2016-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -413,6 +413,7 @@ files:
413
413
  - lib/rest-ftp-daemon/api/dashboard.rb
414
414
  - lib/rest-ftp-daemon/api/debug.rb
415
415
  - lib/rest-ftp-daemon/api/entities/job.rb
416
+ - lib/rest-ftp-daemon/api/entities/location.rb
416
417
  - lib/rest-ftp-daemon/api/entities/options.rb
417
418
  - lib/rest-ftp-daemon/api/jobs.rb
418
419
  - lib/rest-ftp-daemon/api/root-real.rb