moserp-s3sync 1.2.6
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/README +406 -0
- data/README_s3cmd +172 -0
- data/bin/s3cmd +245 -0
- data/bin/s3sync +735 -0
- data/lib/HTTPStreaming.rb +107 -0
- data/lib/S3.rb +707 -0
- data/lib/S3_s3sync_mod.rb +143 -0
- data/lib/S3encoder.rb +50 -0
- data/lib/s3config.rb +27 -0
- data/lib/s3try.rb +177 -0
- data/lib/thread_generator.rb +383 -0
- metadata +67 -0
@@ -0,0 +1,383 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#--
|
3
|
+
# $Idaemons: /home/cvs/rb/generator.rb,v 1.8 2001/10/03 08:54:32 knu Exp $
|
4
|
+
# $RoughId: generator.rb,v 1.10 2003/10/14 19:36:58 knu Exp $
|
5
|
+
# $Id: generator.rb,v 1.12 2005/12/31 02:56:46 ocean Exp $
|
6
|
+
#++
|
7
|
+
#
|
8
|
+
# = generator.rb: convert an internal iterator to an external one
|
9
|
+
#
|
10
|
+
# Copyright (c) 2001,2003 Akinori MUSHA <knu@iDaemons.org>
|
11
|
+
#
|
12
|
+
# All rights reserved. You can redistribute and/or modify it under
|
13
|
+
# the same terms as Ruby.
|
14
|
+
#
|
15
|
+
# == Overview
|
16
|
+
#
|
17
|
+
# This library provides the Generator class, which converts an
|
18
|
+
# internal iterator (i.e. an Enumerable object) to an external
|
19
|
+
# iterator. In that form, you can roll many iterators independently.
|
20
|
+
#
|
21
|
+
# The SyncEnumerator class, which is implemented using Generator,
|
22
|
+
# makes it easy to roll many Enumerable objects synchronously.
|
23
|
+
#
|
24
|
+
# See the respective classes for examples of usage.
|
25
|
+
|
26
|
+
|
27
|
+
#
|
28
|
+
# Generator converts an internal iterator (i.e. an Enumerable object)
|
29
|
+
# to an external iterator.
|
30
|
+
#
|
31
|
+
# == Example
|
32
|
+
#
|
33
|
+
# require 'generator'
|
34
|
+
#
|
35
|
+
# # Generator from an Enumerable object
|
36
|
+
# g = Generator.new(['A', 'B', 'C', 'Z'])
|
37
|
+
#
|
38
|
+
# while g.next?
|
39
|
+
# puts g.next
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # Generator from a block
|
43
|
+
# g = Generator.new { |g|
|
44
|
+
# for i in 'A'..'C'
|
45
|
+
# g.yield i
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# g.yield 'Z'
|
49
|
+
# }
|
50
|
+
#
|
51
|
+
# # The same result as above
|
52
|
+
# while g.next?
|
53
|
+
# puts g.next
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
class Generator
|
57
|
+
include Enumerable
|
58
|
+
|
59
|
+
# Creates a new generator either from an Enumerable object or from a
|
60
|
+
# block.
|
61
|
+
#
|
62
|
+
# In the former, block is ignored even if given.
|
63
|
+
#
|
64
|
+
# In the latter, the given block is called with the generator
|
65
|
+
# itself, and expected to call the +yield+ method for each element.
|
66
|
+
def initialize(enum = nil, &block)
|
67
|
+
if enum
|
68
|
+
@block = proc{|g| enum.each{|value| g.yield value}}
|
69
|
+
else
|
70
|
+
@block = block
|
71
|
+
end
|
72
|
+
@index = 0
|
73
|
+
@queue = []
|
74
|
+
@main_thread = nil
|
75
|
+
@loop_thread.kill if defined?(@loop_thread)
|
76
|
+
@loop_thread = Thread.new do
|
77
|
+
Thread.stop
|
78
|
+
begin
|
79
|
+
@block.call(self)
|
80
|
+
rescue
|
81
|
+
@main_thread.raise $!
|
82
|
+
ensure
|
83
|
+
@main_thread.wakeup
|
84
|
+
end
|
85
|
+
end
|
86
|
+
Thread.pass until @loop_thread.stop?
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
# Yields an element to the generator.
|
91
|
+
def yield(value)
|
92
|
+
if Thread.current != @loop_thread
|
93
|
+
raise "should be called in Generator.new{|g| ... }"
|
94
|
+
end
|
95
|
+
Thread.critical = true
|
96
|
+
begin
|
97
|
+
@queue << value
|
98
|
+
@main_thread.wakeup
|
99
|
+
Thread.stop
|
100
|
+
ensure
|
101
|
+
Thread.critical = false
|
102
|
+
end
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns true if the generator has reached the end.
|
107
|
+
def end?
|
108
|
+
if @queue.empty?
|
109
|
+
if @main_thread
|
110
|
+
raise "should not be called in Generator.new{|g| ... }"
|
111
|
+
end
|
112
|
+
Thread.critical = true
|
113
|
+
begin
|
114
|
+
@main_thread = Thread.current
|
115
|
+
@loop_thread.wakeup
|
116
|
+
Thread.stop
|
117
|
+
rescue ThreadError
|
118
|
+
# ignore
|
119
|
+
ensure
|
120
|
+
@main_thread = nil
|
121
|
+
Thread.critical = false
|
122
|
+
end
|
123
|
+
end
|
124
|
+
@queue.empty?
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns true if the generator has not reached the end yet.
|
128
|
+
def next?
|
129
|
+
!end?
|
130
|
+
end
|
131
|
+
|
132
|
+
# Returns the current index (position) counting from zero.
|
133
|
+
def index
|
134
|
+
@index
|
135
|
+
end
|
136
|
+
|
137
|
+
# Returns the current index (position) counting from zero.
|
138
|
+
def pos
|
139
|
+
@index
|
140
|
+
end
|
141
|
+
|
142
|
+
# Returns the element at the current position and moves forward.
|
143
|
+
def next
|
144
|
+
raise EOFError.new("no more elements available") if end?
|
145
|
+
@index += 1
|
146
|
+
@queue.shift
|
147
|
+
end
|
148
|
+
|
149
|
+
# Returns the element at the current position.
|
150
|
+
def current
|
151
|
+
raise EOFError.new("no more elements available") if end?
|
152
|
+
@queue.first
|
153
|
+
end
|
154
|
+
|
155
|
+
# Rewinds the generator.
|
156
|
+
def rewind
|
157
|
+
initialize(nil, &@block) if @index.nonzero?
|
158
|
+
self
|
159
|
+
end
|
160
|
+
|
161
|
+
# Rewinds the generator and enumerates the elements.
|
162
|
+
def each
|
163
|
+
rewind
|
164
|
+
until end?
|
165
|
+
yield self.next
|
166
|
+
end
|
167
|
+
self
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
#
|
172
|
+
# SyncEnumerator creates an Enumerable object from multiple Enumerable
|
173
|
+
# objects and enumerates them synchronously.
|
174
|
+
#
|
175
|
+
# == Example
|
176
|
+
#
|
177
|
+
# require 'generator'
|
178
|
+
#
|
179
|
+
# s = SyncEnumerator.new([1,2,3], ['a', 'b', 'c'])
|
180
|
+
#
|
181
|
+
# # Yields [1, 'a'], [2, 'b'], and [3,'c']
|
182
|
+
# s.each { |row| puts row.join(', ') }
|
183
|
+
#
|
184
|
+
class SyncEnumerator
|
185
|
+
include Enumerable
|
186
|
+
|
187
|
+
# Creates a new SyncEnumerator which enumerates rows of given
|
188
|
+
# Enumerable objects.
|
189
|
+
def initialize(*enums)
|
190
|
+
@gens = enums.map { |e| Generator.new(e) }
|
191
|
+
end
|
192
|
+
|
193
|
+
# Returns the number of enumerated Enumerable objects, i.e. the size
|
194
|
+
# of each row.
|
195
|
+
def size
|
196
|
+
@gens.size
|
197
|
+
end
|
198
|
+
|
199
|
+
# Returns the number of enumerated Enumerable objects, i.e. the size
|
200
|
+
# of each row.
|
201
|
+
def length
|
202
|
+
@gens.length
|
203
|
+
end
|
204
|
+
|
205
|
+
# Returns true if the given nth Enumerable object has reached the
|
206
|
+
# end. If no argument is given, returns true if any of the
|
207
|
+
# Enumerable objects has reached the end.
|
208
|
+
def end?(i = nil)
|
209
|
+
if i.nil?
|
210
|
+
@gens.detect { |g| g.end? } ? true : false
|
211
|
+
else
|
212
|
+
@gens[i].end?
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# Enumerates rows of the Enumerable objects.
|
217
|
+
def each
|
218
|
+
@gens.each { |g| g.rewind }
|
219
|
+
|
220
|
+
loop do
|
221
|
+
count = 0
|
222
|
+
|
223
|
+
ret = @gens.map { |g|
|
224
|
+
if g.end?
|
225
|
+
count += 1
|
226
|
+
nil
|
227
|
+
else
|
228
|
+
g.next
|
229
|
+
end
|
230
|
+
}
|
231
|
+
|
232
|
+
if count == @gens.size
|
233
|
+
break
|
234
|
+
end
|
235
|
+
|
236
|
+
yield ret
|
237
|
+
end
|
238
|
+
|
239
|
+
self
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
if $0 == __FILE__
|
244
|
+
eval DATA.read, nil, $0, __LINE__+4
|
245
|
+
end
|
246
|
+
|
247
|
+
__END__
|
248
|
+
|
249
|
+
require 'test/unit'
|
250
|
+
|
251
|
+
class TC_Generator < Test::Unit::TestCase
|
252
|
+
def test_block1
|
253
|
+
g = Generator.new { |g|
|
254
|
+
# no yield's
|
255
|
+
}
|
256
|
+
|
257
|
+
assert_equal(0, g.pos)
|
258
|
+
assert_raises(EOFError) { g.current }
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_block2
|
262
|
+
g = Generator.new { |g|
|
263
|
+
for i in 'A'..'C'
|
264
|
+
g.yield i
|
265
|
+
end
|
266
|
+
|
267
|
+
g.yield 'Z'
|
268
|
+
}
|
269
|
+
|
270
|
+
assert_equal(0, g.pos)
|
271
|
+
assert_equal('A', g.current)
|
272
|
+
|
273
|
+
assert_equal(true, g.next?)
|
274
|
+
assert_equal(0, g.pos)
|
275
|
+
assert_equal('A', g.current)
|
276
|
+
assert_equal(0, g.pos)
|
277
|
+
assert_equal('A', g.next)
|
278
|
+
|
279
|
+
assert_equal(1, g.pos)
|
280
|
+
assert_equal(true, g.next?)
|
281
|
+
assert_equal(1, g.pos)
|
282
|
+
assert_equal('B', g.current)
|
283
|
+
assert_equal(1, g.pos)
|
284
|
+
assert_equal('B', g.next)
|
285
|
+
|
286
|
+
assert_equal(g, g.rewind)
|
287
|
+
|
288
|
+
assert_equal(0, g.pos)
|
289
|
+
assert_equal('A', g.current)
|
290
|
+
|
291
|
+
assert_equal(true, g.next?)
|
292
|
+
assert_equal(0, g.pos)
|
293
|
+
assert_equal('A', g.current)
|
294
|
+
assert_equal(0, g.pos)
|
295
|
+
assert_equal('A', g.next)
|
296
|
+
|
297
|
+
assert_equal(1, g.pos)
|
298
|
+
assert_equal(true, g.next?)
|
299
|
+
assert_equal(1, g.pos)
|
300
|
+
assert_equal('B', g.current)
|
301
|
+
assert_equal(1, g.pos)
|
302
|
+
assert_equal('B', g.next)
|
303
|
+
|
304
|
+
assert_equal(2, g.pos)
|
305
|
+
assert_equal(true, g.next?)
|
306
|
+
assert_equal(2, g.pos)
|
307
|
+
assert_equal('C', g.current)
|
308
|
+
assert_equal(2, g.pos)
|
309
|
+
assert_equal('C', g.next)
|
310
|
+
|
311
|
+
assert_equal(3, g.pos)
|
312
|
+
assert_equal(true, g.next?)
|
313
|
+
assert_equal(3, g.pos)
|
314
|
+
assert_equal('Z', g.current)
|
315
|
+
assert_equal(3, g.pos)
|
316
|
+
assert_equal('Z', g.next)
|
317
|
+
|
318
|
+
assert_equal(4, g.pos)
|
319
|
+
assert_equal(false, g.next?)
|
320
|
+
assert_raises(EOFError) { g.next }
|
321
|
+
end
|
322
|
+
|
323
|
+
def test_each
|
324
|
+
a = [5, 6, 7, 8, 9]
|
325
|
+
|
326
|
+
g = Generator.new(a)
|
327
|
+
|
328
|
+
i = 0
|
329
|
+
|
330
|
+
g.each { |x|
|
331
|
+
assert_equal(a[i], x)
|
332
|
+
|
333
|
+
i += 1
|
334
|
+
|
335
|
+
break if i == 3
|
336
|
+
}
|
337
|
+
|
338
|
+
assert_equal(3, i)
|
339
|
+
|
340
|
+
i = 0
|
341
|
+
|
342
|
+
g.each { |x|
|
343
|
+
assert_equal(a[i], x)
|
344
|
+
|
345
|
+
i += 1
|
346
|
+
}
|
347
|
+
|
348
|
+
assert_equal(5, i)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
class TC_SyncEnumerator < Test::Unit::TestCase
|
353
|
+
def test_each
|
354
|
+
r = ['a'..'f', 1..10, 10..20]
|
355
|
+
ra = r.map { |x| x.to_a }
|
356
|
+
|
357
|
+
a = (0...(ra.map {|x| x.size}.max)).map { |i| ra.map { |x| x[i] } }
|
358
|
+
|
359
|
+
s = SyncEnumerator.new(*r)
|
360
|
+
|
361
|
+
i = 0
|
362
|
+
|
363
|
+
s.each { |x|
|
364
|
+
assert_equal(a[i], x)
|
365
|
+
|
366
|
+
i += 1
|
367
|
+
|
368
|
+
break if i == 3
|
369
|
+
}
|
370
|
+
|
371
|
+
assert_equal(3, i)
|
372
|
+
|
373
|
+
i = 0
|
374
|
+
|
375
|
+
s.each { |x|
|
376
|
+
assert_equal(a[i], x)
|
377
|
+
|
378
|
+
i += 1
|
379
|
+
}
|
380
|
+
|
381
|
+
assert_equal(a.size, i)
|
382
|
+
end
|
383
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: moserp-s3sync
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ""
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-10-06 00:00:00 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: ""
|
18
|
+
executables:
|
19
|
+
- s3sync
|
20
|
+
- s3cmd
|
21
|
+
extensions: []
|
22
|
+
|
23
|
+
extra_rdoc_files:
|
24
|
+
- README
|
25
|
+
- README_s3cmd
|
26
|
+
files:
|
27
|
+
- lib/HTTPStreaming.rb
|
28
|
+
- lib/S3.rb
|
29
|
+
- lib/S3_s3sync_mod.rb
|
30
|
+
- lib/S3encoder.rb
|
31
|
+
- lib/s3config.rb
|
32
|
+
- lib/s3try.rb
|
33
|
+
- lib/thread_generator.rb
|
34
|
+
- bin/s3cmd
|
35
|
+
- bin/s3sync
|
36
|
+
- README
|
37
|
+
- README_s3cmd
|
38
|
+
has_rdoc: true
|
39
|
+
homepage: http://s3sync.net/
|
40
|
+
licenses: []
|
41
|
+
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.5
|
63
|
+
signing_key:
|
64
|
+
specification_version: 3
|
65
|
+
summary: rsync-like client for backing up to Amazons S3
|
66
|
+
test_files: []
|
67
|
+
|