Need Help Stay-Open Script

First of all. Thank you in advance for helping me out MacScripter is a amazing resource. What I am trying to accomplish is Stay-Open script I have tried a few of the steps but to honest. I really kind of suck writing applescripts.

A) I want to be able to target / choose the three folders (IN, IN_Done, Out) needed in the script.
B) Opens all .mp3 files within a (IN) folder after the folder is populated by a copy.txt file.
C) When (OUT) folder is populated with a log text file. All files from the (IN) folder to The (IN_DONE) folder.

Thanks so much!

Hello.

It would be nice if you could use some more words on your explanation, some about the context it is intended to work in, what it is really supposed to do etc.

Best Regards

McUsr

Agree with McUsr; why, for example, do you want the script to stay open?

I am using the script to automate audio processing.

Basically i am copying files over the network into a folder (the “IN” folder) i have on another computer. I have assigned all .mp3’s to open with Bias Peak. I use Peak’s batch processor to apply audio processing to these files. Peak does it thing when ever a .mp3 and spits out the .mp3’s into a folder (the “out” folder) along with a log file upon completion of processing.

I am currently doing this process by hand whenever it needs to be down. Here is what i would like to do…

Have a Stay-Open script running once a hour looking in the “IN” folder for the COPY.txt file. The COPY.txt is the last file to be placed in the “IN” folder. This ensure that script is not started until all files are finished transferring into the “IN” folder.

When the script runs and sees there is a COPY.txt file in the “IN” folder. It opens all .mp3 files within the “IN” folder. All .mp3 will open with Peak and be processed with Peak’s Batch Processor. The Batch Processor saves the .mp3 in a “OUT” folder. The “OUT” folder is determined when i setup the Batch Processor.

Finally. The Batch Processor produces a log file when processing is completed. The log file is saved in the “OUT” folder. I would like the log file from the “OUT” folder and all files in the “IN” folder moved to a “DONE” folder after the log file is produced in the “OUT” folder.

SAMPLE FiLES

COPY.txt
http://dl.dropbox.com/u/550920/COPY.txt
Log Mon Jun 21 '10 13.46.36PM http://dl.dropbox.com/u/550920/Log%20Mon%20Jun%2021%20’10%2013.46.36PM

I have wrote some very very basic AS’s but this beyond me! i would appreciate any help! Thanks again!!!

One quick Important question:

When you are copying files over the network is any creation date or modification date affected by the operation.
Or said differently: do any of these file properties change during the operation and reflect the time the operation was performed?

Best Regards

McUsr

No and Yes…

Copied over the network to the “IN” folder nothing changes. All attributes stay the same. After the audio processed with Peak the created and modified dates change to the day processed.

Does it happens to the files in the IN folder?

Question 1
Just wondering, it may be necessary to know that or not, depending on if you start stuffing more files into the IN folder after you have inserted the “COPY.txt” file into the folder:

It would be very nice if you could confirm this behavior on the files in the IN folder, and IN folder only.
It would be nicest for you of course because you then could stuff into the IN folder whenever you wished, without any troubles.

Edit:I see now that I got it wrong, you actually process one batch at a time. (It would still be nice to know though. But I won’t implement the functionality to tackle two different batches in the IN folder this time. -I believe I can’t really trust the time stamp of the COPY.txt file) -We may go back and resolve this later eventually.

