rocketjob 5.2.0.beta1 → 5.3.1

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.
@@ -1,524 +0,0 @@
1
- #--
2
- # Copyright (c) 2006-2017, John Mettraux, jmettraux@gmail.com
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining a copy
5
- # of this software and associated documentation files (the "Software"), to deal
6
- # in the Software without restriction, including without limitation the rights
7
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- # copies of the Software, and to permit persons to whom the Software is
9
- # furnished to do so, subject to the following conditions:
10
- #
11
- # The above copyright notice and this permission notice shall be included in
12
- # all copies or substantial portions of the Software.
13
- #
14
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
- # THE SOFTWARE.
21
- #
22
- # Made in Japan.
23
- #++
24
- #@formatter:off
25
-
26
- module RocketJob::Plugins::Rufus
27
- #
28
- # Zon{ing|ed}Time, whatever.
29
- #
30
- class ZoTime
31
-
32
- attr_reader :seconds
33
- attr_reader :zone
34
-
35
- def initialize(s, zone)
36
-
37
- @seconds = s.to_f
38
- @zone = self.class.get_tzone(zone || :current)
39
-
40
- fail ArgumentError.new(
41
- "cannot determine timezone from #{zone.inspect}" +
42
- " (etz:#{ENV['TZ'].inspect},tnz:#{Time.now.zone.inspect}," +
43
- "tzid:#{defined?(TZInfo::Data).inspect})\n" +
44
- "Try setting `ENV['TZ'] = 'Continent/City'` in your script " +
45
- "(see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)" +
46
- (defined?(TZInfo::Data) ? '' : " and adding 'tzinfo-data' to your gems")
47
- ) unless @zone
48
-
49
- @time = nil # cache for #to_time result
50
- end
51
-
52
- def seconds=(f)
53
-
54
- @time = nil
55
- @seconds = f
56
- end
57
-
58
- def zone=(z)
59
-
60
- @time = nil
61
- @zone = self.class.get_tzone(zone || :current)
62
- end
63
-
64
- def utc
65
-
66
- Time.utc(1970, 1, 1) + @seconds
67
- end
68
-
69
- # Returns a Ruby Time instance.
70
- #
71
- # Warning: the timezone of that Time instance will be UTC.
72
- #
73
- def to_time
74
-
75
- @time ||= begin; u = utc; @zone.period_for_utc(u).to_local(u); end
76
- end
77
-
78
- %w[
79
- year month day wday hour min sec usec asctime
80
- ].each do |m|
81
- define_method(m) { to_time.send(m) }
82
- end
83
- def iso8601(fraction_digits=0); to_time.iso8601(fraction_digits); end
84
-
85
- def ==(o)
86
-
87
- o.is_a?(ZoTime) && o.seconds == @seconds && o.zone == @zone
88
- end
89
- #alias eq? == # FIXME see Object#== (ri)
90
-
91
- def >(o); @seconds > _to_f(o); end
92
- def >=(o); @seconds >= _to_f(o); end
93
- def <(o); @seconds < _to_f(o); end
94
- def <=(o); @seconds <= _to_f(o); end
95
- def <=>(o); @seconds <=> _to_f(o); end
96
-
97
- alias getutc utc
98
- alias getgm utc
99
-
100
- def to_i
101
-
102
- @seconds.to_i
103
- end
104
-
105
- def to_f
106
-
107
- @seconds
108
- end
109
-
110
- def is_dst?
111
-
112
- @zone.period_for_utc(utc).std_offset != 0
113
- end
114
- alias isdst is_dst?
115
-
116
- def utc_offset
117
-
118
- #@zone.period_for_utc(utc).utc_offset
119
- #@zone.period_for_utc(utc).utc_total_offset
120
- #@zone.period_for_utc(utc).std_offset
121
- @zone.period_for_utc(utc).utc_offset
122
- end
123
-
124
- def strftime(format)
125
-
126
- format = format.gsub(/%(\/?Z|:{0,2}z)/) { |f| strfz(f) }
127
-
128
- to_time.strftime(format)
129
- end
130
-
131
- def add(t); @time = nil; @seconds += t.to_f; end
132
- def substract(t); @time = nil; @seconds -= t.to_f; end
133
-
134
- def +(t); inc(t, 1); end
135
- def -(t); inc(t, -1); end
136
-
137
- WEEK_S = 7 * 24 * 3600
138
-
139
- def monthdays
140
-
141
- date = to_time
142
-
143
- pos = 1
144
- d = self.dup
145
-
146
- loop do
147
- d.add(-WEEK_S)
148
- break if d.month != date.month
149
- pos = pos + 1
150
- end
151
-
152
- neg = -1
153
- d = self.dup
154
-
155
- loop do
156
- d.add(WEEK_S)
157
- break if d.month != date.month
158
- neg = neg - 1
159
- end
160
-
161
- [ "#{date.wday}##{pos}", "#{date.wday}##{neg}" ]
162
- end
163
-
164
- def to_s
165
-
166
- strftime('%Y-%m-%d %H:%M:%S %z')
167
- end
168
-
169
- def to_debug_s
170
-
171
- uo = self.utc_offset
172
- uos = uo < 0 ? '-' : '+'
173
- uo = uo.abs
174
- uoh, uom = [ uo / 3600, uo % 3600 ]
175
-
176
- [
177
- 'zt',
178
- self.strftime('%Y-%m-%d %H:%M:%S'),
179
- "%s%02d:%02d" % [ uos, uoh, uom ],
180
- "dst:#{self.isdst}"
181
- ].join(' ')
182
- end
183
-
184
- # Debug current time by showing local time / delta / utc time
185
- # for example: "0120-7(0820)"
186
- #
187
- def to_utc_comparison_s
188
-
189
- per = @zone.period_for_utc(utc)
190
- off = per.utc_total_offset
191
-
192
- off = off / 3600
193
- off = off >= 0 ? "+#{off}" : off.to_s
194
-
195
- strftime('%H%M') + off + utc.strftime('(%H%M)')
196
- end
197
-
198
- def to_time_s
199
-
200
- strftime("%H:%M:%S.#{'%06d' % usec}")
201
- end
202
-
203
- def self.now(zone=nil)
204
-
205
- ZoTime.new(Time.now.to_f, zone)
206
- end
207
-
208
- # https://en.wikipedia.org/wiki/ISO_8601
209
- # Postel's law applies
210
- #
211
- def self.extract_iso8601_zone(s)
212
-
213
- m = s.match(
214
- /[0-2]\d(?::?[0-6]\d(?::?[0-6]\d))?\s*([+-]\d\d(?::?\d\d)?)\s*\z/)
215
- return nil unless m
216
-
217
- zs = m[1].split(':')
218
- zs << '00' if zs.length < 2
219
-
220
- zh = zs[0].to_i.abs
221
-
222
- return nil if zh > 24
223
- return nil if zh == 24 && zs[1].to_i != 0
224
-
225
- zs.join(':')
226
- end
227
-
228
- def self.parse(str, opts={})
229
-
230
- if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
231
- return ZoTime.new(t, nil)
232
- end
233
-
234
- #rold = RUBY_VERSION < '1.9.0'
235
- #rold = RUBY_VERSION < '2.0.0'
236
-
237
- begin
238
- DateTime.parse(str)
239
- rescue
240
- fail ArgumentError, "no time information in #{str.inspect}"
241
- end #if rold
242
- #
243
- # is necessary since Time.parse('xxx') in Ruby < 1.9 yields `now`
244
-
245
- zone = nil
246
-
247
- s =
248
- str.gsub(/\S+/) do |w|
249
- if z = get_tzone(w)
250
- zone ||= z
251
- ''
252
- else
253
- w
254
- end
255
- end
256
-
257
- local = Time.parse(s)
258
- izone = extract_iso8601_zone(s)
259
-
260
- zone ||=
261
- if s.match(/\dZ\b/)
262
- get_tzone('Zulu')
263
- #elsif rold && izone
264
- elsif izone
265
- get_tzone(izone)
266
- elsif local.zone.nil? && izone
267
- get_tzone(local.strftime('%:z'))
268
- else
269
- get_tzone(:local)
270
- end
271
-
272
- secs =
273
- #if rold && izone
274
- if izone
275
- local.to_f
276
- else
277
- zone.period_for_local(local).to_utc(local).to_f
278
- end
279
-
280
- ZoTime.new(secs, zone)
281
- end
282
-
283
- def self.get_tzone(str)
284
-
285
- return str if str.is_a?(::TZInfo::Timezone)
286
-
287
- # discard quickly when it's certainly not a timezone
288
-
289
- return nil if str == nil
290
- return nil if str == '*'
291
-
292
- ostr = str
293
- str = :current if str == :local
294
-
295
- # use Rails' zone by default if Rails is present
296
-
297
- return Time.zone.tzinfo if (
298
- ENV['TZ'].nil? && str == :current &&
299
- Time.respond_to?(:zone) && Time.zone.respond_to?(:tzinfo)
300
- )
301
-
302
- # ok, it's a timezone then
303
-
304
- str = ENV['TZ'] || Time.now.zone if str == :current
305
-
306
- # utc_offset
307
-
308
- if str.is_a?(Numeric)
309
- i = str.to_i
310
- sn = i < 0 ? '-' : '+'; i = i.abs
311
- hr = i / 3600; mn = i % 3600; sc = i % 60
312
- str = (sc > 0 ? "%s%02d:%02d:%02d" : "%s%02d:%02d") % [ sn, hr, mn, sc ]
313
- end
314
-
315
- return nil if str.index('#')
316
- # counters "sun#2", etc... On OSX would go all the way to true
317
-
318
- # vanilla time zones
319
-
320
- z = (::TZInfo::Timezone.get(str) rescue nil)
321
- return z if z
322
-
323
- # time zone abbreviations
324
-
325
- if str.match(/\A[A-Z0-9-]{3,6}\z/)
326
-
327
- toff = Time.now.utc_offset
328
- toff = nil if str != Time.now.zone
329
-
330
- twin = Time.utc(Time.now.year, 1, 1) # winter
331
- tsum = Time.utc(Time.now.year, 7, 1) # summer
332
-
333
- z =
334
- ::TZInfo::Timezone.all.find do |tz|
335
-
336
- pwin = tz.period_for_utc(twin)
337
- psum = tz.period_for_utc(tsum)
338
-
339
- if toff
340
- (pwin.abbreviation.to_s == str && pwin.utc_offset == toff) ||
341
- (psum.abbreviation.to_s == str && psum.utc_offset == toff)
342
- else
343
- # returns the first tz with the given abbreviation, almost useless
344
- # favour fully named zones...
345
- pwin.abbreviation.to_s == str ||
346
- psum.abbreviation.to_s == str
347
- end
348
- end
349
- return z if z
350
- end
351
-
352
- # some time zone aliases
353
-
354
- return ::TZInfo::Timezone.get('Zulu') if %w[ Z ].include?(str)
355
-
356
- # custom timezones, no DST, just an offset, like "+08:00" or "-01:30"
357
-
358
- tz = (@custom_tz_cache ||= {})[str]
359
- return tz if tz
360
-
361
- if m = str.match(/\A([+-][0-1][0-9]):?([0-5][0-9])\z/)
362
-
363
- hr = m[1].to_i
364
- mn = m[2].to_i
365
-
366
- hr = nil if hr.abs > 11
367
- hr = nil if mn > 59
368
- mn = -mn if hr && hr < 0
369
-
370
- return (
371
- @custom_tz_cache[str] =
372
- begin
373
- tzi = TZInfo::TransitionDataTimezoneInfo.new(str)
374
- tzi.offset(str, hr * 3600 + mn * 60, 0, str)
375
- tzi.create_timezone
376
- end
377
- ) if hr
378
- end
379
-
380
- # try with ENV['TZ']
381
-
382
- z = ostr == :current && (::TZInfo::Timezone.get(ENV['TZ']) rescue nil)
383
- return z if z
384
-
385
- # ask the system
386
-
387
- z = ostr == :current && (debian_tz || centos_tz || osx_tz)
388
- return z if z
389
-
390
- # so it's not a timezone.
391
-
392
- nil
393
- end
394
-
395
- def self.debian_tz
396
-
397
- path = '/etc/timezone'
398
-
399
- File.exist?(path) &&
400
- (::TZInfo::Timezone.get(File.read(path).strip) rescue nil)
401
- end
402
-
403
- def self.centos_tz
404
-
405
- path = '/etc/sysconfig/clock'
406
-
407
- File.open(path, 'rb') do |f|
408
- until f.eof?
409
- m = f.readline.match(/ZONE="([^"]+)"/)
410
- return (::TZInfo::Timezone.get(m[1]) rescue nil) if m
411
- end
412
- end if File.exist?(path)
413
-
414
- nil
415
- end
416
-
417
- def self.osx_tz
418
-
419
- path = '/etc/localtime'
420
-
421
- return nil unless File.exist?(path)
422
-
423
- ::TZInfo::Timezone.get(
424
- File.readlink(path).split('/')[4..-1].join('/')
425
- ) rescue nil
426
- end
427
-
428
- def self.local_tzone
429
-
430
- get_tzone(:local)
431
- end
432
-
433
- def self.make(o)
434
-
435
- zt =
436
- case o
437
- when Time
438
- ZoTime.new(o.to_f, o.zone)
439
- when Date
440
- t =
441
- o.respond_to?(:to_time) ?
442
- o.to_time :
443
- Time.parse(o.strftime('%Y-%m-%d %H:%M:%S'))
444
- ZoTime.new(t.to_f, t.zone)
445
- when String
446
- Rufus::Scheduler.parse_in(o, :no_error => true) || self.parse(o)
447
- else
448
- o
449
- end
450
-
451
- zt = ZoTime.new(Time.now.to_f + zt, nil) if zt.is_a?(Numeric)
452
-
453
- fail ArgumentError.new(
454
- "cannot turn #{o.inspect} to a ZoTime instance"
455
- ) unless zt.is_a?(ZoTime)
456
-
457
- zt
458
- end
459
-
460
- # def in_zone(&block)
461
- #
462
- # current_timezone = ENV['TZ']
463
- # ENV['TZ'] = @zone
464
- #
465
- # block.call
466
- #
467
- # ensure
468
- #
469
- # ENV['TZ'] = current_timezone
470
- # end
471
-
472
- protected
473
-
474
- def inc(t, dir)
475
-
476
- if t.is_a?(Numeric)
477
- nt = self.dup
478
- nt.seconds += dir * t.to_f
479
- nt
480
- elsif t.respond_to?(:to_f)
481
- @seconds + dir * t.to_f
482
- else
483
- fail ArgumentError.new(
484
- "cannot call ZoTime #- or #+ with arg of class #{t.class}")
485
- end
486
- end
487
-
488
- def _to_f(o)
489
-
490
- fail ArgumentError(
491
- "comparison of ZoTime with #{o.inspect} failed"
492
- ) unless o.is_a?(ZoTime) || o.is_a?(Time)
493
-
494
- o.to_f
495
- end
496
-
497
- def strfz(code)
498
-
499
- return @zone.name if code == '%/Z'
500
-
501
- per = @zone.period_for_utc(utc)
502
-
503
- return per.abbreviation.to_s if code == '%Z'
504
-
505
- off = per.utc_total_offset
506
- #
507
- sn = off < 0 ? '-' : '+'; off = off.abs
508
- hr = off / 3600
509
- mn = (off % 3600) / 60
510
- sc = 0
511
-
512
- fmt =
513
- if code == '%z'
514
- "%s%02d%02d"
515
- elsif code == '%:z'
516
- "%s%02d:%02d"
517
- else
518
- "%s%02d:%02d:%02d"
519
- end
520
-
521
- fmt % [ sn, hr, mn, sc ]
522
- end
523
- end
524
- end