Comparing two lists of aliases


I’m new to Applescript and I have some questions.

What I’m trying to accomplish is monitor the contents of two folders, one local and one server folder. I want to add any files from the local folder that do not exist on the server folder and remove any files that exist on the server folder that do not exist on the local folder.

This will be put into an on idle handler to keep the two folders in sync.

I have written a script handler that goes through a folder and returns a list of aliases of all the files in that folder. I run this for both the local and the server folder.

on getFileList(currentFolder)
	set iTemBucket to {}
	tell application "Finder" to set folderAlias to every item of currentFolder
	if not (folderAlias = {}) then
		repeat with currentItem in folderAlias
			set currentItemKind to kind of currentItem
			if currentItemKind = "Folder" then
				set iTemBucket to iTemBucket & getFileList(currentItem)
				if currentItemKind = "MPEG-4 Audio File" or currentItemKind = "MP3 Audio File" or currentItemKind = "MPEG-4 Audio File (Protected)" then
					set iTemBucket to iTemBucket & (currentItem as alias)
				end if
			end if
		end repeat
	end if
	return iTemBucket
end getFileList

This returns a list of aliases of all the files in the folder: currentFolder

I then run a compare script that compares whether items in folder 1 are in folder 2 and should return a list of items that are not in folder 2.

on compareFolders(items1, items2)
	set newItems to {}
	tell application "Finder"
		repeat with currentItem in items2
			display dialog "Checking Item: " & currentItem as text
			if currentItem is not in items1 then
				set newItems to newItems & (currentItem as alias)
				display dialog "Adding Item: " & currentItem as text
				display dialog "Currently items are " & newItems as text
			end if
		end repeat
	end tell
	if (not (newItems = {})) then
		display dialog "There are new Items: " & newItems as text
		return newItems
		display dialog "There are not new Items: " & newItems as text
		return {}
	end if
end compareFolders

I’ll then compare the two folders by:

set iTemsToCopy to compareFolders(serverItems, folderItems)

-- if there are iTemsToCopy then copy iTemsToCopy to server

set iTemsToDelete to compareFolders(folderItems, serverItems)

-- if there are iTemsToDelete then delete iTemsToDelete from server.

If I run my code when the server folder is empty, everything works fine. However, if I run the code a second time, the compare script still tells me there are items to copy, even though nothing has changed.

I think it is because the two lists of aliases have different paths and therefore are considered different items when I do the currentItem is not in items2 check. If so, how do I properly compare these two lists?

Thanks for reading…


There is a very efficient system method for doing this called rsync. See its man page. Very powerful and reliable and the basis for several sync programs.

I agree with Adam. rsync is made for keeping things in-sync. FYI: you can get all the files of a folder, including all subfolders using “files of entire contents of theFolder”. You don’t have to loop through checking kinds of things like you’re doing. So your getFileList(currentFolder) handler can be written like this. Notice it can all be done in one command… we get all the files including ones in subfolders, we use a “whose” filter to return only the kind of files you want, and we convert it to a list of alias’s…

tell application "Finder"
			set theList to (files of entire contents of folder currentFolder whose ((kind begins with "MPEG-4 Audio") or (kind begins with "MP3 Audio"))) as alias list
		end tell

As far as comparing the lists of 2 folders, that’s difficult. You’d have to compare the file paths, but to compare the paths you’d have to chop off the specific folder portion of the path.

For example, if you had 2 folders, a and b, and their lists looked like this…
aFolderList = {“path:of:a:path:of:file”}
bFolderList = {“path:of:b:path:of:file”}

The you would want to remove “path:of:a:” from the aFolderList and “path:of:b:” from the bFolderList before comparing the paths. Then once you find 2 paths that match, you would have to get the modification dates of each of those files and compare them… obviously you’d want to keep the newer of the 2 modification dates if they were different.

So it gets complicated and you have to do a lot of looping through the lists to make it work. It’s probably best to use rsync.