The Wednesday Problem: Checking how many tuners EyeTV needs for scheduled recordings

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

Leave a Reply

Your email address will not be published. Required fields are marked *