Portable iCal icon

Portable iCal

Download Portable iCal application

You can download Portable iCal application with a minimum amount of $0.99 or donating more:
Requires OS X 10.4.2 or later, NOT compatible with 10.5 LEOPARD, 10.6 SNOW LEOPARD and 10.7 LION.

Change log

r1.4 (Feb. 2008)

r1.3 (Oct. 2006)

Dowload Portable iCal script source

You can dowload Portable Safari script source from sourceforge.net and then wrap application yourself.
You also need Platypus and CocoaDialog.
Requires OS X 10.4.2 or later, NOT compatible with 10.5 LEOPARD, 10.6 SNOW LEOPARD and 10.7 LION.

Portable iCal script source code

#!/bin/sh -x

##########################################################################
#
#   Portable iCal
#   $Revision: 1.4
#
#   The Contents of this file are made available subject to the terms
#   of the following license
#
#          - GNU General Public License Version 2.1
#
#   Carlo Gandolfi, 2006-2008
#
#   GNU General Public License Version 2.1
#   =============================================
#   Copyright 2006 by Carlo Gandolfi (cgand@users.sourceforge.net)
#
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
##########################################################################

# Reset PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

appurl=com.apple.iCal.plist
appurl2=com.apple.iCal.AlarmScheduler.plist
appurl3=com.apple.iCal.helper.plist
appid=iCal
apppath="/Applications/$appid.app"

userplistbase="Library/Preferences"
userplist="$userplistbase/$appurl"
userplist2="$userplistbase/$appurl2"
userplist3="$userplistbase/$appurl3"
upl="$userplist $userplist2 $userplist3"
userprefbase="Library/Application Support"
userpref="$HOME/$userprefbase/$appid"
usercachebase="$HOME/Library/Caches"
usercache="$usercachebase/com.apple.iCal"
lagents="$HOME/Library/LaunchAgents"

p_userbase="$1/Contents/Resources"
p_userplist="$p_userbase/$userplistbase/$appurl"
p_userpref="$p_userbase/$userprefbase/$appid"
copy_pref="$p_userbase/CopyPref_Done"

CD="$p_userbase/CocoaDialog.app/Contents/MacOS/CocoaDialog"
appicon="$p_userbase/appIcon.icns"
cautionicon="$p_userbase/P_${appid}_Caution.icns"

scrapp='Portable_'$appid'_scr.app'
scrapppath="$p_userbase/$scrapp"

scrplist='org.FreeSMUG.Portable_scr.plist'
scrappplist='org.FreeSMUG.Portable_'$appid'_scr.plist'

# ========================================================
# CDokmessage
# CocoaDialog Ok/Cancel message box
# $1 "text"
# $2 "informative text"
# $3 "--no-cancel" = don't show a cancel button
# ========================================================

function CDokmessage {
	beep
	"$CD" ok-msgbox  --icon-file "$appicon" \
	--text "$1" --informative-text "$2" "$3"
}

function CDokmessagec {
	beep
	"$CD" ok-msgbox  --icon-file "$cautionicon" \
	--text "$1" --informative-text "$2" "$3"
}

function beep {
	/usr/bin/osascript << EOT
	tell application "Finder"
	beep
	end tell
EOT
}

# ========================================================
# bsd_command_check
# Check that the required BSD command are installed
# ========================================================

function command_check_msg {
message1="One or more *BSD commands* to run Portable $appid were not found on \
this machine. You must install the BSD Subsystem package that is in the \
following folder on disk 1 of your Mac OS X installation DVD:\n/Welcome to Mac \
OS X/Optional Installs.\n\nNow quit."
button=`/usr/bin/osascript << EOT
	tell application "Finder"
	beep
	display dialog "$message1" buttons {"Quit"} \
		with icon caution default button "Quit"
	set result to button returned of result
	end tell
EOT`
if test "$button" == "Quit"; then				# Quit application
	exit 112
fi
}

function bsd_command_check {  	# written by Patrick Luby	
commands="awk cp defaults diskutil echo grep ln mkfifo mkdir mv plutil ps rm sed sleep touch"
for i in $commands ; do
	if [ ! -x "/usr/bin/$i" -a ! -x "/bin/$i" -a ! -x "/usr/sbin/$i" -a ! -x "/sbin/$i" ] ; then
	    # Return 96 + 16 if a command is not found
		command_check_msg;
		exit 112;
	fi
done
}


# ========================================================
# osx_version_check
# Check that the user is running Mac OS X 10.4.2 - 10.4.x
# ========================================================

