开发者

How do I repeatedly call an AppleScript droplet with different filenames?

I have a lovely AppleScript droplet which performs OCR of a PDF file using Adobe Acrobat. I am a pretty good Python programmer but don't really understand AppleScript. I have a list of all the PDFs on my system that need to be OCRed. It would be really annoying to have to drag each on one top of the script. I'd like to have either a small python program that has the droplet process each script, or else I'd like to modify the script to read the textfile and dispense with the dropping stuff.

I tried using osascript to open the PDFs with a single test:

tell application "OCRIt-Acrobat"
  open alias "imac3:Users:vy32:FFJ.pdf"
end tell

And I got this lovely error:

31:103: execution error: OCRIt-Acrobat got an error: alias "imac3:Users:vy32:FFJ.pdf" of «script» doesn’t understand the open message. (-1708)

Well, that's not too helpful.

Anyone know what I should do?

Here is OCRIt-Acrobat, in all its glory:

property mytitle : "ocrIt-Acrobat"
-- Modified from a script created by Macworld http://www.macworld.com/article/60229/2007/10/nov07geekfactor.html

-- I am called when the user open the script with a double click
on run
    tell me
        activate
        display dialog "I am an AppleScript droplet." & return & return & "Please drop a bunch of PDF files onto my icon to batch O开发者_如何学CCR them." buttons {"OK"} default button 1 with title mytitle with icon note
    end tell
end run

-- I am called when the user drops Finder items onto the script icon
-- Timeout of 36000 seconds to allow for OCRing really big documents
on open droppeditems
    with timeout of 36000 seconds
        try
            repeat with droppeditem in droppeditems
                set the item_info to info for droppeditem
                tell application "Adobe Acrobat Pro"
                    activate
                    open droppeditem
                end tell
                tell application "System Events"

                    tell application process "Acrobat"

                        click the menu item "Recognize Text Using OCR..." of menu 1 of menu item "OCR Text Recognition" of the menu "Document" of menu bar 1
                        try
                            click radio button "All pages" of group 1 of group 2 of group 1 of window "Recognize Text"
                        end try
                        click button "OK" of window "Recognize Text"

                    end tell

                end tell
                tell application "Adobe Acrobat Pro"
                    save the front document with linearize
                    close the front document
                end tell
            end repeat
            -- catching unexpected errors
        on error errmsg number errnum
            my dsperrmsg(errmsg, errnum)
        end try
    end timeout
end open

-- I am displaying error messages
on dsperrmsg(errmsg, errnum)
    tell me
        activate
        display dialog "Sorry, an error occured:" & return & return & errmsg & " (" & errnum & ")" buttons {"Never mind"} default button 1 with icon stop with title mytitle
    end tell
end dsperrmsg

Thanks!


By calling alias you are essentially making a direct call to a file at that exact path, If the alias can't be found, then Applescript throws an error. If you are reading a list from a text file, then an error could occur in the generation of that list you aren't checking. At minimum, you need to use System Events to make sure you are working with a valid file:

on FileExists(theFile) -- (String) as Boolean
    tell application "System Events"
        if exists file theFile then
            return true
        else
            return false
        end if
    end tell
end FileExists

I have this template I use for processing any number of files or folders that were dropped on a droplet. As long as all your target files are in the same folder hierarchy, you won't need that external list of files:

property kTargetFileExtensions : {"txt", "rtf", "pdf"}
property pValidFileList : {}

on open of theFiles -- Executed when files or folders are dropped on the script

    set fileCount to (get count of items in theFiles)

    repeat with thisFile from 1 to fileCount
        set theFile to item thisFile of theFiles

        my processInitialFile(theFile)

    end repeat

    my processValidFileList()

end open

on run {} -- Executed when the script is run from within the editor
    set sourceFolder to (choose folder)

    my processInitialFile(sourceFolder)

    my processValidFileList()
end run

on processInitialFile(theFile)
    tell application "System Events"
        set file_info to get info for theFile
    end tell

    if visible of file_info is true then -- check for the file extension here as well
        if folder of file_info is true then
            my createList(theFile)
        else
            set targetFileFound to isTargetFile(fileName, kTargetFileExtensions) of me

            if (targetFileFound) then
                set end of pValidFileList to theFile
            end if
        end if
    end if
end processInitialFile

on processValidFileList() -- (void) as void
    set firstFile to 1
    set lastFile to (count pValidFileList)
    repeat with thisFile from firstFile to lastFile
        set theFile to item thisFile of pValidFileList

        log theFile

        (* enter file processing code here. *)

    end repeat

end processValidFileList

on createList(mSource_folder)
    set item_list to ""

    tell application "System Events"
        set item_list to get the name of every disk item of (mSource_folder as alias)
    end tell

    set item_count to (get count of items in item_list)

    repeat with i from 1 to item_count
        set the_properties to ""

        set the_item to item i of the item_list
        set fileName to the_item
        set the_item to ((mSource_folder & the_item) as string) as alias

        tell application "System Events"
            set file_info to get info for the_item
        end tell

        if visible of file_info is true then -- check for the file extension here as well
            if folder of file_info is true then
                my createList(the_item)
            else
                set targetFileFound to isTargetFile(fileName, kTargetFileExtensions) of me

                if (targetFileFound) then
                    set end of pValidFileList to the_item
                end if
            end if
        end if

    end repeat
end createList

on isTargetFile(theFilename, theTargetExtensions) -- (string, array) as boolean
    set AppleScript's text item delimiters to "."
    set fileNameList to every text item of theFilename
    set AppleScript's text item delimiters to ""

    try
        set theFileExtension to item 2 of fileNameList as string
    on error
        return false
    end try

    set firstTargetExtension to 1
    set lastTargetExtension to (count theTargetExtensions)
    repeat with thisTargetExtension from firstTargetExtension to lastTargetExtension
        set targetExtension to item thisTargetExtension of theTargetExtensions
        if theFileExtension is targetExtension then
            return true
        end if
    end repeat

    return false
end isTargetFile


You can't tell an applescript application to open a file. That's not how scripts work even if it's an application. You do this using the "run script" command and you can pass parameters with that command. As an example create this applescript droplet and save it on your desktop with the name "aaa".

on run argList
    try
        -- when an application is double-clicked it errors seemingly because no arguments are passed.
        -- class errors in this case so we can use that to set argList to {} so the script will work.
        class of argList
    on error
        set argList to {}
    end try
    someSubroutine(argList)
end run

on open argList
    someSubroutine(argList)
end open

on someSubroutine(argList)
    set argListCount to count of argList
    tell me
        activate
        display dialog "Count of arguments: " & argListCount
    end tell
end someSubroutine

Now create this script and run it...

set appPath to (path to desktop as text) & "aaa.app"
run script file appPath with parameters {1, 2}

When run like this the "on run argList" is used. You can drop things on it and the "on open argList" handler is used. If you double-click it again the "on run argList" is used.

So this demonstrates how you can do as you wish. Just use the "run script" command and pass the file paths in the parameters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