General housekeeping.

General housekeeping.

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

if (isInLoginItems("SpotiFree", ":Applications:SpotiFree.app") = false) then -- Check if SpotiFree is login items.
	local dialogTitle, dialogMessage, dialogButtonYes, dialogButtonYes, spotifreeAppName, spotifreeAppPath
	set spotifreeAppName to "SpotiFree"
	set spotifreeAppPath to ":Applications:SpotiFree.app"
	set dialogTitle to "Open SpotiFree at login"
	set dialogMessage to "Do you want SpotiFree to run automatically on startup? You'll never notice it, seriously."
	set dialogButtonNo to "No, thanks"
	set dialogButtonYes to "OK"

	-- Run the dialog to a user.
	set runAtStartupQuestion to (display dialog dialogMessage with title dialogTitle with icon 1 buttons {dialogButtonNo, dialogButtonYes} default button 2)
	-- Assign a result to the variable runAtStartupAnswer.
	set runAtStartupAnswer to the button returned of runAtStartupQuestion
	-- Check if user agreed.
	if (runAtStartupAnswer = dialogButtonYes) then
		try
			-- Add SpotiFree to the Login Items.
			my addToLoginItems(spotifreeAppName, spotifreeAppPath)
		end try
	end if
end if

repeat
	try
		-- Checking if Spotify is running and playing right now.
		if (isRunning() and isPlaying()) then
			tell application "Spotify"
				try
					-- 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 try
			end tell

			-- Check if current track is an advertisement.
			if (isAnAd(currentTrackPopularity, currentTrackDuration)) then
				try
					tell application "Spotify"
						try
							-- Get the current sound volume from Spotify and save it in a variable currentVolume.
							set currentVolume to sound volume
							-- Get the current track position and save it in a variable currentTrackPosition.
							set currentTrackPosition to player position
						end try
					end tell

					-- Mute Spotify.
					mute()

					-- Wait until the end of an ad + 1 sec. Then go forward.
					delay currentTrackDuration - currentTrackPosition + 1
				end try

				try
					repeat
						tell application "Spotify"
							try
								-- 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
								-- Get the current track position and save it in a variable currentTrackPosition.
								set currentTrackPosition to player position

							on error number errorNumber
								-- Checking if Spotify returns "Cant get current track." error.  It's being thrown when there's no track after an ad.
								-- Happens, for instance, when an ad has played after the last song on the playlist.
								if (errorNumber = -1728) then
									-- If it is, unmute Spotify and exit the loop.
									my unmute(currentVolume)
									exit repeat
								end if
							end try
						end tell

						-- Check if current track is an ad. Or if Spotify was paused during an advertisement.
						if (isAnAd(currentTrackPopularity, currentTrackDuration)) then
							-- Delay until the end of an ad + 1 sec.
							-- If Spotify was paused, or there is a second ad, this loop will continue to repeat.
							delay currentTrackDuration - currentTrackPosition + 1
						else
							-- If there's no more ads, unmute and exit the loop.
							unmute(currentVolume)
							exit repeat
						end if
					end repeat
				end try
			end if
		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"
			try
				-- 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 try
		end tell
	end try
end mute

on unmute(volume)
	local currentVolume
	set currentVolume to volume

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

on isAnAd(popularity, duration)
	local trackPopularity, trackDuration
	set trackPopularity to popularity
	set trackDuration to duration

	try
		-- If current track's popularity is 0 and its duration is less then 40, then it's almost certainly an ad.
		if (trackPopularity = 0 and trackDuration < 40) then
			return true
		else
			return false
		end if
	end try
end isAnAd

on isPlaying()
	local playerState
	try
		tell application "Spotify"
			try
				-- Hook the variable playerState to Spotify's state (playing, paused etc.).
				set playerState to player state
			end try
		end tell
		-- 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 try

end isPlaying

on isRunning()
	local spotifyProcesses
	try
		tell application "System Events"
			try
				-- 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 try
		end tell
		-- Check the variable spotifyProcesses, to see is Spotify running.
		if spotifyProcesses  0 then
			return true
		else
			return false
		end if
	end try
end isRunning

on isInLoginItems(appName)
	local applicationName, allLoginItems
	set applicationName to appName
	try
		-- Get all apps in Login Items.
		tell application "System Events" to set allLoginItems to name of every login item as string
		-- Check if inputted app is in there.
		if applicationName is in allLoginItems then
			return true
		else
			return false
		end if
	end try
end isInLoginItems

on addToLoginItems(appName, appPath)
	local applicationName, applicationPath, posixAppPath
	set applicationName to appName
	set applicationPath to appPath

	try
		-- Translate a supplied application path to a POSIX standard (e.g. "/Applications/SpotiFree.app" to ":Applications:SpotiFree.app").
		set posixAppPath to POSIX path of alias applicationPath
		tell application "System Events"
			try
				-- Add inputted app to the Login Items.
				make login item at end with properties {path:posixAppPath, hidden:true}
			end try
		end tell
	end try
end addToLoginItems

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

if (isInLoginItems("SpotiFree", ":Applications:SpotiFree.app") = false) then -- Check if SpotiFree is login items.
	local dialogTitle, dialogMessage, dialogButtonYes, dialogButtonYes, spotifreeAppName, spotifreeAppPath
	set spotifreeAppName to "SpotiFree"
	set spotifreeAppPath to ":Applications:SpotiFree.app"
	set dialogTitle to "Open SpotiFree at login"
	set dialogMessage to "Do you want SpotiFree to run automatically on startup? You'll never notice it, seriously."
	set dialogButtonNo to "No, thanks"
	set dialogButtonYes to "OK"

	-- Run the dialog to a user.
	set runAtStartupQuestion to (display dialog dialogMessage with title dialogTitle with icon 1 buttons {dialogButtonNo, dialogButtonYes} default button 2)
	-- Assign the result to the variable runAtStartupAnswer.
	set runAtStartupAnswer to the button returned of runAtStartupQuestion
	-- Check if user agreed.
	if (runAtStartupAnswer = dialogButtonYes) then
		try
			-- Add SpotiFree to the Login Items.
			my addToLoginItems(spotifreeAppName, spotifreeAppPath)
		end try
	end if
end if

-- Repeat this entire block every .3 seconds. As set at the end.
repeat
	try
		if (isRunning() and isPlaying()) then -- Is Spotify running? Is it playing?
			tell application "Spotify"
				try
					-- 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 try
			end tell

			-- Check if current track is an advertisement.
			if (isAnAd(currentTrackPopularity, currentTrackDuration)) then
				try
					tell application "Spotify"
						try
							-- Get the current sound volume from Spotify and save it in a variable currentVolume.
							set currentVolume to sound volume
							-- Get the current track position and save it in a variable currentTrackPosition.
							set currentTrackPosition to player position
						end try
					end tell

					-- Mute Spotify.
					mute()

					-- Wait until the end of an ad + 1 sec. Then go forward.
					delay currentTrackDuration - currentTrackPosition + 1
				end try

				try
					repeat
						tell application "Spotify"
							try
								-- 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
								-- Get the current track position and save it in a variable currentTrackPosition.
								set currentTrackPosition to player position

							on error errorNumber
								-- Checking if Spotify returns "Cant get current track." error.  It's being thrown when there's no track after an ad.
								-- Happens when an ad has played after the last song on the playlist.
								if (errorNumber = -1728) then
									unmute(currentVolume)
									exit repeat
								end if
							end try
						end tell

						if (isAnAd(currentTrackPopularity, currentTrackDuration)) then -- Check if current track is not an advertisement.
							-- Wait until the end of an ad + 1 sec. Then go forward.
							delay currentTrackDuration - currentTrackPosition + 1
						else
							unmute(currentVolume)
							exit repeat
						end if
					end repeat
				end try

			end if

		end if
	end try
	delay 0.3
end repeat

on mute()
	try
		tell application "Spotify"
			try
				pause
				set sound volume to 0
				play
			end try
		end tell
	end try
end mute

on unmute(volume)
	tell application "Spotify"
		try
			-- Restore the volume to the level it was before muting.
			set sound volume to volume
		end try
	end tell
end unmute

on isAnAd(trackPopularity, trackDuration)
	try
		-- If current track's popularity is 0 and its duration is less then 40, then it's almost certainly an ad.
		if (trackPopularity = 0 and trackDuration < 40) then
			return true
		else
			return false
		end if
	end try
end isAnAd

on isPlaying()
	local playerState
	try
		tell application "Spotify"
			try
				-- Hook the variable playerState to Spotify's state (playing, paused etc.).
				set playerState to player state
			end try
		end tell
		-- 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 try

end isPlaying

on isRunning()
	local spotifyProcesses
	try
		tell application "System Events"
			try
				-- 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 try
		end tell
		-- Check the variable spotifyProcesses, to see is Spotify running.
		if spotifyProcesses  0 then
			return true
		else
			return false
		end if
	end try
end isRunning

on isInLoginItems(appName)
	local allLoginItems
	try
		-- Get all apps in Login Items.
		tell application "System Events" to set allLoginItems to name of every login item as string
		-- Check if inputted app is in there.
		if appName is in allLoginItems then
			return true
		else
			return false
		end if
	end try
end isInLoginItems

on addToLoginItems(appName, appPath)
	local posixAppPath
	try
		-- Get the POSIX (Portable Operating System Interface) path of inputted appPath.
		set posixAppPath to POSIX path of alias appPath
		tell application "System Events"
			try
				-- Add inputted app to the Login Items.
				make login item at end with properties {path:posixAppPath, hidden:true}
			end try
		end tell
	end try
end addToLoginItems


Added a newline to the end of the script - snak seemed unhappy without this.

FasdUAS 1.101.10
k
i
I0
registergrowl
registerGrowl
k

r

J
mPublic Message
mPrivate Message

o0allnotesallNotes
O
I
.registernullnull

appl
m

Snak

anot
o0allnotesallNotes

dnot
o0allnotesallNotes

iapp
m
Snak
m!!"nullaa;GrowlHelperApp.appL7P@)(K pGRRRalisWideBoy.1H+a3GrowlHelperApp.appa8v	 	Resources.1va3a2a1	TWideBoy:Library:PreferencePanes:Growl.prefPane:Contents:Resources:GrowlHelperApp.app&GrowlHelperApp.appWideBoyLLibrary/PreferencePanes/Growl.prefPane/Contents/Resources/GrowlHelperApp.app/"#
"l#$%
$l%&'
&i()
(I*
0pubmsg*+,
+o0con,-.
-o
0source./0
/o0
sourcehost012
1o
0target23
3o
0	thestring
)k4456
5l678
7l89:
9l;;VP################################################################################:<=
<l>>4.########	Edit these values to suit your wishes=?@
?lAAVP################################################################################@BC
BlCDE
DlFF:4 set ChannelsToMonitor to {"#example1", "#example2"}EGH
GlII/) set keywords to {"keyword1", "keyword2"}HJK
JrLM
LJ
Mo&0channelstomonitorChannelsToMonitorKNO
Nr	PQ
PJ
Qo0keywordsORS
Rl