Question 2
Does this pseudo code look like what you expect to happen?[/b]


	(*
	
		if there are logfiles in the OUT folder
			move every logfile from the OUT folder to the DONE folder
			move every file except the COPY.txt file from the IN folder to the DONE folder
			remove the the COPY.txt file from the IN folder.
		
		else if "COPY.txt" exists in the IN FOLDER (no logfiles in the OUT folder=
			open every file except COPY.txt in the IN folder thru the converter.app.
		end if 
	*)


About functionality.
I foresee this applet as a faceless one, this is not something you will like to watch in the dock, at least after you have tested it, and knows that it works properly. Am I right?

One more thing. After you have set the inital paths to the folders, there will be quiet a trouble resetting them.
-At least at first hand. I’m currently working with the main parts of the solution. but maybe I can provide a script which resets the folders for you should you ever wish to do so.

The procedure as of today is that you have to open the applet and go into the Contents/Resources folder and delete the file “FolderProperties.scpt”.

Important
In order to restart the app properly after having deleted its scriptobject holding the paths to the folders when it eventually has become a faceless background app is to kill it in the Activity monitor.

Please answer the questions as soon as you can.

Best Regards

McUsr.

No other files will be placed in the “IN” folder until the processing is finished. I decided that multiples were really bad idea. probably would be too confusing.

Yes and no… you are correct once this is running i see no real need to always watch it. Although in time i would build a little interface to go along with it. Something that tells me if the script is idle or active, and has a few buttons to target the “IN” “OUT” and "IN_DONE folders. also allows the me to start and stop the script.

I didnt really think about the procedure to stop the script and that it would so many steps to stop it. A script to reset the folders would be awesome.

Hello.

The busy/Idle status and all the other stuff can be implemented by scripts from a script menu.

Lets go for the core functionality first. I have to conduct some experiments in order to ensure the Scriptable Applet!
-I thought it through last night and believe I could come up with something that works soon, regarding a scriptable app, I just have to verify it. So this is for the next version.

Here is the first version: the objective is to test that the core functionality works.
I have implemented the processing of MP3 files one at a time.
Save it as a stay open application bundle without any startup screen.


property script_title : "Audio Processor Controller"
on run
	local tids
	set AppleScript's text item delimiters to ""
	set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ""}
	global resourcesFolder, scriptObjectFile, firstTime
	tell my logger to run
	-- if script object exists then 
	my logger's logThis("Starting the Audio-applet.")
	set resourcesFolder to (path to me as text) & "Contents:Resources:"
	set scriptObjectFile to resourcesFolder & "FolderProperties.scpt"
	try
		scriptObjectFile as alias
		set my FolderProperties to load script alias scriptObjectFile
		my logger's logThis("Had  folders from last run.")
		display dialog "Am getting properties..."
	on error
		my logger's logThis("No folders were saved last time, must get standard folders now.")
		my setStandardFolders() -- never saved the properties.
	end try
	set firstTime to true
end run

