facets 1.8.0 → 1.8.8

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