Advertisement
twiz

Plex Anti-Idle.ahk

May 3rd, 2018 (edited)
402
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #SingleInstance, Force  ; Allow only one instance of the script to run
  2. #NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
  3. #Persistent ; Keep the script 'alive' in the tray
  4.  
  5. productName         := "twiz AntiIdle"
  6. clientIdentifier    := A_ComputerName
  7. iniFile := A_ScriptDir "\PlexAntiIdle.ini"
  8. Gosub, ReadINI
  9.  
  10. If !FileExist(iniFile) {
  11.     Gosub, WriteINI
  12. }
  13.  
  14. If PlexToken {
  15.     IsValid := VerifyToken(PlexToken)
  16. }
  17.  
  18. If !IsValid {
  19.     Gosub, GeneratePin
  20. }
  21.  
  22. ;Multiply the value by 60000 to use minutes (1,000ms = 1sec, 60,0000ms = 60 sec)
  23. UpdateTimer := 60000 * UpdateTimer
  24. MaxIdleTime := 60000 * MaxIdleTime
  25. PlexURL     := "http://" PlexIP ":" PlexPort "/status/sessions?X-Plex-Token=" PlexToken
  26.  
  27. ; Create a repeating Timer to check if Idle
  28. SetTimer, CheckIdle, %UpdateTimer%
  29. Return
  30.  
  31.  
  32.  
  33. ReadINI:
  34.     iniRead, UpdateTimer,   %iniFile%, Plex, UpdateTimer,   5
  35.     iniRead, MaxIdleTime,   %iniFile%, Plex, MaxIdleTime,   10
  36.     iniRead, PlexIP,        %iniFile%, Plex, PlexIP,        127.0.0.1
  37.     iniRead, PlexPort,      %iniFile%, Plex, PlexPort,      32400
  38.     iniRead, PlexToken, %iniFile%, Plex, PlexToken,     %A_Space%
  39. Return
  40.  
  41.  
  42. WriteINI:
  43.     iniWrite, %UpdateTimer%,    %iniFile%, Plex, UpdateTimer
  44.     iniWrite, %MaxIdleTime%,    %iniFile%, Plex, MaxIdleTime
  45.     iniWrite, %PlexIP%,     %iniFile%, Plex, PlexIP
  46.     iniWrite, %PlexPort%,       %iniFile%, Plex, PlexPort
  47. Return
  48.  
  49.  
  50. CheckIdle:
  51.     ; Check if host PC has been idle more than X minutes
  52.     If (A_TimeIdle > MaxIdleTime) {
  53.         UserCount := ""
  54.  
  55.         ; Try to send an HTTP request to the Plex Server
  56.         Try {
  57.             hObject := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  58.             hObject.Open("GET", PlexURL)
  59.             hObject.Send()
  60.             Response := hObject.ResponseText
  61.         ; Catch any errors, and exit if there is one
  62.         } Catch e {
  63.             MsgBox, 16, %A_ScriptName% - Error, % e.Message ; Display the HTTP error message
  64.             ExitApp
  65.         }
  66.  
  67.         ; Get the number of connected users if the response contains the word "MediaContainer"
  68.         If InStr(Response, "MediaContainer") {
  69.             UserCount := RegExReplace(Response, "is).*<MediaContainer size=""(\d+)"">.*", "$1")
  70.             If (UserCount > 0) {
  71.                 ; If the Plex server has connected users, we reset the computers idle time
  72.                 ; https://msdn.microsoft.com/en-us/library/aa373208(VS.85).aspx
  73.                 DllCall("SetThreadExecutionState", "Int", 0x00000001)
  74.             }
  75.         ; If the response contains the word "Unauthorized", display this message and exit
  76.         } Else If InStr(Response, "Unauthorized") {
  77.             ;RegExReplace(Response, "is).*<body>.*?<h1>(.*?)</h1>.*?</body>.*" "$1")
  78.             Gosub, CheckPin
  79.             ;   MsgBox,, Unauthorized, %A_Now%: Unauthorized.`n`nIt appears your Plex Token is invalid.`nPlease check that your Plex Token is correct and run the app again.
  80.             ;}
  81.         } Else { ; If the response doesn't contain either of the above, then us know
  82.             Gosub, WriteLog
  83.             MsgBox,, Unknown Response, %A_Now%: Unknown response from server.
  84.         }
  85.     }
  86. Return
  87.  
  88.  
  89. ;   https://forums.plex.tv/t/authenticating-with-plex/609370
  90. VerifyToken(PlexToken) {
  91.     Global productName, clientIdentifier
  92.     cmdStr := "curl -X GET https://plex.tv/api/v2/user "
  93.     .   " -H ""accept: application/json"""
  94.     .   " -d ""X-Plex-Product=" productName """"
  95.     .   " -d ""X-Plex-Client-Identifier=" clientIdentifier """"
  96.     .   " -d ""X-Plex-Token=" PlexToken """"
  97.     Response := RunCMD(cmdStr)
  98.     If InStr(Response, """errors"":") {
  99.         HTTPStatus := RegExReplace(Response, ".*""status"":(.*?)[}\]].*", "$1")
  100.         If (HTTPStatus = 401) {
  101.             ;Gosub, WriteLog
  102.             MsgBox, %HTTPStatus%: Access Token is invalid.`n%PlexToken%
  103.             Return 0
  104.         } Else {
  105.             Gosub, WriteLog
  106.             MsgBox, Unknown status code: %HTTPStatus%
  107.             Return
  108.         }
  109.     }
  110.     Return 1
  111. }
  112.  
  113. GeneratePin:
  114.     ThisStep := A_ThisLabel
  115.     cmdStr := "curl -X POST https://plex.tv/api/v2/pins "
  116.     .   " -H ""accept: application/json"""
  117.     .   " -d ""strong=true"""
  118.     .   " -d ""X-Plex-Product=" productName """"
  119.     .   " -d ""X-Plex-Client-Identifier=" clientIdentifier """"
  120.     Response := RunCMD(cmdStr)
  121.     RegExMatch(Response, "id"":(.*?),""code"":""(.*?)""", PinValue)
  122.     If !PinValue1 {
  123.         Gosub, WriteLog
  124.         MsgBox, Error generating PIN.
  125.         Return
  126.     }
  127.     Gosub, ConstructAuthUrl
  128. Return
  129.  
  130. ConstructAuthUrl:
  131.     ThisStep := A_ThisLabel
  132.     AuthURL := "https://app.plex.tv/auth#?"
  133.     .   "clientID=" clientIdentifier
  134.     .   "&code=" PinValue2
  135.     .   "&context%5Bdevice%5D%5Bproduct%5D=" productName
  136.     Run, %AuthURL%
  137.     Sleep, 250
  138.     MsgBox, Please keep this window open until you log into Plex, then click OK to continue.
  139.     Gosub, CheckPin
  140. Return
  141.  
  142. CheckPin:
  143.     ThisStep := A_ThisLabel
  144.     cmdStr := "curl -X GET https://plex.tv/api/v2/pins/" PinValue1
  145.     .   " -H ""accept: application/json"""
  146.     .   " -d ""code=" PinValue2 """"
  147.     .   " -d ""X-Plex-Client-Identifier=" clientIdentifier """"
  148.     Response := RunCMD(cmdStr)
  149.     PlexToken := RegExReplace(Response, ".*?""authToken"":""(.*?)"".*", "$1")
  150.     If VerifyToken(PlexToken) {
  151.         ;iniWrite, %PlexID%,    %iniFile%, Plex, PinValue1
  152.         ;iniWrite, %PlexCode%,  %iniFile%, Plex, PinValue2
  153.         iniWrite, %PlexToken%,  %iniFile%, Plex, PlexToken
  154.     } Else {
  155.         Gosub, WriteLog
  156.         Msgbox, Invalid Access Token generated.
  157.         ExitApp
  158.     }
  159. Return
  160.  
  161.  
  162. RunCMD(Command) {
  163.     DHW := A_DetectHiddenWindows
  164.     DetectHiddenWindows, On
  165.     Run, %ComSpec% /k,, Hide, PID
  166.     WinWait, ahk_pid %PID%,, 10000
  167.     DetectHiddenWindows, %DHW%
  168.     DllCall("AttachConsole", "UInt", PID)
  169.     WshShell := ComObjCreate("WScript.Shell")
  170.     exec := WshShell.Exec(Command)
  171.     output := exec.StdOut.ReadAll()
  172.     DllCall("FreeConsole")
  173.     Process, Close, %pid%
  174.     Return %output%
  175. }
  176.  
  177. WriteLog:
  178.     FileAppend, % "[" A_Now "]`t" ThisStep "`t" PinValue1 "`t" PinValue2 "`n" AuthURL "`n" Response "`n`n", %A_ScriptDir%\ErrorLog.txt
  179. Return
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement