cron_format 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: afc959256f516f7c63218f2408a606ace35ed14f
4
+ data.tar.gz: fa6d239ce30e12024d1fdcf75a703bc13e7cdbb5
5
+ SHA512:
6
+ metadata.gz: 8c5dc056631f4e1073f0f799ded3444735aa7a9f1dcbf280f75c18be8065db2127fcd470abea60a28e1b1b8aaa2f39027e051c9ca5e3b1891e710cc459855858
7
+ data.tar.gz: 07721b020e65c02c511e0fce5d30b4a3bc4537b6c8be9e4f5ed48f549e6a75a7d06b640cc26d61b97ce5f101f15fa0eeb4474366ace15f35f45c2da4912d79dd
checksums.yaml.gz.sig ADDED
@@ -0,0 +1,2 @@
1
+ _I!u�u*cJ�
2
+ �\ޤ��i����V�k;4�ؙBoVa#�*"�o[�0�>�W���N�ks�]���A��97g����\�_U�s�}�s)��ݟ�&�#o�H���h�$��5�fnɪ�$�4��eX�t�e�?f9�lN�y�+UE�݄]^��L��s���q�����-F�7�o�;<,���`Xl��oG�� x�:ZJ��;S��8�v@`MJ�e~��!V`�|:w���� �d�`����!�������v8���
data.tar.gz.sig ADDED
Binary file
@@ -0,0 +1,225 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: cron_format.rb
4
+
5
+ require 'date'
6
+ require 'time'
7
+
8
+
9
+ MINUTE = 60
10
+ HOUR = MINUTE * 60
11
+ DAY = HOUR * 24
12
+
13
+ class Array
14
+
15
+ def inflate()
16
+ Array.new(self.max_by {|x| x.length}.length).map do |x|
17
+ self.map{|x| x.length <= 1 ? x.first : x.shift}
18
+ end
19
+ end
20
+ end
21
+
22
+
23
+ class CronFormat
24
+
25
+ attr_reader :to_time
26
+
27
+ def initialize(cron_string, now=Time.now)
28
+ @cron_string, @to_time = cron_string, now
29
+ parse()
30
+ end
31
+
32
+ def next()
33
+ nudge(); parse()
34
+ end
35
+
36
+ private
37
+
38
+ def nudge()
39
+
40
+ a = @cron_string.split
41
+ val = a.detect{|x| x != '*'}
42
+ index, n = 0, 1
43
+
44
+ if val then
45
+ index = a.index(val)
46
+ r = val[/\/(\d+)$/,1]
47
+ n = r.to_i if r
48
+ end
49
+
50
+ month_proc = lambda {|t1,n|
51
+ a = t1.to_a
52
+ a[4] = a[4] + n <= 12 ? a[4] + n : a[4] + n - 12
53
+ t = Time.parse("%s-%s-%s %s:%s" % a.values_at(5,4,3,2,1,0))
54
+ t -= DAY until t.month == a[4]
55
+ return t
56
+ }
57
+
58
+ day_proc = lambda {|x,n| x + n * DAY}
59
+
60
+ units = [
61
+ lambda {|x,n| x + n * MINUTE},
62
+ lambda {|x,n| x + n * HOUR},
63
+ day_proc,
64
+ month_proc,
65
+ day_proc
66
+ ]
67
+
68
+ @to_time = units[index].call @to_time, n
69
+
70
+ end
71
+
72
+ def parse()
73
+
74
+ raw_a = @cron_string.split
75
+ raw_a << '*' if raw_a.length <= 5 # add the year?
76
+
77
+ units = @to_time.to_a.values_at(1..4) + [nil, @to_time.year]
78
+
79
+ procs = {
80
+ min: lambda{|x, interval| x += (interval * MINUTE).to_i},
81
+ hour: lambda{|x, interval| x += (interval * HOUR).to_i},
82
+ day: lambda{|x, interval| x += (interval * DAY).to_i},
83
+ month: lambda{|x, interval|
84
+ date = x.to_a.values_at(1..5)
85
+ interval.times { date[3].succ! }
86
+ Time.parse("%s-%s-%s %s:%s" % date.reverse)},
87
+ year: lambda{|x, interval|
88
+ date = x.to_a.values_at(1..5)
89
+ interval.times { date[4].succ! }
90
+ Time.parse("%s-%s-%s %s:%s" % date.reverse)}
91
+ }
92
+
93
+ dt = units.map do |start|
94
+ # convert * to time unit
95
+ lambda do |x| v2 = x.sub('*', start.to_s)
96
+ # split any times
97
+ multiples = v2.split(/,/)
98
+ range = multiples.map do |time|
99
+ s1, s2 = time.split(/-/)
100
+ s2 ? (s1..s2).to_a : s1
101
+ end
102
+ range.flatten
103
+ end
104
+
105
+ end
106
+
107
+ # take any repeater out of the unit value
108
+ raw_units, repeaters = [], []
109
+
110
+ raw_a.each do |x|
111
+ v1, v2 = x.split('/')
112
+ raw_units << v1
113
+ repeaters << v2
114
+ end
115
+
116
+ raw_date = raw_units.map.with_index {|x,i| dt[i].call(x) }
117
+
118
+ # expand the repeater
119
+
120
+ ceil = {min: MINUTE, hour: 23, day: 31, month: 12}.values
121
+
122
+ if repeaters.any? then
123
+ repeaters.each_with_index do |x,i|
124
+ if x and not raw_a[i][/^\*/] then
125
+ raw_date[i] = raw_date[i].map {|y|
126
+ (y.to_i...ceil[i]).step(x.to_i).to_a.map(&:to_s)
127
+ }.flatten
128
+ else
129
+ raw_date[i]
130
+ end
131
+ end
132
+ end
133
+
134
+ dates = raw_date.inflate
135
+
136
+ a = dates.map do |date|
137
+
138
+ d = date.map{|x| x ? x.clone : nil}
139
+ wday, year = d.pop(2)
140
+ d << year
141
+
142
+ next unless day_valid? d.reverse.take 3
143
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
144
+
145
+ if t < @to_time and wday and wday != t.wday then
146
+ d[2], d[3] = @to_time.to_a.values_at(3,4).map(&:to_s)
147
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
148
+ t += DAY until t.wday == wday.to_i
149
+ end
150
+
151
+ i = 3
152
+ while t < @to_time and i >= 0 and raw_a[i][/\*/]
153
+
154
+ d[i] = @to_time.to_a[i+1].to_s
155
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
156
+ i -= 1
157
+ end
158
+
159
+ if t < @to_time then
160
+
161
+ if t.month < @to_time.month and raw_a[4] == '*' then
162
+ # increment the year
163
+
164
+ d[4].succ!
165
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
166
+
167
+ if repeaters[4] then
168
+ d[4].succ!
169
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
170
+ end
171
+ elsif t.day < @to_time.day and raw_a[3] == '*' then
172
+
173
+ # increment the month
174
+ if d[3].to_i <= 11 then
175
+ d[3].succ!
176
+ else
177
+ d[3] = '1'
178
+ d[4].succ!
179
+ end
180
+ t = Time.parse("%s-%s-%s %s:%s" % d.reverse)
181
+ elsif (t.hour < @to_time.hour or (t.hour == @to_time.hour \
182
+ and t.min < @to_time.min and raw_a[1] != '*') ) \
183
+ and raw_a[2] == '*' then
184
+
185
+ # increment the day
186
+ t += DAY * ((@to_time.day - d[2].to_i) + 1)
187
+ #jr070713 elsif t.min < @to_time.min and raw_a[1] == '*' then
188
+ elsif t.min < @to_time.min and raw_a[1] == '*' then
189
+
190
+ # increment the hour
191
+ t += HOUR * ((@to_time.hour - d[1].to_i) + 1)
192
+ elsif raw_a[0] == '*' then
193
+ # increment the minute
194
+ t += MINUTE * ((@to_time.min - d[0].to_i) + 1)
195
+ t = procs.values[i].call(t, repeaters[i].to_i) if repeaters[i]
196
+ end
197
+
198
+ end
199
+
200
+ if wday then
201
+ t += DAY until t.wday == wday.to_i
202
+ end
203
+
204
+ if t <= @to_time and repeaters.any? then
205
+
206
+ repeaters.each_with_index do |x,i|
207
+ if x then
208
+ t = procs.values[i].call(t, x.to_i)
209
+ end
210
+ end
211
+ end
212
+
213
+ t
214
+ end
215
+
216
+ @to_time = a.compact.min
217
+ end
218
+
219
+ def day_valid?(date)
220
+ year, month, day = date
221
+ last_day = DateTime.parse("%s-%s-%s" % [year, month.succ, 1]) - 1
222
+ day.to_i <= last_day.day
223
+ end
224
+
225
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cron_format
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - James Robertson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIDljCCAn6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBIMRIwEAYDVQQDDAlnZW1t
14
+ YXN0ZXIxHjAcBgoJkiaJk/IsZAEZFg5qYW1lc3JvYmVydHNvbjESMBAGCgmSJomT
15
+ 8ixkARkWAmV1MB4XDTEzMDcwNzE3MDkzOVoXDTE0MDcwNzE3MDkzOVowSDESMBAG
16
+ A1UEAwwJZ2VtbWFzdGVyMR4wHAYKCZImiZPyLGQBGRYOamFtZXNyb2JlcnRzb24x
17
+ EjAQBgoJkiaJk/IsZAEZFgJldTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
18
+ ggEBAJUerT/w15jZ4h80jvs+EXGwThnDNmrGyrPzJdKCa9cCrqUXVl29oAvjPhhM
19
+ HhHKsjjN7xK+fLjiJt5MuM9jAkrsoZSkdirL4yjatFYWPO3juOWuevVwPxwHSuYl
20
+ WuhCOBzMLlNBQarNLeGr0FuwT6erQOJT/PSh0EPIAtiTkNHC8n+NoeymuoRB8kHj
21
+ bfnIiwapd9jl0pJFQicgL36sNSAmIvn5RNJWMjklIRswNrxvjUhhLI2bqiQiFx/3
22
+ vqFG/dKKjKojJN1517LgASnqWPulbrDvo6Vov4DQCBXabz9KnwotdVhjhhZCZW4g
23
+ 9MEzIubRspCjLFzSZYbP3XFN7AUCAwEAAaOBijCBhzAJBgNVHRMEAjAAMAsGA1Ud
24
+ DwQEAwIEsDAdBgNVHQ4EFgQUSpXjvXlr54xa/0MFq6KksQJbXQQwJgYDVR0RBB8w
25
+ HYEbZ2VtbWFzdGVyQGphbWVzcm9iZXJ0c29uLmV1MCYGA1UdEgQfMB2BG2dlbW1h
26
+ c3RlckBqYW1lc3JvYmVydHNvbi5ldTANBgkqhkiG9w0BAQUFAAOCAQEAKtKQIz7+
27
+ CiONPyn8qY9sQ5RMwl5oZH/cntY3IhB2aaTJqRPHjYH7/k55AjMDhfwePIqMp5nT
28
+ p7A2+NZ1rIHua0FwjCRBIjeOAZdG79FIt0YkfQqzSrpunHQn7DGj8LxTtliHZ6aH
29
+ 7yrVFROyfYpEFeBzQ+0B+/FGlTD24TYsxzLyKEYnhrJnMD7zrxo1HTVO7fQ+F21s
30
+ 6Kx1JnxzsdC9HYcKz/jbHXZURdrB+JTYI92/m8fsPrd1HqKpYHSKS8jga1rGCi7U
31
+ 9DFxFCS6sgAw21S+V+ym9ft8kbqgy7zOGdPRRNlwgb/V+UWqH4yaCtk7yJT+n8vm
32
+ LHkRlhnm0ScZYw==
33
+ -----END CERTIFICATE-----
34
+ date: 2013-07-07 00:00:00.000000000 Z
35
+ dependencies: []
36
+ description:
37
+ email:
38
+ executables: []
39
+ extensions: []
40
+ extra_rdoc_files: []
41
+ files:
42
+ - lib/cron_format.rb
43
+ homepage:
44
+ licenses: []
45
+ metadata: {}
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '>='
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ requirements: []
61
+ rubyforge_project:
62
+ rubygems_version: 2.0.0.rc.2
63
+ signing_key:
64
+ specification_version: 4
65
+ summary: cron_format
66
+ test_files: []
metadata.gz.sig ADDED
Binary file