dronejob 1.0.8 → 1.0.9

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: cd8e68837e8fb8f8a898f16ef5a412c8defe43e8
4
- data.tar.gz: 585eb857b76e5acaf998d16fbe25aedfd170de94
3
+ metadata.gz: f9dbb72f363b027c7375e6d4c0c3ac4944e210df
4
+ data.tar.gz: 1fc73ad750f50c725ecc8472ccab543c6de62842
5
5
  SHA512:
6
- metadata.gz: 088fd4626a488e973a27458cadbf6660f3e515de9444a744abab6e15d49f1d79e122c2389750f1f1c75b54de50f1d6f8d0d1df5a70f42133d20856d9cd1247f1
7
- data.tar.gz: 98cf94d0b923cc10fdeeceaf2c184f1cb0b7feb33e045c99c6c156923b028aadc15f24ab692a68ee583e8e08e845d1b9a4e68007a717e3034f22dba8088cdd75
6
+ metadata.gz: 9c3809dd877e6ced5dd54a528e9f39580201884610dd8fe577ef345d53e2809097a09ee8a3dcb0acd6cc9331740b3434e5704efd0cb2538051a45674564f9b85
7
+ data.tar.gz: 21c53828b64f5fec596b8f0c487181b81731cd3b25fe2b7c4e2772fff3729b96065ea7a9829a14090b8c8d32988648bd7e23923f31783d2f7bfa2b3113f1457b
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dronejob (1.0.8)
4
+ dronejob (1.0.9)
5
5
  activejob (~> 4.2)
6
6
  bundler (~> 1.11)
7
7
  git (~> 1.2)
@@ -12,6 +12,7 @@ PATH
12
12
  sidekiq (~> 4.1.0)
13
13
  sidekiq-status (~> 0.6.0)
14
14
  thor (~> 0.19)
15
+ typhoeus (~> 1.0)
15
16
 
16
17
  GEM
17
18
  remote: http://rubygems.org/
@@ -29,6 +30,9 @@ GEM
29
30
  concurrent-ruby (1.0.1)
30
31
  connection_pool (2.2.0)
31
32
  diff-lcs (1.2.5)
33
+ ethon (0.9.0)
34
+ ffi (>= 1.3.0)
35
+ ffi (1.9.10)
32
36
  git (1.3.0)
33
37
  globalid (0.3.6)
34
38
  activesupport (>= 4.1.0)
@@ -69,6 +73,8 @@ GEM
69
73
  thor (0.19.1)
70
74
  thread_safe (0.3.5)
71
75
  tilt (2.0.2)
76
+ typhoeus (1.0.2)
77
+ ethon (>= 0.9.0)
72
78
  tzinfo (1.2.2)
73
79
  thread_safe (~> 0.1)
74
80
 
data/dronejob.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency "open_uri_redirections", "~> 0.2"
25
25
  s.add_runtime_dependency "rubyzip", "~> 1.1"
26
26
  s.add_runtime_dependency "activejob", "~> 4.2"
27
+ s.add_runtime_dependency "typhoeus", "~> 1.0"
27
28
  s.add_development_dependency "rspec", "~> 3.3"
28
29
  s.add_development_dependency "pry", "~> 0.10"
29
30
  s.files = `git ls-files`.split("\n")
data/lib/dronejob/base.rb CHANGED
@@ -7,6 +7,7 @@ require 'dronejob/modules/queue'
7
7
  require 'dronejob/modules/options'
8
8
  require 'dronejob/modules/params'
9
9
  require 'dronejob/modules/phases'
10
+ require 'dronejob/modules/stateful'
10
11
  require 'dronejob/modules/workspace'
11
12
 
12
13
  module Dronejob
@@ -21,6 +22,7 @@ module Dronejob
21
22
  include Modules::Options
22
23
  include Modules::Params
23
24
  include Modules::Phases
25
+ include Modules::Stateful
24
26
  include Modules::Workspace
25
27
 
26
28
  ActiveSupport.run_load_hooks(:dronejob, self)
@@ -21,7 +21,7 @@ module Dronejob
21
21
 
22
22
  # Worker options
23
23
  worker.params.each do |key, config|
24
- method_option(key, required: config[:required], type: config[:type], default: config[:default])
24
+ method_option(key, required: config[:required], type: config[:argument_type], default: config[:default])
25
25
  end
26
26
 
27
27
  define_method(identifier) do
@@ -59,18 +59,6 @@ module Dronejob
59
59
  end
60
60
  end
61
61
 
62
- Dronejob::Loader.workers(:one_off).each do |identifier, worker|
63
- desc identifier, "Run #{identifier} one-off worker"
64
- method_option(:break, aliases: "-b", type: :boolean, default: false)
65
- method_option(:skip, aliases: "-s", type: :array, default: [])
66
- worker.params.each do |key, config|
67
- method_option(key, required: config[:required], type: config[:type], default: config[:default])
68
- end
69
- define_method(identifier) do
70
- worker.new.perform(options)
71
- end
72
- end
73
-
74
62
  desc :server, "Start Dronejob Server"
75
63
  method_option(:queue_adapter, type: :string, default: "sidekiq", enum: ["sidekiq"])
76
64
  method_option(:jobs_path, type: :string)
@@ -95,7 +83,7 @@ module Dronejob
95
83
  Dronejob::Base.log("info", "Archiving #{dir.name}")
96
84
  archive_file = archive_dir.file("#{dir.name}.zip")
97
85
  if archive_file.exists? and !options.force
98
- Dronejob::Base.log("error", "Error: Archive '#{archive_file.full_path}' already exists. Use --force to replace.")
86
+ Dronejob::Base.log("error", "Error: Archive '#{archive_file}' already exists. Use --force to replace.")
99
87
  else
100
88
  archive_file.delete! if archive_file.exists?
101
89
  dir.compress(archive_file)
@@ -113,7 +101,7 @@ module Dronejob
113
101
  def unarchive
114
102
  archives_dir = WorkspaceDir.new("archive")
115
103
  archive_file = archives_dir.file("#{options.archive}.zip")
116
- Dronejob::Base.log("info", "Unarchiving '#{archive_file.full_path}'")
104
+ Dronejob::Base.log("info", "Unarchiving '#{archive_file}'")
117
105
  target_dir = WorkspaceDir.new("tmp/jobs").dir(options.archive)
118
106
  if !options.force and target_dir.exists?
119
107
  Dronejob::Base.log("error", "Error: Job directory already exists")
@@ -8,45 +8,57 @@ module Dronejob
8
8
  end
9
9
 
10
10
  def perform(params)
11
- @params = params
11
+ set_parameters(params)
12
12
  validate_parameters!
13
13
  create_working_dir
14
- load_variables
15
14
 
16
- git_init(@working_dir.full_path)
17
- git_collect_commits
18
- git_commit("start")
19
- if param(:from)
20
- info("starting from phase #{param(:from)}")
21
- phase = prev_phase(param(:from))
22
- raise("phase '#{param(:from)}' not found!") if phase.nil? or @commits[phase.to_s].nil?
23
- git_reset(phase.to_s)
24
- else
25
- git_reset
15
+ if self.class.stateful?
16
+ load_variables
17
+ git_init(@working_dir.to_s)
18
+ git_collect_commits
19
+ git_commit("start")
20
+ if param(:from)
21
+ info("starting from phase #{param(:from)}")
22
+ phase = prev_phase(param(:from))
23
+ raise("phase '#{param(:from)}' not found!") if phase.nil? or @commits[phase.to_s].nil?
24
+ git_reset(phase.to_s)
25
+ else
26
+ git_reset
27
+ end
28
+ git_collect_commits
29
+ git_clean
26
30
  end
27
- git_collect_commits
28
- git_clean
29
31
 
30
32
  # Run through phases
31
- each_phase do |phase, config|
33
+ each_phase do |phase, phase_config|
32
34
  begin
33
35
  phase_result = public_send(phase)
34
36
  rescue Exception => e
35
37
  error(e.message)
36
38
  error(e.backtrace.join("\n"))
39
+ delete_working_dir if self.class.cleanup_on_error?
40
+ publish_status({title: self.title, description: e.message, phase: phase, backtrace: e.backtrace}, "failed") if param(:notify) and !param(:run)
37
41
  return false
38
42
  end
39
- publish_status(phase_result) if config[:notify]
40
- git_commit(phase)
43
+
44
+ publish_status({title: self.title, description: phase_config[:title], phase: phase}, "working") if phase_config[:notify] and param(:notify) and !param(:run)
45
+ git_commit(phase) if self.class.stateful?
41
46
  end
42
47
  @phase = "complete"
43
- publish_status(true) if param(:notify) and !param(:run)
48
+
49
+ publish_status({title: self.title, description: "Job Completed!", phase: @phase}, "complete") if param(:notify) and !param(:run)
50
+
51
+ delete_working_dir if self.class.cleanup_on_complete?
44
52
  end
45
53
 
46
54
  def uuid
47
55
  @uuid ||= "#{self.class.name.split('::').last.underscore}_#{SecureRandom.uuid}"
48
56
  end
49
57
 
58
+ def title
59
+ self.class.name
60
+ end
61
+
50
62
  def shell
51
63
  @shell ||= Thor::Shell::Color.new
52
64
  end
@@ -7,6 +7,14 @@ module Dronejob
7
7
  def param(key, options)
8
8
  @params ||= {}
9
9
  @params[key] = options
10
+ @params[key][:argument_type] = @params[key][:type]
11
+ if @params[key][:type] == :base64 or @params[key][:type] == :json64
12
+ @params[key][:argument_type] = :string
13
+ end
14
+ end
15
+
16
+ def param_config(key)
17
+ @params[key.to_sym]
10
18
  end
11
19
 
12
20
  def params
@@ -14,6 +22,18 @@ module Dronejob
14
22
  end
15
23
  end
16
24
 
25
+ def set_parameters(params)
26
+ @params = params.map{|name, value| [name, transform_parameter(name, value)]}.to_h
27
+ end
28
+
29
+ def transform_parameter(name, value)
30
+ if config = self.class.param_config(name)
31
+ return Base64.strict_decode64(value) if config[:type] == :base64
32
+ return JSON.parse(Base64.strict_decode64(value)) if config[:type] == :json64
33
+ end
34
+ value
35
+ end
36
+
17
37
  def param(key)
18
38
  @params ||= {}
19
39
  @params[key.to_s]
@@ -29,7 +49,7 @@ module Dronejob
29
49
  end
30
50
 
31
51
  # Validate parameters
32
- type_map = {string: [String], numeric: [Fixnum, Integer, Float], array: [Array], boolean: [TrueClass, FalseClass]}
52
+ type_map = {string: [String], numeric: [Fixnum, Integer, Float], array: [Array], boolean: [TrueClass, FalseClass], base64: [String], json64: [Hash, Array]}
33
53
  self.class.params.each do |param_name, param_config|
34
54
  param_value = @params[param_name.to_s]
35
55
  if param_value.nil?
@@ -30,6 +30,7 @@ module Dronejob
30
30
  elsif skip_phase?(phase)
31
31
  info("skipping...")
32
32
  else
33
+ info "running phase #{phase}"
33
34
  # Require libraries
34
35
  if !config[:require].nil?
35
36
  config[:require].each do |library|
@@ -54,12 +55,15 @@ module Dronejob
54
55
  end
55
56
 
56
57
  @dronejob_completed = true
57
- git_commit("dronejob_completed")
58
- info("JOB COMPLETED")
58
+ git_commit("dronejob_completed") if self.class.stateful?
59
59
  end
60
60
 
61
61
  def completed_phase?(phase)
62
- @commits.include?(phase.to_s)
62
+ if self.class.stateful?
63
+ @commits.include?(phase.to_s)
64
+ else
65
+ false
66
+ end
63
67
  end
64
68
 
65
69
  def skip_phase?(phase)
@@ -18,9 +18,15 @@ module Dronejob
18
18
  end
19
19
  end
20
20
 
