whitespace

whitespace

FasdUAS 1.101.10
k
l
r
m

niji://
	o0uri

l"
V"
k

I

.sysodlogaskrTEXT
m
<Enter a "niji://" URI to test.

dtxt
o
0uri
r
n
1

ttxt
1

rslt
o0uri
I
.GURLGURLnullTEXT
 o0uri
m
boovtrue
!"
!l"#
#i$%
$I&
.GURLGURLnullTEXT
&o0uri
%k''()
(l*+* Decode URI+,, Decode URI)-.
-Q*/01
/r23
2n45
4767

ctxt
6l8
8[9:
9l	;
;I	<
.sysooffslongnull<=>

psof
=m??@@://>A

psin
Ao
0uri
:m
7m
5o0uri
3o0resource
0R
.ascrerr ********
1k"*BBCD
CI"'E
.sysonotfnullTEXT
Em"#FFGG*Malformed URI: Empty.DH
HL(*.IJ
Ir+6KL
KI+4M
.sysooffslongnullMNO

psof
Nm-.PPQQ?OR

psin
Ro/00resource
Lo0qJST
SZ7IUV
UA7:WX
Wo780q
Xm89
Vk=EYYZ[
ZI=B\
.sysonotfnullTEXT
\m=>]]^^2Malformed URI: No action.[_
_LCET`a
`rJYbc
bnJWde
d7KWfg

ctxt
fmOQ
glRVh
h\RVij
ioST0q
jmTU
eoJK0resource
co
0actionakl
kQZwmno
mr]lpq
pn]jrs
r7^jtu

ctxt
tlbfv
v[bfwx
wocd0q
xmde
umgi
so]^0resource
qo
0params
nR
.ascrerr ********
ortwyz
ymtu{{||
zo
0paramsl}~
}rx}
mxy&
n
1z|

txdl
1yz

ascr~
r~
n~
2

citm
o~
0params
o0keyvals
r
m=
n
1

txdl
1

ascr
r
J
o0opts
Y
k
r
n
4

cobj
o0i
o0keyvals
o0kv
Q
s
n
2

citm
o0kv
J
o0k
o0v
R
.ascrerr ********
I
.sysonotfnullTEXT
b
b
m4Malformed URI parameter. (
o0kv
m)
r
I
.sysoexecTEXTTEXT
b
b
m0php -r 'echo urldecode("
o0v
m");'
o0decoded
r
b
o0opts
l
I
.sysodsct****scpt
b
b
b
b
m{|
o0k
m|:"
o0decoded
m"}
o0opts0i
m
I
.corecnte********
o0keyvals
r

m

n
1

txdl
1

ascr
l~}~}
l|| Select action Select action{
Z
=
ozz
0action
m
apply
k
lyy  Check for required params4 Check for required params
QL
k4
r$
n"
o"xx0cmd
oww0opts
ovv0_cmd
r%,

	n%*
o&*uu0name
o%&tt0opts

oss	0_name
r

r-4
n-2
o.2qq0yaml
o-.pp0opts
ooo	0_yamlr
Rnm
n.ascrerr ********
oll0msgm
k<L
I<Ikj
k.sysonotfnullTEXT
b<E
b<A
m<?>Missing a required parameter. (
o?@ii0msg
mAD)jh
LJLggh !
 lMMfedfed!"#
"lMMc$%c$# Write yaml to temporary file%&&: Write yaml to temporary file#'(
'QM)*+
)kP,,-.
-rPe/0
/bPa12
1lP]3ba
3IP]`45
`.earsffdralis afdr
4mPS_
_afdrtemp5^6]
^
rtyp
6mVY\
\
TEXT]ba
2m]`7788niji.yaml
0o[[0tmp.9Z
9IfY:X
Y.sysoexecTEXTTEXT
:bf{;<
;bfs=>
=bfo?@
?mfiAABB
echo
@linCWV
CninDE
D1jnU
U
strq
EoijTT	0_yamlWV
>morFFGG >
<nszHI
H1vzS
S
psxp
IosvRR0tmpXZ
*RQJP
Q.ascrerr ********
JoOO0msgP
+kKKLM
LINNM
N.sysonotfnullTEXT
NbOP
ObQR
QmSSTTRFailed to write YAML to temporary file. (
RoLL0msg
PmUUVV)MMWK
WLJJK(XY
XlIHGIHGYZ[
ZlF\]F\
 Run zenbu]^^ Run zenbu[_E
_Q`ab
`kccde
dIDfC
D.sysoexecTEXTTEXT
fbgh
gbij
ibkl
kbmn
mmooppbash -lc "
noBB0_cmd
lmqqrr
jnst
s1A
A
psxp
to@@0tmp
hmuuvv"Cew?
wI>x=
>.sysonotfnullTEXT
xbyz
yb{|
{m}}~~Applied "
|o<<	0_name
zm".=?
aR;:
;.ascrerr ********
o990msg:
bk
I87
8.sysonotfnullTEXT
b
b
b
b
mFailed run `
o660_cmd
m`. (
o550msg
m)74
L334E
=
o22
0action
msave1
kz
l00  Check for required params4 Check for required params
Q
k
r
n
o//0root
o..0opts
o--	0_root
r
n
o,,0name
o++0opts
o**	0_name)
r
n
o((0yaml
o''0opts
o&&	0_yaml)
R%$
%.ascrerr ********
o##0msg$
k
I"!
".sysonotfnullTEXT
b
b
m>Missing a required parameter. (
o  0msg
m)!
L
l
l    Write yaml to destination4 Write yaml to destination
r 1
b -
b )
b '
o #	0_root
m#&/
o'(	0_name
m),
.yaml
o0dest
Q2z
k5Z
I5J
.sysoexecTEXTTEXT
b5F
b5B
b5>
m58
echo
l8=
n8=
19=

strq
o89	0_yaml
m>A >
oBE0dest
IKZ

.sysonotfnullTEXT
bKV
bKR
mKNSaved to "
oNQ0dest
mRU".
R

.ascrerr ********
o0msg
kbz
Ibw
.sysonotfnullTEXT
bbs
bbo
bbm
bbi
mbe		2Failed to write YAML to "
oeh0dest
mil

" file. (
omn0msg
mor

)
Lxz1
I}
.sysonotfnullTEXT
b}
b}
m}Action "
o
0action
m&" is not supported.{
.GURLGURLnullTEXT
.aevtoappnull****%
.GURLGURLnullTEXT0uri0uri0resource0q
0action
0params0keyvals0opts0i0kv0k0v0decoded0_cmd	0_name	0_yaml0msg0tmp	0_root0destG?FP]{7AFSUoqu}

ctxt

psof

psin
.sysooffslongnull
.sysonotfnullTEXT

ascr

txdl

citm
.corecnte********

cobj
.sysoexecTEXTTEXT
.sysodsct****scpt0cmd0name0yaml0msg
afdrtemp

rtyp

TEXT
.earsffdralis afdr

strq

psxp0root[\[Z*m\Zi2EWXj	OhO*EOl
j	OhYhO[\[Zk\Zk2EO[\[Zk\Zi2EW
XEO,FOa-EOa,FOjvEOukjkha/EOa-E[ak/EQZ[al/EQZWXa%a%j	Oa%a%jEOa%a%%a%j%E[OYOa,FOaa,EOa ,EOa!,EWX"a#%a$%j	OhO4a%a&a'l(a)%E^Oa*a+,%a,%]a-,%jWX"a.%a/%j	OhO,a0%a1%]a-,%a2%jOa3%a4%j	WX"a5%a6%%a7%j	OhYa8a9,E^Oa ,EOa!,EWX"a:%a;%j	OhO]a<%%a=%E^O*a>a+,%a?%]%jOa@]%aA%j	WX"aB]%aC%%aD%j	OhYaE%aF%j
.aevtoappnull****
k"  !!
0uri

dtxt
.sysodlogaskrTEXT

rslt

ttxt
.GURLGURLnullTEXT#EOhelO,EOj[OYascr
ޭ

FasdUAS 1.101.10
k
l
r
m

niji://
	o0uri

l"
V"
k

I

.sysodlogaskrTEXT
m
<Enter a "niji://" URI to test.

dtxt
o
0uri
r
n
1

ttxt
1

rslt
o0uri
I
.GURLGURLnullTEXT
 o0uri
m
boovtrue
!"
!l"#
#i$%
$I&
.GURLGURLnullTEXT
&o0uri
%k''()
(l*+* Decode URI+,, Decode URI)-.
-Q*/01
/r23
2n45
4767

ctxt
6l8
8[9:
9l	;
;I	<
.sysooffslongnull<=>

psof
=m??@@://>A

psin
Ao
0uri
:m
7m
5o0uri
3o0resource
0R
.ascrerr ********
1k"*BBCD
CI"'E
.sysonotfnullTEXT
Em"#FFGG*Malformed URI: Empty.DH
HL(*.IJ
Ir+6KL
KI+4M
.sysooffslongnullMNO

psof
Nm-.PPQQ?OR

psin
Ro/00resource
Lo0qJST
SZ7IUV
UA7:WX
Wo780q
Xm89
Vk=EYYZ[
ZI=B\
.sysonotfnullTEXT
\m=>]]^^2Malformed URI: No action.[_
_LCET`a
`rJYbc
bnJWde
d7KWfg

ctxt
fmOQ
glRVh
h\RVij
ioST0q
jmTU
eoJK0resource
co
0actionakl
kQZwmno
mr]lpq
pn]jrs
r7^jtu

ctxt
tlbfv
v[bfwx
wocd0q
xmde
umgi
so]^0resource
qo
0params
nR
.ascrerr ********
ortwyz
ymtu{{||
zo
0paramsl}~
}rx}
mxy&
n
1z|

txdl
1yz

ascr~
r~
n~
2

citm
o~
0params
o0keyvals
r
m=
n
1

txdl
1

ascr
r
J
o0opts
Y
k
r
n
4

cobj
o0i
o0keyvals
o0kv
Q
s
n
2

citm
o0kv
J
o0k
o0v
R
.ascrerr ********
I
.sysonotfnullTEXT
b
b
m4Malformed URI parameter. (
o0kv
m)
r
I
.sysoexecTEXTTEXT
b
b
m0php -r 'echo urldecode("
o0v
m");'
o0decoded
r
b
o0opts
l
I
.sysodsct****scpt
b
b
b
b
m{|
o0k
m|:"
o0decoded
m"}
o0opts0i
m
I
.corecnte********
o0keyvals
r

m

n
1

txdl
1

ascr
l~}~}
l|| Select action Select action{
Z
=
ozz
0action
m
apply
k
lyy  Check for required params4 Check for required params
QL
k4
r$
n"
o"xx0cmd
oww0opts
ovv0_cmd
r%,

	n%*
o&*uu0name
o%&tt0opts

oss	0_name
r

r-4
n-2
o.2qq0yaml
o-.pp0opts
ooo	0_yamlr
Rnm
n.ascrerr ********
oll0msgm
k<L
I<Ikj
k.sysonotfnullTEXT
b<E
b<A
m<?>Missing a required parameter. (
o?@ii0msg
mAD)jh
LJLggh !
 lMMfedfed!"#
"lMMc$%c$# Write yaml to temporary file%&&: Write yaml to temporary file#'(
'QM)*+
)kP,,-.
-rPe/0
/bPa12
1lP]3ba
3IP]`45
`.earsffdralis afdr
4mPS_
_afdrtemp5^6]
^
rtyp
6mVY\
\
TEXT]ba
2m]`7788niji.yaml
0o[[0tmp.9Z
9IfY:X
Y.sysoexecTEXTTEXT
:bf{;<
;bfs=>
=bfo?@
?mfiAABB
echo
@linCWV
CninDE
D1jnU
U
strq
EoijTT	0_yamlWV
>morFFGG >
<nszHI
H1vzS
S
psxp
IosvRR0tmpXZ
*RQJP
Q.ascrerr ********
JoOO0msgP
+kKKLM
LINNM
N.sysonotfnullTEXT
NbOP
ObQR
QmSSTTRFailed to write YAML to temporary file. (
RoLL0msg
PmUUVV)MMWK
WLJJK(XY
XlIHGIHGYZ[
ZlF\]F\
 Run zenbu]^^ Run zenbu[_E
_Q`ab
`kccde
dIDfC
D.sysoexecTEXTTEXT
fbgh
gbij
ibkl
kbmn
mmooppbash -lc "
noBB0_cmd
lmqqrr
jnst
s1A
A
psxp
to@@0tmp
hmuuvv"Cew?
wI>x=
>.sysonotfnullTEXT
xbyz
yb{|
{m}}~~Applied "
|o<<	0_name
zm".=?
aR;:
;.ascrerr ********
o990msg:
bk
I87
8.sysonotfnullTEXT
b
b
b
b
mFailed run `
o660_cmd
m`. (
o550msg
m)74
L334E
=
o22
0action
msave1
kz
l00  Check for required params4 Check for required params
Q
k
r
n
o//0root
o..0opts
o--	0_root
r
n
o,,0name
o++0opts
o**	0_name)
r
n
o((0yaml
o''0opts
o&&	0_yaml)
R%$
%.ascrerr ********
o##0msg$
k
I"!
".sysonotfnullTEXT
b
b
m>Missing a required parameter. (
o  0msg
m)!
L
l
l
l    Write yaml to destination4 Write yaml to destination
r 1
b -
b )
b '
o #	0_root
m#&/
o'(	0_name
m),
.yaml
o0dest
Q2z
k5Z
I5J
.sysoexecTEXTTEXT
b5F
b5B
b5>
m58
echo
l8=
n8=
19=

strq
o89

	0_yaml
m>A >
oBE0dest
IKZ

.sysonotfnullTEXT
bKV
bKR
mKNSaved to "
oNQ0dest
mRU".
R
.ascrerr ********
o0msg
kbz
Ibw
.sysonotfnullTEXT
bbs
bbo
bbm
bbi
mbe

2Failed to write YAML to "
	oeh0dest
mil

" file. (
omn0msg
mor)
Lxz1
I}
.sysonotfnullTEXT
b}
b}
m}Action "
o
0action
m&" is not supported.{
.GURLGURLnullTEXT
.aevtoappnull****0uri%
.GURLGURLnullTEXT0uri0uri0resource0q
0action
0params0keyvals0opts0i0kv0k0v0decoded0_cmd	0_name	0_yaml0msg0tmp	0_root0destG?FP]{7AFSUoqu}

ctxt

psof

psin
.sysooffslongnull
.sysonotfnullTEXT

ascr

txdl

citm
.corecnte********

cobj
.sysoexecTEXTTEXT
.sysodsct****scpt0cmd0name0yaml0msg
afdrtemp

rtyp

TEXT
.earsffdralis afdr

strq

psxp0root[\[Z*m\Zi2EWXj	OhO*EOl
j	OhYhO[\[Zk\Zk2EO[\[Zk\Zi2EW
XEO,FOa-EOa,FOjvEOukjkha/EOa-E[ak/EQZ[al/EQZWXa%a%j	Oa%a%jEOa%a%%a%j%E[OYOa,FOaa,EOa ,EOa!,EWX"a#%a$%j	OhO4a%a&a'l(a)%E^Oa*a+,%a,%]a-,%jWX"a.%a/%j	OhO,a0%a1%]a-,%a2%jOa3%a4%j	WX"a5%a6%%a7%j	OhYa8a9,E^Oa ,EOa!,EWX"a:%a;%j	OhO]a<%%a=%E^O*a>a+,%a?%]%jOa@]%aA%j	WX"aB]%aC%%aD%j	OhYaE%aF%j	 !"
.aevtoappnull****
 k"##$$!"
0uri

dtxt
.sysodlogaskrTEXT

rslt

ttxt
.GURLGURLnullTEXT#EOhelO,EOj[OY%%6niji://apply?cmd=hi&name=hoascr
ޭ


INTEGRATION: CWS macosxpbuildrepair (1.2.14); FILE MERGED 2007/04/03 19:35:33 tra 1.2.14.1: #75972#fix Panther incompatibility

(*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: main.applescript,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 09:15:16 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser 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
 *
 *************************************************************************)

(*==== (global variables as get-functions) ====*)

on getOOInstallPath()
	-- return (((path to applications folder from system domain) as string) & "OpenOffice %PRODUCTVERSION.app:" & "Contents:MacOS:")
	return (((path to me) as string) & "Contents:MacOS:")
end getOOInstallPath

on getOOResourcesPath()
	return (((path to me) as string) & "Contents:Resources:")
end getOOResourcesPath

on getOOProgramPath()
	return (getOOInstallPath() & "program:")
end getOOProgramPath

on getScriptPath()
	-- set this to absolute path when debugging
	return (((path to me) as string) & "Contents:Resources:Scripts:")
end getScriptPath

on getOOUserSettingsPath()
	return (((path to home folder) as string) & "Library:Application Support:OpenOffice.org:%USERDIRPRODUCTVERSION:")
end getOOUserSettingsPath

on getOOUserFontPath()
	return (getOOUserSettingsPath() & "user:fonts:")
end getOOUserFontPath

on getUserLogsPath()
	return (((path to home folder) as string) & "Library:Logs:")
end getUserLogsPath

on shellTerminator()
	return (" &>/dev/null & echo $!") as string
end shellTerminator

--
-- the default handlers: run, open, idle, quit
--

on run
	if (preRun()) then
		logEvent("(Scripts/main) Running OpenOffice.org")
		openSoffice("-")
	end if
end run

on open (theFiles)
	if (preRun()) then
		openFiles(theFiles)
	end if
end open

on idle
	-- close icon only if ooo has terminated
	if (hasOOoQuit()) then
		tell me to quit
	end if
	-- check all x seconds if ok to quit
	return 3
end idle

on quit
	if (hasOOoQuit()) then
		continue quit
	end if
end quit

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

on preRun()

	-- Check for the required version of Mac OS X
	if (not atLeastOSXVersion(10, 3, 0)) then
		display dialog getMessage("ERROR_NEED_PANTHER")
		return false
	end if

	-- Check for that OOo can be found
	if (not isRealPath(getOOProgramPath())) then
		display dialog getMessage("ERROR_OOO_NOT_FOUND")
		return false
	end if

	if (not isRealPath(getOOUserFontPath())) then
		set createUserFont to "mkdir -p " & (quoted form of POSIX path of getOOUserFontPath()) & "; "
		do shell script createUserFont
	end if

	-- If no crash occured before, ~/Library/Logs does not exist, and OpenOffice.org cannot be started
	if (not isRealPath(getUserLogsPath())) then
		set createUserLogsPath to "mkdir -p " & (quoted form of POSIX path of getUserLogsPath()) & "; "
		do shell script createUserLogsPath
	end if

	-- Checks are ok, now do the PostInstall stuff (e.g. fondu)

	-- load helper library
	set postinstall to load script alias
		(getScriptPath() & "PostInstall.scpt")
	-- execute the postinstall script
	run of postinstall

	return true
end preRun

on hasOOoQuit()
	if (isRealPath(getOOProgramPath())) then
		-- set the location of soffice binary
		set soffice to (quoted form of (POSIX path of getOOProgramPath() & "soffice"))

		set isRunning to do shell script "_FOUND_=`ps -wx -o command | grep " & soffice & " | grep -v grep`; echo $_FOUND_"
		if isRunning  "" then
			return false
		else
			return true
		end if
	else
		return true
	end if
end hasOOoQuit

on openSoffice(aFile)
	set theDisplay to startXServer()
	if (theDisplay is equal to "error") then
		return
	end if
	set theEnv to "DISPLAY=" & theDisplay & " ; export DISPLAY; "
	set theCmd to "sh " & (quoted form of (POSIX path of getOOProgramPath() & "soffice")) & " "
	do shell script theEnv & theCmd & aFile & shellTerminator()
	-- logEvent("open CMD: " & theEnv & theCmd & aFile)
end openSoffice

-- helper function to start X11 server
on startXServer()

	-- get X settings
	set XSettingsList to findXServer()
	set whichserver to item 1 of XSettingsList
	set Xserverloc to item 2 of XSettingsList

	-- debug:
	-- logEvent("(scripts/main) X settings: " & whichserver & "--" & POSIX path of Xserverloc)
	-- set whichserver to "NOXSERVER"

	-- if nothing really was found, display an error message.
	if (whichserver is equal to "NOXSERVER") then

		display dialog getMessage("ERROR_NEED_X11") buttons {"Quit", "More Info"} default button "More Info"
		if the button returned of the result is "Quit" then
			quit
		else
			-- if more info is chosen, then open a help web page
			do shell script "open http://porting.openoffice.org/mac/faq/installing/X11.html"
			-- cannot continue, so quit the script
			return "error"
		end if

	end if

	set now_running to ""
	set now_running to do shell script "INX=`ps -wcx | grep  " & quoted form of (whichserver & "$") & "`; echo $INX"
	if whichserver = "NOXSERVER" then
		-- display dialog "No XServer Found"
		set now_running to "Skip"
	end if
	if now_running = "" then
		if whichserver = "X11" then
			set x11cmd to quoted form of (Xserverloc & "/Contents/MacOS/X11") & shellTerminator()
			do shell script x11cmd
			-- save process id
			set x11pid to the result
			-- wait until the window manager is started which is the second child process of x11
			set numchildrencmd to "ps -x -o ppid | grep " & x11pid & " | wc -l"
			set numchildren to 0
			set d to current date
			set t1 to time of d
			repeat while numchildren  2
				set d to current date
				set t2 to time of d
				-- give up after 30 seconds
				if t2 - t1 > 30 then
					display dialog "Command timed out"
					exit repeat
				end if
				set result to do shell script numchildrencmd
				set numchildren to result as integer
			end repeat
		else -- startup XDarwin
			do shell script "open " & quoted form of Xserverloc & shellTerminator()
			do shell script "sleep 4"
		end if
	end if
	if whichserver is equal to "X11" then
		-- the DISPLAY variable is different for every user currently logged in
		-- X11 passes the DISPLAY as the last command line parameter to its child process
		-- we can use ps to read the command line and parse the trailing :0, :1, or whatever
		set xdisplay to do shell script "ps -wx -o command | grep X11.app | grep \":.$\" | sed \"s/^.*:/:/g\""
		--display dialog xdisplay
		return xdisplay
	else
		-- TODO: find out how XDarwin does it
		return ":0"
	end if
end startXServer

on openFiles(fileList)
	if (count of fileList) > 0 then
		repeat with i from 1 to the count of fileList
			set theDocument to (item i of fileList)
			set theFilePath to (quoted form of POSIX path of theDocument)
			set theFileInfo to (info for theDocument)
			openSoffice(theFilePath)
			logEvent("(Scripts/main) Open file: " & theFilePath)
		end repeat
	end if
end openFiles

(* ===== (Helper functions) ======= *)

-- get a localized string
on getMessage(aKey)
	try
		if (aKey is equal to "YES_KEY") then
			return "Yes"
		end if

		if (aKey is equal to "NO_KEY") then
			return "No"
		end if

		if (aKey is equal to "ERROR_OOO_NOT_FOUND") then
			return "OpenOffice.org was not found on your system. Please (re-)install OpenOffice.org first."
		end if

		if (aKey is equal to "ERROR_NEED_PANTHER") then
			return "This build of OpenOffice.org cannot be run on this system, OpenOffice.org requires MacOSX 10.3 (Panther) or newer system"
		end if

		if (aKey is equal to "ERROR_NEED_X11") then
			return "OpenOffice.org for Mac OS X cannot be started, because the X11 software is not installed. Please install Apple X11 first from the Mac OS X install DVD. More information: http://porting.openoffice.org/mac/faq/installing/X11.html"
		end if
	end try
end getMessage

-- function for logging script messages
on logEvent(themessage)
	set theLine to (do shell script
		"date  +'%Y-%m-%d %H:%M:%S'" as string)
		& " " & themessage
	do shell script "echo " & quoted form of theLine &
		" >> ~/Library/Logs/OpenOffice%USERDIRPRODUCTVERSION.log"
end logEvent

-- function for checking if a path exists
on isRealPath(aPath)
	try
		alias aPath
		return true
	on error
		-- error number -43 from aPath
		-- display dialog "NotRP -- " & aPath
		return false
	end try
end isRealPath

-- try to find X11 server on the Mac OS X system
-- return value: the found server or "NOXSERVER"
on findXServer()
	-- First try standard X11 location, then try standard XDarwin location

	set whichserver to "NOXSERVER"
	--Utilities folder of system
	set Xserverloc to ((path to utilities folder from system domain) as string) & "X11.app:"
	--display dialog " Xserverloc" & Xserverloc
	if (isRealPath(Xserverloc)) then
		set whichserver to "X11"
		set Xserverloc to (POSIX path of Xserverloc)
	else
		--Applications folder of system
		set Xserverloc to ((path to applications folder from system domain) as string) & "XDarwin.app:"
		if (isRealPath(Xserverloc)) then
			set whichserver to "XDarwin"
			set Xserverloc to (POSIX path of Xserverloc)
		end if
	end if

	-- if nothing found yet try using locate, first with X11.app and then with XDarwin.app
	if (whichserver is equal to "NOXSERVER") then
		set Xserverloc to do shell script "locate X11.app/Contents/MacOS/X11 | sed -e 's-/Contents/MacOS/X11--g'"
		if Xserverloc  "" then
			set whichserver to "X11"
		end if
	end if

	if (whichserver is equal to "NOXSERVER") then
		set Xserverloc to do shell script "locate XDarwin.app/Contents/MacOS/XDarwin | sed -e 's-/Contents/MacOS/XDarwin--g'"
		if Xserverloc  "" then
			set whichserver to "XDarwin"
		end if
	end if

	return {whichserver, Xserverloc}
end findXServer

-- Test for a minimum version of Mac OS X
on atLeastOSXVersion(verMajor, verMinor, verStep)
	-- The StandardAdditions's 'system attribute' used to be the Finder's 'computer' command.
	tell application "Finder" to set sysv to (system attribute "sysv")

	-- Generate sysv-compatible number from given version
	set reqVer to ((verMajor div 10) * 4096 + (verMajor mod 10) * 256 + verMinor * 16 + verStep)

	-- DEBUGGING:
	-- display dialog ("RV:" & reqVer & " < " & sysv as string)

	-- set major to ((sysv div 4096) * 10 + (sysv mod 4096 div 256))
	-- set minor to (sysv mod 256 div 16)
	-- set step to (sysv mod 16)
	-- display dialog ("Your Mac OS X version: " & major & "." & minor & "." & step)

	if (reqVer > sysv) then
		return false
	else
		return true
	end if
end atLeastOSXVersion

(*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: main.applescript,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-26 14:57:12 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser 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
 *
 *************************************************************************)

(*==== (global variables as get-functions) ====*)

on getOOInstallPath()
	-- return (((path to applications folder from system domain) as string) & "OpenOffice %PRODUCTVERSION.app:" & "Contents:MacOS:")
	return (((path to me) as string) & "Contents:MacOS:")
end getOOInstallPath

on getOOResourcesPath()
	return (((path to me) as string) & "Contents:Resources:")
end getOOResourcesPath

on getOOProgramPath()
	return (getOOInstallPath() & "program:")
end getOOProgramPath

on getScriptPath()
	-- set this to absolute path when debugging
	return (((path to me) as string) & "Contents:Resources:Scripts:")
end getScriptPath

on getOOUserSettingsPath()
	return (((path to home folder) as string) & "Library:Application Support:OpenOffice.org:%USERDIRPRODUCTVERSION:")
end getOOUserSettingsPath

on getOOUserFontPath()
	return (getOOUserSettingsPath() & "user:fonts:")
end getOOUserFontPath

on getUserLogsPath()
	return (((path to home folder) as string) & "Library:Logs:")
end getUserLogsPath

on shellTerminator()
	return (" &>/dev/null & echo $!") as string
end shellTerminator

--
-- the default handlers: run, open, idle, quit
--

on run
	if (preRun()) then
		logEvent("(Scripts/main) Running OpenOffice.org")
		openSoffice("-")
	end if
end run

on open (theFiles)
	if (preRun()) then
		openFiles(theFiles)
	end if
end open

on idle
	-- close icon only if ooo has terminated
	if (hasOOoQuit()) then
		tell me to quit
	end if
	-- check all x seconds if ok to quit
	return 3
end idle

on quit
	if (hasOOoQuit()) then
		continue quit
	end if
end quit

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

on preRun()

	-- Check for the required version of Mac OS X
	if (not atLeastOSXVersion(10, 3, 0)) then
		display dialog getMessage("ERROR_NEED_PANTHER")
		return false
	end if

	-- Check for that OOo can be found
	if (not isRealPath(getOOProgramPath())) then
		display dialog getMessage("ERROR_OOO_NOT_FOUND")
		return false
	end if

	if (not isRealPath(getOOUserFontPath())) then
		set createUserFont to "mkdir -p " & (quoted form of POSIX path of getOOUserFontPath()) & "; "
		do shell script createUserFont
	end if

	-- If no crash occured before, ~/Library/Logs does not exist, and OpenOffice.org cannot be started
	if (not isRealPath(getUserLogsPath())) then
		set createUserLogsPath to "mkdir -p " & (quoted form of POSIX path of getUserLogsPath()) & "; "
		do shell script createUserLogsPath
	end if

	-- Checks are ok, now do the PostInstall stuff (e.g. fondu)

	-- load helper library
	set postinstall to load script alias
		(getScriptPath() & "PostInstall.scpt")
	-- execute the postinstall script
	run of postinstall

	return true
end preRun

on hasOOoQuit()
	if (isRealPath(getOOProgramPath())) then
		-- set the location of soffice binary
		set soffice to (quoted form of (POSIX path of getOOProgramPath() & "soffice"))

		set isRunning to do shell script "_FOUND_=`ps -wx -o command | grep " & soffice & " | grep -v grep`; echo $_FOUND_"
		if isRunning  "" then
			return false
		else
			return true
		end if
	else
		return true
	end if
end hasOOoQuit

on openSoffice(aFile)
	set theDisplay to startXServer()
	if (theDisplay is equal to "error") then
		return
	end if
	set theEnv to "DISPLAY=" & theDisplay & " ; export DISPLAY; "
	set theCmd to "sh " & (quoted form of (POSIX path of getOOProgramPath() & "soffice")) & " "
	do shell script theEnv & theCmd & aFile & shellTerminator()
	-- logEvent("open CMD: " & theEnv & theCmd & aFile)
end openSoffice

-- helper function to start X11 server
on startXServer()

	-- get X settings
	set XSettingsList to findXServer()
	set whichserver to item 1 of XSettingsList
	set Xserverloc to item 2 of XSettingsList

	-- debug:
	-- logEvent("(scripts/main) X settings: " & whichserver & "--" & POSIX path of Xserverloc)
	-- set whichserver to "NOXSERVER"

	-- if nothing really was found, display an error message.
	if (whichserver is equal to "NOXSERVER") then
		display dialog getMessage("ERROR_NEED_X11") buttons {"Quit", "More Info"} default button "More Info" cancel button "Quit" with icon stop
		-- if more info is chosen, then open a help web page
		do shell script "open http://porting.openoffice.org/mac/faq/installing/X11.html"
		-- cannot continue, so quit the script
		return "error"
	end if

	set now_running to ""
	set now_running to do shell script "INX=`ps -wcx | grep  " & quoted form of (whichserver & "$") & "`; echo $INX"
	if whichserver = "NOXSERVER" then
		-- display dialog "No XServer Found"
		set now_running to "Skip"
	end if
	if now_running = "" then
		if whichserver = "X11" then
			set x11cmd to quoted form of (Xserverloc & "/Contents/MacOS/X11") & shellTerminator()
			do shell script x11cmd
			-- save process id
			set x11pid to the result
			-- wait until the window manager is started which is the second child process of x11
			set numchildrencmd to "ps -x -o ppid | grep " & x11pid & " | wc -l"
			set numchildren to 0
			set d to current date
			set t1 to time of d
			repeat while numchildren  2
				set d to current date
				set t2 to time of d
				-- give up after 30 seconds
				if t2 - t1 > 30 then
					display dialog "Command timed out"
					exit repeat
				end if
				set result to do shell script numchildrencmd
				set numchildren to result as integer
			end repeat
		else -- startup XDarwin
			do shell script "open " & quoted form of Xserverloc & shellTerminator()
			do shell script "sleep 4"
		end if
	end if
	if whichserver is equal to "X11" then
		-- the DISPLAY variable is different for every user currently logged in
		-- X11 passes the DISPLAY as the last command line parameter to its child process
		-- we can use ps to read the command line and parse the trailing :0, :1, or whatever
		set xdisplay to do shell script "ps -wx -o command | grep X11.app | grep \":.$\" | sed \"s/^.*:/:/g\""
		--display dialog xdisplay
		return xdisplay
	else
		-- TODO: find out how XDarwin does it
		return ":0"
	end if
end startXServer

on openFiles(fileList)
	if (count of fileList) > 0 then
		repeat with i from 1 to the count of fileList
			set theDocument to (item i of fileList)
			set theFilePath to (quoted form of POSIX path of theDocument)
			set theFileInfo to (info for theDocument)
			openSoffice(theFilePath)
			logEvent("(Scripts/main) Open file: " & theFilePath)
		end repeat
	end if
end openFiles

(* ===== (Helper functions) ======= *)

-- get a localized string
on getMessage(aKey)
	try
		if (aKey is equal to "YES_KEY") then
			return "Yes"
		end if

		if (aKey is equal to "NO_KEY") then
			return "No"
		end if

		if (aKey is equal to "ERROR_OOO_NOT_FOUND") then
			return "OpenOffice.org was not found on your system. Please (re-)install OpenOffice.org first."
		end if

		if (aKey is equal to "ERROR_NEED_PANTHER") then
			return "This build of OpenOffice.org cannot be run on this system, OpenOffice.org requires MacOSX 10.3 (Panther) or newer system"
		end if

		if (aKey is equal to "ERROR_NEED_X11") then
			return "OpenOffice.org for Mac OS X cannot be started, because the X11 software is not installed. Please install Apple X11 first from the Mac OS X install DVD. More information: http://porting.openoffice.org/mac/faq/installing/X11.html"
		end if
	end try
end getMessage

-- function for logging script messages
on logEvent(themessage)
	set theLine to (do shell script
		"date  +'%Y-%m-%d %H:%M:%S'" as string)
		& " " & themessage
	do shell script "echo " & quoted form of theLine &
		" >> ~/Library/Logs/OpenOffice%USERDIRPRODUCTVERSION.log"
end logEvent

-- function for checking if a path exists
on isRealPath(aPath)
	try
		alias aPath
		return true
	on error
		-- error number -43 from aPath
		-- display dialog "NotRP -- " & aPath
		return false
	end try
end isRealPath

-- try to find X11 server on the Mac OS X system
-- return value: the found server or "NOXSERVER"
on findXServer()
	-- First try standard X11 location, then try standard XDarwin location

	set whichserver to "NOXSERVER"
	--Utilities folder of system
	set Xserverloc to ((path to utilities folder from system domain) as string) & "X11.app:"
	--display dialog " Xserverloc" & Xserverloc
	if (isRealPath(Xserverloc)) then
		set whichserver to "X11"
		set Xserverloc to (POSIX path of Xserverloc)
	else
		--Applications folder of system
		set Xserverloc to ((path to applications folder from system domain) as string) & "XDarwin.app:"
		if (isRealPath(Xserverloc)) then
			set whichserver to "XDarwin"
			set Xserverloc to (POSIX path of Xserverloc)
		end if
	end if

	-- if nothing found yet try using locate, first with X11.app and then with XDarwin.app
	if (whichserver is equal to "NOXSERVER") then
		set Xserverloc to do shell script "locate X11.app/Contents/MacOS/X11 | sed -e 's-/Contents/MacOS/X11--g'"
		if Xserverloc  "" then
			set whichserver to "X11"
		end if
	end if

	if (whichserver is equal to "NOXSERVER") then
		set Xserverloc to do shell script "locate XDarwin.app/Contents/MacOS/XDarwin | sed -e 's-/Contents/MacOS/XDarwin--g'"
		if Xserverloc  "" then
			set whichserver to "XDarwin"
		end if
	end if

	return {whichserver, Xserverloc}
end findXServer

-- Test for a minimum version of Mac OS X
on atLeastOSXVersion(verMajor, verMinor, verStep)
	-- The StandardAdditions's 'system attribute' used to be the Finder's 'computer' command.
	tell application "Finder" to set sysv to (system attribute "sysv")

	-- Generate sysv-compatible number from given version
	set reqVer to ((verMajor div 10) * 4096 + (verMajor mod 10) * 256 + verMinor * 16 + verStep)

	-- DEBUGGING:
	-- display dialog ("RV:" & reqVer & " < " & sysv as string)

	-- set major to ((sysv div 4096) * 10 + (sysv mod 4096 div 256))
	-- set minor to (sysv mod 256 div 16)
	-- set step to (sysv mod 16)
	-- display dialog ("Your Mac OS X version: " & major & "." & minor & "." & step)

	if (reqVer > sysv) then
		return false
	else
		return true
	end if
end atLeastOSXVersion


Huge update! More in the description.

Huge update! More in the description.

– Hopefuly fixing issue #5 (crash on Spotify updates)
– Improved general stability
– Added optional logging functionality
– General code cleanup
– Removed some redundant comments

property debug : false
property currentVolume : null

if (my isTheFirstRun() = true and my isInLoginItems() = false) then
	set userAnswer to the button returned of (display dialog "Hi, thanks for installing Spotifree!" &
		return & "Just so you know, Spotifree has no interface yet, and will work silently in the background." & return & return
		& "BTW, do you want it to run automatically on startup?" with title
		"You are awesome!" with icon 1 buttons {"No, thanks", "OK"} default button 2)
	if (userAnswer = "OK") then
		try
			my addToLoginItems()
		end try
	end if
	try
		-- Save in the preferences that Spotifree has already ran.
		do shell script "defaults write com.ArtemGordinsky.Spotifree 'hasRanBefore' 'true'"
	end try
end if

repeat
	try
		if (isRunning() and isPlaying() and isAnAd()) then
			try
				mute()
			end try
			repeat
				try
					if (isAnAd() = false) then
						-- Have to delay a little bit, because Spotify may tell us about the next track too early,
						-- and a user has to hear the last half-second of an ad.
						delay 0.8
						unmute()
						exit repeat
					end if
				end try
				delay 0.3
			end repeat
		else
			-- Delaying, to get less of the crashing "connection is invalid" errors.
			delay 1
		end if
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "some unhandled error in the outer loop.")
	end try
	-- This is how fast we are polling Spotify.
	-- The only speed at which you will hear almost no sounds passing through.
	-- Fortunately, even combined with the added load on Spotify, the CPU usage is rather miniscule.
	delay 0.3
end repeat

on mute()
	try
		tell application "Spotify"
			set currentVolume to sound volume
			-- This is the only way possible to mute Spotify during an advertisement.
			-- Otherwise it pauses when you mute the sound.
			pause
			set sound volume to 0
			play
		end tell
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "trying to mute Spotify.")
	end try
	return
end mute

on unmute()
	try
		tell application "Spotify"
			-- Restore the volume to the level supplied to the parameter.
			set sound volume to currentVolume
		end tell
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "trying to restore Spotify's volume.")
	end try
	return
end unmute

on isAnAd()
	local currentTrackPopularity, currentTrackDuration
	set currentTrackPopularity to null
	set currentTrackDuration to null
	try
		tell application "Spotify"
			set currentTrackPopularity to popularity of current track
			set currentTrackDuration to duration of current track
		end tell
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "trying to get popularity and duration of the current track.")
		return false
	end try
	if ((currentTrackPopularity  null and currentTrackDuration  null) and (currentTrackPopularity = 0 and currentTrackDuration  40)) then
		return true
	else
		return false
	end if
end isAnAd

on isPlaying()
	local playerState
	set playerState to null
	-- Adding a 5 seconds timeout instead of default 2 min. Prevents long unresponsiveness of the app.
	with timeout of (5) seconds
		try
			tell application "Spotify"
				set playerState to player state
			end tell
		on error errorMessage number errorNumber
			my log_error(errorNumber, errorMessage, "counting Spotify processes.")
			return false
		end try
	end timeout
	if (playerState  null and playerState = constant ****kPSP) then
		return true
	else
		return false
	end if
end isPlaying

on isRunning()
	local spotifyProcesses
	-- Adding a 5 seconds timeout instead of default 2 min. Prevents long unresponsiveness of the app.
	with timeout of (5) seconds
		try
			tell application "System Events"
				set spotifyProcesses to (count of (every process whose name is "Spotify"))
			end tell
		on error errorMessage number errorNumber
			my log_error(errorNumber, errorMessage, "counting Spotify processes.")
			return false
		end try
	end timeout
	if spotifyProcesses = 1 then
		return true
	else
		return false
	end if
end isRunning

on addToLoginItems()
	try
		tell application "System Events"
			-- Add Spotifree to the Login Items.
			make login item at end with properties {name:"Spotifree", path:"/Applications/Spotifree.app", hidden:true}
		end tell
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "adding Spotifree to the Login Items")
		return
	end try
end addToLoginItems

on isTheFirstRun()
	try
		-- Get the value of the key 'hasRanBefore' in the file "~/Library/Preferences/com.ArtemGordinsky.Spotifree"
		set hasRanBefore to do shell script "defaults read com.ArtemGordinsky.Spotifree 'hasRanBefore'"
	on error errorMessage number errorNumber
		-- If the file not there yet, an error is going to be thrown. So it's the first run, probably.
		-- We are going to return 'true' even if it was some other error. Not a big deal, after all.
		my log_error(errorNumber, errorMessage, "checking is Spotify being run the first time.")
		return true
	end try

	if (hasRanBefore = "true") then
		return true
	else
		return false
	end if
end isTheFirstRun

on isInLoginItems()
	try
		tell application "System Events"
			if login item "Spotifree" exists then
				return true
			else
				return false
			end if
		end tell
	on error errorMessage number errorNumber
		my log_error(errorNumber, errorMessage, "checking if Spotify is in Login Items")
		return false
	end try
end isInLoginItems

on log_message(message)
	local content
	set content to (return &
		"-----------------------------------------------------------" &
		return & my dateAndTime() & return & message & return
		& "-----------------------------------------------------------" & return)
	set log_file to (((path to desktop folder) as text) & "Spotifree_log.txt")
	my write_to_file(content, log_file, true)