function version_check_msg {
message1="You are running OS X version $version.\n\
Portable $appid can only be opened on Mac OS X 10.4.2 up to 10.4.x"
button=`/usr/bin/osascript << EOT
	tell application "Finder"
	beep
	display dialog "$message1" buttons {"Quit"} \
		with icon caution default button "Quit"
	set result to button returned of result
	end tell
EOT`
if test "$button" == "Quit"; then				# Quit application
	exit 113
fi

}

function osx_version_check {	 # written by Patrick Luby	
if [ -x "/usr/bin/sw_vers" ] ; then
    # Return 96 + 17 if it is a bad version
    version=`/usr/bin/sw_vers | grep '^ProductVersion:' | awk '{ print $2 }'`
    case "$version" in
        10.[01234]) version_check_msg ; exit 113;;
        10.[01234].[01]) version_check_msg ; exit 113;;
        1[0-9].[5-9]) version_check_msg ; exit 113;;
        1[0-9].[5-9].[0-9]) version_check_msg ; exit 113;;
        1[0-9].[5-9].[0-9][0-9]) version_check_msg ; exit 113;;
    esac
fi
}

# ========================================================
# quitapp
# Check if local app is open and quit
# ========================================================

function quitapp {
	if ps cx | grep '[0-9] '"$appid"'$' > /dev/null; then
		rv=` CDokmessage "$appid is already running on this system" \
		"Only one copy can be run at a time. \
Quit runnig $appid and reopen Portable $appid." "--no-cancel" `
		if [ "$rv" == "1" ] ; then				# Quit application
			exit 0
		fi
	fi
}

# ========================================================
# checkapppath
# Check if $appid is in /Application folder
# ========================================================

function select_app {
	rvf=` "$CD" fileselect --title "Open $appid" --text "Please select $appid" \
	--with-directory /Applications --with-extensions .app `
	if [ -x "$rvf/Contents/MacOS/$appid" ] ; then
		apppath="$rvf"; export apppath
	else
		rv=` CDokmessagec "$appid not selected" "Sorry you have not choose \
$appid. You have selected \"$rvf\". Try again?" `
		if [ "$rv" == "1" ] ; then
			select_app
		elif [ "$rv" == "2" ] ; then
			exit 0
		fi
	fi
}

function checkapppath {
	if	[ ! -x "/Applications/$appid.app/Contents/MacOS/$appid" ] ; then
		rv=` CDokmessagec "$appid not found" \
		"$appid is not in default \"/Application\" folder. \
Locate $appid to open it." `
		if [ "$rv" == "1" ] ; then
			select_app
 		elif [ "$rv" == "2" ] ; then
			exit 0
		fi
	fi
}

# ========================================================
# repair
# Repair preferences if Portable Application crashed
# ========================================================

function restore {
	for i in $upl ; do
		if [ -f "$HOME/$i.pabu" ] ; then
			mv "$HOME/$i" "$HOME/$i.old"
			mv "$HOME/$i.pabu" "$HOME/$i"
		fi
	done
	if [ -d "$userpref.pabu" ] ; then
		mv "$userpref" "$userpref.old"
		mv "$userpref.pabu" "$userpref"
	fi
}

function restorepabu {
		if  [ -f "$HOME/$userplist" ] || \
		[ -f "$HOME/$userplist2" ] || \
		[ -f "$HOME/$userplist3" ] || \
		[ -d "$userpref" ] ; then
		removemsg="Portable $appid has not restored local preferences back-up. \
Local preferences already exists. You are now restoring preferences back-up \
renaming existing as $appid.old."
	else
		removemsg="Portable $appid has not restored local preference back-up. \
You are now restoring them."
	fi
	rv=` CDokmessagec "Restore local preferences back-up" "$removemsg" `
	if [ "$rv" == "1" ] ; then
		if restore ; then
			CDokmessage "$appid Preferences back-up Restore done" \
"Local $appid preferences back-up restored with success." "--no-cancel" > /dev/null
		else
			CDokmessagec "$appid Preferences back-up Restore error" \
		"Local $appid preferences back-up can't be restored. Now quit." "--no-cancel" \
		> /dev/null
			exit 0
		fi
	elif [ "$rv" == "2" ] ; then
		repair
	fi
}

