Just finished my first script :D Can I get some help optimising it?

OK, I have some beginner questions. I never touched AppleScript before last week and suddenly I can’t tear myself away from it. :slight_smile:

My first script is a background application to take a photo of my room every 10 minutes using the built-in iSight camera, and then save it in /Pictures/Look. My top priority is low CPU/memory use. I chose an idle handler because I read here it uses hardly any resources between calls. The script works, and it even does Growl! But…

…it won’t work in any other folder than /Applications/Look/, because I’m not sure how to properly refer to icons I put inside its bundle (Look.app/Contents/Resources/), so I keep them in the app folder

  • It launches, runs a shell script called looklaunch to work, and looklaunch then runs a shell application called isightcapture which I found online.

Can you help me make the shell script do the same thing as fast in AppleScript, and give me any suggestions for cleaning up my code a bit?

tell application "GrowlHelperApp"
	set the allNotificationsList to {"Next", "Status"}
	set the enabledNotificationsList to {"Next", "Status"}
	register as application "Look" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "Look"
	notify with name "Status" title "Look is now running." description "" application name "Look" icon of file "/Applications/Look/applet.icns"
end tell

on idle
	set NextPhotoText to ("Next photo at " & (time string of ((current date) + 600)) as string)
	set PictureSavedTo to do shell script "/Applications/Look/looklaunch"
	tell application "GrowlHelperApp"
		notify with name "Next" title NextPhotoText description "" application name "Look" icon of file "/Applications/Look/lens.icns"
	end tell
	return 600
end idle

Here’s looklaunch:

myimg=${HOME}/Pictures/Look
if [ ! -d $myimg ]
then
  mkdir "$myimg"
fi
myimg=${myimg}/`date "+%y%m%d.%H%M"`.jpg
/Applications/Look/isightcapture $myimg
if [ ! "$1" = "quiet" ]
then
   if [ -f $myimg ]
   then
      echo $myimg
   else
     echo "error"
  fi
fi
unset myimg

Thanks for your help :slight_smile:

Hi,

this is the AppleScript equivalent of your script. As you can see, there are anyway a few shell script calls.

Requirements
¢ Save the script as application bundle with option Stay Open
¢ Open the application bundle in Finder with the contextual menu > Show Package Contents
¢ Copy the isightcapture executable and the icons lens.icns and your custom applet.icns into /Contents/Resources of the application bundle

At the first run (or the folder doesn’t exist) you will prompted to select the destination folder.
If you want to change it later, delete the folder
Instead of the lens icon you will see the recent taken picture in the Growl notification.
You can change the time interval in the first line


property interval : 600
property tempFolder : missing value
property iSightCapture : ""
property lensIcon : ""

try
    POSIX file tempFolder as alias
on error
    set tempFolder to POSIX path of (choose folder with prompt "select destination folder")
end try
set the allNotificationsList to {"Next", "Status"}
set the enabledNotificationsList to {"Next", "Status"}
tell application "GrowlHelperApp"
    register as application "Look" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "Look"
    notify with name "Status" title "Look is now running." description "" application name "Look" icon of application "Look"
end tell
set iSightCapture to quoted form of (POSIX path of (path to me) & "Contents/Resources/isightcapture")
set lensIcon to POSIX path of (path to me) & "Contents/Resources/lens.icns"

on idle
    set NextPhotoText to "Next photo at " & (time string of ((current date) + interval))
    set timeStamp to do shell script "/bin/date +%y%m%d.%H%M"
    try
        do shell script (iSightCapture & space & quoted form of (tempFolder & timeStamp & ".jpg"))
        tell application "GrowlHelperApp"
            notify with name "Next" title NextPhotoText description "" application name "Look" image from location (tempFolder & timeStamp & ".jpg")
        end tell
    on error e
        tell application "GrowlHelperApp"
            notify with name "Next" title NextPhotoText description "an error occured: " & e application name "Look" icon of file lensIcon
        end tell
    end try
    return interval
end idle

Note: except while running the isightcapture executable there is no further error handling like checking the existence of the resource files or the iSight camera

To make the application running in background only hiding the main menu and from the dock,
open Info.plist in /Contents of the application bundle and add this key right before the NSMainNibFile key

<key>LSUIElement</key> <string>1</string>
disadvantage: You can quit the application only in Activity Monitor or in Terminal.app

Wow, thanks Stefan, that rocks!

I noted what you said about no error handling, so I’ve been working a bit on it, to introduce error handling in case of no Growl, and to allow the interval to change.

The problem I’m having is that Look now always asks me to choose the folder to store the files when it starts up, even if the folder hasn’t changed since the last time it ran. How can I make it remember the folder store setting?

Also, any idea how to change the contents of the File > About box from the default applescript placeholder text?

Here’s how the script looks at the omment:

property intervalSeconds : 600
property tempFolder : missing value
property iSightCapture : ""
property lensIcon : ""
global hasGrowl

set iSightCapture to quoted form of (POSIX path of (path to me) & "Contents/Resources/isightcapture")
set lensIcon to POSIX path of (path to me) & "Contents/Resources/lens.icns"

try
	POSIX file tempFolder as alias
on error
	set tempFolder to POSIX path of (choose folder with prompt "Look! Choose where to save Look's photos...")
	set intervalMins to (text returned of (display dialog "Look likes to take photos every 10 minutes. Or you can set a new interval here." giving up after 30 default answer "10" with icon 1))
	set intervalMins to intervalMins as real
	set intervalSeconds to ((intervalMins * 60) as integer)
	tell application "Finder" to activate
end try

tell application "System Events" to set hasGrowl to ((application processes whose (name is equal to "GrowlHelperApp")) count)
if hasGrowl ≥ 1 then
	tell application "GrowlHelperApp"
		set the allNotificationsList to {"Next", "Status", "Error"}
		set the enabledNotificationsList to {"Next", "Status", "Error"}
		register as application "Look" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "Look"
		notify with name "Status" title "Look is now running!" description "" application name "Look" icon of application "Look"
	end tell
end if

on idle
	set NextPhotoText to "Next photo at " & (time string of ((current date) + intervalSeconds))
	set timeStamp to do shell script "/bin/date +%y%m%d.%H%M"
	if hasGrowl ≥ 1 then
		try
			do shell script (iSightCapture & space & quoted form of (tempFolder & timeStamp & ".jpg"))
			tell application "GrowlHelperApp"
				notify with name "Next" title NextPhotoText description "" application name "Look" icon of file lensIcon
			end tell
		on error e
			tell application "GrowlHelperApp"
				notify with name "Error" title "Look must quit. :(" description e application name "Look" icon of file lensIcon
			end tell
			quit
		end try
		return intervalSeconds
	else
		return intervalSeconds
	end if
end idle

when you save the script as application bundle and run it always by launching the app,
the saved folder path persists. But it does not as an AppleScript Studio application

A more reliable way to check the presence of Growl is this subroutine


set growlExists to check_Application_exists("com.Growl.GrowlHelperApp") --> true or false

on check_Application_exists(theApp)
	try
		tell application "Finder" to application file id theApp
		return true
	on error
		return false
	end try
end check_Application_exists

I don’t know how to change the about window in AppleScript,
maybe it works the same way as in AppleScript Studio, which is described in the documentation