end log_message

on log_error(error_number, error_message, diag_message)
	local content
	if (debug = true) then
		set content to (return & "-----------------------------------------------------------" &
			return & my dateAndTime() & return & "Error number: " & error_number
			& return & "Error message: " & error_message & return &
			"Diagnostic message: " & diag_message & return
			& "-----------------------------------------------------------" & return)
		set log_file to (((path to desktop folder) as text) & "Spotifree_log.txt")
		my write_to_file(content, log_file, true)
	end if
end log_error

on write_to_file(this_data, target_file, append_data) -- (string, file path as string, boolean)
	try
		set the target_file to the target_file as text
		set the open_target_file to
			open for access file target_file with write permission
		if append_data is false then
			set eof of the open_target_file to 0
		write this_data to the open_target_file starting at eof
		close access the open_target_file
		return true
	on error
		try
			close access file target_file
		end try
	end try
end write_to_file

on dateAndTime()
	set currentDateAndTime to (current date) as string
	return currentDateAndTime
end dateAndTime

-- Setting the "playing" property to the constant returned by Spotify as a "player state" when it's playing.
property playing : constant ****kPSP
global currentVolume

-- Check if Spotifree is being run the first time and is in Login Items.
if (my isTheFirstRun() = true and my isInLoginItems() = false) then
	-- Tell the user how Spotifree runs and ask if he wants Spotifree to run automatically on startup.
	-- Assign a result to the variable 'userAnswer'.
	set userAnswer to the button returned of (display dialog "Hi, thanks for installing Spotifree!" &
		return & "Just so you know, Spotifree has no interface yet, and will work silently in the background." & return & return
		& "BTW, do you want it to run automatically on startup?" with title
		"You are awesome!" with icon 1 buttons {"No, thanks", "OK"} default button 2)
	-- Check if user agreed.
	if (userAnswer = "OK") then
		try
			-- Add Spotifree to the Login Items.
			my addToLoginItems()
		end try
	end if
	try
		-- Save in the preferences that Spotifree has already ran.
		do shell script "defaults write com.ArtemGordinsky.Spotifree 'hasRanBefore' 'true'"
	end try
