s3cp 1.1.12 → 1.1.13
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.
- data/History.txt +9 -0
- data/lib/s3cp/s3mod.rb +67 -19
- data/lib/s3cp/s3stat.rb +15 -2
- data/lib/s3cp/utils.rb +28 -2
- data/lib/s3cp/version.rb +1 -1
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 1.1.13 (2013-01-27)
|
2
|
+
|
3
|
+
* Added: s3stat --acl option to display associated access-control list XML document.
|
4
|
+
|
5
|
+
* Added: s3mod now accepts multiple (wildcard) paths and supports setting both
|
6
|
+
--headers and --acl. (Denis Arh).
|
7
|
+
|
8
|
+
* Fixed: Beter metadata display in s3stat.
|
9
|
+
|
1
10
|
=== 1.1.12 (2013-01-22)
|
2
11
|
|
3
12
|
* Added: Support for 'Content-Disposition' header (Denis Arh).
|
data/lib/s3cp/s3mod.rb
CHANGED
@@ -17,17 +17,51 @@
|
|
17
17
|
|
18
18
|
require 's3cp/utils'
|
19
19
|
|
20
|
+
# Default options
|
21
|
+
options = {
|
22
|
+
:verbose => false,
|
23
|
+
:acl => nil,
|
24
|
+
:headers => []
|
25
|
+
}
|
26
|
+
|
27
|
+
# Setup cli params
|
20
28
|
op = OptionParser.new do |opts|
|
21
|
-
opts.banner = "s3mod [path]
|
29
|
+
opts.banner = "s3mod [path(s)]"
|
30
|
+
|
31
|
+
opts.banner = <<-BANNER
|
32
|
+
s3mod [path(s)] ([permission])
|
33
|
+
|
34
|
+
Multiple paths with multiple wildcards are supported:
|
35
|
+
s3://bucket/path/*foo/*/bar*.jpg
|
36
|
+
|
37
|
+
LEGACY SUPPORT
|
38
|
+
|
39
|
+
This tool still supports old paramater format:
|
40
|
+
% s3mod [path] [permission]
|
41
|
+
You are encouraged to use --acl instead of passing permission as last parameter.
|
42
|
+
|
43
|
+
WARNINGS:
|
44
|
+
|
45
|
+
1) Due to limitations in AWS's S3 API, when you use --headers all ACL
|
46
|
+
properties are removed from the S3 object.
|
47
|
+
|
48
|
+
2) Due to limitations in AWS's S3 API, this command fails on S3 objects
|
49
|
+
larger then 5Gb.
|
50
|
+
|
51
|
+
BANNER
|
52
|
+
opts.separator ''
|
53
|
+
|
54
|
+
opts.on("--verbose", "Verbose mode") do
|
55
|
+
options[:verbose] = true
|
56
|
+
end
|
22
57
|
|
23
|
-
opts.
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
opts.
|
28
|
-
|
29
|
-
|
30
|
-
opts.separator ""
|
58
|
+
opts.on('--headers \'Header1: Header1Value\',\'Header2: Header2Value\'', Array, "Headers to set on the item in S3." ) do |h|
|
59
|
+
options[:headers] = h
|
60
|
+
end
|
61
|
+
|
62
|
+
opts.on("--acl PERMISSION", "One of 'private', 'authenticated-read', 'public-read', 'public-read-write'") do |permission|
|
63
|
+
options[:acl] = S3CP.validate_acl(permission)
|
64
|
+
end
|
31
65
|
|
32
66
|
opts.on_tail("-h", "--help", "Show this message") do
|
33
67
|
puts op
|
@@ -36,22 +70,36 @@ op = OptionParser.new do |opts|
|
|
36
70
|
end
|
37
71
|
|
38
72
|
op.parse!(ARGV)
|
73
|
+
paths = ARGV
|
39
74
|
|
40
|
-
if ARGV.size <
|
75
|
+
if ARGV.size < 1 || !options[:headers]
|
41
76
|
puts op
|
42
77
|
exit
|
43
78
|
end
|
44
79
|
|
45
|
-
|
46
|
-
|
47
|
-
|
80
|
+
# Legacy (support for s3mod [path] [acl] )
|
81
|
+
# See if last param starts with "s3://", validate & remove it from list of paths
|
82
|
+
if !options[:acl] && paths.size > 1 && S3CP::LEGAL_MODS.include?(paths.last)
|
83
|
+
options[:acl] = S3CP.validate_acl(paths.pop);
|
48
84
|
end
|
49
85
|
|
50
|
-
source = ARGV[0]
|
51
|
-
permission = S3CP.validate_acl(ARGV.last)
|
52
|
-
|
53
86
|
S3CP.load_config()
|
54
|
-
|
55
87
|
@s3 = S3CP.connect()
|
56
|
-
|
57
|
-
|
88
|
+
|
89
|
+
paths.each do |path|
|
90
|
+
bucket,key = S3CP.bucket_and_key(path)
|
91
|
+
fail "Invalid bucket/key: #{path}" unless key
|
92
|
+
|
93
|
+
S3CP.objects_by_wildcard(@s3.buckets[bucket], key) { | obj |
|
94
|
+
puts "s3://#{bucket}/#{obj.key}"
|
95
|
+
|
96
|
+
if options[:headers].size > 0
|
97
|
+
current_medata = obj.metadata
|
98
|
+
object_metadata = S3CP.set_header_options(current_medata, S3CP.headers_array_to_hash(options[:headers]))
|
99
|
+
end
|
100
|
+
|
101
|
+
if options[:acl]
|
102
|
+
obj.acl = options[:acl]
|
103
|
+
end
|
104
|
+
}
|
105
|
+
end
|
data/lib/s3cp/s3stat.rb
CHANGED
@@ -17,9 +17,15 @@
|
|
17
17
|
|
18
18
|
require 's3cp/utils'
|
19
19
|
|
20
|
+
@options = {}
|
21
|
+
|
20
22
|
op = OptionParser.new do |opts|
|
21
23
|
opts.banner = "s3stat [path]"
|
22
24
|
|
25
|
+
opts.on("--acl", "Display Access Control List XML document") do
|
26
|
+
@options[:acl] = true
|
27
|
+
end
|
28
|
+
|
23
29
|
opts.on_tail("-h", "--help", "Show this message") do
|
24
30
|
puts op
|
25
31
|
exit
|
@@ -43,8 +49,15 @@ S3CP.load_config()
|
|
43
49
|
|
44
50
|
@s3 = S3CP.connect().buckets[@bucket]
|
45
51
|
|
46
|
-
|
52
|
+
obj = @s3.objects[@key]
|
53
|
+
|
54
|
+
metadata = obj.head
|
47
55
|
metadata.keys.sort { |k1, k2| k1.to_s <=> k2.to_s}.each do |k|
|
48
|
-
puts "#{"%30s" % k} #{metadata[k]}"
|
56
|
+
puts "#{"%30s" % k} #{metadata[k].is_a?(Hash) ? metadata[k].inspect : metadata[k].to_s}"
|
49
57
|
end
|
50
58
|
|
59
|
+
if @options[:acl]
|
60
|
+
puts
|
61
|
+
xml = Nokogiri::XML(obj.acl.to_s)
|
62
|
+
puts xml.to_s
|
63
|
+
end
|
data/lib/s3cp/utils.rb
CHANGED
@@ -175,8 +175,9 @@ module S3CP
|
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
178
|
-
|
179
|
-
|
178
|
+
remaining.each do |k,v|
|
179
|
+
options[k] = v
|
180
|
+
end
|
180
181
|
|
181
182
|
options
|
182
183
|
end
|
@@ -187,6 +188,31 @@ module S3CP
|
|
187
188
|
end
|
188
189
|
permission
|
189
190
|
end
|
191
|
+
|
192
|
+
# Yield to block for all objects matching key_regex
|
193
|
+
def objects_by_wildcard(bucket, key_regex, &block)
|
194
|
+
# First, trim multiple wildcards & wildcards on the end
|
195
|
+
key = key_regex.gsub(/\*+/, '*')
|
196
|
+
|
197
|
+
if 0 < key.count('*')
|
198
|
+
key_split = key.split('*', 2);
|
199
|
+
kpfix = key_split.shift(); # ignore first part as AWS API takes it as a prefix
|
200
|
+
regex = []
|
201
|
+
|
202
|
+
key_split.each do |kpart|
|
203
|
+
regex.push Regexp.quote(kpart)
|
204
|
+
end
|
205
|
+
|
206
|
+
regex = regex.empty? ? nil : Regexp.new(regex.join('.*') + '$');
|
207
|
+
|
208
|
+
bucket.objects.with_prefix(kpfix).each do |obj|
|
209
|
+
yield obj if regex == nil || regex.match(obj.key[kpfix.size..-1])
|
210
|
+
end
|
211
|
+
else
|
212
|
+
# no wildcards, simple:
|
213
|
+
yield bucket.objects[key]
|
214
|
+
end
|
215
|
+
end
|
190
216
|
end
|
191
217
|
|
192
218
|
# Monkey-patch S3 object for download streaming
|
data/lib/s3cp/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: s3cp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 1.1.
|
9
|
+
- 13
|
10
|
+
version: 1.1.13
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Boisvert
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2013-01-
|
18
|
+
date: 2013-01-27 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|