Stopping a script and trapping an error.

I’m making a program to backup a student’s work to a network volume. There are two main problems i’m running into.

  1. I’m trying to make a cancel button but have no idea how. There are two shell commands used, one for copying and one for compressing (cp and tar). I found a way to stop those commands using the ‘kill’ command after searching through the processes but don’t know how to stop the ‘backMeUp’ click event so that the script stops and I can go back to the main window.

  2. When the script tries to connect to the server and the user’s internet connection is not up (ex. if airport is off) there is an error “Unable to connect to the server at the address you specified (server address). ¬ Try again later or try connecting to a different server. (server returned error 1)”. I cannot trap it for some reason.

Can I get any and all thoughts on this? It’s my first first time writing applescript and I appreciate all comments.

on clicked theObject
	
	if name of theObject is "cancel" then
		set listem to do shell script "/bin/ps -ax"
		set howmanyprogs to the number of paragraphs in listem
		set loopcounter to 1
		
		repeat howmanyprogs times
			if paragraph loopcounter of listem contains "tar cfz" or "cp" then
				set psNumber to the first word of paragraph loopcounter of listem
				set theCommand to "/bin/kill -9 " & psNumber
				do shell script theCommand
				return
			end if
			set loopcounter to loopcounter + 1
		end repeat
	end if
	
	if name of theObject is "backMeUp" then
		
		if contents of text field "name" of window "BackerUpper" is "" then
			display alert "Wait!" as critical message ¬
				"You must enter both the username and password for your personal folder" default button "OK"
			
		else if contents of text field "pass" of window "BackerUpper" is "" then
			display alert "Wait!" as critical message ¬
				"You must enter both the username and password for your personal folder" default button "OK"
			
		else
			show window "status"
			tell window "status"
				set indeterminate of progress indicator "progress" to false
				set contents of text field "statusMessage" to "Preparing..."
				set minimum value of progress indicator "progress" to 0
				set maximum value of progress indicator "progress" to 6
				set contents of progress indicator "progress" to 1
				delay 1
				set indeterminate of progress indicator "progress" to true
			end tell
			delay 1
			ignoring case
				set theirname to contents of text field "name" of window "BackerUpper"
				set theirnum to contents of text field "pass" of window "BackerUpper"
			end ignoring
			set thevolume to "afp://" & theirname & ":" & theirnum & "@freeman-students.henrico.k12.va.us/" & theirname
			set makescript to "'#!/bin/bash'; tar cfz /Users/student/Documents/" & theirname & ¬
				"backup.tgz '/Users/student/Documents/ My Classes' '/Users/student/Library/Hog Bay Notebook'"
			set savescript to "'#!/bin/bash'; cp /Users/student/Documents/" & theirname & ¬
				"backup.tgz /Volumes/" & theirname & "/Documents/"
			tell window "status"
				set indeterminate of progress indicator "progress" to false
				set contents of text field "statusMessage" to "Collecting and compressing your work."
				set contents of progress indicator "progress" to 2
				delay 1
				set indeterminate of progress indicator "progress" to true
			end tell
			do shell script makescript
			delay 1
			tell window "status"
				set indeterminate of progress indicator "progress" to false
				set contents of text field "statusMessage" to "Logging into your personal folder.  If you get an error, " & ¬
					"click ok and quit BackerUpper"
				set contents of progress indicator "progress" to 3
				delay 1
				set indeterminate of progress indicator "progress" to true
			end tell
			delay 1
			set pfworked to true
			set mountedDisks to list disks
			
			if mountedDisks does not contain theirname then
				open location thevolume
				with timeout of 6 seconds
					repeat until mountedDisks contains theirname
						set mountedDisks to list disks
					end repeat
				end timeout
			end if
			
			if mountedDisks does not contain theirname then set pfworked to false
			
			if (pfworked is false) then
				tell window "status"
					set indeterminate of progress indicator "progress" to false
					set contents of text field "statusMessage" to "Error connecting to personal folder."
					set contents of progress indicator "progress" to 0
					delay 2
					hide
				end tell
				display alert "Couldn't Login" as critical message ¬
					"Could not login to your personal folder." default button "OK"
				
			else if pfworked is true then
				tell window "status"
					set indeterminate of progress indicator "progress" to false
					set contents of text field "statusMessage" to "Saving backup file to personal folder."
					set contents of progress indicator "progress" to 4
					delay 1
					set indeterminate of progress indicator "progress" to true
				end tell
				delay 1
				do shell script savescript
				delay 1
				tell window "status"
					set indeterminate of progress indicator "progress" to false
					set contents of text field "statusMessage" to "Closing your personal folder."
					set contents of progress indicator "progress" to 5
					delay 1
					set indeterminate of progress indicator "progress" to true
				end tell
				delay 1
				try
					tell application "Finder" to eject theirname
				end try
				tell window "status"
					set indeterminate of progress indicator "progress" to false
					set contents of text field "statusMessage" to "Done."
					delay 1
					set contents of progress indicator "progress" to 6
				end tell
				delay 1
				hide window "status"
				
			end if
		end if
	end if
