Problem Passing Along Values to Script Application On Idle

No, the key is to use always the right path references :wink:

¢ 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… :stuck_out_tongue:

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! :smiley:

Alex

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. :slight_smile:

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?

Of course you get one. My line is different

so this works


	set Tweet to read file DocName
	display dialog Tweet

The return true / return false lines come from the original subroutine
to indicate the success of the write operation, you can omit the lines

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!!! :smiley:

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!

Your’re welcome, glad to help :slight_smile:

:smiley:

One final dumb question before I force myself to bed :wink:

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?

the common way is


tell application "Update Twitter Sending Application"
	launch
	run
end tell

Awesome. Does just what’s needed. :smiley:

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?

Thanks again for all your help!

Alex

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.

The Dock and loginwindow are two applications that run as agent applications.[/i]
Source: http://developer.apple.com/documentation/MacOSX/Conceptual/BPRuntimeConfig/Articles/PListKeys.html#//apple_ref/doc/uid/20001431-108256

Actually, I do want to be able to see this app in the Dock. :slight_smile:

I tried

but I got this error:

Can't set <<class prcs>> "Update Twitter Sending Application" of application System Events to false.

There is no “activate” command in either of my scripts. Any guesses what’s going on? (I can of course post the script if you’d like to see it…)

It would definitely be better to have a different method than my key “Cmd-H” method, though – it did wind up hiding something it shouldn’t have… :frowning:

Thanks again for your help!

Alex

⌘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.)

Thanks again for your help!

Alex

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

Alex