QLab Script - path checker

Contents

Table of Contents

This is an "external script" - see QLab Scripts and Macros

 
# Path checker
 
--
 
set theExplanation to "This script allows you to search the current QLab workspace for audio files that may be in the wrong place, by checking the file targets " & ¬
    "for the text you enter below (it doesn't check broken cues, as they do not report a file target when queried by a script).
 
Optionally, you can then either save a tab-delimited text file on the Desktop with a list of these audio files, or step through the cues to fix them one at a time " & ¬
    "(which only works if \"Playback position is always the selected cue\" is ON!). \"Fix\" will maintain start/end & loop start/end times, whilst \"Replace\" will not."
 
--
 
(* This script is not designed to be run from within QLab!
 
v1.0: 17/11/09 Rich Walsh (proof of concept)
v1.1: 11/01/10 Improved efficiency; added tell front workspace for elegance; wrapped text for better wiki experience;
        implemented dialogTitle for cross-script pillaging; new explanation format
v1.2: 31/01/10 Decided to put step and fix procedure into this script, and not into "All purpose enquiry"; general tidying
 
<<< Last tested with: QLab 2.2.6; Mac OS 10.5.8 & 10.6.2 >>> *)
 
-- ###FIXME### QLab and/or the "script runner" is, generally, increasingly unresponsive to scripts the more cues there are in a workspace
 
-- Declarations
 
global dialogTitle
set dialogTitle to "Path checker"
 
set defaultAnswer to "soundshare" -- Use this to specify the default answer,
(* ie: the place from which you are most likely to have inadvertently copied files (eg: a server, or external hard drive) *)
 
-- Preamble
 
