hasseg.org

Automatic, Periodic Syncing with iSync

Filed under Mac, Scripts

Sync completed successfully Growl notification The first time I decided I wanted to start synchronizing my cell phone's calendar and address book with my Mac's, I noticed how iSync doesn't have a system of automatically invoking the synchronization procedure between regular intervals. I wanted to have the sync invoked automatically every 30 minutes, so I figured I had to do it myself somehow. I've had this script in place and running for, I don't know, a year and a half now, and I've used it with two different phones (the Nokia 3230 and the Nokia N82.) I'm not sure why I haven't blogged about it before, since this is exactly the kind of stuff I tend to write about here. Probably I've just forgotten is all. In any case, here it is.

Marc Liyanage at entropy.ch has already pretty much done the bulk of the work for this already. The differences between my solution and his are basically that mine tries to output lots of info to the user (via stdout or Growl,) mine doesn't care when the last sync took place, and that mine can be configured to start up iSync if it isn't already running.

An earlier version of my script figured out (via iSync's AppleScript interface) when the last sync procedure took place (regardless of whether it had been invoked from this script or from iSync itself) and then either cancelled or proceeded with the syncing based on that, but after a while I realized I had no need for that kind of a feature, so I removed it. I don't have the old version available anymore, but if anyone is interested in adding that feature, I still have the lastSync.scpt AppleScript I used to check if the difference between the current date and the last sync's date was long enough. It's included in the zip archive (a link to which is below.)

The (very general) directions to configuring the script and making it run are in the comments in the beginning of the file.

Download:

The script:

#!/bin/bash

—————————————————————-

DESCRIPTION:

A script that is meant to be run periodically in order to

force iSync to synchronize.

It will not, however, invoke the sync if a specific

device (e.g. a mobile phone) is not connected via Bluetooth.

(c) Ali Rantakari, 2007-2008

http://hasseg.org

—————————————————————-

REQUIRES:

- OS X 10.4 (Tiger) or later

- The “bluelist” helper application by Marc Liyanage

and Will Harris

( link to the blog post where i found it:

http://tinyurl.com/2ahpme

direct link to the app itself:

http://will.harris.ch/bluelist.gz )

OPTIONAL:

- Growl + growlnotify (for notifications)

- Lingon (launchd/launchctl GUI for scheduling the running

of this script at regular intervals)

—————————————————————-

SETTING IT UP:

1) Change the settings in the “settings” area below to

correspond to your environment

2) Use Lingon/launchctl to schedule this script to be run

periodically

—————————————————————-

NOTE 1: You can run this script from the command line

with the parameter “-v” to check that it is working.

all notifications (and some additional info) will

be printed to the standard output then.

NOTE 2: I also noticed that iSync seems to not be setting the

sync status value for applescript properly -

a failed sync may have a status code of a successful

one - and thus this script may notify you that

the sync was successful when it in fact was not.

I have reported this issue to Apple on 12 Feb 2008,

and as of this writing (17 Apr 2008,) it still seems

to be open (the radar ID is 5738357).

NOTE 3: I found a lot of useful info for making this

script from these places:

http://hollington.ca/technocrat/?p=44

http://tinyurl.com/2ahpme [ -> entropy.ch]

—————————————————————-

get the location of this script.

do not change this (unless you know a better

implementation ;) )

DN=dirname $0 THISDIR="cd $DN; pwd"

—————————————————————-

SETTINGS:

the bluetooth name of your mobile phone (or any similar device

you’re syncing with iSync via BT)

MOBILEBTNAME=“MyPhoneName”

the level of notifications you want to receive

0 = quiet (no notifications at all)

1 = inform only when starting to sync and

when sync has completed

2 = inform of everything

NOTIFICATIONLEVEL=1

whether to run iSync if it isn’t already running

“true” = if iSync is not running, run it

and then invoke the sync procedure

“false” = if iSync is not running, don’t sync

RUNISYNCIFNOTRUNNING=“false”

locations of CLI apps used

custom: (you need to get these yourself)

