Trouble with one-way file sync...

This is a simple problem, I think, but may require a complicated answer. Also, if I’ve posted this in the wrong forum, somebody please tell me so I can relocate it.

I have a lot of sensitive information on my laptop, and it lives only on my laptop. So, on a local Mac Mini I’ve set up a special user that the management can log into to get the keys to the kingdom. That Mac Mini has a WebDAV server on it.

I have one database (Wallet) that syncs with that Mini whenever it can. Wallet is a password database, and it has built-in WebDAV syncing. So, that’s easy. If something happens, management can open this user profile, open Wallet, and it will look just like I opened it yesterday on my laptop. I also run a Bento database that I constantly both update and change structurally. So, the database needs to live on my laptop. I had thought of running it off of the Mini and just sharing it. But, I can’t structurally change it through sharing, nor can I work on it at home. However, Bento doesn’t have a built-in sync feature.

I know from experience that I can put the file /Users/xxxxx/Library/Application Support/Bento/bento.bentodb on just about any computer and it will be openable by Bento. What I want to do is automate that file copying every so often to a location on the Mini, and point the Mini’s copy of Bento to that DB so they can open it and it will be working just the same.

I’ve tried this:


set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to POSIX file "Users/xxxxx/Library/Application Support/Bento/bento.bentodb"

set WebDAVBentoFolder to POSIX file "/Volumes/topdbs/Bento/"

tell application "Finder"

try
mount volume "http://192.168.1.12/topdbs/"
end try

delay 3

if SendOrReceive = "Sending" then
duplicate LocalBentoFile to the folder WebDAVBentoFolder with replacing

end if
end tell

The interesting thing there is that each of those pieces of code works separately (or so I thought). If I run a mount volume it works great - there’s my WebDAV. If the WebDAV is already mounted, the duplicate copies just fine (or so I thought). If I try to run both together, even with a delay, something wrong happens and I end up with a tiny mess.

The “so I thought” refers to the fact that for some reason, when I copy my bento.bentodb file onto the WebDAV, even though the files size reads in Finder as 1.5 MB, it shows in the WebDAV as anywhere between 4 and 6 G. That’s weird enough.

Then I decided WebDAV probably wasn’t the way to go for the Bento file. So, I figured on the Mini I would just share the folder Users/xxxxx/Library/Application Support/Bento/ and then have a script that copied to there. So, I made something like this:


set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to POSIX file "Users/xxxxx/Library/Application Support/Bento/bento.bentodb"

set SharedBentoFolder to POSIX file "/Volumes/Bento/"

tell application "Finder"

try
mount volume "afp://20101209-SS._afpovertcp._tcp.local/Bento/"
end try

delay 3

if SendOrReceive = "Sending" then
duplicate LocalBentoFile to the folder SharedBentoFolder with replacing

end if
end tell

The problem there is that for some reason the copying won’t happen. I can’t seem to delete any files from the Mini’s Bento folder, even though the user I’m authenticated to the Mini with was given full Read/Write via the System Preferences share pane.

Is there a better way to do this? The end result needs to be that when these people log into the Mini, there are three applications, one of them Bento, that they can open up and it looks exactly how it was the day I quit/got fired/got hit by a bus/whatever. And, what was up with that file size discrepancy in the WebDAV folder? Weird…

Caveat, I’m not super good at any of this, but I’ve done some scripts and it’s always fun. I’m open to learning and always appreciate the help.

Hi,

AppleScript works with HFS paths, the POSIX file coercion is a bit long-winded and the result (a file URL) isn’t expected in every case.

After mounting a volume wait until the volume appears in /Volumes. This is much more reliable than a guessed delay.
If the user presses “Cancel” the script aborts anyway so if the script continues, “Sending” has been pressed.

Try this


set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to (path to application support folder from user domain as text) & "Bento:bento.bentodb"
set WebDAVBentoFolder to "Bento:"
try
	mount volume "http://192.168.1.12/topdbs/"
	repeat until (do shell script "/bin/ls /Volumes") contains "Bento"
		delay 0.5
	end repeat
	tell application "Finder" to duplicate file LocalBentoFile to the folder WebDAVBentoFolder with replacing
end try

personally I would prefer a shell command to move or duplicate file to shared volumes


set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)
set LocalBentoFile to POSIX path of (path to application support folder from user domain) & "Bento/bento.bentodb"
set WebDAVBentoFolder to "/Volumes/Bento"
try
	mount volume "http://192.168.1.12/topdbs/"
	repeat until (do shell script "/bin/ls /Volumes") contains "Bento"
		delay 0.5
	end repeat
	do shell script "/bin/cp " & quoted form of LocalBentoFile & space & quoted form of WebDAVBentoFolder
end try

Thanks a lot for pointing me in this direction.

A couple things I want to address. I don’t think I was clear in my description, but when the WebDAV folder mounts, it strictly mounts as topdbs with the address [i]http://192.168.1.12/topdbs/[/i]. There is no “Bento” mount in there. So, any lines like set WebDAVBentoFolder to “Bento:” and repeat until (do shell script “/bin/ls /Volumes”) contains “Bento” had to be slightly changed to read simply “topdbs”. In the cases where I tried to use the WebDAV mount, the first script you gave me worked great, the second I couldn’t get to go for some reason.

