Relative paths and missing value error

I’ve been working on an iChat remote program in Code Exchange here. All of my systems are set up the same. So relative paths are not an issue when testing on my machines. When I post the code here… It gets messed up for people. When compiled the script retains my systems paths. Also for some reason my lists aren’t separating correctily when ran through iChat, in the Script Editor they are fine (Error filtering commands. Can’t make file {missing value, “time.scpt”} into type file. -1700)

property scriptLoc : missing value
property weatherLoc : missing value
property loadCommand : missing value
--property theCommands : missing value
property theCommands : {{"time", "time.scpt"}, {"externalIP", "external IP.scpt"}, {"process", "process.scpt"}, {"email", "email.scpt"}, {"Google", "Google.scpt"}, {"help", "help.scpt"}, {"iTunes", "iTunes.scpt"}, {"say", "say.scpt"}, {"volume", "volume.scpt"}, {"weather", "weather.scpt"}, {"Wiki", "Wiki.scpt"}, {"activate", "activate.scpt"}, {"echo", "echo.scpt"}, {"kill", "kill.scpt"}, {"send", "send.scpt"}, {"TinyURL", "TinyURL.scpt"}, {"uptime", "uptime.scpt"}, {"credits", "credits.scpt"}, {"internalIP", "internal IP.scpt"}}
on run
	
	set scriptLoc to ((path to home folder as text) & "Documents:AAIR:")
	set weatherLoc to POSIX path of scriptLoc & "weather.py"
	
	display dialog "Command to test: " default answer ""
	set theMessage to the text returned of the result
	set theResponse to load(theMessage)
	display dialog theResponse
	
end run

on load(theMessage)
	set loadCommand to ""
	------------------------
	try
		set staticCommand to text 1 thru ((offset of " " in theMessage) - 1) of theMessage
		set dynamicCommand to text ((offset of " " in theMessage) + 1) thru -1 of theMessage
		set theResponse to ""
	on error error_message number error_number
		set theResponse to "Error splitting commands. " & error_message & " " & error_number
		return theResponse
	end try
	------------------------
	try
		repeat with t in theCommands
			
			------------------------
			try
				set CCommand to item 1 of t
				if staticCommand = CCommand then
					set cScript to item 2 of t
					set loadCommand to load script file (scriptLoc & cScript)
					exit repeat
				end if
			on error error_message number error_number
				set theResponse to "Error filtering commands. " & error_message & " " & error_number
				return theResponse
			end try
		end repeat
		------------------------	
		try
			if loadCommand is "" then
				set theResponse to "Invalid Command"
			else
				set theResponse to loadCommand's AAIR(theMessage, staticCommand, dynamicCommand, weatherLoc)
			end if
		on error error_message number error_number
			set theResponse to "Error loading plugin. " & error_message & " " & error_number
			return theResponse
		end try
		------------------------	
		--end repeat
	on error error_message number error_number
		set theResponse to "Error loading. " & error_message & " " & error_number
		return theResponse
	end try
	
	return theResponse
	
end load

using terms from application "iChat"
	
	on message received theMessage from theBudy for theChat
		try
			set theResponse to load(theMessage)
			send theResponse to theChat
		on error error_message
			send error_message to theChat
		end try
	end message received
	
end using terms from

Hi,

the problem is, if the script is triggered by iChat, the run handler will never be called.
So better put the lines to specify the paths into the load() handler.
With this method you don’t need all the properties

By the way: as your commands and the appropriate scripts have exactly the same prefix (except the IP ones)
it’s easier to check if the command is in the list and then load scriptLoc & staticCommand & “.scpt”

This is a version with some suggestions, when you try it, change the name of the IP scripts (without space characters)


property theCommands : {"time", "externalIP", "process", "email", "Google", "help", "iTunes", "say", "volume", "weather", "Wiki", "activate", "echo", "kill", "send", "TinyURL", "uptime", "credits", "internalIP"}


