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.
@@ -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
+