function copy {
	rm -rf "$HOME/$appid Pref BackUp/"
	for i in $upl ; do
		if  [ -f "$HOME/$i.pabu" ] ; then
			mkdir -p "$HOME/$appid Pref BackUp/$userplistbase"
			mv "$HOME/$i.pabu" "$HOME/$appid Pref BackUp/$i"
		fi
	done
	if [ -d "$userpref.pabu" ] ; then
		mkdir -p "$HOME/$appid Pref BackUp/$userprefbase"
		mv "$userpref.pabu" \
		"$HOME/$appid Pref BackUp/$userprefbase/$appid"
	fi
	cp "$p_userbase/CopyPrefBU_ReadMe.txt" "$HOME/$appid Pref BackUp/ReadMe.txt"
}
	
function copypabu {
	rv=` CDokmessagec "Copy local preferences back-up" \
	"Portable $appid has not restored local preference back-up. \
You are now copying them to \"$HOME/$appid Pref BackUp/\" folder." `
	if [ "$rv" == "1" ] ; then
		if copy ; then
			CDokmessage "$appid Preferences back-up Copy done" "Preferences \
back-up copied to \"$HOME/$appid Pref BackUp/\" folder with success." \
"--no-cancel" > /dev/null
		else
			CDokmessagec "$appid Preferences back-up Copy error" "Preferences \
back-up can't be copied to \"$HOME/$appid Pref BackUp/\" folder. Now quit." \
"--no-cancel" > /dev/null
			exit 0
		fi
	elif [ "$rv" == "2" ] ; then
		repair
	fi
}

function repair {
	if  [ -d "$usercache.pabu" ] ; then
		rm -rf "$usercache.pabu"			# Delete backup cache
	fi
	if [ -h "$userpref" ] ; then
		rm -f "$userpref"					# Delete symlink
	fi
	if  [ -f "$HOME/$userplist.pabu" ] || \
	[ -f "$HOME/$userplist2.pabu" ] || \
	[ -f "$HOME/$userplist3.pabu" ] || \
	[ -d "$userpref.pabu" ] ; then
		beep	
		text2="Local $appid preferences back-up not restored"
		informativetext2="A temporary back-up of local $appid preferences \
still exist, Portable $appid crashed without restoring this back-up. You can \
Restore local preferences back-up now or Copy to \""$HOME/$appid" BackUp\" \
folder to manually restore later."
		rv=`"$CD" msgbox  --icon-file "$cautionicon" \
		--text "$text2" --informative-text "$informativetext2" \
		--button1 "Restore" --button2 "Copy"`
		if [ "$rv" == "1" ] ; then
			restorepabu			
		elif [ "$rv" == "2" ] ; then
			copypabu
		fi	
	fi
}

# ========================================================
# system_crash_repair
# Repair pabu preferences after system crash
# ========================================================
function add_launchagents {
	if [ ! -d "$lagents" ] ; then
		mkdir "$lagents"
	fi
	sed -e 's|${HOME}|'"$HOME|g" \
	-e 's|${appid}|'"$appid|g" "$p_userbase/$scrplist" > "$lagents/$scrappplist"
}

function del_launchagents {
	if [ -f "$lagents/$scrappplist" ] ; then
		rm -f "$lagents/$scrappplist"
	fi
}

# copy system crash repair from portable $appid to $HOME
function copy_scr {
	cp -R "$scrapppath" "$HOME/.$scrapp"
}

# delete system crash repair from $HOME
function del_scr {
	rm -rf "$HOME/.$scrapp"
}

# ========================================================
# check_p_asf
# Check and create Portable Application Support folders
# ========================================================

function check_p_asf {
	readonly=`diskutil info "$p_userbase" | grep "Read Only" | awk '{ print $3 }'`
	if [ "$readonly" = Yes ]; then
		CDokmessagec "Portable $appid is on a locked volume" "Portable $appid can't \
be opened on a locked volume. Now quit." "--no-cancel" > /dev/null
		exit 0
	else
		if [ ! -d "$p_userpref" ] ; then
			mkdir -p "$p_userpref"
		fi
		if [ ! -d "$p_userbase/$userplistbase" ] ; then
			mkdir -p "$p_userbase/$userplistbase"
		fi
	fi
}

# ========================================================
# bu/recover preference
# BackUp existing preference and restore portable ones
# ========================================================

function bu_plist {	
	for i in $upl ; do
		if  [ -f "$HOME/$i" ] ; then
			mv "$HOME/$i" "$HOME/$i.pabu"
		fi
	done
}

function recover_plist {
	for i in $upl ; do
		if  [ -f "$HOME/$i.pabu" ] ; then
			mv "$HOME/$i.pabu" "$HOME/$i"
		else
			rm -f "$HOME/$i"
		fi
	done
}

