rest-ftp-daemon 0.422.0 → 0.423.0

Sign up to get free protection for your applications and to get access to all the features.
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