facets 1.8.0 → 1.8.8
Sign up to get free protection for your applications and to get access to all the features.
- data/PROJECT +4 -4
- data/Rakefile +19 -14
- data/VERSION +1 -1
- data/lib/facet/enumerable/cart.rb +1 -0
- data/lib/facet/enumerable/cartesian_product.rb +1 -0
- data/lib/facet/enumerable/self/cart.rb +1 -0
- data/lib/facet/enumerable/self/cartesian_product.rb +1 -0
- data/lib/facets.rb +2 -1
- data/lib/facets/core/dir/self/multiglob_sum.rb +2 -0
- data/lib/facets/core/enumerable/cart.rb +119 -0
- data/lib/facets/core/enumerable/cartesian_product.rb +8 -0
- data/lib/facets/core/enumerable/self/cart.rb +120 -0
- data/lib/facets/core/enumerable/self/cartesian_product.rb +8 -0
- data/lib/facets/core/string/singular.rb +7 -7
- data/lib/facets/more/ann.rb +6 -5
- data/lib/facets/more/ann_attr.rb +11 -14
- data/lib/facets/more/autovivify.rb +2 -2
- data/lib/facets/more/dictionary.rb +63 -69
- data/lib/facets/more/opencascade.rb +3 -3
- data/lib/facets/more/openobject.rb +318 -9
- data/lib/facets/more/times.rb +129 -43
- data/lib/facets/more/uploadutils.rb +248 -43
- data/work/hash_open.rb +23 -0
- data/work/openobject-temp.rb +45 -0
- metadata +13 -9
- data/lib/facet/enumerable/cross.rb +0 -1
- data/lib/facet/enumerable/self/cross.rb +0 -1
- data/lib/facet/openhash.rb +0 -1
- data/lib/facets/core/enumerable/cross.rb +0 -47
- data/lib/facets/core/enumerable/self/cross.rb +0 -85
- data/lib/facets/more/openhash.rb +0 -350
data/lib/facets/more/times.rb
CHANGED
@@ -13,13 +13,22 @@
|
|
13
13
|
#
|
14
14
|
# == SPECIAL THANKS
|
15
15
|
#
|
16
|
-
# Thanks to Richard Kilmer for the orignal work and
|
17
|
-
#
|
16
|
+
# Thanks to Richard Kilmer for the orignal work and Alexander Kellett
|
17
|
+
# for suggesting it for Facets.
|
18
|
+
#
|
19
|
+
# Thanks to Dave Hoover and Ryan Platte for the Weekdays implementation.
|
18
20
|
#
|
19
21
|
# == Author(s)
|
20
22
|
#
|
21
23
|
# * Rich Kilmer
|
22
24
|
# * Thomas Sawyer
|
25
|
+
# * Dave Hoover
|
26
|
+
# * Ryan Platte
|
27
|
+
#
|
28
|
+
# CREDIT Rich Kilmer
|
29
|
+
# CREDIT Thomas Sawyer
|
30
|
+
# CREDIT Dave Hoover
|
31
|
+
# CREDIT Ryan Platte
|
23
32
|
#
|
24
33
|
# == Developer Notes
|
25
34
|
#
|
@@ -98,8 +107,55 @@ class Numeric
|
|
98
107
|
alias_method :from_now, :after # Reads best without arguments: 10.minutes.from_now
|
99
108
|
alias_method :later, :after # Reads best without arguments: 10.minutes.later
|
100
109
|
|
110
|
+
# Works with day in terms of weekdays.
|
111
|
+
def weekdays
|
112
|
+
Weekdays.new(self)
|
113
|
+
end
|
114
|
+
alias :weekday :weekdays
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# The Weekdays class provides useful weekday terminology to Numeric.
|
120
|
+
|
121
|
+
class Weekdays
|
122
|
+
WEEKDAYS = 1..5 # Monday is wday 1
|
123
|
+
ONE_DAY = 60 * 60 * 24
|
124
|
+
|
125
|
+
def initialize(n)
|
126
|
+
@n = n
|
127
|
+
end
|
128
|
+
|
129
|
+
def ago(time = ::Time.now)
|
130
|
+
step :down, time
|
131
|
+
end
|
132
|
+
alias :until :ago
|
133
|
+
alias :before :ago
|
134
|
+
|
135
|
+
def since(time = ::Time.now)
|
136
|
+
step :up, time
|
137
|
+
end
|
138
|
+
alias :from_now :since
|
139
|
+
alias :after :since
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def step(direction, original_time)
|
144
|
+
result = original_time
|
145
|
+
time = ONE_DAY
|
146
|
+
|
147
|
+
compare = direction == :up ? ">" : "<"
|
148
|
+
time *= -1 if direction == :down
|
149
|
+
|
150
|
+
@n.times do
|
151
|
+
result += time until result.send(compare, original_time) && WEEKDAYS.member?(result.wday)
|
152
|
+
original_time = result
|
153
|
+
end
|
154
|
+
result
|
155
|
+
end
|
101
156
|
end
|
102
157
|
|
158
|
+
|
103
159
|
class Time
|
104
160
|
|
105
161
|
NEVER = Time.mktime(2038)
|
@@ -267,61 +323,91 @@ end
|
|
267
323
|
|
268
324
|
=begin testing
|
269
325
|
|
270
|
-
require 'test/unit'
|
271
|
-
#require 'mega/multiplier'
|
326
|
+
require 'test/unit'
|
327
|
+
#require 'mega/multiplier'
|
272
328
|
|
273
|
-
class
|
329
|
+
class NumericTest < Test::Unit::TestCase
|
274
330
|
|
275
|
-
|
276
|
-
|
277
|
-
|
331
|
+
#def test_micro_seconds
|
332
|
+
# assert_equal( 0.000001, 1.microsecond )
|
333
|
+
#end
|
278
334
|
|
279
|
-
|
280
|
-
|
281
|
-
|
335
|
+
#def test_milli_seconds
|
336
|
+
# assert_equal( 0.001, 1.millisecond )
|
337
|
+
#end
|
282
338
|
|
283
|
-
|
284
|
-
|
285
|
-
|
339
|
+
def test_seconds
|
340
|
+
assert_equal( 60**0, 1.seconds )
|
341
|
+
end
|
286
342
|
|
287
|
-
|
288
|
-
|
289
|
-
|
343
|
+
def test_minutes
|
344
|
+
assert_equal( 60**1, 1.minutes )
|
345
|
+
end
|
290
346
|
|
291
|
-
|
292
|
-
|
293
|
-
|
347
|
+
def test_hours
|
348
|
+
assert_equal( 60**2, 1.hours )
|
349
|
+
end
|
294
350
|
|
295
|
-
|
296
|
-
|
297
|
-
|
351
|
+
def test_days
|
352
|
+
assert_equal( 24*(60**2), 1.days )
|
353
|
+
end
|
298
354
|
|
299
|
-
|
300
|
-
|
301
|
-
|
355
|
+
def test_weeks
|
356
|
+
assert_equal( 7*24*(60**2), 1.weeks )
|
357
|
+
end
|
302
358
|
|
303
|
-
|
304
|
-
|
305
|
-
|
359
|
+
def test_fortnights
|
360
|
+
assert_equal( 14*24*(60**2), 1.fortnights )
|
361
|
+
end
|
306
362
|
|
307
|
-
|
308
|
-
|
309
|
-
|
363
|
+
def test_months
|
364
|
+
assert_equal( 30*24*(60**2), 1.months )
|
365
|
+
end
|
310
366
|
|
311
|
-
|
312
|
-
|
313
|
-
|
367
|
+
def test_years
|
368
|
+
assert_equal( 365*24*(60**2), 1.years )
|
369
|
+
end
|
314
370
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
371
|
+
def test_before
|
372
|
+
t = Time.now
|
373
|
+
assert_equal( t - 1.day, 1.day.before(t) )
|
374
|
+
end
|
375
|
+
|
376
|
+
def test_after
|
377
|
+
t = Time.now
|
378
|
+
assert_equal( t + 1.day, 1.day.after(t) )
|
379
|
+
end
|
319
380
|
|
320
|
-
def test_after
|
321
|
-
t = Time.now
|
322
|
-
assert_equal( t + 1.day, 1.day.after(t) )
|
323
381
|
end
|
324
382
|
|
325
|
-
|
383
|
+
class WeekdaysTest < Test::Unit::TestCase
|
384
|
+
|
385
|
+
MONDAY = Time.at(1165250000)
|
386
|
+
THURSDAY = Time.at(1165500000)
|
387
|
+
FRIDAY = Time.at(1165606025)
|
388
|
+
|
389
|
+
def test_weekday_after_monday
|
390
|
+
assert_equal 2, 1.weekday.since(MONDAY).wday
|
391
|
+
end
|
392
|
+
|
393
|
+
def test_weekday_after_friday
|
394
|
+
assert_equal 1, 1.weekday.after(FRIDAY).wday
|
395
|
+
end
|
396
|
+
|
397
|
+
def test_weekdays_before_friday
|
398
|
+
assert_equal 2, 3.weekdays.before(FRIDAY).wday
|
399
|
+
end
|
400
|
+
|
401
|
+
#def test_weekday_before_today
|
402
|
+
# Time.expects(:now).returns(THURSDAY)
|
403
|
+
# assert_equal 3, 1.weekday.ago.wday
|
404
|
+
#end
|
405
|
+
|
406
|
+
#def test_weekdays_after_today
|
407
|
+
# Time.expects(:now).returns(MONDAY)
|
408
|
+
# assert_equal 3, 2.weekday.from_now.wday
|
409
|
+
#end
|
410
|
+
|
411
|
+
end
|
326
412
|
|
327
413
|
=end
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# = uploadutils.rb
|
2
2
|
#
|
3
|
-
# TODO Incorporate password into scp and ftp
|
3
|
+
# TODO Incorporate password into scp and ftp ?
|
4
|
+
#
|
5
|
+
# TODO rsync needs --delete option
|
6
|
+
#++
|
4
7
|
|
5
8
|
require 'openssl'
|
6
9
|
require 'shellwords'
|
@@ -44,6 +47,248 @@ require 'tmpdir'
|
|
44
47
|
module UploadUtils
|
45
48
|
|
46
49
|
module_function
|
50
|
+
|
51
|
+
#
|
52
|
+
# Upload via given protocol.
|
53
|
+
#
|
54
|
+
|
55
|
+
def upload( protocol, opts )
|
56
|
+
send(protocol.to_s.downcase,opts)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Use ftp to upload files.
|
61
|
+
#
|
62
|
+
|
63
|
+
def ftp( keys )
|
64
|
+
keys = keys.to_openhash
|
65
|
+
|
66
|
+
# set transfer rules
|
67
|
+
if keys.stage
|
68
|
+
trans = stage_transfer(keys.stage)
|
69
|
+
else
|
70
|
+
files(keys.dir, keys.copy).each do |from|
|
71
|
+
trans << [from,from]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# append location of publication dir to from
|
76
|
+
dir = keys.dir
|
77
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
78
|
+
|
79
|
+
if keys.dryrun
|
80
|
+
puts "ftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
81
|
+
keys.trans.each do |f, t|
|
82
|
+
puts "ftp put #{f} #{t}"
|
83
|
+
end
|
84
|
+
else
|
85
|
+
require 'net/ftp'
|
86
|
+
Net::FTP.open(keys.host) do |ftp|
|
87
|
+
ftp.login(keys.user) #password?
|
88
|
+
ftp.chdir(keys.root)
|
89
|
+
keys.trans.each do |f, t|
|
90
|
+
puts "ftp #{f} #{t}" unless keys.quiet
|
91
|
+
ftp.putbinaryfile( f, t, 1024 )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Use sftp to upload files.
|
99
|
+
#
|
100
|
+
|
101
|
+
def sftp( keys )
|
102
|
+
keys = keys.to_openobject
|
103
|
+
|
104
|
+
# set transfer rules
|
105
|
+
if keys.stage
|
106
|
+
trans = stage_transfer(keys.stage)
|
107
|
+
else
|
108
|
+
files(keys.dir, keys.copy).each do |from|
|
109
|
+
trans << [from,from]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# append location of publication dir to from
|
114
|
+
dir = keys.dir
|
115
|
+
trans.collect!{ |from,to| [File.join(dir,from), to] }
|
116
|
+
|
117
|
+
if keys.dryrun
|
118
|
+
puts "sftp open #{keys.user}@#{keys.host}:#{keys.root}/"
|
119
|
+
keys.trans.each do |f,t|
|
120
|
+
puts "sftp put #{f} #{t}"
|
121
|
+
end
|
122
|
+
else
|
123
|
+
require 'net/sftp'
|
124
|
+
Net::SFTP.start(keys.host, keys.user, keys.pass) do |sftp|
|
125
|
+
#sftp.login( user )
|
126
|
+
sftp.chdir(keys.root)
|
127
|
+
keys.trans.each do |f,t|
|
128
|
+
puts "sftp #{f} #{t}" unless keys.quiet
|
129
|
+
sftp.put_file(f,t) #, 1024 )
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
#
|
136
|
+
# Use rsync to upload files.
|
137
|
+
#
|
138
|
+
|
139
|
+
def rsync( keys )
|
140
|
+
keys = keys.to_openobject
|
141
|
+
|
142
|
+
flags = []
|
143
|
+
flags << "-n" if keys.dryrun
|
144
|
+
flags << "-q" if keys.quiet
|
145
|
+
flags << "-v" if keys.verbose
|
146
|
+
flags << "--progress" unless keys.quiet
|
147
|
+
flags = flags.join(' ').strip
|
148
|
+
flags = ' ' + flags unless flags.empty?
|
149
|
+
|
150
|
+
manfile = '.publish.mainfest'
|
151
|
+
|
152
|
+
if keys.stage
|
153
|
+
dir = stage_linkdir(keys.dir, keys.stage)
|
154
|
+
Dir.chdir(dir) do
|
155
|
+
cpy = files(keys.copy)
|
156
|
+
end
|
157
|
+
manifest = File.join(dir,manfile)
|
158
|
+
cmd = %{rsync#{flags} -L -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
|
159
|
+
else
|
160
|
+
dir = keys.dir
|
161
|
+
cpy = files(dir, keys.copy)
|
162
|
+
manifest = File.join(dir,manfile)
|
163
|
+
cmd = %{rsync#{flags} -arz --files-from='#{manifest}' #{dir} #{keys.user}@#{keys.host}:/#{keys.root}}
|
164
|
+
end
|
165
|
+
|
166
|
+
#Dir.chdir(keys.dir) do
|
167
|
+
begin
|
168
|
+
File.open(manifest, 'w'){ |f| f << cpy.join("\n") }
|
169
|
+
ENV['RSYNC_PASSWORD'] = keys.pass if keys.pass
|
170
|
+
puts cmd unless keys.quiet
|
171
|
+
system cmd
|
172
|
+
ensure
|
173
|
+
ENV.delete('RSYNC_PASSWORD') if keys.pass
|
174
|
+
end
|
175
|
+
#end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
# private (can't do b/c of module_function)
|
180
|
+
|
181
|
+
# parse publishing options.
|
182
|
+
|
183
|
+
def upload_parameters( keys )
|
184
|
+
keys = OpenObject.new(keys)
|
185
|
+
|
186
|
+
keys.copy = keys.copy || '**/*'
|
187
|
+
keys.host = keys.host || keys.domain
|
188
|
+
keys.user = keys.user || keys.username
|
189
|
+
keys.root = keys.root || '/'
|
190
|
+
#keys.pass = keys.pass || keys.password
|
191
|
+
|
192
|
+
# validate
|
193
|
+
raise ArgumentError, "missing publish parameter -- host" unless keys.host
|
194
|
+
raise ArgumentError, "missing publish parameter -- user" unless keys.user
|
195
|
+
raise ArgumentError, "missing publish parameter -- copy" unless keys.copy
|
196
|
+
#raise ArgumentError, "missing publish parameter -- root" unless keys.root
|
197
|
+
|
198
|
+
#keys.root = '' if keys.root.nil?
|
199
|
+
#keys.root = keys.root[1..-1] if keys.root[0,1] == '/'
|
200
|
+
keys.root = '' if opts.root.nil?
|
201
|
+
keys.root.sub!(/^\//,'')
|
202
|
+
|
203
|
+
if String===keys.copy and File.directory?(keys.copy)
|
204
|
+
copy = File.join(keys.copy, '*')
|
205
|
+
end
|
206
|
+
keys.copy = [keys.copy].flatten.compact
|
207
|
+
|
208
|
+
# trans = []
|
209
|
+
# keys.copy.each do |from|
|
210
|
+
# #from, to = *Shellwords.shellwords(c)
|
211
|
+
# #to = from if to.nil?
|
212
|
+
# #to = to[1..-1] if to[0,1] == '/'
|
213
|
+
# from.sub('*','**/*') unless from =~ /\*\*/
|
214
|
+
# files = Dir.glob(from)
|
215
|
+
# files.each do |f|
|
216
|
+
# #t = File.join(to,File.basename(f))
|
217
|
+
# #t = t[1..-1] if t[0,1] == '/'
|
218
|
+
# trans << [f,f]
|
219
|
+
# end
|
220
|
+
# end
|
221
|
+
# keys.trans = trans
|
222
|
+
|
223
|
+
return keys
|
224
|
+
end
|
225
|
+
|
226
|
+
# Put together the list of files to copy.
|
227
|
+
|
228
|
+
def files( dir, copy )
|
229
|
+
Dir.chdir(dir) do
|
230
|
+
del, add = copy.partition{ |f| /^[-]/ =~ f }
|
231
|
+
|
232
|
+
# remove - and + prefixes
|
233
|
+
del.collect!{ |f| f.sub(/^[-]/,'') }
|
234
|
+
add.collect!{ |f| f.sub(/^[+]/,'') }
|
235
|
+
|
236
|
+
del.concat(must_exclude)
|
237
|
+
|
238
|
+
files = []
|
239
|
+
add.each{ |g| files += Dir.multiglob_recurse(g) }
|
240
|
+
del.each{ |g| files -= Dir.multiglob_recurse(g) }
|
241
|
+
|
242
|
+
files.collect!{ |f| f.sub(/^\//,'') }
|
243
|
+
|
244
|
+
return files
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
# Combine three part stage list into a two part from->to list.
|
249
|
+
#
|
250
|
+
# Using the stage list of three space separated fields.
|
251
|
+
#
|
252
|
+
# fromdir file todir
|
253
|
+
#
|
254
|
+
# This is used to generate a from -> to list of the form:
|
255
|
+
#
|
256
|
+
# fromdir/file todir/file
|
257
|
+
#
|
258
|
+
|
259
|
+
def stage_transfer( list )
|
260
|
+
trans = []
|
261
|
+
list.each do |line|
|
262
|
+
trans << Shellwords.shellwords(line)
|
263
|
+
end
|
264
|
+
|
265
|
+
trans.collect! do |from, base, to|
|
266
|
+
file = File.join(from,base)
|
267
|
+
to = File.join(to,base)
|
268
|
+
[from, to]
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
# When using stage options this will create temporary linked location.
|
273
|
+
|
274
|
+
def stage_linkdir( dir, list )
|
275
|
+
folder = File.join(Dir.tmpdir, 'ratchets', 'project', object_id.abs.to_s)
|
276
|
+
FileUtils.mkdir_p(folder)
|
277
|
+
|
278
|
+
Dir.chdir(dir) do
|
279
|
+
stage_transfer(list).each do |file, to|
|
280
|
+
link = File.join(folder,to)
|
281
|
+
FileUtils.ln_s(link,file)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
return folder
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
=begin
|
290
|
+
|
291
|
+
|
47
292
|
#--
|
48
293
|
# SHELLS OUT! Need net/scp library to fix.
|
49
294
|
#++
|
@@ -134,49 +379,7 @@ module UploadUtils
|
|
134
379
|
end
|
135
380
|
end
|
136
381
|
|
137
|
-
# private (can't do b/c of module_function)
|
138
|
-
|
139
|
-
# parse publishing options.
|
140
|
-
|
141
|
-
def upload_parameters( keys )
|
142
|
-
keys = OpenHash.new(keys)
|
143
|
-
|
144
|
-
keys.copy = keys.copy || '**/*'
|
145
|
-
keys.host = keys.host || keys.domain
|
146
|
-
keys.user = keys.user || keys.username
|
147
|
-
keys.pass = keys.pass || keys.password
|
148
|
-
|
149
|
-
# validate
|
150
|
-
raise ArgumentError, "missing publish parameter -- host" unless keys.host
|
151
|
-
raise ArgumentError, "missing publish parameter -- user" unless keys.user
|
152
|
-
raise ArgumentError, "missing publish parameter -- copy" unless keys.copy
|
153
|
-
raise ArgumentError, "missing publish parameter -- root" unless keys.root
|
154
|
-
|
155
|
-
keys.root = '' if keys.root.nil?
|
156
|
-
keys.root = keys.root[1..-1] if keys.root[0,1] == '/'
|
157
|
-
|
158
|
-
if String===keys.copy and File.directory?(keys.copy)
|
159
|
-
copy = File.join(keys.copy, '*')
|
160
|
-
end
|
161
|
-
keys.copy = [keys.copy].flatten.compact
|
162
|
-
|
163
|
-
trans = []
|
164
|
-
keys.copy.each do |from|
|
165
|
-
#from, to = *Shellwords.shellwords(c)
|
166
|
-
#to = from if to.nil?
|
167
|
-
#to = to[1..-1] if to[0,1] == '/'
|
168
|
-
from.sub('*','**/*') unless from =~ /\*\*/
|
169
|
-
files = Dir.glob(from)
|
170
|
-
files.each do |f|
|
171
|
-
#t = File.join(to,File.basename(f))
|
172
|
-
#t = t[1..-1] if t[0,1] == '/'
|
173
|
-
trans << [f,f]
|
174
|
-
end
|
175
|
-
end
|
176
|
-
keys.trans = trans
|
177
382
|
|
178
|
-
return keys
|
179
|
-
end
|
180
383
|
|
181
384
|
# Creates a stage from which the whole directory can be uploaded.
|
182
385
|
# This is needed for scp and rsync which have to shelled out,
|
@@ -204,4 +407,6 @@ module UploadUtils
|
|
204
407
|
FileUtils.rm_r(tmpdir) # now remove the temp dir
|
205
408
|
end
|
206
409
|
|
410
|
+
=end
|
411
|
+
|
207
412
|
end
|