applescript to copy files from a mounted disc automatically

Hello,

I’m pretty sure this is possible, just not sure what the commands are. I would like to try to stick to just applescript for this, maybe a stay-open application with an idle handler? Here’s what I’d like to do:

When the portable disc (a digital recorder) is inserted, (it’s name is “dm_620”) a script needs to check for files from today (whatever today’s date is) in all folders on the disc.
If it finds files from today’s dates, move those files to a folder structure on my mac, placing them in a folder with today’s date.
Please let me know if any of this doesn’t make sense.
Thanks so much!!
Rocco

Hi,

a comfortable solution for this purpose is launchd

¢ Create the folder ~/Library/LaunchAgents/ if it doesn’t exist (~ represents your home folder).
¢ Copy the following code in a text editor as plain text (not RTF !)

[code]<?xml version="1.0" encoding="UTF-8"?>

Label WatchingVolumesFolder LowPriorityIO Program /usr/bin/osascript ProgramArguments osascript /Users/myUser/Library/Scripts/launchd/WatchingVolumesFolder.scpt WatchPaths /Volumes [/code] ¢ In the Program Arguments path line replace [b]myUser[/b] with your short user name ¢ save the text file with UTF8 text encoding in ~/Library/LaunchAgents/WatchingVolumesFolder.plist

¢ Create the folder ~/Library/Scripts/launchd/ if it doesn’t exist
¢ Copy the following code in AppleScript Editor


property flashState : false
property baseFolder : "/Users/myUser/path/to/Folder" -- without trailing slash

property portableDisk : "dm_620"

set currentDisks to paragraphs of (do shell script "/bin/ls /Volumes")

if (portableDisk is in currentDisks) then
    if (flashState is false) then
        set flashState to true
        set diskRootFolder to "/Volumes/" & portableDisk
        set filesToBeMoved to paragraphs of (do shell script "/usr/bin/mdfind -onlyin " & quoted form of diskRootFolder & " 'kMDItemContentModificationDate >= $time.today && kMDItemKind != \"Folder\"'")
        repeat with aFile in filesToBeMoved
            set subPath to text ((length of diskRootFolder) + 1) thru -1 of aFile
            do shell script "/usr/bin/ditto " & quoted form of aFile & space & quoted form of (baseFolder & subPath)
        end repeat
    end if
else
    if flashState is true then
        set flashState to false
    end if
end if


¢ Replace the literal string path in the property baseFolder line with the path to the base destination folder on your mac.
¢ save the script in ~/Library/Scripts/launchd/WatchingVolumesFolder.scpt

The script will be executed automatically whenever a volume is mounted or unmounted.
If your portable disc is mounted, the files of today are determined with Spotlight and copied to the destination folder with the same folder structure as on the disc. The intermediate directories in the destination folder are created automatically.

Hi,

This is absolutely awesome! Thank you so much! I have two minor questions:

  1. When I put the plist file and the script in their respective folders, nothing happens when I connect dm_620. I ran the script in script editor, and discovered why. The script gives the error "can’t get text 16 thru 1 of “/Volumes/DM_620” (by the way, I just realized that the DM in the volume name is capitalized, which I changed in the script, still getting this error.)
    and
  2. When it copies the files from “today” into the selected base folder on my mac, is there a way for it to name that folder using today’s date, and place all of today’s files from “DM_620” in that one folder with the date? I’m not sure if this is the way the script is already set up, because it hasn’t completed itself yet, but from looking at the script it didn’t look that way to me.

Again, thanks so much for all of your help! Sorry I’m such a pain with this stuff…lol :slight_smile:

Rocco

now the files are saved to a single folder YYYY_MM_DD in the base folder


property flashState : false
property baseFolder : "/Users/myUser/path/to/Folder" -- without trailing slash

property portableDisk : "DM_620"

set currentDisks to paragraphs of (do shell script "/bin/ls /Volumes")

if (portableDisk is in currentDisks) then
	if (flashState is false) then
		set flashState to true
		set diskRootFolder to "/Volumes/" & portableDisk
		set todayString to do shell script "/bin/date +%Y-%m-%d"
		set filesToBeMoved to paragraphs of (do shell script "/usr/bin/mdfind -onlyin " & quoted form of diskRootFolder & " 'kMDItemContentModificationDate >= $time.today && kMDItemKind != \"Folder\"'")
		set {TID, text item delimiters} to {text item delimiters, "/"}
		repeat with aFile in filesToBeMoved
			set fileName to last text item of aFile
			do shell script "/usr/bin/ditto " & quoted form of aFile & space & quoted form of (baseFolder & "/" & todayString & "/" & fileName)
		end repeat
		set text item delimiters to TID
	end if
else
	if flashState is true then
		set flashState to false
	end if
end if


Hi,

This works great, thank you so much! The only way I got it to work though was by running it manually from script editor. After it worked manually, I deleted the newly created folder with today’s date, ejected the disc, and plugged it in again, waiting for the script to act automatically. But it didn’t…wondering what I’m doing wrong?
Also, is it possible for the script to name the folder “May 2” instead of 05/2? If not, not a big deal at all.
Again, thank you, and sorry for so many questions! I’m actually very good with computers and tech things in general, but I feel like I’m a 2 year old when it comes to scripting…:slight_smile:

to get the abbreviated month name replace %m with %b


set todayString to do shell script "/bin/date +%Y-%b-%d" --> 2014-May-03

I tested the launchd agent / script combination successfully.
To get any feedback you could add display dialog or in Mavericks rather display notification lines

