module Midnight

Constants

VERSION

Public Class Methods

debug() click to toggle source
# File lib/midnight.rb, line 23
def self.debug; false; end
dwrite(msg) click to toggle source
# File lib/midnight.rb, line 25
def self.dwrite(msg)
  puts msg if Midnight.debug
end
guess() click to toggle source
# File lib/midnight/handler.rb, line 4
def guess()
  # Not sure we'll need interval for cron output
  interval = guess_unit_types
  interval ||= guess_weekday
  interval ||= guess_weekday
  interval ||= guess_month_names
  interval ||= guess_number_and_unit
  interval ||= guess_special

  # defines the next occurrence of this midnight if not set in a guess routine
  @next ||= @start + (interval * 60 * 60 * 24) if interval
  
  # # check to see if the start date is > NOW and, if so, set the next occurrence = start
  @next = @start if @start.to_time > Time.now
  
  # # return the next occurrence
  return @next.to_time if interval
end
guess_month_names() click to toggle source
# File lib/midnight/handler.rb, line 39
def guess_month_names
  if token_types.same?([:month_name]) then
    @start = Chronic.parse("#{token_of_type(:month_name).start.to_s} 1")
    interval = 30
  end
  interval
end
guess_number_and_unit() click to toggle source
# File lib/midnight/handler.rb, line 47
def guess_number_and_unit
  interval = token_of_type(:number).interval if token_types.same?([:number, :day])
  interval = (token_of_type(:number).interval * 7) if token_types.same?([:number, :week])
  interval = (token_of_type(:number).interval * 30) if token_types.same?([:number, :month])
  interval = (token_of_type(:number).interval * 365) if token_types.same?([:number, :year])
  interval
end
guess_special() click to toggle source
# File lib/midnight/handler.rb, line 55
def guess_special
  interval = guess_special_other
  interval ||= guess_special_beginning
  interval ||= guess_special_middle
  interval ||= guess_special_end
end
guess_unit_types() click to toggle source
# File lib/midnight/handler.rb, line 23
def guess_unit_types
  interval = 1 if token_types.same?([:day])
  interval = 7 if token_types.same?([:week])
  interval = 30 if token_types.same?([:month])
  interval = 365 if token_types.same?([:year])
  interval
end
guess_weekday() click to toggle source
# File lib/midnight/handler.rb, line 31
def guess_weekday
  if token_types.same?([:weekday]) then
    @start = Chronic.parse(token_of_type(:weekday).start.to_s)
    interval = 7
  end
  interval
end
parse(text, specified_options = {}) click to toggle source
# File lib/midnight/midnight.rb, line 6
def parse(text, specified_options = {})
  # get options and set defaults if necessary
  default_options = {:start => Time.now}
  options = default_options.merge specified_options

  # ensure the specified options are valid
  specified_options.keys.each do |key|
    default_options.keys.include?(key) || raise(InvalidArgumentException, "#{key} is not a valid option key.")
  end
  Chronic.parse(specified_options[:start]) || raise(InvalidArgumentException, ':start specified is not a valid datetime.') if specified_options[:start]

  # remove every is specified
  text = text.gsub(/^every\s\b/, '')

  # put the text into a normal format to ease scanning using Chronic
  text = pre_normalize(text)
  text = Chronic::Parser.new.pre_normalize(text)
  text = numericize_ordinals(text)

  # check to see if this event starts some other time and reset now
  event, starting = text.split('starting')
  @start = (Chronic.parse(starting) || options[:start])
  @next = nil

  # split into tokens
  @tokens = base_tokenize(event)

  # scan the tokens with each token scanner
  @tokens = Repeater.scan(@tokens)

  # remove all tokens without a type
  @tokens.reject! {|token| token.type.nil? }

  converter = Converter.new
  cron_expression = converter.convert_tokens_to_cron_expression(@tokens)

  return cron_expression
end
pre_normalize(text) click to toggle source

Normalize natural string removing prefix language

# File lib/midnight/midnight.rb, line 46
def pre_normalize(text)
  normalized_text = text.gsub(/^every\s\b/, '')
  normalized_text = text.gsub(/^each\s\b/, '')
  normalized_text = text.gsub(/^on the\s\b/, '')
  normalized_text
end
token_types() click to toggle source

Returns an array of types for all tokens

# File lib/midnight/midnight.rb, line 65
def token_types
  @tokens.map(&:type)
end

Private Class Methods

guess_special_beginning() click to toggle source
# File lib/midnight/handler.rb, line 72
def guess_special_beginning
  if token_types.same?([:special, :week]) && token_of_type(:special).start == :beginning then interval = 7;  @start = Chronic.parse('Sunday'); end
  if token_types.same?([:special, :month]) && token_of_type(:special).start == :beginning then interval = 30;  @start = Chronic.parse('1st day next month'); end
  if token_types.same?([:special, :year]) && token_of_type(:special).start == :beginning then interval = 365;  @start = Chronic.parse('1st day next year'); end
  interval
end
guess_special_end() click to toggle source
# File lib/midnight/handler.rb, line 79
def guess_special_end
  if token_types.same?([:special, :week]) && token_of_type(:special).start == :end then interval = 7;  @start = Chronic.parse('Saturday'); end
  if token_types.same?([:special, :month]) && token_of_type(:special).start == :end then interval = 30;  @start = Date.new(Date.today.year, Date.today.month, Date.today.days_in_month); end
  if token_types.same?([:special, :year]) && token_of_type(:special).start == :end then interval = 365;  @start = Date.new(Date.today.year, 12, 31); end
  interval
end
guess_special_middle() click to toggle source
# File lib/midnight/handler.rb, line 86
def guess_special_middle
  if token_types.same?([:special, :week]) && token_of_type(:special).start == :middle then interval = 7;  @start = Chronic.parse('Wednesday'); end
  if token_types.same?([:special, :month]) && token_of_type(:special).start == :middle then
    interval = 30;
    @start = (Date.today.day >= 15 ? Chronic.parse('15th day of next month') : Date.new(Date.today.year, Date.today.month, 15))
  end
  if token_types.same?([:special, :year]) && token_of_type(:special).start == :middle then
    interval = 365;
    @start = (Date.today.day >= 15 && Date.today.month >= 6 ? Date.new(Date.today.year+1, 6, 15) : Date.new(Date.today.year, 6, 15))
  end
  interval
end
guess_special_other() click to toggle source
# File lib/midnight/handler.rb, line 64
def guess_special_other
  interval = 2 if token_types.same?([:special, :day]) && token_of_type(:special).start == :other
  interval = 14 if token_types.same?([:special, :week]) && token_of_type(:special).start == :other
  if token_types.same?([:special, :month]) && token_of_type(:special).start == :other then interval = 60;  @next = Chronic.parse('2 months from now'); end
  if token_types.same?([:special, :year]) && token_of_type(:special).start == :other then interval = 730;  @next = Chronic.parse('2 years from now'); end
  interval
end
token_of_type(type) click to toggle source
# File lib/midnight/handler.rb, line 99
def token_of_type(type)
  @tokens.detect {|token| token.type == type}
end