;---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 CurrentTabURL
global URLOfLastErrorPage
DevModeMsgBox(Message){
if(!DevMode)
return
Msgbox, 4096, DevModeMsgBox, %Message%
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-------------------------------
; -------------------------------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){
; Do not log if we do not have an errorlog filepath
if(ErrorLoggingFilePath = "")
return
; ErrorLoggingFile := Filepath
FormatTime, TodayDate , YYYYMMDDHH24MISS, yyyyMMdd_hhmmss
text =
(
---------------%TodayDate%---------------
%Text%
)
FileAppend, %Text%, %ErrorLoggingFilePath%
}
; -------------------------------/LogErrorsToTextFile-------------------------------
; -------------------------------LogErrorsToVar-------------------------------
Func_LogErrorsToVar(Text){
ErrorLogVar .= "`n" . Text
}
; -------------------------------/LogErrorsToVar-------------------------------
; -------------------------------CheckDirExistAndCreate-------------------------------
; Check if directory exists and if not, create it
CheckDirExistAndCreate(Path){
if(!FileExist(Path)){
FileCreateDir, %Path%
}
}
; -------------------------------/CheckDirExistAndCreate-------------------------------
; Script Updates
; ------------------------------------------------
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
}
/*
*/
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,
}
/*
*/
; -------------------------------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
}
SaveCurrentChromeVersionToIniFile(){
if(InstalledChromeVersion = "")
InstalledChromeVersion := GetInstalledChromeVersion()
IniWrite, %InstalledChromeVersion%, Settings.ini, Misc, ChromeVersion
}
; -------------------------------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
}
HasSubstringVal(haystack, needle)
{
if !(IsObject(haystack)) || (haystack.Length() = 0)
return 0
for index, value in haystack
if (InStr(value, Needle))
return index
return 0
}
; -------------------------------Functions-------------------------------
; https://www.autohotkey.com/docs/v2/Functions.htm#Variadic
Join(sep, params*) {
For index, param in params
str .= param . sep
return SubStr(str, 1, -StrLen(sep))
}
LogErrorToTextFile(Error){
/* if(LogErrorsToTextFile != 1)
Return
*/
ErrorLoggingFile := VideoFolderDir . "\" . "ErrorLogging.txt"
FormatTime, TodayDate , YYYYMMDDHH24MISS, yyyyMMdd_hhmmss
text =
(
---------------%TodayDate%---------------
%CurrentSite%: %Error%
)
if(LogErrorsToMsgbox)
Msgbox % "Text: " Text
FileAppend, %Text%, %ErrorLoggingFile%
} ; End of Function
/*
*/
AddToTotalVideosUploadedCount(){
; IniRead, TotalVideosUploaded, %SettingsIniFilepath%, General, TotalVideosUploaded, %A_Space%
TotalVideosUploaded += 1
; IniWrite, %TotalVideosUploaded%, %SettingsIniFilepath%, General, TotalVideosUploaded
}
Check_For_Stuck_Video_Upload(Index_Number, Upload_Status){
if(A_index = 1){ ; Create a blank array
ProgressStatusArray := []
Return
}
Message = Upload Status: %Upload_Status%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip")
; if we reached the last loop number:
if(A_index = %Number_of_loops_to_Check_Upload_status%){
Message = Upload Most Likely Failed: Video Hasn't Finished Uploading after 1 hour.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return "Failed"
}
; If progress is still the same after a ten minute interval then error out
if(HasVal(Array_Index_Num_of_Upload_StatusChecks, A_index)){ ; if current index is in Array of index numbers to check status during
; Send a notification message of upload status
Message = Upload Status: %Upload_Status%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
; if current upload_status is in the array of values that are updated every 10 mins
if(HasVal(ProgressStatusArray, Upload_Status)){
Message = Upload Failed (E#4508)`nUpload Stuck at same point for 10 minutes. Stuck Status: %ProgressStatus%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return "Failed"
}
ProgressStatusArray.Push(Upload_Status) ; append current status to array
}
} ; end of func
/*
*/
; Find the longest word in a string of words
FindLongestWordInString(m, calloutNumber, pos, haystack, pattern){
Global wordLength, longestWord
len := StrLen(m)
If ( len > wordLength )
{
wordLength := len
longestWord := m
; MsgBox, %m%
}
}
/*
*/
; Split a long string into multiple pieces based on the string lengtht you want and return an array with all strings
SplitStringWithSentences(text, maxChunkSize) {
sentences := StrSplit(text, "\. ") ; split at period with space after it
currentChunk := ""
chunks := []
Loop, % sentences.Length()
{
sentence := sentences[A_Index]
CurrentChunkAndSentence := currentChunk . sentence
; Msgbox % "CurrentChunkAndSentence: " CurrentChunkAndSentence
; msgbox % StrLen(CurrentChunkAndSentence)
if (StrLen(CurrentChunkAndSentence) <= maxChunkSize)
{
currentChunk .= sentence . "\. "
}
else
{
chunks.Push(currentChunk)
currentChunk := sentence . "\. "
}
}
if (currentChunk != "")
chunks.Push(currentChunk)
return chunks
}
CreateErrorLoggingFiles(Directory := ""){
FormatTime, TodayDate, YYYYMMDDHH24MISS, yyyyMMdd_hhmmss
ErrorLoggingDirectory := Directory
if(ErrorLoggingDirectory = ""){
ErrorLoggingDirectory := A_ScriptDir . "\Lib\ErrorLogging"
; If directory for error logging doesn't exist, create it
if(!FileExist(ErrorLoggingDirectory))
FileCreateDir, %ErrorLoggingDirectory%
ErrorLoggingDirectory := ErrorLoggingDirectory . "\" . TodayDate . "_" . ScriptAbbreviatedName
}
; Msgbox % "ErrorLoggingDirectory: " ErrorLoggingDirectory
FileCreateDir, %ErrorLoggingDirectory%
; Create variables with filepaths that content will be saved to.
global ErrorLoggingFilePath := ErrorLoggingDirectory . "\" . "ErrorLogging.txt"
global StatusFileFilePath := ErrorLoggingDirectory . "\" . "PostStatus.ini"
global PostTitleFilePath := ErrorLoggingDirectory . "\" . "PostTitle.txt"
global PostBodyFilePath := ErrorLoggingDirectory . "\" . "PostBody.txt"
global PostTagsFilePath := ErrorLoggingDirectory . "\" . "PostTags.txt"
PostStatusesFilepath := ErrorLoggingDirectory . "\" . "Status.ini"
; Msgbox % "ErrorLoggingDirectory: " ErrorLoggingDirectory
Return
}
; if passed argument is .exe file, then script has just been updated and we need to delete the old .exe file
CheckIfUpdateInstalled(PassedInArgument :=""){
if(InStr(PassedInArgument,".exe")){
FileDelete, %PassedInArgument%
if(ErrorLevel){ ; most likely because the old version hasn't finished exiting yet
Message = Failed to Delete Old .exe file after Updating
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar")
}
}
}
; https://www.autohotkey.com/boards/viewtopic.php?t=59936
GetDateOrdinalSuffix(D) {
Static Special := {1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st"}
Return D . ((S := Special[D]) ? S : "th")
}
; OnMsgbox - Custom Msgbox Screens
;------------------------------------------------
ConfirmBeforeSubmitMsgboxFunc(){
/*
; Snippet to for check:
if (ConfirmBeforeSubmit && ConfirmBeforeSubmitMsgboxFunc() != true) {
Message = User Selected STOP button when asked for confirmation. Cancelling Rest of Site Upload.
SaveOrPostProgress(Message:=Message, PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
return
}
*/
OnMessage(0x44, "OnMsgBoxUserConfirmation")
MsgBox 0x21, User Confirmation, Please check that all data was input correctly and fix any mistakes and then click PROCEED to finalize the Upload.`n`nClick STOP to cancel the rest of this Upload and move on to the next website.
OnMessage(0x44, "")
IfMsgBox OK, {
return true
} Else IfMsgBox Cancel, {
Message = User Selected STOP button when asked for confirmation. Cancelling Rest of Site Upload.
Return %Message%
}
}
OnMsgBoxUpdateAvailable() {
DetectHiddenWindows, On
Process, Exist
If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) {
ControlSetText Button1, Cancel
ControlSetText Button2, Install
}
}
; Show a user confirmation msgbox with a PROCEED and STOP buttons
; Used by the "Confirm before Submit" checkbox
OnMsgBoxUserConfirmation() {
DetectHiddenWindows, On
Process, Exist
If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) {
ControlSetText Button1, PROCEED
ControlSetText Button2, STOP
}
}
OnMsgBoxConfirmChromiumOverwrite() {
DetectHiddenWindows, On
Process, Exist
If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) {
ControlSetText Button1, Cancel
ControlSetText Button2, Yes
}
}
OnMsgBoxPodcastFinish() {
DetectHiddenWindows, On
Process, Exist
If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) {
WinMove,, 0
}
}
OnMsgBoxSocialMediaPoster() {
DetectHiddenWindows, On
Process, Exist
If (WinExist("ahk_class #32770 ahk_pid " . ErrorLevel)) {
ControlSetText Button1, Yes
ControlSetText Button2, Not Now
}
}