It seems fair that you might wonder whether or not I have what it takes to, not only teach myself Python, but also not give up halfway through. To such a request I would say this:
“I taught myself AppleScript through mainly trial and (normally considerable) error. In the end I came up with what I called Bootle26. I described it as a security application, but it was more like a . . . internet nanny/taddler application. It cross referenced Safari history items with banned and iffy words we didn’t want people searching on public computers. I had help from some very friendly people on the internet, over at MacScripter, but it was mainly through sheer bloody-mindedness that I managed to get all the way up to version 2.5.4 before I moved on to something else. It worked very well and here is the proof.”
-- Bootle26, Version 2.5.4 -- © Dan Barker 2010 -- Last updated: 12/12/2010 at 2052 -- Hint? See bottom of script. set LBootleVersion to "B26 v2.5.4" property lastBlacklistHit : missing value property lastBlacklistTime : missing value property lastRedlistHit : missing value property lastRedlistTime : missing value set plistPath to (path to library folder from user domain as text) & "Safari:History.plist" tell application "System Events" set plist to property list file plistPath set webHistory to value of property list item "WebHistoryDates" of plist set firstItem to item 1 of webHistory set secondItem to item 2 of webHistory set this2URL to || of secondItem set thisTitle to |title| of firstItem set thisURL to || of firstItem set lastVisit to |lastVisitedDate| of firstItem set visCount to |visitCount| of firstItem end tell -- 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 ¬ set LongWords to thisTitle & " " & thisURL tell application "Finder" to set this_item to words of LongWords 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 set currentDate to current date if this_item_word is lastRedlistHit then if currentDate - lastRedlistTime is less than 60 then return set lastRedlistTime to currentDate else set lastRedlistHit to this_item_word set lastRedlistTime to currentDate end if my keyWords(this_item_word, false, thisTitle, thisURL, lastVisit, visCount, LBootleVersion, 0) else if this_item_word is in blackWords then set currentDate to current date if this_item_word is lastBlacklistHit then if currentDate - lastBlacklistTime is less than 60 then return set lastBlacklistTime to currentDate else set lastBlacklistHit to this_item_word set lastBlacklistTime to currentDate end if my keyWords(this_item_word, true, thisTitle, thisURL, lastVisit, visCount, LBootleVersion, this2URL) end if end repeat on keyWords(N, isBlack, tTit, tURL, laV, visC, LBv, t2u) set White_File to (open for access ("Macintosh HD:Library:Application Support:Bootle26:Wordlists:White List.txt")) set txt3 to (read White_File for (get eof White_File)) set WhiteWords to every paragraph of txt3 close access White_File set cDate to current date set theDate to date string of cDate set theTime to time string of cDate set theSHORTdate to short date string of cDate set dateandtime to "At " & theTime & " on " & theDate -- Hint can be added from now! 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:" & ErrorFileName if isBlack then set SCDump to "Blacklist" else set SCDump to "RedFlag List" end if set SCnum to my doMath(theTime, theSHORTdate) set SCID to N & " " & SCnum set picPath to "/Library/Application Support/Bootle26/Screenshots/" & SCDump & "/" & SCID & ".png" -- Creates slightly different error terms for the Growl Sub Routine ¬ set ErrorLogTextGG to "Reports error code #" set ErrorLogTextGG2 to ErrorLogTextGG & "2.3" & return & "An issue with the Log File" & return & "Unique " & SCnum & return & LBv set GrowlError to ErrorLogTextGG2 -- General Error Texts ¬ set ErrorLogText0 to return & return & "Bootle Error Message!" & return & MacName & return & dateandtime & return & "Reports error code #" set ErrorLogText2_3 to ErrorLogText0 & "2.3" & return & "An issue with the Log File" & return & "Alert " & SCnum & return & LBv set ErrorLogText2_4 to ErrorLogText0 & "2.4" & return & "An issue with ScreenCap" & return & "Alert " & SCnum & return & LBv set ErrorLogText2_5 to ErrorLogText0 & "2.5" & return & "An issue with Growl/Network/Authentication" & return & "Alert " & SCnum & return & LBv set theurl to item 2 of tURL if theurl is "block.opendns.com" then set theurl to "Blocked by OpenDNS" else -- asiz end if set SafTitle to tTit set t2t to word 2 of t2u if tURL is in WhiteWords then set AlertState to false else set AlertState to true end if set the_file to "Macintosh HD:Library:Application Support:Bootle26:Machine Logs:" & LogFileName if isBlack then else -- Below script is used for new BETA feature, SaR -- BEGIN BETA set K to count characters of N set Sc to character 1 of N set Ec to last character of N set AppleScript's text item delimiters to {Sc, Ec} set delimitedList to every text item of N set delimChars to every character of item 2 of delimitedList set findtext to delimChars try set newN to my SaR(N, findtext, "*") on error set newN to "SaR Error #1" set K to "E" end try -- END BETA end if if isBlack then set BootleAlertLevel to "Blacklist Warning!" set VisHelp to "" try my SCD(picPath) set SCDcheck to "SCD: Success" on error my write_error_log(ErrorLogText2_4, ErrorFileName) set SCDcheck to "SCD: Failed" end try set GrowlDes to "Catalyst: " & N & return & theurl & return & "At " & theTime & return & "Alert " & SCnum & return & SCDcheck & " • " & LBv set GrowlLevel to 0 else set BootleAlertLevel to "RED FLAG!" set VisHelp to "00000000" try my SCD(picPath) set SCDcheck to "SCD: Success" on error my write_error_log(ErrorLogText2_4, ErrorFileName) set SCDcheck to "SCD: Failed" end try set GrowlDes to "The User was logged out!" & return & "Catalyst: " & newN & " (" & K & ")" & return & "At " & theTime & return & "Alert " & SCnum & return & SCDcheck & " • " & LBv set GrowlLevel to 2 end if set LogFileText to return & return & "000000000000000000" & VisHelp & return & BootleAlertLevel & return & "User of " & MacName & " requests: " & return & theurl & return & "Title: " & SafTitle & return & "Path to: " & t2t & return & "Alert State: " & AlertState & return & "Catalyst: " & N & return & "Alert " & SCnum & return & "Last Visited Date: " & laV & return & "Visit Count: " & visC & return & dateandtime & return & LBv & return & "000000000000000000" & VisHelp 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 my write_error_log(ErrorLogText2_3, ErrorFileName) set BootleAlertLevel to "Bootle Reports!" set GrowlLevel to -2 set AlertState to true my AlertStaff(AlertState, BootleAlertLevel, MacName, GrowlError, GrowlLevel) end try -- Pushes Growl notification to left hand machine try my AlertStaff(AlertState, BootleAlertLevel, MacName, GrowlDes, GrowlLevel) if isBlack then else try delay 1.5 do shell script "killall 'Safari'" on error -- don't bother then. end try delay 1 -- DON'T FORGET TO REMOVE THE DASHES BEFORE THE BELOW COMMAND!! --do shell script "'/System/Library/CoreServices/Menu Extras/User.menu/Contents/Resources/CGSession' -suspend" end if on error my write_error_log(ErrorLogText2_5, ErrorFileName) end try end keyWords -- -- Start of SaR -- on SaR(sourceText, findtt, replaceText) set {atid, AppleScript's text item delimiters} to {AppleScript's text item delimiters, findtt} set tempText to text items of sourceText set AppleScript's text item delimiters to replaceText set sourceText to tempText as string set AppleScript's text item delimiters to atid return sourceText end SaR on doMath(tTime, tSDate) set AppleScript's text item delimiters to {":"} set delimitedList01 to every text item of tTime set AppleScript's text item delimiters to {"/"} set delimitedList02 to every text item of tSDate set |day| to item 1 of delimitedList02 set |month| to item 2 of delimitedList02 set Anchor to |day| & |month| if item 2 of delimitedList01 is "00" then set item 2 of delimitedList01 to "13" else --nothing end if if item 3 of delimitedList01 is "00" then set item 3 of delimitedList01 to "13" else --nothing end if set theMath to (item 2 of delimitedList01) * (item 3 of delimitedList01) * 3 set SCnum to "ID#" & Anchor & theMath end doMath on SCD(pP) do shell script "screencapture -tjpg " & quoted form of pP end SCD on write_error_log(this_error, EFile) set error_file to "Macintosh HD:Library:Application Support:Bootle26:Error Log:" & EFile try open for access file the error_file with write permission write (this_error) to file the error_file starting at eof close access file the error_file on error try close access file the error_file end try end try end write_error_log on AlertStaff(AState, AlertLevel, McNme, gDes, GAL) if AState is true then set appName to "Bootle26" set notificationName to "Bootle26" set notifs to {notificationName} tell application "Growl" --of machine "eppc://User:Pass@Derby-Counter-Left.local" register as application appName all notifications notifs default notifications notifs notify with name notificationName title (AlertLevel & return & McNme) description gDes application name appName icon of application "BootleAppIcon" priority GAL with sticky end tell else -- Don't Alert Staff! end if end AlertStaff on write_dev_log(the_log, DAT) set dev_file to (path to desktop folder from user domain as text) & "B26 Dev Log" try open for access file the dev_file with write permission write return & DAT & return & the_log to file the dev_file starting at eof close access file the dev_file on error try close access file the dev_file end try end try end write_dev_log (* Hint: Developing Bootle26? Got a bit that's not working? Add ' my write_dev_log(, dateandtime) ' Make sure to remove it before you load it onto your machines though. Credits: Author: Dan Barker Script help: MacScripter.net MacRumors.com (forum) Rob Whitaker Wordlist help: Dave Novis *)
If I can do that, then I can do this.
You’re more than welcome to download Bootle26 and use it for yourself, just know that I haven’t done anything with it since 2010.