facets 1.8.0 → 1.8.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -13,13 +13,22 @@
13
13
  #
14
14
  # == SPECIAL THANKS
15
15
  #
16
- # Thanks to Richard Kilmer for the orignal work and
17
- # Alexander Kellett for suggesting it for Facets.
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 TC_Numeric < Test::Unit::TestCase
329
+ class NumericTest < Test::Unit::TestCase
274
330
 
275
- #def test_micro_seconds
276
- # assert_equal( 0.000001, 1.microsecond )
277
- #end
331
+ #def test_micro_seconds
332
+ # assert_equal( 0.000001, 1.microsecond )
333
+ #end
278
334
 
279
- #def test_milli_seconds
280
- # assert_equal( 0.001, 1.millisecond )
281
- #end
335
+ #def test_milli_seconds
336
+ # assert_equal( 0.001, 1.millisecond )
337
+ #end
282
338
 
283
- def test_seconds
284
- assert_equal( 60**0, 1.seconds )
285
- end
339
+ def test_seconds
340
+ assert_equal( 60**0, 1.seconds )
341
+ end
286
342
 
287
- def test_minutes
288
- assert_equal( 60**1, 1.minutes )
289
- end
343
+ def test_minutes
344
+ assert_equal( 60**1, 1.minutes )
345
+ end
290
346
 
291
- def test_hours
292
- assert_equal( 60**2, 1.hours )
293
- end
347
+ def test_hours
348
+ assert_equal( 60**2, 1.hours )
349
+ end
294
350
 
295
- def test_days
296
- assert_equal( 24*(60**2), 1.days )
297
- end
351
+ def test_days
352
+ assert_equal( 24*(60**2), 1.days )
353
+ end
298
354
 
299
- def test_weeks
300
- assert_equal( 7*24*(60**2), 1.weeks )
301
- end
355
+ def test_weeks
356
+ assert_equal( 7*24*(60**2), 1.weeks )
357
+ end
302
358
 
303
- def test_fortnights
304
- assert_equal( 14*24*(60**2), 1.fortnights )
305
- end
359
+ def test_fortnights
360
+ assert_equal( 14*24*(60**2), 1.fortnights )
361
+ end
306
362
 
307
- def test_months
308
- assert_equal( 30*24*(60**2), 1.months )
309
- end
363
+ def test_months
364
+ assert_equal( 30*24*(60**2), 1.months )
365
+ end
310
366
 
311
- def test_years
312
- assert_equal( 365*24*(60**2), 1.years )
313
- end
367
+ def test_years
368
+ assert_equal( 365*24*(60**2), 1.years )
369
+ end
314
370
 
315
- def test_before
316
- t = Time.now
317
- assert_equal( t - 1.day, 1.day.before(t) )
318
- end
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
- end
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