function recover_p_plist {
	for i in $upl ; do
		if [ -f "$p_userbase/$i" ] ; then
			cp "$p_userbase/$i" "$HOME/$i"
		fi
	done
}

function bu_p_plist {
	for i in $upl ; do
		if [ -f "$HOME/$i" ] ; then
			cp "$HOME/$i" "$p_userbase/$i"
		fi
	done
}

# ========================================================
# copy_local_pref
# Copy local preferences to Portable Application
# ========================================================

function runcopypref {	# written by Kevin Hendricks 
	rm -f /tmp/hpipe
	mkfifo /tmp/hpipe
	"$CD" progressbar --indeterminate --title "Copying $appid Preferences" \
	--text "Copying \"$userpref\". Please wait..." < /tmp/hpipe &
	exec 3<> /tmp/hpipe
	echo -n . >&3
	# do all of your work here
	cp -R "$userpref" "$p_userpref"
	exec 3>&-
	wait
	rm -f /tmp/hpipe
}
	
function check_asf {
	if [ -d "$p_userpref" ] ; then
		# delete p_userpref if it still exist
		rm -Rf "$p_userpref"
	else
		mkdir -p "$p_userpref"
	fi
}

# copy Preferences Folder
function copy_pf {
	userprefsize=`du -hc "$userpref" | cut -f1 | tail -1`
	freesize=`df -h "$p_userbase" | tail -1 | awk '{print $4}'`
	buserprefsize=`du -c "$userpref" | cut -f1 | tail -1`
	bfreesize=`df "$p_userbase" | tail -1 | awk '{print $4}'`
	if [ $buserprefsize -lt $bfreesize ] ; then
		rv=` CDokmessage "Copy $appid Preferences" \
		"Your $appid Preferences are $userprefsize. \
You have $freesize available. Copy to Portable $appid?" `
		if [ "$rv" == "1" ] ; then
			if check_asf ; bu_p_plist ; runcopypref ; then
				touch -f "$copy_pref"
				"$CD" bubble --title "$appid Preferences copied" --text "Local \
$appid Preferences copied to Portable $appid with success." \
--icon-file "$appicon"
			else
				"$CD" bubble --title "$appid Preferences copy error" \
--text "An error occurred copying $appid Preferences to Portable $appid." \
--icon-file "$cautionicon"
			fi
		fi
		else
		CDokmessagec "No space to copy $appid Preferences" \
		"Your $appid Preferences are $userprefsize. \
You have $freesize available. There is no enough space. Portable $appid will \
open without copy existing $appid Preferences." "--no-cancel" > /dev/null
	fi
}

function copy_local_pref {
	if [ ! -f "$copy_pref" ] && [ -d  "$userpref" ] ; then
	beep
	text="Copy Preferences"
	informativetext="Copy the existing $appid Preferences \
on this system to Portable $appid?"
	rv=`"$CD" msgbox --no-newline --icon-file "$appicon" \
	--text "$text" --informative-text "$informativetext" \
	--button1 "Copy" --button2 "Don't Copy" --button3 "Never"`
		if [ "$rv" == "1" ] ; then
			copy_pf
		elif [ "$rv" == "3" ] ; then
			touch -f "$copy_pref" 
		fi
	fi
}

# ========================================================
# bu/recover asf
# BackUp existing Application Support Folder and restore portable ones
# ========================================================

function bu_asf {
	if [ -d "$userpref" ] ; then
		mv "$userpref" "$userpref.pabu"
	fi
}

function recover_asf {
	if [ -d "$userpref.pabu" ] ; then
		mv "$userpref.pabu" "$userpref"
	fi
}

function recover_p_asf {
	ln -s "$p_userpref" "$userpref"
}

function bu_p_asf {
	if [ -h "$userpref" ] ; then
		rm -rf "$userpref"
	fi
}

# ========================================================
# bu/recover cache
# BackUp existing cache
# ========================================================

function bu_cache {
	if [ -d "$usercache" ] ; then
		mv "$usercache" "$usercache.pabu"
	fi
}

function recover_cache {
	if  [ -d "$usercache.pabu" ] ; then
		mv "$usercache.pabu" "$usercache"
	fi
}

function remove_p_cache {
	if  [ -d "$usercache" ] ; then	
		rm -rf "$usercache"
	fi
}

# ========================================================
# run
# Open Portable Application
# ========================================================

function run_app {
	"$apppath/Contents/MacOS/$appid"
}

# ========================================================
# open_p_app
# Run Portable Application script
# ========================================================
	
