class Schedule
cattr_accessor :logger
QBeat.setup_logging
# returns a programming block representing the current date/time in the
# schedule
#
# Time should only be set for testing purposes
def self.load(filename, time=Time.now)
sched = load_schedule_file(filename)
today = sched.find_all {|slot| slot.is_today?(time)}
today.each do |slot|
return load_pblock(filename, slot) if slot.is_now?(time)
end
today << time
today.sort!
today.each_index do |idx|
slot = today[idx]
if slot.kind_of?(Time)
if slot == today.first
ts = TimeSlot.new(:start => 0, :end => today[idx+1].start)
elsif slot == today.last
ts = TimeSlot.new(:start => today[idx-1].end, :end => 0)
else
ts = TimeSlot.new(:start => today[idx-1].end,
:end => today[idx+1].start)
end
return ProgrammingBlock.default(:name => "Random",
:description => "Pure random",
:time_slot => ts)
end
end
raise "I screwed up!"
end
# Take a schedule file, and return an array of sorted TimeSlot objects
def self.load_schedule_file(filename)
begin
sched = YAML::load_file(filename)
sched.map! {|slot| TimeSlot.new(slot)}
sched.sort
rescue Exception => ex
logger.error("Failed to load schedule: #{ex.inspect}")
logger.warn("Loading default programming block")
[TimeSlot.default]
end
end
def self.load_pblock(filename, time_slot)
begin
return ProgrammingBlock.default unless time_slot.pblock
filename = File.join(PB_DIR, time_slot.pblock + ".yml")
return ProgrammingBlock.default unless File.exist?(filename)
yaml_pb = YAML::load_file(filename).symbolize_keys
yaml_pb[:filename] = filename
yaml_pb[:time_slot] = time_slot
ProgrammingBlock.new(yaml_pb)
rescue Exception => ex
logger.error("#{ex.inspect}\n+#{ex.backtrace.join("\n")}")
ProgrammingBlock.default
end
end
def initialize
@@logger = nil
end
# Iterate through the day's programming blocks, returning an array of them.
def self.for(filename, date=Time.now)
sched = load_schedule_file(filename)
pblocks = []
today = sched.find_all {|slot| slot.is_today?(date)}.sort
date = date.midnight
tomorrow = date.tomorrow
loop do
pblocks << pblock = load(filename, date)
date = TimeSlot.blend_with(pblock.end, date)
break if date >= tomorrow || pblock.end == "00:00"
end
pblocks
end
def self.for_week_of(filename, date=Time.now)
days = []
sched = load_schedule_file(filename)
orig_date = date
0.upto(6) do |x|
pblocks = []
today = sched.find_all {|slot| slot.is_today?(orig_date + x.days)}.sort
date = (orig_date + x.days).midnight
tomorrow = date.tomorrow
loop do
pblocks << pblock = load(filename, date)
date = TimeSlot.blend_with(pblock.end, date)
break if date >= tomorrow || pblock.end == "00:00"
end
days << pblocks
end
days
end
def self.matches?(filename, pblock, time=Time.now)
now_pblock = load(filename, time)
now_pblock == pblock
end
private
# TODO this is kinda crappy
if RAILS_ENV == "test"
PB_DIR = File.join(RAILS_ROOT, "spec", "fixtures", "programming_blocks")
else
PB_DIR = File.join(RAILS_ROOT, "config", "programming_blocks")
end
def self.to_hour_min(time)
begin
raise "foo" if /^(\d{1,2})(?::(\d{2}))?$/.match(time.to_s).nil?
hour = $~[1].to_i % 24
min = $~[2].to_i
sprintf("%02d:%02d", hour, min)
rescue Exception
raise "Invalid schedule time format: '#{time}'"
end
end
end