Remove calendar
parent
5f59c89951
commit
96b8b7c704
|
@ -1,77 +0,0 @@
|
|||
module FarmEvents
|
||||
# Used to calculate next 60ish occurrences or so of a FarmEvent.
|
||||
class GenerateCalendar < Mutations::Command
|
||||
GRACE_PERIOD = 5.minutes
|
||||
NEVER = FarmEvent::NEVER.to_s
|
||||
TIME = { "minutely" => 60,
|
||||
"hourly" => 60 * 60,
|
||||
"daily" => 60 * 60 * 24,
|
||||
"weekly" => 60 * 60 * 24 * 7,
|
||||
"monthly" => 60 * 60 * 24 * 30, # Not perfect...
|
||||
"yearly" => 60 * 60 * 24 * 365 }
|
||||
UNIT_TRANSLATION = { "minutely" => :minutes,
|
||||
"hourly" => :hours,
|
||||
"daily" => :days,
|
||||
"weekly" => :weeks,
|
||||
"monthly" => :months,
|
||||
"yearly" => :years }
|
||||
required do
|
||||
integer :repeat
|
||||
string :time_unit, in: FarmEvent::UNITS_OF_TIME
|
||||
time :origin
|
||||
time :lower_limit
|
||||
end
|
||||
|
||||
optional do
|
||||
time :upper_limit
|
||||
end
|
||||
|
||||
def execute
|
||||
# Does the input have a valid repeat?
|
||||
# Is it in the future?
|
||||
# Then generate a calendar.
|
||||
# Otherwise, return a "partial calendar" that is either empty or (in the
|
||||
# case of one-off events) has only one date in it (origin).
|
||||
(is_repeating ? full_calendar : partial_calendar)
|
||||
end
|
||||
|
||||
def full_calendar
|
||||
interval_sec = TIME[time_unit] * repeat
|
||||
upper = compute_endtime
|
||||
# Current time, plus a 5 minute grace period.
|
||||
now = Time.now - GRACE_PERIOD
|
||||
# How many items must we skip to get to the first occurence?
|
||||
skip_intervals = ((lower_limit - origin) / interval_sec).ceil
|
||||
# At what time does the first event occur?
|
||||
first_item = origin + (skip_intervals * interval_sec).seconds
|
||||
list = [first_item]
|
||||
60.times do
|
||||
item = list.last + interval_sec.seconds
|
||||
list.push(item) unless (item >= upper) || (item <= now)
|
||||
end
|
||||
|
||||
return list
|
||||
end
|
||||
|
||||
def partial_calendar
|
||||
in_future? ? [origin] : []
|
||||
end
|
||||
|
||||
def the_unit
|
||||
UNIT_TRANSLATION[time_unit]
|
||||
end
|
||||
|
||||
def is_repeating
|
||||
(the_unit != NEVER) && the_unit && repeat.send(the_unit)
|
||||
end
|
||||
|
||||
def in_future?
|
||||
origin > (Time.now - GRACE_PERIOD)
|
||||
end
|
||||
|
||||
def compute_endtime
|
||||
next_year = (Time.now + 1.year)
|
||||
(upper_limit && (upper_limit < next_year)) ? upper_limit : next_year
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,29 +1,5 @@
|
|||
class FarmEventSerializer < ActiveModel::Serializer
|
||||
class BadExe < StandardError; end
|
||||
attributes :id, :start_time, :end_time, :repeat, :time_unit, :executable_id,
|
||||
:executable_type, :calendar
|
||||
|
||||
BAD_EXE = "Dont know how to calendarize %s"
|
||||
|
||||
def calendar
|
||||
case object.executable
|
||||
when Sequence then sequence_calendar
|
||||
when Regimen then []
|
||||
else
|
||||
throw BadExe.new(BAD_EXE % object.executable.class)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sequence_calendar
|
||||
FarmEvents::GenerateCalendar
|
||||
.run!(origin: object.start_time,
|
||||
lower_limit: Time.now,
|
||||
upper_limit: object.end_time,
|
||||
repeat: object.repeat,
|
||||
time_unit: object.time_unit)
|
||||
.map(&:utc)
|
||||
.map(&:as_json)
|
||||
end
|
||||
:executable_type
|
||||
end
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe FarmEvents::GenerateCalendar do
|
||||
it 'Builds a list of dates' do
|
||||
start = Time.now + 1.minute
|
||||
params = { origin: start,
|
||||
lower_limit: start,
|
||||
upper_limit: start + 1.hours,
|
||||
repeat: 5,
|
||||
time_unit: "minutely" }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.first).to eq(params[:origin])
|
||||
calendar.map { |date| expect(date).to be >= params[:origin] }
|
||||
calendar.map { |date| expect(date).to be <= params[:upper_limit] }
|
||||
expect(calendar.length).to eq(12)
|
||||
end
|
||||
|
||||
it 'hit a bug in production' do
|
||||
start = Time.now + 1.minute
|
||||
finish = start + 5.days
|
||||
params = { origin: start,
|
||||
lower_limit: start,
|
||||
upper_limit: finish,
|
||||
repeat: 1,
|
||||
time_unit: "daily" }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.first.day).to eq(start.day)
|
||||
expect(calendar.length).to be > 4
|
||||
expect(calendar.length).to be < 7
|
||||
end
|
||||
|
||||
it 'has a known calendar bug' do
|
||||
tomorrow = (Time.now + 1.day).midnight
|
||||
ten_am = tomorrow + 10.hours
|
||||
calendar = FarmEvents::GenerateCalendar.run!("origin" => tomorrow,
|
||||
"lower_limit" => tomorrow,
|
||||
"upper_limit" => ten_am,
|
||||
"repeat" => 2,
|
||||
"time_unit" => "hourly")
|
||||
expect(calendar.length).to be > 3
|
||||
expect(calendar.length).to be < 7
|
||||
end
|
||||
|
||||
it 'hit more bugs' do
|
||||
tomorrow = Time.now + 1.day
|
||||
calendar = FarmEvents::GenerateCalendar.run!("origin" => tomorrow,
|
||||
"lower_limit" => tomorrow,
|
||||
"upper_limit" => tomorrow + 5.minutes,
|
||||
"repeat" => 1,
|
||||
"time_unit" => "minutely")
|
||||
expect(calendar.length).to be > 3
|
||||
expect(calendar.length).to be < 7
|
||||
end
|
||||
|
||||
it 'schedules one-off events: origin < lower_limit outside of grace period' do
|
||||
params = { origin: Time.now - 6.minutes,
|
||||
lower_limit: Time.now,
|
||||
upper_limit: nil,
|
||||
repeat: 1,
|
||||
time_unit: FarmEvent::NEVER }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.length).to eq(0)
|
||||
end
|
||||
|
||||
it 'schedules one-off events: origin < lower_limit within grace period' do
|
||||
params = { origin: Time.now - 2.minutes,
|
||||
lower_limit: Time.now,
|
||||
upper_limit: nil,
|
||||
repeat: 1,
|
||||
time_unit: FarmEvent::NEVER }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.length).to eq(1)
|
||||
end
|
||||
|
||||
it 'schedules one-off events: origin = lower_limit' do
|
||||
tomorrow = Time.now + 1.day
|
||||
params = { origin: tomorrow,
|
||||
lower_limit: tomorrow,
|
||||
upper_limit: nil,
|
||||
repeat: 1,
|
||||
time_unit: FarmEvent::NEVER }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.length).to eq(1)
|
||||
expect(calendar.first).to eq(params[:origin])
|
||||
end
|
||||
|
||||
it 'schedules one-off events: origin > lower_limit' do
|
||||
params = { origin: Time.now + 1.day,
|
||||
lower_limit: Time.now - 1.day,
|
||||
upper_limit: nil,
|
||||
repeat: 1,
|
||||
time_unit: FarmEvent::NEVER }
|
||||
calendar = FarmEvents::GenerateCalendar.run!(params)
|
||||
expect(calendar.length).to eq(1)
|
||||
expect(calendar.first).to eq(params[:origin])
|
||||
end
|
||||
|
||||
idea = ->(start, interval_sec, lower, upper = (Time.now + 1.year)) {
|
||||
# How many items must we skip to get to the first occurence?
|
||||
skip_intervals = ((lower - start) / interval_sec).ceil
|
||||
# At what time does the first event occur?
|
||||
first_item = start + (skip_intervals * interval_sec).seconds
|
||||
list = [first_item]
|
||||
60.times do
|
||||
item = list.last + interval_sec.seconds
|
||||
list.push(item) unless item > upper
|
||||
end
|
||||
return list
|
||||
}
|
||||
|
||||
it 'trys new idea' do
|
||||
monday = (Time.now - 14.days).monday.midnight + 8.hours # 8am Monday
|
||||
tuesday = monday + 19.hours # 3am Tuesday
|
||||
thursday = (monday + 3.days) + 10.hours # 18pm Thursday
|
||||
interval = 4 * FarmEvents::GenerateCalendar::TIME["hourly"]
|
||||
result1 = idea[monday, interval, tuesday, thursday]
|
||||
expect(result1[0].tuesday?).to be(true)
|
||||
expect(result1[0].hour).to be(4)
|
||||
expect(result1.length).to be(16)
|
||||
end
|
||||
end
|
|
@ -9,11 +9,4 @@ describe FarmEventSerializer do
|
|||
time_offset: 7000)
|
||||
fe
|
||||
end
|
||||
|
||||
it "does not render `nil` and friends" do
|
||||
farm_event.executable = nil
|
||||
expect{
|
||||
FarmEventSerializer.new(farm_event).as_json
|
||||
}.to raise_error(UncaughtThrowError)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
import * as moment from "moment";
|
||||
import {
|
||||
FarmEventWithExecutable
|
||||
} from "../farm_designer/farm_events/calendar/interfaces";
|
||||
|
||||
export const TIME = {
|
||||
MONDAY: moment("2017-06-19T06:30:00.000-05:00"),
|
||||
TUESDAY: moment("2017-06-20T06:30:00.000-05:00"),
|
||||
WEDNESDAY: moment("2017-06-21T06:30:00.000-05:00"),
|
||||
THURSDAY: moment("2017-06-22T06:30:00.000-05:00"),
|
||||
FRIDAY: moment("2017-06-23T06:30:00.000-05:00"),
|
||||
SATURDAY: moment("2017-06-24T06:30:00.000-05:00")
|
||||
};
|
||||
|
||||
export let fakeFarmEventWithExecutable = (): FarmEventWithExecutable => {
|
||||
return {
|
||||
id: 1,
|
||||
start_time: "---",
|
||||
repeat: 5,
|
||||
time_unit: "daily",
|
||||
executable_id: 23,
|
||||
executable_type: "Sequence",
|
||||
executable: {
|
||||
color: "red",
|
||||
name: "faker",
|
||||
kind: "sequence",
|
||||
args: { version: 0, label: "WIP", locals: { kind: "scope_declaration", args: {} }, }
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export let calendarRows = [
|
||||
{
|
||||
"sortKey": 1500922800,
|
||||
"year": 17,
|
||||
"month": "Jul",
|
||||
"day": 24,
|
||||
"items": [
|
||||
{
|
||||
"mmddyy": "072417",
|
||||
"sortKey": 1500922800,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79
|
||||
},
|
||||
{
|
||||
"mmddyy": "072417",
|
||||
"sortKey": 1500915900,
|
||||
"timeStr": "12:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072417",
|
||||
"sortKey": 1500930300,
|
||||
"timeStr": "04:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072417",
|
||||
"sortKey": 1500922800,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072417",
|
||||
"sortKey": 1500944400,
|
||||
"timeStr": "08:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sortKey": 1501009200,
|
||||
"year": 17,
|
||||
"month": "Jul",
|
||||
"day": 25,
|
||||
"items": [
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1501009200,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1500959100,
|
||||
"timeStr": "12:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1500973500,
|
||||
"timeStr": "04:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1500987900,
|
||||
"timeStr": "08:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1501002300,
|
||||
"timeStr": "12:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1501016700,
|
||||
"timeStr": "04:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1501009200,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072517",
|
||||
"sortKey": 1501030800,
|
||||
"timeStr": "08:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"sortKey": 1501095600,
|
||||
"year": 17,
|
||||
"month": "Jul",
|
||||
"day": 26,
|
||||
"items": [
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501095600,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501045500,
|
||||
"timeStr": "12:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501059900,
|
||||
"timeStr": "04:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501074300,
|
||||
"timeStr": "08:05am",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501088700,
|
||||
"timeStr": "12:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501103100,
|
||||
"timeStr": "04:05pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501095600,
|
||||
"timeStr": "02:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
},
|
||||
{
|
||||
"mmddyy": "072617",
|
||||
"sortKey": 1501117200,
|
||||
"timeStr": "08:00pm",
|
||||
"heading": "Every 4 hours",
|
||||
"executableId": 25,
|
||||
"subheading": "25",
|
||||
"id": 79,
|
||||
"childExecutableName": "Goto 0, 0, 0 123"
|
||||
}
|
||||
]
|
||||
}
|
||||
];
|
Loading…
Reference in New Issue