A very long time ago I started creating a script that will cross reference Safari history items with a wordlist and then notify me when a word from the list was spotted in the history item. I use it for passive surveillance of the machines at work. As I got more and more into it, I kept adding new features. The script works, but, as expected is rather slow. I realise that, to a certain extent, the slowness is down to the fact that Safari takes forever to add history items in to the Finder. I would like to be able to read the plist file at some point, but we’ll talk about that later.
Anyway, here is the script in its current form, it’s called Bootle26, any suggestions at streamlining it would be greatly appreciated:
(*
Bootle26, Version 1.1.3
"The ability to monitor the machines, without having to actually monitor the machines"
Dan Barker 2010
Help from MacScripter.net, MacRumors.com (forum), Rob Whitaker & Dave Novis
Abuse from Rob Whitaker & Matt Clark
Support from Jenifer Webber, Neil Munro, David Simons & Dave Novis
Last updated: 22/7/10 at 2346
*)
(* Block 1 *)
on adding folder items to this_file after receiving added_items
(* Locates and reads Blacklist *)
set Blacklist_File to (open for access ("Macintosh HD:Library:Application Support:Bootle26:Wordlists:Blacklist.txt"))
set txt to (read Blacklist_File for (get eof Blacklist_File))
set blackWords to every paragraph of txt
close access Blacklist_File
(* Locates and reads RedFlag List *)
set Red_File to (open for access ("Macintosh HD:Library:Application Support:Bootle26:Wordlists:RedFlagList.txt"))
set txt2 to (read Red_File for (get eof Red_File))
set RedWords to every paragraph of txt2
close access Red_File
(* Cross references words in Blacklist with words in history items *)
repeat with i from 1 to number of items in added_items
tell application "Finder" to set this_item to words of (displayed name of (item i of added_items as alias) as string)
repeat with z from 1 to number of items in this_item
set this_item_word to item z of this_item
if this_item_word is in RedWords then
my redKeyword(this_item_word)
else
if this_item_word is in blackWords then
my blackKeyword(this_item_word)
end if
end if
end repeat
end repeat
end adding folder items to
(* EOBlock 1 *)
(* Block 2 *)
(* if any word is in the Blacklist then the following happens *)
on blackKeyword(N)
(* Script now defines the required variables *)
set theDate to date string of (current date)
set theTime to time string of (current date)
set dateandtime to "At " & theTime & " on " & theDate
set ScreenCapDT to theTime & " - " & theDate
set MacName to computer name of (system info)
set LogFileName to MacName & ".logtxt"
set ErrorFileName to MacName & ".errtxt"
set error_file to (("Macintosh HD:Library:Application Support:Bootle26:Error Log:" as text) & ErrorFileName)
set picPath to "/Library/Application Support/Bootle26/Screenshots/Blacklist/" & ScreenCapDT & ".png" as string
set ErrorLogText0 to return & return & "Bootle Error Message!" & return & MacName & return & dateandtime & return & "Reports error code #"
set ErrorLogTextG to "Error Message!" & return & MacName & return & "Reports error code #"
(* Blacklist Error Texts *)
set ErrorLogText2_1 to ErrorLogText0 & "2.1" & return & "An issue with Safari"
set ErrorLogText2_2 to ErrorLogText0 & "2.2" & return & "An issue with the Log File"
set ErrorLogText2_3 to ErrorLogText0 & "2.3" & return & "An issue with the Log File"
set ErrorLogText2_4 to ErrorLogText0 & "2.4" & return & "An issue with Growl/Network/Authentication"
(* Growl Error Texts *)
set ErrorLogTextG_2_2 to ErrorLogTextG & "2.2" & return & "An issue with the Log File"
set ErrorLogTextG_2_3 to ErrorLogTextG & "2.3" & return & "An issue with the Log File"
(* Block 2.1 *)
(* Safari reports the current URL & webpage title and saves them as text strings *)
try
tell application "Safari"
get URL of front document as string
end tell
copy result as text to longURL
set i to count words of longURL
set theURL to word 2 of longURL
tell application "Safari"
do JavaScript "document.title" in document 0
end tell
copy result as list to {SafTitle}
on error
set theURL to "Safari exited early"
set SafTitle to "Safari exited early"
end try
(* EOBlock 2.1 *)
(* Block 2.2 *)
(* Locates Log files and defines required log text *)
try
set the_file to (("Macintosh HD:Library:Application Support:Bootle26:Machine Logs:" as text) & LogFileName)
set LogFileText to return & return & "Blacklist Warning!" & return & "User of " & MacName & " requests: " & return & theURL & return & "Title: " & SafTitle & return & "Catalyst: " & N & return & dateandtime
on error
set datastream to open for access file error_file with write permission
write ErrorLogText2_2 to datastream starting at eof
close access datastream
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("Bootle Reports!") description ErrorLogTextG_2_2 & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 2 with sticky
end tell
end try
(* EOBlock 2.2 *)
(* Block 2.3 *)
(* Writes Log file data to the log file for future reference *)
try
set datastream to open for access file the_file with write permission
write LogFileText to datastream starting at eof
close access datastream
on error
set datastream to open for access file error_file with write permission
write ErrorLogText2_3 to datastream starting at eof
close access datastream
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("Bootle Reports!") description ErrorLogTextG_2_3 & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 2 with sticky
end tell
end try
(* EOBlock 2.3 *)
(* Block 2.4 *)
(* Pushes Growl notification to left hand machine *)
(*DON'T FORGET TO REMOVE QUOTES AROUND EPPC BIT*)
try
do shell script "screencapture -tjpg " & quoted form of picPath
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("Blacklist Warning!" & return & MacName) description "Catalyst: " & N & return & theURL & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 0 with sticky
end tell
on error
set datastream to open for access file error_file with write permission
write ErrorLogText2_4 to datastream starting at eof
close access datastream
end try
(* EOBlock 2.4 *)
end blackKeyword
(* EOBlock 2 *)
(* 000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 *)
(* Block 3 *)
(* if any word is in the RedFlag List then the following happens *)
on redKeyword(K)
set theDate to date string of (current date)
set theTime to time string of (current date)
set dateandtime to "At " & theTime & " on " & theDate
set ScreenCapDT to theTime & " - " & theDate
set MacName to computer name of (system info)
set LogFileName to MacName & ".logtxt"
set ErrorFileName to MacName & ".errtxt"
set error_file to (("Macintosh HD:Library:Application Support:Bootle26:Error Log:" as text) & ErrorFileName)
set picPath to "/Library/Application Support/Bootle26/Screenshots/RedFlag List/" & ScreenCapDT & ".png" as string
set ErrorLogText0 to return & return & "Bootle Error Message!" & return & MacName & return & dateandtime & return & "Reports error code #"
set ErrorLogTextG to "Error Message!" & return & MacName & return & "Reports error code #"
(* RedFlag Error Texts *)
set ErrorLogText3_1 to ErrorLogText0 & "3.1" & return & "An issue with Safari"
set ErrorLogText3_2 to ErrorLogText0 & "3.2" & return & "An issue with the Log File"
set ErrorLogText3_3 to ErrorLogText0 & "3.3" & return & "An issue with the Log File"
set ErrorLogText3_4 to ErrorLogText0 & "3.4" & return & "An issue with Growl/Network/Authentication"
(* Growl Error Texts *)
set ErrorLogTextG_3_2 to ErrorLogTextG & "3.2" & return & "An issue with the Log File"
set ErrorLogTextG_3_3 to ErrorLogTextG & "3.3" & return & "An issue with the Log File"
(* Block 3.1 *)
(* Safari reports the current URL & window title and saves as text strings *)
try
tell application "Safari"
get URL of front document as string
end tell
copy result as text to longURL
set i to count words of longURL
set theURL to word 2 of longURL
tell application "Safari"
do JavaScript "document.title" in document 0
end tell
copy result as list to {SafTitle}
on error
set theURL to "Safari exited early"
set SafTitle to "Safari exited early"
end try
(* EOBlock 3.1 *)
(* Block 3.2 *)
(* Locates Log files and defines required log text *)
try
set the_file to (("Macintosh HD:Library:Application Support:Bootle26:Machine Logs:" as text) & LogFileName)
set LogFileText to return & return & "RED FLAG!" & return & "User of " & MacName & " requests: " & return & theURL & return & "Title: " & SafTitle & return & "Catalyst: " & K & return & dateandtime
on error
set datastream to open for access file error_file with write permission
write ErrorLogText3_2 to datastream starting at eof
close access datastream
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("Bootle Reports!") description ErrorLogTextG_3_2 & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 2 with sticky
end tell
end try
(* EOBlock 3.2 *)
(* Block 3.3 *)
(* Writes Log file data to the log file for future reference *)
try
set datastream to open for access file the_file with write permission
write LogFileText to datastream starting at eof
close access datastream
on error
set datastream to open for access file error_file with write permission
write ErrorLogText3_3 to datastream starting at eof
close access datastream
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("Bootle Reports!") description ErrorLogTextG_3_3 & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 2 with sticky
end tell
end try
(* EOBlock 3.3 *)
(* Block 3.4 *)
(* Pushes Growl notification to left hand machine *)
(*DON'T FORGET TO REMOVE QUOTES AROUND EPPC BIT*)
try
do shell script "screencapture -tjpg " & quoted form of picPath
tell application "GrowlHelperApp" (*of machine "eppc://UserName:Password@Derby-Counter-Left.local"*)
set appName to "Bootle26"
set notificationName to "Bootle26"
set notifs to {notificationName}
register as application appName all notifications notifs default notifications notifs
notify with name notificationName title ("RED FLAG!" & return & MacName) description "The User was logged out!" & return & "At " & theTime application name appName icon of application "BootleAppIcon" priority 2 with sticky
end tell
on error
set datastream to open for access file error_file with write permission
write ErrorLogText3_4 to datastream starting at eof
close access datastream
end try
(* EOBlock 3.4 *)
(* DON'T FORGET TO REMOVE THE QUOTES ROUND THE BELOW COMMAND!! *)
(* The next command is what logs the user out of their machine, it is commented so as to allow script development, as constantly being logged out is incredibly annoying *)
--do shell script "'/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession' -suspend"
end redKeyword
(* EOBlock 3 *)
Half way through creating Bootle26, I started learning Objective-C, but, oddly, found that the more I learned about Obj-C, the easier it became to finish Bootle in AppleScript.
Bootle is my baby, so be nice. (And yes, I do know about Safari’s Private Browsing mode, but that’s not applicable here.)
Dan.
Model: iMac
Browser: Safari 533.16
Operating System: Mac OS X (10.6)