set searchText to ""
repeat until searchText is not ""
    set searchText to text returned of (display dialog theExplanation & return & return & "Enter the text to search for:" with title dialogTitle with icon 1 ¬
        default answer defaultAnswer buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel")
    set defaultAnswer to ""
end repeat
 
-- Grab the current time and format it appropriately to append it to the filename
-- Written with help from http://www.fluther.com/disc/22258/applescript-get-and-reformat-current-date-then-insert-it-in-any/
 
set currentTIDs to AppleScript's text item delimiters
set AppleScript's text item delimiters to "" -- Can't assume this!
set {year:y, month:m, day:d, time string:t} to (current date)
set dateString to (y * 10000 + m * 100 + d) as string
set timeString to (t) as string
set theTime to ¬
    (text items 3 thru 4 of dateString) & "-" & ¬
    (text items 5 thru 6 of dateString) & "-" & ¬
    (text items 7 thru 8 of dateString) & " " & ¬
    (text items 1 thru 2 of timeString) & ¬
    (text items 4 thru 5 of timeString) as string
set AppleScript's text item delimiters to currentTIDs
 
-- Check QLab is running
 
tell application "System Events"
    set qLabIsRunning to count (every process whose name is "QLab")
end tell
if qLabIsRunning is 0 then
    display dialog "QLab is not running." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
    return
end if
 
tell application "QLab"
 
    activate
 
    -- Get the workspace name for later, and also protect against no open workspace
 
    try
        set workspaceName to q number of front workspace -- This actually gets the name of the workspace
    on error
        display dialog "There is no workspace open in QLab." with title dialogTitle with icon 0 buttons {"OK"} default button "OK" giving up after 5
        return
    end try
 
    -- Find the cues (which may take a few moments)
 
    display dialog "One moment caller..." with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 1
 
    tell front workspace
 
        set allCues to every cue whose (q type is "Audio" and broken is false)
        set allCuesRef to a reference to allCues
        set allTargets to file target of every cue whose (q type is "Audio" and broken is false)
        set allTargetsRef to a reference to allTargets
        set countCues to count allCuesRef
        set foundCues to {}
 
        repeat with i from 1 to countCues
            if ((item i of allTargetsRef) as string) contains searchText then
                copy item i of allCuesRef to end of foundCues
            end if
        end repeat
        set foundCuesRef to a reference to foundCues
        set countFoundCues to count foundCuesRef
 
        -- Return the result
 
        if countFoundCues is not 0 then
 
            if countFoundCues is 1 then
                set thereAreString to "There is 1 cue in the workspace \""
                set pathString to "path contains"
            else
                set thereAreString to "There are " & countFoundCues & " cues in the workspace \""
                set pathString to "paths contain"
            end if
            activate
            set whatNow to the button returned of (display dialog thereAreString & workspaceName & "\" whose audio file target " & pathString ¬
                & " \"" & searchText & "\"..." with title dialogTitle with icon 2 buttons {"Thanks", "Step and fix", "Make a list"} ¬
                default button "Make a list" cancel button "Thanks")
 
            if whatNow is "Step and fix" then
 
                -- Jump to the cue
 
                repeat with i from 1 to countFoundCues
                    set eachFoundCue to item i of foundCuesRef
 
                    set theContainer to (the first cue whose (q type is "Group" and cues contains eachFoundCue))
                    repeat until mode of theContainer is cue_list
                        set theContainer to (the first cue whose (q type is "Group" and cues contains theContainer))
                    end repeat
                    set current cue list to theContainer
                    set playback position of the current cue list to eachFoundCue
                    activate
                    set skipReplaceFix to button returned of (display dialog "Search text: \"" & searchText & "\"" & return & return & ¬
                        "Here's cue " & i & " of " & countFoundCues & "." & return & return & "(\"Fix\" keeps times, \"Replace\" doesn't.)" with title dialogTitle ¬
                        with icon 1 buttons {"Skip", "Replace", "Fix"} default button "Fix")
 
                    if skipReplaceFix is not "Skip" then
 
                        -- Get the new file target
 
                        if skipReplaceFix is "Fix" then
                            set promptHeader to "FIXING: start/end & loop start/end times maintained..."
                        else
                            set promptHeader to "REPLACING: this process will not maintain the start/end & loop start/end times!"
                        end if
 
                        set newTarget to choose file with prompt promptHeader & return & return & ¬
                            "Please select the new file target for this cue:" without invisibles
 
                        -- Set it
 
                        if skipReplaceFix is "Fix" then
                            set currentStart to start time of eachFoundCue
                            if currentStart is missing value then -- ### Mac OS X 10.6.2 fix for incorrectly returned items
                                set currentStart to 0
                            end if
                            set currentLoopStart to loop start time of eachFoundCue
                            if currentLoopStart is missing value then -- ### Mac OS X 10.6.2 fix for incorrectly returned items
                                set currentLoopStart to 0
                            end if
                            set currentLoopEnd to loop end time of eachFoundCue
                            set currentEnd to end time of eachFoundCue
                        end if
 
                        set file target of eachFoundCue to newTarget
 
                        if skipReplaceFix is "Fix" then
                            set start time of eachFoundCue to currentStart
                            set loop start time of eachFoundCue to currentLoopStart
                            set loop end time of eachFoundCue to currentLoopEnd
                            set end time of eachFoundCue to currentEnd
                        end if
 
                    end if
 
                end repeat
 
                display dialog "That's your lot." with title dialogTitle with icon 1 buttons {"Small onion"} default button "Small onion"
 
            else if whatNow is "Make a list" then
 
                -- Make the list (this is the really slow bit)
 
                display dialog "One moment caller..." with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 1
 
                set startTime to time of (current date)
 
                set theText to "#" & tab & "Q" & tab & "Target"
                repeat with i from 1 to countFoundCues
                    set eachCue to item i of foundCuesRef
                    set eachCueRef to (a reference to eachCue)
                    set theText to theText & (return & q number of eachCueRef & tab & q name of eachCueRef & tab & ¬
                        (POSIX path of (file target of eachCueRef as alias)))
                    if i mod 50 is 0 and (countFoundCues - i) > 25 then -- Countdown timer (and opportunity to escape)
                        set timeTaken to ((time of (current date)) - startTime) as integer
                        set timeString to my makeMMSS(timeTaken)
                        if application "QLab" is frontmost then
                            display dialog (("Time elapsed: " & timeString & " - " & i as string) & " of " & countFoundCues as string) & ¬
                                " found Audio Cues done..." with title dialogTitle with icon 1 ¬
                                buttons {"Cancel", "OK"} default button "OK" cancel button "Cancel" giving up after 1
                        end if
                    end if
                end repeat
                set theText to theText & return & return & "Search text: " & searchText
 
                -- Create a string of the full path of the text file to be created
 
                set newFile to "" & (path to desktop) & "QLab | " & workspaceName & " | " & dialogTitle & " | " & theTime & ".txt"
 
                -- Make the file
 
                copy (open for access newFile with write permission) to theOpenFile
                write theText to theOpenFile
                close access theOpenFile
 
                -- Open it in TextEdit
 
                tell application "TextEdit"
                    activate
                    open file (newFile)
                    set zoomed of front window to true
                    set timeTaken to ((time of (current date)) - startTime) as integer
                    set timeString to my makeNiceT(timeTaken)
                    display dialog "Done. 
 
(That took " & timeString & ".)" with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 60
                end tell
 
            end if
 
        else
            activate
            display dialog "All clear!" with title dialogTitle with icon 1 buttons {"OK"} default button "OK" giving up after 5
        end if
 
    end tell
 
end tell
 
-- Subroutines
 
on makeMMSS(howLong)
    set howManyMinutes to howLong div 60
    set minuteString to (howManyMinutes as string)
    set howManySeconds to howLong mod 60 as integer
    if howManySeconds > 9 then
        set secondString to (howManySeconds as string)
    else
        set secondString to "0" & (howManySeconds as string)
    end if
    return minuteString & ":" & secondString
end makeMMSS
 
on makeNiceT(howLong)
    if howLong is 0 then
        return "less than a second"
    end if
    set howManyHours to howLong div 3600
    if howManyHours is 0 then
        set hourString to ""
    else if howManyHours is 1 then
        set hourString to "1 hour"
    else
        set hourString to (howManyHours as string) & " hours"
    end if
    set howManyMinutes to (howLong mod 3600) div 60
    if howManyMinutes is 0 then
        set minuteString to ""
    else if howManyMinutes is 1 then
        set minuteString to "1 minute"
    else
        set minuteString to (howManyMinutes as string) & " minutes"
    end if
    set howManySeconds to howLong mod 60 as integer
    if howManySeconds is 0 then
        set secondString to ""
    else if howManySeconds is 1 then
        set secondString to "1 second"
    else
        set secondString to (howManySeconds as string) & " seconds"
    end if
    if hourString is not "" then
        if minuteString is not "" and secondString is not "" then
            set theAmpersand to ", "
        else if minuteString is not "" or secondString is not "" then
            set theAmpersand to " and "
        else
            set theAmpersand to ""
        end if
    else
        set theAmpersand to ""
    end if
    if minuteString is not "" and secondString is not "" then
        set theOtherAmpersand to " and "
    else
        set theOtherAmpersand to ""
    end if
    return hourString & theAmpersand & minuteString & theOtherAmpersand & secondString
end makeNiceT
 
(* END: Path checker *)