end clicked

Here you can find some advices…
http://bbs.applescript.net/viewtopic.php?t=5711
http://bbs.applescript.net/viewtopic.php?t=4047

You can try first some dummy connection to check it before attempting to mount the afp volume:

try
	do shell script "curl [url=http://www.google.com]www.google.com[/url]"
on error
	display dialog "Couldn't find a valid internet connection. Connect and try again..."
	return
end try

If I try ‘repeat while’ and have the cancel button trip the repeat loop to stop it seems to wait for the loop to end before it exits the repeat. Is there a way for it to instantly exit the repeat? --Or am I just missing something?

here’s the code I have so far with the repeat and without all the progress stuff.

	if name of theObject is "cancel" then
		set stopitnow to true
	end if
	
	if name of theObject is "backMeUp" then
		set stopitnow to false
		repeat while stopitnow = false
				show window "status"

				ignoring case
					set theirname to contents of text field "name" of window "BackerUpper"
					set theirnum to contents of text field "pass" of window "BackerUpper"
				end ignoring
				set thevolume to "afp://" & theirname & ":" & theirnum & "@freeman-students.henrico.k12.va.us/" & theirname
				set makescript to "'#!/bin/bash'; tar cfz /Users/student/Documents/" & theirname & ¬
					"backup.tgz '/Users/student/Documents/ My Classes' '/Users/student/Library/Hog Bay Notebook'"
				set savescript to "'#!/bin/bash'; cp /Users/student/Documents/" & theirname & ¬
					"backup.tgz /Volumes/" & theirname & "/Documents/"

				do shell script makescript

				set pfworked to true
				set mountedDisks to list disks				
				if mountedDisks does not contain theirname then
					open location thevolume
					with timeout of 8 seconds
						repeat until mountedDisks contains theirname
							set mountedDisks to list disks
						end repeat
					end timeout
				end if
				
				if mountedDisks does not contain theirname then set pfworked to false
				
				if (pfworked is false) then
					tell window "status" to hide
					display alert "Couldn't Login" as critical message ¬
						"Could not login to your personal folder." default button "OK"
					
				else if pfworked is true then
					do shell script savescript
          delay 1

					try
						tell application "Finder" to eject theirname
					end try
					hide window "status"
					exit repeat
				end if
			end if
		end repeat
		if stopitnow is true then
			tell window "status" to set contents of text field "statusMessage" to "Cancelling"
			set listem to do shell script "/bin/ps -ax"
			set howmanyprogs to the number of paragraphs in listem
			set loopcounter to 1
			
			repeat howmanyprogs times
				if paragraph loopcounter of listem contains "tar cfz" or "cp" then
					set psNumber to the first word of paragraph loopcounter of listem
					set theCommand to "/bin/kill -9 " & psNumber
					do shell script theCommand
					return
				end if
				set loopcounter to loopcounter + 1
			end repeat
			tell window "status" to hide
		end if
	end if
end clicked

You may include several:

if stopitnow then exit repeat

Within your repeat loop (do you really need a repeat loop??), perhaps before and after doing some tedious operations (eg, tgzin a lots-of-mb document).

I’ll give that a try and see how it comes out.

Works great but now I have to find a way to wait for the volume to mount after the open location command that has a max of N seconds… I had one but it didn’t work all the time.

You can use this trick:

repeat
	try
		alias "VolumeToMount:"
		exit repeat --> because volume is mounted yet!
	end try
end repeat

If you wish a less cpu-intensive routine than a continuous “repeat loop”, you can include a “delay 1” after the “end try”.

Well it works wonderfully except something’s changed with the server and now it won’t login, desktop aliases used to work but don’t anymore. Not my problem but it is annoying. You can still loging the old way (go–>connect to server–>type in address, login and password). If anyone knows what’s causing this feel free to post any ideas here.

To solve the login wait problem I reorganized the program. It first checks to see if it’s already mounted, if so, set already to true, if not, it tries to mount it, then compresses the user’s work, if the already is true then save work to server, if already is false then look for volume and if it’s not there throw an error. It works great (minus that damn server problem) and thanks for everyone’s input.

Just a little annoying thing: the curor does not blink in the first text box but it is selected and you can just start typing, is there any way to MAKE SURE it starts blinking so that I D 10 Ts don’t get confused?