on idle
	global listOfiles
	-- Lines below are commented out during testing so you won't have to wait an hour to get results.
	--	if firstTime is true then --  dont bother to check for anything the first hour.
	--		set firstTime to false
	--		return 3600
	--	end if
	-- if there are log files in the OUT folder then we are living in the belief that 
	-- the batch is completed. As this is the last step in the process.
	set listOfiles to {}
	my logger's logThis("I have entered the Idle handler.")
	
	my logger's logThis("I have entered the Idle handler and I'm looking for files whose name begins with \"Log\" in the path : " & (my FolderProperties's outFolderPath))
	try
		set listOfiles to every paragraph of (do shell script "find " & quoted form of POSIX path of (my FolderProperties's outFolderPath) & "  -name 'Log*' ")
	on error e number n
		-- display dialog e & " : " & n
		my logger's logThis("There were errors in finding every file whose name begins with \"Log\" i error " & e & " number " & n & " path: " & (my FolderProperties's outFolderPath))
	end try
	
	if listOfiles ≠ {} then
		my logger's logThis("there are LOG files in the OUT folder path I CLEAN UP the infolder and move Log files")
		-- we are also living in the positive assumption that there can only be one Logfile at a time.
		repeat with aFile in listOfiles
			try
				do shell script "mv " & quoted form of (contents of aFile) & " " & quoted form of POSIX path of (my FolderProperties's doneFolderPath)
			on error
				my logger's logThis("There were errors in moving every file whose name begins with \"Log\" i error " & e & " number " & n & " from path: " & (my FolderProperties's outFolderPath) & " to  : " & (my FolderProperties's doneFolderPath))
			end try
		end repeat
		
		
		-- we also move everything expect the "COPY.txt" file to the done folder.
		-- we replace any file with similiar name, maybe a file was processed twice.
		do shell script "rm -f " & quoted form of POSIX path of (my FolderProperties's inFolderPath & "COPY.txt")
		do shell script "/usr/bin/ditto  " & quoted form of POSIX path of my FolderProperties's inFolderPath & " " & quoted form of (POSIX path of my FolderProperties's doneFolderPath)
		do shell script " rm " & quoted form of (POSIX path of my FolderProperties's inFolderPath) & "*"
	else
		my logger's logThis("There were nothing to clean up in : " & (my FolderProperties's outFolderPath) & "  checks if we shall start the batch processor.")
		-- we are checking if the "COPY.txt" file exist.
		try
			set listOfiles to every paragraph of (do shell script "find " & quoted form of POSIX path of (my FolderProperties's inFolderPath) & "  -name 'COPY.txt' ")
		on error e number n
			-- display dialog e & " : " & n
			my logger's logThis("There were errors in finding every file whose name is \"COPY.txt\" i error " & e & " number " & n & " path: " & (my FolderProperties's outFolderPath))
		end try
		
		tell application "Finder"
			if listOfiles ≠ {} then
				my logger's logThis("We shall start the batch processor.")
				set listOfFiles to (every file in folder (my FolderProperties's inFolderPath) whose name extension is "mp3")
				repeat with aFile in listOfiles
					try
						my logger's logThis("Shall open " & name of (contents of aFile))
						open (contents of aFile) -- which should autmagically be opened by Peaks batch processor.
					on error e number n
						my logger's logThis("Error opening mp3 file : " & e & " nr : " & n)
					end try
					-- Maybe all files should be opened at once.
					delay 0.1
				end repeat
				-- Got it! we have to open every file which is not "COPY.txt" through the app.
			else
				my logger's logThis("Nothing to do yet.")
			end if
		end tell
	end if
	
	(*
	
		if there are logfiles in the OUT folder
			move every logfile from the OUT folder to the DONE folder
			move every file except the COPY.txt file from the IN folder to the DONE folder
			remove the the COPY.txt file from the in folder.
		
		else if "COPY.txt" exists in the IN FOLDER
			open every file except COPY.txt in the IN folder.
		end if 
	*)
	return 3600
end idle


-- this routine is provided for centralized cleanup like setting back AppleScript's text item delimiters.
on quit
	-- error number -128 -- comment this wen saved as a stay open handler
	-- uncomment line below when saved as a stay open applet.
	my logger's flushLogFile()
	continue quit
end quit

script FolderProperties
	property inFolderPath : {}
	property outFolderPath : {}
	property doneFolderPath : {}
end script

-- This is becoming a module, I'm using the parent path of previous folder as initial_path to next
on setStandardFolders()
	global resourcesFolder, scriptObjectFile
	set my FolderProperties's inFolderPath to my select_initial_path(true, script_title, "IN folder where incoming audfiles are placed")
	my logger's logThis("this is the INFOLDERPATH: " & my FolderProperties's inFolderPath)
	set my FolderProperties's outFolderPath to my select_initial_path(true, script_title, "OUT folder where results and logfiles are placed")
	my logger's logThis("this is the OUTFOLDERPATH: " & my FolderProperties's outFolderPath)
	set my FolderProperties's doneFolderPath to my select_initial_path(true, script_title, "DONE folder where all processed audiofiles and logfiles are placed")
	my logger's logThis("this is the DONEFOLDERPATH: " & my FolderProperties's doneFolderPath)
	try
		store script my FolderProperties in scriptObjectFile replacing yes
		display dialog "Storing of the Standard folders is  done \n To Start with new properties you have to open bundle of the app :\n " & resourcesFolder & " remove the file " & "FolderProperties.scpt"
	end try
end setStandardFolders



-- Edit: updated 06.22.2010
on select_initial_path(talkative, main_title, theObjective)
	-- This handler is called the first time the script is beeing run after editing in order to set the initial path
	-- Returns a chosen path
	-- parameters.
	-- 			     talkative           		: parameter to avoid the "really want to exit? question.
	--				main_title			:Title of your app/script.
	local new_path
	set selection_title to main_title & ": Select the intitial folder for " & theObjective
	set new_path to getFolder(selection_title, "/", talkative)
	return new_path
end select_initial_path


-- its a generic hander for choosing a folder which can ask if your really want to quit, or just quits the script otherwise.
-- calls an on_quit handler for quitting when run as an applet. this can be configured by a variable is_Applet or just
-- uncomment som lines.
on getFolder(aTitle, aStartPath, aTalksBack)
	local new_path
	tell me
		activate
		repeat while true
			try
				set new_path to (choose folder with prompt aTitle default location (POSIX file aStartPath) without invisibles) as text
				return new_path
			on error e number n
				if n is -128 then
					try
						if aTalksBack is true then
							set theButton to the button returned of (display dialog "Are you sure that you want to Exit?" with title theTitle buttons {"Exit", "Try Again"} default button 2 cancel button {"Exit"} with icon 2)
							if theButton is "Exit" then
								exit repeat
							end if
						else -- not talking back
							exit repeat
						end if
					end try
				end if
			end try
		end repeat
	end tell
	tell me to quit
end getFolder


