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)


157
158
159
160
161
162
# File 'lib/lucid_works/activity.rb', line 157

def custom?
  return true if self.frequency == 'custom'
  return false unless self.start_time
  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



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

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



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

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



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

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
  when 'custom' then period # don't change anything
  else raise "unknown frequency"
  end
end

#hourObject

convenince method for setting the current value in a view selector



128
129
130
# File 'lib/lucid_works/activity.rb', line 128

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

#minObject

convenince method for setting the current value in a view selector



135
136
137
# File 'lib/lucid_works/activity.rb', line 135

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

#next_startObject

predict when action will occur next if active at that time



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

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


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
120
121
122
123
# File 'lib/lucid_works/activity.rb', line 94

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 
    when 'custom'
      # don't change this activity's start_time
    else
      puts "*** frequency: <#{all_attributes[:frequency]}>"
      raise "unexpected frequency encountered"
    end
end

#startObject



177
178
179
180
181
# File 'lib/lucid_works/activity.rb', line 177

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

#start_is_more_than_one_period_in_the_future?Boolean

Returns:

  • (Boolean)


147
148
149
150
151
# File 'lib/lucid_works/activity.rb', line 147

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



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

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



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

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