I was beginning to think that using the WebDAV folder for the bentodb file wasn’t that great of an idea anyhow. The file seems to continue to show as being 4 G or so, when really it’s only a a few MB. Moreover, Bento doesn’t seem to want to open the file from a WebDAV location. I’m giving it a good few minutes, just in case it’s trying to open a 4G database, but I doubt that.

So, I changed the script a little to copy the file directly into the location on the Mini Users/DeadAccess/Application Support/Bento, which I’ve made a shared folder.

My modifications look like this:


set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to (path to application support folder from user domain as text) & "Bento:bento.bentodb"
set WebDAVBentoFolder to "Bento:"
try
	mount volume "afp://20101209-SS._afpovertcp._tcp.local/Bento/"
	repeat until (do shell script "/bin/ls /Volumes") contains "Bento"
		delay 0.5
	end repeat
	tell application "Finder" to duplicate file LocalBentoFile to the folder WebDAVBentoFolder with replacing
end try

That worked… once. Now it won’t work again. For some reason, Finder defaults to Guest access even though it knows the Admin credentials. That means that the command can’t execute because it can’t delete the old file because it doesn’t have permissions to do so. I can confirm this because I don’t have permissions to do so when I go to that volume unless I disconnect and reconnect as Admin. So, I have to figure that out.

Also, I’m wondering if I should even bother with the button command. It would seem more reasonable to find a way to trigger this action every time I quit Bento, or every hour that I have Bento open or something. Can I throw this bit of code in Automator for that?

I haven’t needed a script in a long while, and even though I only know super-basics, I forgot how fun it was.

I’m not at work now, but I wonder if I need to force Finder to mount the volume a certain way to ensure the correct permissions. Maybe this would help:

set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to (path to application support folder from user domain as text) & "Bento:bento.bentodb"
set WebDAVBentoFolder to "Bento:"
try
   mount volume "afp://<user>:<password>@20101209-SS._afpovertcp._tcp.local/Bento/"
   repeat until (do shell script "/bin/ls /Volumes") contains "Bento"
       delay 0.5
   end repeat
   tell application "Finder" to duplicate file LocalBentoFile to the folder WebDAVBentoFolder with replacing
end try

Would that be better?

The script doesn’t work twice because the mount command throws an error if the volume is already mounted.
This modification checks first the state of the volume.


property WebDAVBentoFolder : "Bento"

set SendOrReceive to button returned of (display dialog "Hey J, Sync or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to (path to application support folder from user domain as text) & "Bento:bento.bentodb"

if not volumeIsMounted(WebDAVBentoFolder) then
	try
		mount volume "afp://<user>:<password>@20101209-SS._afpovertcp._tcp.local/Bento/"
		repeat until volumeIsMounted(WebDAVBentoFolder)
			delay 0.5
		end repeat
	on error e
		display dialog e
	end try
end if
tell application "Finder" to duplicate file LocalBentoFile to disk WebDAVBentoFolder with replacing

on volumeIsMounted(volumeName)
	return ((do shell script "/bin/ls /Volumes") contains volumeName)
end volumeIsMounted

If you get a permission error use the shell script copy method by appending with administrator privileges . You could also add lines with chmod or chown to adjust the permissions after the copy process

Permissions are fine, and the script works well. I’ve added some things to try and make it do that save every 20 minutes or upon quitting. Can I make this the script that launches Bento and then double those idle commands, something like this?

tell application "Finder"¨       open file "tech.hd:Applications:Bento"¨   end tell
end run

property currenttime : 0¨property previousbreak : 0 as integer¨property currentbreak : 0 as integer¨on idle

 tell application "System Events" to set theApphasQuit to not (application process "Bento" exists)¨   set currenttime to time of (current date)¨   set currentbreak to (currenttime / 60 / 60 * 3) as integer¨   if currentbreak is not equal to previousbreak or if theApphasQuit then

property BentoFolder : "Bento"

set SendOrReceive to button returned of (display dialog "Hey J, Send or Cancel?" buttons {"Sending", "Cancel"} default button 2 with icon caution)

set LocalBentoFile to (path to application support folder from user domain as text) & "Bento:bento.bentodb"

if not volumeIsMounted(BentoFolder) then
	try
		mount volume "afp://access:XXXPassworDXXX@20101209-SS._afpovertcp._tcp.local/Bento/"
		repeat until volumeIsMounted(BentoFolder)
			delay 0.5
		end repeat
	on error e
		display dialog e
	end try
end if
tell application "Finder" to duplicate file LocalBentoFile to disk BentoFolder with replacing

on volumeIsMounted(volumeName)
	return ((do shell script "/bin/ls /Volumes") contains volumeName)
end volumeIsMounted
¨       set previousbreak to currentbreak¨   
end if
¨end idle


Maybe a little notice but it’s better to check for mounted volumes like this. First of all your method will return true when a mounted volume is “/Volumes/bento” and looking for volume “/Volumes/ben” for example. Also if a folder /Volumes/Bento exists it doesn’t mean it is a mounted volume. for those two reasons it’s better to use the following function.

on volumeIsMounted(volumePath)
	return (do shell script "mount") contains (" on " & volumePath & " (")
end volumeIsMounted