on foundFileInPath(hfsFileNameWithExtAsText, hfsTargetPathAsText)
	tell application "Finder"
		set flist to (get every file of folder hfsTargetPathAsText)
		repeat with aFile in flist
			if name of contents of aFile is hfsFileNameWithExtAsText then return true
		end repeat
		return false
	end tell
end foundFileInPath

script logger
	property logFolderPath : POSIX path of (path to desktop folder) -- "LOGPATH" -- posixpath - text
	
	on run
		global logList, logFileName
		set myName to my internal's myShortName()
		set pxLogfileName to logFolderPath & myName & ".txt"
		set myData to "This is all my data so far\n\t\t and so be it"
		
		if my internal's posixPathExist(pxLogfileName) then
			if not my internal's deletePosixFile(pxLogfileName) then
				display alert "Logger: Couldn't delete " & pxLogfileName & " hmm. exiting"
				error number -128
			end if
		end if
		set logFileName to my internal's macStylePathName(pxLogfileName)
		set logFileName to the logFileName as text
		-- prep of the list to store data in 
		set logList to {}
		-- 
	end run
	
	on logThis(theStatement) -- ex: logger's logThis(" a has now a value of : " & a )
		set theStatement to theStatement & "\n"
		set end of my logList to theStatement
	end logThis
	
	on logThisDirectly(theStatement) -- for those low on memory
		set theStatement to theStatement & "\n"
		try
			set the open_target_file to open for access the file (my logFileName) with write permission
			write this_data to the open_target_file starting at eof
			close access the open_target_file
			return true
		on error
			try
				close access the open_target_file
				display alert "Logger: IOerror in " & pxLogfileName & "While trying to close the file exiting"
				error number -128
			end try
			return false
		end try
		
	end logThisDirectly
	
	on flushLogFile() -- flushes the log into logfile on disk. ( the flushLogFile )
		try
			
			set the open_target_file to open for access the file (my logFileName) with write permission
			set eof of the open_target_file to 0 --> remove this line if you want written data appended to existing data
			repeat with aLogStatement in my logList
				write aLogStatement to the open_target_file starting at eof
			end repeat
			close access the open_target_file
		on error
			try
				close access the open_target_file
				display alert "Logger: IOerror in " & pxLogfileName & "While trying to close the file exiting"
			end try
			return false
		end try
		my showLogFile()
		
	end flushLogFile
	
	on showLogFile() -- intended to be used with logThisDirectly
		tell application "Finder" to open my logFileName as alias
	end showLogFile
	script internal
		
		on macStylePathName(posixStylePathName)
			return (POSIX file posixStylePathName as Unicode text)
		end macStylePathName
		
		on deletePosixFile(posixFn)
			local fRef, success
			if not posixPathExist(posixFn) then return missing value
			
			set success to true
			set fRef to a reference to POSIX file posixFn as alias
			tell application "Finder"
				try
					delete file fRef as alias
				on error
					set success to false
				end try
			end tell
			return success
		end deletePosixFile
		
		on posixPathExist(s)
			try
				POSIX file s as alias
			on error
				return false
			end try
			return true
		end posixPathExist
		
		on myShortName()
			local myNameShort
			set myNameShort to my extract_shortname_from(extract_filename_from(path to me as Unicode text))
			log myNameShort
			return myNameShort
		end myShortName
		(* Sal Soghoian ©1998 Apple Computer *)
		on extract_filename_from(the_filepath)
			local tids
			set {tids, AppleScript's text item delimiters} to {AppleScript's text item delimiters, ":"}
			set the_filepath to the_filepath as text
			set x to the offset of ":" in (the reverse of every character of the_filepath) as string
			if x is 1 then
				set the_filepath to text item -2 of the_filepath
			else
				set the_filepath to text item -1 of the_filepath
			end if
			set AppleScript's text item delimiters to ""
			set the_filepath to the_filepath as text
			set AppleScript's text item delimiters to tids
			return the_filepath
		end extract_filename_from
		(* Sal Soghoian ©1998 Apple Computer *)
		on extract_shortname_from(the_filepath)
			set the_filepath to the_filepath as text
			set x to the offset of "." in (the reverse of every character of the_filepath) as string
			--    return ((characters -(x - 1) thru -1 of the_filepath) as text)
			return ((characters 1 thru -(x + 1) of the_filepath) as text)
		end extract_shortname_from
	end script
end script

Best Regards

McUsr