end if

repeat
	try
		-- Checking if Spotify is running, playing, and if current track is an advertisement.
		if (isRunning() and isPlaying() and isAnAd()) then
			try
				-- Mute Spotify.
				mute()
			end try
			repeat
				try
					-- Check if current track is an ad. Or if Spotify was paused during an advertisement.
					if (isAnAd()) then
						-- If Spotify was paused, or there is a second ad, this loop will continue to repeat.
					else
						-- If there's no more ads, pause for .5 seconds to let Spotify respond.
						-- Then, unmute and exit the loop.
						delay 0.5
						unmute()
						exit repeat
					end if
				end try
				delay 0.3
			end repeat
		end if
	end try
	-- This is how fast we are polling Spotify.
	-- The only speed at which you will hear no sounds passing through.
	-- Fortunately, combined with the added load on Spotify, the CPU usage stays well below 1% even on an old dual-core 3.6 GHz processor.
	delay 0.3
end repeat

on mute()
	try
		tell application "Spotify"
			-- Get the current sound volume from Spotify and save it in a variable currentVolume.
			set currentVolume to sound volume
			-- This is the only way possible to mute Spotify during an advertisement. Otherwise it pauses when you mute the sound.
			pause
			set sound volume to 0
			play
		end tell
	end try
	return
