commit 2396f8f67bf879b2c2b4361f58efc7513178cfc7 Author: yuriy Date: Thu Feb 23 15:54:44 2023 -0500 initial commit diff --git a/Freedomain-Uploader-Shared-Functions.ahk b/Freedomain-Uploader-Shared-Functions.ahk new file mode 100644 index 0000000..881b751 --- /dev/null +++ b/Freedomain-Uploader-Shared-Functions.ahk @@ -0,0 +1,1872 @@ +;---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 ChromeTabsURLArray +global DriverTitleArray +global LastWebsitePostURL +global ChromeFilepath +global CurrentTabURL +global URLOfLastErrorPage + +; #Include %A_ScriptDir%\ChromeAutomationFunctions.ahk +; #Include %A_ScriptDir%\RunCMD.ahk + + +DevModeMsgBox(Message){ + if(!DevMode) + return + + Msgbox, 4096, DevModeMsgBox, %Message% + return +} + + +CheckForUpdates(GitReleasesAPIURL){ + ; msgbox, checking for updates + Message = Checking For Updates + SaveOrPostProgress(Message,PostType:="ErrorLoggingTextFile") + + data := URLDownloadToVar(GitReleasesAPIURL) + ; Msgbox % "data: " data + + parsed := JSON.Load(data) + + UpdateVersionNumber := parsed.1.name + + ; Message = UpdateVersionNumber: %UpdateVersionNumber% + ; DevModeMsgBox(Message) + + + if(ScriptVersion = UpdateVersionNumber OR ScriptVersion > UpdateVersionNumber){ + ToolTip + return 0 + } + else, { + UpdateAvailable := 1 + ; msgbox, update found! + Message = Program Update Found + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile") + ; IniWrite, 1, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable + ; ToolTip + return 1 +} + +} + + +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") + ; 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, "DevModeMsgBox")){ + DevModeMsgBox(Message) + } + 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) + +} + + + + +; -------------------------------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 + + ; @ todo: replace with regex + 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 + + if(ReuseTabs) + CreateArrayOfChromeTabs() + + +} + +SeleniumConnectToActiveTab(IP_Port := "127.0.0.1:9222"){ + Driver := ComObjCreate("Selenium.ChromeDriver") + Driver.SetCapability("debuggerAddress", IP_Port) + try Driver.Start() + catch e { + Message = Failed to Connect to Chrome. Showing Error Msgbox + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + 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 +} + +CreateArrayOfChromeTabs() { + Message = Creating an Array of All Chrome Tabs + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + ; Create an arrays + DriverTitleArray := [] + ChromeTabsURLArray := [] + + try TotalTabsFound := Driver.Windows.Count + ; Message = TotalTabsFound: %TotalTabsFound% + ; DevModeMsgBox(Message) + ; DevModeMsgBox(TotalTabsFound) + +/* ; if only 1 tab exists, grab info, push to array and return + if(TotalTabsFound = 1){ + try Title := Driver.Title + try URL := Driver.URL + + if(Title != "") + DriverTitleArray.Push(Title) + if(URL != "") + ChromeTabsURLArray.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 + + + + ; 5 is arbitrary number to do some extra loops to make sure all tabs are gone through + ; most likely not necessary because unloaded tabs cannot be activated + TotalTabLoops := TotalTabsFound + 5 + ; Message = TotalTabLoops: %TotalTabLoops% + ; DevModeMsgBox(message) + + Loop % TotalTabLoops { + Message = Creating an Array of All Chrome Tabs`nCurrent Loop: %A_index%/%TotalTabLoops% (Cannot check on unloaded tabs)`nSometimes might get stuck for a short while if there is something loading in active tab + TooltipThis(Message) + + ; exit after looping through 1 tab, if only 1 tab found in count + if(TotalTabsFound = 1 AND A_index > TotalTabsFound){ + Message = Exiting Early after 1 loop + ; DevModeMsgBox(message) + 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 + + ; 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(ChromeTabsURLArray, STRINGVAR) ; returns position of value in array + +/* + if(HasVal(ChromeTabsURLArray, URL)){ ; returns position of value in array + DevModeMsgBox("Skipping rest of loop and continuing") + Continue + } + + */ + + + if(Title != "") + DriverTitleArray.Push(Title) + if(URL != "") + ChromeTabsURLArray.Push(URL) + + + try driver.SwitchToNextWindow ;Focuses Selenium on the newly opened/next window. + ; DevModeMsgBox("switching to next tab") + } ; end of loop + + ; TimeToLoopThroughAllTabs := A_TickCount - StartTime + ; Message = Time to Loop through all tabs: %TimeToLoopThroughAllTabs% + ; SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") + ; DevModeMsgBox(Message) + + return + + + } + + 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------------------------------- +ExtractBaseURL(URL){ + URLBase := StrReplace(URL,"https://","") ; remove beginning of URL + URLBase := StrReplace(URLBase,"http://","") ; remove beginning of URL + URLBase := StrReplace(URLBase, "www.","") ; remove www if there 1 + URLBase := StrSplit(URLBase, "/") ; remove text after url base + URLBase := URLBase[1] + + return URLBase +} + + +ActivateChromeTab(URL){ + ; convert to baseUR + if(InStr(URL, "/")){ + URLBase := ExtractBaseURL(URL) + } + else, { + URLBase := URL + } + + + Message = Finding Tab with URL base: %URLBase% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + DevModeMsgBox(Message) + + + ; if not connected to selenium chrome, then re-connect + if(!DriverStatus){ + Status := CheckSeleniumDriver() + if(Status) + Return "Failed" + + ; CreateArrayOfChromeTabs() ; moved to the end of checkseleniumdriver() + } + + + TabFoundSuccessfully := + + NumberOfTabActivationLoops := ChromeTabsURLArray.Length() + Message := "NumberOfTabActivationLoops: " NumberOfTabActivationLoops + DevModeMsgBox(Message) + + ; NumberOfTabLoops := Driver.Windows.Count + 2 + loop % NumberOfTabActivationLoops { ; loop through tabs to find matching tab + try driver.SwitchToNextWindow() + + ; sleep, 1000 + ; msgbox, looping through tabs + try CurrentTabTitle := driver.window.title + try CurrentTabURL := driver.Url + + if(InStr(CurrentTabURL, URLBase)){ + + Message = Found Tab:.`n%CurrentTabTitle% = %PageTitle%`n%CurrentTabURL% = %URLBase% + DevModeMsgBox(message) + + TabFoundSuccessfully := 1 + ; msgbox %CurrentTabTitle% = %PageTitle% + ; msgbox %CurrentTabURL% = %URL% + return + } + + ; / loop through tabs +} +return "Failed" +} + +/*ActivateChromeTab(URL){ + + + + ; ChromeTabsURLArray + if(!HasSubstringVal(ChromeTabsURLArray, URLBase)) + { + try, run "%ChromeFilepath%" "%URL%" + ChromeTabsURLArray.Push(URL) ; Append the new url to the array + NewTabCreated := 1 + sleep, 1000 + } +} + + +*/ + + + +NavigateFromBaseURLTo(URL,PageTitle := "TodoDeleteme"){ + if(!DriverStatus){ ; if not connected to selenium chrome, then re-connect + Status := CheckSeleniumDriver() + if(Status) + Return "Failed" + + ; CreateArrayOfChromeTabs() ; moved to the end of checkseleniumdriver() + } + + ; ArrayOfOpenTabsLength := ChromeTabsURLArray.Length() ; Save total number of items in the array + + + ; message = URL: %URL% + ; DevModeMsgBox(message) + + URLBase := ExtractBaseURL(URL) + + +/* if(ReuseTabs){ + URLBase := StrReplace(URL,"https://","") ; remove beginning of URL + URLBase := StrSplit(URLBase, "/") ; remove text after url base + URLBase := URLBase[1] + URLBase := StrReplace(URLBase, "www.","") ; remove www if there 1 + } + + */ + ; Message = URLbase after cleaning: %URLBase%`nOriginal URL: %URL% + ; DevModeMsgBox(message) + + ; if URLBase is NOT a substring within any of the values in the array + if(!HasSubstringVal(ChromeTabsURLArray, URLBase)) + { + ; DevModeMsgBox("Creating new tab") + try, run "%ChromeFilepath%" "%URL%" + ChromeTabsURLArray.Push(URL) ; Append the new url to the array + NewTabCreated := 1 + sleep, 1000 + } + + message = NewTabCreated: %NewTabCreated% + DevModeMsgBox(message) + + + status := ActivateChromeTab(URLBase) + if(Status = "Failed"){ + try currentURL := driver.url + Message = Failed to switch active tab to %URLBase%. Current tab is: %currentURL% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + ; message = ActivateChromeTab Status: %status% + ; DevModeMsgBox(message) + + if(!NewTabCreated){ ; if re-using a tab then we want to re-navigate to URL because it might be the wrong page + + ; Double check that the current tab URL matches the url base + try, CurrentTabURl := driver.url + Message = Reusing Tab. `nCurrentTabURl: %CurrentTabURl%`nURL Navigating to: %URL% + DevModeMsgBox(Message) + + + try driver.Get(URL) ;Open selected URL + catch e { + Message = Failed to Navigate to URL in pre-existing tab`nPlease See Error #5648 for code section + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; SaveDriverURLOFErrorPage() + ; Return + + ; 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" + } + } + try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + } + ; msgbox, no error caught + ; } + + + Return +} + + +CheckForAlerts(){ + status := 1 + try driver.SwitchToAlert() + catch e { + status := 0 + return 0 + } + + if(status){ + ; msgbox, alert found + Message = Page Alert Found. Dismissing. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + try driver.switchToalert().dismiss() + return "AlertFound" + } + + +} + +; 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 + + return LastWebsitePostURL +} + + +; -------------------------------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 the Uploader to control it with Selenium.`nAutomatically restart Chrome in debug mode 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. Program Exiting + 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")){ + 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 +} + + + + + + +; Various functions used to control Selenium, Chrome and Chrome.AHK + + +;---Javascript--- +;------------------------------------------------ +JS_TryToExecute(JsToExecute,NumberofAttempts := 1,SleepLength:=1000){ + loop, %NumberofAttempts% { + try driver.executeScript(JsToExecute) + catch e { + Continue + } + Return + } + Return "Failed" +} + + + +js_SendAndCheckWithQuerySelector(Selector,ValueToCheck:="value",SleepLength:=1000,JSStringText:="TEXT"){ + js = document.querySelector("%Selector%").value = "%JSStringText%"; + try driver.executeScript(js) + + sleep, %SleepLength% + + js = return document.querySelector("#title").value; + try, status := driver.executeScript(js) + + ; DevModeMsgBox(status) + + if(Status = "") + return "Failed" + else, + return "" + +} + + +; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value +js_SendAndCheckWithClassName(ClassName:="",ClassIndexNum:=0,ValueToCheck:="textContent",SleepLength:=1000,JSStringText:="TEXT"){ + jsSend = document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].value = "%JSStringText%"; + try driver.executeScript(jsSend) + + sleep, %SleepLength% + + jsCheck = return document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].%ValueToCheck%; + try Status := driver.executeScript(jsCheck) + ; Msgbox % "Status: " Status + + if(Status = "") + return "Failed" + else, + return "" +} + +; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value +js_SendAndCheckWithNAME(Element:="",IndexNum:=0,ValueToCheck:="textContent",SleepLength:=1000,JSStringText:=""){ + jsSend = document.getElementsByName('%Element%')[%IndexNum%].value = "%JSStringText%"; +/*Clipboard := jsSend +Msgbox % "jsSend: " jsSend + +*/ +; document.getElementsByClassName('%ClassName%')[%ClassIndexNum%].value = "%JSStringText%"; +try driver.executeScript(jsSend) + +sleep, %SleepLength% + +jsCheck = return document.getElementsByName('%Element%')[%IndexNum%].%ValueToCheck%; +; Clipboard := jscheck +; Msgbox % "jsCheck: " jsCheck +try Status := driver.executeScript(jsCheck) +; Msgbox % "Status: " Status +if(Status = "") +return "Failed" +else, +return "" +} + +; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value +js_SendAndCheckWithID(Element:="",ValueToCheck:="textContent",SleepLength:=1000,JSStringText:=""){ + ; Msgbox % "Element: " Element + ; Msgbox % "JSStringText: " JSStringText + jsSend = document.getElementById('%Element%').value = "%JSStringText%"; + ; Clipboard := jsSend + ; Msgbox % "jsSend: " jsSend + try driver.executeScript(jsSend) + + ; Msgbox % "JSStringText: " JSStringText + sleep, %SleepLength% + + jsCheck = return document.getElementById('%Element%').%ValueToCheck%; + try Status := driver.executeScript(jsCheck) + if(Status = "") + return "Failed" + else, + return "" +} + +;---\Javascript--- +;------------------------------------------------ + + +;---Selenium--- +;------------------------------------------------ +; When called these will try multiple times to click/input into a web element + +Selenium_LoopToClickID(IDName,NumOfLoops:=1,SleepLength:=1000){ + loop, %NumOfLoops% { + try driver.findElementsByID(IDName).item[1].click() ; Click on "upload image" button + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + + +Selenium_LoopToClickName(ElementName,NumOfLoops:=1,SleepLength:=1000){ + loop, %NumOfLoops% { + try driver.findElementsByName(ElementName).item[1].click() + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + + +Selenium_LoopToSendValueToID(IDName,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ + loop, %NumOfLoops% { + try driver.findElementsByID(IDName).item[1].sendKeys(StringTextContent) ; Click on "upload image" button + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} +; Selenium_LoopToSendValueByName(ElementName:="NAME",NumOfLoops:=2,SleepLength:=1000,StringTextContent:="TEXT") +Selenium_LoopToSendValueByName(ElementName,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ + loop, %NumOfLoops% { + try driver.findElementsByName(ElementName).item[1].SendKeys(StringTextContent) + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + +Selenium_LoopToSendValueToXpath(Xpath,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=""){ + loop, %NumOfLoops% { + ; ToolTip, Loop attempt: %A_index% + try driver.FindElementByXPath(Xpath).sendKeys(StringTextContent) ; Click on "upload image" button + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + + +Selenium_LoopToClickXpath(Xpath,NumOfLoops:=1,SleepLength:=1000){ + loop, %NumOfLoops% { + try driver.FindElementByXPath(Xpath).click() + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + +Selenium_LoopToClickXpathAndWaitForOpenWindow(Xpath,NumOfLoops:=1,SleepLength:=1000,WindowName:="Open"){ + loop, %NumOfLoops% { + ; TooltipThis("Clicking xpath") + try driver.FindElementByXPath(Xpath).click() + catch e { + if(A_index = NumOfLoops){ + Return "Failed to Click Xpath or Open File window did not show up on click" + } + sleep, %SleepLength% + Continue + } + ; tooltipthis("Checking if window exists") + sleep, 1000 + ; Msgbox % "WindowName: " WindowName + if(!WinExist(WindowName)){ + Message = %WindowName% not found on %A_index% attempt. + ; tooltipthis("Window not found") + + sleep, %SleepLength% + Continue + } + Return +} +} + + +Selenium_LoopToClearXpath(Xpath,NumOfLoops:=1,SleepLength:=1000){ + loop, %NumOfLoops% { + try driver.FindElementByXPath(Xpath).clear() + catch e { + if(A_index = NumOfLoops){ + Return "Failed" + } + sleep, %SleepLength% + Continue + } + Return +} +} + +;---\Selenium--- +;------------------------------------------------ + +; -------------------------------Javascript------------------------------- +ReturnAndDisplayJSData(jsref){ +; msgbox, here goes +; https://www.w3schools.com/jsref/dom_obj_all.asp +; -----TEXT CONTENT----- +js = return %jsref%.textContent; +try status := driver.executeScript(js) + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3,.TextContent:,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + +} Else IfMsgBox No, { +TextForClip = js = %js% `n try, status := driver.executeScript(js) +Clipboard := TextForClip +} Else IfMsgBox Cancel, { +return +} + +; -----VALUE----- +js = return %jsref%.value; +try status := driver.executeScript(js) + + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3,.value:,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + +} Else IfMsgBox No, { +TextForClip = js = %js% `n try, status := driver.executeScript(js) +Clipboard := TextForClip +} Else IfMsgBox Cancel, { +return +} + +; -----INNERTEXT----- +js = return %jsref%.innerText; +try status := driver.executeScript(js) + + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3, .innerText,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + +} Else IfMsgBox No, { +TextForClip = js = %js% `n try, status := driver.executeScript(js) +Clipboard := TextForClip +} Else IfMsgBox Cancel, { + return +} + + +; -----OuterText----- +js = return %jsref%.outerText; +try status := driver.executeScript(js) + + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3, .outerText,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + +} Else IfMsgBox No, { +TextForClip = js = %js% `n try, status := driver.executeScript(js) +Clipboard := TextForClip +} Else IfMsgBox Cancel, { +return +} + + +;-----innerHTML----- +js = return %jsref%.innerHTML; +try status := driver.executeScript(js) + + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3, .innerHTML,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + +} Else IfMsgBox No, { +TextForClip = js = %js% `n try, status := driver.executeScript(js) +Clipboard := TextForClip +} Else IfMsgBox Cancel, { + return +} + + +; -----outerHTML----- +js = return %jsref%.outerHTML; +try status := driver.executeScript(js) + + +OnMessage(0x44, "OnMsgBoxJSReturnData") +MsgBox 0x3, .outerHTML,%status% +OnMessage(0x44, "") + +IfMsgBox Yes,{ + + } Else IfMsgBox No, { + TextForClip =js = %js% `n try,status := driver.executeScript(js) + Clipboard := TextForClip + } Else IfMsgBox Cancel, { + return + } + + + } + + +OnMsgBoxJSReturnData() { + DetectHiddenWindows, On + Process, Exist + If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) { + ControlSetText Button1, OK + ControlSetText Button2, Copy + ControlSetText Button3, Return + } +}