Thank you so much!I am getting a error for so reason. could you please explain the steps for restarting the script again. I thought i had a grasp on how to do this, guess not. I did change the timing so i didn’t have to wait an hour to see the effects. I don’t think that has anything to do with the error tho.


tell current application
	path to current application as text
		--> "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:Batch.scpt"
	activate
end tell
tell application "AppleScript Editor"
	choose folder with prompt "Audio Processor Controller: Select the intitial folder for IN folder where incoming audfiles are placed" default location file "Macintosh HD:" without invisibles
		--> alias "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:IN:"
end tell
tell current application
	activate
end tell
tell application "AppleScript Editor"
	choose folder with prompt "Audio Processor Controller: Select the intitial folder for OUT folder where results and logfiles are placed" default location file "Macintosh HD:" without invisibles
		--> alias "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:Out:"
end tell
tell current application
	activate
end tell
tell application "AppleScript Editor"
	choose folder with prompt "Audio Processor Controller: Select the intitial folder for DONE folder where all processed audiofiles and logfiles are placed" default location file "Macintosh HD:" without invisibles
		--> alias "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:IN_DONE:"
	store script «script FolderProperties» in "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:Batch.scptContents:Resources:FolderProperties.scpt" replacing yes
		--> error number -4960 from file "Macintosh HD:Users:mychalherron:Public:C2W Audio Processing:Batch.scptContents:Resources:FolderProperties.scpt"
end tell
Result:
true


Hello.

You must save it as a stay open applet as I stated in post #9 in order for this to work.
the script object is to be stored inside an applet, which is a “package” with directories, and is not a single file which a script is.

You can still run it from within the script editor after you have saved it as an Application in the “Save As” dialogue, be sure to click the Stay open check box.

Should you want to reopen an applet in Script Editor after having closed it, then you must open the package by right clicking on the applet, then choose Show package contents , then open the folder Contents then open the folder Resources, and then open the folder Scripts and then double click on the file main.scpt.

You can also download a service from somewhere near the Automator page at apple.com (Services) it is called
AScrEd.

You can of course also open the script via the Edit Script from the applet’s menu.

Best Regards

McUsr

Sorry for the delay getting back to you. Thanks again for your help. so after running the applet and setting the folders. I am encountering error " The Variable FolderProperties is not defined ".

Hello

I have updated the script in the post above post #9.
I had not referenced the script FolderProperties correctly, sorry about that.
Download and test this new version and see if you are getting better results now.

Best Regards

McUsr

I created two versions applets. I left one alone running at 3600 seconds and one running at 60 seconds. i couldn’t get either of the applets to work. This time there were no errors that came up.

I am creating applets in AS. i save the the “test script” as a application and select the stay-open option. This is the only method i know of to do this.

Any pointers here?

Hello.

I’ll come back with a version that writes to a log file.
So that we can see what is actually happening.

It should be here at least by this time tomorrow.

Best Regards

McUsr

Hello :slight_smile:

I have updated the code in the post above, with logging statements.
This worked fine from my place when I ran the applet from the desktop.
When you quit the applet there should be opened a file containing the execution history by text edit.
Please post this.

Best Regards
McUsr

i think i am going crazy! So i went threw the same saving procedure. i must have check everything on my end. making sure Peak was launching when a file was opened, making sure the batch processor was working ok in Peak etc. After i started the applet i put some files and a “COPY.txt” file in the folder. So i went to dinner and a movie with the girlfriend. upon arriving home i noticed that the “IN_Done” folder was empty along with the “Out” folder. The only thing i can this of is maybe there is some case sensitivity with the “COPY.txt” or your “COPY.txt” file is different somehow… i dont know. just looking at the script log. you would assume everything worked fine.

Script Log

Hello.

When I run the script with having a “COPY.txt” file I get this output:

So I have a couple of questions:

¢ What was the [b]exact[/b] spelling of the filename of "COPY.txt"
¢ Will the spelling differ from time to time?

I think you are right about the case sensitivity issue, and will create an “case insensitive version”.

Best regards

McUsr

Hello.

The code is now updated with “un case sensitiveness” what regards the existence of the file “COPY.txt”.

Please have a go and see if that helps. Please post me some feedback when you are done.

Best Regards

McUsr

I have been out of town for the past week. so i wasnt able to test the applet again till today. i am running into the same issue. It seems the applet is running and cycling threw but nothing is going through. When i manually open the files in the finder the audio processing in peak works fine. any ideas?