;---FUNCTIONS----------------------------------------------------------------------- ; Misc Functions that are called by both the Video and Social Media poster ; -------------------------------Variables------------------------------- ; Declare global variables here so they don't have to be declared in each script global DriverURLArray global DriverTitleArray global LastWebsitePostURL global ScreenshotsTaken global ChromeFilepath global CurrentTabURL ; #Include %A_ScriptDir%\ChromeAutomationFunctions.ahk ; #Include %A_ScriptDir%\RunCMD.ahk #Include C:\Users\%A_username%\Syncthing\Freedomain\Uploaders\Lib\ChromeAutomationFunctions.ahk #Include C:\Users\%A_username%\Syncthing\Freedomain\Uploaders\Lib\RunCMD.ahk DevModeMsgBox(Message){ if(!DevMode) return Msgbox, 4096, DevModeMsgBox, %Message% return } CheckForUpdates(){ ; msgbox, checking for updates Message = Checking For Updates SaveOrPostProgress(Message,PostType:="ErrorLoggingTextFile") data := URLDownloadToVar(GitReleasesAPIURL) ; Msgbox % "data: " data ; [{"id":3,"tag_name":"v2.71","target_commitish":"main","name":"2.71","body":"- Fixed and expanded Parler login check\r\n- Fixed long time bug where a newly created website tab would not get connected to properly\r\n- Temporarily removed Auto Update Support until I can integrate with gitea API","url":"https://git.zinchuk.xyz/api/v1/repos/yuriy/Freedomain_Social_Media_Poster/releases/3","html_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/releases/tag/v2.71","tarball_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/archive/v2.71.tar.gz","zipball_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/archive/v2.71.zip","draft":false,"prerelease":true,"created_at":"2023-01-26T23:45:25-05:00","published_at":"2023-01-26T23:45:25-05:00","author":{"id":1,"login":"yuriy","login_name":"","full_name":"Yuriy Zinchuk","email":"yuriy@noreply.localhost","avatar_url":"https://secure.gravatar.com/avatar/82acf184352c9232da15222248417df0?d=identicon","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-01-02T16:40:09-05:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"yuriy"},"assets":[{"id":4,"name":"Freedomain Social Media Poster.exe","size":1708544,"download_count":0,"created_at":"2023-01-26T23:45:19-05:00","uuid":"2ee05d49-a314-4079-bcc8-b6857dc29e98","browser_download_url":"https://git.zinchuk.xyz/attachments/2ee05d49-a314-4079-bcc8-b6857dc29e98"}]},{"id":2,"tag_name":"v2.70","target_commitish":"main","name":"2.70","body":"* Initial commit of V2.7 to git\r\n* Pushed codebase to personal [git instance](https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/)\r\n* Fixed Locals Posting\r\n* Fixed Gettr Posting\r\n* Fixed Flote Posting\r\n* Fixed MeWe Posting\r\n* Fixed Minds Posting\r\n* Fixed Steemit Posting\r\n* Fixed LinkedIn Image Posting\r\n* Removed Tumblr Support\r\n* Removed Pintrest support","url":"https://git.zinchuk.xyz/api/v1/repos/yuriy/Freedomain_Social_Media_Poster/releases/2","html_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/releases/tag/v2.70","tarball_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/archive/v2.70.tar.gz","zipball_url":"https://git.zinchuk.xyz/yuriy/Freedomain_Social_Media_Poster/archive/v2.70.zip","draft":false,"prerelease":true,"created_at":"2023-01-25T22:38:24-05:00","published_at":"2023-01-25T22:38:24-05:00","author":{"id":1,"login":"yuriy","login_name":"","full_name":"Yuriy Zinchuk","email":"yuriy@noreply.localhost","avatar_url":"https://secure.gravatar.com/avatar/82acf184352c9232da15222248417df0?d=identicon","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-01-02T16:40:09-05:00","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"yuriy"},"assets":[{"id":2,"name":"Freedomain Social Media Poster.exe","size":1707520,"download_count":1,"created_at":"2023-01-25T22:36:17-05:00","uuid":"d91a4ab0-b1fb-4c2f-adfa-e986e587cf0a","browser_download_url":"https://git.zinchuk.xyz/attachments/d91a4ab0-b1fb-4c2f-adfa-e986e587cf0a"}]}] parsed := JSON.Load(data) UpdateVersionNumber := parsed.1.name if(ScriptVersion = UpdateVersionNumber){ ToolTip return } else, { UpdateAvailable := 1 ; msgbox, update found! Message = Program Update Found SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile") ; IniWrite, 1, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable ; ToolTip return } } UpdateScript(){ data := URLDownloadToVar(GitReleasesAPIURL) parsed := JSON.Load(data) UpdateVersionNumber := parsed.1.name ChangeLog := parsed.1.body exename := parsed.1.assets.1.name exeURL := parsed.1.assets.1.browser_download_url ; Msgbox % "UpdateVersionNumber: " UpdateVersionNumber ; msgbox, Version: %Version% ; Msgbox % "ChangeLog: " ChangeLog ; Msgbox % "exeURL: " exeURL ; Msgbox % "exename: " exename ExeName := StrReplace(exename, ".exe", "") UpdateExeName = %exename% %UpdateVersionNumber%.exe UpdateExeFilepath = %A_ScriptDir%\%UpdateExeName% if(ScriptVersion = UpdateVersionNumber){ ; IniWrite, 0, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable MsgBox, You are Up-To-Date ; IniRead, UpdateAvailable, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable, 0 return } Changelog = %ScriptVersion% --> %UpdateVersionNumber%`n%Changelog% OnMessage(0x44, "OnMsgBoxUpdateAvailable") MsgBox 0x44, Update Available, %Changelog% OnMessage(0x44, "") IfMsgBox Yes, { Return } Else IfMsgBox No, { SaveOrPostProgress(Message:="Downloading Update",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Msgbox, downloading to: %A_ScriptDir%\%UpdateExeName% UrlDownloadToFile, %exeURL%, %UpdateExeFilepath% run, "%UpdateExeFilepath%" "%A_ScriptFullPath%" ExitApp } return } ; -------------------------------SaveOrPostProgress------------------------------- ; PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging,DiscordVideos" SaveOrPostProgress(Message:="",PostType:=""){ MessageBU := Message ; Msgbox % "PostType: " PostType ; Msgbox % "CurrentSite: " CurrentSite if(CurrentSite != "") Message := CurrentSite . ": " . Message if(InStr(PostType, "Tooltip")){ TooltipThis(Message) } if(InStr(PostType, "ErrorLoggingTextFile")){ Func_LogErrorsToTextFile(Message) } if(InStr(PostType, "ErrorSummaryVar")){ Func_LogErrorsToVar(Message) } if(InStr(PostType, "DiscordErrorLogging")){ PostToDiscordChannel(Message,DiscordErrorLoggingWebhookBotURL) } if(InStr(PostType, "DiscordVideos")){ Message := MessageBU PostToDiscordChannel(Message,DiscordVideosWebhookURL) } if(InStr(PostType, "DiscordParler")){ Message := MessageBU PostToDiscordChannel(Message,DiscordParlerWebhookURL) } } ; -------------------------------/SaveOrPostProgress------------------------------- TakeScreenshotOfPage(SaveFilepath := ""){ if(!ScreenshotResult) return TooltipThis("Sleeping 5 Seconds Before Taking Screenshot") ; sleep, 5000 if(SaveFilepath = ""){ SaveFilepath := ErrorLoggingDirectory } ; if(!FileExist(SaveFilepath)) FileCreateDir, %SaveFilepath% /* if(!TakeScreenshotsOfErrors) Return */ ; Take a screenshot of the page and save it. FormatTime, TodayDate , YYYYMMDDHH24MISS, yyyyMMdd_hhmmss ; Msgbox % "ErrorLoggingDirectory: " ErrorLoggingDirectory savepath = %SaveFilepath%\%TodayDate%.jpg ; Msgbox % "savepath: " savepath try driver.TakeScreenshot().SaveAs(savepath) ; ScreenshotsTaken := 1 } ; -------------------------------TooltipThis------------------------------- TooltipThis(String){ ; Xposition := StrLen(String) StringFirstLine := StrSplit(String, "`n") StringFirstLine := StringFirstLine[1] Xposition := StrLen(StringFirstLine) ; Msgbox % "String: " String Xposition := Xposition * 4 X := (A_ScreenWidth / 2) - Xposition ; Msgbox % "X: " X if(ShowTooltipProgress){ ToolTip, %String%, %X%, 0 } } ; -------------------------------/TooltipThis------------------------------- ;------------------------------------------------ TimedToolTip(Text, x="", y="",RemoveAfterTime:=2000, SetWhichToolTip="") { if(X = ""){ Xposition := StrLen(Text) ; Msgbox % "Xposition: " Xposition Xposition := Xposition * 4 ; Xposition := 0 X := (A_ScreenWidth / 2) - Xposition ; Msgbox % "X: " X } (y = "")?(y:=0):(y:=y) ; Msgbox % "y: " y ToolTip, %Text%, %X%, %Y% SetTimer, RMApp_ToolTipRASub, % - RemoveAfterTime return RMApp_ToolTipRASub: ToolTip,,,, %WhichToolTip% return } ; -------------------------------LogErrorsToTextFile------------------------------- Func_LogErrorsToTextFile(Text){ ; ErrorLoggingFile := Filepath FormatTime, TodayDate , YYYYMMDDHH24MISS, yyyyMMdd_hhmmss text = ( ---------------%TodayDate%--------------- %Text% ) FileAppend, %Text%, %ErrorLoggingFilePath% } ; -------------------------------/LogErrorsToTextFile------------------------------- ; -------------------------------LogErrorsToVar------------------------------- Func_LogErrorsToVar(Text){ ErrorLogVar .= "`n" . Text } ; -------------------------------/LogErrorsToVar------------------------------- ; -------------------------------Discord------------------------------- PostToDiscordChannel(Message,WebhookChannel){ ; Msgbox % "Message: " Message ; Msgbox % "WebhookChannel: " WebhookChannel ; Replace all the json forbidden characters SingleQuote = " ReplacedQuote = \" Message := StrReplace(Message, "\", "\\") ; Replace Tabs Message := StrReplace(Message, SingleQuote, ReplacedQuote) ; Replace single quote Message := StrReplace(Message, "`r", "") ; Replace Carriage return Message := StrReplace(Message, A_Tab, "\t") ; Replace Tabs Message := StrReplace(Message, "`n", "\n") ; Escape New Line Character Message := StrReplace(Message, "`f", "\f") ; Replace Tabs ; Convert into json string JsonString= ( { "content": "%Message%" } ) ; Msgbox % "JsonString: " JsonString ; try WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1") try WebRequest.Open("POST", WebhookChannel, false) try WebRequest.SetRequestHeader("Content-Type", "application/json") try WebRequest.Send(JsonString) } ; -------------------------------/Discord------------------------------- ; -------------------------------TelegramAPI------------------------------- TelegramMsgBox(Text:="", TelegramBotToken := "", TelegramBotChatID :=""){ ; Send Images: ; https://www.autohotkey.com/boards/viewtopic.php?f=76&t=68417&p=294332#p294332 ; Msgbox % "Text: " Text ; Replace all forbidden characters - https://www.ascii-code.com/ ; Text := StrReplace(Text, "`%", "%25") ; percent with Text := StrReplace(Text, "`n", "%0A") ; New Line ; Text := StrReplace(Text, "`n", "%0A") ; New Line ; Text := StrReplace(Text, " ", "%23") ; New Line ; Text := ; Text := StrReplace(Text, "`n", "%0A") ; New Line ; Msgbox % "Text: " Text ErrorLoggingPath = %A_ScriptDir%\Lib\ErrorLogging\check.rups loop 3 { UrlDownloadToFile https://api.telegram.org/bot%TelegramBotToken%/sendmessage?chat_id=%TelegramBotChatID%&text=%Text%, %ErrorLoggingPath% sleep 1000 ifexist %ErrorLoggingPath% { break } if A_index = 3 { Message = Post failed due to API Issue. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Return "Failed" ; MsgBox, 16,, something went wrong with sending } } FileRead, TelegramOutput, %ErrorLoggingPath% TelegramOutput := "API Result: " . TelegramOutput ; Msgbox % "TelegramOutput: " TelegramOutput filedelete %ErrorLoggingPath% SaveOrPostProgress(Message:=TelegramOutput,PostType:="ErrorLoggingTextFile") if(InStr(TelegramOutput, "error_code")){ Return "Failed" } } ; -------------------------------/TelegramAPI------------------------------- ; Telegram Message API ;------------------------------------------------ SendTelegramMessage(token, chatID, text := "", ParseMode := "MarkdownV2") ; you could add more options; compare the Telegram API docs { ; ParseMode := "MarkdownV2" ; msgbox ; Msgbox % "text: " text url_str := "https://api.telegram.org/bot" token "/sendMessage" objParam := { "chat_id" : chatID ,"parse_mode" : ParseMode ,"text" : text } CreateFormData(postData, hdr_ContentType, objParam) whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") whr.Open("POST", url_str, true) whr.SetRequestHeader("Content-Type", hdr_ContentType) ; whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") ; ??????? whr.Option(6) := False ; No auto redirect whr.Send(postData) whr.WaitForResponse() json_resp := whr.ResponseText whr := ; free COM object ; Msgbox % "json_resp: " json_resp if(InStr(json_resp, "error_code")) Return json_resp } /* *bold \*text* _italic \*text_ __underline__ ~strikethrough~ *bold _italic bold ~italic bold strikethrough~ __underline italic bold___ bold* [inline URL](http://www.example.com/) [inline mention of a user](tg://user?id=123456789) `inline fixed-width code` ``` pre-formatted fixed-width code block ``` ```python pre-formatted fixed-width code block written in the Python programming language ``` */ ; -------------------------------Telegram Image Sending------------------------------- ; https://www.autohotkey.com/boards/viewtopic.php?t=68417 SendTelegramPhoto(token, chatID, file, caption := "", ParseMode := "MarkdownV2") ; you could add more options; compare the Telegram API docs { ; ParseMode := "MarkdownV2" url_str := "https://api.telegram.org/bot" token "/sendPhoto" objParam := { "chat_id" : chatID , "photo" : [file] , "parse_mode" : ParseMode , "caption" : caption} CreateFormData(postData, hdr_ContentType, objParam) whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") whr.Open("POST", url_str, true) whr.SetRequestHeader("Content-Type", hdr_ContentType) ; whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") ; ??????? whr.Option(6) := False ; No auto redirect whr.Send(postData) whr.WaitForResponse() json_resp := whr.ResponseText whr := ; free COM object ; Msgbox % "json_resp: " json_resp if(InStr(json_resp, "error_code")) Return json_resp } ; -------------------------------Telegram Image Sending------------------------------- ; https://www.autohotkey.com/boards/viewtopic.php?t=68417 SendTelegramVideo(token, chatID, file, caption := "", ParseMode := "MarkdownV2") ; you could add more options; compare the Telegram API docs { ; ParseMode := "MarkdownV2" url_str := "https://api.telegram.org/bot" token "/sendVideo?caption=" caption objParam := { "chat_id" : chatID , "video" : [file] , "parse_mode" : ParseMode } CreateFormData(postData, hdr_ContentType, objParam) whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") whr.Open("POST", url_str, true) whr.SetRequestHeader("Content-Type", hdr_ContentType) ; whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") ; ??????? whr.Option(6) := False ; No auto redirect whr.Send(postData) whr.WaitForResponse() json_resp := whr.ResponseText whr := ; free COM object ; Msgbox % "json_resp: " json_resp if(InStr(json_resp, "error_code")) Return json_resp } ; -------------------------------Telegram File Sending------------------------------- ; https://www.autohotkey.com/boards/viewtopic.php?t=68417 SendTelegramFile(token, chatID, file, caption := "", ParseMode := "MarkdownV2") ; you could add more options; compare the Telegram API docs { ; ParseMode := "MarkdownV2" url_str := "https://api.telegram.org/bot" token "/sendDocument?caption=" caption objParam := { "chat_id" : chatID , "document" : [file] , "parse_mode" : ParseMode } CreateFormData(postData, hdr_ContentType, objParam) whr := ComObjCreate("WinHttp.WinHttpRequest.5.1") whr.Open("POST", url_str, true) whr.SetRequestHeader("Content-Type", hdr_ContentType) ; whr.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") ; ??????? whr.Option(6) := False ; No auto redirect whr.Send(postData) whr.WaitForResponse() json_resp := whr.ResponseText whr := ; free COM object ; Msgbox % "json_resp: " json_resp if(InStr(json_resp, "error_code")) Return json_resp } ; -------------------------------/Telegram API Image Sending------------------------------- ASCIISTRReplace(Message){ ; Msgbox % "Message of function: " Message ; https://tech.saigonist.com/b/code/escaping-special-characters-markdown.html ; Replace all forbidden characters - https://www.ascii-code.com/ LineBreakChar = `%0A ; Used for API Message := StrReplace(Message, "\", "\\") ; replace all new line characters with the global charater Message := StrReplace(Message, "*", "\*") ; replace all new line characters with the global charater ; Message := StrReplace(Message, "`n", LineBreakChar) ; replace all new line characters with the global charater Message := StrReplace(Message, "!", "\!") ; replace all new line characters with the global charater Message := StrReplace(Message, "_", "\_") ; replace all new line characters with the global charater Message := StrReplace(Message, "{", "\{") ; replace all new line characters with the global charater Message := StrReplace(Message, "}", "\}") ; replace all new line characters with the global charater Message := StrReplace(Message, "[", "\[") ; replace all new line characters with the global charater Message := StrReplace(Message, "]", "\]") ; replace all new line characters with the global charater Message := StrReplace(Message, "(", "\(") ; replace all new line characters with the global charater Message := StrReplace(Message, ")", "\)") ; replace all new line characters with the global charater Message := StrReplace(Message, "#", "\#") ; replace all new line characters with the global charater Message := StrReplace(Message, "+", "\+") ; replace all new line characters with the global charater Message := StrReplace(Message, "-", "\-") ; replace all new line characters with the global charater Message := StrReplace(Message, ".", "\.") ; replace all new line characters with the global charater Message := StrReplace(Message, ">", "\>") ; replace all new line characters with the global charater Message := StrReplace(Message, "<", "\<") ; replace all new line characters with the global charater Message := StrReplace(Message, "=", "\=") ; replace all new line characters with the global charater Message := StrReplace(Message, "|", "\|") ; replace all new line characters with the global charater Message := StrReplace(Message, "~", "\~") ; replace all new line characters with the global charater Message := StrReplace(Message, "`", "\`") ; replace all new line characters with the global charater Message := StrReplace(Message, "$", "\$") ; replace all new line characters with the global charater ; Message := StrReplace(Message, "%", "\%") ; replace all new line characters with the global charater Message := StrReplace(Message, "&", "\&") ; replace all new line characters with the global charater ; Msgbox % "replaced Message: " Message Return Message } ; -------------------------------Discord Images------------------------------- UploadImageToDiscord(Webhook, Message:="", Filepath:=""){ filepath := [Filepath] ; Create object objParam := {file: filepath, content: Message} CreateFormData(PostData, hdr_ContentType, objParam) HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1") HTTP.Open("POST", Webhook, true) HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") HTTP.SetRequestHeader("Content-Type", hdr_ContentType) HTTP.SetRequestHeader("Pragma", "no-cache") HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store") HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT") HTTP.Send(PostData) HTTP.WaitForResponse() ; msgbox % HTTP.ResponseText return HTTP.ResponseText } ; -------------------------------/Discord Images------------------------------- ;---------------------------Discord Messages--------------------- UploadMessageToDiscord(Webhook, Message:=""){ ; filepath := [Filepath] ; Create object objParam := {file: filepath, content: Message} CreateFormData(PostData, hdr_ContentType, objParam) HTTP := ComObjCreate("WinHTTP.WinHTTPRequest.5.1") HTTP.Open("POST", Webhook, true) HTTP.SetRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko") HTTP.SetRequestHeader("Content-Type", hdr_ContentType) HTTP.SetRequestHeader("Pragma", "no-cache") HTTP.SetRequestHeader("Cache-Control", "no-cache, no-store") HTTP.SetRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT") HTTP.Send(PostData) HTTP.WaitForResponse() ; msgbox % HTTP.ResponseText return HTTP.ResponseText } ;---------------------------/Discord Messages--------------------- ; -------------------------------CreateFormData - Creates "multipart/form-data" for http post------------------------------- ; Used for WinHttp.WinHttpRequest.5.1, Msxml2.XMLHTTP ... CreateFormData(ByRef retData, ByRef retHeader, objParam) { New CreateFormData(retData, retHeader, objParam) } ; Used for WinInet CreateFormData_WinInet(ByRef retData, ByRef retHeader, objParam) { New CreateFormData(safeArr, retHeader, objParam) size := safeArr.MaxIndex() + 1 VarSetCapacity(retData, size, 1) DllCall("oleaut32\SafeArrayAccessData", "ptr", ComObjValue(safeArr), "ptr*", pdata) DllCall("RtlMoveMemory", "ptr", &retData, "ptr", pdata, "ptr", size) DllCall("oleaut32\SafeArrayUnaccessData", "ptr", ComObjValue(safeArr)) } Class CreateFormData { __New(ByRef retData, ByRef retHeader, objParam) { CRLF := "`r`n" Boundary := this.RandomBoundary() BoundaryLine := "------------------------------" . Boundary ; Loop input paramters binArrs := [] For k, v in objParam { If IsObject(v) { For i, FileName in v { str := BoundaryLine . CRLF . "Content-Disposition: form-data; name=""" . k . """; filename=""" . FileName . """" . CRLF . "Content-Type: " . this.MimeType(FileName) . CRLF . CRLF binArrs.Push( BinArr_FromString(str) ) binArrs.Push( BinArr_FromFile(FileName) ) binArrs.Push( BinArr_FromString(CRLF) ) } } Else { str := BoundaryLine . CRLF . "Content-Disposition: form-data; name=""" . k """" . CRLF . CRLF . v . CRLF binArrs.Push( BinArr_FromString(str) ) } } str := BoundaryLine . "--" . CRLF binArrs.Push( BinArr_FromString(str) ) retData := BinArr_Join(binArrs*) retHeader := "multipart/form-data; boundary=----------------------------" . Boundary } RandomBoundary() { str := "0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z" Sort, str, D| Random str := StrReplace(str, "|") Return SubStr(str, 1, 12) } MimeType(FileName) { n := FileOpen(FileName, "r").ReadUInt() Return (n = 0x474E5089) ? "image/png" : (n = 0x38464947) ? "image/gif" : (n&0xFFFF = 0x4D42 ) ? "image/bmp" : (n&0xFFFF = 0xD8FF ) ? "image/jpeg" : (n&0xFFFF = 0x4949 ) ? "image/tiff" : (n&0xFFFF = 0x4D4D ) ? "image/tiff" : "application/octet-stream" } } ;############################################################################################################# ; Update: 2015-6-4 - Added BinArr_ToFile() BinArr_FromString(str) { oADO := ComObjCreate("ADODB.Stream") oADO.Type := 2 ; adTypeText oADO.Mode := 3 ; adModeReadWrite oADO.Open oADO.Charset := "UTF-8" oADO.WriteText(str) oADO.Position := 0 oADO.Type := 1 ; adTypeBinary oADO.Position := 3 ; Skip UTF-8 BOM return oADO.Read, oADO.Close } BinArr_FromFile(FileName) { oADO := ComObjCreate("ADODB.Stream") oADO.Type := 1 ; adTypeBinary oADO.Open oADO.LoadFromFile(FileName) return oADO.Read, oADO.Close } BinArr_Join(Arrays*) { oADO := ComObjCreate("ADODB.Stream") oADO.Type := 1 ; adTypeBinary oADO.Mode := 3 ; adModeReadWrite oADO.Open For i, arr in Arrays oADO.Write(arr) oADO.Position := 0 return oADO.Read, oADO.Close } BinArr_ToString(BinArr, Encoding := "UTF-8") { oADO := ComObjCreate("ADODB.Stream") oADO.Type := 1 ; adTypeBinary oADO.Mode := 3 ; adModeReadWrite oADO.Open oADO.Write(BinArr) oADO.Position := 0 oADO.Type := 2 ; adTypeText oADO.Charset := Encoding return oADO.ReadText, oADO.Close } BinArr_ToFile(BinArr, FileName) { oADO := ComObjCreate("ADODB.Stream") oADO.Type := 1 ; adTypeBinary oADO.Open oADO.Write(BinArr) oADO.SaveToFile(FileName, 2) oADO.Close } ; -------------------------------/CreateFormData - Creates "multipart/form-data" for http post------------------------------- ; -------------------------------CheckDirExistAndCreate------------------------------- ; Check if directory exists and if not, create it CheckDirExistAndCreate(Path){ if(!FileExist(Path)){ FileCreateDir, %Path% } } ; -------------------------------/CheckDirExistAndCreate------------------------------- CheckIfUpdateAvailable(Filepath, CurrentVersion){ FileRead, ScriptUpdateContents, %Filepath% FileContents := StrSplit(ScriptUpdateContents, "ScriptVersion") FileContents := FileContents[2] FileContents := StrSplit(FileContents, "`n") UpdateVersion := FileContents[1] ; msgbox % UpdateVersion if(!InStr(UpdateVersion, CurrentVersion)){ ; Update found for file, write to settings.ini for next time script is run Message = Update Available to Download SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") Return True } Return False } FindUpdateChangeLog(Filepath){ FileRead, ScriptUpdateContents, %Filepath% ; Set Variables ChangelogStart =;---Changelog------------------------------------------------------ ChangelogEnd =;---/Changelog------------------------------------------------------ ; Msgbox % "ScriptUpdateContents: " ScriptUpdateContents ChangeLog := StrSplit(ScriptUpdateContents, ChangelogStart) ChangeLog := ChangeLog[2] ChangeLog := StrSplit(ChangeLog, ChangelogEnd) ChangeLog := ChangeLog[1] Return Changelog } CheckSeleniumDriver(){ try Driver := SChrome_Get("", ChromeProfile := "") ; open new tab page with with specified profile catch e { ShowSeleniumErrorMsgbox() ; Message = Failed to Make Connection to Chrome. Check for Any Open Dialogue Boxes or out of date ChromeDriver ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") Return "Failed" } ; Driver := SChrome_Get("https://www.bitchute.com/", ChromeProfile) ; open new tab page with with specified profile ; driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding catch e { ShowSeleniumErrorMsgbox() ; Message = Failed to send command to Chrome. Check for an Open Dialogue Box. ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") Return "Failed" } DriverStatus := 1 } SeleniumConnectToActiveTab(IP_Port := "127.0.0.1:9222"){ Driver := ComObjCreate("Selenium.ChromeDriver") Driver.SetCapability("debuggerAddress", IP_Port) try Driver.Start() catch e { ShowSeleniumErrorMsgbox() ; msgbox, failed to connect to Chrome for some reason. ; Message = Failed to Connect to Chrome for some reason. ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") } return Driver } CreateArrayOfTabs() { Message = Creating an Array of All Chrome Tabs SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") DriverTitleArray := [] ; Create an array DriverURLArray := [] try TotalTabsFound := Driver.Windows.Count ; if only 1 tab exists, grab info, push to array and exit early if(TotalTabsFound = 1){ try Title := Driver.Title try URL := Driver.URL if(Title != "") DriverTitleArray.Push(Title) if(URL != "") DriverURLArray.Push(URL) return } ; Msgbox % "TotalTabsFound: " TotalTabsFound ; if(DevMode) ; Msgbox % "TotalTabsFound: " TotalTabsFound ; msgbox % "total Tabs:" Driver.Windows.Count ; Message = Creating an Array of Chrome Tabs ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") ; StartTime := A_TickCount ; Sleep, 1000 StartTime := A_TickCount Loop, { Message = Creating an Array of All Chrome Tabs`nCurrent Loop: %A_index%/%TotalTabsFound% (Cannot loop through unloaded tabs)`nSometimes might get stuck for a short while if there is something loading in active tab TooltipThis(Message) ; SaveOrPostProgress(Message:=URL,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar") ; if(ArrayContainsURL = 3 AND A_index > TotalTabsFound) ; Break TabEndTime := A_TickCount - TabFoundStartTime TabEndTimeArray .= TabEndTime . "," ; Message = Time to switch to new tab: %TabEndTime%`nCurrent Loop: %A_index%/%TotalTabsFound% ; SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") TabFoundStartTime := A_TickCount IndexMinus3 := A_index - 3 ; if(FirstURLPosition AND SecondURLPosition AND ThirdURLPosition AND IndexPlus3 > TotalTabsFound OR A_index = 30) { if(IndexMinus3 > TotalTabsFound) { ; DevModeMsgBox("First 3 tabs found. Breaking") ; Msgbox % "A_index: " A_index "`n" "IndexPlus3: " IndexPlus3 break } if(TotalTabsFound < 4 AND A_index = 4) break ; TimeToGrabCurrentTab := A_TickCount - StartTime ; Msgbox % "TimeToGrabCurrentTab: " TimeToGrabCurrentTab ; Stop page refresh if it's happening ; try driver.executeScript("return window.stop") try Title := Driver.Title try URL := Driver.URL ; TimeToGrabCurrentTab := A_TickCount - StartTime ; Msgbox % "TimeToGrabCurrentTab: " TimeToGrabCurrentTab ; VAR := HasVal(DriverURLArray, STRINGVAR) ; returns position of value in array if(HasVal(DriverURLArray, URL)) ; returns position of value in array { URLPositionInArray := HasVal(DriverURLArray, URL) if(URLPositionInArray = 1){ FirstURLPosition := 1 } if(URLPositionInArray = 2){ SecondURLPosition := 1 } if(URLPositionInArray = 3){ ThirdURLPosition := 1 } if(URLPositionInArray = 4){ FourthURLPosition := 1 } ; Msgbox % "PositionInArray: " PositionInArray ; ArrayContainsURL += 1 } ; TimeToCheckArray := A_TickCount - StartTime ; Msgbox % "ArrayContainsURL: " ArrayContainsURL if(Title != "") DriverTitleArray.Push(Title) if(URL != "") DriverURLArray.Push(URL) /* if(TotalTabsFound = 1){ TimeToKickOut := A_TickCount - StartTime ; Msgbox % "TimeToGrabCurrentTab: " TimeToGrabCurrentTab ; Msgbox % "TimeToCheckArray: " TimeToCheckArray ; Msgbox % "TimeToKickOut: " TimeToKickOut ; MsgBox, %ElapsedTime% milliseconds have elapsed. ; Msgbox % "A_index: " A_index ; DevModeMsgBox("breaking early on loop 1?") break } ; if there is only 1 tab, then break out of loop and don't bother looping through same tab */ try driver.SwitchToNextWindow ;Focuses Selenium on the newly opened/next window. } ; end of loop ; Iterate from 1 to the end of the array: Loop % DriverURLArray.Length() { ARRAYNAMEList .= DriverURLArray[A_Index] . "`n" ; ArrayItem := DriverURLArray[A_Index] ; MsgBox % DriverURLArray[A_Index] } ; Msgbox % "ARRAYNAMEList: " ARRAYNAMEList TimeToLoopThroughAllTabs := A_TickCount - StartTime Message = Time to Loop through all tabs: %TimeToLoopThroughAllTabs% SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") ; DevModeMsgBox(Message) return } ; /FUNC InputFilePathIntoOpenWindow(Filepath){ ; Msgbox % "Filepath: " Filepath Message = Waiting for "Open" window to appear to input filepath into SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") ; Tooltip,Waiting for "Open" window to appear to input filepath into,850,0 ; WinWait, Open WinWait,Open,,5 ; Wait for 10 seconds for window if(ErrorLevel) { ; msgbox, failed to find window. Return "Failed" } WinActivate, Open sleep, 1000 ControlSetText, Edit1, %Filepath%, Open sleep, 1000 ControlSend, Edit1, {Enter}, Open sleep, 1000 ; Do an extra check in case the Open window is still open. OpenWindowExist := WinExist("Open") if(OpenWindowExist) ControlSend, Edit1, {Enter}, Open ToolTip, } ; -------------------------------NavigateFromBaseURLTo------------------------------- NavigateFromBaseURLTo(URL){ if(!DriverStatus){ ; if not connected to selenium chrome, then re-connect Status := CheckSeleniumDriver() if(Status) Return "Failed" CreateArrayOfTabs() ; store all open tabs to memory for later usage } if(ReuseTabs){ ; pull out base of URL and check if it's within the array of tabs URLBase := StrReplace(URL,"https://","") URLBase := StrSplit(URLBase, "/") URLBase := URLBase[1] URLBase := StrReplace(URLBase, "www.","") } if(!HasSubstringVal(DriverURLArray, URLBase)) ; if base url is not in tab array, create new tab and push url to array { try, run "%ChromeFilepath%" "%URL%" DriverURLArray.Push(URL) ; Append an item to the array NewTabCreated := 1 sleep, 2000 } ; msgbox, Message = Finding Tab SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") TabFoundSuccessfully := NumberOfTabLoops := DriverURLArray.Length() ; NumberOfTabLoops := Driver.Windows.Count + 2 loop % NumberOfTabLoops { ; loop through tabs to find matching tab try driver.SwitchToNextWindow() ; sleep, 1000 ; msgbox, looping through tabs try CurrentTabTitle := driver.window.title ; caused by tab being manually closed. Not sure if this is the only cause though. if(CurrentTabTitle = "") { Message = CurrentTabTitle: %CurrentTabTitle% DevModeMsgBox(Message) Message = CurrenttabURL: %CurrentTabURL% DevModeMsgBox(Message) ; try driver.SwitchToNextWindow Continue } try CurrentTabURL := driver.Url if(InStr(CurrentTabURL, URLBase)){ ; msgbox, found it.`n%CurrentTabTitle% = %PageTitle%`n%CurrentTabURL% = %URLBase% TabFoundSuccessfully := 1 ; msgbox %CurrentTabTitle% = %PageTitle% ; msgbox %CurrentTabURL% = %URL% Break } } if(!NewTabCreated){ ; if re-using a tab then we want to re-navigate to URL because it might be the wrong page try driver.Get(URL) ;Open selected URL try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding catch e { ; msgbox, error caught. trying something try driver.switchToalert().accept() try driver.Get(URL) ;Open selected URL catch e { Message = Failed to Navigate to %URL%: Please Check for Any Open Dialogue Boxes SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") Return "Failed" } } } ; msgbox, no error caught ; } Return } ; End of Function ; -------------------------------/NavigateFromBaseURL------------------------------- SaveDriverURL(){ ; save the url of the result page. That way if a tab is not found for a site, we can open up a tab from this tab instead of middle of nowhere. That way we can keep the tabs together try LastWebsitePostURL := driver.URL } ; -------------------------------SChrome_Get------------------------------- SChrome_Get(URL := "", Profile := "Profile 1", IP_Port := "127.0.0.1:9222"){ IP_Port_Nr := RegExReplace(IP_Port, ".*:(\d*)", "$1") if WinExist("ahk_exe Chrome.exe"){ WinGet, pid, PID, ahk_exe chrome.exe for item in ComObjGet("winmgmts:").ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId='" pid "'"){ if RegExMatch(item.CommandLine, "i)--remote-debugging-port=\K\d+", port){ break } } if (Port=""){ MsgBox, 36, ,Chrome Needs to be started in debugging mode in order for Autohotkey to connect to it.`nIs it ok to restart Chrome in debugmode to enable a connection? IfMsgBox, Yes { Message = Restarting Chrome in Debug Mode SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") While(WinExist("ahk_exe chrome.exe")) { WinClose, ahk_exe chrome.exe } Process, WaitClose, chrome.exe } Else{ Msgbox, 4096, Error, Cannot connect to Chrome profile if it is Not running in debug mode. Script Terminating ExitApp ; @todo: Make this error out to the script result screen } } } ; ; yuriy's settings ; IniRead, ChromeFilepath, C:\Users\%A_username%\Documents\Autohotkey\Lib\ScriptSettings.ini, Selenium, %A_Computername%, %A_Space% ; ; Establish Variable with Filepath to be used throughout the script ; if(ChromeFilepath = ""){ if(FileExist("C:\Program Files\Google\Chrome\Application\chrome.exe")){ ChromeFilepath = C:\Program Files\Google\Chrome\Application\chrome.exe } else if (FileExist("C:\Program Files (x86)\Google\Chrome\Application\chrome.exe")){ ChromeFilepath = C:\Program Files (x86)\Google\Chrome\Application\chrome.exe } if(ChromeFilepath = ""){ Message = Failed to find chrome.exe in the usual locations. SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") MsgBox 0x30, Error!, Unable to find Chrome.exe in the usual locations. `nScript Exiting. ExitApp } if(!winExist("ahk_exe chrome.exe")){ message = %ChromeFilepath% --remote-debugging-port=%IP_Port_Nr% %URL% Clipboard := Message DevModeMsgBox(message) run, %ChromeFilepath% --remote-debugging-port=%IP_Port_Nr% %URL% } Driver := ComObjCreate("Selenium.ChromeDriver") Driver.SetCapability("debuggerAddress", IP_Port) try Driver.Start() catch e { ShowSeleniumErrorMsgbox() } ; end of catch ; Save current chrome version to ini file return Driver } ; -------------------------------/SChrome_Get------------------------------- ShowSeleniumErrorMsgbox(){ GetChromeVersionCommand = powershell (Get-Item '%ChromeFilepath%').VersionInfo.ProductVersion Chromeversion := RunCMD(GetChromeVersionCommand) ChromeVersion := StrReplace(ChromeVersion, "`n", "") ; Clipboard := ChromeVersion ; Msgbox % "Chromeversion: " Chromeversion IniRead, PreviousWorkingChromeVersion, Settings.ini, Misc, ChromeVersion, %A_Space% ; IniWrite, %ChromeVersion%, Settings.ini, Misc, ChromeVersion ; msgbox, failed to connect to Chrome for some reason. ; Message = Failed to Connect to Chrome. Most likely problem is either Chrome has some sort of dialogue box open or ChromeDriver needs to be updated. ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") OnMessage(0x44, "OnMsgBoxChromeDriverFailed") MsgBox 0x40043, Error, Failed to Connect to Chrome. `nMost likely issue is either Chrome has some sort of dialogue box open or ChromeDriver needs to be updated.`n`nClick "Reload" to reload the script to try again`nClick "ChromeDriver" to open up the ChromeDriver download page. `n`nClick "Instructions" to open up .pdf file with instructions for updating chromedriver.exe`n`nPossibly Helpful Info:`nCurrent Chrome Version: %Chromeversion%Chrome Version of Last Successfull Upload: %PreviousWorkingChromeVersion% OnMessage(0x44, "") IfMsgBox Yes, { ; Reload script Reload } Else IfMsgBox No, { run, https://chromedriver.chromium.org/downloads ExitApp ; open chromedriver site } Else IfMsgBox Cancel, { URL = https://freedomainplaylists.com/wp-content/FreedomainScripts/Update`%20Selenium`%20ChromeDriver.pdf Filepath = %A_ScriptDir%\Lib\Update Selenium ChromeDriver.pdf if(!FileExist(Filepath)){ UrlDownloadToFile, %URL%, %Filepath% run, %Filepath% } ExitApp } } ; -------------------------------HasVal------------------------------- ; Function needed for finding a value in an array HasVal(haystack, needle) { if !(IsObject(haystack)) || (haystack.Length() = 0) return 0 for index, value in haystack if (value = needle) return index return 0 } ; -------------------------------/HasVal------------------------------- HasSubstringVal(haystack, needle) { if !(IsObject(haystack)) || (haystack.Length() = 0) return 0 for index, value in haystack if (InStr(value, Needle)) return index return 0 } ; SubStr(String, StartingPos [, Length]) ; InStr(value, Needle) ; -------------------------------FileXPro Get File Attributes------------------------------- ;https://www.autohotkey.com/boards/viewtopic.php?t=59882 Filexpro( sFile := "", Kind := "", P* ) { ; v.90 By SKAN on D1CC @ goo.gl/jyXFo9 Local Static xDetails If ( sFile = "" ) { ; Deinit static variable xDetails := "" Return } fex := {}, _FileExt := "" Loop, Files, % RTrim(sfile,"\*/."), DF { If not FileExist( sFile:=A_LoopFileLongPath ) { Return } SplitPath, sFile, _FileExt, _Dir, _Ext, _File, _Drv If ( p[p.length()] = "xInfo" ) ; Last parameter is xInfo { p.Pop() ; Delete parameter fex.SetCapacity(11) ; Make room for Extra info fex["_Attrib"] := A_LoopFileAttrib fex["_Dir"] := _Dir fex["_Drv"] := _Drv fex["_Ext"] := _Ext fex["_File"] := _File fex["_File.Ext"] := _FileExt fex["_FilePath"] := sFile fex["_FileSize"] := A_LoopFileSize fex["_FileTimeA"] := A_LoopFileTimeAccessed fex["_FileTimeC"] := A_LoopFileTimeCreated fex["_FileTimeM"] := A_LoopFileTimeModified } Break } If Not ( _FileExt ) ; Filepath not resolved { Return } objShl := ComObjCreate("Shell.Application") objDir := objShl.NameSpace(_Dir) objItm := objDir.ParseName(_FileExt) If ( VarSetCapacity(xDetails) = 0 ) ; Init static variable { i:=-1, xDetails:={}, xDetails.SetCapacity(309) While ( i++ < 309 ) { xDetails[ objDir.GetDetailsOf(0,i) ] := i } xDetails.Delete("") } If ( Kind and Kind <> objDir.GetDetailsOf(objItm,11) ) ; File isn't desired kind { Return } i:=0, nParams:=p.Count(), fex.SetCapacity(nParams + 11) While ( i++ < nParams ) { Prop := p[i] If ( (Dot:=InStr(Prop,".")) and (Prop:=(Dot=1 ? "System":"") . Prop) ) { fex[Prop] := objItm.ExtendedProperty(Prop) Continue } If ( PropNum := xDetails[Prop] ) > -1 { fex[Prop] := ObjDir.GetDetailsOf(objItm,PropNum) Continue } } fex.SetCapacity(-1) Return fex } ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; GuiButtonIcon ;------------------------------------------------ GuiButtonIcon(Handle, File, Index := 1, Options := "") { RegExMatch(Options, "i)w\K\d+", W), (W="") ? W := 16 : RegExMatch(Options, "i)h\K\d+", H), (H="") ? H := 16 : RegExMatch(Options, "i)s\K\d+", S), S ? W := H := S : RegExMatch(Options, "i)l\K\d+", L), (L="") ? L := 0 : RegExMatch(Options, "i)t\K\d+", T), (T="") ? T := 0 : RegExMatch(Options, "i)r\K\d+", R), (R="") ? R := 0 : RegExMatch(Options, "i)b\K\d+", B), (B="") ? B := 0 : RegExMatch(Options, "i)a\K\d+", A), (A="") ? A := 4 : Psz := A_PtrSize = "" ? 4 : A_PtrSize, DW := "UInt", Ptr := A_PtrSize = "" ? DW : "Ptr" VarSetCapacity( button_il, 20 + Psz, 0 ) NumPut( normal_il := DllCall( "ImageList_Create", DW, W, DW, H, DW, 0x21, DW, 1, DW, 1 ), button_il, 0, Ptr ) ; Width & Height NumPut( L, button_il, 0 + Psz, DW ) ; Left Margin NumPut( T, button_il, 4 + Psz, DW ) ; Top Margin NumPut( R, button_il, 8 + Psz, DW ) ; Right Margin NumPut( B, button_il, 12 + Psz, DW ) ; Bottom Margin NumPut( A, button_il, 16 + Psz, DW ) ; Alignment SendMessage, BCM_SETIMAGELIST := 5634, 0, &button_il,, AHK_ID %Handle% return IL_Add( normal_il, File, Index ) } ; \GuiButtonIcon ;------------------------------------------------ ToggleTestingMode(){ IniRead, TestingMode, Settings.ini, General, TestingMode, 0 ; Msgbox % "TestingMode: " TestingMode if(TestingMode) IniWrite, 0, Settings.ini, General, TestingMode else, IniWrite, 1, Settings.ini, General, TestingMode } ToggleManualSubmit(){ IniRead, ManualSubmit, Settings.ini, General, ManualSubmit, 0 ; Msgbox % "TestingMode: " TestingMode if(ManualSubmit) IniWrite, 0, Settings.ini, General, ManualSubmit else, IniWrite, 1, Settings.ini, General, ManualSubmit } ToggleDevMode(){ IniRead, DevMode, Settings.ini, General, DevMode, 0 ; Msgbox % "TestingMode: " TestingMode if(DevMode) IniWrite, 0, Settings.ini, General, DevMode else, IniWrite, 1, Settings.ini, General, DevMode } FormatTextToJSText(Var){ ; Replaces AHK newline characters with javascript ones /*\b Backspace \f Form Feed \n New Line - done \r Carriage Return \t Horizontal Tabulator \v Vertical Tabulator \' Single quote - done \" Double quote - done \\ Backslash - done */ SingleQuotationmark = " ; Variable of Escaped Symbols EscapedSingleQuote = \' EscapedDoubleQuote = \" EscapedBackslash = \\ EscapedNewLine = \n ; Replace each character that needs replacing in the text string Var := StrReplace(Var, "\", EscapedBackslash) ; needed otherwise selenium will error out Var := StrReplace(Var, "`n", EscapedNewLine) ; needed otherwise selenium will error out Var := StrReplace(Var, "`r", "") ; needed otherwise selenium will error out Var := StrReplace(Var, SingleQuotationmark, EscapedDoubleQuote) ; needed otherwise selenium will error out Var := StrReplace(Var, "'", EscapedSingleQuote) ; needed otherwise selenium will error out ; Var := StrReplace(Var, "`r", "") ; needed otherwise selenium will error out Return Var } ; OnMsgbox Functions ;------------------------------------------------ OnMsgBoxUpdateAvailable() { DetectHiddenWindows, On Process, Exist If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) { ControlSetText Button1, Cancel ControlSetText Button2, Install } } OnMsgBoxChromeDriverFailed() { DetectHiddenWindows, On Process, Exist If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) { WinMove,, 0 ControlSetText Button1, Reload Script ControlSetText Button2, ChromeDriver ControlSetText Button3, Instructions } } SaveCurrentChromeVersionToIniFile(){ ; Msgbox % "ChromeFilepath: " ChromeFilepath GetChromeVersionCommand = powershell (Get-Item '%ChromeFilepath%').VersionInfo.ProductVersion Chromeversion := RunCMD(GetChromeVersionCommand) if(InStr(ChromeVersion, "scripts is disabled on this system")){ ChromeVersion = Not Able to Grab Because: "scripts are disabled in powershell" } ; Msgbox % "Chromeversion: " Chromeversion ; Msgbox % "Chromeversion: " Chromeversion if(ChromeFilepath = "") return ; Chromeversion := StrSplit(Chromeversion, "`n") ; Chromeversion := Chromeversion[4] IniWrite, %ChromeVersion%, Settings.ini, Misc, ChromeVersion } SaveDriverURLOFErrorPage(){ ; save the url of the result page. That way if a tab is not found for a site, we can open up a tab from this tab instead of middle of nowhere. That way we can keep the tabs together try URLOfLastErrorPage := driver.URL } FindAndActivateTab(TabURL){ DevModeMsgBox(TabURL) Loop, { if(A_index = 30) break try CurrentTabTitle := driver.window.title if(CurrentTabTitle = "") ; caused by tab being manually closed. Not sure if this is the only cause though. { ; DevModeMsgBox("currenttabtutle is blank") try driver.SwitchToNextWindow Continue } ; DevModeMsgBox(CurrentTabTitle) try CurrentTabURL := driver.Url DevModeMsgBox(CurrentTabURL) if(CurrentTabURL = TabURL) Break try driver.SwitchToNextWindow() } }