file_loader 0.1.0 → 0.1.1

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: a38a99763a2f2b7161408df4885cef39a0498d0f
4
- data.tar.gz: e4c6a6d161429b7346bcfbc544a1e6819bace1ec
3
+ metadata.gz: 9382fbacb05be26be6f65d6fb26354e77955a687
4
+ data.tar.gz: da0602da95eb580284f8ae6a2bd20d33adcddcc9
5
5
  SHA512:
6
- metadata.gz: 8697676b11c6709402cd1df1e40482b5693f16c4f4ea329ea72e63328ceeb2cf8b4b5b328081f81db1bb9a9acb7a34c702d347354a873d64d4f8033e3a0b6334
7
- data.tar.gz: d9b245e098a9b84e6f4f6203544978f43dda8115503d75c7f0d6b7dbb7b4f3b8854330d990980db47a5903df5127e04afcd07bcd1dbbfef337f43466be0778af
6
+ metadata.gz: 65a51540e5457f9230edb63055e0128d1242572c6d90e923a4dc9f3b5ab80583191166e9461999161b21e91cdbb49beb93cb17b56462d3fa0be1ef75e3d3d00c
7
+ data.tar.gz: 45bfbaa1796384b268a9a98a27e8fa92664549505e9a38bfcd91fa0d95aeecb509d25e2070b343653ef9b763c3dec7b998d9fa0d20ef01ce3c3329ea4540e0af
@@ -1,3 +1,3 @@
1
1
  module FileLoader
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
data/lib/file_loader.rb CHANGED
@@ -1,10 +1,26 @@
1
1
  require "file_loader/version"
2
2
  require 'shellwords'
3
3
  require 'socket'
4
- require 'fileutils'
4
+ require 'logger'
5
5
 
6
6
  module FileLoader
7
7
  extend self
8
+
9
+ # === Options
10
+ # [:permissions] b.e. '0777'
11
+ # [:speed_limit] in Kbit/s
12
+ # [:user] default user, used if url has no user
13
+ # [:password]
14
+ # [:logger] Logger instance
15
+ # [:retries] count of retries, default 1
16
+ # [:delay] sleep seconds between retries
17
+ # [:dry_run]
18
+ attr_accessor :defaults
19
+ self.defaults = {
20
+ retries: 0,
21
+ logger: Logger.new(STDOUT),
22
+ delay: 5
23
+ }
8
24
 
9
25
  def parse_url(url)
10
26
  url.match(/^(?:(?<protocol>\w+):\/\/(?:(?<user>.+?)(?:\:(?<password>.+?))?@)?(?<host>.+?):?)?(?<path>\/.+)?$/) or raise("Invalid url #{url}")
@@ -16,103 +32,106 @@ module FileLoader
16
32
  res += opts[:user].to_s
17
33
  res += ":#{opts[:password]}" if opts[:password]
18
34
  res += '@' if opts[:user]
19
- res += "#{opts[:host]}:" if opts[:host]
20
- res += opts[:path].to_s
35
+ res += opts[:host] if opts[:host]
36
+ res += ':' if opts[:host] && opts[:path]
37
+ res += opts[:path] if opts[:path]
38
+ res
21
39
  end
22
40
 
23
41
  def download(src, dst, opts = {})
24
- src = src.shellescape
25
- dst = dst.shellescape
26
- psrc = parse_url(src)
27
- unless Dir.exists?(File.dirname(dst))
28
- FileUtils.mkdir_p(File.dirname(dst), :mode => opts[:permissions] ? opts[:permissions].to_i(8) : nil)
29
- end
42
+ pdst = parse_url(dst = dst.shellescape)
43
+ raise "Unsupported dst protocol #{pdst[:protocol]}" if pdst[:protocol]
44
+
45
+ opts = defaults.merge(opts)
46
+
47
+ psrc = parse_url(src = src.shellescape)
30
48
  case psrc[:protocol]
31
49
  when 'http', 'https', 'ftp'
32
50
  cmd = "wget #{src} -O #{dst}"
51
+ cmd += " --limit-rate #{opts[:speed_limit] * 1024 / 8}" if opts[:speed_limit]
33
52
  when 'scp'
34
53
  if Socket.gethostname == psrc[:host]
35
54
  cmd = cp_cmd(psrc[:path], dst)
36
55
  else
37
56
  cmd = "scp -r -oBatchMode=yes -oStrictHostKeyChecking=no "
38
- cmd += "-l #{speed_limit} " if opts[:speed_limit]
57
+ cmd += "-l #{opts[:speed_limit]} " if opts[:speed_limit]
39
58
  cmd += '"'
40
59
  cmd += build_url(user: psrc[:user] || opts[:user], password: psrc[:password] || opts[:password], host: psrc[:host], path: psrc[:path])
60
+ cmd += '" "'
61
+ cmd += dst
41
62
  cmd += '"'
42
- cmd += " \"#{dst}\""
43
63
  end
44
64
  when nil
45
65
  cmd = cp_cmd(src, dst)
46
66
  else
47
- raise "Unsupported protocol #{psrc[:protocol]}"
67
+ raise "Unsupported src protocol #{psrc[:protocol]}"
48
68
  end
49
- opts[:logger].debug(cmd) if opts[:logger]
50
- exec_cmd(cmd, opts[:retries].to_i) unless opts[:dry_run]
69
+ cmd = mkdir_cmd(dst, opts) + ' && ' + cmd if cmd
70
+ exec_cmd(cmd, opts)
51
71
  end
52
72
 
53
73
  def upload(src, dst, opts = {})
54
- src = src.shellescape
55
- dst = dst.shellescape
56
- parsed_dst = parse_url(dst)
57
- case parsed_dst[:protocol]
74
+ psrc = parse_url(src = src.shellescape)
75
+ raise "Unsupported src protocol #{psrc[:protocol]}" if psrc[:protocol]
76
+
77
+ opts = defaults.merge(opts)
78
+
79
+ pdst = parse_url(dst = dst.shellescape)
80
+ case pdst[:protocol]
58
81
  when 'scp'
59
- if Socket.gethostname == parsed_dst[:host]
60
- unless Dir.exists?(File.dirname(dst))
61
- FileUtils.mkdir_p(File.dirname(dst), :mode => opts[:permissions] ? opts[:permissions].to_i(8) : nil)
62
- end
63
- cmd = cp_cmd(src, parsed_dst[:path])
82
+ if Socket.gethostname == pdst[:host]
83
+ cmd = cp_cmd(src, pdst[:path])
84
+ cmd = mkdir_cmd(pdst[:path], opts) + ' && ' + cmd if cmd
64
85
  else
65
86
  cmd = "ssh -oBatchMode=yes -oStrictHostKeyChecking=no "
66
- user = parsed_dst[:user] || opts[:user]
67
- cmd += user if user
68
- cmd += ":#{parsed_dst[:password]}" if parsed_dst[:password]
69
- cmd += '@' if user
70
- cmd += "#{parsed_dst[:host]} \""
71
- if opts[:permissions]
72
- umask = 'umask %03o' % ('0777'.to_i - opts[:permissions].to_i)
73
- cmd += "(#{umask}; "
74
- end
75
- cmd += "mkdir -p #{File.dirname(parsed_dst[:path])}"
76
- cmd += ")" if opts[:permissions]
77
- cmd += "\" && scp -r -oBatchMode=yes -oStrictHostKeyChecking=no "
87
+ cmd += build_url(user: pdst[:user] || opts[:user], password: pdst[:password], host: pdst[:host])
88
+ cmd += ' "'
89
+ cmd += mkdir_cmd(pdst[:path], opts)
90
+ cmd += '" && scp -r -oBatchMode=yes -oStrictHostKeyChecking=no '
78
91
  cmd += "-l #{opts[:speed_limit]} " if opts[:speed_limit]
79
92
  cmd += "#{src} \""
80
- cmd += user if user
81
- cmd += ":#{opts[:password]}" if opts[:password]
82
- cmd += '@' if user
83
- cmd += "#{parsed_dst[:host]}:#{parsed_dst[:path]}\""
93
+ cmd += build_url(user: pdst[:user] || opts[:user], password: pdst[:password], host: pdst[:host], path: pdst[:path])
94
+ cmd += '"'
84
95
  end
85
96
  when nil
86
- unless Dir.exists?(File.dirname(dst))
87
- FileUtils.mkdir_p(File.dirname(dst), :mode => opts[:permissions] ? opts[:permissions].to_i(8) : nil)
88
- end
89
97
  cmd = cp_cmd(src, dst)
98
+ cmd = mkdir_cmd(pdst[:path], opts) + ' && ' + cmd if cmd
90
99
  else
91
100
  raise "Unsupported protocol #{parsed_src[:protocol]}"
92
101
  end
93
- opts[:logger].debug(cmd) if opts[:logger]
94
- exec_cmd(cmd, opts[:retries].to_i) unless opts[:dry_run]
102
+ exec_cmd(cmd, opts)
95
103
  end
96
104
 
97
105
  private
98
106
 
99
- def exec_cmd(cmd, retries = 0, delay = 5)
100
- return unless cmd
107
+ def exec_cmd(cmd, opts)
108
+ opts[:logger].debug(cmd) if opts[:logger]
109
+ return if opts[:dry_run] || !cmd
101
110
  cmd += " 2>&1"
102
- (retries + 1).times do |n|
111
+ (opts[:retries].to_i + 1).times do |n|
103
112
  res = `#{cmd}`
104
113
  if $?.exitstatus == 0
105
114
  break
106
- elsif n >= retries
115
+ elsif n >= opts[:retries].to_i
107
116
  raise res
108
117
  else
109
- sleep delay
118
+ opts[:logger].debug('retry') if opts[:logger]
119
+ sleep(opts[:delay] || 5)
110
120
  end
111
121
  end
112
122
  end
113
123
 
114
- def cp_cmd(src, dst, permissions = nil)
124
+ def cp_cmd(src, dst)
115
125
  return if src == dst
116
126
  "cp -r #{src} #{dst}"
117
127
  end
118
- end
128
+
129
+ def mkdir_cmd(dst, opts)
130
+ cmd = "mkdir -p #{File.dirname(dst)}"
131
+ if opts[:permissions]
132
+ umask = 'umask %03o' % ('0777'.to_i - opts[:permissions].to_i)
133
+ cmd = "(#{umask}; #{cmd})"
134
+ end
135
+ cmd
136
+ end
137
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file_loader
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - novikov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-07 00:00:00.000000000 Z
11
+ date: 2015-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler