rufus-scheduler 3.0.8 → 3.2.0

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,95 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, 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
+
25
+ require 'fileutils'
26
+
27
+
28
+ class Rufus::Scheduler
29
+
30
+ #
31
+ # A lock that can always be acquired
32
+ #
33
+ class NullLock
34
+
35
+ # Locking is always successful.
36
+ #
37
+ def lock; true; end
38
+
39
+ def locked?; true; end
40
+ def unlock; true; end
41
+ end
42
+
43
+ #
44
+ # The standard flock mecha, with its own class thanks to @ecin
45
+ #
46
+ class FileLock
47
+
48
+ attr_reader :path
49
+
50
+ def initialize(path)
51
+
52
+ @path = path.to_s
53
+ end
54
+
55
+ # Locking is successful if this Ruby process can create and lock
56
+ # its lockfile (at the given path).
57
+ #
58
+ def lock
59
+
60
+ return true if locked?
61
+
62
+ @lockfile = nil
63
+
64
+ FileUtils.mkdir_p(::File.dirname(@path))
65
+
66
+ file = File.new(@path, File::RDWR | File::CREAT)
67
+ locked = file.flock(File::LOCK_NB | File::LOCK_EX)
68
+
69
+ return false unless locked
70
+
71
+ now = Time.now
72
+
73
+ file.print("pid: #{$$}, ")
74
+ file.print("scheduler.object_id: #{self.object_id}, ")
75
+ file.print("time: #{now}, ")
76
+ file.print("timestamp: #{now.to_f}")
77
+ file.flush
78
+
79
+ @lockfile = file
80
+
81
+ true
82
+ end
83
+
84
+ def unlock
85
+
86
+ !! (@lockfile && @lockfile.flock(File::LOCK_UN))
87
+ end
88
+
89
+ def locked?
90
+
91
+ !! (@lockfile && @lockfile.flock(File::LOCK_NB | File::LOCK_EX))
92
+ end
93
+ end
94
+ end
95
+
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2006-2014, John Mettraux, jmettraux@gmail.com
2
+ # Copyright (c) 2006-2015, John Mettraux, jmettraux@gmail.com
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining a copy
5
5
  # of this software and associated documentation files (the "Software"), to deal
@@ -38,7 +38,7 @@ module Rufus
38
38
  parse_cron(o, opts) ||
39
39
  parse_in(o, opts) || # covers 'every' schedule strings
40
40
  parse_at(o, opts) ||
41
- raise(ArgumentError.new("couldn't parse \"#{o}\""))
41
+ fail(ArgumentError.new("couldn't parse \"#{o}\""))
42
42
  end
43
43
 
44
44
  def self.parse_in(o, opts={})
@@ -46,37 +46,14 @@ module Rufus
46
46
  o.is_a?(String) ? parse_duration(o, opts) : o
47
47
  end
48
48
 
49
- TZ_REGEX = /\b((?:[a-zA-Z][a-zA-z0-9\-+]+)(?:\/[a-zA-Z0-9\-+]+)?)\b/
50
-
51
49
  def self.parse_at(o, opts={})
52
50
 
53
- return o if o.is_a?(Time)
54
-
55
- # TODO: deal with tz if suffixed to Chronic string?
56
- return Chronic.parse(o, opts) if defined?(Chronic)
57
-
58
- tz = nil
59
- s =
60
- o.to_s.gsub(TZ_REGEX) { |m|
61
- t = TZInfo::Timezone.get(m) rescue nil
62
- tz ||= t
63
- t ? '' : m
64
- }
65
-
66
- begin
67
- DateTime.parse(o)
68
- rescue
69
- raise ArgumentError, "no time information in #{o.inspect}"
70
- end if RUBY_VERSION < '1.9.0'
71
-
72
- t = Time.parse(s)
73
-
74
- tz ? tz.local_to_utc(t) : t
51
+ Rufus::Scheduler::ZoTime.parse(o, opts).time
75
52
 
76
53
  rescue StandardError => se
77
54
 
78
55
  return nil if opts[:no_error]
79
- raise se
56
+ fail se
80
57
  end
81
58
 
82
59
  def self.parse_cron(o, opts)
@@ -86,7 +63,7 @@ module Rufus
86
63
  rescue ArgumentError => ae
87
64
 
88
65
  return nil if opts[:no_error]
89
- raise ae
66
+ fail ae
90
67
  end
91
68
 
92
69
  def self.parse_to_time(o)
@@ -95,7 +72,7 @@ module Rufus
95
72
  t = parse(t) if t.is_a?(String)
96
73
  t = Time.now + t if t.is_a?(Numeric)
97
74
 
98
- raise ArgumentError.new(
75
+ fail ArgumentError.new(
99
76
  "cannot turn #{o.inspect} to a point in time, doesn't make sense"
100
77
  ) unless t.is_a?(Time)
101
78
 
@@ -155,7 +132,7 @@ module Rufus
155
132
  m = string.match(/^(-?)([\d\.#{DURATION_LETTERS}]+)$/)
156
133
 
157
134
  return nil if m.nil? && opts[:no_error]
158
- raise ArgumentError.new("cannot parse '#{string}'") if m.nil?
135
+ fail ArgumentError.new("cannot parse '#{string}'") if m.nil?
159
136
 
160
137
  mod = m[1] == '-' ? -1.0 : 1.0
161
138
  val = 0.0
@@ -173,9 +150,7 @@ module Rufus
173
150
  elsif opts[:no_error]
174
151
  return nil
175
152
  else
176
- raise ArgumentError.new(
177
- "cannot parse '#{string}' (especially '#{s}')"
178
- )
153
+ fail ArgumentError.new("cannot parse '#{string}' (especially '#{s}')")
179
154
  end
180
155
  break unless m && m[3]
181
156
  s = m[3]
@@ -0,0 +1,175 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, 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
+
25
+
26
+ class Rufus::Scheduler
27
+
28
+ TIMEZONES = %w[
29
+ GB NZ UCT EET CET PRC ROC WET GMT EST ROK UTC MST HST MET Zulu Cuba Iran W-SU
30
+ Eire GMT0 Libya Japan Egypt GMT+0 GMT-0 Israel Poland Navajo Turkey GB-Eire
31
+ Iceland PST8PDT Etc/UCT CST6CDT NZ-CHAT MST7MDT Jamaica EST5EDT Etc/GMT Etc/UTC
32
+ US/Samoa Etc/GMT0 Portugal Hongkong Etc/Zulu Singapore Asia/Baku Etc/GMT-9
33
+ Etc/GMT+1 Etc/GMT+0 Asia/Aden Etc/GMT+2 Etc/GMT+3 Etc/GMT+4 Etc/GMT+5 Etc/GMT+6
34
+ Etc/GMT+7 Etc/GMT+8 Etc/GMT+9 Etc/GMT-0 Etc/GMT-1 Universal Asia/Dili Greenwich
35
+ Asia/Gaza Etc/GMT-8 Etc/GMT-7 US/Alaska Asia/Oral Etc/GMT-6 Etc/GMT-5 Etc/GMT-4
36
+ Asia/Hovd Etc/GMT-3 US/Hawaii Etc/GMT-2 Kwajalein Asia/Omsk Asia/Macao
37
+ Etc/GMT-14 Asia/Kabul US/Central Etc/GMT-13 US/Arizona Asia/Macau Asia/Qatar
38
+ Asia/Seoul Asia/Tokyo Asia/Dubai US/Pacific Etc/GMT-12 Etc/GMT-11 Etc/GMT-10
39
+ Asia/Dhaka Asia/Dacca Asia/Chita Etc/GMT+12 Etc/GMT+10 Asia/Amman Asia/Aqtau
40
+ Etc/GMT+11 US/Eastern Asia/Thimbu Asia/Brunei Asia/Tehran Asia/Beirut
41
+ Europe/Rome Europe/Riga Brazil/Acre Brazil/East Europe/Oslo Brazil/West
42
+ Africa/Lome Asia/Taipei Asia/Saigon Asia/Riyadh Asia/Aqtobe Asia/Anadyr
43
+ Europe/Kiev Asia/Almaty Africa/Juba Pacific/Yap US/Aleutian Asia/Muscat
44
+ US/Mountain Asia/Harbin Asia/Hebron Asia/Manila Asia/Kuwait Asia/Urumqi
45
+ US/Michigan Indian/Mahe SystemV/EST5 Asia/Kashgar Indian/Cocos Asia/Jakarta
46
+ Asia/Kolkata Asia/Kuching America/Atka Asia/Irkutsk Pacific/Apia Asia/Magadan
47
+ Africa/Dakar America/Lima Pacific/Fiji Pacific/Guam Europe/Vaduz Pacific/Niue
48
+ Asia/Nicosia Africa/Ceuta Pacific/Truk America/Adak Pacific/Wake Africa/Tunis
49
+ Africa/Cairo Asia/Colombo SystemV/AST4 SystemV/CST6 Asia/Karachi Asia/Rangoon
50
+ SystemV/MST7 Asia/Baghdad Europe/Malta Africa/Lagos Europe/Minsk SystemV/PST8
51
+ Canada/Yukon Asia/Tbilisi America/Nome Asia/Bahrain Africa/Accra Europe/Paris
52
+ Asia/Bangkok Asia/Bishkek Asia/Thimphu SystemV/YST9 Asia/Yerevan Asia/Yakutsk
53
+ Europe/Sofia Asia/Ust-Nera Australia/ACT Australia/LHI Europe/Tirane
54
+ Asia/Tel_Aviv Australia/NSW Africa/Luanda Asia/Tashkent Africa/Lusaka
55
+ Asia/Shanghai Africa/Malabo Asia/Sakhalin Africa/Maputo Africa/Maseru
56
+ SystemV/HST10 Africa/Kigali Africa/Niamey Pacific/Samoa America/Sitka
57
+ Pacific/Palau Pacific/Nauru Pacific/Efate Asia/Makassar Pacific/Chuuk
58
+ Africa/Harare Africa/Douala America/Aruba America/Thule America/Bahia
59
+ America/Jujuy America/Belem Asia/Katmandu America/Boise Indian/Comoro
60
+ Indian/Chagos Asia/Jayapura Europe/Zurich Asia/Istanbul Europe/Zagreb
61
+ Etc/Greenwich Europe/Warsaw Europe/Vienna Etc/Universal Asia/Dushanbe
62
+ Europe/Athens Europe/Berlin Africa/Bissau Asia/Damascus Africa/Banjul
63
+ Europe/Dublin Africa/Bangui Africa/Bamako Europe/Jersey Africa/Asmera
64
+ Europe/Lisbon Africa/Asmara Europe/London Asia/Ashgabat Asia/Calcutta
65
+ Europe/Madrid Europe/Monaco Europe/Moscow Europe/Prague Europe/Samara
66
+ Europe/Skopje Asia/Khandyga Canada/Pacific Africa/Abidjan America/Manaus
67
+ Asia/Chongqing Asia/Chungking Africa/Algiers America/Maceio US/Pacific-New
68
+ Africa/Conakry America/La_Paz America/Juneau America/Nassau America/Inuvik
69
+ Europe/Andorra Africa/Kampala Asia/Ashkhabad Asia/Hong_Kong America/Havana
70
+ Canada/Eastern Europe/Belfast Canada/Central Australia/West Asia/Jerusalem
71
+ Africa/Mbabane Asia/Kamchatka America/Virgin America/Guyana Asia/Kathmandu
72
+ Mexico/General America/Panama Europe/Nicosia America/Denver Europe/Tallinn
73
+ Africa/Nairobi America/Dawson Europe/Vatican Europe/Vilnius America/Cuiaba
74
+ Africa/Tripoli Pacific/Wallis Atlantic/Faroe Pacific/Tarawa Pacific/Tahiti
75
+ Pacific/Saipan Pacific/Ponape America/Cayman America/Cancun Asia/Pontianak
76
+ Asia/Pyongyang Asia/Vientiane Asia/Qyzylorda Pacific/Noumea America/Bogota
77
+ Pacific/Midway Pacific/Majuro Asia/Samarkand Indian/Mayotte Pacific/Kosrae
78
+ Asia/Singapore Indian/Reunion America/Belize America/Regina America/Recife
79
+ Pacific/Easter Mexico/BajaSur America/Merida Pacific/Chatham Pacific/Fakaofo
80
+ Pacific/Gambier America/Rosario Asia/Ulan_Bator Indian/Maldives Pacific/Norfolk
81
+ America/Antigua Asia/Phnom_Penh America/Phoenix America/Caracas America/Cayenne
82
+ Atlantic/Azores Pacific/Pohnpei Atlantic/Canary America/Chicago Atlantic/Faeroe
83
+ Africa/Windhoek America/Cordoba America/Creston Africa/Timbuktu America/Curacao
84
+ Africa/Sao_Tome Africa/Ndjamena SystemV/AST4ADT Europe/Uzhgorod Europe/Tiraspol
85
+ SystemV/CST6CDT Africa/Monrovia America/Detroit Europe/Sarajevo Australia/Eucla
86
+ America/Tijuana America/Toronto America/Godthab America/Grenada Europe/Istanbul
87
+ America/Ojinaga America/Tortola Australia/Perth Europe/Helsinki Australia/South
88
+ Europe/Guernsey SystemV/EST5EDT Europe/Chisinau SystemV/MST7MDT Europe/Busingen
89
+ Europe/Budapest Europe/Brussels America/Halifax America/Mendoza America/Noronha
90
+ America/Nipigon Canada/Atlantic America/Yakutat SystemV/PST8PDT SystemV/YST9YDT
91
+ Canada/Mountain Africa/Kinshasa Africa/Khartoum Africa/Gaborone Africa/Freetown
92
+ America/Iqaluit America/Jamaica US/East-Indiana Africa/El_Aaiun America/Knox_IN
93
+ Africa/Djibouti Africa/Blantyre America/Moncton America/Managua Asia/Choibalsan
94
+ America/Marigot Australia/North Europe/Belgrade America/Resolute
95
+ America/Mazatlan Pacific/Funafuti Pacific/Auckland Pacific/Honolulu
96
+ Pacific/Johnston America/Miquelon America/Santarem Mexico/BajaNorte
97
+ America/Santiago Antarctica/Troll America/Asuncion America/Atikokan
98
+ America/Montreal America/Barbados Africa/Bujumbura Pacific/Pitcairn
99
+ Asia/Ulaanbaatar Indian/Mauritius America/New_York Antarctica/Syowa
100
+ America/Shiprock Indian/Kerguelen Asia/Novosibirsk America/Anguilla
101
+ Indian/Christmas Asia/Vladivostok Asia/Ho_Chi_Minh Antarctica/Davis
102
+ Atlantic/Bermuda Europe/Amsterdam Antarctica/Casey America/St_Johns
103
+ Atlantic/Madeira America/Winnipeg America/St_Kitts Europe/Volgograd
104
+ Brazil/DeNoronha Europe/Bucharest Africa/Mogadishu America/St_Lucia
105
+ Atlantic/Stanley Europe/Stockholm Australia/Currie Europe/Gibraltar
106
+ Australia/Sydney Asia/Krasnoyarsk Australia/Darwin America/Dominica
107
+ America/Edmonton America/Eirunepe Europe/Podgorica America/Ensenada
108
+ Europe/Ljubljana Australia/Hobart Europe/Mariehamn Africa/Lubumbashi
109
+ America/Goose_Bay Europe/Luxembourg America/Menominee America/Glace_Bay
110
+ America/Fortaleza Africa/Nouakchott America/Matamoros Pacific/Galapagos
111
+ America/Guatemala Pacific/Kwajalein Pacific/Marquesas America/Guayaquil
112
+ Asia/Kuala_Lumpur Europe/San_Marino America/Monterrey Europe/Simferopol
113
+ America/Araguaina Antarctica/Vostok Europe/Copenhagen America/Catamarca
114
+ Pacific/Pago_Pago America/Sao_Paulo America/Boa_Vista America/St_Thomas
115
+ Chile/Continental America/Vancouver Africa/Casablanca Europe/Bratislava
116
+ Pacific/Enderbury Pacific/Rarotonga Europe/Zaporozhye US/Indiana-Starke
117
+ Antarctica/Palmer Asia/Novokuznetsk Africa/Libreville America/Chihuahua
118
+ America/Anchorage Pacific/Tongatapu Antarctica/Mawson Africa/Porto-Novo
119
+ Asia/Yekaterinburg America/Paramaribo America/Hermosillo Atlantic/Jan_Mayen
120
+ Antarctica/McMurdo America/Costa_Rica Antarctica/Rothera America/Grand_Turk
121
+ Atlantic/Reykjavik Atlantic/St_Helena Australia/Victoria Chile/EasterIsland
122
+ Asia/Ujung_Pandang Australia/Adelaide America/Montserrat America/Porto_Acre
123
+ Africa/Brazzaville Australia/Brisbane America/Kralendijk America/Montevideo
124
+ America/St_Vincent America/Louisville Australia/Canberra Australia/Tasmania
125
+ Europe/Isle_of_Man Europe/Kaliningrad Africa/Ouagadougou America/Rio_Branco
126
+ Pacific/Kiritimati Africa/Addis_Ababa America/Metlakatla America/Martinique
127
+ Asia/Srednekolymsk America/Guadeloupe America/Fort_Wayne Australia/Lindeman
128
+ America/Whitehorse Arctic/Longyearbyen America/Pangnirtung America/Mexico_City
129
+ America/Los_Angeles America/Rainy_River Atlantic/Cape_Verde Pacific/Guadalcanal
130
+ Indian/Antananarivo America/El_Salvador Australia/Lord_Howe Africa/Johannesburg
131
+ America/Tegucigalpa Canada/Saskatchewan America/Thunder_Bay Canada/Newfoundland
132
+ America/Puerto_Rico America/Yellowknife Australia/Melbourne America/Porto_Velho
133
+ Australia/Queensland Australia/Yancowinna America/Santa_Isabel
134
+ America/Blanc-Sablon America/Scoresbysund America/Danmarkshavn
135
+ Pacific/Port_Moresby Antarctica/Macquarie America/Buenos_Aires
136
+ Africa/Dar_es_Salaam America/Campo_Grande America/Dawson_Creek
137
+ America/Indianapolis Pacific/Bougainville America/Rankin_Inlet
138
+ America/Indiana/Knox America/Lower_Princes America/Coral_Harbour
139
+ America/St_Barthelemy Australia/Broken_Hill America/Cambridge_Bay
140
+ America/Indiana/Vevay America/Swift_Current America/Port_of_Spain
141
+ Antarctica/South_Pole America/Santo_Domingo Atlantic/South_Georgia
142
+ America/Port-au-Prince America/Bahia_Banderas America/Indiana/Winamac
143
+ America/Indiana/Marengo America/Argentina/Jujuy America/Argentina/Salta
144
+ Canada/East-Saskatchewan America/Indiana/Vincennes America/Argentina/Tucuman
145
+ America/Argentina/Ushuaia Antarctica/DumontDUrville America/Indiana/Tell_City
146
+ America/Argentina/Mendoza America/Argentina/Cordoba America/Indiana/Petersburg
147
+ America/Argentina/San_Luis America/Argentina/San_Juan America/Argentina/La_Rioja
148
+ America/North_Dakota/Center America/Kentucky/Monticello
149
+ America/North_Dakota/Beulah America/Kentucky/Louisville
150
+ America/Argentina/Catamarca America/Indiana/Indianapolis
151
+ America/North_Dakota/New_Salem America/Argentina/Rio_Gallegos
152
+ America/Argentina/Buenos_Aires America/Argentina/ComodRivadavia
153
+ ]
154
+ TIMEZONEs = TIMEZONES.collect(&:downcase)
155
+
156
+ ##
157
+ ## http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
158
+ #
159
+ #ABBREVIATIONS = %w[
160
+ #ACDT ACST ACT ADT AEDT AEST AFT AKDT AKST AMST AMST AMT AMT ART AST AST AWDT
161
+ #AWST AZOST AZT BDT BIOT BIT BOT BRT BST BST BTT CAT CCT CDT CDT CEDT CEST CET
162
+ #CHADT CHAST CHOT ChST CHUT CIST CIT CKT CLST CLT COST COT CST CST CST CST CST
163
+ #CT CVT CWST CXT DAVT DDUT DFT EASST EAST EAT ECT ECT EDT EEDT EEST EET EGST EGT
164
+ #EIT EST EST FET FJT FKST FKST FKT FNT GALT GAMT GET GFT GILT GIT GMT GST GST
165
+ #GYT HADT HAEC HAST HKT HMT HOVT HST ICT IDT IOT IRDT IRKT IRST IST IST IST JST
166
+ #KGT KOST KRAT KST LHST LHST LINT MAGT MART MAWT MDT MET MEST MHT MIST MIT MMT
167
+ #MSK MST MST MST MUT MVT MYT NCT NDT NFT NPT NST NT NUT NZDT NZST OMST ORAT PDT
168
+ #PET PETT PGT PHOT PKT PMDT PMST PONT PST PST PYST PYT RET ROTT SAKT SAMT SAST
169
+ #SBT SCT SGT SLST SRET SRT SST SST SYOT TAHT THA TFT TJT TKT TLT TMT TOT TVT UCT
170
+ #ULAT USZ1 UTC UYST UYT UZT VET VLAT VOLT VOST VUT WAKT WAST WAT WEDT WEST WET
171
+ #WIT WST YAKT YEKT Z
172
+ #].uniq
173
+
174
+ end
175
+
@@ -0,0 +1,167 @@
1
+ #--
2
+ # Copyright (c) 2006-2015, 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
+
25
+ require 'rufus/scheduler/zones'
26
+
27
+
28
+ class Rufus::Scheduler
29
+
30
+ #
31
+ # Zon{ing|ed}Time, whatever.
32
+ #
33
+ class ZoTime
34
+
35
+ attr_accessor :seconds
36
+ attr_accessor :zone
37
+
38
+ def initialize(s, zone)
39
+
40
+ @seconds = s.to_f
41
+ @zone = zone
42
+ end
43
+
44
+ def time
45
+
46
+ in_zone do
47
+
48
+ t = Time.at(@seconds)
49
+
50
+ #if t.isdst
51
+ # t1 = Time.at(@seconds + 3600)
52
+ # t = t1 if t.zone != t1.zone && t.hour == t1.hour && t.min == t1.min
53
+ # # ambiguous TZ (getting out of DST)
54
+ #else
55
+ # t.hour # force t to compute itself
56
+ #end
57
+ #
58
+ # jump out of DST as soon as possible, jumps 1h as seen from UTC
59
+
60
+ t.hour # force t to compute itself
61
+ #
62
+ # stay in DST as long as possible, no jump seen from UTC
63
+
64
+ t
65
+ end
66
+ end
67
+
68
+ def utc
69
+
70
+ time.utc
71
+ end
72
+
73
+ def add(s)
74
+
75
+ @seconds += s.to_f
76
+ end
77
+
78
+ def substract(s)
79
+
80
+ @seconds -= s.to_f
81
+ end
82
+
83
+ def to_f
84
+
85
+ @seconds
86
+ end
87
+
88
+ #DELTA_TZ_REX = /^[+-][0-1][0-9]:?[0-5][0-9]$/
89
+
90
+ def self.envtzable?(s)
91
+
92
+ TIMEZONES.include?(s)
93
+ end
94
+
95
+ def self.parse(str, opts={})
96
+
97
+ if defined?(::Chronic) && t = ::Chronic.parse(str, opts)
98
+ return ZoTime.new(t, ENV['TZ'])
99
+ end
100
+
101
+ begin
102
+ DateTime.parse(str)
103
+ rescue
104
+ fail ArgumentError, "no time information in #{o.inspect}"
105
+ end if RUBY_VERSION < '1.9.0'
106
+
107
+ zone = nil
108
+
109
+ s =
110
+ str.gsub(/\S+/) { |m|
111
+ if envtzable?(m)
112
+ zone ||= m
113
+ ''
114
+ else
115
+ m
116
+ end
117
+ }
118
+
119
+ return nil unless zone.nil? || is_timezone?(zone)
120
+
121
+ zt = ZoTime.new(0, zone || ENV['TZ'])
122
+ zt.in_zone { zt.seconds = Time.parse(s).to_f }
123
+
124
+ zt.seconds == nil ? nil : zt
125
+ end
126
+
127
+ def self.is_timezone?(str)
128
+
129
+ return false if str == nil
130
+ return false if str == '*'
131
+
132
+ return false if str.index('#')
133
+ # "sun#2", etc... On OSX would go all the way to true
134
+
135
+ return true if Time.zone_offset(str)
136
+
137
+ return !! (::TZInfo::Timezone.get(str) rescue nil) if defined?(::TZInfo)
138
+
139
+ return true if TIMEZONES.include?(str)
140
+ return true if TIMEZONEs.include?(str)
141
+
142
+ t = ZoTime.new(0, str).time
143
+
144
+ return false if t.zone == ''
145
+ return false if t.zone == 'UTC'
146
+ return false if t.utc_offset == 0 && str.start_with?(t.zone)
147
+ # 3 common fallbacks...
148
+
149
+ return false if RUBY_PLATFORM.include?('java') && ! envtzable?(str)
150
+
151
+ true
152
+ end
153
+
154
+ def in_zone(&block)
155
+
156
+ current_timezone = ENV['TZ']
157
+ ENV['TZ'] = @zone
158
+
159
+ block.call
160
+
161
+ ensure
162
+
163
+ ENV['TZ'] = current_timezone
164
+ end
165
+ end
166
+ end
167
+