end mute

on unmute()
	try
		tell application "Spotify"
			-- Restore the volume to the level supplied to the parameter.
			set sound volume to currentVolume
		end tell
	end try
	return
end unmute

on isAnAd()
	local currentTrackPopularity, currentTrackDuration
	try
		tell application "Spotify"
			-- Get the popularity of a current track and save it in a variable currentTrackPopularity.
			set currentTrackPopularity to popularity of current track
			-- Get the duration of current track and save it in a variable currentTrackDuration.
			set currentTrackDuration to duration of current track
		end tell
	on error
		return false
	end try
	-- If current track's popularity is 0 and its duration is 40 seconds or less, then it's almost certainly an ad.
	if (currentTrackPopularity = 0 and currentTrackDuration  40) then
		return true
	else
		return false
	end if
end isAnAd

on isPlaying()
	local playerState
	try
		tell application "Spotify"
			-- Hook the variable playerState to Spotify's state (playing, paused etc.).
			set playerState to player state
		end tell
	on error
		return false
	end try
	-- Compare Spotify's state with a constant saved in the property on line 1.
	if playerState = playing then
		return true
	else
		return false
	end if
end isPlaying

on isRunning()
	local spotifyProcesses
	try
		tell application "System Events"
			-- Check if there are any Spotify processes. Set to variable spotifyProcesses
			set spotifyProcesses to (count of (every process whose bundle identifier is "com.spotify.client"))
		end tell
	on error
		return false
	end try
	-- Check the variable spotifyProcesses, to see is Spotify running.
	if spotifyProcesses  0 then
		return true
	else
		return false
	end if
end isRunning

on addToLoginItems()
	try
		tell application "System Events"
			-- Add Spotifree to the Login Items.
			make login item at end with properties {name:"Spotifree", path:"/Applications/Spotifree.app", hidden:true}
		end tell
	on error
		return
	end try
end addToLoginItems

on isTheFirstRun()
	try
		-- Get the value of the key 'hasRanBefore' in the file "~/Library/Preferences/com.ArtemGordinsky.Spotifree"
		set hasRanBefore to do shell script "defaults read com.ArtemGordinsky.Spotifree 'hasRanBefore'"
	on error
		-- If the file not there yet, an error is going to be thrown. So it's the first run, probably.
		-- We are going to return 'true' even if it was some other error. Not a big deal, after all.
		return true
	end try

	if (hasRanBefore  "true") then
		return true
	else
		return false
	end if
end isTheFirstRun

on isInLoginItems()
	try
		-- Ask 'System Events' is 'Spotifree' is in 'Login Items'.
		tell application "System Events"
			if login item "Spotifree" exists then
				return true
			else
				return false
			end if
		end tell
	on error
		return false
	end try
end isInLoginItems


update

update

global num_servers
set num_servers to 12

on open_window_tabs()
	tell application "Terminal"
		activate
		-- Open a new window
		--   http://superuser.com/questions/195633/applescript-to-open-a-new-terminal-window-in-current-space
		do script "clear"
		-- set currentWindow to front window

		-- Open new tabs
		repeat (num_servers * 2 - 1) times
			tell application "System Events" to tell process "Terminal" to keystroke "t" using command down
		end repeat
	end tell
end open_window_tabs

on ssh()
	tell application "Terminal"
		set currentWindow to front window

		-- Without the delay, some connections are not made.
		set delay_after_ssh to 0.5

		set tab_id to 0
		set s_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "sshs" & s_id
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set tab_id to tab_id + 1
			set cmd to "sshc" & s_id
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set s_id to s_id + 1
		end repeat
	end tell
end ssh

on screen()
	tell application "Terminal"
		set currentWindow to front window

		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "screen"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to " "
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end screen

on install_pkgs_0()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "sudo add-apt-repository -y ppa:webupd8team/java && sudo apt-get update && sudo apt-get install oracle-java8-installer git ctags ant htop tree maven gnuplot-nox ntp ioping realpath make gcc cmake g++ libboost-dev libboost-system-dev libboost-timer-dev collectl -y && sudo apt-get autoremove -y vim-tiny && mkdir -p ~/work && cd ~/work && git clone https://github.com/hoytech/vmtouch.git && cd vmtouch && make -j && sudo make install && sudo service ntp stop && sudo ntpdate -bv 0.ubuntu.pool.ntp.org && sudo service ntp start && cd ~/work && git clone git@github.com:hobinyoon/linux-home.git && cd linux-home && ./setup-linux.sh"
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end install_pkgs_0

on install_pkgs_1()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to key code 36 -- enter
		delay 0.2
		tell application "System Events" to key code 123 -- left
		tell application "System Events" to key code 36 -- enter
		tell application "System Events" to key code 124 using {shift down, command down} -- move to the next tab
		delay 0.1
	end repeat
end install_pkgs_1

-- Sometimes the previous step takes forever. Need to make sure.
on install_pkgs_2()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "yes"
			do script (cmd) in tab tab_id of currentWindow
			delay 0.1
		end repeat
	end tell
end install_pkgs_2

on exit_screen()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "d" using {control down}
		delay 0.1

		-- Move to the right
		tell application "System Events" to key code 124 using {shift down, command down}

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "d" using {control down}
		delay 0.1

		-- Move to the right
		tell application "System Events" to key code 124 using {shift down, command down}
	end repeat
end exit_screen

on server_screen_split_htop()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "htop"
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "watch -n 0.5 \"free -mt\""
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move 2 to the right, since S and C take turns.
		--   124: right arrow
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_screen_split_htop

on client_screen_split_htop()
	tell application "Terminal" to activate
	set tab_id to 0
	-- Start from the 2nd tab, which is the first client tab
	tell application "System Events" to key code 124 using {shift down, command down}
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "htop"
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move 2 to the right, since S and C take turns.
		--   124: right arrow
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	-- Set the current tab to the 1st one
	tell application "System Events" to key code 123 using {shift down, command down}

end client_screen_split_htop

on build_cass_pressuremem_loadgen()
	tell application "Terminal"
		set currentWindow to front window

		-- Without the delay, some connections are not made.
		set delay_after_ssh to 0.2

		set tab_id to 0
		set s_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "cd ~/work && git clone git@github.com:hobinyoon/apache-cassandra-2.2.3-src.git && ln -s ~/work/apache-cassandra-2.2.3-src ~/work/cassandra && cd ~/work/cassandra/mtdb/tools/pressure-memory && mkdir -p .build && cd .build && cmake .. && make -j && cdcass && time ant"
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set tab_id to tab_id + 1
			set cmd to "cd ~/work && git clone git@github.com:hobinyoon/apache-cassandra-2.2.3-src.git && ln -s ~/work/apache-cassandra-2.2.3-src ~/work/cassandra && cd ~/work/cassandra/mtdb/loadgen && ./loadgen"
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set s_id to s_id + 1
		end repeat
	end tell
end build_cass_pressuremem_loadgen

on git_pull()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "c" using {control down}

		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "cdcass && git pull"
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end git_pull

on server_format_ebs_mag_mount_prepare_dirs()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "sudo mkfs.ext4 -m 0 /dev/xvdd && sudo cp ~/work/cassandra/mtdb/ec2-tools/etc-fstab /etc/fstab && sudo umount /mnt && sudo mkdir -p /mnt/local-ssd && sudo mount /mnt/local-ssd && sudo chown -R ubuntu /mnt/local-ssd && mkdir /mnt/local-ssd/cass-data && mkdir ~/cass-data-vol && sudo ln -s ~/cass-data-vol /mnt/ebs-ssd-gp2 && mkdir /mnt/ebs-ssd-gp2/cass-data && sudo mkdir -p /mnt/ebs-mag && sudo mount /mnt/ebs-mag && sudo mkdir /mnt/ebs-mag/cass-data && sudo chown -R ubuntu /mnt/ebs-mag && sudo chown -R ubuntu /mnt/ebs-mag/cass-data && sudo mkdir -p /mnt/ebs-ssd-gp2/mtdb-cold && (sudo mkdir -p /mnt/ebs-mag/mtdb-cold || true) && sudo ln -s /mnt/ebs-mag /mnt/cold-storage && sudo chown -R ubuntu /mnt/ebs-ssd-gp2 && sudo chown -R ubuntu /mnt/cold-storage && sudo chown -R ubuntu /mnt/cold-storage/mtdb-cold && mkdir -p ~/work/cassandra/mtdb/logs/collectl && ln -s /mnt/local-ssd/cass-data ~/work/cassandra/data"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_format_ebs_mag_mount_prepare_dirs

on watch_free_mem()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "watch -n 0.5 \"free -mt\""
		tell application "System Events" to key code 36
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end watch_free_mem

on server_edit_cassandra_yaml()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			--			set cmd to "sed -i -r 's/^    migrate_to_cold_storage:.+/    migrate_to_cold_storage: true/' ~/work/cassandra/conf/cassandra.yaml"
			set cmd to "sed -i -r 's/^    migrate_to_cold_storage:.+/    migrate_to_cold_storage: false/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to "sed -i -r 's/^    tablet_coldness_threshold:.+/    tablet_coldness_threshold: 75/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_edit_cassandra_yaml

