YARP (Yet Another Rename Problem)

What I am doing doesn’t seem to be rocket science, but I keep getting error -37 (indicates I’ve got a bad filename). The script is designed to erase files in the source folder that have been converted (using VisualHub, if anyone’s curious) once the converted files arrive in the target folder. VisualHub has a strange behavior where if a file exists with the same name, it adds an extension to the path, so myFilm.mp4 becomes myFilm.mp4.mp4 if a copy is already in the target folder.

I’m having trouble renaming the .mp4.mp4 file to just .mp4.

Here’s the code:


on adding folder items to this_folder after receiving these_items
	set theQueueFolder to "XStorage01:showcase_queue"
	tell application "Finder" to set theQueuedFiles to entire contents of folder theQueueFolder
	repeat with theFullPath in these_items
		copy theFullPath as string to thisPath
		if (thisPath contains "mp4.mp4") then
			--startPosition = lastIndexOf(".mp4", thisPath)
			set correctFileName to text 1 thru -5 of thisPath
			try
				tell application "Finder" to move file correctFileName to trash
			on error the error_message number the error_number
				display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
			end try
			--display dialog "File Moved"
			try -- THIS TRY IS WHERE IT FAILS
				tell application "Finder" to set the name of theFullPath to correctFileName
			on error the error_message number the error_number
				display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
			end try
			--display dialog "File renamed"
			set thisPath to correctFileName
		end if
		
		if (thisPath does not contain ".temp") then
			set the convertedFile to getFileNoExtension(thisPath)
			repeat with theFile in theQueuedFiles
				copy theFile as string to tempFile
				set queuedFile to getFileNoExtension(tempFile)
				--display dialog "converted file: '" & convertedFile & "'  - Testing against: '" & queuedFile & "'"
				if (convertedFile = queuedFile) then tell application "Finder" to move file tempFile to trash
			end repeat
		end if
	end repeat
end adding folder items to

on getFileNoExtension(thePath)
	set oldDelimiters to AppleScript's text item delimiters
	--copy the as string to thePath
	set AppleScript's text item delimiters to ":"
	set theFileName to last text item of thePath
	set AppleScript's text item delimiters to "."
	-- Should work with or without an extension
	set nameWithoutExtension to first text item of theFileName
	set AppleScript's text item delimiters to oldDelimiters
	return nameWithoutExtension
end getFileNoExtension

I can’t see what the problem is. I’ve tried several variations – if anyone has any input, it would be greatly appreciated.

Hi Kcl

Its not a folder action you will need to convert !, but i hope this should do the trick for you:

tell application "Finder"
	set l to every item of (choose folder) whose name ends with ".mp4.mp4"
	repeat with k in l
		set k to k as alias
		set theText to name of item k
		set OldDelims to AppleScript's AppleScript's text item delimiters
		set AppleScript's AppleScript's text item delimiters to ".mp4.mp4"
		set newText to text items of theText
		set AppleScript's AppleScript's text item delimiters to ".mp4"
		set newText to newText as text
		set AppleScript's AppleScript's text item delimiters to OldDelims
		set name of item k to newText
	end repeat
end tell

Hey, Pidge. Thanks for the response.

I’m looking at your code and it seems we end up with the same string, just two different ways. I’ve "display dialog"ed the string just before initiating the command (in previous versions) and it looks like it should be fine. So, why would yours work:


tell application "Finder"
       ...
       set name of item k to newText
end tell

… and THIS doesn’t?


try -- THIS TRY IS WHERE IT FAILS
      tell application "Finder" to set the name of theFullPath to correctFileName
      ...
end try

Thanks again for your suggestion. I’m not looking as much for a workaround as an explanation as to why it’s not working. From here, it makes no sense.

Scott.

Model: XServe
Browser: Safari 523.10
Operating System: Mac OS X (10.4)

Hi

i’m never good at looking at other peoples code and making head nor tale of whats going on in there. but i’ll give it my best shot!!
i don’t think your script likes the file paths as strings the finder just doesn’t understand what your feeding it!!
you need to be using aliases etc.

i don’t mean to be too critical but i do think you have over complicated it a bit. (its easy done! i know!)

try thinking of ways to simplify it!!
and you’ll get there!

good luck

Perhaps I have. Here’s the situation:

We’ve built an application to accept video in a variety of formats and convert them to quicktime. Once converted, the files need to be accessible via HTTP to the world. To that end, we’re using VisualHub in the “Tech Preview”, which means it can accept files to be converted via applescript and our web server points to a separate directory that is accessible via HTTP.

We have another script that watches the Queue folder and fires up VisualHub to kick off the process when a file is FTPed in. VisualHub chugs along and then puts the finished product in our target folder that is accessible via HTTP. VisualHub does no cleanup on it’s own, so that’s where this script comes in.

The primary use of this script is to clean things up. It compares the name of the file just converted to one in the Queue folder and deletes it (that’s the second part of the script).

We found that VisualHub adds an extra extension on the end of a file that already exists (that .mp4.mp4 business). The goal is to replace the quicktime file, not simply add endless versions. However, we don’t want to delete the previous version BEFORE VH has completed, in case of an error somewhere. So the idea is that in the case of a file coming in that has the double-extension, we need to 1) find the previous file with a single extension and delete it, and 2) rename the double-extension file to a single extension and then go about the business of cleaning up the queue folder.

What I am still stuck on is why my simple command doesn’t work…!

Thanks again for the response.

Scott.

The finder doesn’t understand what the “correctFileName” variable is!
its just a string to it, you need to coerce it to an alias or something that the finder will understand.
the variable “theFullPath” is not an alias but its an acceptable file path that it understands so you can get its name!!

My Apologies upfront cause i’m not good at explain the inner workings of applescript, but i think this is definitely the problem.
in your script your talking to the finder in one liners!! try and create you “Finder” bits in a nested Tell Block

tell application "Finder"
	set these_items to every item of (choose folder)
	copy theFullPath as string to thisPath
	return theFullPath
	if (thisPath contains "mp4.mp4") then
	end if
end tell

just an example but hopefully you get the idea, the finder will have a better idea whats coming its way so if something goes wrong.
it may throw up some more helpful errors.

Hope this is a bit clearer.
Good Luck!

p.s. At this point if anyone with a bit more of an idea wants to step in and explain better or confirm (or deny) what i’m saying then please feel free to do so!!

OK, so after all this hassle, I decided to go the shell script route.

I mean, come on. I have a string and I want to replace the name of a file with it. Why is that so hard? Having to twist delimiters or set aliases (neither of which worked for me but I know it probably would have if I’d kept at it.)

I replaced this:


           try -- THIS TRY IS WHERE IT FAILS
               tell application "Finder" to set the name of theFullPath to correctFileName
           on error the error_message number the error_number
               display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
           end try

… with this:


	try
		set shellPathSource to "/Volumes/" & findAndReplace(":", "/", thisPath)
		set shellPathTarget to "/Volumes/" & findAndReplace(":", "/", correctFileName)
		set shellScript to "mv -f " & shellPathSource & " " & shellPathTarget
		do shell script shellScript
		on error the error_message number the error_number
		display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
	end try

Variables ‘thisPath’ and ‘correctFileName’ are both strings. The filenames are completely generated within the system, so we’re not worried about injection.

I would prefer to have an applescript-only solution, as this particular piece of code might get heavy usage and as I understand things, going to the shell involves some overhead. We could potentially have up to 50 simultaneous users (10% of total 500 ‘active’ users) on our G5 dual 2.3Mhz XServe.

Anyone out there know if we should be worried about load for this particular operation?

Thanks in advance.

Scott.

Model: XServe Dual G5 2.3
Browser: Safari 523.10
Operating System: Mac OS X (10.4)

this is quite easy


.
set shellPathSource to quoted form of POSIX path of thisPath
set shellPathTarget to quoted form of POSIX path of correctFileName
set shellScript to "mv -f " & shellPathSource & " " & shellPathTarget
.

Notes:
POSIX path converts HFS paths (colon delimited) into POSIX paths (slash delimited) and works with string paths, file specifiers and aliases
quoted form is important to escape spaces and special characters

