Automatic, Periodic Syncing with iSync
Posted on April 17, 2008
Filed under Mac, Scripts
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 and supporting files in a zip archive
- bluelist by Marc Liyanage and Will Harris (required for this to work — save it in /usr/local/bin or somewhere)
- Lingon by Peter Borg (optional: for setting up a launchd configuration for this from a GUI)
- Growl (optional: for notifications. also remember to install the growlnotify CLI app that is included with the distribution package, and if you’re running Leopard, check out my workaround for a Leopard bug in growlnotify)
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
Comments
3 Responses to “Automatic, Periodic Syncing with iSync”
Im pretty new to macs, if you have the time could you please post a step-by-step?
thanks!
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: http://hasseg.org/blog/?p=111
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”):
./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 /usr/local/bin/growlnotify
chmod a+x /usr/local/bin/bluelist