Here at Ice Moon Prison, inmates receive the Australian digital free-to-air broadcast, on the assumption that it is the least consumer-friendly television ecosystem in existence. Shows routinely run late, requiring those using PVR software to add at least 20 minutes to each scheduled recording Just In Case. Networks also collude and ensure that all the shows you actually want to watch are scheduled at the same time on different channels. We call this the Wednesday Problem.
Ice Moon Prison uses EyeTV and HDHomeRuns for a total of four tuners. This is usually sufficient except for the busiest Wednesdays. Rather than manually check the schedule and count whether five or more tuners are needed at any given time, we have an AppleScript … er, script, which gets this information straight from EyeTV and reports how many tuners are needed for its upcoming scheduled recordings.
local now, schedule_list, eyetv_programs, eyetv_recordings, concurrent_limit set now to current date -- How many tuners are available? set concurrent_limit to 4 set schedule_list to {} tell application "EyeTV" set eyetv_programs to programs set eyetv_recordings to recordings repeat with schedule in eyetv_programs local sched_start_time, sched_end_time, sched_channel, matching_recording set sched_start_time to (start time of schedule) - prepad time * 60 set sched_end_time to sched_start_time + (duration of schedule) + prepad time * 60 + postpad time * 60 set sched_channel to channel number of schedule set matching_recording to 0 repeat with rec in eyetv_recordings local recording_start_time, recording_end_time, recording_channel set recording_start_time to actual start of rec set recording_end_time to recording_start_time + (actual duration of rec) set recording_channel to channel number of rec if (recording_channel = sched_channel and recording_start_time ? sched_start_time and recording_end_time ? sched_end_time) then set matching_recording to unique ID of rec exit repeat end if end repeat if (matching_recording = 0) then copy schedule to end of schedule_list end if end repeat end tell local tuners_needed, overlap_list set tuners_needed to 0 set overlap_list to {} repeat with candidate in schedule_list tell application "EyeTV" local candidate_start_time -- , candidate_end_time set candidate_start_time to (start time of candidate) - prepad time * 60 local overlap set overlap to 0 repeat with contestant in schedule_list local contestant_start_time, contestant_end_time set contestant_start_time to (start time of contestant) - prepad time * 60 set contestant_end_time to contestant_start_time + (duration of contestant) + prepad time * 60 + postpad time * 60 if (candidate_start_time ? contestant_start_time and candidate_start_time ? contestant_end_time) then set overlap to overlap + 1 end if end repeat if (overlap > tuners_needed) then set tuners_needed to overlap if (overlap > concurrent_limit) then log name of candidate & " " & overlap end if if (overlap > concurrent_limit and overlap_list does not contain candidate_start_time) then copy candidate_start_time to end of overlap_list end if end tell end repeat local output if (length of overlap_list > 0) then set output to "2" & return & tuners_needed & " tuners needed" repeat with start_time in overlap_list set output to output & return & (start_time as string) end repeat else set output to "0" & return & tuners_needed & " tuners needed" return output end if
Run this script like so, using tr to convert AppleScript’s carriage returns to line feeds:
$ osascript eyetv-overlap-check.applescript | tr '\015' '\012' 0 4 tuners needed
The first line is 0 if there are enough tuners, 2 otherwise, designed to be fed into a Nagios check script like this one:
#!/bin/sh print_usage() { echo "check_osascript user applescript.scpt" } if [ $# -lt 2 ]; then print_usage; exit $STATE_OK fi script="$1" osascript_status=3 # Run script, translating Mac OS Classic line ends into Unix ones. sudo -u "$1" osascript "$2" | tr '\015' '\012' > /tmp/check-osascript.$$ if [ $? -ne 0 ]; then exit 3 fi exec 0</tmp/check-osascript.$$ # First line is exit status. read osascript_status # Remaining lines are echoed as-is. while read; do echo $REPLY done rm -f /tmp/check-osascript.$$ exit $osascript_status