function set_p_app {
	copy_scr			# Copy System Crash Restore app
	add_launchagents	# Add LaunchAgents plist file
	bu_plist			# Backup of existing preference
	bu_asf				# Backup existing Application Support folder
	bu_cache			# Backup exixting Cache folder
	recover_p_plist		# Recover portable preference
	recover_p_asf		# Recover portable Application Support folder
}

function close_p_app {
	bu_p_plist			# Backup portable preference
	bu_p_asf			# Backup portable Application Support folder
	remove_p_cache		# Remove portable cache
	recover_plist		# Restore existing preference
	recover_asf			# Restore portable Application Support folder
	recover_cache		# Restore existing cache
	del_launchagents	# Delete LaunchAgents .plist file
	del_scr				# Delete System Crash Restore app
}
	
function open_p_app {
	if set_p_app ; then
		"$CD" bubble --title "Portable $appid setup ok" --text "Portable \
$appid open with success." --icon-file "$appicon" &
	else
		CDokmessagec "Portable $appid setup error" \
"An error occour while opening portable preferences. Now quit." "--no-cancel" > /dev/null
	close_p_app
	exit 0
	fi
	run_app 				# Run application with external drive prefs
	if close_p_app ; then
	"$CD" bubble --title "Portable $appid quit" --text "Portable \
$appid quit with success." --icon-file "$appicon" &
	else
	CDokmessagec "Portable $appid quit error" \
"An error occur while restoring local preferences. \
Try to reopen Portable $appid to fix the problem." "--no-cancel" > /dev/null
	fi
}

bsd_command_check
osx_version_check
quitapp
checkapppath
repair
check_p_asf
copy_local_pref
open_p_app
exit 0
		

Portable_iCal_scr.app script source code

#!/bin/sh -x

##########################################################################
#
#   Portable iCal scr (system crash restore)
#   $Revision: 1.1
#
#   The Contents of this file are made available subject to the terms
#   of the following license
#
#          - GNU General Public License Version 2.1
#
#   Carlo Gandolfi, October 2006
#
#   GNU General Public License Version 2.1
#   =============================================
#   Copyright 2006 by Carlo Gandolfi (cgand@users.sourceforge.net)
#
#   This program is free software; you can redistribute it and/or
#   modify it under the terms of the GNU General Public
#   License version 2.1, as published by the Free Software Foundation.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   General Public License for more details.
#
#   You should have received a copy of the GNU General Public
#   License along with this library; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston,
#   MA  02111-1307  USA
#
##########################################################################

# Reset PATH
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH

appurl=com.apple.iCal.plist
appurl2=com.apple.iCal.AlarmScheduler.plist
appurl3=com.apple.iCal.helper.plist
appid=iCal

userplistbase="Library/Preferences"
userplist="$userplistbase/$appurl"
userplist2="$userplistbase/$appurl2"
userplist3="$userplistbase/$appurl3"
upl="$userplist $userplist2 $userplist3"
userprefbase="Library/Application Support"
userpref="$HOME/$userprefbase/$appid"
usercachebase="$HOME/Library/Caches"
usercache="$usercachebase/com.apple.iCal"
lagents="$HOME/Library/LaunchAgents"

scrapp='Portable_'$appid'_scr.app'

scrappplist='org.FreeSMUG.Portable_'$appid'_scr.plist'

function bu_p_asf {
	if [ -h "$userpref" ] ; then 
		rm -rf "$userpref"
	fi
}

function remove_p_cache {
	rm -rf "$usercache"
}

function recover_plist {
	for i in $upl ; do
		if  [ -f "$HOME/$i.pabu" ] ; then
			mv "$HOME/$i.pabu" "$HOME/$i"
		else
			rm -f "$HOME/$i"
		fi
	done
}

function recover_asf {
	if [ -d "$userpref.pabu" ] ; then
		mv "$userpref.pabu" "$userpref"
	fi
}

function recover_cache {
	if  [ -d "$usercache.pabu" ] ; then
		mv "$usercache.pabu" "$usercache"
	fi
}

function del_launchagents {
	if [ -f "$lagents/$scrappplist" ] ; then
		rm -f "$lagents/$scrappplist"
	fi
}

function del_scr {
	sleep 1; rm -rf "$HOME/.$scrapp"
}

function close_p_app {
	bu_p_asf			# Backup portable Application Support folder
	remove_p_cache			# Remove portable cache
	recover_plist		# Restore existing preference
	recover_asf			# Restore portable Application Support folder
	recover_cache		# Restore existing cache
	del_launchagents		# Delete LaunchAgents .plist file
	del_scr					# Delete System Crash Restore app
}

close_p_app
exit 0