Automatic, Periodic Syncing with iSync

Posted on April 17, 2008
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
Bookmark and Share

Comments

3 Responses to “Automatic, Periodic Syncing with iSync”

Show/hide comments & reply form: