No, the key is to use always the right path references
¢ A global is not necessary within the same scope
¢ oneFile in everyFile is a form of a repeat loop, it doesn’t work elsewhere
tell application "Finder"
set TweetFolder to ((path to documents folder as Unicode text) & "Tweets Pending:")
set everyfile to sort (get every file in folder TweetFolder) by creation date
repeat with oneFile in everyfile
set DocName to name of oneFile
display dialog DocName
set f to read (oneFile as alias) -- is the same as the open for access form
display dialog f
end repeat
end tell
Yeah, I kinda figured that out, after banging my head against the wall for an hour or two…
I was able to come up with a solution that did all the things I was looking for, though! (I commented out the delete commands in case anyone decides to try to run this on something – but out of the two options, I prefer the shell script because it’s silent when it deletes…) Here’s what I came up with:
tell application "Finder"
set MainFolder to ((path to documents folder as Unicode text) & "Update Twitter AppleScript:")
set TweetFolder to MainFolder & "Tweets Pending:"
set everyfile to sort (get every file in folder TweetFolder) by creation date
set DocName to last item of everyfile as text
display dialog DocName
set n to count of items in everyfile
display dialog n
end tell
if not (n = 0) then
try
set hh to open for access file DocName with write permission
set Tweet to read hh
display dialog Tweet
close access hh
-- tell application "Finder" to move file DocName to folder MainFolder
--do shell script "rm " & quoted form of the POSIX path of DocName
return true
on error
try
close access file DocName
end try
return false
end try
else
display dialog "There are NO files here!"
end if
This does everything I was needing it to do, so I’m now going to try putting together the real script. If you see anything bad about this, though, let me know – and thank you very much for all your help!
Two notes:
¢ if you want just to read a text file, this
try
set hh to open for access file DocName with write permission
set Tweet to read hh
display dialog Tweet
close access hh
-- tell application "Finder" to move file DocName to folder MainFolder
--do shell script "rm " & quoted form of the POSIX path of DocName
return true
on error
try
close access file DocName
end try
return false
end try
can be replaced by
display dialog (read file DocName)
¢ this line
do shell script "/bin/mv " & quoted form of POSIX path of DocName & space & quoted form of POSIX path of MainFolder
moves the file into MainFolder i.e. the file at the source location will be deleted.
Unlike the Finder this works also while moving a file to a different volume
I actually need to do some work with the text within it – namely place it within a shell script and also use it in some Growl notifications, so ideally a variable should be set to it.
When I tried
set Tweet to read DocName
display dialog Tweet
I got an error. This
set hh to open for access file DocName
set Tweet to read hh
display dialog Tweet
close access hh
seems to work, though.
Thank you. That’s good for me to know.
Oh, I did have another question, though – is “return true” just another way to tell the application to quit? Will it do that if I use it in the middle of an “on idle” routine?
I’m going to try putting the real script together now. Should I post it up here when I’m finished?
Thank you. That’s much more elegant than what I was using.
The reason I was asking about “return true” is that I am using an “on idle” handler in a script that also uses the “on quit” handler. I thought I had read somewhere that using “return true” inside of the “on idle” handler would be a graceful way of telling the script application to quit without invoking the “on quit” handler. So I was wondering if I should use it inside the “on idle” handler instead of the command “quit” for those times I want the script application to quit.
No, quit is the proper command to quit an application, return x in an idle handler specifies the number of seconds (x) when the handler will be called again
OK, then, that makes sense. I very much appreciate your patience and help – you are always able to point me to the best way to do things. And to update you… so far, my little Twitter application is working!!!
It’s doing what it’s supposed to do – I’m running some more tests on it just to make sure – but thank you, thank you!
One final dumb question before I force myself to bed
What’s the best way for an AppleScript to tell a stay-open application to run? Right now I am using
tell application "Update Twitter Sending Application" to run
in the Script which interfaces directly with LaunchBar. This works, but I’m getting a spinning beach-ball in LaunchBar – and the spinning beachball stays until I quit my Stay Open App.
What’s the best command to use so that the first script sets the script application running and then lets go?
Now I had noticed is that when my script application ran, it stayed the frontmost application which I didn’t like. So I wanted it to hide itself (after getting the username and password in the on run handler), so I tried a bunch of different hiding commands using “set visible to false” and System Events and Finder. This was the only one that worked for me:
on idle
tell application "System Events" to keystroke "h" using command down
But it seems a little kludgy and I wonder if it might accidentally hide an application it shouldn’t (or does a Stay Open Script Application always come to the front when it restarts its idle loop?)
Is this the best way to tell my Script App to hide itself?
maybe you have an activate command in your script
The common way to put an application to the background is
tell application "System Events" to set visible of process "Update Twitter Sending Application" to false
but if you don’t need any menu or dock appearance, add in info.plist of the app
<key>LSUIElement</key>
<string>1</string>
[i]LSUIElement
If this key is set to “1”, Launch Services runs the application as an agent application. Agent applications do not appear in the Dock or in the Force Quit window. Although they typically run as background applications, they can come to the foreground to present a user interface if desired. A click on a window belonging to an agent application brings that application forward to handle events.
⌘H and setting visible of the process in System Events is exactly the same.
You have to determine the name of the process of your app.
Maybe it’s different from the name of the app
Hmm… Well, in my activity monitor, the process name is usually listed as “Update Twitter Sending Application.app” – think that I need to add the .“app”? When I added it to the System Events line in my script application, I didn’t get the same error (but it also didn’t process the instructions in the app…)
But I noticed though that sometimes – especially when I get an error – it is listed as “(null)” in the Activity Monitor. Would that designation ever persist?
Also, I have noticed some strange behavior occur sometimes when I run the first script and the script application is still running (on idle) – when I run the first script, the script application seems not to use the On Run handler (which I thought would happen based on the commands I’m using:)
tell application "Update Twitter Sending Application"
launch
run
end tell
and sometimes running the first script even seems to make the script application quit. Should I use different language for when the script application is running, something like: if script application is running then just use the “run” command? Or maybe this process name is the problem? (But when I tried to add the “.app” in the kickoff script, the Compiler removed it.)
I seem to have solved some of my woes by using this code in my kickoff script
tell application "System Events"
set processnames to name of every process
end tell
if "Update Twitter Sending Application.app" is in processnames then
display dialog "I see the Update Twitter Sending Application!"
tell application "Update Twitter Sending Application" to SendNewTweet()
else
display dialog "Nope, no application here..."
tell application "Update Twitter Sending Application"
launch
run
end tell
end if
And this handler in my script application
on SendNewTweet()
set returnVal to 120
idle
end SendNewTweet
(the “returnVal to 120” resets my 2 hour timeout window for sending out Tweets)
The “hiding” thing is still not working, but I think I have an idea of a workaround based on the above – to check to make sure that the Update Twitter Sending Application is the frontmost app before sending the Cmd-H… I’m going to try that now…
UPDATE:
This is what I came up with for that. So far it seems to work:
tell application "System Events"
set frontmostapps to every application process whose frontmost is true
set frontmostappname to name of item 1 of frontmostapps
end tell
if frontmostappname = "Update Twitter Sending Application.app" then
tell application "System Events" to keystroke "h" using command down
end if