21
- def publish_status(result=nil)
22
- data = {phase: @phase, result: result}
23
- Redis.new({url: option(:redis_url)}).publish(self.publish_channel, data.to_json)
21
+ def publish_status(data={}, status="working", backend=false)
22
+ data[:action] = "update_process"
23
+ data[:user_id] = param(:user_id)
24
+ data[:jid] = job_id
25
+ data[:worker] = Loader.identifier_for(self)
26
+ data[:timestamp] = Time.now.to_i
27
+ data[:status] = status
28
+ data[:secret_key] = option(:secret_key) if backend
29
+ Redis.new(url: option(:redis_url)).publish("processes_#{backend ? 'backend' : data[:user_id]}", data.to_json)
24
30
  end
25
31
 
26
32
  def publish_channel
@@ -0,0 +1,18 @@
1
+ module Dronejob
2
+ module Modules
3
+ module Stateful
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def stateful(value=true)
8
+ @stateful = value
9
+ end
10
+
11
+ def stateful?
12
+ !!@stateful
13
+ end
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -5,6 +5,24 @@ module Dronejob
5
5
  module Workspace
6
6
  extend ActiveSupport::Concern
7
7
 
8
+ module ClassMethods
9
+ def cleanup_on_complete(value=true)
10
+ @cleanup_on_complete = value
11
+ end
12
+
13
+ def cleanup_on_complete?
14
+ !!@cleanup_on_complete
15
+ end
16
+
17
+ def cleanup_on_error(value=true)
18
+ @cleanup_on_error = value
19
+ end
20
+
21
+ def cleanup_on_error?
22
+ !!@cleanup_on_error
23
+ end
24
+ end
25
+
8
26
  included do
9
27
  attr_accessor :working_dir
10
28
  cattr_accessor(:jobs_path) { "app/jobs" }
@@ -30,9 +48,17 @@ module Dronejob
30
48
  @working_dir
31
49
  end
32
50
 
51
+ def delete_working_dir
52
+ working_dir.delete!
53
+ end
54
+
33
55
  def asset_file(path)
34
56
  WorkspaceDir.new("app/assets").file(path)
35
57
  end
58
+
59
+ def asset_dir(path)
60
+ WorkspaceDir.new("app/assets").dir(path)
61
+ end
36
62
  end
37
63
  end
38
64
  end
@@ -1,3 +1,3 @@
1
1
  module Dronejob
2
- VERSION = "1.0.8"
2
+ VERSION = "1.0.9"
3
3
  end
@@ -0,0 +1,18 @@
1
+ module Dronejob
2
+ class WorkspaceDir
3
+ module Archive
4
+ extend ActiveSupport::Concern
5
+
6
+ def compress(target_file)
7
+ target_file.delete!
8
+ require "zip"
9
+ Zip::File.open(target_file.to_s, 'w') do |zipfile|
10
+ Dir["#{to_s}/**/**"].each do |file|
11
+ zipfile.add(file.sub("#{to_s}/",''), file)
12
+ end
13
+ end
14
+ self
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,5 +1,9 @@
1
+ require 'dronejob/workspace_dir/archive'
2
+
1
3
  module Dronejob
2
4
  class WorkspaceDir
5
+ include WorkspaceDir::Archive
6
+
3
7
  attr_accessor :workspace, :path
4
8
 
5
9
  def initialize(workspace, path="")
@@ -7,25 +11,30 @@ module Dronejob
7
11
  @path = path
8
12
  end
9
13
 
10
- def name
11
- File.basename(full_path)
14
+ def to_s
15
+ File.join(@workspace, @path)
12
16
  end
13
17
 
14
- def full_path
15
- File.join(@workspace, @path)
18
+ def name
19
+ File.basename(to_s)
16
20
  end
17
21
 
18
22
  def create
19
- FileUtils.mkdir_p(full_path)
23
+ FileUtils.mkdir_p(to_s)
20
24
  self
21
25
  end
22
26
 
23
27
  def exists?
24
- File.directory?(full_path)
28
+ File.directory?(to_s)
29
+ end
30
+
31
+ def copy(target_dir)
32
+ target_dir.parent_dir.create if !target_dir.parent_dir.exists?
33
+ FileUtils.cp_r(to_s, target_dir.to_s)
25
34
  end