STU
Tl

VVSM Set to false to popup notifications even when snak is the active applicationUWX
Wr

YZ
Ym

boovtrue
Zo00notifyinbackgroundonlyNotifyInBackgroundOnlyX[\
[l\]^
]l__VP################################################################################^`a
`lbb######### 	End Editable Regionacd
cleeWQ################################################################################	dfg
flghi
hlijk
jlklm
llnn)# Get the name of the topmost windowmop
oO$qr
qr#st
s6!uv
unwx
w1

pnam
x4y

prcs
ym
v= z{
z1

pisf
{m
boovtrue
to"0nameofactiveappNameOfActiveApp
rm||null

Finder.app΀0L7ΰp)(K MACSalisbWideBoy.1H+

Finder.app2	 CoreServices.1

.WideBoy:System:Library:CoreServices:Finder.app
Finder.appWideBoy&System/Library/CoreServices/Finder.app/p}~
}l%%~
l%%
l%%$ Get your current irc nickname
O%2
r)1
n)/
1-/

NICK
4)-

CONN
o+,0con
o
0mynick
m%&nullA߸`baSnakQP0L7ՀZ()(K ՠSNpaalisZWideBoy.1H+`baSnak`bۺtMt	 	Snak 4.13.1tM`ba|,WideBoy:Users:diggory:Desktop:Snak 4.13:Snak
SnakWideBoy$Users/diggory/Desktop/Snak 4.13/Snak/
l33
l33
l33NH First, make sure we are either focused on another app, or we want to be
l33'! notified even if Snak is on top
Z3
G3>
l36
>36
o34"0nameofactiveappNameOfActiveApp
m45
Snak
l9<
=9<
o9:00notifyinbackgroundonlyNotifyInBackgroundOnly
m:;
boovfals
kA
lAA
lAA
lAAa[ Make sure the message's target is in ChannelsToMonitor, or that ChannelsToMonitor is empty
ZA
lAN
GAN
EAD
oAB&0channelstomonitorChannelsToMonitor
oBC
0target
=GL
nGJ
1HJ

leng
oGH&0channelstomonitorChannelsToMonitor
mJK
kQ
lQQ
lQQHB if keywords is empty, we're successful and we display the message
lQQNH otherwise, only set success if the message contains one of our keywords
ZQ
lQV
=QV
nQT
1RT

leng
oQR0keywords
mTU
rY\
mYZ
boovtrue
o0keywordmatchkeywordMatch
k_
r_b
m_`
boovfals
o0keywordmatchkeywordMatch
Xc
Zs
lsv
Esv
ost
0	thestring
otu0thiskeywordthisKeyword
ry|
myz
boovtrue
o0keywordmatchkeywordMatch0thiskeywordthisKeyword
lfg
ofg0keywords
l
l;5 if the message contains our nick, we will display it
Z
l~
E
o}}
0	thestring
o||
0mynick~
r
m{
{boovtrue
ozz0keywordmatchkeywordMatchy
lxwxwy
lvuvu
lttmg If the message is coming from a valid channel, and we got success in matching either keywords or nick,
lss display an alert
Zrq
lp
=
ooo0keywordmatchkeywordMatch
mn
nboovtruep
k
n
Imlkm0
registergrowl
registerGrowllk
fj
O
Iih
i.notifygrnullnullhg
g
titl
l	f
	b

b

oee
0source

m:
odd
0targetfc
c
desc
lb
oaa
0	thestringb`
`
appl
m
Snak_^
_
name
mPublic Message^
m!jrq]
l\[\[]
lZYZYX
lWVWVX
lUTUTS
L
mR
RboovfalsS'
lQPQP !"
!lO#O#(" Log all private messages to growl"$%
$i&'
&IN(MN0privmsg()*
)oLL0con*+,
+oKK
0source,-.
-oJJ0
sourcehost./0
/oII
0target01H
1oGG
0	thestringHM
'kI2234
3lFEFE456
5lD7D7.( Get the name of the topmost application689
8O:;
:r<=
<6>?
>n
@A
@1
C
C
pnam
A4BB
B
prcs
BmAA
?=CD
C1@
@
pisf
Dm?
?boovtrue
=o>>"0nameofactiveappNameOfActiveApp
;m|9EF
El=<=<FGH
GZGIJ;:
IG"KL
KlM9
M>NO
No88"0nameofactiveappNameOfActiveApp
OmPP
Snak9
Ll Q7
Q= RS
Ro6600notifyinbackgroundonlyNotifyInBackgroundOnly
Sm5
5boovfals7
Jk%CTTUV
Un%*WX
WI&*43240
registergrowl
registerGrowl32
Xf%&VY1
YO+CZ[
ZI/B0/\
0.notifygrnullnull/\.]^
.
titl
]l16_-
_b16`a
`b14bc
bo12,,
0source
cm23dd:
ao45++
0target-^*ef
*
desc
el78g)
go78((
0	thestring)f'hi
'
appl
hm9:jj
Snaki&k%
&
name
km;<llPrivate Message%
[m+,!1;:Hm$
mlHH#"#"$%no
nl! ! op
plqrstq0
registergrowl
registerGrowl
0pubmsg0privmsgruv0
registergrowl
registerGrowlu0allnotesallNotesv!

appl

anot

dnot

iapp
.registernullnulllvEO*
Us
)wx

0pubmsg	y	y0con
0source0
sourcehost
0target
0	thestringw0con
0source0
sourcehost
0target
0	thestring&0channelstomonitorChannelsToMonitor0keywords00notifyinbackgroundonlyNotifyInBackgroundOnly"0nameofactiveappNameOfActiveApp
0mynick0keywordmatchkeywordMatch0thiskeywordthisKeywordx|z!

prcs

pnamz

pisf

CONN

NICK

bool

leng

kocl

cobj
.corecnte********0
registergrowl
registerGrowl

titl

desc

appl

name
.notifygrnullnull
jvEOjvEOeEO*k/,[,\Ze81EUO
*/,EUO
f&
	,j&,jeEY8fEO![l
kheEYh[OYOeEYhOPOe1)j+O#*aa%%aaaaaaUYhOPYhOPYhOft'{|0privmsg}}0con
0source0
sourcehost
0target
0	thestring{0con
0source0
sourcehost
0target
0	thestring"0nameofactiveappNameOfActiveApp00notifyinbackgroundonlyNotifyInBackgroundOnly||zP!djl

prcs

pnam

pisf

bool0
registergrowl
registerGrowl

titl

desc

appl

name
.notifygrnullnullJ*k/,[,\Ze81EUO
f&#)j+O*%%aUYhOPascr
ޭ

FasdUAS 1.101.10
k
i
I0
registergrowl
registerGrowl
k

r

J
mPublic Message
mPrivate Message

o0allnotesallNotes
O
I
.registernullnull

appl
m

Snak

anot
o0allnotesallNotes

dnot
o0allnotesallNotes

iapp
m
Snak
m!!"nullaa;GrowlHelperApp.appL7P@)(K pGRRRalisWideBoy.1H+a3GrowlHelperApp.appa8v	 	Resources.1va3a2a1	TWideBoy:Library:PreferencePanes:Growl.prefPane:Contents:Resources:GrowlHelperApp.app&GrowlHelperApp.appWideBoyLLibrary/PreferencePanes/Growl.prefPane/Contents/Resources/GrowlHelperApp.app/"#
"l#$%
$l%&'
&i()
(I*
0pubmsg*+,
+o0con,-.
-o
0source./0
/o0
sourcehost012
1o
0target23
3o
0	thestring
)k4456
5l678
7l89:
9l;;VP################################################################################:<=
<l>>4.########	Edit these values to suit your wishes=?@
?lAAVP################################################################################@BC
BlCDE
DlFF:4 set ChannelsToMonitor to {"#example1", "#example2"}EGH
GlII/) set keywords to {"keyword1", "keyword2"}HJK
JrLM
LJ
Mo&0channelstomonitorChannelsToMonitorKNO
Nr	PQ
PJ
Qo0keywordsORS
Rl

STU
Tl

VVSM Set to false to popup notifications even when snak is the active applicationUWX
Wr

YZ
Ym

boovtrue
Zo00notifyinbackgroundonlyNotifyInBackgroundOnlyX[\
[l\]^
]l__VP################################################################################^`a
`lbb######### 	End Editable Regionacd
cleeWQ################################################################################	dfg
flghi
hlijk
jlklm
llnn)# Get the name of the topmost windowmop
oO$qr
qr#st
s6!uv
unwx
w1

pnam
x4y

prcs
ym
v= z{
z1

pisf
{m
boovtrue
to"0nameofactiveappNameOfActiveApp
rm||null

Finder.app΀0L7ΰp)(K MACSalisbWideBoy.1H+

Finder.app2	 CoreServices.1

.WideBoy:System:Library:CoreServices:Finder.app
Finder.appWideBoy&System/Library/CoreServices/Finder.app/p}~
}l%%~
l%%
l%%$ Get your current irc nickname
O%2
r)1
n)/
1-/

NICK
4)-

CONN
o+,0con
o
0mynick
m%&nullA߸`baSnakQP0L7ՀZ()(K ՠSNpaalisZWideBoy.1H+`baSnak`bۺtMt	 	Snak 4.13.1tM`ba|,WideBoy:Users:diggory:Desktop:Snak 4.13:Snak
SnakWideBoy$Users/diggory/Desktop/Snak 4.13/Snak/
l33
l33
l33NH First, make sure we are either focused on another app, or we want to be
l33'! notified even if Snak is on top
Z3
G3>
l36
>36
o34"0nameofactiveappNameOfActiveApp
m45
Snak
l9<
=9<
o9:00notifyinbackgroundonlyNotifyInBackgroundOnly
m:;
boovfals
kA
lAA
lAA
lAAa[ Make sure the message's target is in ChannelsToMonitor, or that ChannelsToMonitor is empty
ZA
lAN
GAN
EAD
oAB&0channelstomonitorChannelsToMonitor
oBC
0target
=GL
nGJ
1HJ

leng
oGH&0channelstomonitorChannelsToMonitor
mJK
kQ
lQQ
lQQHB if keywords is empty, we're successful and we display the message
lQQNH otherwise, only set success if the message contains one of our keywords
ZQ
lQV
=QV
nQT
1RT

leng
oQR0keywords
mTU
rY\
mYZ
boovtrue
o0keywordmatchkeywordMatch
k_
r_b
m_`
boovfals
o0keywordmatchkeywordMatch
Xc
Zs
lsv
Esv
ost
0	thestring
otu0thiskeywordthisKeyword
ry|
myz
boovtrue
o0keywordmatchkeywordMatch0thiskeywordthisKeyword
lfg
ofg0keywords
l
l;5 if the message contains our nick, we will display it
Z
l~
E
o}}
0	thestring
o||
0mynick~
r
m{
{boovtrue
ozz0keywordmatchkeywordMatchy
lxwxwy
lvuvu
lttmg If the message is coming from a valid channel, and we got success in matching either keywords or nick,
lss display an alert
Zrq
lp
=
ooo0keywordmatchkeywordMatch
mn
nboovtruep
k
n
Imlkm0
registergrowl
registerGrowllk
fj
O
Iih
i.notifygrnullnullhg
g
titl
l	f
	b

b

oee
0source

m:
odd
0targetfc
c
desc
lb
oaa
0	thestringb`
`
appl
m
Snak_^
_
name
mPublic Message^
m!jrq]
l\[\[]
lZYZYX
lWVWVX
lUTUTS
L
mR
RboovfalsS'
lQPQP !"
!lO#O#(" Log all private messages to growl"$%
$i&'
&IN(MN0privmsg()*
)oLL0con*+,
+oKK
0source,-.
-oJJ0
sourcehost./0
/oII
0target01H
1oGG
0	thestringHM
'kI2234
3lFEFE456
5lD7D7.( Get the name of the topmost application689
8O:;
:r<=
<6>?
>n
@A
@1
C
C
pnam
A4BB
B
prcs
BmAA
?=CD
C1@
@
pisf
Dm?
?boovtrue
=o>>"0nameofactiveappNameOfActiveApp
;m|9EF
El=<=<FGH
GZGIJ;:
IG"KL
KlM9
M>NO
No88"0nameofactiveappNameOfActiveApp
OmPP
Snak9
Ll Q7
Q= RS
Ro6600notifyinbackgroundonlyNotifyInBackgroundOnly
Sm5
5boovfals7
Jk%CTTUV
Un%*WX
WI&*43240
registergrowl
registerGrowl32
Xf%&VY1
YO+CZ[
ZI/B0/\
0.notifygrnullnull/\.]^
.
titl
]l16_-
_b16`a
`b14bc
bo12,,
0source
cm23dd:
ao45++
0target-^*ef
*
desc
el78g)
go78((
0	thestring)f'hi
'
appl
hm9:jj
Snaki&k%
&
name
km;<llPrivate Message%
[m+,!1;:Hm$
mlHH#"#"$%n!
nl  !opqro0
registergrowl
registerGrowl
0pubmsg0privmsgpst0
registergrowl
registerGrowls0allnotesallNotest!

appl

anot

dnot

iapp
.registernullnulllvEO*
Uq)
uv
0pubmsgww

0con
0source0
sourcehost
0target
0	thestring
u0con
0source0
sourcehost
0target
0	thestring&0channelstomonitorChannelsToMonitor0keywords00notifyinbackgroundonlyNotifyInBackgroundOnly"0nameofactiveappNameOfActiveApp
0mynick0keywordmatchkeywordMatch0thiskeywordthisKeywordv|x!

prcs

pnamx

pisf

CONN

NICK

bool

leng

kocl

cobj
.corecnte********0
registergrowl
registerGrowl

titl

desc

appl

name
.notifygrnullnulljvEOjvEOeEO*k/,[,\Ze81EUO
*/,EUO
f&
	,j&,jeEY8fEO![l
kheEYh[OYOeEYhOPOe1)j+O#*aa%%aaaaaaUYhOPYhOPYhOfr'yz0privmsg{{0con
0source0
sourcehost
0target
0	thestringy0con
0source0
sourcehost
0target
0	thestring"0nameofactiveappNameOfActiveApp00notifyinbackgroundonlyNotifyInBackgroundOnlyz|xP!djl

prcs

pnam

pisf

bool0
registergrowl
registerGrowl

titl

desc

appl

name
.notifygrnullnullJ*k/,[,\Ze81EUO
f&#)j+O*%%aUYhOPascrޭ


Woot for delay 0.5! applescript handles non-integer delays!

tell application "System Events" to key code 49 using {command down}
delay 0.3
tell application "System Events" to keystroke "terminal"
tell application "System Events" to key code 36
delay 0.3
tell application "System Events" to keystroke "./jarvis.sh \"\""
tell application "System Events" to key code 123

tell application "System Events" to key code 63
tell application "System Events" to key code 63
delay 4
tell application "System Events" to tell process "DictationIM"
	click button 1
end tell
delay 1.2
tell application "System Events" to key code 36

tell application "System Events" to key code 49 using {command down}
delay 1
tell application "System Events" to keystroke "terminal"
tell application "System Events" to key code 36
delay 2
tell application "System Events" to keystroke "./jarvis.sh \"\""
tell application "System Events" to key code 123

tell application "System Events" to key code 63
tell application "System Events" to key code 63
delay 2
tell application "System Events" to tell process "DictationIM"
	click button 1
end tell
delay 1
tell application "System Events" to key code 36


update fmGUI_ManageScripts_FmScript_Select

-- fmGUI_ManageScripts_FmScript_Select({})
-- Daniel A. Shockley, NYHTC
-- Select an existing script in the Script Workspace.

(*
HISTORY:
	2020-03-03 ( dshockley, hdu ): Updated as standalone function for fm-scripts git repository.
	1.3.1 - 2017-06-05 ( eshagdar ): the name of the script is the name of UI elemnt, not the value of a text field.
	1.3 - 2017-01-12 ( eshagdar ): updated for FM15 - script names are now in a splitter group.
	2017-06-05 ( eshagdar ): we should just be using the search bar instead of scanning through the list

REQUIRES:
	fmGUI_AppFrontMost
	fmGUI_DataViewer_Close
	fmGUI_Inspector_Close
	fmGUI_ManageScripts_Open
	fmGUI_ManageScripts_ScriptListFocus
	fmGUI_ManageScripts_SearchBoxClear
	fmGUI_ManageScripts_SearchBoxFind
	quoteString
	unParseChars

*)

property debugMode : true
property ScriptName : "fmGUI_ManageScripts_FmScript_Select"

on run
	fmGUI_ManageScripts_FmScript_Select({})
end run

--------------------
-- START OF CODE
--------------------

on fmGUI_ManageScripts_FmScript_Select(prefs)
	-- version 1.3.1

	-- Attempt to select a FileMaker Script based on name or, alternatively, other partial matches.

	set defaultPrefs to {fmScriptName:null, altPatterns:null}
	set prefs to prefs & defaultPrefs
	(* EXAMPLE:
	altPatterns:{
		{pattern:{{testType:"is", testMatch:"z_Auto1"}}},
		{pattern:{{testType:"startsWith", testMatch:"z"},{testType:"endsWith", testMatch:"_Auto1"}}}
		}
	*)

	-- CONSTANTS:
	set testCodeHeader to "tell application \"System Events\"" & return & "tell application process \"FileMaker Pro Advanced\"" & return
	set selectCode to "select ("
	set rowRefCode to "first row of (outline 1 of scroll area 1 of splitter group 1 of window 1)"
	set whoseCode to " whose "
	set scriptNameObjectCode to "name of UI Element 1"
	-- (then some test will be inserted)
	set betweenTestsCode to " and "
	-- (then possibly some other test will be inserted)
	set afterAllTestsCode to ")"
	set testCodeFooter to return & "end tell" & return & "end tell"

	try
		if fmScriptName of prefs is equal to "-" then error "This is a SEPARATOR SCRIPT - don't try to edit it!" number -1024

		fmGUI_AppFrontMost()
		fmGUI_Inspector_Close()
		fmGUI_DataViewer_Close()
		fmGUI_ManageScripts_Open({})
		fmGUI_ManageScripts_ScriptListFocus({})

		fmGUI_ManageScripts_SearchBoxFind({searchCriteria:fmScriptName of prefs})
		tell application "System Events"
			tell application process "FileMaker Pro Advanced"
				(*
				set searchField to text field 1 of splitter group 1 of window 1
				set focused of searchField to true
				delay 0.25
				keystroke "a" using command down
				key code 51 -- clear the search box
				delay 0.25
				set value of searchField to fmScriptName of prefs
				keystroke tab
				*)

				-- SELECT the easy way if the object is directly available:
				if (exists (first row of (outline 1 of scroll area 1 of splitter group 1 of window 1) whose name of UI element 1 is fmScriptName of prefs)) then
					select (first row of (outline 1 of scroll area 1 of splitter group 1 of window 1) whose name of UI element 1 is fmScriptName of prefs)
					return true

				else -- if NOT found, then seek by alternate patterns, if specified:

					-- NOT FOUND, so try each altPattern:
					set scriptNowSelected to false

					my fmGUI_ManageScripts_SearchBoxClear({})
					repeat with oneAltPattern in altPatterns of prefs
						set testList to contents of pattern of oneAltPattern
						if testList is equal to {{}} then
							--list of empty list, so we can't do anything with it
						else
							-- there are some valid items, so loop over them

							try
								-- BEGIN: try oneAltPattern:
								set testCode to {}
								repeat with oneTestRec in testList
									copy ("" & testType of oneTestRec & " " & quoteString(testMatch of oneTestRec)) to end of testCode
								end repeat

								set testCode to unParseChars(testCode, betweenTestsCode & scriptNameObjectCode & " ")
								set testCode to selectCode & rowRefCode & whoseCode & scriptNameObjectCode & " " & testCode & afterAllTestsCode
								set testCode to testCodeHeader & testCode & testCodeFooter
								tell me to run script testCode

								set scriptNowSelected to true -- no error, so we selected it.
								exit repeat -- no need to keep checking altPatterns

								-- ERROR: try oneAltPattern.
							on error errMsg number errNum
								if errNum is not -1719 then
									-- some error OTHER than not found in list:
									error errMsg number errNum
								else
									-- just try the next altPattern, so continue repeat loop.
								end if
								-- END OF: try oneAltPattern.
							end try
							-- END OF: List had things.
						end if
					end repeat
				end if
			end tell
		end tell

		return scriptNowSelected
	on error errMsg number errNum
		error "unable to fmGUI_ManageScripts_FmScript_Select '" & fmScriptName of prefs & "' - " & errMsg number errNum
	end try
end fmGUI_ManageScripts_FmScript_Select

--------------------
-- END OF CODE
--------------------

on fmGUI_AppFrontMost()
	tell application "htcLib" to fmGUI_AppFrontMost()
end fmGUI_AppFrontMost

on fmGUI_DataViewer_Close()
	tell application "htcLib" to fmGUI_DataViewer_Close()
end fmGUI_DataViewer_Close

on fmGUI_Inspector_Close()
	tell application "htcLib" to fmGUI_Inspector_Close()
end fmGUI_Inspector_Close

on fmGUI_ManageScripts_Open(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_Open(prefs)
end fmGUI_ManageScripts_Open

on fmGUI_ManageScripts_ScriptListFocus(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_ScriptListFocus(prefs)
end fmGUI_ManageScripts_ScriptListFocus

on fmGUI_ManageScripts_SearchBoxClear(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_SearchBoxClear(prefs)
end fmGUI_ManageScripts_SearchBoxClear

on fmGUI_ManageScripts_SearchBoxFind(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_SearchBoxFind(prefs)
end fmGUI_ManageScripts_SearchBoxFind

on quoteString(prefs)
	tell application "htcLib" to quoteString(prefs)
end quoteString

on unParseChars(prefs)
	tell application "htcLib" to unParseChars(prefs)
end unParseChars

-- fmGUI_ManageScripts_FmScript_Select({})
-- Daniel A. Shockley, NYHTC
-- Select an existing script in the Script Workspace.

(*
HISTORY:
	2020-03-03 ( dshockley, hdu ): Updated as standalone function for fm-scripts git repository.
	1.3.1 - 2017-06-05 ( eshagdar ): the name of the script is the name of UI elemnt, not the value of a text field.
	1.3 - 2017-01-12 ( eshagdar ): updated for FM15 - script names are now in a splitter group.
	2017-06-05 ( eshagdar ): we should just be using the search bar instead of scanning through the list

REQUIRES:
	fmGUI_AppFrontMost
	fmGUI_DataViewer_Close
	fmGUI_Inspector_Close
	fmGUI_ManageScripts_Open
	fmGUI_ManageScripts_ScriptListFocus
	fmGUI_ManageScripts_SearchBoxClear
	fmGUI_ManageScripts_SearchBoxFind
	unParseChars

*)

property debugMode : true
property ScriptName : "fmGUI_ManageScripts_FmScript_Select"

on run
	fmGUI_ManageScripts_FmScript_Select({})
end run

--------------------
-- START OF CODE
--------------------

on fmGUI_ManageScripts_FmScript_Select(prefs)
	-- version 1.3.1

	-- Attempt to select a FileMaker Script based on name or, alternatively, other partial matches.

	set defaultPrefs to {fmScriptName:null, altPatterns:null}
	set prefs to prefs & defaultPrefs
	(* EXAMPLE:
	altPatterns:{
		{pattern:{{testType:"is", testMatch:"z_Auto1"}}},
		{pattern:{{testType:"startsWith", testMatch:"z"},{testType:"endsWith", testMatch:"_Auto1"}}}
		}
	*)

	-- CONSTANTS:
	set testCodeHeader to "tell application \"System Events\"" & return & "tell application process \"FileMaker Pro Advanced\"" & return
	set selectCode to "select ("
	set rowRefCode to "first row of (outline 1 of scroll area 1 of splitter group 1 of window 1)"
	set whoseCode to " whose "
	set scriptNameObjectCode to "name of UI Element 1"
	-- (then some test will be inserted)
	set betweenTestsCode to " and "
	-- (then possibly some other test will be inserted)
	set afterAllTestsCode to ")"
	set testCodeFooter to return & "end tell" & return & "end tell"

	try
		if fmScriptName of prefs is equal to "-" then error "This is a SEPARATOR SCRIPT - don't try to edit it!" number -1024

		tell application "htcLib"
			fmGUI_AppFrontMost()
			fmGUI_Inspector_Close()
			fmGUI_DataViewer_Close()
			fmGUI_ManageScripts_Open({})
			fmGUI_ManageScripts_ScriptListFocus({})
		end tell

		fmGUI_ManageScripts_SearchBoxFind({searchCriteria:fmScriptName of prefs})
		tell application "System Events"
			tell application process "FileMaker Pro Advanced"
				(*
				set searchField to text field 1 of splitter group 1 of window 1
				set focused of searchField to true
				delay 0.25
				keystroke "a" using command down
				key code 51 -- clear the search box
				delay 0.25
				set value of searchField to fmScriptName of prefs
				keystroke tab
				*)

				-- SELECT the easy way if the object is directly available:
				if (exists (first row of (outline 1 of scroll area 1 of splitter group 1 of window 1) whose name of UI element 1 is fmScriptName of prefs)) then
					select (first row of (outline 1 of scroll area 1 of splitter group 1 of window 1) whose name of UI element 1 is fmScriptName of prefs)
					return true

				else -- if NOT found, then seek by alternate patterns, if specified:

					-- NOT FOUND, so try each altPattern:
					set scriptNowSelected to false

					my fmGUI_ManageScripts_SearchBoxClear({})
					repeat with oneAltPattern in altPatterns of prefs
						set testList to contents of pattern of oneAltPattern
						if testList is equal to {{}} then
							--list of empty list, so we can't do anything with it
						else
							-- there are some valid items, so loop over them

							try
								-- BEGIN: try oneAltPattern:
								set testCode to {}
								tell application "htcLib"
									repeat with oneTestRec in testList
										copy ("" & testType of oneTestRec & " " & quoteString(testMatch of oneTestRec)) to end of testCode
									end repeat
								end tell

								tell application "htcLib" to set testCode to unParseChars(testCode, betweenTestsCode & scriptNameObjectCode & " ")
								set testCode to selectCode & rowRefCode & whoseCode & scriptNameObjectCode & " " & testCode & afterAllTestsCode
								set testCode to testCodeHeader & testCode & testCodeFooter
								tell me to run script testCode

								set scriptNowSelected to true -- no error, so we selected it.
								exit repeat -- no need to keep checking altPatterns

								-- ERROR: try oneAltPattern.
							on error errMsg number errNum
								if errNum is not -1719 then
									-- some error OTHER than not found in list:
									error errMsg number errNum
								else
									-- just try the next altPattern, so continue repeat loop.
								end if
								-- END OF: try oneAltPattern.
							end try
							-- END OF: List had things.
						end if
					end repeat
				end if
			end tell
		end tell

		return scriptNowSelected
	on error errMsg number errNum
		error "unable to fmGUI_ManageScripts_FmScript_Select '" & fmScriptName of prefs & "' - " & errMsg number errNum
	end try
end fmGUI_ManageScripts_FmScript_Select

--------------------
-- END OF CODE
--------------------

on fmGUI_AppFrontMost()
	tell application "htcLib" to fmGUI_AppFrontMost()
end fmGUI_AppFrontMost

on fmGUI_DataViewer_Close()
	tell application "htcLib" to fmGUI_DataViewer_Close()
end fmGUI_DataViewer_Close

on fmGUI_Inspector_Close()
	tell application "htcLib" to fmGUI_Inspector_Close()
end fmGUI_Inspector_Close

on fmGUI_ManageScripts_Open(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_Open(prefs)
end fmGUI_ManageScripts_Open

on fmGUI_ManageScripts_ScriptListFocus(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_ScriptListFocus(prefs)
end fmGUI_ManageScripts_ScriptListFocus

on fmGUI_ManageScripts_SearchBoxClear(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_SearchBoxClear(prefs)
end fmGUI_ManageScripts_SearchBoxClear

on fmGUI_ManageScripts_SearchBoxFind(prefs)
	tell application "htcLib" to fmGUI_ManageScripts_SearchBoxFind(prefs)
end fmGUI_ManageScripts_SearchBoxFind

on unParseChars(prefs)
	tell application "htcLib" to unParseChars(prefs)
end unParseChars


Fixed toggle DnD for Hammerspoon

Fixed toggle DnD for Hammerspoon


Delete jLinuxUpdater.scpt

Delete jLinuxUpdater.scpt

display dialog "Opening jLinux Updater..." with title "jLinux Updater" buttons {"Ok"} default button 1
display alert "Updating jLinux will close all active Terminal sessions and overwrite your current jLinux executable. Is this OK?" buttons {"Yes", "No"} default button 1
if button returned of result = "Yes" then
	display alert "Updating..." giving up after 2
	tell application "Terminal"
		quit
		delay 5
		activate
		do script "curl -f http://thecyberbay.com/cdn/jLinux/latest/latest.jar -o /Applications/jLinux/latest.jar"
		delay 10
		do script "rm /Applications/jLinux/jLinux.jar"
		do script "mv /Applications/jLinux/latest.jar /Applications/jLinux/jLinux.jar"
		quit
		delay 1
	end tell
	display alert "Updated! Relaunching jLinux!" giving up after 3
	tell application "Terminal"
		do script "java -jar /Applications/jLinux/jLinux.jar"
	end tell
else
	display alert "jLinux has NOT been updated! Re-run this program at any time to update to the latest jLinux version!" giving up after 6
end if


refactor: minor update to test AppleScript watcher

--- Inspired by: http://www.makeuseof.com/tag/3-tools-unleash-mac-os-menu-bar

to conditionalclose(application_name)
	tell application application_name
		if it is running then
			quit
			return "Quit " & application_name
		else
			-- 	display dialog "Already quit  " & application_name
			return "Already quit " & application_name
		end if
	end tell
	delay 0.4
end conditionalclose

to conditionalopen(application_name)
	tell application application_name
		if it is running then
			-- 	display dialog "Already running " & application_name
			return application_name & " is already open"
		else
			launch
			return "Opened " & application_name
		end if
	end tell
	delay 0.2
end conditionalopen

-- if you are not sure about the exact name, start "Activity Monitor" (e.g. search it with Spotlight)
-- and look up the "Process Name" (first column) in the list of running processes

-- Open apps if not open already:
conditionalopen("Sip")
conditionalopen("Dash")
-- conditionalopen("PopClip") -- Causes CMD C to fail. Currently deactivated
conditionalopen("Dropshelf")
conditionalopen("Flux")
conditionalopen("Downlink")
-- conditionalopen("Numi")

-- Background Apps
-- conditionalopen("Rocket")
-- conditionalopen("BetterTouchTool")
-- conditionalopen("EvernoteHelper")
conditionalopen("Bartender 2")
conditionalopen("Dropbox")
conditionalopen("Backup and Sync") -- Google Drive Sync

-- Debugging:

-- Use console to log timestamp and info to console upon error
-- to logit(log_string, log_file)
-- 	do shell script
-- 		"echo `date '+%Y-%m-%d %T: '`\"" & log_string &
-- 		"\" >> $HOME/Library/Logs/" & log_file & ".log"
-- end logit

-- Quit any unneccessary apps
-- conditionalclose("KeepingYouAwake")

-- Other method of printing results
set dateStamp to date string of (current date)
set timeStamp to time string of (current date)
return "This script was run on " & dateStamp & " at " & timeStamp

--- Inspired by: http://www.makeuseof.com/tag/3-tools-unleash-mac-os-menu-bar

to conditionalclose(application_name)
	tell application application_name
		if it is running then
			quit
			return "Quit " & application_name
		else
			-- 	display dialog "Already quit  " & application_name
			return "Already quit " & application_name
		end if
	end tell
	delay 0.4
end conditionalclose

to conditionalopen(application_name)
	tell application application_name
		if it is running then
			-- 	display dialog "Already running " & application_name
			return application_name & " is already open"
		else
			launch
			return "Opened " & application_name
		end if
	end tell
	delay 0.2
end conditionalopen

-- if you are not sure about the exact name, start "Activity Monitor" (e.g. search it with Spotlight)
-- and look up the "Process Name" (first column) in the list of running processes

-- Open apps if not open already:
conditionalopen("Sip")
conditionalopen("Dash")
-- conditionalopen("PopClip") -- causes CMD C to fail...
conditionalopen("Dropshelf")
conditionalopen("Flux")
conditionalopen("Downlink")
-- conditionalopen("Numi")

-- Background Apps
-- conditionalopen("Rocket")
-- conditionalopen("BetterTouchTool")
-- conditionalopen("EvernoteHelper")
conditionalopen("Bartender 2")
conditionalopen("Dropbox")
conditionalopen("Backup and Sync")  -- Google Drive Sync

-- Debugging:

-- Use console to log timestamp and info to console upon error
-- to logit(log_string, log_file)
-- 	do shell script ¬
-- 		"echo `date '+%Y-%m-%d %T: '`\"" & log_string & ¬
-- 		"\" >> $HOME/Library/Logs/" & log_file & ".log"
-- end logit

-- Quit any unneccessary apps
-- conditionalclose("KeepingYouAwake")

-- Other method of printing results
set dateStamp to date string of (current date)
set timeStamp to time string of (current date)
return "This script was run on " & dateStamp & " at " & timeStamp


also paste

also paste

Scripts/fmClip - Custom Function Paste As Needed.applescript


Simplify sent mail script

Simplify sent mail script

on run argv
  set window_from to date (item 1 of argv)
  set window_to   to date (item 2 of argv)

  tell application "Mail"
    set results to {}

    set msgs to (messages of sent mailbox whose date sent >= window_from and date sent <= window_to)
    repeat with msg in msgs
      set the end of results to {subject:subject of msg, datetime:date sent of msg as string}
    end repeat

    results
  end tell
end run

on run argv
  set window_from to date (item 1 of argv)
  set window_to   to date (item 2 of argv)

  tell application "Mail"
    set results to {}

    repeat with acct in every account
      set username to user name of acct
      try
        set mbox to mailbox "[Gmail]/All Mail" of acct
      on error
        set mbox to mailbox "Sent" of acct
      end try

      set msgs to (messages whose sender contains username and date sent >= window_from and date sent <= window_to) in mbox
      repeat with msg in msgs
        set the end of results to {subject:subject of msg, datetime:date sent of msg as string}
      end repeat
    end repeat

    results
  end tell
end run


Simplified "Set Homepage"

Simplified "Set Homepage"

Changed the mechanism for creating a new Safari preference file from launching Safari to just using "touch". This should eliminate the side effect of Safari opening every time the MHQ Tools app is opened.

-- This is the master machq script to replace all others!
-- First find out the version of OS X

global osVersion
global externalIP
global SWUpdateServer
global store
global resources_directory

set osVersion to do shell script "/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'"

try
	set externalIP to do shell script "/usr/bin/curl http://icanhazip.com/"

	set test1 to do shell script "/usr/bin/dig +short 001.machq.com"
	set test2 to do shell script "/usr/bin/dig +short 002.machq.com"
	set test3 to do shell script "/usr/bin/dig +short 003.machq.com"

	if externalIP is test1 then
		set store to "001"
		set SWUpdateServer to "netboot-station.local:8088"
	else if externalIP is test2 then
		set store to "002"
		set SWUpdateServer to "xserve.local:8088"
	else if externalIP is test3 then
		set store to "003"
		set SWUpdateServer to "servercdr.local:8088"
	end if

on error
	--can't determine which store automatically
	set theStoreList to {"St. Louis", "O'Fallon", "Cedar Rapids"}
	set theStore to choose from list theStoreList with title "Help!" with prompt "Where are we?"

	if theStore as string is "St. Louis" then
		set SWUpdateServer to "netboot-station.local:8088"
	else if theStore as string is "O'Fallon" then
		set SWUpdateServer to "xserve.local:8088"
	else if theStore as string is "Cedar Rapids" then
		set SWUpdateServer to "servercdr.local:8088"
	end if

end try

--check for updates to the updater script
try
	tell application "Finder"
		set scripts_directory to (container of (path to me) as text)
		set resources_directory to (container of container of (path to me) as text)
	end tell

	set local_file to the POSIX path of (resources_directory & "updater.version")
	set local_version to do shell script "/bin/cat \"" & local_file & "\""

	set current_version to do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.version"
	--display dialog "Local version of updater is: " & local_version & ", current version is: " & current_version

	if current_version > local_version then

		--download the new version
		set local_file to the POSIX path of (scripts_directory & "updater.applescript")
		do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.applescript > \"" & local_file & "\""
		--update the local version string
		set local_file to the POSIX path of (resources_directory & "updater.version")
		do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.version > \"" & local_file & "\""

	end if
end try

tell application "Finder"
	set resources_directory to (container of container of (path to me) as text)
end tell

--display dialog osVersion buttons {"OK"}

--display dialog SWUpdateServer buttons {"OK"}

set theButtonNames to {"Set Used Prefs (all *'ed items)", "Set SWUpdateServer*", "List SWUpdateServer", "Remove SWUpdateServer", "Set MacHQ homepage*", "Disable Sleep*", "Rename HD by Size*", "Install MHQ Reset Script", "Remove Current User & Reset CPU", "Test for Flashback Trojan", "Test for ShellShock vulnerability", "Rebuild Launch Services DB", "Flush DNS Cache", "Reset Fake preferences", "Update Fake Workflows from Server", "Install SWUpdate StartupItem", "Save System Profiler Report to server"}

repeat
	set theChoice to choose from list theButtonNames
	if theChoice is false then
		exit repeat
	else if theChoice as string is "Set SWUpdateServer*" then
		setSWUpdateServer()
	else if theChoice as string is "List SWUpdateServer" then
		listSWUpdateServer()
	else if theChoice as string is "Remove SWUpdateServer" then
		resetSWUpdateServer()
	else if theChoice as string is "Set MacHQ homepage*" then
		setHomePage()
	else if theChoice as string is "Set Used Prefs (all *'ed items)" then
		setUsedPrefs()
	else if theChoice as string is "Disable Sleep*" then
		disableSleep()
	else if theChoice as string is "Rename HD by Size*" then
		renameHDbySize()
	else if theChoice as string is "Install MHQ Reset Script" then
		installResetScript()
	else if theChoice as string is "Remove MHQ User & Reset CPU" then
		if resetUserCPU() = -128 then
			return
		end if
	else if theChoice as string is "Remove Current User & Reset CPU" then
		if resetThisUserCPU() = -128 then
			return
		end if
	else if theChoice as string is "Test for Flashback Trojan" then
		testForFlashbackTrojan()
	else if theChoice as string is "Rebuild Launch Services DB" then
		rebuildLaunchServicesDB()
	else if theChoice as string is "Reset Fake preferences" then
		reinstallDefaultFakePreferences()
	else if theChoice as string is "Reinstall Fake Workflows" then
		reinstallFakeWorkflows()
	else if theChoice as string is "Install SWUpdate StartupItem" then
		InstallSWUpdatePlist()
	else if theChoice as string is "Flush DNS Cache" then
		FlushDNSCache()
	else if theChoice as string is "Save System Profiler Report to server" then
		SystemProfilerReport()
	else if theChoice as string is "Update Fake Workflows from Server" then
		UpdateWorkflowsFromServer()
	else if theChoice as string is "Test for ShellShock vulnerability" then
		testForShellShockVulnerability()
	else
		tell me to quit
	end if

end repeat

on setUsedPrefs()
	disableSleep()
	setSWUpdateServer()
	setHomePage()
	renameHDbySize()
end setUsedPrefs

on setHomePage()
	set fileTarget to (path to library folder from user domain as text) & "Preferences:com.apple.Safari.plist"

	try
		-- we don't really need the alias; we're just checking to see if it exists
		fileTarget as alias
	on error
		do shell script "touch " & fileTarget
	end try
	do shell script "defaults write com.apple.Safari HomePage http://twitter.com/machq; defaults write com.apple.Safari NewWindowBehavior 0"
end setHomePage

on listSWUpdateServer()
	try
		set server_name to do shell script "defaults read /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
		display dialog "SW update server is: " & server_name buttons {"OK"}
	on error
		display dialog "Using default Apple SW Update Server" buttons {"OK"}
	end try
end listSWUpdateServer

on resetSWUpdateServer()
	try
		--if running in 10.7 or later we need to supply password

		if (osVersion as number > 6) then
			do shell script "defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL" with administrator privileges
		else
			do shell script "/usr/bin/defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
		end if

		--do shell script "defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
	end try
end resetSWUpdateServer

on disableSleep()
	try
		do shell script "pmset -c displaysleep 0 sleep 0 disksleep 0" with administrator privileges
	end try
end disableSleep

on renameHDbySize()
	set theSetScript to "

#!/bin/bash

boot_vol=`bless --getBoot`

boot_disk=`diskutil info ${boot_vol} |sed '/^ *Volume Name: */!d;s###'`

disk_size=`system_profiler SPSerialATADataType |sed '/^ *Capacity: */!d;s###' | awk '{print int($1+0.5)  $2\" HD\"}' | head -n 1 `

diskutil rename \"${boot_disk}\" \"${disk_size}\"

# Show icons for hard drives, servers, and removable media on the desktop
#defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool true
#defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
#defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true

killall Finder

"
	do shell script theSetScript

end renameHDbySize

on setSWUpdateServer()

	set theSetScript to "

#!/bin/bash

URL1='http://" & SWUpdateServer & "'
    case `/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'` in
      4) URL=\"${URL1}/index.sucatalog\" ;;
      5) URL=\"${URL1}/index-leopard.merged-1.sucatalog\" ;;
      6) URL=\"${URL1}/index-leopard-snowleopard.merged-1.sucatalog\" ;;
	7) URL=\"${URL1}/index-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	8) URL=\"${URL1}/index-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	9) URL=\"${URL1}/index-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	10) URL=\"${URL1}/index-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
      *) echo \"Unsupported client OS\"; exit 1 ;;
    esac

/usr/bin/defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL \"${URL}\"

	"
	--if running in 10.7 or later we need to supply password
	try
		if (osVersion as number > 6) then
			do shell script theSetScript with administrator privileges
		else
			do shell script theSetScript
		end if
	end try
end setSWUpdateServer

on installResetScript()
	try
		tell application "Finder"
			set TheFile to (resources_directory & "mhqreset.sh") as alias
			duplicate TheFile to the startup disk with replacing
		end tell
	on error error_message
		display dialog error_message
	end try
end installResetScript

on resetUserCPU()
	try
		display dialog "This will install the MHQ reset script and restart the computer into single user mode, then run the reset script automatically. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		installResetScript()

		if osVersion is "10" then
			set target_file to ".bashrc"
		else
			set target_file to ".profile"
		end if

		do shell script "echo \"sh /mhqreset.sh\" >> /private/var/root/" & target_file with administrator privileges

		do shell script "nvram boot-args=\"-s\"" with administrator privileges

		tell application "Finder" to restart
		return -128
	end try
end resetUserCPU

on resetThisUserCPU()
	try
		tell application "System Events"
			set current_user to get the name of current user
		end tell

		display dialog "This will install the MHQ reset script and restart the computer into single user mode, then run the reset script automatically. The user \"" & current_user & "\" will be deleted with all it's files. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		display dialog "Are you absolutely certain?. The user \"" & current_user & "\" will be deleted with all it's files. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		installResetScript()

		if osVersion is "10" then
			set target_file to ".bashrc"
		else
			set target_file to ".profile"
		end if

		do shell script "echo \"sh /mhqreset.sh\" " & current_user & " >> /private/var/root/" & target_file with administrator privileges

		do shell script "nvram boot-args=\"-s\"" with administrator privileges

		tell application "Finder" to restart
		return -128
	end try
end resetThisUserCPU

on InstallSWUpdatePlist()

	set TheFile to (resources_directory & "Set SWUpdate Server") as alias

	if (osVersion as number > 7) then

		tell application "Finder"
			duplicate TheFile to (path to startup items from local domain as alias) with replacing
		end tell
	else

		set theScript to "

		#!/bin/bash

		if [ ! -e '/Library/StartupItems/Set SWUpdate Server' ]; then
		    mkdir '/Library/StartupItems/Set SWUpdate Server'
		fi
		cp -R '" & (the POSIX path of TheFile) & "' '/Library/StartupItems/Set SWUpdate Server/.'
		"
		do shell script theScript with administrator privileges

	end if

	do shell script "chmod -R 755 '/Library/StartupItems/Set SWUpdate Server'; sudo chown -R root:wheel '/Library/StartupItems/Set SWUpdate Server'" with administrator privileges

end InstallSWUpdatePlist

on testForFlashbackTrojan()
	display alert ("Beginning test") message "Testing for presence of Flashback trojan. Keep in mind this is NOT a definitive test!"

	try
		set check1 to do shell script "defaults read /Applications/Safari.app/Contents/Info LSEnvironment"
		display alert ("Possible infection!") message "Recommend running full antivirus scan with up to date scanner. Please note this test is a first release and may produce false positives."

	on error error_message number error_number
		if error_number is equal to 1 then
			display alert ("Alert!") message "First check appears okay"
		end if
	end try

	try
		set check2 to do shell script "defaults read ~/.MacOSX/environment DYLD_INSERT_LIBRARIES"
		display alert ("Possible infection!") message "Recommend running full antivirus scan with up to date scanner. Please note this test is a first release and may produce false positives."

	on error error_message number error_number
		if error_number is equal to 1 then
			display alert ("Alert!") message "Second check appears okay"
		end if
	end try
end testForFlashbackTrojan

on rebuildLaunchServicesDB()
	display alert ("Alert!") message "The Finder must be quit and will relaunch when complete."

	try
		tell application "Finder" to quit
		do shell script "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user"
		tell application "Finder" to activate

	end try
end rebuildLaunchServicesDB

on reinstallDefaultFakePreferences()

	--delete the current preference file

	tell application "Finder"
		set oldFile to (path to preferences folder as string) & "com.fakeapp.Fake.plist"
		delete file oldFile
	end tell

	-- create new preference file and set the properties we care about
	set theSetScript to "
#!/bin/bash

touch \"~/Preferences/com.fakeapp.Fake.plist\"
defaults write com.fakeapp.Fake \"FakeDelayBetweenRunningActions\" '0'
defaults write com.fakeapp.Fake \"FakePlaySuccessFailureSounds\" '0'
"
	do shell script theSetScript

end reinstallDefaultFakePreferences

on reinstallFakeWorkflows()
	set oldFolder to (path to application support from user domain as text) & "Fake:Workflows:"
	set fakeFolder to (path to application support from user domain as text) & "Fake:"
	set newFolder to (resources_directory & "Workflows") as alias
	--	display dialog oldFolder buttons {"OK"}
	tell application "Finder"
		try
			delete oldFolder
		end try
		duplicate newFolder to fakeFolder
	end tell
end reinstallFakeWorkflows

on FlushDNSCache()
	set theSetScript to "

#!/bin/bash

case `/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'` in
    4) lookupd -flushcache ;;
   [56]) dscacheutil -flushcache ;;
    [78]) sudo killall -HUP mDNSResponder ;;
    9) dscacheutil -flushcache; sudo killall -HUP mDNSResponder ;;
  10) dscacheutil -flushcache; sudo discoveryutil mdnsflushcache ;;
      *) echo \"Unsupported client OS\"; exit 1 ;;
esac

	"
	--if running in 10.7 or 10.8 we need to supply password

	if (osVersion as number > 7) then
		do shell script theSetScript with administrator privileges
	else
		do shell script theSetScript
	end if
end FlushDNSCache

on SystemProfilerReport()

	if (store = "001") then
		set destination to "/Volumes/MHQ/Backed Up/System Profiler Reports/"
		set dest_volume to "afp://mhq-swupdate.local/MHQ"
	else if (store = "002") then
		set destination to "/Volumes/Service/System Profiler Reports/"
		set dest_volume to "afp://xserve.local/Service"
	else if (store = "003") then
		set destination to "/Volumes/Service/System Profiler Reports/"
		set dest_volume to "afp://servercdr.local/Service"
	end if

	--	display dialog oldFolder

	tell application "Finder"
		try
			mount volume dest_volume
		on error
			return "Error mounting server volume \"" & dest_volume & "\". Please connect to server manually and try again."
			tell me to quit
		end try
	end tell

	--this shell script will generate a system profiler report and save it to the server
	do shell script "#!/bin/sh

# the location includes a folder based on the date in yyyy-mm-dd format
report_location=\"" & destination & "`date \"+%Y-%m-%d\"`/\"

if [ ! -d \"${report_location}\" ]; then
	mkdir \"${report_location}\"
fi

serial=`system_profiler SPHardwareDataType | grep \"Serial Number\" | awk  '{print $4}'`

SPDataTypes=\"SPHardwareDataType SPMemoryDataType SPPowerDataType SPSerialATADataType SPSoftwareDataType SPThunderboltDataType SPUSBDataType SPAirPortDataType SPFireWireDataType SPParallelATADataType SPAudioDataType SPBluetoothDataType SPNetworkDataType\"

system_profiler -xml $SPDataTypes > $report_location$serial\".spx\"
"

end SystemProfilerReport

on UpdateWorkflowsFromServer()

	set destination to POSIX path of ((path to application support from user domain as text) & "Fake:Workflows:")

	if (store = "001") then
		set source to "/Volumes/MHQ/Backed Up/Retail Stuff/Current Workflows/"
		set dest_volume to "afp://mhq-swupdate.local/MHQ"
	else if (store = "002") then
		set source to "/Volumes/Retail/Current Workflows/"
		set dest_volume to "afp://xserve.local/Retail"
	else if (store = "003") then
		set source to "/Volumes/Retail/Current Workflows/"
		set dest_volume to "afp://servercdr.local/Retail"
	end if

	--	display dialog oldFolder buttons {"OK"}

	tell application "Finder"
		try
			mount volume dest_volume
		on error
			return "Error mounting server volume \"" & dest_volume & "\". Please connect to server manually and try again."
			tell me to quit
		end try
	end tell

	try
		set theScript to "
	#!/bin/bash

	/usr/bin/rsync -a '" & source & "' '" & destination & "'
	" --shell script

		do shell script theScript --with administrator privileges
	on error
		return "Error syncronizing folders."
	end try

end UpdateWorkflowsFromServer

on testForShellShockVulnerability()

	set test_1 to "
#!/bin/bash

EXPLOIT_1=`env x='() { :;}; echo vulnerable' bash -c \"echo this is a test\"`
if [ \"${EXPLOIT_1}\" = \"vulnerable\" ]; then
    echo \"Test 1 (CVE-2014-6271):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 1 (CVE-2014-6271):	Machine doesn't appear to be vulnerable\"
fi
"
	set test_2 to "
#!/bin/bash

EXPLOIT_2=`env X='() { (shellshocker.net)=>\\' bash -c \"echo date\"; cat echo; rm ./echo `
if [ \"${EXPLOIT_2}\" != \"date\" ]; then
    echo \"Test 2 (CVE-2014-7169):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 2 (CVE-2014-7169):	Machine doesn't appear to be vulnerable\"
fi
"
	set test_3 to "
#!/bin/bash

EXPLOIT_3=`env X=' () { }; echo hello' bash -c 'date'`
if [ \"${EXPLOIT_3}\" = \"hello\" ]; then
    echo \"Test 3 (CVE-??):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 3 (CVE-??):	Machine doesn't appear to be vulnerable\"
fi

"

	set test_4 to "
#!/bin/bash

EXPLOIT_4=`bash -c 'true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF' || echo \"CVE-2014-7186 vulnerable, redir_stack\"`
if [ \"${EXPLOIT_4}\" = \"CVE-2014-7186 vulnerable, redir_stack\" ]; then
    echo \"Test 4 (CVE-2014-7186):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 4 (CVE-2014-7186):	Machine doesn't appear to be vulnerable\"
fi

"

	set test_5 to "
#!/bin/bash

EXPLOIT_5=`(for x in {1..200} ; do echo \"for x$x in ; do :\"; done; for x in {1..200} ; do echo done ; done) | bash || echo \"CVE-2014-7187 vulnerable, word_lineno\"`
if [ \"${EXPLOIT_5}\" = \"CVE-2014-7187 vulnerable, word_lineno\" ]; then
    echo \"Test 5 (CVE-2014-7187):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 5 (CVE-2014-7187):	Machine doesn't appear to be vulnerable\"
fi

"
	set test_6 to "
#!/bin/bash

EXPLOIT_6=`shellshocker='() { echo You are vulnerable; }' bash -c shellshocker`
if [ \"${EXPLOIT_6}\" = \"You are vulnerable\" ]; then
    echo \"Test 6 (CVE-2014-6278):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 6 (CVE-2014-6278):	Machine doesn't appear to be vulnerable\"
fi

"
	set test_7 to "
#!/bin/bash

EXPLOIT_7=`bash -c \"f() { x() { _;}; x() { _;} <<a; }\" 2>/dev/null || echo vulnerable`
if [ \"${EXPLOIT_7}\" = \"vulnerable\" ]; then
    echo \"Test 7 (CVE-2014-6277):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 7 (CVE-2014-6277):	Machine doesn't appear to be vulnerable\"
fi

"

	set result_1 to do shell script test_1
	set result_2 to do shell script test_2
	set result_3 to do shell script test_3
	set result_4 to do shell script test_4
	set result_5 to do shell script test_5
	set result_6 to do shell script test_6
	set result_7 to do shell script test_7

	try
		display dialog result_1 & return & result_2 & return & result_3 & return & result_4 & return & result_6 & return & result_6 & return & result_7 & return buttons {"OK"}
	end try
end testForShellShockVulnerability

-- This is the master machq script to replace all others!
-- First find out the version of OS X

global osVersion
global externalIP
global SWUpdateServer
global store
global resources_directory

set osVersion to do shell script "/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'"

try
	set externalIP to do shell script "/usr/bin/curl http://icanhazip.com/"

	set test1 to do shell script "/usr/bin/dig +short 001.machq.com"
	set test2 to do shell script "/usr/bin/dig +short 002.machq.com"
	set test3 to do shell script "/usr/bin/dig +short 003.machq.com"

	if externalIP is test1 then
		set store to "001"
		set SWUpdateServer to "netboot-station.local:8088"
	else if externalIP is test2 then
		set store to "002"
		set SWUpdateServer to "xserve.local:8088"
	else if externalIP is test3 then
		set store to "003"
		set SWUpdateServer to "servercdr.local:8088"
	end if

on error
	--can't determine which store automatically
	set theStoreList to {"St. Louis", "O'Fallon", "Cedar Rapids"}
	set theStore to choose from list theStoreList with title "Help!" with prompt "Where are we?"

	if theStore as string is "St. Louis" then
		set SWUpdateServer to "netboot-station.local:8088"
	else if theStore as string is "O'Fallon" then
		set SWUpdateServer to "xserve.local:8088"
	else if theStore as string is "Cedar Rapids" then
		set SWUpdateServer to "servercdr.local:8088"
	end if

end try

--check for updates to the updater script
try
	tell application "Finder"
		set scripts_directory to (container of (path to me) as text)
		set resources_directory to (container of container of (path to me) as text)
	end tell

	set local_file to the POSIX path of (resources_directory & "updater.version")
	set local_version to do shell script "/bin/cat \"" & local_file & "\""

	set current_version to do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.version"
	--display dialog "Local version of updater is: " & local_version & ", current version is: " & current_version

	if current_version > local_version then

		--download the new version
		set local_file to the POSIX path of (scripts_directory & "updater.applescript")
		do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.applescript > \"" & local_file & "\""
		--update the local version string
		set local_file to the POSIX path of (resources_directory & "updater.version")
		do shell script "/usr/bin/curl https://raw.githubusercontent.com/nilness/mhqtools/master/updater.version > \"" & local_file & "\""

	end if
end try

tell application "Finder"
	set resources_directory to (container of container of (path to me) as text)
end tell

--display dialog osVersion buttons {"OK"}

--display dialog SWUpdateServer buttons {"OK"}

set theButtonNames to {"Set Used Prefs (all *'ed items)", "Set SWUpdateServer*", "List SWUpdateServer", "Remove SWUpdateServer", "Set MacHQ homepage*", "Disable Sleep*", "Rename HD by Size*", "Install MHQ Reset Script", "Remove Current User & Reset CPU", "Test for Flashback Trojan", "Test for ShellShock vulnerability", "Rebuild Launch Services DB", "Flush DNS Cache", "Reset Fake preferences", "Update Fake Workflows from Server", "Install SWUpdate StartupItem", "Save System Profiler Report to server"}

repeat
	set theChoice to choose from list theButtonNames
	if theChoice is false then
		exit repeat
	else if theChoice as string is "Set SWUpdateServer*" then
		setSWUpdateServer()
	else if theChoice as string is "List SWUpdateServer" then
		listSWUpdateServer()
	else if theChoice as string is "Remove SWUpdateServer" then
		resetSWUpdateServer()
	else if theChoice as string is "Set MacHQ homepage*" then
		setHomePage()
	else if theChoice as string is "Set Used Prefs (all *'ed items)" then
		setUsedPrefs()
	else if theChoice as string is "Disable Sleep*" then
		disableSleep()
	else if theChoice as string is "Rename HD by Size*" then
		renameHDbySize()
	else if theChoice as string is "Install MHQ Reset Script" then
		installResetScript()
	else if theChoice as string is "Remove MHQ User & Reset CPU" then
		if resetUserCPU() = -128 then
			return
		end if
	else if theChoice as string is "Remove Current User & Reset CPU" then
		if resetThisUserCPU() = -128 then
			return
		end if
	else if theChoice as string is "Test for Flashback Trojan" then
		testForFlashbackTrojan()
	else if theChoice as string is "Rebuild Launch Services DB" then
		rebuildLaunchServicesDB()
	else if theChoice as string is "Reset Fake preferences" then
		reinstallDefaultFakePreferences()
	else if theChoice as string is "Reinstall Fake Workflows" then
		reinstallFakeWorkflows()
	else if theChoice as string is "Install SWUpdate StartupItem" then
		InstallSWUpdatePlist()
	else if theChoice as string is "Flush DNS Cache" then
		FlushDNSCache()
	else if theChoice as string is "Save System Profiler Report to server" then
		SystemProfilerReport()
	else if theChoice as string is "Update Fake Workflows from Server" then
		UpdateWorkflowsFromServer()
	else if theChoice as string is "Test for ShellShock vulnerability" then
		testForShellShockVulnerability()
	else
		tell me to quit
	end if

end repeat

on setUsedPrefs()
	disableSleep()
	setSWUpdateServer()
	setHomePage()
	renameHDbySize()
end setUsedPrefs

on setHomePage()
	set fileTarget to (path to library folder from user domain as text) & "Preferences:com.apple.Safari.plist"

	try
		-- we don't really need the alias; we're just checking to see if it exists
		fileTarget as alias
	on error
		tell application "Safari"
			activate
		end tell
	end try
	if running of application "Safari" then
		tell application "Safari"
			quit
		end tell
		repeat while (running of application "Safari")
			delay 1
		end repeat
		delay 2
	end if
	do shell script "defaults write com.apple.Safari HomePage http://twitter.com/machq; defaults write com.apple.Safari NewWindowBehavior 0"
	delay 2
	tell application "Safari"
		activate
		delay 2
		close every window
		quit
	end tell
end setHomePage

on listSWUpdateServer()
	try
		set server_name to do shell script "defaults read /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
		display dialog "SW update server is: " & server_name buttons {"OK"}
	on error
		display dialog "Using default Apple SW Update Server" buttons {"OK"}
	end try
end listSWUpdateServer

on resetSWUpdateServer()
	try
		--if running in 10.7 or later we need to supply password

		if (osVersion as number > 6) then
			do shell script "defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL" with administrator privileges
		else
			do shell script "/usr/bin/defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
		end if

		--do shell script "defaults delete /Library/Preferences/com.apple.SoftwareUpdate CatalogURL"
	end try
end resetSWUpdateServer

on disableSleep()
	try
		do shell script "pmset -c displaysleep 0 sleep 0 disksleep 0" with administrator privileges
	end try
end disableSleep

on renameHDbySize()
	set theSetScript to "

#!/bin/bash

boot_vol=`bless --getBoot`

boot_disk=`diskutil info ${boot_vol} |sed '/^ *Volume Name: */!d;s###'`

disk_size=`system_profiler SPSerialATADataType |sed '/^ *Capacity: */!d;s###' | awk '{print int($1+0.5)  $2\" HD\"}' | head -n 1 `

diskutil rename \"${boot_disk}\" \"${disk_size}\"

# Show icons for hard drives, servers, and removable media on the desktop
#defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool true
#defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
#defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true

killall Finder

"
	do shell script theSetScript

end renameHDbySize

on setSWUpdateServer()

	set theSetScript to "

#!/bin/bash

URL1='http://" & SWUpdateServer & "'
    case `/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'` in
      4) URL=\"${URL1}/index.sucatalog\" ;;
      5) URL=\"${URL1}/index-leopard.merged-1.sucatalog\" ;;
      6) URL=\"${URL1}/index-leopard-snowleopard.merged-1.sucatalog\" ;;
	7) URL=\"${URL1}/index-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	8) URL=\"${URL1}/index-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	9) URL=\"${URL1}/index-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
	10) URL=\"${URL1}/index-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog\" ;;
      *) echo \"Unsupported client OS\"; exit 1 ;;
    esac

/usr/bin/defaults write /Library/Preferences/com.apple.SoftwareUpdate CatalogURL \"${URL}\"

	"
	--if running in 10.7 or later we need to supply password
	try
		if (osVersion as number > 6) then
			do shell script theSetScript with administrator privileges
		else
			do shell script theSetScript
		end if
	end try
end setSWUpdateServer

on installResetScript()
	try
		tell application "Finder"
			set TheFile to (resources_directory & "mhqreset.sh") as alias
			duplicate TheFile to the startup disk with replacing
		end tell
	on error error_message
		display dialog error_message
	end try
end installResetScript

on resetUserCPU()
	try
		display dialog "This will install the MHQ reset script and restart the computer into single user mode, then run the reset script automatically. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		installResetScript()

		if osVersion is "10" then
			set target_file to ".bashrc"
		else
			set target_file to ".profile"
		end if

		do shell script "echo \"sh /mhqreset.sh\" >> /private/var/root/" & target_file with administrator privileges

		do shell script "nvram boot-args=\"-s\"" with administrator privileges

		tell application "Finder" to restart
		return -128
	end try
end resetUserCPU

on resetThisUserCPU()
	try
		tell application "System Events"
			set current_user to get the name of current user
		end tell

		display dialog "This will install the MHQ reset script and restart the computer into single user mode, then run the reset script automatically. The user \"" & current_user & "\" will be deleted with all it's files. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		display dialog "Are you absolutely certain?. The user \"" & current_user & "\" will be deleted with all it's files. Do you wish to continue?" buttons {"Quit", "Continue"} default button "Continue" cancel button "Quit"
		installResetScript()

		if osVersion is "10" then
			set target_file to ".bashrc"
		else
			set target_file to ".profile"
		end if

		do shell script "echo \"sh /mhqreset.sh\" " & current_user & " >> /private/var/root/" & target_file with administrator privileges

		do shell script "nvram boot-args=\"-s\"" with administrator privileges

		tell application "Finder" to restart
		return -128
	end try
end resetThisUserCPU

on InstallSWUpdatePlist()

	set TheFile to (resources_directory & "Set SWUpdate Server") as alias

	if (osVersion as number > 7) then

		tell application "Finder"
			duplicate TheFile to (path to startup items from local domain as alias) with replacing
		end tell
	else

		set theScript to "

		#!/bin/bash

		if [ ! -e '/Library/StartupItems/Set SWUpdate Server' ]; then
		    mkdir '/Library/StartupItems/Set SWUpdate Server'
		fi
		cp -R '" & (the POSIX path of TheFile) & "' '/Library/StartupItems/Set SWUpdate Server/.'
		"
		do shell script theScript with administrator privileges

	end if

	do shell script "chmod -R 755 '/Library/StartupItems/Set SWUpdate Server'; sudo chown -R root:wheel '/Library/StartupItems/Set SWUpdate Server'" with administrator privileges

end InstallSWUpdatePlist

on testForFlashbackTrojan()
	display alert ("Beginning test") message "Testing for presence of Flashback trojan. Keep in mind this is NOT a definitive test!"

	try
		set check1 to do shell script "defaults read /Applications/Safari.app/Contents/Info LSEnvironment"
		display alert ("Possible infection!") message "Recommend running full antivirus scan with up to date scanner. Please note this test is a first release and may produce false positives."

	on error error_message number error_number
		if error_number is equal to 1 then
			display alert ("Alert!") message "First check appears okay"
		end if
	end try

	try
		set check2 to do shell script "defaults read ~/.MacOSX/environment DYLD_INSERT_LIBRARIES"
		display alert ("Possible infection!") message "Recommend running full antivirus scan with up to date scanner. Please note this test is a first release and may produce false positives."

	on error error_message number error_number
		if error_number is equal to 1 then
			display alert ("Alert!") message "Second check appears okay"
		end if
	end try
end testForFlashbackTrojan

on rebuildLaunchServicesDB()
	display alert ("Alert!") message "The Finder must be quit and will relaunch when complete."

	try
		tell application "Finder" to quit
		do shell script "/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -kill -r -domain local -domain system -domain user"
		tell application "Finder" to activate

	end try
end rebuildLaunchServicesDB

on reinstallDefaultFakePreferences()

	--delete the current preference file

	tell application "Finder"
		set oldFile to (path to preferences folder as string) & "com.fakeapp.Fake.plist"
		delete file oldFile
	end tell

	-- create new preference file and set the properties we care about
	set theSetScript to "
#!/bin/bash

touch \"~/Preferences/com.fakeapp.Fake.plist\"
defaults write com.fakeapp.Fake \"FakeDelayBetweenRunningActions\" '0'
defaults write com.fakeapp.Fake \"FakePlaySuccessFailureSounds\" '0'
"
	do shell script theSetScript

end reinstallDefaultFakePreferences

on reinstallFakeWorkflows()
	set oldFolder to (path to application support from user domain as text) & "Fake:Workflows:"
	set fakeFolder to (path to application support from user domain as text) & "Fake:"
	set newFolder to (resources_directory & "Workflows") as alias
	--	display dialog oldFolder buttons {"OK"}
	tell application "Finder"
		try
			delete oldFolder
		end try
		duplicate newFolder to fakeFolder
	end tell
end reinstallFakeWorkflows

on FlushDNSCache()
	set theSetScript to "

#!/bin/bash

case `/usr/bin/sw_vers -productVersion | /usr/bin/awk -F . '{print $2}'` in
    4) lookupd -flushcache ;;
   [56]) dscacheutil -flushcache ;;
    [78]) sudo killall -HUP mDNSResponder ;;
    9) dscacheutil -flushcache; sudo killall -HUP mDNSResponder ;;
  10) dscacheutil -flushcache; sudo discoveryutil mdnsflushcache ;;
      *) echo \"Unsupported client OS\"; exit 1 ;;
esac

	"
	--if running in 10.7 or 10.8 we need to supply password

	if (osVersion as number > 7) then
		do shell script theSetScript with administrator privileges
	else
		do shell script theSetScript
	end if
end FlushDNSCache

on SystemProfilerReport()

	if (store = "001") then
		set destination to "/Volumes/MHQ/Backed Up/System Profiler Reports/"
		set dest_volume to "afp://mhq-swupdate.local/MHQ"
	else if (store = "002") then
		set destination to "/Volumes/Service/System Profiler Reports/"
		set dest_volume to "afp://xserve.local/Service"
	else if (store = "003") then
		set destination to "/Volumes/Service/System Profiler Reports/"
		set dest_volume to "afp://servercdr.local/Service"
	end if

	--	display dialog oldFolder

	tell application "Finder"
		try
			mount volume dest_volume
		on error
			return "Error mounting server volume \"" & dest_volume & "\". Please connect to server manually and try again."
			tell me to quit
		end try
	end tell

	--this shell script will generate a system profiler report and save it to the server
	do shell script "#!/bin/sh

# the location includes a folder based on the date in yyyy-mm-dd format
report_location=\"" & destination & "`date \"+%Y-%m-%d\"`/\"

if [ ! -d \"${report_location}\" ]; then
	mkdir \"${report_location}\"
fi

serial=`system_profiler SPHardwareDataType | grep \"Serial Number\" | awk  '{print $4}'`

SPDataTypes=\"SPHardwareDataType SPMemoryDataType SPPowerDataType SPSerialATADataType SPSoftwareDataType SPThunderboltDataType SPUSBDataType SPAirPortDataType SPFireWireDataType SPParallelATADataType SPAudioDataType SPBluetoothDataType SPNetworkDataType\"

system_profiler -xml $SPDataTypes > $report_location$serial\".spx\"
"

end SystemProfilerReport

on UpdateWorkflowsFromServer()

	set destination to POSIX path of ((path to application support from user domain as text) & "Fake:Workflows:")

	if (store = "001") then
		set source to "/Volumes/MHQ/Backed Up/Retail Stuff/Current Workflows/"
		set dest_volume to "afp://mhq-swupdate.local/MHQ"
	else if (store = "002") then
		set source to "/Volumes/Retail/Current Workflows/"
		set dest_volume to "afp://xserve.local/Retail"
	else if (store = "003") then
		set source to "/Volumes/Retail/Current Workflows/"
		set dest_volume to "afp://servercdr.local/Retail"
	end if

	--	display dialog oldFolder buttons {"OK"}

	tell application "Finder"
		try
			mount volume dest_volume
		on error
			return "Error mounting server volume \"" & dest_volume & "\". Please connect to server manually and try again."
			tell me to quit
		end try
	end tell

	try
		set theScript to "
	#!/bin/bash

	/usr/bin/rsync -a '" & source & "' '" & destination & "'
	" --shell script

		do shell script theScript --with administrator privileges
	on error
		return "Error syncronizing folders."
	end try

end UpdateWorkflowsFromServer

on testForShellShockVulnerability()

	set test_1 to "
#!/bin/bash

EXPLOIT_1=`env x='() { :;}; echo vulnerable' bash -c \"echo this is a test\"`
if [ \"${EXPLOIT_1}\" = \"vulnerable\" ]; then
    echo \"Test 1 (CVE-2014-6271):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 1 (CVE-2014-6271):	Machine doesn't appear to be vulnerable\"
fi
"
	set test_2 to "
#!/bin/bash

EXPLOIT_2=`env X='() { (shellshocker.net)=>\\' bash -c \"echo date\"; cat echo; rm ./echo `
if [ \"${EXPLOIT_2}\" != \"date\" ]; then
    echo \"Test 2 (CVE-2014-7169):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 2 (CVE-2014-7169):	Machine doesn't appear to be vulnerable\"
fi
"
	set test_3 to "
#!/bin/bash

EXPLOIT_3=`env X=' () { }; echo hello' bash -c 'date'`
if [ \"${EXPLOIT_3}\" = \"hello\" ]; then
    echo \"Test 3 (CVE-??):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 3 (CVE-??):	Machine doesn't appear to be vulnerable\"
fi

"

	set test_4 to "
#!/bin/bash

EXPLOIT_4=`bash -c 'true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF' || echo \"CVE-2014-7186 vulnerable, redir_stack\"`
if [ \"${EXPLOIT_4}\" = \"CVE-2014-7186 vulnerable, redir_stack\" ]; then
    echo \"Test 4 (CVE-2014-7186):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 4 (CVE-2014-7186):	Machine doesn't appear to be vulnerable\"
fi

"

	set test_5 to "
#!/bin/bash

EXPLOIT_5=`(for x in {1..200} ; do echo \"for x$x in ; do :\"; done; for x in {1..200} ; do echo done ; done) | bash || echo \"CVE-2014-7187 vulnerable, word_lineno\"`
if [ \"${EXPLOIT_5}\" = \"CVE-2014-7187 vulnerable, word_lineno\" ]; then
    echo \"Test 5 (CVE-2014-7187):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 5 (CVE-2014-7187):	Machine doesn't appear to be vulnerable\"
fi

"
	set test_6 to "
#!/bin/bash

EXPLOIT_6=`shellshocker='() { echo You are vulnerable; }' bash -c shellshocker`
if [ \"${EXPLOIT_6}\" = \"You are vulnerable\" ]; then
    echo \"Test 6 (CVE-2014-6278):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 6 (CVE-2014-6278):	Machine doesn't appear to be vulnerable\"
fi

"
	set test_7 to "
#!/bin/bash

EXPLOIT_7=`bash -c \"f() { x() { _;}; x() { _;} <<a; }\" 2>/dev/null || echo vulnerable`
if [ \"${EXPLOIT_7}\" = \"vulnerable\" ]; then
    echo \"Test 7 (CVE-2014-6277):	**** Machine appears to be vulnerable ****\"
else
    echo \"Test 7 (CVE-2014-6277):	Machine doesn't appear to be vulnerable\"
fi

"

	set result_1 to do shell script test_1
	set result_2 to do shell script test_2
	set result_3 to do shell script test_3
	set result_4 to do shell script test_4
	set result_5 to do shell script test_5
	set result_6 to do shell script test_6
	set result_7 to do shell script test_7

	try
		display dialog result_1 & return & result_2 & return & result_3 & return & result_4 & return & result_6 & return & result_6 & return & result_7 & return buttons {"OK"}
	end try
end testForShellShockVulnerability