on client_edit_cassandra_yaml()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 2
		repeat until tab_id > (num_servers * 2)
			set cmd to "sed -i -r 's/^        num_writes_per_simulation_time_mins:.+/        num_writes_per_simulation_time_mins: " & (tab_id * 5000) & "/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to "grep num_writes_per_simulation_time_mins: ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next client tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end client_edit_cassandra_yaml

on save_screen_layout()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke ":layout save default"
		tell application "System Events" to key code 36

		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end save_screen_layout

-- One-time fix. Won't need again
on mkdir_collectl()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "mkdir ~/work/cassandra/mtdb/logs/collectl"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end mkdir_collectl

on run_server()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "sudo -- sh -c 'echo 1 > /proc/sys/vm/drop_caches' && cdcass && time ant && rm -rf ~/work/cassandra/data/* && rm -rf /mnt/cold-storage/mtdb-cold/* && (killall mon-num-cass-threads.sh >/dev/null 2>&1 || true) && (~/work/cassandra/mtdb/tools/mon-num-cass-threads.sh &) && (killall collectl >/dev/null 2>&1 || true) && ((collectl -i 1 -sCDN -oTm > ~/work/cassandra/mtdb/logs/collectl/collectl-`date +'%y%m%d-%H%M%S'` 2>/dev/null) &) && bin/cassandra -f | grep --color -E '^|MTDB:'"
			do script (cmd) in tab tab_id of currentWindow
			-- Give enough delay to make sure the logs have different datetimes.
			delay 3

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end run_server

on server_pressure_memory()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "cd ~/work/cassandra/mtdb/tools/pressure-memory/.build"
			set cmd to cmd & " && (./pressure-memory &)"
			set cmd to cmd & " && watchsstables"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_pressure_memory

on client_run_loadgen()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 2
		repeat until tab_id > (num_servers * 2)
			set cmd to "cd ~/work/cassandra/mtdb/loadgen && ./create-db.sh && ./loadgen"
			do script (cmd) in tab tab_id of currentWindow
			-- Make sure we get different exp datetime
			delay 2
			-- Go to the next client tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end client_run_loadgen

on screen_detach()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "d"
		delay 0.1
		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
	end repeat
end screen_detach

on screen_reattach()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "screen -r"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next tab
			set tab_id to tab_id + 1
		end repeat
	end tell
end screen_reattach

on server_get_client_logs_and_process()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "c" using {control down}

		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "(killall pressure-memory > /dev/null 2>&1 || true) && (sudo killall collectl > /dev/null 2>&1 || true) && (sudo killall mon-num-cass-threads.sh > /dev/null 2>&1 || true) && rsync -ave \"ssh -o StrictHostKeyChecking=no\" $CASSANDRA_CLIENT_ADDR:work/cassandra/mtdb/logs/loadgen ~/work/cassandra/mtdb/logs && cd ~/work/cassandra/mtdb/process-log/calc-cost-latency-plot-tablet-timeline && (\\rm *.pdf || true) && ./plot-cost-latency-tablet-timelines.py && du -hs ~/work/cassandra/data/"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_get_client_logs_and_process

-- One-time fix. Won't need again
on server_rename_client_log()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			-- I don't like the float division. oh well.
			set cmd to "mv ~/work/cassandra/mtdb/logs/loadgen/160302-023811 ~/work/cassandra/mtdb/logs/loadgen/160302-023811-" & ((tab_id - 1) / 2) & " && mv ~/work/cassandra/mtdb/logs/cassandra/160302-023811 ~/work/cassandra/mtdb/logs/cassandra/160302-023811-" & ((tab_id - 1) / 2)
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_rename_client_log

-- One-time use.
on server_kill_monitor_processes()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "(killall pressure-memory > /dev/null 2>&1 || true) && (sudo killall collectl > /dev/null 2>&1 || true) && (sudo killall mon-num-cass-threads.sh > /dev/null 2>&1 || true)"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_kill_monitor_processes

-- One-time use.
on server_data_dir_to_ebs_mag()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "cdcass"
			set cmd to cmd & " && \\rm data"
			set cmd to cmd & " && ln -s /mnt/ebs-mag/cass-data data"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_data_dir_to_ebs_mag

on open_window_tabs_ssh_screen()
	my open_window_tabs()
	my ssh()
	my screen()
end open_window_tabs_ssh_screen

on run_all()
	my open_window_tabs_ssh_screen()

	my install_pkgs_0()
	my install_pkgs_1()
	my install_pkgs_2()

	-- Not a normal process. In case something goes wrong.
	-- my exit_screen()

	-- These can be grouped
	my server_screen_split_htop()
	my client_screen_split_htop()
	my build_cass_pressuremem_loadgen()

	-- In case needed
	-- my git_pull()

	-- These can be grouped
	my server_format_ebs_mag_mount_prepare_dirs()
	my watch_free_mem()
	-- Make sure which experiment you want, by editing migrate_to_cold_storage
	my server_edit_cassandra_yaml()
	my client_edit_cassandra_yaml()
	my save_screen_layout()

	-- This takes like 40 secs. Do not move focus to anywhere else, or it will fail.
	my run_server()

	my server_pressure_memory()

	my client_run_loadgen()

	my screen_detach()
	my screen_reattach()

	my server_get_client_logs_and_process()

	-- Switch data directory
	-- my server_data_dir_to_ebs_mag()
end run_all

my screen_detach()

global num_servers
set num_servers to 12

on open_window_tabs()
	tell application "Terminal"
		activate
		-- Open a new window
		--   http://superuser.com/questions/195633/applescript-to-open-a-new-terminal-window-in-current-space
		do script "clear"
		-- set currentWindow to front window

		-- Open new tabs
		repeat (num_servers * 2 - 1) times
			tell application "System Events" to tell process "Terminal" to keystroke "t" using command down
		end repeat
	end tell
end open_window_tabs

on ssh()
	tell application "Terminal"
		set currentWindow to front window

		-- Without the delay, some connections are not made.
		set delay_after_ssh to 0.5

		set tab_id to 0
		set s_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "sshs" & s_id
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set tab_id to tab_id + 1
			set cmd to "sshc" & s_id
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set s_id to s_id + 1
		end repeat
	end tell
end ssh

on screen()
	tell application "Terminal"
		set currentWindow to front window

		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "screen"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to " "
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end screen

on install_pkgs_0()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "sudo add-apt-repository -y ppa:webupd8team/java && sudo apt-get update && sudo apt-get install oracle-java8-installer git ctags ant htop tree maven gnuplot-nox ntp ioping realpath make gcc cmake g++ libboost-dev libboost-system-dev libboost-timer-dev collectl -y && sudo apt-get autoremove -y vim-tiny && mkdir -p ~/work && cd ~/work && git clone https://github.com/hoytech/vmtouch.git && cd vmtouch && make -j && sudo make install && sudo service ntp stop && sudo ntpdate -bv 0.ubuntu.pool.ntp.org && sudo service ntp start && cd ~/work && git clone git@github.com:hobinyoon/linux-home.git && cd linux-home && ./setup-linux.sh"
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end install_pkgs_0

on install_pkgs_1()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to key code 36 -- enter
		delay 0.2
		tell application "System Events" to key code 123 -- left
		tell application "System Events" to key code 36 -- enter
		tell application "System Events" to key code 124 using {shift down, command down} -- move to the next tab
		delay 0.1
	end repeat
end install_pkgs_1

-- Sometimes the previous step takes forever. Need to make sure.
on install_pkgs_2()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "yes"
			do script (cmd) in tab tab_id of currentWindow
			delay 0.1
		end repeat
	end tell
end install_pkgs_2

on exit_screen()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "X"

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "d" using {control down}
		delay 0.1

		-- Move to the right
		tell application "System Events" to key code 124 using {shift down, command down}

		tell application "System Events" to keystroke "d" using {control down}
		tell application "System Events" to keystroke "d" using {control down}
		delay 0.1

		-- Move to the right
		tell application "System Events" to key code 124 using {shift down, command down}
	end repeat
end exit_screen

on server_screen_split_htop()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "htop"
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "watch -n 0.5 \"free -mt\""
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move 2 to the right, since S and C take turns.
		--   124: right arrow
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_screen_split_htop

on client_screen_split_htop()
	tell application "Terminal" to activate
	set tab_id to 0
	-- Start from the 2nd tab, which is the first client tab
	tell application "System Events" to key code 124 using {shift down, command down}
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "S"
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "c"
		tell application "System Events" to keystroke "htop"
		tell application "System Events" to key code 36

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move 2 to the right, since S and C take turns.
		--   124: right arrow
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	-- Set the current tab to the 1st one
	tell application "System Events" to key code 123 using {shift down, command down}

end client_screen_split_htop