26
35
 
27
36
  def delete!
28
- FileUtils.rm_rf(full_path)
37
+ FileUtils.rm_rf(to_s)
29
38
  end
30
39
 
31
40
  def file(file_path)
@@ -36,19 +45,17 @@ module Dronejob
36
45
  WorkspaceDir.new(@workspace, File.join(@path, dir_path))
37
46
  end
38
47
 
39
- def compress(target_file)
40
- target_file.delete!
41
- Zip::File.open(target_file.full_path, 'w') do |zipfile|
42
- Dir["#{full_path}/**/**"].each do |file|
43
- zipfile.add(file.sub("#{full_path}/",''), file)
44
- end
45
- end
46
- self
48
+ def root_dir
49
+ WorkspaceDir.new(@workspace, "")
50
+ end
51
+
52
+ def parent_dir
53
+ root_dir.dir(File.expand_path("..", @path))
47
54
  end
48
55
 
49
56
  def children
50
57
  entries = []
51
- Dir.chdir(full_path) do
58
+ Dir.chdir(to_s) do
52
59
  Dir["*"].each do |path|
53
60
  entries.push(dir(path))
54
61
  end
@@ -0,0 +1,47 @@
1
+ module Dronejob
2
+ class WorkspaceFile
3
+ module Archive
4
+ extend ActiveSupport::Concern
5
+
6
+
7
+ def extract(target_dir)
8
+ target_dir.create
9
+ if extension == "zip"
10
+ extract_zip(target_dir)
11
+ elsif extension == "gz"
12
+ extract_gz(target_dir)
13
+ end
14
+ self
15
+ end
16
+
17
+ private
18
+
19
+ def extract_zip(target_dir)
20
+ require "zip"
21
+ Zip::File.open(to_s) do |archive|
22
+ archive.each do |entry|
23
+ entry.extract(File.join(target_dir.to_s, entry.name))
24
+ end
25
+ end
26
+ end
27
+
28
+ def extract_gz(target_dir)
29
+ require 'rubygems/package'
30
+ workspace_dir = target_dir.root_dir
31
+ archive = Gem::Package::TarReader.new(Zlib::GzipReader.open(to_s))
32
+ archive.rewind
33
+ archive.each do |entry|
34
+ if entry.directory?
35
+ archive_dir = workspace_dir.dir(entry.full_name)
36
+ archive_dir.create
37
+ elsif entry.file?
38
+ archive_file = workspace_dir.file(entry.full_name)
39
+ archive_file.write(entry.read)
40
+ end
41
+ end
42
+ archive.close
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,81 @@
1
+ module Dronejob
2
+ class WorkspaceFile
3
+ module Media
4
+ extend ActiveSupport::Concern
5
+
6
+ def acbaker(type, output_dir, delete=true)
7
+ require "acbaker"
8
+ output_dir.delete! if delete and output_dir.exists?
9
+ output_dir.create
10
+ config = WorkspaceDir.new("app/assets").file("acbaker/#{type}.json").read_json
11
+ acb = Acbaker::AssetPack.new(type, json: config)
12
+ acb.process(to_s, output_dir.to_s)
13
+ self
14
+ end
15
+
16
+ def image?
17
+ ["jpg", "jpeg", "gif", "png"].include?(extension)
18
+ end
19
+
20
+ def video?
21
+ ["mp4"].include?(extension)
22
+ end
23
+
24
+ def audio?
25
+ ["mp3"].include?(extension)
26
+ end
27
+
28
+ def cache_assets(cache_dir, &block)
29
+ hydra = Typhoeus::Hydra.new(max_concurrency: 10)
30
+ html = contents
31
+ html.scan(/["'(]{1}(https?\:\/\/[^"')]+\.(jpg|jpeg|png|gif|mp3|mp4))["')?#]{1}/).map{|match| match[0]}.uniq.each do |url|
32
+ ext = File.extname(url).gsub(/^\./, "")
33
+ cache_file = cache_dir.file("#{Digest::MD5.hexdigest(url)}.#{ext}")
34
+ request = cache_file.queue_download(url) do
35
+ cache_file.optimize!
36
+ html.gsub!(url, cache_file.relative_path)
37
+ end
38
+ hydra.queue(request)
39
+ end
40
+ hydra.run
41
+ set(html)
42
+ self
43
+ end
44
+
45
+ def optimize!
46
+ return false if !exists?
47
+ return optimize_jpg! if image? and ["jpg", "jpeg"].include?(extension)
48
+ return optimize_png! if image? and ["png"].include?(extension)
49
+ false
50
+ end
51
+
52
+ private
53
+
54
+ def optimize_jpg!
55
+ require "rmagick"
56
+ image_max_width = Dronejob::Base.option(:image_max_width)
57
+ image = Magick::Image.read(to_s).first
58
+ image.change_geometry!("#{image_max_width}>x"){|cols, rows, img| img.resize!(cols, rows)} if image.columns > image_max_width
59
+ image.write(to_s) { self.quality = Dronejob::Base.option(:image_quality) }
60
+ image.destroy!
61
+ end
62
+
63
+ def optimize_png!
64
+ require "rmagick"
65
+ image_max_width = Dronejob::Base.option(:image_max_width)
66
+ image = Magick::Image.read(to_s).first
67
+ image.change_geometry!("#{image_max_width}>x"){|cols, rows, img| img.resize!(cols, rows)} if image.columns > image_max_width
68
+
69
+ # Convert to jpg
70
+ if !image.alpha? or image.resize(1,1).pixel_color(0,0).opacity == 0
71
+ image.format = "JPG"
72
+ rename!("#{basename}.jpg")
73
+ end
74
+
75
+ image.write(to_s) { self.quality = Dronejob::Base.option(:image_quality) }
76
+ image.destroy!
77
+ end
78
+
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,33 @@
1
+ require "typhoeus"
2
+ require "open-uri"
3
+ require "open_uri_redirections"
4
+
5
+ module Dronejob
6
+ class WorkspaceFile
7
+ module Net
8
+ extend ActiveSupport::Concern
9
+
10
+ def cdn_download(key)
11
+ download("http://#{Dronejob::Base.option(:cdn_bucket)}/#{key}")
12
+ end
13
+
14
+ def queue_download(url, &block)
15
+ request = Typhoeus::Request.new(url)
16
+ request.on_complete do |response|
17
+ if response.success?
18
+ write(response.body)
19
+ block.call(self) if !block.nil?
20
+ end
21
+ end
22
+ request
23
+ end
24
+
25
+ def download(url)
26
+ contents = open(url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, allow_redirections: :safe }).read
27
+ dir.create if !dir.exists?
28
+ write(contents)
29
+ self
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ module Dronejob
2
+ class WorkspaceFile
3
+ module Parse
4
+ extend ActiveSupport::Concern
5
+
6
+ def pbxproj_replace(data)
7
+ data.each do |key, value|
8
+ replace(/#{key} = .*;/, "#{key} = \"#{value}\";") if !value.nil?
9
+ end
10
+ write
11
+ self
12
+ end
13
+
14
+ def with_plist(&block)
15
+ require "plist"
16
+ plist = Plist.parse_xml(to_s)
17
+ block.call(plist)
18
+ write(Plist::Emit.dump(plist))
19
+ end
20
+
21
+ def read_json
22
+ JSON.parse(read)
23
+ end
24
+
25
+ def read_yaml
26
+ require "psych"
27
+ Psych.load_file(to_s)
28
+ end
29
+
30
+ def read_haml(options)
31
+ require "haml"
32
+ engine = Haml::Engine.new(read)
33
+ engine.render(Object.new, options)
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -1,9 +1,15 @@
1
- require "psych"
2
- require "zip"
3
- require "open-uri"
4
- require "open_uri_redirections"
1
+ require 'dronejob/workspace_file/archive'
2
+ require 'dronejob/workspace_file/media'
3
+ require 'dronejob/workspace_file/net'
4
+ require 'dronejob/workspace_file/parse'
5
+
5
6
  module Dronejob
6
7
  class WorkspaceFile
8
+ include WorkspaceFile::Archive
9
+ include WorkspaceFile::Media
10
+ include WorkspaceFile::Net
11
+ include WorkspaceFile::Parse
12
+
7
13
  attr_accessor :workspace, :path
8
14
 
9
15
  def initialize(workspace, path)
@@ -11,116 +17,67 @@ module Dronejob
11
17
  @path = path
12
18
  end
13
19
 
14
- def set(contents)
15
- @contents = contents
20
+ def set(data)
21
+ @contents = data
16
22
  self
17
23
  end
18
-
24
+
19
25
  def contents
20
26
  @contents ||= read
21
27
  end
22
-
28
+
23
29
  def replace(key, value)
24
30
  contents.gsub!(key, value)
25
31
  self
26
32
  end
27
33
 
28
- def pbxproj_replace(data)
29
- data.each do |key, value|
30
- replace(/#{key} = .*;/, "#{key} = #{value};") if !value.nil?
31
- end
32
- end
33
-
34
- def with_plist(&block)
35
- require "plist"
36
- plist = Plist.parse_xml(full_path)
37
- block.call(plist)
38
- write(Plist::Emit.dump(plist))
39
- end
40
-
41
- def write(contents=nil)
42
- contents ||= @contents
43
- File.open(full_path, "wb") do |file|
44
- file << contents
45
- end
34
+ def write(data=nil)
35
+ data ||= @contents
36
+ dir.create if !dir.exists?
37
+ File.open(to_s, "wb") {|file| file << data}
46
38
  self
47
39
  end
48
40
 
49
- def full_path
41
+ def copy(target_file)
42
+ target_file.dir.create if !target_file.dir.exists?
43
+ FileUtils.cp(to_s, target_file.to_s)
44
+ end
45
+
46
+ def to_s
50
47
  File.join(@workspace, @path)
51
48
  end
52
-
49
+
50
+ def relative_path
51
+ @path.gsub(/^\//, "")
52
+ end
53
+
53
54
  def exists?
54
- File.exists?(full_path)
55
+ File.exists?(to_s)
55
56
  end
56
-
57
+
57
58
  def read
58
- File.open(full_path).read
59
- end
60
-
61
- def read_json
62
- JSON.parse(read)
63
- end
64
-
65
- def read_yaml
66
- Psych.load_file(full_path)
67
- end
68
-
69
- def read_haml(options)
70
- require "haml"
71
- engine = Haml::Engine.new(read)
72
- engine.render(Object.new, options)
73
- end
74
-
75
- def download!(url)
76
- raise "file not found at #{url}" unless download(url)
77
- self
78
- end
79
-
80
- def cdn_download!(key)
81
- raise "cdn file not found at #{key}" unless cdn_download(key)
82
- self
83
- end
84
-
85
- def cdn_download(key)
86
- download("#{Dronejob::Base.option(:cdn_url)}/#{key}")
87
- end
88
-
89
- def download(url)
90
- open(full_path, "wb") do |file|
91
- file << open(url, { ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE, allow_redirections: :safe }).read
92
- end
93
- return self
94
- rescue StandardError => e
95
- return false
96
- end
97
-
98
- def extract(target_dir)
99
- target_dir.create
100
- Zip::File.open(full_path) do |zip_file|
101
- zip_file.each do |entry|
102
- entry.extract(File.join(target_dir.full_path, entry.name))
103
- end
104
- end
105
- self
106
- end
107
-
108
- def acbaker(type, output_dir, delete=true)
109
- require "acbaker"
110
- output_dir.delete! if delete and output_dir.exists?
111
- output_dir.create
112
- config = WorkspaceDir.new("app/assets").file("acbaker/#{type}.json").read_json
113
- acb = Acbaker::AssetPack.new(type, json: config)
114
- acb.process(full_path, output_dir.full_path)
115
- self
59
+ File.open(to_s).read
116
60
  end
117
61
 
118
62
  def dir
119
63
  WorkspaceDir.new(@workspace, File.dirname(@path))
120
64
  end
121
-
65
+
122
66
  def delete!
123
- FileUtils.rm_f(full_path)
67
+ FileUtils.rm_f(to_s)
68
+ end
69
+
70
+ def basename
71
+ File.basename(path, ".*")
72
+ end
73
+
74
+ def extension
75
+ File.extname(to_s).gsub(/^\./, "")
76
+ end
77
+
78
+ def rename!(filename)
79
+ FileUtils.mv(to_s, dir.file(filename).to_s) if exists?
80
+ @path = dir.file(filename).path
124
81
  end
125
82
  end
126
83
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dronejob
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.8
4
+ version: 1.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tobias Strebitzer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-25 00:00:00.000000000 Z
11
+ date: 2016-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '4.2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: typhoeus
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.0'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.0'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rspec
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -204,14 +218,19 @@ files:
204
218
  - lib/dronejob/modules/params.rb
205
219
  - lib/dronejob/modules/phases.rb
206
220
  - lib/dronejob/modules/queue.rb
221
+ - lib/dronejob/modules/stateful.rb
207
222
  - lib/dronejob/modules/workspace.rb
208
- - lib/dronejob/one_off.rb
209
223
  - lib/dronejob/railtie.rb
210
224
  - lib/dronejob/railties/dronejob.rake
211
225
  - lib/dronejob/server/sidekiq.rb
212
226
  - lib/dronejob/version.rb
213
227
  - lib/dronejob/workspace_dir.rb
228
+ - lib/dronejob/workspace_dir/archive.rb
214
229
  - lib/dronejob/workspace_file.rb
230
+ - lib/dronejob/workspace_file/archive.rb
231
+ - lib/dronejob/workspace_file/media.rb
232
+ - lib/dronejob/workspace_file/net.rb
233
+ - lib/dronejob/workspace_file/parse.rb
215
234
  homepage: https://github.com/MagLoft/dronejob
216
235
  licenses:
217
236
  - BSD-3-Clause
@@ -1,77 +0,0 @@
1
- require "active_job"
2
- require 'dronejob/modules/core'
3
- require 'dronejob/modules/log'
4
- require 'dronejob/modules/options'
5
- require 'dronejob/modules/params'
6
- require 'dronejob/modules/phases'
7
-
8
- module Dronejob
9
- class OneOff
10
- DRONEJOB_TYPE = "one_off"
11
- include Modules::Core
12
- include Modules::Log
13
- include Modules::Options
14
- include Modules::Params
15
- include Modules::Phases
16
-
17
- def perform(params)
18
- @params = params
19
- validate_parameters!
20
-
21
- # Run through phases
22
- each_phase do |phase, config|
23
- begin
24
- phase_result = public_send(phase)
25
- rescue Exception => e
26
- error(e.message)
27
- error(e.backtrace.join("\n"))
28
- return false
29
- end
30
- end
31
- end
32
-
33
- def each_phase(&block)
34
- self.class.phases.each do |phase, config|
35
- fail "Phase not found: '#{phase}'" unless self.respond_to?(phase)
36
- @phase = phase
37
- before_phase(phase, config) if self.respond_to?(:before_phase)
38
-
39
- logger.tagged(phase) do
40
- if completed_phase?(phase) and !config[:always_run]
41
- info("already completed")
42
- elsif skip_phase?(phase)
43
- info("skipping...")
44
- else
45
- # Require libraries
46
- if !config[:require].nil?
47
- config[:require].each do |library|
48
- require library
49
- end
50
- end
51
-
52
- # Include helpers
53
- if !config[:helpers].nil?
54
- config[:helpers].each do |helper|
55
- helper_path = "helpers/#{helper}"
56
- require "./app/#{helper_path}"
57
- self.class.include helper_path.camelcase.constantize
58
- end
59
- end
60
-
61
- block.call(phase, config)
62
- end
63
- end
64
-
65
- after_phase(phase, config) if self.respond_to?(:after_phase)
66
- end
67
-
68
- info("JOB COMPLETED")
69
- end
70
-
71
- def completed_phase?(phase)
72
- false
73
- end
74
-
75
- ActiveSupport.run_load_hooks(:dronejob, self)
76
- end
77
- end