The Omni Group Forums

The Omni Group Forums (
-   OmniFocus Extras (
-   -   SyncMirror: Sync to server with user interface (

davidamis 2008-03-09 01:36 PM

SyncMirror: Sync to server with user interface
This is a user interface and scripts to sync your OmniFocus document folder and a 'Mirrored' folder between two or more machines and a central server. I use it to 'transfer control' of my Omnifocus and other documents between a laptop and desktop.

SyncMirror is based on a post by Ken Case, and then detailed instructions by Señor Pantalones. From their work, I rewrote it, added a user interface, and lots of new features to make it more user friendly.

[SIZE="4"][B]How it works[/B][/SIZE]
Omnifocus 1.0 can't merge changes made by multiple users into a single document, so in our case sync really means tracking which is the most-current document, or put another way, who owns it, and then copying it to another machine. To transfer ownership of the sync, the files (or at least the recent changes to the files) are copied to the server, and then copied from the server to the new owner.

MirrorSync uses a central server to store the synced documents from each client, with one folder for each client in a 'Mirrors' folder. Note that the central server could also be a client, but I haven’t tested this. We use the term 'Push' when we copy from a client to the server, and 'Pull' when client files are replaced with files from another client that are on the server.

The script keeps track of who 'owns' the sync. The name of the owner is stored on the server.

Another reason the word 'sync' is used here is that we use rsync to push or pull the files. rsync is efficient, only copying changes, not entire files or unchanged files.

[SIZE="4"][B]Using SyncMirror[/B][/SIZE]
After installation and setup, open the SyncMirror application. If you're using a remote server, it may take a few seconds for SyncMirror to contact the server to find out who owns the sync. If you own the sync, you'll see:


The title bar shows that you own the sync. If you want to transfer it to, say, your desktop, then click Push. SyncMirror will first check to see if any applications are running that you have specified (i.e. OmniFocus), and warn you, so that there aren't any unsaved changes. The list of applications is cQuitAppList in SyncMirror. It then copies your changes since the last push to the server.

Now, go to your desktop machine and open SyncMirror on that machine. You will see:


Just hit return, and SyncMirror will compare the local files to the files on the server for the sync owner (in this case MacBook-Pro-David), and update the local files to match. If you run SyncMirror again, it will show that your desktop machine now owns the sync.

To help you remember if you do or don't own the sync, SyncMirror will change the color of your 'Mirrored' folder and its immediate descendants to green if you own it, red if you don't.

[SIZE="4"][B]Timed Push[/B][/SIZE]
As with the original post by Ken, you can optionally set up timed pushes so that the server always has a recent copy of your Mirrored and OmniFocus folders. This is useful if you forget to do a push, and want to later pull on another machine. The only downside is if you have open documents, you may loose unsaved changes. Timed pushes also make manual pushes faster.

[SIZE="4"][B]Terminal commands[/B][/SIZE]
If you prefer using the terminal, you can use push_files and pull_files.

[FONT="Courier New"]push_files[/FONT]
This pushes the current version of your Omnifocus and Mirrored folders from your client computer (the one on which you're typing) to the host. Use this right before you're about to switch from one computer to another, go home from work, etc.

[FONT="Courier New"]pull_files computername[/FONT]
This gets the latest version of your Omnifocus and Mirrored folders from your host computer and puts it on your client computer. Use this when you get on another computer, when you get home from work, etc.

[FONT="Courier New"]get_who_last_pulled[/FONT]
This gets the computer name of the client that last pushed to the server. You can pipe this to pull_files. It also colors the Mirrored folder.

davidamis 2008-03-09 01:51 PM

1 Attachment(s)
I have taken these instructions: [URL=""]Ken Case[/URL], [URL=""]Senor Pantalones[/URL], and heavily modified them.

You must have a central (either local or on the internet), 99% uptime repository with a static IP.

I you want to this to be awesome, install Growl and the growlnotify tool, because growl notifications are included in the script, alerting when it syncs. The script detects if growlnotify is installed and uses it if it's available. Note that growlnotify doesn't currently work reliably in Leopard, so if you're using 10.5 don't expect to get all notifications.

[B]"Client"[/B] refers to the client computers running OmniFocus.

Each of your client computers has a "[B]computer name[/B]." You can find this by typing "[FONT="Courier New"]hostname -s[/FONT]" in terminal. Ken's examples were jamethiel and hypno.

[B]"Host"[/B] refers to the central computer (which could be running OmniFocus) which contains the Mirrors folder and hosts sync files/backups for OmniFocus and Mirrored folders.

[B][/B] refers to your static IP of your host. In SP's case, it's In ken's case (ken case! ha!), it's If it's a local machine with a manually-entered IP addres, it will be something like "" If your host is a mac, enable [B]remote access[/B] in the sharing preferences.

[B]myname[/B] refers to your login name/account name on

[B][SIZE="4"]Setting up the DSA keys:[/SIZE][/B]
Since you don't want to be entering passwords everywhere, you should generate DSA keys so your computers can freely communicate.

1. On any client computer, open terminal. Type the following: [FONT="Courier New"]ssh [email][/email][/FONT] Enter your password. This window will be where you enter host commands.

2. Type "ssh-keygen -tdsa", and accept all defaults.

Leave this host window open.

3. On a client computer, open Terminal (or open a new window if you did step 1 on this machine). You're now most likely in your home directory. Type "ssh-keygen -tdsa", and accept all defaults.

4. In the client window, type the following:
[FONT="Courier New"]scp ~/.ssh/ [email][/email][/FONT] You have just copied your key to the host

5. In host terminal window (, type the following commands:
[FONT="Courier New"]cat >> ~/.ssh/authorized_keys2

6. Repeat steps 3-5 for each client computer.

7. In host terminal window (, type the following commands:
[FONT="Courier New"]chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys2[/FONT]

This will now allow you to ssh, scp and rsync from your client to host without having to enter your password.

If you're not much of a terminal junkie, you're likely using bash, the default shell. If you're using tcsh or zsh, you already know enough about what you're doing to modify the following instructions to meet your needs.

[B][SIZE="4"]Installing Scripts[/SIZE][/B]
1. Grab the file "SyncMirror" included in this post.

2. Put it in your home directory.

3. Double click it to unzip it, then delete the zip file.

4. Open bash_profile in a text editor like BBEdit or TextEdit.

Change the content in red to your own information.
[FONT="Courier New"]
5. Save, and close the file.

6. The "SyncMirror Folder" is now customized for your clients. Copy it to the other client computers you plan on using.

7. Move all of the files out of the "SyncMirror Folder" folder to your home folder. You can put the SyncMirror application anywhere.

8. Open terminal, and type the following command:
[FONT="Courier New"]mv bash_profile .bash_profile[/FONT]

Repeat steps 7 and 8 for each client.

[B][SIZE="4"]Pushing the files up there:[/SIZE][/B]
1. Open the SyncMirror applicaiton on the client machine with the files you want to push to the server. It will ask if you want to add your machine's name to the list, click yes.

2. Click Push, and wait for the Push to comlete. A Mirrored folder will be created on your client machine, which you can now put files in to be synced. A Mirrors folder will be created on your host, it will contain a folder for this client machine.

Verify that your files have been pushed to your server. If SyncMirror didn't work, you can try push_files from the terminal, and see any error messages.

[B][SIZE="4"]Setting up the LaunchAgent:[/SIZE][/B]
This is optional, but recommended.

Although unix folks are more accustomed to cron, it's been phased out (but still supported) in OS X, in favor of LaunchAgents (for tasks run while the user is logged in) and LaunchDaemons (for tasks run regardless of user login). We're going to set up a LaunchAgent that runs every 30 minutes.

1. The files and com.omnigroup.OmniFocusSync.plist should be in your home directory, added in "Installing Scripts" above.

2. Open com.omnigroup.OmniFocusSync.plist in a text editor like BBEdit or TextEdit.

Change the content in red to your own information.

[FONT="Courier New"]<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">
<dict>[INDENT] <key>Disabled</key>

3. Save, and close the file.

4. Move the file to LaunchAgents, set permissions, and load it up. In Terminal, type:
[FONT="Courier New"]
mkdir -p ~/Library/LaunchAgents

mv com.omnigroup.OmniFocusSync.plist ~/Library/LaunchAgents/

sudo chown root:wheel ~/Library/LaunchAgents/com.omnigroup.OmniFocusSync.plist

sudo launchctl load ~/Library/LaunchAgents/com.omnigroup.OmniFocusSync.plist

As long as you didn't get an error, you've successfully set up auto-syncing on your client computer. It will now sync omnifocus data every 30 minutes.

Repeat all of these steps to setup launchagent for each client.

[SIZE="4"][B]The cQuitAppList in SyncMirror[/B][/SIZE]
SyncMirror can check if certain applications are running before a sync. The cQuitAppList initially just has Omnifocus, but you can add others, as in this example:

[FONT="Courier New"]--Fill in the following list with the applications that you want to be warned to quit before syncing
set cQuitAppList to {"OmniFocus", "Quicken", "SBook5"}[/FONT]
To edit the list, open SyncMirror in Script Editor, edit the list, and save.

If anyone has any problems, please let me know.

frilliams 2008-03-13 07:20 AM

Variable "wholastpulled" is not defined
Running the initial sync, I got the error "The variable 'wholastpulled' is not defined". Scripts in the terminal window weren't working.


Update: So, I didn't source my .bash_profile file (checked the instructions from Senor Pantelones which included that as a step).

Now push_files worked from my primary OF (which is on my host machine). And then SyncMirror worked to push and pull.

Note: I had to move my databases back to the default location. I'd moved them elsewhere thinking I'd be syncing with iDisk or a USB, but saw in .bash_profile that they expect the default location..


Next Update: Pull on my client didn't copy anything. It said "List empty". As a potentially useful bit of information, the "Mirrored" directory on my host computer is empty, though "Mirrors" has the folders "tide", my short hostname, and "WhoLastPulled"

Ok, found solution: more details from Senor P, I needed to create a directory in Mirrors for my client computer that I was pulling from.


Thanks for all these! Both OF and the syncmirror.

All times are GMT -8. The time now is 11:52 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2020, vBulletin Solutions, Inc.