Class: LucidWorks::Activity

Inherits:
Base
  • Object
show all
Defined in:
lib/lucid_works/activity.rb,
lib/lucid_works/activity/status.rb,
lib/lucid_works/activity/history.rb

Defined Under Namespace

Classes: History, Status

Constant Summary collapse

TYPES =
%w{ optimize click autocomplete }

Constants included from Utils::BoolConverter

Utils::BoolConverter::FALSE_VALUES, Utils::BoolConverter::TRUE_VALUES

Instance Attribute Summary

Attributes inherited from Base

#attributes, #id, #parent, #persisted, #raw_response, #response_data

Instance Method Summary collapse

Methods inherited from Base

all, #collection_url, collection_url, create, #destroy, extract_parent_from_options, find, first, human_attribute_value, #human_attribute_value, #initialize, #inspect, last, #member_url, #persisted?, #read_attribute_for_validation, #save, schema, singleton_name, to_select, #update_attributes

Methods included from SimpleNaming

#model_name

Methods included from Utils::BoolConverter

#to_bool

Constructor Details

This class inherits a constructor from LucidWorks::Base

Instance Method Details

#custom?Boolean

convenience method for detecting whether schedule can be represented in simple format or should be described as custom (meaning it is beyond the capabilities of the convenience methods)

Returns:

  • (Boolean)


153
154
155
156
157
158
# File 'lib/lucid_works/activity.rb', line 153

def custom?
  return false unless self.start_time
  return true if self.frequency == 'custom'
  return true if self.start_is_more_than_one_period_in_the_future?
  return false
end

#day_of_weekObject

convenince method for setting the current value in a view selector



138
139
140
141
# File 'lib/lucid_works/activity.rb', line 138

def day_of_week
  # subract 1 because '%u' returns 1-7, and this is working with zero-indexed ruby arrays
  self.start_time.localtime.strftime('%u').to_i - 1 rescue nil
end

#frequencyObject



24
25
26
27
28
29
30
31
32
# File 'lib/lucid_works/activity.rb', line 24

def frequency
  case period
  when 1.weeks.seconds then 'weekly'
  when 1.days.seconds then 'daily'
  when 1.hours.seconds then 'hourly'
  when 0 then nil
  else 'custom'
  end
end

#frequency=(frequency) ⇒ Object

accepts hourly, daily, weekly, and sets period to respective # of seconds



37
38
39
40
41
42
43
44
# File 'lib/lucid_works/activity.rb', line 37

def frequency=(frequency)
  self.period = case frequency
  when 'hourly' then 1.hours.seconds.to_i
  when 'daily' then 1.days.seconds.to_i
  when 'weekly' then 1.weeks.seconds.to_i
  else raise "unknown frequency"
  end
end

#hourObject

convenince method for setting the current value in a view selector



124
125
126
# File 'lib/lucid_works/activity.rb', line 124

def hour
  self.start_time.localtime.hour rescue nil
end

#minObject

convenince method for setting the current value in a view selector



131
132
133
# File 'lib/lucid_works/activity.rb', line 131

def min
  self.start_time.localtime.min rescue nil
end

#next_startObject

predict when action will occur next if active at that time



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/lucid_works/activity.rb', line 49

def next_start
  return start_time if (now = Time.now) <= start_time 
  # require 'ruby-debug'; debugger
  time_since_start = now - start_time
  last_interval_num = (time_since_start / period).to_i
  next_interval_num =  if (time_since_start % period) == 0
    # this is sort of a stupid condition b/c time precision is millisecond or less
    # for human purposes we wouldn't care if the result were as though the call 
    # happened a millisecond later. But whatever.
    last_interval_num # the next interval *is* the last interval if it is exactly now
  else
    last_interval_num + 1
  end
  start_time + period * next_interval_num
end

#schedule=(all_attributes) ⇒ Object

phantom attribute for compiling real start time and frequency from appropriate form data Allows the user to specify a schedule simply with repeat interval (hourly, daily, weekly) and time within the interval to run (e.g 5 past, or Tuesdays at 2:15)

We have to figure out when the actual start time will be because we are not asking the user for this. It needs to be:

* at the requested time relative to the interval chosen
* as soon as possible
* in the future

This is obvious to humans, but when computing it, you run into the following problem. It happens with all interval sizes, but for the sake of example, we’ll use weekly:

Problem 1) If today is Thursday, and the user asks for “weekly on Wednesdays,” Wednesday has already happened this week. We have to make sure we pick the nearest wednesday that is in the future

Problem 2) If today is Tuesday, and the user asks for “weekly on Wednesdays,”, the simple solution to problem 1 (start next week instead of this week) causes you to skip this Tuesday, even though it is valid and is what the user would expect

The algorith to solve both problems at once is this:

* From Time.now, back up to the beginning of the interval even if it is in the past. 
* Fast forward to the requested siimple start time
* If you are still in the past, advance by one interval


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/lucid_works/activity.rb', line 92

def schedule=(all_attributes)
  # convert to format accepted by Time.advance
  if all_attributes['start']
    all_attributes['start'].to_options!
    all_attributes['start'].each{|k,v| all_attributes['start'][k]=v.to_i}
  end
  
  self.active = all_attributes['active']  if all_attributes.keys.include?('active')
  
  now = Time.now
  self.frequency = all_attributes['frequency']
  self.start_time = 
    case all_attributes['frequency']
    when 'weekly'
      # require 'ruby-debug'; debugger
      start = now.beginning_of_week.advance(all_attributes['start'])
      start < now ? start.advance(:weeks => 1) : start 
    when 'daily'                                                       
      start = now.beginning_of_day.advance(all_attributes['start'])
      start < now ? start.advance(:days => 1) : start 
    when 'hourly'                                                      
      start = now.change(:min => 0).advance(all_attributes['start'])
      start < now ? start.advance(:hours => 1) : start 
    else
      puts "*** frequency: <#{all_attributes[:frequency]}>"
      raise "unexpected frequency encountered"
    end
end

#startObject



173
174
175
176
177
# File 'lib/lucid_works/activity.rb', line 173

def start
  self.start_time = 0
  self.active = true
  save
end

#start_is_more_than_one_period_in_the_future?Boolean

Returns:

  • (Boolean)


143
144
145
146
147
# File 'lib/lucid_works/activity.rb', line 143

def start_is_more_than_one_period_in_the_future?
  # This works fine with start times that are multiple periods in the past
  # because that gives a negative difference, and period is always >= 0
    (self.start_time - Time.now) > self.period 
end

#t_typeObject



169
170
171
# File 'lib/lucid_works/activity.rb', line 169

def t_type
  I18n.t(type, :scope => 'activemodel.models.lucid_works.collection.activity.type')
end

#ui_appropriate_defaults!Object

convenience method for setting defaults in a UI that make sense for a user



163
164
165
166
167
# File 'lib/lucid_works/activity.rb', line 163

def ui_appropriate_defaults!
  if self.start_time.blank? || self.period == 0
    self.active = true
  end
end