Class: SayWhen::CronExpression

Inherits:
Object
  • Object
show all
Defined in:
lib/say_when/cron_expression.rb

Overview

Based on the extended cron capabilties wiki.opensymphony.com/display/QRTZ1/CronTriggers+Tutorial

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(expression, time_zone = nil) ⇒ CronExpression

Returns a new instance of CronExpression.



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
# File 'lib/say_when/cron_expression.rb', line 11

def initialize(expression, time_zone=nil)
  if expression.is_a?(Hash)
    opts = expression

    @expression = if opts[:expression]
      opts[:expression]
    else
      [:days_of_month, :days_of_week].each do |f|
        opts[f] ||= '?'
      end

      [:seconds, :minutes, :hours, :days_of_month, :months, :days_of_week, :years].each do |f|
        opts[f] ||= '*'
      end
      
      "#{opts[:seconds]} #{opts[:minutes]} #{opts[:hours]} #{opts[:days_of_month]} #{opts[:months]} #{opts[:days_of_week]} #{opts[:years]}"
    end
    
    @time_zone = if opts.has_key?(:time_zone) && !opts[:time_zone].blank?
      opts[:time_zone]
    else
      Time.zone.nil? ? "UTC" : Time.zone.name
    end

  else
    @expression = expression
    @time_zone = if time_zone.blank?
        Time.zone.nil? ? "UTC" : Time.zone.name
      else
        time_zone
      end
  end

  parse
  validate
end

Instance Attribute Details

#days_of_monthObject

Returns the value of attribute days_of_month.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def days_of_month
  @days_of_month
end

#days_of_weekObject

Returns the value of attribute days_of_week.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def days_of_week
  @days_of_week
end

#expressionObject (readonly)

Returns the value of attribute expression.



8
9
10
# File 'lib/say_when/cron_expression.rb', line 8

def expression
  @expression
end

#hoursObject

Returns the value of attribute hours.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def hours
  @hours
end

#minutesObject

Returns the value of attribute minutes.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def minutes
  @minutes
end

#monthsObject

Returns the value of attribute months.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def months
  @months
end

#secondsObject

Returns the value of attribute seconds.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def seconds
  @seconds
end

#time_zoneObject

Returns the value of attribute time_zone.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def time_zone
  @time_zone
end

#yearsObject

Returns the value of attribute years.



9
10
11
# File 'lib/say_when/cron_expression.rb', line 9

def years
  @years
end

Instance Method Details

#last_fire_at(time = nil) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/say_when/cron_expression.rb', line 96

def last_fire_at(time=nil)
  Time.zone = @time_zone
  before = time.nil? ? Time.zone.now : time.in_time_zone(@time_zone)
  # before = 1.second.ago(before)
  # puts "last fire at before: #{before.inspect}"

  while (true)
    [years, months, days_of_month, days_of_week, hours, minutes, seconds].each do |cron_value|
      # puts "last_fire_at cron val loop: #{cron_value.part} for #{before.inspect}"
      # puts "before move_to_last: #{before.to_s}"
      before, changed = move_to_last(cron_value, before)
      # puts "after move_to_last:  #{before.to_s}"
      return if before.nil?
      break if changed
    end
    
    break if will_fire_on?(before)
  end
  # puts "NEXT FIRE AT: #{before}, NOW: #{Time.zone.now}"
  return before
end

#next_fire_at(time = nil) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/say_when/cron_expression.rb', line 74

def next_fire_at(time=nil)
  Time.zone = @time_zone
  after = time.nil? ? Time.zone.now : time.in_time_zone(@time_zone)
  # after = 1.second.since(after)
  # puts "next fire at after: #{after.inspect}"

  while (true)
    [years, months, days_of_month, days_of_week, hours, minutes, seconds].each do |cron_value|
      # puts "next_fire_at cron val loop: #{cron_value.part}"
      # puts "before move_to_next: #{after.inspect}"
      after, changed = move_to_next(cron_value, after)
      # puts "after move_to_next:  #{after.inspect}"
      return if after.nil?
      break if changed
    end
    
    break if will_fire_on?(after)
  end
  # puts "NEXT FIRE AT: #{after}, NOW: #{Time.zone.now}"
  return after
end

#parseObject



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/say_when/cron_expression.rb', line 48

def parse
  return if @expression.blank? 
  vals = @expression.split.collect{|word| word.upcase.gsub(/\s/, '')}
  @seconds = SecondsCronValue.new(vals[0])
  @minutes = MinutesCronValue.new(vals[1])
  @hours = HoursCronValue.new(vals[2])
  @days_of_month = DaysOfMonthCronValue.new(vals[3])
  @months = MonthsCronValue.new(vals[4])
  @days_of_week = DaysOfWeekCronValue.new(vals[5])
  @years = YearsCronValue.new(vals[6] || "*")    
end

#to_sObject



65
66
67
# File 'lib/say_when/cron_expression.rb', line 65

def to_s
  "s:#{seconds}m:#{minutes}h:#{hours}dom:#{days_of_month}m:#{months}dow:#{days_of_week}y:#{years}"
end

#validateObject



60
61
62
63
# File 'lib/say_when/cron_expression.rb', line 60

def validate
  return if @expression.blank? 
  raise "days_of_week or days_of_month needs to be ?" if (@days_of_month.is_specified && @days_of_week.is_specified)
end

#will_fire_on?(date) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
72
# File 'lib/say_when/cron_expression.rb', line 69

def will_fire_on?(date)
 # puts "will fire on? #{date} : #{self.to_s}"
  [@seconds, @minutes, @hours, @days_of_month, @months, @days_of_week, @years].detect{|part| !part.include?(date)}.nil?
end