Are the paths correct? Did you replace myUser with your short user name in the plist file.
The script must be in the folder “launchd” in folder “Scripts” in folder “Library” in your home folder

Hi,

The date issue is fixed, awesome, thanks!

The script still refuses to run unless I trigger it manually, not sure why. Everything is where it should be, I just checked again based on your last post.
Also, I put a “display notification” line at the end of the script, but then didn’t know what to write after that. I always thought you had to write like “display notification ‘I’m done’” or something similar…sorry if I’m misunderstanding this

this is the script with notification lines.


property flashState : false
property baseFolder : "/Users/myUser/path/to/Folder" -- without trailing slash

property portableDisk : "DM_620"

set currentDisks to paragraphs of (do shell script "/bin/ls /Volumes")

if (portableDisk is in currentDisks) then
	if (flashState is false) then
		set flashState to true
		display notification "Volume " & portableDisk & " mounted"
		set diskRootFolder to "/Volumes/" & portableDisk
		set todayString to do shell script "/bin/date +%Y-%b-%d"
		set filesToBeMoved to paragraphs of (do shell script "/usr/bin/mdfind -onlyin " & quoted form of diskRootFolder & " 'kMDItemContentModificationDate >= $time.today && kMDItemKind != \"Folder\"'")
		set {TID, text item delimiters} to {text item delimiters, "/"}
		repeat with aFile in filesToBeMoved
			set fileName to last text item of aFile
			do shell script "/usr/bin/ditto " & quoted form of aFile & space & quoted form of (baseFolder & "/" & todayString & "/" & fileName)
		end repeat
		set text item delimiters to TID
	end if
else
	if flashState is true then
		set flashState to false
		display notification "Volume " & portableDisk & " unmounted"
	end if
end if


okay, awesome! Thank you, this also works with notifications when I run the script manually from within script editor. But it still refuses to run automatically…the file names are exactly as written here, with case-sensitivity…

I put the script and the plist code below for your reference:



property flashState : false
property baseFolder : "/Users/rocco/Piano Lessons"

property portableDisk : "DM_620"

set currentDisks to paragraphs of (do shell script "/bin/ls /Volumes")

if (portableDisk is in currentDisks) then
	if (flashState is false) then
		set flashState to true
		display notification "Volume " & portableDisk & " mounted"
		set diskRootFolder to "/Volumes/" & portableDisk
		set todayString to do shell script "/bin/date +%b-%d-%Y"
		set filesToBeMoved to paragraphs of (do shell script "/usr/bin/mdfind -onlyin " & quoted form of diskRootFolder & " 'kMDItemContentModificationDate >= $time.today && kMDItemKind != \"Folder\"'")
		set {TID, text item delimiters} to {text item delimiters, "/"}
		repeat with aFile in filesToBeMoved
			set fileName to last text item of aFile
			do shell script "/usr/bin/ditto " & quoted form of aFile & space & quoted form of (baseFolder & "/" & todayString & "/" & fileName)
		end repeat
		set text item delimiters to TID
	end if
else
	if flashState is true then
		set flashState to false
		display notification "Volume " & portableDisk & " unmounted"
	end if
end if



Plist file:
[b]

<?xml version="1.0" encoding="UTF-8"?>¨¨¨¨Label¨WatchingVolumesFolder¨LowPriorityIO¨¨Program¨/usr/bin/osascript¨ProgramArguments¨¨osascript¨/Users/rocco/Library/Scripts/launchd/WatchingVolumesFolder.scpt¨¨WatchPaths¨¨/Volumes¨¨¨

[/b]

and the location of the plist file is /Users/rocco/Library/LaunchAgents/WatchingVolumesFolder.plist
and it’s a UTF-8 encoded plain text file ?

yes.
Do you think it would help if I copied it’s contents, and resaved it again? Maybe I did something wrong in the encoding when I saved it the first time, but I remember seeing “plain text encoding” when I saved. It did, however, ask me if I was sure I wanted to use “.plist” instead of “.text” and I said yes.

This seems to be OK.
Plain Text Encoding must be Unicode (UTF-8) which is the default encoding.

Please open Terminal.app and type (or copy/paste)

launchctl list | grep WatchingVolumes

Is there a line containing WatchingVolumesFolder ?

Hi,

Yes, it does say UTF-8 when I save it. When I type that command into terminal, nothing happens after pressing enter. I see no lines of anything…probably me again, doing something wrong. lol :slight_smile:

Normally the launchd agents are loaded automatically after the next restart,
but you can load it manually - again in Terminal.app

launchctl load -w ~/Library/LaunchAgents/WatchingVolumesFolder.plist

Ok…this is very strange. When I type this into terminal, it says “No plist returned.” but when I look in that folder, the plist file is definitely there…

Again, we’re talking about the library in the user folder, not the main library on the top level of the hard disk

Yes, I know. I just checked one more time to make sure it was there, and it is…

since, for some reason, I can’t get this script to run whenever a drive mounts or unmounts like it’s supposed to, should I make it an on idle applet and run it in the background?

Please try this plist file, it’s my working one with your script path

WatchingVolumesFolder.zip

Hi

This script sounded really neat so I thought I would try the solution that StephenK has posted. I did everything that StephenK said and it works very well. The only problem that I see is that it only works automaticlly one time and then after a reboot it will work one time again. It will work every time if you run it manually. The script does make the Date folder and moves the files of the current date into that folder, but it also installs a sub folder in the Date folder with the name of the portable disk with all of the files of the portable disk.

PolishPrince