If you are going to use do shell script, Stefan’s code from post #8 is definitely the way to go. Doing the conversion by hand is error prone (e.g. you should also convert slashes in the HFS path to colons in the POSIX path). The quoting is very important for both functionality and security.

But aside from that, maybe I have found why your script’s use of Finder was failing. If correctFileName contains the complete path as the second excerpt (do shell script .) from post #7 implies, then your problem might be that the first excerpt (tell application “Finder” to set the name of .) is effectively telling Finder to stuff the whole pathname into just the last component (at they very least, it will have colons, which you cannot have in individual HFS pathname components since the colon is the HFS delimiter for pathname components).

In Finder, the name of an item is just the last component of its pathname. This implies that you cannot move a file by telling Finder to change its name.

Since you do not appear to want to move the file, just alter the filename (strip the doubled extension?), this might work for you:

â‹®
set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {":"}}
set correctName to last text item of correctPath
set AppleScript's text item delimiters to tid
tell application "Finder" to set name of theFullPath to correctName
â‹®

Also, it might be better to change your contains “mp4.mp4” test to ends with “.mp4.mp4” so that you do not accidentally mangle some file that had “mp4.mp4” in the middle of the filename. It is probably unlikely, but it is a latent bug nonetheless.

Ah! My faith in Applescript is suddenly renewed!

The key piece of information I couldn’t find was exactly:

Chrys, I added your code and it worked like a champ. Also renamed corrrectFileName to correctPath for clarity.

Also, given the help you guys provided, I went back and added the POSIX code into the shell script version, and it ALSO worked great. Took the suggestions about using “ends with” as opposed to “contains” as well. Although our app completely controls these filenames, I may want to use this code elsewhere.

In the future, we probably will be using a shell script to tell the mySQL db the status of the file, but the supporting code isn’t developed yet, so no worries.

To make the thing really robust, it would be nice if it simply detected any double-extension instead of an explicit “mp4.mp4” but this will certainly work for the short term.

For anyone else’ edification, here’s the final file, in it’s entirety:


-- VHCleanup:
-- Cleans up the VisualHub Queue as well as double extension weirdness generated by VH when attempting to replace an existing file in the Target directory
-- Author: Scott Kallen, Digital Event Logistics
-- Created: 12/10/2007
-- 
on adding folder items to this_folder after receiving these_items
	set theQueueFolder to "XStorage01:showcase_queue"
	tell application "Finder" to set theQueuedFiles to entire contents of folder theQueueFolder
	repeat with theFullPath in these_items
		copy theFullPath as string to thisPath
		if (thisPath ends with "mp4.mp4") then
			set correctPath to text 1 thru -5 of thisPath
			-- The previous file is named "xxx.mp4".  Delete that, then rename the "xxx.mp4.mp4" file (the new one) to replace it.
			try
				tell application "Finder" to move file correctPath to trash
			on error the error_message number the error_number
				display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
			end try
			--display dialog "Previous version deleted"
			try
				set {tid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, {":"}}
				set correctName to last text item of correctPath
				set AppleScript's text item delimiters to tid
				tell application "Finder" to set name of theFullPath to correctName
			on error the error_message number the error_number
				display dialog "Folder action caused an error: " & the error_number & ". " & the error_message
			end try
			--display dialog "New version renamed"
			set thisPath to correctPath
		end if
		
		if (thisPath does not contain ".temp") then -- VH creates a .temp interim file that gets deleted once it's finished transcoding.  Ignore it.
			set the convertedFile to getFileNoExtension(thisPath)
			repeat with theFile in theQueuedFiles
				copy theFile as string to tempFile
				set queuedFile to getFileNoExtension(tempFile)
				if (convertedFile = queuedFile) then tell application "Finder" to move file tempFile to trash
			end repeat
		end if
	end repeat
end adding folder items to

on getFileNoExtension(thePath)
	set oldDelimiters to AppleScript's text item delimiters
	--copy the as string to thePath
	set AppleScript's text item delimiters to ":"
	set theFileName to last text item of thePath
	set AppleScript's text item delimiters to "."
	-- Should work with or without an extension
	set nameWithoutExtension to first text item of theFileName
	set AppleScript's text item delimiters to oldDelimiters
	return nameWithoutExtension
end getFileNoExtension