PDA

View Full Version : AppleScript Folder Actions: Add action to subfolders, rsync on add/remove




maztec
Apr 13, 2011, 01:08 AM
Greetings.

This is my first real attempt at doing something with AppleScript, which may explain why I am having trouble with it. I searched for similar topics but did not find anything that revealed to me what I was doing wrong or another way of doing this, but did find a few topics that gave me hints that got me this far. If those exist, my apologies and please accept my humble request for a link to the appropriate location.

I have been playing around with this script for a few weeks. What I am wanting to do is set up a script so that anytime I add a new file or remove a file from my Documents directory, the directory is automatically rsync'd to my remote server. For reasons that I do not feel like going into, I cannot use Dropbox or some other product for this and really would rather do it myself.

Necessary Features:
*) Rsync to remote server when file added to or removed from Documents directory [working]
*) Rsync to remote server when documents added to subdirectory [not working]
*) Folder action added to subfolders automatically, when a subfolder is added - so that when new documents are added to those folders rsync to remote server is triggered [broken]

Wanted Future Features, after I fix what is already broken:
*) When folder removed from Documents the folder action should automatically be removed.
*) Stop folder actions from making the Documents folder "blink" when activated.
*) Rsync when files are modified - not just added or deleted.

Here is the code snippet that is generating an error. The error is "Can't get folder of alias:".

Open this Scriplet in your Editor:

on updateFolders(each_item)
notify("1")

-- This is where I am getting an error. The "if class of each_item is folder" never seems to work. I have wrapped this a dozen different ways and just do not seem to be getting anywhere with it. I think it has something to do with the type that each_item is, but even adjusting that and trying to munge it about doesn't seem to be doing anything.
if class of each_item is folder then
notify("2")
tell application "Finder" to set theSubItems to (every item of each_item as alias list)
repeat with thisItem in theSubItems
notify("3")
tell application "System Events" to attach action to thisItem using SCRIPTPATH
notify("4")
updateFolders(thisItem)
end repeat
end if
return
end updateFolders

Note, I admit that I used someone else's code for some of this. I cannot remember who offhand, but if I do I will be sure to annotate it with that information.

Here is the entire script, with remote server information removed:

Open this Scriplet in your Editor:


-- Variables used by RSYNC
global SOURCE
global TARGET
global PARAMETERS
global MODE
global SCRIPTPATH
global SCRIPTNAME

-- Initializes the RSYNC parameters and registers the script with GROWL
on init()
set TARGET to "me@myserver.com:directory/"
set SOURCE to "/Users/MyUser/Documents"
set PARAMETERS to "-ra --delete-after -e ssh --out-format \"" & (ASCII character (37)) & "o " & (ASCII character (37)) & "n\" --exclude=\".DS_STORE\" "
set MODE to "growl"
-- set MODE to "dialog" -- use dialogs instead of growl if not installed.. snipped this code from someone, embarrassingly enough I cannot remember who or where, sorry :(.
set SCRIPTNAME to "sync JDocuments folder.scpt"
set SCRIPTPATH to ((path to Folder Action scripts) as text) & SCRIPTNAME

-- If we are using growl we need to register this script with growl
if MODE is "growl" then
tell application "GrowlHelperApp"
set the allNotificationsList to {"sync"}
set the enabledNotificationsList to allNotificationsList
register as application
"SHARED folder actions" all notifications allNotificationsList
default notifications enabledNotificationsList
icon of application "Script Editor"
end tell
end if
end init

-- Synchronize the folders specified in SOURCE and TARGET using rsync
on synchronize(local_folder)
-- gratuitous sync messages used while debugging.
notify("Synchronizing")

set message to do shell script "rsync" & " " & PARAMETERS & " " & SOURCE & " " & TARGET

notify("Synchronized")
return message
end synchronize

on updateFolders(each_item)
notify("1")

-- This is where I am losing it. the "if class of each_item is folder" never seems to work. I have wrapped this a dozen different ways and just do not seem to be getting anywhere with it. I think it has something to do with the type that each_item is, but even adjusting that and trying to munge it about doesn't seem to be doing anything.
if class of each_item is folder then
notify("2")
tell application "Finder" to set theSubItems to (every item of each_item as alias list)
repeat with thisItem in theSubItems
notify("3")
tell application "System Events" to attach action to thisItem using SCRIPTPATH
notify("4")
updateFolders(thisItem)
end repeat
end if
return
end updateFolders

-- These two functions are called by the folder actions. they initialize the system according to preferences and then call the chosen notification system
on adding folder items to this_folder after receiving added_items
init()
notify(POSIX path of this_folder)
repeat with each_item in added_items
notify("repeat for each item")
set message to updateFolders(each_item)
end repeat
set message to synchronize(POSIX path of this_folder)
notify(message)
end adding folder items to

on removing folder items from this_folder after losing removed_items
init()
notify("removed")
-- this is where I need to add the remove action script from subfolders if removed from the directory.
set message to synchronize(POSIX path of this_folder)
--notify(message)
end removing folder items from

-- Sends an even to growl about modified files or open a dialog with the same information
on notify(message)
-- let's avoid empty notifications (silly)
if message is not "" then
if MODE is "growl" then
tell application "GrowlHelperApp"
notify with name
"sync" title
"Folder updated" description
message application name "SHARED folder actions"
end tell
else if MODE is "dialog" then
display dialog the ("folder update complete") giving up after 5
end if
end if
end notify


-- This function is just for testing, anything in here is executed by pressing "RUN" in the Applescript editor
on run
-- Initialize
-- various silly things I have done to test it at different times.
init()

-- not doing anything at the moment.
end run

Any help, especially with the error I am getting now would be appreciated. Suggestions for the other features I want to add would also be great, but my first focus is to debug what exists. If there is a better way to do all of this, I am all ears.

Thanks!