GROWLNOTIFY=/usr/local/bin/growlnotify BLUELIST=/usr/local/bin/bluelist

system: (these should be here)

OSASCRIPT=/usr/bin/osascript STAT=/usr/bin/stat TOUCH=/usr/bin/touch

the name of this application

(to send to growlnotify)

THISAPP=“Autosync script”

whether to use growl or stdout (or both) for notifications

“stdout” -> notifications will be printed to stdout

“growl” -> notifications will be sent to growl

“both” -> notifications will be sent to growl and

printed to stdout

NOTIFICATIONS=“growl”

the icon to show in growl notifications

GROWLICON="$THISDIR/forcesync.icon.png"

- - - - - - - - - - - - - - - - - - - - - -

settings end here.

—————————————————————-

Script IMPLEMENTATION begins here —————————

————————————————————-

— functions ——

parameters:

$1 = Title

$2 = Message

$3 = Minimum notification level

$4 = Location of icon to show

show_message() { if [ $NOTIFICATIONLEVEL -gt $(( $3 - 1 )) ] || [ $VERBOSEMODE == 1 ];then

	if [ "$NOTIFICATIONS" != "stdout" ]; then
		
		if [ -e "$4" ];then
			THISGROWLICON="$4"
		else
			THISGROWLICON="$GROWLICON"
		fi
		
		$GROWLNOTIFY -n "$THISAPP" -t "$1" -m "$2" --image "$THISGROWLICON"
		
	fi
	
	if [ "$NOTIFICATIONS" != "growl" ];then
		
		echo "** $1"
		echo "   $2"
		echo " "
		
	fi

fi

}

no params

check_isync_running() { if [ “ps xwww | grep -v grep | grep -c iSync.app/Contents/MacOS/iSync” == “0” ];then echo “false” else echo “true” fi }

no params