on build_cass_pressuremem_loadgen()
	tell application "Terminal"
		set currentWindow to front window

		-- Without the delay, some connections are not made.
		set delay_after_ssh to 0.2

		set tab_id to 0
		set s_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "cd ~/work && git clone git@github.com:hobinyoon/apache-cassandra-2.2.3-src.git && ln -s ~/work/apache-cassandra-2.2.3-src ~/work/cassandra && cd ~/work/cassandra/mtdb/tools/pressure-memory && mkdir -p .build && cd .build && cmake .. && make -j && cdcass && time ant"
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set tab_id to tab_id + 1
			set cmd to "cd ~/work && git clone git@github.com:hobinyoon/apache-cassandra-2.2.3-src.git && ln -s ~/work/apache-cassandra-2.2.3-src ~/work/cassandra && cd ~/work/cassandra/mtdb/loadgen && ./loadgen"
			do script (cmd) in tab tab_id of currentWindow
			delay delay_after_ssh

			set s_id to s_id + 1
		end repeat
	end tell
end build_cass_pressuremem_loadgen

on git_pull()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "c" using {control down}

		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 0
		repeat until tab_id is (num_servers * 2)
			set tab_id to tab_id + 1
			set cmd to "cdcass && git pull"
			do script (cmd) in tab tab_id of currentWindow
		end repeat
	end tell
end git_pull

on server_format_ebs_mag_mount_prepare_dirs()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "sudo mkfs.ext4 -m 0 /dev/xvdd && sudo cp ~/work/cassandra/mtdb/ec2-tools/etc-fstab /etc/fstab && sudo umount /mnt && sudo mkdir -p /mnt/local-ssd && sudo mount /mnt/local-ssd && sudo chown -R ubuntu /mnt/local-ssd && mkdir /mnt/local-ssd/cass-data && mkdir ~/cass-data-vol && sudo ln -s ~/cass-data-vol /mnt/ebs-ssd-gp2 && mkdir /mnt/ebs-ssd-gp2/cass-data && sudo mkdir -p /mnt/ebs-mag && sudo mount /mnt/ebs-mag && sudo mkdir /mnt/ebs-mag/cass-data && sudo chown -R ubuntu /mnt/ebs-mag && sudo chown -R ubuntu /mnt/ebs-mag/cass-data && sudo mkdir -p /mnt/ebs-ssd-gp2/mtdb-cold && (sudo mkdir -p /mnt/ebs-mag/mtdb-cold || true) && sudo ln -s /mnt/ebs-mag /mnt/cold-storage && sudo chown -R ubuntu /mnt/ebs-ssd-gp2 && sudo chown -R ubuntu /mnt/cold-storage && sudo chown -R ubuntu /mnt/cold-storage/mtdb-cold && mkdir -p ~/work/cassandra/mtdb/logs/collectl && ln -s /mnt/local-ssd/cass-data ~/work/cassandra/data"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_format_ebs_mag_mount_prepare_dirs

on watch_free_mem()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "watch -n 0.5 \"free -mt\""
		tell application "System Events" to key code 36
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab

		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end watch_free_mem

on server_edit_cassandra_yaml()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			--			set cmd to "sed -i -r 's/^    migrate_to_cold_storage:.+/    migrate_to_cold_storage: true/' ~/work/cassandra/conf/cassandra.yaml"
			set cmd to "sed -i -r 's/^    migrate_to_cold_storage:.+/    migrate_to_cold_storage: false/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to "sed -i -r 's/^    tablet_coldness_threshold:.+/    tablet_coldness_threshold: 75/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_edit_cassandra_yaml

on client_edit_cassandra_yaml()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 2
		repeat until tab_id > (num_servers * 2)
			set cmd to "sed -i -r 's/^        num_writes_per_simulation_time_mins:.+/        num_writes_per_simulation_time_mins: " & (tab_id * 5000) & "/' ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow
			set cmd to "grep num_writes_per_simulation_time_mins: ~/work/cassandra/conf/cassandra.yaml"
			do script (cmd) in tab tab_id of currentWindow

			-- Go to the next client tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end client_edit_cassandra_yaml

on save_screen_layout()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1

		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke ":layout save default"
		tell application "System Events" to key code 36

		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end save_screen_layout

-- One-time fix. Won't need again
on mkdir_collectl()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "mkdir ~/work/cassandra/mtdb/logs/collectl"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end mkdir_collectl

on run_server()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "sudo -- sh -c 'echo 1 > /proc/sys/vm/drop_caches' && cdcass && time ant && rm -rf ~/work/cassandra/data/* && rm -rf /mnt/cold-storage/mtdb-cold/* && (killall mon-num-cass-threads.sh >/dev/null 2>&1 || true) && (~/work/cassandra/mtdb/tools/mon-num-cass-threads.sh &) && (killall collectl >/dev/null 2>&1 || true) && ((collectl -i 1 -sCDN -oTm > ~/work/cassandra/mtdb/logs/collectl/collectl-`date +'%y%m%d-%H%M%S'` 2>/dev/null) &) && bin/cassandra -f | grep --color -E '^|MTDB:'"
			do script (cmd) in tab tab_id of currentWindow
			-- Give enough delay to make sure the logs have different datetimes.
			delay 4

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end run_server

on server_pressure_memory()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "cd ~/work/cassandra/mtdb/tools/pressure-memory && mkdir -p .build && cd .build && cmake ..  && make -j && (./pressure-memory &) && watchsstables"
			do script (cmd) in tab tab_id of currentWindow
			delay 1

			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_pressure_memory

on client_run_loadgen()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 2
		repeat until tab_id > (num_servers * 2)
			set cmd to "cd ~/work/cassandra/mtdb/loadgen && ./create-db.sh && ./loadgen"
			do script (cmd) in tab tab_id of currentWindow
			-- Make sure we get different exp datetime
			delay 2
			-- Go to the next client tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end client_run_loadgen

on screen_detach()
	tell application "Terminal" to activate
	set tab_id to 0
	repeat until tab_id is (num_servers * 2)
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke "d"
		delay 0.1
		-- Move to the next tab
		tell application "System Events" to key code 124 using {shift down, command down}
	end repeat
end screen_detach

on screen_reattach()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "screen -r"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next tab
			set tab_id to tab_id + 1
		end repeat
	end tell
end screen_reattach

on server_get_client_logs_and_process()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "c" using {control down}

		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "(killall pressure-memory > /dev/null 2>&1 || true) && (sudo killall collectl > /dev/null 2>&1 || true) && (sudo killall mon-num-cass-threads.sh > /dev/null 2>&1 || true) && rsync -ave \"ssh -o StrictHostKeyChecking=no\" $CASSANDRA_CLIENT_ADDR:work/cassandra/mtdb/logs/loadgen ~/work/cassandra/mtdb/logs && cd ~/work/cassandra/mtdb/process-log/calc-cost-latency-plot-tablet-timeline && (\\rm *.pdf || true) && ./plot-cost-latency-tablet-timelines.py && du -hs ~/work/cassandra/data/"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_get_client_logs_and_process

-- One-time fix. Won't need again
on server_rename_client_log()
	tell application "Terminal" to activate

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat

	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			-- I don't like the float division. oh well.
			set cmd to "mv ~/work/cassandra/mtdb/logs/loadgen/160302-023811 ~/work/cassandra/mtdb/logs/loadgen/160302-023811-" & ((tab_id - 1) / 2) & " && mv ~/work/cassandra/mtdb/logs/cassandra/160302-023811 ~/work/cassandra/mtdb/logs/cassandra/160302-023811-" & ((tab_id - 1) / 2)
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell

	set tab_id to 0
	repeat until tab_id is num_servers
		set tab_id to tab_id + 1
		tell application "System Events" to keystroke "a" using {control down}
		tell application "System Events" to keystroke tab
		-- Move to the next server tab
		tell application "System Events" to key code 124 using {shift down, command down}
		tell application "System Events" to key code 124 using {shift down, command down}
		delay 0.1
	end repeat
end server_rename_client_log

-- One-time use.
on server_kill_monitor_processes()
	tell application "Terminal"
		set currentWindow to front window
		set tab_id to 1
		repeat until tab_id > (num_servers * 2)
			set cmd to "(killall pressure-memory > /dev/null 2>&1 || true) && (sudo killall collectl > /dev/null 2>&1 || true) && (sudo killall mon-num-cass-threads.sh > /dev/null 2>&1 || true)"
			do script (cmd) in tab tab_id of currentWindow
			-- Go to the next server tab
			set tab_id to tab_id + 2
		end repeat
	end tell
end server_kill_monitor_processes

on open_window_tabs_ssh_screen()
	my open_window_tabs()
	my ssh()
	my screen()
end open_window_tabs_ssh_screen

on run_all()
	my open_window_tabs_ssh_screen()

	my install_pkgs_0()
	my install_pkgs_1()
	my install_pkgs_2()

	-- Not a normal process. In case something goes wrong.
	-- my exit_screen()

	-- These can be grouped
	my server_screen_split_htop()
	my client_screen_split_htop()
	my build_cass_pressuremem_loadgen()

	-- In case needed
	-- my git_pull()

	-- These can be grouped
	my server_format_ebs_mag_mount_prepare_dirs()
	my watch_free_mem()
	-- Make sure which experiment you want, by editing migrate_to_cold_storage
	my server_edit_cassandra_yaml()
	my client_edit_cassandra_yaml()
	my save_screen_layout()

	my run_server()
	my server_pressure_memory()

	my client_run_loadgen()

	my screen_detach()
	my screen_reattach()

	my server_get_client_logs_and_process()
end run_all


Multiple Search-Replace

Multiple Search-Replace

Scripts/fmClip - Replace String in FM Objects.applescript