lib/fugit/cron.rb in fugit-1.1.9 vs lib/fugit/cron.rb in fugit-1.1.10

- old
+ new

@@ -9,12 +9,11 @@ '@annually' => '0 0 1 1 *', '@monthly' => '0 0 1 * *', '@weekly' => '0 0 * * 0', '@daily' => '0 0 * * *', '@midnight' => '0 0 * * *', - '@hourly' => '0 * * * *', - } + '@hourly' => '0 * * * *' } attr_reader :original, :zone attr_reader :seconds, :minutes, :hours, :monthdays, :months, :weekdays, :timezone class << self @@ -47,21 +46,19 @@ end end def to_cron_s - @cron_s ||= begin - [ - @seconds == [ 0 ] ? nil : (@seconds || [ '*' ]).join(','), - (@minutes || [ '*' ]).join(','), - (@hours || [ '*' ]).join(','), - (@monthdays || [ '*' ]).join(','), - (@months || [ '*' ]).join(','), - (@weekdays || [ [ '*' ] ]).map { |d| d.compact.join('#') }.join(','), - @timezone ? @timezone.name : nil - ].compact.join(' ') - end + @cron_s ||= [ + @seconds == [ 0 ] ? nil : (@seconds || [ '*' ]).join(','), + (@minutes || [ '*' ]).join(','), + (@hours || [ '*' ]).join(','), + (@monthdays || [ '*' ]).join(','), + (@months || [ '*' ]).join(','), + (@weekdays || [ [ '*' ] ]).map { |d| d.compact.join('#') }.join(','), + @timezone ? @timezone.name : nil + ].compact.join(' ') end class TimeCursor def initialize(cron, t) @@ -71,11 +68,11 @@ end def time; @t; end def to_i; @t.to_i; end - %w[ year month day wday hour min sec wday_in_month ] + %w[ year month day wday hour min sec wday_in_month rweek rday ] .collect(&:to_sym).each { |k| define_method(k) { @t.send(k) } } def inc(i) @t = @t + i self @@ -138,25 +135,39 @@ def month_match?(nt); ( ! @months) || @months.include?(nt.month); end def hour_match?(nt); ( ! @hours) || @hours.include?(nt.hour); end def min_match?(nt); ( ! @minutes) || @minutes.include?(nt.min); end def sec_match?(nt); ( ! @seconds) || @seconds.include?(nt.sec); end + def weekday_hash_match?(nt, hsh) + + phsh, nhsh = nt.wday_in_month + + if hsh > 0 + hsh == phsh # positive wday, from the beginning of the month + else + hsh == nhsh # negative wday, from the end of the month, -1 == last + end + end + + def weekday_modulo_match?(nt, mod) + + nt.rweek % mod[0] == mod[1] + end + def weekday_match?(nt) return true if @weekdays.nil? - wd, hsh = @weekdays.find { |d, _| d == nt.wday } + wd, hom = @weekdays.find { |d, _| d == nt.wday } return false unless wd - return true if hsh.nil? + return true if hom.nil? - phsh, nhsh = nt.wday_in_month - - if hsh > 0 - hsh == phsh # positive wday, from the beginning of the month + if hom.is_a?(Array) + weekday_modulo_match?(nt, hom) else - hsh == nhsh # negative wday, from the end of the month, -1 == last + weekday_hash_match?(nt, hom) end end def monthday_match?(nt) @@ -485,15 +496,15 @@ def determine_weekdays(arr) @weekdays = [] - arr.each do |a, z, s, h| # a to z, slash and hash - if h - @weekdays << [ a, h ] - elsif s - ((a || 0)..(z || (a ? a : 6))).step(s < 1 ? 1 : s) + arr.each do |a, z, sl, ha, mo| # a to z, slash, hash, and mod + if ha || mo + @weekdays << [ a, ha || mo ] + elsif sl + ((a || 0)..(z || (a ? a : 6))).step(sl < 1 ? 1 : sl) .each { |i| @weekdays << [ i ] } elsif z (a..z).each { |i| @weekdays << [ i ] } elsif a @weekdays << [ a ] @@ -525,24 +536,18 @@ def hyphen(i); str(nil, i, '-'); end def comma(i); str(nil, i, ','); end def slash(i); rex(:slash, i, /\/\d\d?/); end - def core_mos(i); rex(:mos, i, /[0-5]?\d/); end # min or sec - def core_hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end - def core_dom(i); rex(:dom, i, /(-?(3[01]|[12][0-9]|0?[1-9])|last|l)/i); end - def core_mon(i); rex(:mon, i, /(1[0-2]|0?[1-9]|#{MONTHS[1..-1].join('|')})/i); end - def core_dow(i); rex(:dow, i, /([0-7]|#{WEEKDS.join('|')})/i); end + def mos(i); rex(:mos, i, /[0-5]?\d/); end # min or sec + def hou(i); rex(:hou, i, /(2[0-4]|[01]?[0-9])/); end + def dom(i); rex(:dom, i, /(-?(3[01]|[12][0-9]|0?[1-9])|last|l)/i); end + def mon(i); rex(:mon, i, /(1[0-2]|0?[1-9]|#{MONTHS[1..-1].join('|')})/i); end + def dow(i); rex(:dow, i, /([0-7]|#{WEEKDS.join('|')})/i); end def dow_hash(i); rex(:hash, i, /#(-?[1-5]|last|l)/i); end - def mos(i); core_mos(i); end - def hou(i); core_hou(i); end - def dom(i); core_dom(i); end - def mon(i); core_mon(i); end - def dow(i); core_dow(i); end - def _mos(i); seq(nil, i, :hyphen, :mos); end def _hou(i); seq(nil, i, :hyphen, :hou); end def _dom(i); seq(nil, i, :hyphen, :dom); end def _mon(i); seq(nil, i, :hyphen, :mon); end def _dow(i); seq(nil, i, :hyphen, :dow); end @@ -566,14 +571,17 @@ def sorws_hou(i); seq(:elt, i, :sor_hou, :slash, '?'); end def sorws_dom(i); seq(:elt, i, :sor_dom, :slash, '?'); end def sorws_mon(i); seq(:elt, i, :sor_mon, :slash, '?'); end def sorws_dow(i); seq(:elt, i, :sor_dow, :slash, '?'); end - def h_dow(i); seq(:elt, i, :core_dow, :dow_hash); end + def mod(i); rex(:mod, i, /%\d+(\+\d+)?/); end - def _sorws_dow(i); alt(nil, i, :h_dow, :sorws_dow); end + def mod_dow(i); seq(:elt, i, :dow, :mod); end + def h_dow(i); seq(:elt, i, :dow, :dow_hash); end + def _sorws_dow(i); alt(nil, i, :h_dow, :mod_dow, :sorws_dow); end + def list_sec(i); jseq(:sec, i, :sorws_mos, :comma); end def list_min(i); jseq(:min, i, :sorws_mos, :comma); end def list_hou(i); jseq(:hou, i, :sorws_hou, :comma); end def list_dom(i); jseq(:dom, i, :sorws_dom, :comma); end def list_mon(i); jseq(:mon, i, :sorws_mon, :comma); end @@ -605,36 +613,51 @@ alt(:cron, i, :second_cron, :classic_cron) end # rewriting the parsed tree - def to_i(k, t) + def rewrite_bound(k, t) s = t.string.downcase (k == :mon && MONTHS.index(s)) || (k == :dow && WEEKDS.index(s)) || ((k == :dom) && s[0, 1] == 'l' && -1) || # L, l, last s.to_i end + def rewrite_mod(k, t) + + mod, plus = t.string + .split(/[%+]/).reject(&:empty?).collect(&:to_i) + + [ mod, plus || 0 ] + end + def rewrite_elt(k, t) - (a, z), others = t - .subgather(nil) - .partition { |tt| ![ :hash, :slash ].include?(tt.name) } - s = others.find { |tt| tt.name == :slash } - h = others.find { |tt| tt.name == :hash } + at, zt, slt, hat, mot = nil; t.subgather(nil).each do |tt| + case tt.name + when :slash then slt = tt + when :hash then hat = tt + when :mod then mot = tt + else if at; zt ||= tt; else; at = tt; end + end + end - h = h ? h.string[1..-1] : nil - h = -1 if h && h.upcase[0, 1] == 'L' - h = h.to_i if h + sl = slt ? slt.string[1..-1].to_i : nil - a = a ? to_i(k, a) : nil - z = z ? to_i(k, z) : nil + ha = hat ? hat.string[1..-1] : nil + ha = -1 if ha && ha.upcase[0, 1] == 'L' + ha = ha.to_i if ha + + mo = mot ? rewrite_mod(k, mot) : nil + + a = at ? rewrite_bound(k, at) : nil + z = zt ? rewrite_bound(k, zt) : nil a, z = z, a if a && z && a > z - [ a, z, s ? s.string[1..-1].to_i : nil, h ] + [ a, z, sl, ha, mo ] end def rewrite_entry(t) t