Module: RCron::Parser
- Defined in:
- lib/rcron/parser.rb
Class Method Summary collapse
-
.parse(cron) ⇒ Hash
Parsed schedule.
Class Method Details
.parse(cron) ⇒ Hash
Returns Parsed schedule.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/rcron/parser.rb', line 5 def self.parse(cron) elements = cron.strip.split(/\s+/) raise ArgumentError.new("Invalid format: '#{cron}'") unless [5, 6].include? elements.length parser = lambda { |type, min, len, element, subs, extra| return nil if element.nil? max = min + len - 1 (subs || {}).each do |k, v| element = element.gsub(/\b#{k}\b/i, v.to_s) end ret = element.split(',').map { |e| err = ArgumentError.new("Invalid #{type} specification: '#{cron}'") case e when '*' nil when %r|^[0-9]+$| ei = e.to_i raise err if ei < min || ei > max ei when %r|^\*/([1-9][0-9]*)$| (min..max).select { |m| m % $1.to_i == 0 } when %r|^([0-9]+)-([0-9]+)/([1-9][0-9]*)$| f, t = $1.to_i, $2.to_i raise err if f < min || f > max raise err if t < min || t > max if f < t (f..t).select { |m| (m - f) % $3.to_i == 0 } else (f..max).select { |m| (m - f) % $3.to_i == 0 } + (min..t).select { |m| m = m + max + 1 - min (m - f) % $3.to_i == 0 } end when %r|^([0-9]+)-([0-9]+)$| f, t = $1.to_i, $2.to_i raise err if f < min || f > max raise err if t < min || t > max if f < t (f..t).to_a else (f..max).to_a + (min..t).to_a end else extra && extra.call(e) || raise(err) end }.flatten.compact.uniq.inject({}) { |h, k| if k.is_a? Hash h[k.first.first] = k.first.last else h[k] = true end h } ret.empty? ? nil : ret } schedule = { :minutes => parser.call('minute', 0, 60, elements[0], nil, nil), :hours => parser.call('hour', 0, 24, elements[1], nil, nil), :days => parser.call('day/month', 1, 31, elements[2], nil, lambda { |e| case e.upcase when 'L' -1 when /W/ raise NotImplementedError.new("Nearest weekday not implemeneted: '#{cron}'") end }), :months => parser.call('month', 1, 12, elements[3], { 'jan' => 1, 'feb' => 2, 'mar' => 3, 'apr' => 4, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'sep' => 9, 'oct' => 10, 'nov' => 11, 'dec' => 12 }, nil), :weekdays => parser.call('day/week', 0, 7, elements[4], { 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, 'thu' => 4, 'fri' => 5, 'sat' => 6 }, lambda { |e| if e =~ /^([0-6]+)#([1-5])$/ {$1.to_i => $2.to_i} end }), :years => parser.call('year', 1970, 130, elements[5], nil, nil) } schedule end |