I have this little script. it will start a text session with a buddy. It will then read the conversation. It checks for new text every 3 seconds. It will then read the new text/conversation. Sometimes it will get the new text and not read it. I do not know if it is just timing and the new text is falling under the old text, so it skips it, or what. Also, the script is to end when the chat window closes. This works. but if it is t accessing the text field it will error. If you open it, it should run as it is in your computer. Here are my questions:
Is there a way to make it quit skipping parts?
is there a way to shut the script down as soon as the chat window closes, rather than throwing an error when it closes?
tell application "iChat"
set myBuddy to name of first account
set myMessage to "Who do you want to chat with?"
repeat
display dialog myMessage default answer myBuddy
set myBuddy to text returned of result
if account myBuddy exists then
if status of account myBuddy is not offline then
exit repeat
else
set myMessage to """ & myBuddy & "" is currently offline."
end if
else
set myMessage to """ & myBuddy & "" is not a buddy name."
end if
end repeat
set myAnswer1 to button returned of (display dialog "What is " & myBuddy & "?" buttons {"Boy", "Girl"} default button 2)
if myAnswer1 is "Boy" then
set voiceType to "Fred"
else
set voiceType to "victoria"
end if
send "Hey" to account myBuddy
end tell
--------------------------HERE IS THE REPEAT
tell application "System Events" to tell process "iChat"
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
set x to number of paragraphs of talking1
set OldCount to 3
repeat while window ("chat with " & myBuddy) exists delay 3
repeat with i from OldCount to x
say paragraph i of talking1 using voiceType
end repeat
set OldCount to x
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
set x to number of paragraphs of talking1
end repeat
end tell
You can look through this scirpt which uses TextEdit (plain text document) and maybe get clues as to what’s wrong in yours if you want. It uses the linefeed character to signal the end of a paragraph and hence the beginning of saying something. The paragraph index i only increments when new paragraphs are added, so like a chat it is assumed that paragraphs may not be deleted. I don’t know how much of the chat is stored also,
set lf to (ASCII character 10)
tell application “TextEdit”
launch
activate
make new document at front with properties ¬
{text:“type some paragraphs after this one” & lf}
end tell
set i to 0
set f to true
repeat while f
tell front document of application “TextEdit”
set para_list to paragraphs whose last character is lf
end tell
set c to count para_list
if i < c then
set i to i + 1
set this_para to item i of para_list
say (this_para as string)
end if
do shell script “sleep 1”
tell application “System Events”
if not (exists process “TextEdit”) then
set f to false
end if
end tell
end repeat
set lf to (ASCII character 10)
tell application “TextEdit”
launch
activate
make new document at front with properties ¬
{text:“type some paragraphs after this one” & lf}
end tell
set i to 0
set f to true
repeat while f
tell front document of application “TextEdit”
try
set para_list to paragraphs whose last character is lf
on error
set f to false
end try
end tell
set c to count para_list
if i < c then
set i to i + 1
set this_para to item i of para_list
say (this_para as string)
end if
do shell script “sleep 1”
tell application “System Events”
set f to (exists process “TextEdit”)
end tell
end repeat
Kel, this works until the number of said paragraphs is equal to the initial number there. But, it does not see that other paragraphs have been added. So, it just does the delay/exist over and over. Can you tell which part of th script is not doing its job? It seems like the value x does not grow each time I add another paragraph.
tell application "iChat"
set myBuddy to name of first account
set myMessage to "Who do you want to chat with?"
repeat
display dialog myMessage default answer myBuddy
set myBuddy to text returned of result
if account myBuddy exists then
if status of account myBuddy is not offline then
exit repeat
else
set myMessage to """ & myBuddy & "" is currently offline."
end if
else
set myMessage to """ & myBuddy & "" is not a buddy name."
end if
end repeat
set myAnswer1 to button returned of (display dialog "What is " & myBuddy & "?" buttons {"Boy", "Girl"} default button 2)
if myAnswer1 is "Boy" then
set voiceType to "Fred"
else
set voiceType to "victoria"
end if
send "Hey" to account myBuddy
end tell
-----------------------------------
tell application "System Events" to tell process "iChat"
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
set x to number of paragraphs of talking1
set OldCount to 0
set f to true
repeat while f
set x to number of paragraphs of talking1
if x > OldCount then
set OldCount to OldCount + 1
say paragraph OldCount of talking1 using voiceType
end if
do shell script "sleep 1"
if not (exists window ("chat with " & myBuddy)) then
set f to false
end if
end repeat
end tell
A quick look, this statement needs to be in the repeat loop, to update the text:
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
otherwise the text talking1 is always the same. If you’re interested in my updated script I can post it. I caught more errors. Mainly, I placed the error handler around more statements because I think the script was trying to get the text from TextEdit while it was still in the act of quitting.
Editted: also, it’s not good to place the tell block around the whole script like that or you will probably get errors like I wrote above in my script.
Here’s my updated script:
set lf to (ASCII character 10)
tell application “TextEdit”
launch
activate
make new document at front with properties ¬
{text:“type some paragraphs after this one” & lf}
end tell
set i to 0
set f to true
repeat while f
try
tell front document of application “TextEdit”
set para_list to paragraphs whose last character is lf
end tell
set c to count para_list
if i < c then
set i to i + 1
set this_para to item i of para_list
say (this_para as string)
end if
do shell script “sleep 1”
tell application “System Events” to set f to (exists process “TextEdit”)
on error
set f to false
end try
end repeat
Can you see how the tell block doesn’t surround the main part of the script. The tell blocks are used when needed to querry the app or whatever.
Kel, is this what you mean? I added the try/end try. There are no troubles quitting it upon closure of the window. Here is what I do not understand:
I inserted that into the repeats. it works fine as long as I keep typing paragraphs fast. If nothing new is typed for a few seconds, and then you start typing, it does not work properly. i cant figure this out. It is almost exactly the same as the script you posted.
How to I remove the Tell/end tell stuff you suggest? I tried to do this, but it does not understand the “value of text area 1” when the system events is not doing it.
tell application "iChat"
set myBuddy to name of first account
set myMessage to "Who do you want to chat with?"
repeat
display dialog myMessage default answer myBuddy
set myBuddy to text returned of result
if account myBuddy exists then
if status of account myBuddy is not offline then
exit repeat
else
set myMessage to """ & myBuddy & "" is currently offline."
end if
else
set myMessage to """ & myBuddy & "" is not a buddy name."
end if
end repeat
set myAnswer1 to button returned of (display dialog "What is " & myBuddy & "?" buttons {"Boy", "Girl"} default button 2)
if myAnswer1 is "Boy" then
set voiceType to "Fred"
else
set voiceType to "victoria"
end if
send "Hey" to account myBuddy
end tell
-----------------------------------
tell application "System Events" to tell process "iChat"
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
set x to number of paragraphs of talking1
set OldCount to 2
set f to true
repeat while f
try
if x > OldCount then
set OldCount to OldCount + 1
say paragraph OldCount of talking1 using voiceType
end if
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
set x to number of paragraphs of talking1
do shell script "sleep 1"
if not (exists window ("chat with " & myBuddy)) then
set f to false
end if
on error
set f to false
end try
end repeat
end tell
I had to do this in the text editor and hope it’s at least close to working:
set OldCount to 2
set f to true
repeat while f
try
tell process “iChat” of application “System Events”
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
end tell
set x to number of paragraphs of talking1
if x > OldCount then
set OldCount to OldCount + 1
– check if typer is finished with this paragraph, by checking for linefeed
set this_paragraph to paragraph OldCount of talking1
if last character of this_paragraph is (ascii character 10) then
say paragraph OldCount of talking1 using voiceType
else – reset the index
set OldCount to OldCount - 1
end if
do shell script “sleep 1”
tell process “iChat” of application “System Events”
set f to (exists window ("chat with " & myBuddy))
end tell
on error
set f to false
end try
end repeat
Instead of getting only paragraphs with linefeed, the script checks if the last character of the paragraph with updated index ends with linefeed. Cross your fingers and pray to God.
Editted: I think there should be another ‘end if’ right after the other one.
kel,
I had to change a couple thing that were just errors, but here it is below. The code runs, but it does not say the text. That makes no sense to me, it looks like it would.
tell application "iChat"
set myBuddy to name of first account
set myMessage to "Who do you want to chat with?"
repeat
display dialog myMessage default answer myBuddy
set myBuddy to text returned of result
if account myBuddy exists then
if status of account myBuddy is not offline then
exit repeat
else
set myMessage to """ & myBuddy & "" is currently offline."
end if
else
set myMessage to """ & myBuddy & "" is not a buddy name."
end if
end repeat
set myAnswer1 to button returned of (display dialog "What is " & myBuddy & "?" buttons {"Boy", "Girl"} default button 2)
if myAnswer1 is "Boy" then
set voiceType to "Fred"
else
set voiceType to "victoria"
end if
send "Hey" to account myBuddy
end tell
-----------------------------------
set OldCount to 2
set f to true
repeat while f
try
tell application "System Events" to tell process "iChat"
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
end tell
set X to number of paragraphs of talking1
if X > OldCount then
set OldCount to OldCount + 1
-- check if typer is finished with this paragraph, by checking for linefeed
set this_paragraph to paragraph OldCount of talking1
end if
if last character of this_paragraph is (ASCII character 10) then
say paragraph OldCount of talking1 using voiceType
else -- reset the index
set OldCount to OldCount - 1
end if
do shell script "sleep 1"
tell application "System Events" to tell process "iChat"
set f to (exists window ("chat with " & myBuddy))
end tell
on error
set f to false
end try
end repeat
Thanks Kel and Jacques!
Jacques, I plugged your idea into it all. You ought to try it. There is one weird characteristic about it. It will keep on reading everything to you if you keep typing from the start. But, if you pause, it will stop recognizing the text. it will start reading again if you enter in bunch of lines real fast, but it skips the first couple. I do not know if it has to do with the delay time of the shell script or what. If I increase that delay, it seems to be more accurate, but it is so slow between sentences. I will have to play around and see if I can make it more accurate. Here is the full script if you want to open it and try it. It is sort of fun. Ian
tell application "iChat"
set myBuddy to name of first account
set myMessage to "Who do you want to chat with?"
repeat
display dialog myMessage default answer myBuddy
set myBuddy to text returned of result
if account myBuddy exists then
if status of account myBuddy is not offline then
exit repeat
else
set myMessage to """ & myBuddy & "" is currently offline."
end if
else
set myMessage to """ & myBuddy & "" is not a buddy name."
end if
end repeat
set myAnswer1 to button returned of (display dialog "What is " & myBuddy & "?" buttons {"Boy", "Girl"} default button 2)
if myAnswer1 is "Boy" then
set voiceType to "Fred"
else
set voiceType to "victoria"
end if
send "Hey" to account myBuddy
end tell
-----------------------------------
set OldCount to 2
set f to true
repeat while f
try
tell application "System Events" to tell process "iChat"
set talking1 to value of text area 1 of scroll area 1 of window ("chat with " & myBuddy)
end tell
set X to number of paragraphs of talking1
if X > OldCount then
set OldCount to OldCount + 1
set this_paragraph to paragraph OldCount of talking1
if this_paragraph is not "" then say this_paragraph using voiceType
end if
do shell script "sleep 1"
tell application "System Events" to tell process "iChat"
set f to (exists window ("chat with " & myBuddy))
end tell
on error
set f to false
end try
end repeat
When I run the script for TextEdit, I set the delay for .5 seconds and it does quite well.
do shell script “sleep .5”
About the linefeed, it must be carriage return instead (dos linefeed + cr) or maybe they send a linefeed before it sends a paragraph. I wasn’t thinking that one whole paragraph is sent at a time.