on load(theMessage)
	set loadCommand to ""
	------------------------
	try
		set {TID, text item delimiters} to {text item delimiters, space}
		set staticCommand to text item 1 of theMessage
		set dynamicCommand to (text items 2 thru -1 of theMessage) as text
		set text item delimiters to TID
	on error error_message number error_number
		set text item delimiters to {""}
		return "Error splitting commands. " & error_message & " " & error_number
	end try
	------------------------
	try
		if staticCommand is in theCommands then
			set scriptLoc to ((path to documents folder as text) & "AAIR:")
			set weatherLoc to POSIX path of scriptLoc & "weather.py"
			set loadCommand to load script file (scriptLoc & staticCommand & ".scpt")
			try
				return loadCommand's AAIR(theMessage, staticCommand, dynamicCommand, weatherLoc)
			on error error_message number error_number
				return "Error loading plugin. " & error_message & " " & error_number
			end try
		else
			return "Invalid Command"
		end if
		
	on error error_message number error_number
		return "Error loading. " & error_message & " " & error_number
	end try
end load

using terms from application "iChat"
	
	on message received theMessage from theBudy for theChat
		try
			set theResponse to load(theMessage)
			send theResponse to theChat
		on error error_message
			send error_message to theChat
		end try
	end message received
	
end using terms from

Another suggestion is to specify the path of the weather python script right in weather.scpt.
then you can omit the 4th parameter in the handler call

Thanks again man! Every time you come to my rescue. Also, I see what you did there. With the TID… You’ve been very adamant about using delimiters to separate commands, i think this time I may actually listen. =)

PS:

as all errors are caught in the load() handler, this event handler is sufficient


using terms from application "iChat"
	on message received theMessage from theBudy for theChat
		set theResponse to load(theMessage)
		send theResponse to theChat
	end message received
end using terms from

There is actually a slight opps in your script Stefan. If theMessage doesn’t need to be separated, like for time, it would crash. I fixed it just incase anyone wants to copy this code for their own use.

property theCommands : {"time", "externalIP", "process", "email", "Google", "help", "iTunes", "say", "volume", "weather", "Wiki", "activate", "echo", "kill", "send", "TinyURL", "uptime", "credits", "internalIP"}

on run
	display dialog "Command to test: " default answer ""
	set theMessage to the text returned of the result
	set theResponse to load(theMessage)
	display dialog theResponse
end run

on load(theMessage)
	set loadCommand to ""
	set staticCommand to ""
	set dynamicCommand to ""
	------------------------
	try
		set {tid, text item delimiters} to {text item delimiters, space}
		set staticCommand to text item 1 of theMessage
		set dynamicCommand to (text items 2 thru -1 of theMessage) as text
		set text item delimiters to tid
	on error error_message number error_number
		set text item delimiters to {""}
		try
			set staticCommand to theMessage
		on error
			return "Error splitting commands. " & error_message & " " & error_number
		end try
	end try
	------------------------
	try
		if staticCommand is in theCommands then
			set scriptLoc to ((path to documents folder as text) & "AAIR:")
			set weatherLoc to POSIX path of scriptLoc & "weather.py"
			set loadCommand to load script file (scriptLoc & staticCommand & ".scpt")
			try
				return loadCommand's AAIR(theMessage, staticCommand, dynamicCommand, weatherLoc)
			on error error_message number error_number
				return "Error loading plugin. " & error_message & " " & error_number
			end try
		else
			return "Invalid Command"
		end if
		
	on error error_message number error_number
		return "Error loading. " & error_message & " " & error_number
	end try
end load

using terms from application "iChat"
	
	on message received theMessage from theBudy for theChat
		try
			set theResponse to load(theMessage)
			send theResponse to theChat
		on error error_message
			send error_message to theChat
		end try
	end message received
	
end using terms from

Also thanks again man!

In this case better check the number of text items instead of having another try block


.
try
		set {TID, text item delimiters} to {text item delimiters, space}
		if count (text items of theMessage) is 1 then
			set staticCommand to theMessage
			set dynamicCommand to ""
		else
			set staticCommand to text item 1 of theMessage
			set dynamicCommand to (text items 2 thru -1 of theMessage) as text
		end if
		set text item delimiters to TID
	on error error_message number error_number
		set text item delimiters to {""}
		return "Error splitting commands. " & error_message & " " & error_number
	end try
.