oreilly.comSafari Books Online.Conferences.


AddThis Social Bookmark Button

Building Applications with AppleScript and FaceSpan
Pages: 1, 2, 3

Having created our three additional scripts, we can organize our code. There are many ways to do this, so I'll just make some arbitrary decisions. The top-level Project Script.applescript holds just those properties and handlers that reasonably should go at the top level of our code structure:

property perlScriptPath : ""
property L1 : {}
property L2 : {}

on launched theApplication
    local f
    open window "main"
    set f to resource path of main bundle
    set perlScriptPath to POSIX path of ¬
        POSIX file (f & "/")
    set perlScriptPath to quoted form of perlScriptPath
end launched

on choose menu item theMenuItem
    local theTitle
    set theTitle to (get title of theMenuItem)
    if theTitle is "New" then
        show window "main"
        hide window "results"
        tell window "main"
            set string value of text field "textField" to ""
            set string value of text field "titleField" to ""
            set string value of text field "authorField" to ""
        end tell
    else if theTitle is "Close" then
        hide window 1
    end if
end choose menu item

on displayResults()
    local ds, tv, col, aName, aRow
    set ds to make new data source at end of data sources
    set tv to table view 1 of scroll view 1 of window "results"
    set col to make new data column at end of data columns of ds ¬
        with properties {name:"titles"}
    repeat with aName in L2
        set aRow to make new data row at end of data rows of ds
        set contents of data cell "titles" of aRow to aName
    end repeat
    set data source of tv to ds
    show window "results"
end displayResults

(Unfortunately, the "on choose menu item" handler is called when the user chooses either of our two menu items, just as in AppleScript Studio; FaceSpan provides no way to give a menu item its own script.)

The push button script simply receives the "clicked" event and calls a handler in the "main" window script:

on clicked theObject
end clicked

The "main" window script does all the work after the user clicks the push button:

property textSought : ""
property titleSought : ""
property authorSought : ""

on startNewSearch()
    tell window "main"
        set textSought to 
            (get string value of text field "textField")
        set titleSought to 
            (get string value of text field "titleField")
        set authorSought to 
            (get string value of text field "authorField")
    end tell
end startNewSearch

on urlEncodeStuff()
    set textSought to urlEncode(textSought)
    set titleSought to urlEncode(titleSought)
    set authorSought to urlEncode(authorSought)
end urlEncodeStuff

on urlEncode(what)
    set AppleScript's text item delimiters to "+"
    return (words of what) as string
end urlEncode

on feedbackBusy(yn)
    tell window "main"
        if yn then
            set enabled of button 1 to false
            start progress indicator 1
            set enabled of button 1 to true
            stop progress indicator 1
        end if
    end tell
end feedbackBusy

on doTheSearch()
    local d, u, f, r, L, half
    set d to "'-response=TBSearch.lasso&-token.srch=TBAdv"
    set d to d & "&Article+HTML=" & textSought
    set d to d & "&Article+Author=" & authorSought
    set d to d & "&Article+Title=" & titleSought
    set d to d & "&-operator"
    set d to d & "=eq&RawIssueNum=&-operator=equals&ArticleDate"
    set d to d & "=&-sortField=ArticleDate&-sortOrder=descending"
    set d to d & "&-maxRecords=2000&-nothing=MSExplorerHack&-nothing"
    set d to d & "=Start+Search' "
    set u to ""
    set f to "/tmp/tempTidBITS"
        do shell script ¬
            "curl -s --connect-timeout 15 -m 120 -d " ¬
            & d & " -o " & f & " " & u
        set r to do shell script ¬
            ("perl " & my perlScriptPath & " " & f)
        set L to paragraphs of r
        set half to (count L) / 2
        set my L1 to items 1 thru half of L
        set my L2 to items (half + 1) thru -1 of L
    on error
    end try
end doTheSearch

And here is the code for the table view script:

on double clicked theObject
    set r to clicked row of theObject
    if r is less than or equal to (count my L1) then
        open location (item r of my L1)
    end if
end double clicked

The code itself is just like the AppleScript Studio code in my book. The difference here is simply in its organization. And note that this is not the only way to organize the code! For example, in the "main" window script I call the "displayResults" handler. That handler, for purposes of this example, is located in the top-level Project Script.applescript script. But it doesn't have to be there. It could just as well be in "main" window script, or even in the push button script! The point is that FaceSpan can help you use whatever style of organization feels natural to you as you develop and maintain your code.

Final Thoughts

In its earlier incarnations, FaceSpan had an enthusiastic base of users, who have naturally been clamoring for a Mac OS X update. Now such an update exists, and it promises to be an easy and enjoyable way to develop stand-alone applications with AppleScript. It will be interesting to see how further development of FaceSpan pans out. If FaceSpan 4.0 had existed when I was writing my book, I would certainly have included some discussion of it, so now that it does exist, I'm glad to have been able to post this little online addendum to my book.

Matt Neuburg is the author of O'Reilly's "AppleScript: The Definitive Guide," "REALbasic: The Definitive Guide," and "Frontier: The Definitive Guide," and is a former editor of MacTech magazine.

Return to the Mac DevCenter