Skip to content
Snippets Groups Projects
Commit cd4212a3 authored by Rusty Myers's avatar Rusty Myers
Browse files

Releasing Version 2.2 of Idle Logout.app

parent 66cf329d
No related branches found
Tags 2.2
No related merge requests found
#tag Class Protected Class IdleLogout Inherits Application #tag Event Sub Open() Dim debugFileName as string Dim theDate as date dim mXMLtreeToFollow(-1) as string dim mPrefKeyFoundData(-1) as string dim mTempFoundPlistData as string = "" // Local variable to use for gathering plist settings theDate = new Date Globals.gAppFolderItem = GetFolderItem("/Users/Shared/", FolderItem.PathTypeShell) if Globals.gAppFolderItem.Exists = false then Globals.gAppFolderItem = GetFolderItem("/tmp/", FolderItem.PathTypeShell) MsgBox "Can't find /Users/Shared! Using /tmp/ for logs" end // Set the name of the log debugFileName = "psuIdleLogout.RUN" + MiscMethods.PadData("0",2,str(theDate.Year),Globals.kLogToFileDisable) _ + "-" + MiscMethods.PadData("0",2,str(theDate.Month),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Day),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Hour),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Minute),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Second),Globals.kLogToFileDisable) + ".log" // Initilize the log, quit if we can't create the log if not (LogToFile.Initialize(debugFileName,Globals.gAppFolderItem)) then beep MsgBox "Error creating run log file! Exiting..." quit end if // Keep only the last 5 logs if ( LogToFile.DeleteOldLogs(5) ) then LogToFile("Deleted Old Logs") end if // Get App Prefs Prefs = new TTsSmartPreferences("edu.psu.idlelogout") // Check for the user to ignore pIgnoreUser = Prefs.Value("IgnoreUser", "macadmin") // Check the group to ignore pIgnoreGroup = Prefs.Value ("IgnoreGroup", "admin") // How long should we wait before considering the Mac is idle too long? pComputerIdleAfterNumSeconds = Prefs.Value("ComputerIdleAfterNumSeconds", 600) // How often should we check to see how long the Mac has been idle? pIdleLoopDelaySeconds = Prefs.Value("IdleLoopDelaySeconds", 30) // How long should we wait for the user to respond for More Time or to Log Out? pWaitForUserPromptSeconds = Prefs.Value("WaitForUserPromptSeconds",90) // What should we display on the popup window text pWindowMessage = Prefs.Value("WindowMessage",pWindowMessage) // Create temp string with new line char Dim cr As String cr = EndOfLine.Unix // Replace \n with new line chars pWindowMessage = ReplaceAllB(pWindowMessage, "\n", EndOfLine) // Update Window Message LogoutWarning.WarningMessage.setString(pWindowMessage) // What should the Title Be in the Popup Window pWindowTitle = Prefs.Value("WindowTitle","Idle Logout Alert") // Update Window Title LogoutWarning.WarningTitle.setString(pWindowTitle) // Set Values in the Plist - Probably don't need to touch the disk 'Prefs.Value("IgnoreUser") = pIgnoreUser 'Prefs.Value ("IgnoreGroup") = pIgnoreGroup 'Prefs.Value("ComputerIdleAfterNumSeconds") = pComputerIdleAfterNumSeconds 'Prefs.Value("IdleLoopDelaySeconds") = pIdleLoopDelaySeconds 'Prefs.Value("WaitForUserPromptSeconds") = pWaitForUserPromptSeconds 'Prefs.Value("WindowMessage") = pWindowMessage 'Prefs.Value("WindowTitle") = pWindowTitle 'Prefs.Sync LogToFile(CurrentMethodName + ": Received user exception = " + str(pIgnoreUser) ) LogToFile(CurrentMethodName + ": Received group exception = " + str(pIgnoreGroup) ) LogToFile(CurrentMethodName + ": Received ComputerIdleAfterNumSeconds = " + str(pComputerIdleAfterNumSeconds) ) LogToFile(CurrentMethodName + ": Received IdleLoopDelaySecond, = " + str(pIdleLoopDelaySeconds) ) LogToFile(CurrentMethodName + ": Received WaitForUserPromptSeconds = " + str(pWaitForUserPromptSeconds) ) // Is this user macadmin? if ( MiscMethods.CurrentUsername(pIgnoreUser) ) then // It is macadmin, quit the app LogToFile("Current user is " + pIgnoreUser + ", quiting app") quit else LogToFile("User is not " + pIgnoreUser + ", continuing") end if // Is this user an admin? if ( MiscMethods.CurrentGroup(pIgnoreGroup) ) then // It is macadmin, quit the app LogToFile("Current user is an " + pIgnoreGroup + ", quiting app") quit else LogToFile("User is not an " + pIgnoreGroup + ", continuing") end if // Hide window from view at start LogoutWarning.Hide() // Start IdleThread LogToFile(CurrentMethodName + ": Running IdleThread") // start thread to watch for idle StartIdleWatch() // exit app now LogToFile(CurrentMethodName + ": <---") End Sub #tag EndEvent #tag Method, Flags = &h0 Sub forceLogout() LogToFile(CurrentMethodName + ": --->") // Testing mode, use say instead of logout Dim s As Shell s=New Shell dim ShellResults as string s.Mode = 0 // Log LogToFile(CurrentMethodName + ": START Killing Apps") // Graceful quit of apps LogToFile(CurrentMethodName + ": Quiting all launched from /Applications") s.Execute("ps axxx -o comm | grep ""/Applications"" | grep -v grep | awk -F'.app' '{print $1"".app""}'") Dim runningapps as string runningapps = s.Result // Create New Array for running apps Dim appArray() as String // Place each line in new array appArray=SPLIT(runningapps,EndOfLine) // For each app in the array try to graceful quit For Each appPath as string in appArray if appPath = "" then Continue end LogToFile("Quiting: " + appPath) s.Execute("osascript -e 'quit app ""appPath""'") LogToFile(" Exit Code: " + str(s.ErrorCode)) Next // kill the apps that are open from /Apps LogToFile(CurrentMethodName + ": Killing all launched from /Applications") s.Execute("kill -9 `ps axxx | grep ""/Applications"" | awk '{print $1}'`") LogToFile(CurrentMethodName + ": App Kill Results: " + s.Result) // Log out our user with force LogToFile(CurrentMethodName + ": Tell AppleScript to log it out") // New method to logout with osascript. s.Execute("osascript -e 'tell application ""System Events"" to keystroke ""q"" using {command down, shift down, option down}'") LogToFile(CurrentMethodName + ": LogOut AS Results: " + s.Result) // Log and quit LogToFile(CurrentMethodName + ": <---") End Sub #tag EndMethod #tag Method, Flags = &h0 Function IdleSeconds() As Integer // Set up variables for idle time // Shell result Dim mIdleSecs As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "/bin/echo $((`/usr/sbin/ioreg -c IOHIDSystem | /usr/bin/sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))" // Set results to mIdleResult mIdleSecs = s.Result // Set error code to mIdleError merrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) Return val(mIdleSecs) End Function #tag EndMethod #tag Method, Flags = &h0 Function makeFolder(mkdirPath As string) As Boolean // Set up variables for idle time // Shell result = mkdirPath // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "mkdir -p /Users/Shared" // Set results to mIdleResult mkdirPath = s.Result // Set error code to mIdleError merrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) if mkdirPath = "0" then return true else return false end End Function #tag EndMethod #tag Method, Flags = &h0 Function RemoteControlCheck() As Boolean // Set up variables for idle time Dim stablished as String = "ESTABLISHED" // Shell result Dim rccheck As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check for connection s.Execute "/usr/sbin/netstat -n | /usr/bin/grep '.5900'| /usr/bin/awk '{print $6}'" // Set results to rccheck // Make the entire returned text uppercase in case Apple ever changes the case to CaMeL CaSe, which would break our code: rccheck = Uppercase(s.Result) //LogToFile("rccheck: " + rccheck) // Set error code to merrCode merrCode = s.ErrorCode // LogToFile("rccheck: "+ rccheck) // LogToFile("stablished: "+ stablished) If ( InStr( rccheck, stablished ) > 0 ) then return true else //LogToFile("rccheck: false") return false End if // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) End Function #tag EndMethod #tag Method, Flags = &h0 Sub StartIdleWatch() // if the new WatchForIdleThread is not created, do it now if ( pWatchForIdleThread = nil ) then // instatiate new thread with enumerated type pWatchForIdleThread = _ new WatchForIdleThread(Int32(eTaskType.StartIdleWatch )) // add custom methods for run and finished handlers AddHandler pWatchForIdleThread.Run, WeakAddressOf Thread_WaitForIdleTime AddHandler pWatchForIdleThread.Finished, WeakAddressOf Thread_Finished end if // Run the thread if it's not already running: if ( pWatchForIdleThread.State <> Thread.Running ) then // Hide window during idle watch LogoutWarning.Hide() // Set label to default countdown time LogoutWarning.TimeLabel.setString(str(pWaitForUserPromptSeconds)) // run the new thread pWatchForIdleThread.Run end if End Sub #tag EndMethod #tag Method, Flags = &h0 Sub StartUserCountDown() // if the new WatchForIdleThread is not created, do it now if ( pIdleCountDownThread = nil ) then // instatiate new thread with enumerated type pIdleCountDownThread = _ new WatchForIdleThread(Int32(eTaskType.StartUserCountDown )) // add custom methods for run and finished handlers AddHandler pIdleCountDownThread.Run, WeakAddressOf Thread_WaitForUserInput AddHandler pIdleCountDownThread.Finished, WeakAddressOf Thread_Finished end if // Run the thread if it's not already running if ( pIdleCountDownThread.State <> Thread.Running ) then // run the new thread pIdleCountDownThread.Run end if End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_Finished(paramThread as WatchForIdleThread) LogToFile(CurrentMethodName + ": --->") // Kill the thread that was used to get here paramThread.Kill // Found out which thread just finished select case Int32 ( paramThread.pTaskType ) // If the StartIdleWatch thread just finished case int32( eTaskType.StartIdleWatch ) // LogToFile(CurrentMethodName + ": Idle time has expired.") // Show Login Window LogoutWarning.Show() // start logout countdown window StartUserCountDown() case int32 ( eTaskType.StartUserCountDown ) // LogToFile(CurrentMethodName + ": No user response from countdown.") // LogToFile(CurrentMethodName + ": LogoutWarning.pMoreTimeAskedFor = " +str(pMoreTimeAskedFor)) // If the user (or anyone) asked for more time if (pMoreTimeAskedFor) then // if the user asks for more time, start the idle watch thread again // Restart Idle Watch StartIdleWatch() else // if the user ran out of time, start the logout // kill user logins forceLogout() end if else end select End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_WaitForIdleTime(paramThread as WatchForIdleThread) // Set up new integer to store idle seconds Dim mIdleResult As Integer // get current idle seconds mIdleResult = IdleSeconds() // LogToFile(CurrentMethodName + " Idle Seconds: " + str(mIdleResult)) // LogToFile(CurrentMethodName + " waiting for " + str(LogoutWarning.pComputerIdleAfterNumSeconds)) // While our idle result is less than max time while ( mIdleResult < pComputerIdleAfterNumSeconds ) // Wait pIdleLoopDelaySeconds each loop App.SleepCurrentThread( pIdleLoopDelaySeconds * 1000 ) // Check idle time: mIdleResult = IdleSeconds() // Log our time idle LogToFile(CurrentMethodName + ": Idle Seconds: " + str(mIdleResult)) wend // while there is a ARD/VNC session, don't idle out (netstat -n | grep '.5900') while (RemoteControlCheck() ) // Wait pIdleLoopDelaySeconds each loop App.SleepCurrentThread( pIdleLoopDelaySeconds * 1000 ) // Log LogToFile(CurrentMethodName + ": Someone is controlling via ARD/VNC, waiting...") wend // When there is not remote control LogToFile(CurrentMethodName + ": No one is controlling via ARD/VNC, continuing...") End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_WaitForUserInput(paramThread as WatchForIdleThread) LogToFile(CurrentMethodName + ": --->") // Set how long to wait before logging out user, set from global variable for LogOutDelay Dim pLogoutDelay as Integer = pWaitForUserPromptSeconds // While we're waiting for the countdown to finish... While pLogoutDelay >= 0 // LogToFile(CurrentMethodName + "Time Left: " + str(pLogoutDelay)) // Set global variable to the time left pCountDownTime = pLogoutDelay // call updateUI to set countdown label pIdleCountDownThread.UpdateUI() // take a second away from the time left pLogoutDelay = pLogoutDelay - 1 // do nothing for 1 second App.SleepCurrentThread( 1000 ) // sleep 1 second Wend // If we're here, the user didn't cancel or log out manaully // user did not ask for more time pMoreTimeAskedFor = false // Log LogToFile(CurrentMethodName + ": Time Out for Response. Log User Out...") // Done here LogToFile(CurrentMethodName + ": <---") // Return to Thread_Finished End Sub #tag EndMethod #tag Note, Name = Icon Application Icon use with CC license: From http://www.flickr.com/photos/23453447@N02/5107438855/sizes/o/in/photostream/ By zyrquel http://www.flickr.com/photos/23453447@N02/ #tag EndNote #tag Note, Name = Tests New builds should be tested for: Launching Hiding Dock Icon Logging to File Reading Preferences Reading Idle Time Countdown Timer starts when idle time reached Countdown Window Shows More Time button resets the clock Log Out Button quits open apps and logs out Timer Runs out and Auto-Logs Out Remove Control Blocks logout Custom Name Custom Text defaults write /Library/Preferences/edu.psu.idlelogout.plist IgnoreUser -string clcclmadmin defaults write /Library/Preferences/edu.psu.idlelogout.plist IgnoreGroup -string user defaults write /Library/Preferences/edu.psu.idlelogout.plist ComputerIdleAfterNumSeconds -string 10 defaults write /Library/Preferences/edu.psu.idlelogout.plist IdleLoopDelaySeconds -string 5 defaults write /Library/Preferences/edu.psu.idlelogout.plist WaitForUserPromptSeconds -string 120 defaults write /Library/Preferences/edu.psu.idlelogout.plist WindowTitle -string "Our Idle Logout" defaults write /Library/Preferences/edu.psu.idlelogout.plist WindowMessage "You're going to be logged out\n\n\nDude\!" #tag EndNote #tag Property, Flags = &h0 pAppVersion As String = "2.1" #tag EndProperty #tag Property, Flags = &h0 pComputerIdleAfterNumSeconds As Integer = 900 #tag EndProperty #tag Property, Flags = &h0 pCountDownTime As Integer #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFileName As String = "edu.psu.its.clc.IdleLogoutSettings.plist" #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFSPath As String = "/Library/CLMadmin/Config/" #tag EndProperty #tag Property, Flags = &h0 pIdleCountDownThread As WatchForIdleThread #tag EndProperty #tag Property, Flags = &h0 pIdleLoopDelaySeconds As Integer = 60 #tag EndProperty #tag Property, Flags = &h0 pIgnoreGroup As String = "admin" #tag EndProperty #tag Property, Flags = &h0 pIgnoreUser As String = "clmadmin" #tag EndProperty #tag Property, Flags = &h0 pMoreTimeAskedFor As Boolean = true #tag EndProperty #tag Property, Flags = &h0 Prefs As TTsSmartPreferences #tag EndProperty #tag Property, Flags = &h0 pWaitForUserPromptSeconds As Integer = 90 #tag EndProperty #tag Property, Flags = &h0 pWatchForIdleThread As WatchForIdleThread #tag EndProperty #tag Property, Flags = &h0 pWindowMessage As String = "This Mac is now Idle.\n\nClick the ""More Time"" button to continue using the Mac.\n\nOtherwise, an automatic logout will occur and all unsaved documents will be LOST!" #tag EndProperty #tag Property, Flags = &h0 pWindowTitle As String #tag EndProperty #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete" #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete" #tag EndConstant #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit" #tag EndConstant #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q" #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q" #tag EndConstant #tag Enum, Name = eTaskType, Type = Int32, Flags = &h0 StartIdleWatch StartUserCountDown #tag EndEnum #tag ViewBehavior #tag ViewProperty Name="pAppVersion" Group="Behavior" InitialValue="1.1" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pComputerIdleAfterNumSeconds" Group="Behavior" InitialValue="900" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pCountDownTime" Group="Behavior" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pDefaultPrefsFileName" Group="Behavior" InitialValue="edu.psu.its.clc.IdleLogoutSettings.plist" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pDefaultPrefsFSPath" Group="Behavior" InitialValue="/Library/CLMadmin/Config/" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pIdleLoopDelaySeconds" Group="Behavior" InitialValue="60" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pIgnoreGroup" Group="Behavior" InitialValue="admin" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pIgnoreUser" Group="Behavior" InitialValue="macadmin" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pMoreTimeAskedFor" Group="Behavior" InitialValue="true" Type="Boolean" #tag EndViewProperty #tag ViewProperty Name="pWaitForUserPromptSeconds" Group="Behavior" InitialValue="90" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pWindowMessage" Group="Behavior" InitialValue="'This Mac is idle. Click the """"More Time"""" button to continue using the Mac. Otherwise, an automatic logout will occur and all unsaved documents will be LOST!" Type="String" #tag EndViewProperty #tag ViewProperty Name="pWindowTitle" Group="Behavior" Type="String" #tag EndViewProperty #tag EndViewBehavior End Class #tag EndClass
\ No newline at end of file
#tag Class Protected Class IdleLogout Inherits Application #tag Event Sub Open() Dim debugFileName as string Dim theDate as date dim mXMLtreeToFollow(-1) as string dim mPrefKeyFoundData(-1) as string dim mTempFoundPlistData as string = "" // Local variable to use for gathering plist settings theDate = new Date Globals.gAppFolderItem = GetFolderItem("/Users/Shared/", FolderItem.PathTypeShell) if Globals.gAppFolderItem.Exists = false then Globals.gAppFolderItem = GetFolderItem("/tmp/", FolderItem.PathTypeShell) MsgBox "Can't find /Users/Shared! Using /tmp/ for logs" end // Set the name of the log debugFileName = "psuIdleLogout.RUN" + MiscMethods.PadData("0",2,str(theDate.Year),Globals.kLogToFileDisable) _ + "-" + MiscMethods.PadData("0",2,str(theDate.Month),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Day),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Hour),Globals.kLogToFileDisable) + "-" debugFileName = debugFileName + MiscMethods.PadData("0",2,str(theDate.Minute),Globals.kLogToFileDisable) + _ "-" + MiscMethods.PadData("0",2,str(theDate.Second),Globals.kLogToFileDisable) + ".log" // Initilize the log, quit if we can't create the log if not (LogToFile.Initialize(debugFileName,Globals.gAppFolderItem)) then beep MsgBox "Error creating run log file! Exiting..." quit end if // Keep only the last 5 logs if ( LogToFile.DeleteOldLogs(5) ) then LogToFile("Deleted Old Logs") end if // Get App Prefs Prefs = new TTsSmartPreferences("edu.psu.idlelogout") // Check for the user to ignore pIgnoreUser = Prefs.Value("IgnoreUser", "macadmin") // Check the group to ignore pIgnoreGroup = Prefs.Value ("IgnoreGroup", "admin") // How long should we wait before considering the Mac is idle too long? pComputerIdleAfterNumSeconds = Prefs.Value("ComputerIdleAfterNumSeconds", 600) // How often should we check to see how long the Mac has been idle? pIdleLoopDelaySeconds = Prefs.Value("IdleLoopDelaySeconds", 30) // How long should we wait for the user to respond for More Time or to Log Out? pWaitForUserPromptSeconds = Prefs.Value("WaitForUserPromptSeconds",90) // What should we display on the popup window text pWindowMessage = Prefs.Value("WindowMessage",pWindowMessage) // Create temp string with new line char Dim cr As String cr = EndOfLine.Unix // Replace \n with new line chars pWindowMessage = ReplaceAllB(pWindowMessage, "\n", EndOfLine) // Update Window Message LogoutWarning.WarningMessage.setString(pWindowMessage) // What should the Title Be in the Popup Window pWindowTitle = Prefs.Value("WindowTitle","Idle Logout Alert") // Update Window Title LogoutWarning.WarningTitle.setString(pWindowTitle) // Set Values in the Plist - Probably don't need to touch the disk 'Prefs.Value("IgnoreUser") = pIgnoreUser 'Prefs.Value ("IgnoreGroup") = pIgnoreGroup 'Prefs.Value("ComputerIdleAfterNumSeconds") = pComputerIdleAfterNumSeconds 'Prefs.Value("IdleLoopDelaySeconds") = pIdleLoopDelaySeconds 'Prefs.Value("WaitForUserPromptSeconds") = pWaitForUserPromptSeconds 'Prefs.Value("WindowMessage") = pWindowMessage 'Prefs.Value("WindowTitle") = pWindowTitle 'Prefs.Sync LogToFile(CurrentMethodName + ": Received user exception = " + str(pIgnoreUser) ) LogToFile(CurrentMethodName + ": Received group exception = " + str(pIgnoreGroup) ) LogToFile(CurrentMethodName + ": Received ComputerIdleAfterNumSeconds = " + str(pComputerIdleAfterNumSeconds) ) LogToFile(CurrentMethodName + ": Received IdleLoopDelaySecond, = " + str(pIdleLoopDelaySeconds) ) LogToFile(CurrentMethodName + ": Received WaitForUserPromptSeconds = " + str(pWaitForUserPromptSeconds) ) // Is this user macadmin? if ( MiscMethods.CurrentUsername(pIgnoreUser) ) then // It is macadmin, quit the app LogToFile("Current user is " + pIgnoreUser + ", quiting app") quit else LogToFile("User is not " + pIgnoreUser + ", continuing") end if // Is this user an admin? if ( MiscMethods.CurrentGroup(pIgnoreGroup) ) then // It is macadmin, quit the app LogToFile("Current user is an " + pIgnoreGroup + ", quiting app") quit else LogToFile("User is not an " + pIgnoreGroup + ", continuing") end if // Hide window from view at start LogoutWarning.Hide() // Start IdleThread LogToFile(CurrentMethodName + ": Running IdleThread") // start thread to watch for idle StartIdleWatch() // exit app now LogToFile(CurrentMethodName + ": <---") End Sub #tag EndEvent #tag Method, Flags = &h0 Sub forceLogout() LogToFile(CurrentMethodName + ": --->") // Testing mode, use say instead of logout Dim s As Shell s=New Shell dim ShellResults as string s.Mode = 0 // Log LogToFile(CurrentMethodName + ": START Killing Apps") // Graceful quit of apps LogToFile(CurrentMethodName + ": Quiting all launched from /Applications") s.Execute("ps axxx -o comm | grep ""/Applications"" | grep -v grep | awk -F'.app' '{print $1"".app""}'") Dim runningapps as string runningapps = s.Result // Create New Array for running apps Dim appArray() as String // Place each line in new array appArray=SPLIT(runningapps,EndOfLine) // For each app in the array try to graceful quit For Each appPath as string in appArray if appPath = "" then Continue end LogToFile("Quiting: " + appPath) s.Execute("osascript -e 'quit app ""appPath""'") LogToFile(" Exit Code: " + str(s.ErrorCode)) Next // kill the apps that are open from /Apps LogToFile(CurrentMethodName + ": Killing all launched from /Applications") s.Execute("kill -9 `ps axxx | grep ""/Applications"" | awk '{print $1}'`") LogToFile(CurrentMethodName + ": App Kill Results: " + s.Result) // Log out our user with force LogToFile(CurrentMethodName + ": Tell AppleScript to log it out") // New method to logout with osascript. s.Execute("osascript -e 'tell application ""System Events"" to keystroke ""q"" using {command down, shift down, option down}'") LogToFile(CurrentMethodName + ": LogOut AS Results: " + s.Result) // Log and quit LogToFile(CurrentMethodName + ": <---") End Sub #tag EndMethod #tag Method, Flags = &h0 Function IdleSeconds() As Integer // Set up variables for idle time // Shell result Dim mIdleSecs As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "/bin/echo $((`/usr/sbin/ioreg -c IOHIDSystem | /usr/bin/sed -e '/HIDIdleTime/ !{ d' -e 't' -e '}' -e 's/.* = //g' -e 'q'` / 1000000000))" // Set results to mIdleResult mIdleSecs = s.Result // Set error code to mIdleError merrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) Return val(mIdleSecs) End Function #tag EndMethod #tag Method, Flags = &h0 Function makeFolder(mkdirPath As string) As Boolean // Set up variables for idle time // Shell result = mkdirPath // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check idle time from USB input devices s.Execute "mkdir -p /Users/Shared" // Set results to mIdleResult mkdirPath = s.Result // Set error code to mIdleError merrCode = s.ErrorCode // Log mIdleResult for debugging // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) if mkdirPath = "0" then return true else return false end End Function #tag EndMethod #tag Method, Flags = &h0 Function RemoteControlCheck() As Boolean // Set up variables for idle time Dim stablished as String = "ESTABLISHED" // Shell result Dim rccheck As String // Shell exit code Dim merrCode As Integer // Set up shell Dim s As Shell s=New Shell s.Mode = 0 // Check idle time //s.Execute code to check for connection s.Execute "/usr/sbin/netstat -n | /usr/bin/grep '.5900'| /usr/bin/awk '{print $6}'" // Set results to rccheck // Make the entire returned text uppercase in case Apple ever changes the case to CaMeL CaSe, which would break our code: rccheck = Uppercase(s.Result) //LogToFile("rccheck: " + rccheck) // Set error code to merrCode merrCode = s.ErrorCode // LogToFile("rccheck: "+ rccheck) // LogToFile("stablished: "+ stablished) If ( InStr( rccheck, stablished ) > 0 ) then return true else //LogToFile("rccheck: false") return false End if // System.Log(System.LogLevelError, "Method: " + midleSecs) // LogToFile("mIdleSeconds: " + str(mIdleSecs)) End Function #tag EndMethod #tag Method, Flags = &h0 Sub StartIdleWatch() // if the new WatchForIdleThread is not created, do it now if ( pWatchForIdleThread = nil ) then // instatiate new thread with enumerated type pWatchForIdleThread = _ new WatchForIdleThread(Int32(eTaskType.StartIdleWatch )) // add custom methods for run and finished handlers AddHandler pWatchForIdleThread.Run, WeakAddressOf Thread_WaitForIdleTime AddHandler pWatchForIdleThread.Finished, WeakAddressOf Thread_Finished end if // Run the thread if it's not already running: if ( pWatchForIdleThread.State <> Thread.Running ) then // Hide window during idle watch LogoutWarning.Hide() // Set label to default countdown time LogoutWarning.TimeLabel.setString(str(pWaitForUserPromptSeconds)) // run the new thread pWatchForIdleThread.Run end if End Sub #tag EndMethod #tag Method, Flags = &h0 Sub StartUserCountDown() // if the new WatchForIdleThread is not created, do it now if ( pIdleCountDownThread = nil ) then // instatiate new thread with enumerated type pIdleCountDownThread = _ new WatchForIdleThread(Int32(eTaskType.StartUserCountDown )) // add custom methods for run and finished handlers AddHandler pIdleCountDownThread.Run, WeakAddressOf Thread_WaitForUserInput AddHandler pIdleCountDownThread.Finished, WeakAddressOf Thread_Finished end if // Run the thread if it's not already running if ( pIdleCountDownThread.State <> Thread.Running ) then // run the new thread pIdleCountDownThread.Run end if End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_Finished(paramThread as WatchForIdleThread) LogToFile(CurrentMethodName + ": --->") // Kill the thread that was used to get here paramThread.Kill // Found out which thread just finished select case Int32 ( paramThread.pTaskType ) // If the StartIdleWatch thread just finished case int32( eTaskType.StartIdleWatch ) // LogToFile(CurrentMethodName + ": Idle time has expired.") // Show Login Window LogoutWarning.Show() // start logout countdown window StartUserCountDown() case int32 ( eTaskType.StartUserCountDown ) // LogToFile(CurrentMethodName + ": No user response from countdown.") // LogToFile(CurrentMethodName + ": LogoutWarning.pMoreTimeAskedFor = " +str(pMoreTimeAskedFor)) // If the user (or anyone) asked for more time if (pMoreTimeAskedFor) then // if the user asks for more time, start the idle watch thread again // Restart Idle Watch StartIdleWatch() else // if the user ran out of time, start the logout // kill user logins forceLogout() end if else end select End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_WaitForIdleTime(paramThread as WatchForIdleThread) // Set up new integer to store idle seconds Dim mIdleResult As Integer // get current idle seconds mIdleResult = IdleSeconds() // LogToFile(CurrentMethodName + " Idle Seconds: " + str(mIdleResult)) // LogToFile(CurrentMethodName + " waiting for " + str(LogoutWarning.pComputerIdleAfterNumSeconds)) // While our idle result is less than max time while ( mIdleResult < pComputerIdleAfterNumSeconds ) // Wait pIdleLoopDelaySeconds each loop App.SleepCurrentThread( pIdleLoopDelaySeconds * 1000 ) // Check idle time: mIdleResult = IdleSeconds() // Log our time idle LogToFile(CurrentMethodName + ": Idle Seconds: " + str(mIdleResult)) wend // while there is a ARD/VNC session, don't idle out (netstat -n | grep '.5900') while (RemoteControlCheck() ) // Wait pIdleLoopDelaySeconds each loop App.SleepCurrentThread( pIdleLoopDelaySeconds * 1000 ) // Log LogToFile(CurrentMethodName + ": Someone is controlling via ARD/VNC, waiting...") wend // When there is not remote control LogToFile(CurrentMethodName + ": No one is controlling via ARD/VNC, continuing...") End Sub #tag EndMethod #tag Method, Flags = &h21 Private Sub Thread_WaitForUserInput(paramThread as WatchForIdleThread) LogToFile(CurrentMethodName + ": --->") // Set how long to wait before logging out user, set from global variable for LogOutDelay Dim pLogoutDelay as Integer = pWaitForUserPromptSeconds // While we're waiting for the countdown to finish... While pLogoutDelay >= 0 // LogToFile(CurrentMethodName + "Time Left: " + str(pLogoutDelay)) // Set global variable to the time left pCountDownTime = pLogoutDelay // call updateUI to set countdown label pIdleCountDownThread.UpdateUI() // take a second away from the time left pLogoutDelay = pLogoutDelay - 1 // do nothing for 1 second App.SleepCurrentThread( 1000 ) // sleep 1 second Wend // If we're here, the user didn't cancel or log out manaully // user did not ask for more time pMoreTimeAskedFor = false // Log LogToFile(CurrentMethodName + ": Time Out for Response. Log User Out...") // Done here LogToFile(CurrentMethodName + ": <---") // Return to Thread_Finished End Sub #tag EndMethod #tag Note, Name = Icon Application Icon use with CC license: From http://www.flickr.com/photos/23453447@N02/5107438855/sizes/o/in/photostream/ By zyrquel http://www.flickr.com/photos/23453447@N02/ #tag EndNote #tag Note, Name = Tests New builds should be tested for: Launching Hiding Dock Icon Logging to File Reading Preferences Reading Idle Time Countdown Timer starts when idle time reached Countdown Window Shows More Time button resets the clock Log Out Button quits open apps and logs out Timer Runs out and Auto-Logs Out Remove Control Blocks logout Custom Name Custom Text defaults write /Library/Preferences/edu.psu.idlelogout.plist IgnoreUser -string clcclmadmin defaults write /Library/Preferences/edu.psu.idlelogout.plist IgnoreGroup -string user defaults write /Library/Preferences/edu.psu.idlelogout.plist ComputerIdleAfterNumSeconds -string 10 defaults write /Library/Preferences/edu.psu.idlelogout.plist IdleLoopDelaySeconds -string 5 defaults write /Library/Preferences/edu.psu.idlelogout.plist WaitForUserPromptSeconds -string 120 defaults write /Library/Preferences/edu.psu.idlelogout.plist WindowTitle -string "Our Idle Logout" defaults write /Library/Preferences/edu.psu.idlelogout.plist WindowMessage "You're going to be logged out\n\n\nDude\!" #tag EndNote #tag Property, Flags = &h0 pAppVersion As String = "2.1" #tag EndProperty #tag Property, Flags = &h0 pComputerIdleAfterNumSeconds As Integer = 900 #tag EndProperty #tag Property, Flags = &h0 pCountDownTime As Integer #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFileName As String = "edu.psu.its.clc.IdleLogoutSettings.plist" #tag EndProperty #tag Property, Flags = &h0 pDefaultPrefsFSPath As String = "/Library/CLMadmin/Config/" #tag EndProperty #tag Property, Flags = &h0 pIdleCountDownThread As WatchForIdleThread #tag EndProperty #tag Property, Flags = &h0 pIdleLoopDelaySeconds As Integer = 60 #tag EndProperty #tag Property, Flags = &h0 pIgnoreGroup As String = "admin" #tag EndProperty #tag Property, Flags = &h0 pIgnoreUser As String = "clmadmin" #tag EndProperty #tag Property, Flags = &h0 pMoreTimeAskedFor As Boolean = true #tag EndProperty #tag Property, Flags = &h0 Prefs As TTsSmartPreferences #tag EndProperty #tag Property, Flags = &h0 pWaitForUserPromptSeconds As Integer = 90 #tag EndProperty #tag Property, Flags = &h0 pWatchForIdleThread As WatchForIdleThread #tag EndProperty #tag Property, Flags = &h0 pWindowMessage As String = "This Mac is now Idle.\n\nClick the ""More Time"" button to continue using the Mac.\n\nOtherwise, an automatic logout will occur and all unsaved documents will be LOST!" #tag EndProperty #tag Property, Flags = &h0 pWindowTitle As String #tag EndProperty #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete" #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete" #tag EndConstant #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit" #tag EndConstant #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q" #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q" #tag EndConstant #tag Enum, Name = eTaskType, Type = Int32, Flags = &h0 StartIdleWatch StartUserCountDown #tag EndEnum #tag ViewBehavior #tag ViewProperty Name="pAppVersion" Group="Behavior" InitialValue="1.1" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pComputerIdleAfterNumSeconds" Group="Behavior" InitialValue="900" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pCountDownTime" Group="Behavior" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pDefaultPrefsFileName" Group="Behavior" InitialValue="edu.psu.its.clc.IdleLogoutSettings.plist" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pDefaultPrefsFSPath" Group="Behavior" InitialValue="/Library/CLMadmin/Config/" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pIdleLoopDelaySeconds" Group="Behavior" InitialValue="60" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pIgnoreGroup" Group="Behavior" InitialValue="admin" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pIgnoreUser" Group="Behavior" InitialValue="macadmin" Type="String" EditorType="MultiLineEditor" #tag EndViewProperty #tag ViewProperty Name="pMoreTimeAskedFor" Group="Behavior" InitialValue="true" Type="Boolean" #tag EndViewProperty #tag ViewProperty Name="pWaitForUserPromptSeconds" Group="Behavior" InitialValue="90" Type="Integer" #tag EndViewProperty #tag ViewProperty Name="pWindowMessage" Group="Behavior" InitialValue="'This Mac is idle. Click the """"More Time"""" button to continue using the Mac. Otherwise, an automatic logout will occur and all unsaved documents will be LOST!" Type="String" #tag EndViewProperty #tag ViewProperty Name="pWindowTitle" Group="Behavior" Type="String" #tag EndViewProperty #tag EndViewBehavior End Class #tag EndClass
\ No newline at end of file
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment