I’m new to applescript, and I’m writing a script that parses the output of a Minecraft Server, and filters out everything besides the chat. I had this all working in an infinite repeat loop, but that meant the application had to be force quitted to stop it. I looked into handlers and read lots of documentation and re-organized my script. However, now none of the code in the run handler seems to be getting execute so my variables are uninitiated. This is exported as a stay open application. I can’t figure out why this isn’t running the code in the run handler when I open the application. On opening the application I get this error “The variable thePath is not defined.”
on run
set thePath to (path to desktop as Unicode text) & "MinecraftServer:logs:"
try
set fRef to open for access file (thePath & "latest.log")
set fRef2 to open for access file (thePath & "serverChat.log") with write permission
on error
set i to 0
repeat 3000 times --Tries to close all accesses if one was already open
try
close access i
end try
set i to i + 1
end repeat
set fRef to open for access file (thePath & "latest.log")
set fRef2 to open for access file (thePath & "serverChat.log") with write permission
end try
end run
on idle
--This is supposed to read latest.log and write all of the lines containing chat to serverChat.log every second
set serverOutput to read file (thePath & "latest.log") from 1 to eof
set serverChat to logfilter(serverOutput, "[Server thread/INFO]: <")
write serverChat to file (thePath & "serverChat.log") starting at 1
return 1
end idle
on quit
try
close access fRef
close access fRef2
end try
end quit
on logfilter(theLog, searchPhrase)
set n to count paragraphs of theLog
set theOutput to ""
set i to 1
repeat n times
if paragraph i of theLog contains searchPhrase then
set theOutput to (theOutput & paragraph i of theLog & " @**" & i & "**@" as string) & return
end if
set i to i + 1
end repeat
return theOutput
end logfilter
Hi,
the problem is in the on idle handler.
thePath is a local variable in the on run handler and not visible in on idle
Solution is to declare a property at the beginning of the script outside the on run handler
property thePath : ""
PS: Instead of that weird 3000 times repeat write better code to reliably balance the open and close pairs.
I’ve adjusted my script now. I’ve tried both properties and global variables for thePath. It still gives the same error about thePath not being defined. This is the beginning of the script now:
property thePath : (path to desktop as Unicode text) & "MinecraftServer:logs:"
property fRef : open for access file (thePath & "latest.log")
property fRef2 : open for access file (thePath & "serverChat.log") with write permission
on run
end run
on idle
set serverOutput to read file (thePath & "latest.log") from 1 to eof
set serverChat to logfilter(serverOutput, "[Server thread/INFO]: <")
write serverChat to file (thePath & "serverChat.log") starting at 1
return 1
end idle
on quit
try
close access fRef
close access fRef2
end try
end quit
No, I suggested to declare the property thePath as an empty string and set it in the run handler.
Never use relative paths (path to … ) in properties.
And also never use open or close statements in properties.
Properties are evaluated at compile time. In case of the path the script loses its portability because the path is quasi hard-coded. In case of the open statements the file is opened immediately which is certainly not intended.
Try this
property logFolder : ""
on run
set logFolder to (path to desktop as text) & "MinecraftServer:logs:"
end run
on idle
--This is supposed to read latest.log and write all of the lines containing chat to serverChat.log every second
set serverOutput to read file (logFolder & "latest.log") from 1 to eof
set serverChatLog to logFolder & "serverChat.log"
set serverChat to logfilter(serverOutput, "[Server thread/INFO]: <")
try
set fRef to open for access file serverChatLog with write permission
write serverChat to fRef starting at 1
close access fRef
on error
try
close access file serverChatLog
end try
end try
return 1
end idle
on logfilter(theLog, searchPhrase)
set n to count paragraphs of theLog
set theOutput to ""
set i to 1
repeat n times
if paragraph i of theLog contains searchPhrase then
set theOutput to (theOutput & paragraph i of theLog & " @**" & i & "**@" as string) & return
end if
set i to i + 1
end repeat
return theOutput
end logfilter
Thank you so much! It works perfectly now, and I’m really starting to understand AppleScript a lot better. The only thing is I made more of the variables properties and moved some of the code to initialize them into the run handle. That way it’s doing the least possible amount of work on the idle handler.
Eh… I’m new to this forum. I don’t know how to mark the topic solved or anything…
There is no option to mark a topic as solved like on Stackoverflow