check_mobile_present() { if [ “$BLUELIST | grep \"$MOBILEBTNAME\"” == “$MOBILEBTNAME” ];then echo “true” else echo “false” fi }

no params

activate_isync() { $OSASCRIPT -e “tell application "iSync" to activate” -s o }

no params

hide_isync() { $OSASCRIPT -e “tell application "System Events" to set visible of process "iSync" to false” -s o }

— /functions ——

script runs from here:

——————————————–

VERBOSEMODE=0 if [ “$1” == “-v” ];then VERBOSEMODE=1 NOTIFICATIONS=“both” echo " " fi

check if mobile phone is in Bluetooth range

if [ $VERBOSEMODE == 1 ];then echo " " echo -n “Scanning for bluetooth device "$MOBILEBTNAME"…” fi

if [ “check_mobile_present” == “false” ];then if [ $VERBOSEMODE == 1 ];then echo " …not found!" echo " " fi show_message “Will not sync” “"$MOBILEBTNAME" not found (either BT is off or device is out of range)” 2 exit 0 else if [ $VERBOSEMODE == 1 ];then echo " …found!" echo " " fi fi

check if iSync is running

ISYNCRUNNING="check_isync_running"

if [ “$ISYNCRUNNING” == “false” ] && [ “$RUNISYNCIFNOTRUNNING” == “true” ];then

show_message "Starting up iSync" "Activating and hiding iSync" 2
activate_isync
hide_isync

elif [ “$ISYNCRUNNING” == “false” ] && [ “$RUNISYNCIFNOTRUNNING” != “true” ];then

show_message "Will not sync" "iSync is not running" 2
exit 0

elif [ “$ISYNCRUNNING” == “true” ];then if [ $VERBOSEMODE == 1 ];then echo “iSync seems to be running. continuing…” echo " " fi else show_message “Error” “The iSyncRunning applescript returned invalid value: "$ISYNCRUNNING"” 1 exit 0 fi

sync

show_message “Sync starting” “Telling iSync to synchronize…” 1

SYNCSTATUS="$OSASCRIPT -s o \"$THISDIR/forceSync.scpt\""

if [ “$SYNCSTATUS” == “2” ];then show_message “Sync completed” “…Synchronization completed successfully.” 1 exit 0 elif [ “$SYNCSTATUS” == “3” ];then show_message “Sync warnings” “…Synchronization completed with warnings!” 1 exit 3 elif [ “$SYNCSTATUS” == “4” ];then show_message “Sync errors” “…Synchronization completed with errors!” 1 exit 4 elif [ “$SYNCSTATUS” == “5” ];then show_message “Sync cancelled” “…Synchronization was cancelled!” 1 exit 5 elif [ “$SYNCSTATUS” == “6” ];then show_message “Sync failed” “…Synchronization failed to complete!” 1 exit 6 elif [ “$SYNCSTATUS” == “7” ];then show_message “Sync failed” “…Synchronization did not succeed (status: (7) "never synced")!” 1 exit 7 else show_message “Sync error” “…Undefined error with sync: "$SYNCSTATUS"” 1 exit 127 fi

4 Comments

Ollie May 25, 2008 at 12:29 PM

This sounds awesome! but im having REAL problems setting this up…

Im pretty new to macs, if you have the time could you please post a step-by-step?

thanks!

Ali Rantakari May 25, 2008 at 4:04 PM

Hi Ollie,

Hope this helps:

Growl is a system-wide notification server, which receives notifications from applications and displays them to the user somehow. The idea is that applications would tell Growl what they want to tell the user and then Growl would tell it to the user. This way, the user can tell Growl how they’d like to receive all of their notifications instead of being constrained to however each individual application displays their stuff. When you’ve installed it, you’ll be able to find a “Growl” preference pane in the System Preferences application where you can configure the kinds of notifications you’d like to receive from Growl-enabled applications. growlnotify is a command-line application that can be easily used by scripts such as this to send notifications to Growl.

Lingon is an application that allows you to make OS X run scripts between regular intervals (among other things.) Its UI should be quite straightforward.

1) Download Growl (the link is in the post) and install it. From the Growl disk image (.dmg file) where the installer can be found, you’ll find a file called “growlnotify” (in a folder called “Extras”, if I remember correctly.) Copy this file over to /usr/local/bin (if this folder structure doesn’t exist, create it.) If you’re running Leopard, see my post about making growlnotify work properly in Leopard: ://hasseg.org/blog/post/111/growlnotify-leopard-incompatibility-workaround/

2) Download bluelist from the following location (this is a gzip archive so you’ll have to extract it first to get the bluelist application itself) and put it in /usr/local/bin as well: http://will.harris.ch/bluelist.gz

3) Download my script and its support files (the link is in the post.) Extract the contents of the archive somewhere (e.g. in /Users/your_user_name/scripts/forceSync)

4) Open my script in a text editor and configure it (in the “SETTINGS” section.) I Hope the comments I’ve put in the script will make it clear what each of the configuration values mean and what the allowed values for them are. Save the edited script when you’re done.

5) Test the script by running it in the terminal with the “verbose” parameter ("-v"):

cd /Users/your_user_name/scripts/forceSync/
./forceSync.bash -v

6) Download Lingon (the link is in the post) and run it. Create a new “agent”. You can put “org.hasseg.forceSync” into the Name field, “/Users/your_user_name/scripts/forceSync/forceSync.bash” (or wherever you put my script in) into the What field, and specify how often youd like to run it (e.g. “Run it every 30 minutes”.) Remember to check the “enabled” checkbox and click save.

If you’re still having problems, make sure that all of the command-line apps as well as my script are executable:

chmod a+x /Users/your_user_name/scripts/forceSync/forceSync.bash
chmod a+x /usr/local/bin/growlnotify
chmod a+x /usr/local/bin/bluelist
google.com/accounts/o8… January 4, 2010 at 7:48 PM

Thanks for this. I had to rebuild bluelist on Snow Leopard but otherwise it works fine.

paolo April 2, 2012 at 8:02 PM

Hi, thanks for all of this! It’s perfect! I’ve modified it a little bit because I don’t want my bluetooth always on. It’s simple, you have only to integrate it with ‘blueutil’ (http://www.frederikseiffert.de/blueutil/), just adding at the beginning and at the ending two commands. Bye!

Categories