diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cda495c --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +Settings.ini +VideoLinks.ini +body.txt +**/ErrorLogging +**/Test Videos +**/Backups +**/Debug +**/Templates +**/Testing +*/ConnectToActiveChromeTab.ahk +**ConnectToActiveChromeTab.ahk +Freedomain Social Media Poster*.exe +Compile Scripts to EXE.ahk diff --git a/Assets/FDRBlack.png b/Assets/FDRBlack.png new file mode 100644 index 0000000..6cca716 Binary files /dev/null and b/Assets/FDRBlack.png differ diff --git a/Assets/FDRRoundIcon.png b/Assets/FDRRoundIcon.png new file mode 100644 index 0000000..94bf1b9 Binary files /dev/null and b/Assets/FDRRoundIcon.png differ diff --git a/Assets/Freedomain.ico b/Assets/Freedomain.ico new file mode 100644 index 0000000..d090e5d Binary files /dev/null and b/Assets/Freedomain.ico differ diff --git a/Assets/FreedomainShare.ico b/Assets/FreedomainShare.ico new file mode 100644 index 0000000..534922d Binary files /dev/null and b/Assets/FreedomainShare.ico differ diff --git a/Assets/FreedomainShare_Scheduled.ico b/Assets/FreedomainShare_Scheduled.ico new file mode 100644 index 0000000..787d001 Binary files /dev/null and b/Assets/FreedomainShare_Scheduled.ico differ diff --git a/Assets/FreedomainVideo.ico b/Assets/FreedomainVideo.ico new file mode 100644 index 0000000..059e7a1 Binary files /dev/null and b/Assets/FreedomainVideo.ico differ diff --git a/Assets/Share.ico b/Assets/Share.ico new file mode 100644 index 0000000..2a6e35e Binary files /dev/null and b/Assets/Share.ico differ diff --git a/Assets/Social.ico b/Assets/Social.ico new file mode 100644 index 0000000..7ff1ab6 Binary files /dev/null and b/Assets/Social.ico differ diff --git a/Assets/Update.ico b/Assets/Update.ico new file mode 100644 index 0000000..48250ae Binary files /dev/null and b/Assets/Update.ico differ diff --git a/Freedomain Video Uploader.ahk b/Freedomain Video Uploader.ahk new file mode 100644 index 0000000..83d5c2b --- /dev/null +++ b/Freedomain Video Uploader.ahk @@ -0,0 +1,5216 @@ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +; #Warn ; Enable warnings to assist with detecting common errors. +#SingleInstance, Force +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +CoordMode, ToolTip, Screen +CoordMode, Mouse, Screen +FileEncoding, UTF-8-RAW ; Needed for special symbols that are used in video descritions +if(InStr(A_ScriptFullPath, ".ahk")){ + try Menu, Tray, Icon, %A_ScriptDir%\Assets\FreedomainVideo.ico +} + +PassedParameter = %1% + +; Add menus to the toolbar icon +Menu, tray, NoStandard + +Menu, Tray, Add, Exit, KillScript +Menu, Tray, Add, Pause, PauseScript + +Menu, Tray, Add, Open New Project, ReloadScript +; Menu, Tray, Add, Restart to Last Project Upload Results, ReloadToResults ; @todo fix this as it currently just loads the last project +Menu, Tray, Add, Restart with Last Project, RetryUpload +Menu, Tray, Default, Restart with Last Project + + +global ScriptName +global ScriptVersion +global FullScriptName + +ScriptName = Freedomain Video Uploader +ScriptVersion = 2.98 +FullScriptName := ScriptName . " - " . ScriptVersion + + + +; Included Files +#include %A_ScriptDir%\Lib\StdOutToVar.ahk ; used for chrome debugging mode connection +#Include C:\Users\%A_UserName%\Syncthing\Git\Freedomain-Social-Media-Poster\Lib\SharedFunctions.ahk ; @todo, move this to a git submodule +#Include %A_ScriptDir%\Lib\JSON.ahk +#Include %A_ScriptDir%\Lib\ChromeAutomationFunctions.ahk + + +;---ToDo--- +;------------------------------------------------ +; @todo: Update Locals Share link grabbing + +; @todo: finish show results functionality on line 430 +; @todo: fix uploader saying there's been failures b/c there was no lbry audio upload +; @todo: finish telegram multi-message split functionality. +; @todo: add different icon when update is available +; @todo: fix telegram post getting cut off if too long instead of splitting into 2 +; @todo: fix ping always saying that there was failures +; @todo: let user make last minute changes to text before submitting to telegram and discord +; @todo: replace all .Attribute("innerText") with js +; @todo: Fix locals not grabbing url if a post is pinned +; @todo: Add an input box for sources in the new frontend +; @todo: Fix bitchute title getting input twice +; @todo: Add login check for each website and ability to auto login +; @todo: ; add to statistics in statusbar - length of philosophy uploaded... total hours uploaded? + +; @todo: add support for unauthorized.tv +; @todo: Bitchute has a 5k char limit for description as well. split description to remove reocurring bits and Add freedomainpodcasts.com/podcast/# link if still not big enough +; @todo: Split long discord/telegram messages into multiple messages +; @todo: Redo Discord posting with "PostErrors" function from social media poster +; @todo: Save updates made to GUi text to .ini file on changes +; @todo: add a SaveDriverURL() next to each RETURN in the code so reusable tabs can be grouped together + +;---Global Variables--- +;------------------------------------------------ +global LBRYResolveAPICommand +global LBRYPermanentURL +global VideoTitle +global VideoFilepath +global VideoThumbFilepath +global VideoTags +global VideoDescription +global SocialMediaDescription +global DiscordErrorLoggingWebhookBotURL +global DiscordVideosWebhookURL +global VideoFolderDir +global LogErrorsToMsgbox +; global LogErrorsToTextFile +global CurrentSite +global Driver +global DriverStatus +global ChromeProfile +global ShowTooltipProgressCheckStatus +global ShowTooltipProgress +global ErrorLogSummary +global DiscordParlerWebhookURL +global ErrorLoggingFilePath + +global ErrorLogVar +ErrorLogVar := "Upload Errors:" . "`n" + +global ReuseTabs ; reuse tabs variable +global DevMode +global ScreenshotResult + +global LBRYNetFilepath +LBRYNetFilepath := "C:\Program Files\LBRY\resources\static\daemon\lbrynet.exe" + +global Number_of_loops_to_Check_Upload_status +Number_of_loops_to_Check_Upload_status = 720 +; 720 loops, at 5 seonds each = 3600 seconds (60 mins) + +; number of seconds to wait between loops when checking video upload status +global Time_Between_Loops_Upload_Status +Time_Between_Loops_Upload_Status = 5000 + +; loop Index number to check if video is stuck uploading +global Array_Index_Num_of_Upload_StatusChecks +Array_Index_Num_of_Upload_StatusChecks := [144,288,432, 576,720,864] +; loop number that discord message gets sent off at to track upload progress +; 144 x 5 seconds = 12 minutes + +; Check if Lib folder exists and create it if not +LibFolder := A_ScriptDir . "\Lib" +ErrorLoggingFolder := A_ScriptDir . "\Lib\ErrorLogging" +FileCreateDir, %ErrorLoggingFolder% + +; Set filepaths for different files and folders +global SettingsIniFilepath +SettingsIniFilepath := A_ScriptDir . "\Settings.ini" + +global ChangelogIniFilepath +ChangelogIniFilepath := A_ScriptDir . "\Lib\FreedomScriptsChangelogINI" + +global ScriptSettingsSection +ScriptSettingsSection := "VideoUploader" + + +;---Script Settings--- +;------------------------------------------------ +; Checkbox Settings +IniRead, ShowTooltipProgress, %SettingsIniFilepath%, General, ShowTooltipProgress, 1 +(ShowTooltipProgress)?(ShowTooltipProgressCheckStatus := 1) : (ShowTooltipProgressCheckStatus := 0) + + +Message = Reading Settings from .ini files +; ToolTip, reading settings +SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + + + +IniRead, RootDirToStartIn, %SettingsIniFilepath%, General, RootDirToStartIn +IniRead, LogErrorsToMsgbox, %SettingsIniFilepath%, General, LogErrorsToMsgbox, %A_Space% +IniRead, UpdateAvailable, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable, 0 +; Msgbox % "SettingsIniFilepath: " SettingsIniFilepath +; Msgbox % "UpdateAvailable: " UpdateAvailable +IniRead, DevMode, %SettingsIniFilepath%, General, DevMode, 0 +IniRead, ScreenshotResult, %SettingsIniFilepath%, General, ScreenshotResult, 0 +IniRead, TotalVideosUploaded, %SettingsIniFilepath%, General, TotalVideosUploaded, 0 + +; Checkbox Settings +IniRead, ShowTooltipProgress, %SettingsIniFilepath%, General, ShowTooltipProgress, 1 +(ShowTooltipProgress)?(ShowTooltipProgressCheckStatus := 1) : (ShowTooltipProgressCheckStatus := 0) + +IniRead, ReuseTabs, %SettingsIniFilepath%, General, ReuseTabs, 1 +(ReuseTabs)?(ReuseTabsCheckStatus := 1) : (ReuseTabsCheckStatus := 0) + +IniRead, AutoUpdateCheck, %SettingsIniFilepath%, General, AutoUpdateCheck, 1 +(AutoUpdateCheck)?(AutoUpdateCheckCheckStatus := 1) : (AutoUpdateCheckCheckStatus := 0) + +IniRead, PingOnCompletion, %SettingsIniFilepath%, General, PingOnCompletion, 1 +(PingOnCompletion)?(PingOnCompletionCheckStatus := 1) : (PingOnCompletionCheckStatus := 0) + +IniRead, KillLBRYAfterUpload, %SettingsIniFilepath%, General, KillLBRYAfterUpload, 1 +(KillLBRYAfterUpload)?(=KillLBRYAfterUploadCheckStatus := 1) : (KillLBRYAfterUploadCheckStatus := 0) + +IniRead, DiscordErrorLoggingWebhookBotURL, %SettingsIniFilepath%, General, DiscordWebhookBotURL, %A_space% +if(DiscordErrorLoggingWebhookBotURL = ""){ + Message = DiscordErrorLoggingWebhookBotURL is blank. `nWill not be able to post error messages or upload status to discord.`nPlease add discord webhook URL in settings.ini under: `n`n[General]`DiscordErrorLoggingWebhookBotURL= + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") +} + +IniRead, DiscordUsernameID, %SettingsIniFilepath%, General, DiscordUsernameID, %A_space% +if(DiscordUsernameID = ""){ + Message = DiscordUsernameID is blank. Will not be able to ping to notify when uploads are complete.`nPlease add user ID in settings.ini under: `n`n[General]`nDiscordUsernameID= + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") +} + +;---Auto Updater Settings--- +;------------------------------------------------ +global GitReleasesAPIURL +GitReleasesAPIURL = https://git.zinchuk.xyz/api/v1/repos/yuriy/Freedomain-Social-Media-Poster/releases + +global GitReleasesLBRYKillerAPIURL +GitReleasesAPIURL = https://git.zinchuk.xyz/api/v1/repos/yuriy/LBRY-Process-Killer/releases + + + +;---LBRY Settings--- +;------------------------------------------------ +IniRead, LBRYNewVideoStakeAmount, %SettingsIniFilepath%, General, LBRYNewVideoStakeAmount, %A_Space% +if(LBRYNewVideoStakeAmount = ""){ + LBRYNewVideoStakeAmount = 1.0 + IniWrite, %LBRYNewVideoStakeAmount%, %SettingsIniFilepath%, General, LBRYNewVideoStakeAmount +} + +IniRead, LBRYChannelID, %SettingsIniFilepath%, General, LBRYChannelID, %A_Space% +if(LBRYChannelID = ""){ + LBRYChannelID = b89ed227c49e726fcccf913bdc9dec4c8fec99c2 + IniWrite, %LBRYChannelID%, %SettingsIniFilepath%, General, LBRYChannelID +} + + + +;---Read Info From Project Files--- +;------------------------------------------------ +; Ask user to select file within the production folder +if(PassedParameter = "LastPost"){ + IniRead, PassedParameter, %SettingsIniFilepath%, %ScriptSettingsSection%, LastPost, %A_Space% +} + +if(PassedParameter = "ShowResults"){ + IniRead, PassedParameter, %SettingsIniFilepath%, %ScriptSettingsSection%, LastPost, %A_Space% +} + +PassedParameterLength := StrLen(PassedParameter) +if(PassedParameterLength < 5){ + FileSelectFile, BodyTextFilePath,,%RootDirToStartIn%,Please Select ANY File Within the Project Folder + if(ErrorLevel) + Return +} +else, { + SkipUpdateCheckThisRun := 1 + BodyTextFilePath := PassedParameter +} + + +; Do this with an array. Add all filepaths to array and then pull out the ones with the extension. +; get directory from the filepath grabbed +SplitPath, BodyTextFilePath, OutFileName, VideoFolderDir, OutExtension, OutNameNoExt, OutDrive + +Loop, files, %VideoFolderDir%\*.*, F ; loop through the files in the directory +{ ; D = Directories, F = Files, R = Recursive + SplitPath, A_LoopFileFullPath, FileNameWExt, FileDir, FileExt, FileNameNoExt, + + if(FileNameWExt = "title.txt"){ + FileRead, VideoTitle, %A_LoopFileFullPath% + LBRYURLSlug := VideoTitle + OriginalVideoTitle := VideoTitle + OriginalLBRYURLSlug := LBRYURLSlug + } + + if(FileNameWExt = "body.txt"){ + FileRead, VideoDescription, %A_LoopFileFullPath% + DescriptionCharCount := StrLen(VideoDescription) + OriginalVideoDescription := VideoDescription + } + + if(FileNameWExt = "keywords.txt"){ + FileRead, VideoTags, %A_LoopFileFullPath% + FileRead, PodcastTags, %A_LoopFileFullPath% + OriginalVideoTags := VideoTags + OriginalPodcastTags := PodcastTags + } + + if(FileNameWExt = "keywords_podcast.txt"){ + FileRead, PodcastTags, %A_LoopFileFullPath% + OriginalPodcastTags := PodcastTags + } + + if(FileExt = "mp4"){ + VideoFilepath := A_LoopFileFullPath + SplitPath, A_LoopFileFullPath,,,, VideoFileNameNoExt + FileGetSize, VideoFileSizeInMB, %A_LoopFileFullPath%, M + } + + if(FileExt = "png" OR FileExt = "jpg"){ + VideoThumbFilepath := A_LoopFileFullPath + } +} + +if(VideoDescription = ""){ + ; @todo: is this used anymore? + FileRead, VideoDescription, %A_scriptDir%\Lib\DescriptionTemplate.txt +} + +; Loop through the folder again to find the correct .WAV audio file as Stef has multiple in there and we need the .mp4 file to be found first so we know what to look for file name wise. +Loop, files, %VideoFolderDir%\*.WAV, F ; loop through the files in the directory +{ ; D = Directories, F = Files, R = Recursive + SplitPath, A_LoopFileFullPath, FileNameWExt, FileDir, FileExt, FileNameNoExt + + if(FileNameNoExt = VideoFileNameNoExt){ + WavAudioFilepath := A_LoopFileFullPath + } +} + +; Loop through the folder again to find the correct .WAV audio file as Stef has multiple in there and we need the .mp4 file to be found first so we know what to look for file name wise. +Loop, files, %VideoFolderDir%\*.mp3, F ; loop through the files in the directory +{ ; D = Directories, F = Files, R = Recursive + SplitPath, A_LoopFileFullPath, FileNameWExt, FileDir, FileExt, FileNameNoExt + + if(FileNameNoExt = VideoFileNameNoExt){ + MP3AudioFilepath := A_LoopFileFullPath + } +} + +;---Read Info From Previous Run (If Any)--- +;------------------------------------------------ +; @todo: Figure out a way to do this with an array +VideoLinksIniFile = %VideoFolderDir%\VideoLinks.ini + +if(FileExist(VideoLinksIniFile)){ + ; IniRead, StreamanityURL, %VideoLinksIniFile%, URLs, StreamanityURL, %A_Space% + IniRead, BitChuteURL, %VideoLinksIniFile%, URLs, BitChuteURL, %A_Space% + ; LBRY + IniRead, LBRYURLSlug, %VideoLinksIniFile%, Misc, LBRYURLSlug, %A_Space% + if(LBRYURLSlug = ""){ + LBRYURLSlug := OriginalLBRYURLSlug ; video title + } + ; LBRY Video + IniRead, LBRYVideoURL, %VideoLinksIniFile%, URLs, LBRYVideoURL, %A_Space% + IniRead, LBRYVideoThumb, %VideoLinksIniFile%, Misc, LBRYVideoThumb, %A_Space% + IniRead, LBRYVideoPermanentURL, %VideoLinksIniFile%, URLs, LBRYVideoPermanentURL, %A_Space% + IniRead, OdyseeVideoURL, %VideoLinksIniFile%, URLs, OdyseeVideoURL, %A_Space% + IniRead, OdyseeVideoThumb, %VideoLinksIniFile%, Misc, OdyseeVideoThumb, %A_Space% + OdyseeVideoThumb := StrReplace(OdyseeVideoThumb, "Thumb:", "") + + ; LBRY Audio + IniRead, LBRYAudioURL, %VideoLinksIniFile%, URLs, LBRYAudioURL, %A_Space% + IniRead, LBRYAudioThumb, %VideoLinksIniFile%, Misc, LBRYAudioThumb, %A_Space% + IniRead, LBRYAudioPermanentURL, %VideoLinksIniFile%, URLs, LBRYAudioPermanentURL, %A_Space% + IniRead, OdyseeAudioURL, %VideoLinksIniFile%, URLs, OdyseeAudioURL, %A_Space% + IniRead, OdyseeAudioThumb, %VideoLinksIniFile%, Misc, OdyseeAudioThumb, %A_Space% + OdyseeAudioThumb := StrReplace(OdyseeAudioThumb, "Thumb:", "") + + ; Others + IniRead, RumbleURL, %VideoLinksIniFile%, URLs, RumbleURL, %A_Space% + IniRead, BrighteonURL, %VideoLinksIniFile%, URLs, BrighteonURL, %A_Space% + IniRead, DailyMotionURL, %VideoLinksIniFile%, URLs, DailyMotionURL, %A_Space% + IniRead, PodcastNumber, %VideoLinksIniFile%, Misc, PodcastNumber, %A_Space% + IniRead, LocalsURL, %VideoLinksIniFile%, URLs, LocalsURL, %A_Space% + IniRead, FacebookURL, %VideoLinksIniFile%, URLs, FacebookURL, %A_Space% + + ; MISC + IniRead, ErrorLoggingFilePath, %VideoLinksIniFile%, Misc, ErrorLoggingFilePath, %A_Space% + IniRead, ScreenShotSavePath, %VideoLinksIniFile%, Misc, ScreenShotSavePath, %A_Space% + + if(VideoFileSizeInMB < 50){ + IniRead, Telegram, %VideoLinksIniFile%, Misc, Telegram, %A_Space% + } + +} + +; Create a directory for errorlogging and screenshots if this is the first time working on this project +if(ErrorLoggingFilePath = ""){ + ; DevModeMsgBox("generating filepath") + FormatTime, TodayDate , YYYYMMDDHH24MISS, yyyyMMdd_hhmmss + ErrorLoggingDirectory := ErrorLoggingFolder . "\" . TodayDate . "_FVU" + FileCreateDir, %ErrorLoggingDirectory% + ErrorLoggingFilePath := ErrorLoggingFolder . "\" . TodayDate . "_FVU\ErrorLogging.txt" ; Set locaiton where error logging text will go + ScreenShotSavePath = %ErrorLoggingDirectory% + + ; Write both filepaths to .ini file + IniWrite, %ErrorLoggingFilePath%, %VideoLinksIniFile%, Misc, ErrorLoggingFilePath + IniWrite, %ScreenShotSavePath%, %VideoLinksIniFile%, Misc, ScreenShotSavePath +} + +if(PodcastNumber = ""){ + PodcastNumber := StrSplit(VideoFileNameNoExt, "_") + PodcastNumber := PodcastNumber[2] +} + +; Set the checkmark status of each item based on the variable status +; (StreamanityURL != "")?(StreamanityCheckStatus := 0) : (StreamanityCheckStatus := 1) +(BitChuteURL != "")?(BitChuteCheckStatus := 0) : (BitChuteCheckStatus := 1) + +(OdyseeVideoURL != "")?(OdyseeVideoCheckStatus := 0) : (OdyseeVideoCheckStatus := 1) +(OdyseeVideoThumb != "")?(OdyseeVideoThumbCheckStatus := 0) : (OdyseeVideoThumbCheckStatus := 0) +OdyseeAudioThumbCheckStatus := 0 +if(OdyseeAudioURL OR WavAudioFilepath = "") +OdyseeAudioCheckStatus := 0 +/* +if(OdyseeAudioThumb OR WavAudioFilepath = "") +OdyseeAudioThumbCheckStatus := 0 + +*/ +(RumbleURL != "")?(RumbleCheckStatus := 0) : (RumbleCheckStatus := 1) +(LocalsURL != "")?(LocalsCheckStatus := 0) : (LocalsCheckStatus := 0) +(BrighteonURL != "")?(BrighteonCheckStatus := 0) : (BrighteonCheckStatus := 1) +if(VideoFileSizeInMB > 6144){ + VideoFileSizeOver6GB := 1 + BrighteonCheckStatus := 0 +} + +(DailyMotionURL != "")?(DailyMotionCheckStatus := 0) : (DailyMotionCheckStatus := 1) +FacebookCheckStatus := 0 +TelegramCheckStatus := 0 + + + +;---Testing Mode Overrides--- +;------------------------------------------------ +IniRead, TestingMode, %SettingsIniFilepath%, General, TestingMode, 0 +if(TestingMode){ ; save currently seelcted sites to ini file for next test + ; IniRead, Streamanity, %SettingsIniFilepath%, Testing, Streamanity, %A_Space% + ; (Streamanity)?(StreamanityCheckStatus := 1) : (StreamanityCheckStatus := 0) + IniRead, BitChute, %SettingsIniFilepath%, Testing, BitChute, %A_Space% + (BitChute)?(BitChuteCheckStatus := 1) : (BitChuteCheckStatus := 0) + + IniRead, OdyseeVideo, %SettingsIniFilepath%, Testing, OdyseeVideo, %A_Space% + (OdyseeVideo)?(OdyseeVideoCheckStatus := 1) : (OdyseeVideoCheckStatus := 0) + + IniRead, OdyseeVideoThumb, %SettingsIniFilepath%, Testing, OdyseeVideoThumb, %A_Space% + (OdyseeVideoThumb)?(OdyseeVideoThumbCheckStatus := 1) : (OdyseeVideoThumbCheckStatus := 0) + + IniRead, OdyseeAudio, %SettingsIniFilepath%, Testing, OdyseeAudio, %A_Space% + (OdyseeAudio)?(OdyseeAudioCheckStatus := 1) : (OdyseeAudioCheckStatus := 0) + + IniRead, OdyseeAudioThumb, %SettingsIniFilepath%, Testing, OdyseeAudioThumb, %A_Space% + (OdyseeAudioThumb)?(OdyseeAudioThumbCheckStatus := 1) : (OdyseeAudioThumbCheckStatus := 0) + + IniRead, Rumble, %SettingsIniFilepath%, Testing, Rumble, %A_Space% + (Rumble)?(RumbleCheckStatus := 1) : (RumbleCheckStatus := 0) + + IniRead, Brighteon, %SettingsIniFilepath%, Testing, Brighteon, %A_Space% + (Brighteon)?(BrighteonCheckStatus := 1) : (BrighteonCheckStatus := 0) + + IniRead, DailyMotion, %SettingsIniFilepath%, Testing, DailyMotion, %A_Space% + (DailyMotion)?(DailyMotionCheckStatus := 1) : (DailyMotionCheckStatus := 0) + + IniRead, Locals, %SettingsIniFilepath%, Testing, Locals, %A_Space% + (Locals)?(LocalsCheckStatus := 1) : (LocalsCheckStatus := 0) + + IniRead, Telegram, %SettingsIniFilepath%, Testing, Telegram, %A_Space% + (Telegram)?(TelegramCheckStatus := 1) : (TelegramCheckStatus := 0) + + IniRead, Facebook, %SettingsIniFilepath%, Testing, Facebook, %A_Space% + (Facebook)?(FacebookCheckStatus := 1) : (FacebookCheckStatus := 0) +} + + +; @todo: DELETE +if(DevMode){ + ; IniWrite, 0, %SettingsIniFilepath%, %ScriptSettingsSection%, UpdateAvailable + ; UpdateAvailable := 0 + ; Menu, Tray, Add, Reload to Results, ReloadToResults + +} +; Msgbox % "PassedParameter: " PassedParameter +; Msgbox % "PassedParameter: " PassedParameter +if(PassedParameter = "ShowResults"){ + msgbox, we are showing results + goto, DisplayResults +} + + +;---GUI Variables--- +;------------------------------------------------ +GuiHeight = 800 +GuiWidth = 1366 +GuiFontSize = 10 + +MarginSpace := 10 +MarginSpaceDoubled := MarginSpace * 2 + +EditBoxWidths := (GuiWidth / 100) * 60 +EditBoxHalfWidths := (EditBoxWidths / 2) - (MarginSpace / 2) +OdyseeURLSlugEditWidth := (EditBoxHalfWidths / 4) * 3 + +PodcastNumberTextXPos := EditBoxHalfWidths + OdyseeURLSlugEditWidth + (MarginSpace * 3) +PodcastNumberEditWidth := (EditBoxHalfWidths / 4) - MarginSpace + +EditBoxOneFourthWidth := (EditBoxWidths / 4 ) +EditBoxThreeFourthsWidth := (EditBoxWidths / 4 ) * 3 + + +ColumnOneHalfWidthXPos := EditBoxHalfWidths + MarginSpaceDoubled + +EditBoxThirdsWidths := (EditBoxWidths / 3) - (MarginSpace / 2) +OdyseeURLSlugXPos := EditBoxHalfWidths + (MarginSpace * 2) + +EditBoxFourthWidths := (EditBoxWidths / 4) - (MarginSpace - 2) +VideoTagsTextXPos := EditBoxHalfWidths + (MarginSpace * 2) + +; EditBoxHalfWidthsWithMargin := (EditBoxWidths / 2) +DescriptionCharCountXPos := EditBoxWidths - 40 + +PageTwoXStartPos := EditBoxWidths + 50 + +CopyButtonWidths := 150 +ResultEditBoxXPos := CopyButtonWidths + MarginSpace + 5 +ResultEditBoxWidths := EditBoxWidths - CopyButtonWidths + +ResultEditBoxHalfWidths := (ResultEditBoxWidths / 2) - (MarginSpace /2) +ResultLBRYURLEditBoxWidthPieces := (ResultEditBoxWidths / 4) +ResultLBRYURLEditBoxWidths := ResultLBRYURLEditBoxWidthPieces * 3 + +ResultEditBoxThirdsWidths := (ResultEditBoxWidths / 3) - (MarginSpace /3) + + +ResultLBRYThumbEditBoxWidth := ResultLBRYURLEditBoxWidthPieces - 5 + +ErrorLogEditBoxXPos := ResultEditBoxWidths + CopyButtonWidths + 30 +ErrorLogEditBoxHeight := GuiHeight - (MarginSpace * 20) +ErrorLogEditBoxWidth := GuiWidth - ErrorLogEditBoxXPos - (MarginSpace * 12) + + +ButtonWidths := 150 +ButtonXPos := GuiWidth - ButtonWidths - 15 + +SubmitButtonYLocation := GuiHeight - 50 +SubmitButtonXLocation := GuiWidth - 90 +CancelButtonXLocation := GuiWidth - 180 + +EditBoxHeight := 25 +ThumbnailPreviewWidth := 300 +PageTwoGroupBoxWidth := ThumbnailPreviewWidth + 20 + +; Size of Description Edit Box and the location of the checkboxes underneath them +VideoDescriptionEditBoxHeight = 100 +CheckboxesStartYPos := 630 + +FilePathEditBoxWidths := EditBoxWidths - MarginSpace - 70 +SelectFileButtonWidths := 30 + +ButtonStartYPos := CheckboxesStartYPos + 10 +MarginSquared := MarginSpace * 2 + +if(DevMode){ + MainButtonHeight := 30 + SecondaryButtonHeights := 30 + +} +else, { + MainButtonHeight := 30 + SecondaryButtonHeights := 35 +} + +; -------------------------------GUI------------------------------- + +Gui, Font, s%GuiFontSize% +Gui, Margin, %MarginSpace%, %MarginSpace% + +; Video Title +Gui, Font, Bold +Gui, Add, Text,, Show Title +Gui, Add, Text, x%ColumnOneHalfWidthXPos% yp+0,Odysee URL Slug +Gui, Add, Text, x%PodcastNumberTextXPos% yp+0,Podcast # + + +Gui, Font, Normal +Gui, Add, Edit, y+5 x%MarginSpace% w%EditBoxHalfWidths% h%EditBoxHeight% gUpdateVars vVideoTitle, %VideoTitle% +Gui, Add, Edit, yp+0 x+%Marginspace% w%OdyseeURLSlugEditWidth% h%EditBoxHeight% gUpdateVars vLBRYURLSlug, %LBRYURLSlug% +Gui, Add, Edit, yp+0 x+%Marginspace% w%PodcastNumberEditWidth% h%EditBoxHeight% gUpdateVars vPodcastNumber, %PodcastNumber% + +; LBRY URL +Gui, Font, Bold +Gui, Add, Text, x%Marginspace%,Video Tags +Gui, Add, Text,x%ColumnOneHalfWidthXPos% yp+0,Podcast Tags + +Gui, Font, Normal +Gui, Add, Edit, x%Marginspace% Y+5 w%EditBoxHalfWidths% h%EditBoxHeight% gUpdateVars vVideoTags, %VideoTags% +Gui, Add, Edit, yp+0 x+%Marginspace% w%EditBoxHalfWidths% h%EditBoxHeight% gUpdateVars vPodcastTags, %PodcastTags% + + +/*; Podcast Number & Tags +Gui, Font, Bold +Gui, Add, Text,x%MarginSpace% y+%Marginspace%,Podcast Number + +Gui, Font, Normal + +*/ +; Video Description +Gui, Font, Bold +if(NoOriginalVideoDescription) +Gui, Add, Text,cRed y+%Marginspace% x%Marginspace%,Video Description +else, +Gui, Add, Text,y+%Marginspace% x%Marginspace%,Video Description: +if(TestingMode){ + Gui, Add, Text,cRed yp+0 xp+150 ,TESTING MODE +} +if(DevMode){ + Gui, Add, Text,cRed yp+0 xp+150 ,DEV MODE +} +Gui, Font, Normal +Gui, Add, Edit,x%Marginspace% y+2 w%EditBoxWidths% h%VideoDescriptionEditBoxHeight% vVideoDescription gSubmitDescription,%VideoDescription% +gui, font, s8 +Gui, font, Bold +if(DescriptionCharCount > 3000){ + Gui, Add, Edit,cRed w50 h20 x%DescriptionCharCountXPos% y+1 vDescriptionCharCount, %DescriptionCharCount% +} +else, +Gui, Add, Edit, w50 h20 x%DescriptionCharCountXPos% y+1 vDescriptionCharCount, %DescriptionCharCount% +Gui, Font, Normal +Gui, Add,Text, yp+3 xp-310, (Platform Char Limits: DM & Bitchute = 3K, Odysee,Brighteon = 5K) +Gui, Font, s%GuiFontSize% +Gui, font, Bold +Gui, Add, GroupBox,r8.5 x%MarginSpace% yp+10 w%EditBoxWidths% Center, Filepaths + +; Video Filepath +Gui, Font, Bold +Gui, Add, Text,xp+5 yp+15,Video Filepath +Gui, Font, Normal +Gui, Add, Edit, x%MarginSquared% y+2 w%FilePathEditBoxWidths% h%EditBoxHeight% gUpdateVars vVideoFilepath,%VideoFilepath% +Gui, Add, Button, x+5 yp+0 h%EditBoxHeight% gSelectVideoFilepath, Select + +; Video Thumbnail Filepath +Gui, Font, Bold +if(NoOriginalVideoThumbFilepath) +Gui, Add, Text, x%MarginSquared% CRed y+15,Video Thumbnail Filepath +else, +Gui, Add, Text,y+15 x%MarginSquared% ,Video Thumbnail Filepath +Gui, Font, Normal +Gui, Add, Edit, x%MarginSquared% y+2 w%FilePathEditBoxWidths% h%EditBoxHeight% gUpdateVars vVideoThumbFilepath,%VideoThumbFilepath% +Gui, Add, Button, x+5 yp+0 h%EditBoxHeight% gSelectVideoThumbFilepath, Select +; WAV Audio File Filepath +Gui, Font, Bold +if(WavAudioFilepath = "") +Gui, Add, Text,cRed x%MarginSquared% y+15,WAV Filepath +else, +Gui, Add, Text,x%MarginSquared% y+15,WAV Filepath +Gui, Font, Normal +Gui, Add, Edit, x%MarginSquared% y+2 w%FilePathEditBoxWidths% h%EditBoxHeight% gUpdateVars vWavAudioFilepath,%WavAudioFilepath% +Gui, Add, Button, x+5 yp+0 h%EditBoxHeight% gSelectWAVFilepath, Select + +Gui, Font, Bold +if(MP3AudioFilepath = "") +Gui, Add, Text,cRed x%MarginSquared% y+15,Podcast MP3 Filepath +else, +Gui, Add, Text,x%MarginSquared% y+15,Podcast MP3 Filepath +Gui, Font, Normal +Gui, Add, Edit, x%MarginSquared% y+2 w%FilePathEditBoxWidths% h%EditBoxHeight% gUpdateVars vMP3AudioFilepath,%MP3AudioFilepath% +Gui, Add, Button, x+5 yp+0 h%EditBoxHeight% gSelectMP3Filepath, Select + + +; Submit Button +Gui, Font, s%GuiFontSize% +gui, Font, Bold +if(DevMode) +Gui, Add, Button, x%MarginSpace% w%EditBoxHalfWidths% y+25 h%MainButtonHeight% gCancelPost hwndIcon, Close +else, +Gui, Add, Button, x%MarginSpace% w%EditBoxHalfWidths% y+25 h%MainButtonHeight% gCancelPost hwndIcon, Close + +GuiButtonIcon(Icon, "imageres.dll", 208, "s20 a1 r2") +Gui, Add, Button, x+%MarginSpace% w%EditBoxHalfWidths% h%MainButtonHeight% gStartScript hwndIcon, Upload +GuiButtonIcon(Icon, "shell32.dll", 136, "s20 a1 r2") + +if(DevMode) +Gui, Add, Button, x%MarginSpace% w%EditBoxFourthWidths% y+%Marginspace% h%SecondaryButtonHeights% gDisplayResults hwndIcon, View Results +else, +Gui, Add, Button, x%MarginSpace% w%EditBoxFourthWidths% y+%Marginspace% h%SecondaryButtonHeights% gDisplayResults hwndIcon, View Results +GuiButtonIcon(Icon, "shell32.dll", 210, "s30 a1 r2") + +Gui, Add, Button, w%EditBoxFourthWidths% x+%Marginspace% h%SecondaryButtonHeights% gOpenProjectFolder hwndIcon, Open Project Folder +GuiButtonIcon(Icon, "shell32.dll", 267, "s30 a1 r2") + + +if(UpdateAvailable) +Gui, Add, Button, w%EditBoxHalfWidths% x+%Marginspace% gUpdateScript vUpdateAvailable h%SecondaryButtonHeights% hwndIcon, Update Available - Click to Install +else, +Gui, Add, Button, w%EditBoxHalfWidths% x+%Marginspace% gUpdateScript vUpdateAvailable h%SecondaryButtonHeights% hwndIcon, Program is Up-to-Date +; Gui, Add, Button, w%EditBoxHalfWidths% x+%Marginspace% vUpdateAvailable hwndIcon, Script is Up-to-Date +GuiButtonIcon(Icon, "shell32.dll", 239, "s30 a1 r2") + +if(DevMode){ + Gui, Add, Button, x%MarginSpace% w%EditBoxFourthWidths% h30 y+5 h%SecondaryButtonHeights% gOpenErrorLog, Open ErrorLog + Gui, Add, Button, x+%MarginSpace% w%EditBoxFourthWidths% h30 h%SecondaryButtonHeights% gClearVideoLinks, Clear VideoLinks + Gui, Add, Button, x+%MarginSpace% w%EditBoxFourthWidths% h30 h%SecondaryButtonHeights% gCompileScript, Compile + Gui, Add, Button, x+%MarginSpace% w%EditBoxFourthWidths% h30 h%SecondaryButtonHeights% gUploadFiles, UploadWinscp + + Gui, Add, Button, x%MarginSpace% w%EditBoxFourthWidths% h30 y+5 h%SecondaryButtonHeights% gToggleTestingMode, Toggle TestingMode + Gui, Add, Button, x+%MarginSpace% w%EditBoxFourthWidths% h30 h%SecondaryButtonHeights% gToggleDevMode, Toggle DevMode + +} + + + +; -------------------------------Page 2 Side of Main GUI Window------------------------------- +LineSplitXPosition := PageTwoXStartPos - ( MarginSpace * 2) +gui, add, text, x%LineSplitXPosition% y20 h500 0x11 ; 0x11 is a "line" ; refer to here: https://autohotkey.com/board/topic/50910-draw-line-gui/ +; Thumbnail Preview +Gui, Font, Normal +gui, Font, s4 +; Miscellaneous Settings +DevModToggleButton := PageTwoXStartPos + 160 +Gui, Add, Button, x%DevModToggleButton% y5 w50 h10 gToggleDevMode,DevMode +Gui, Add, Button, x+5 y5 w50 h10 gToggleTestingMode, Testing Mode +Gui, Add, Button, x+5 y5 w50 h10 gOpenGiteaPage, Gitea + +Gui, Font, s%GuiFontSize% +Gui, Font, Bold +Gui, Add, GroupBox,r5 y+0 x%PageTwoXStartPos% w%PageTwoGroupBoxWidth%,Settings +; Gui, Add, Text, y%CheckboxesStartYPos% x+80, Miscellaneous Settings: +; Gui, Font, Normal +; Gui, Add, Checkbox, vIncludeDescriptionWhenPostingToVideos %IncludeDescriptionWhenPostingToVideos%, Include Description in #videos Posts +Gui, Add, Checkbox, xp+10 yp+20 vReuseTabs Checked%ReuseTabsCheckStatus% gUpdateVars, Try to Re-Use Tabs +Gui, Add, Checkbox, vShowTooltipProgress Checked%ShowTooltipProgressCheckStatus% gUpdateVars,Show Tooltip Progress +Gui, Add, Checkbox, vKillLBRYAfterUpload Checked%KillLBRYAfterUploadCheckStatus% ,Kill LBRY After Uploading +Gui, Add, Checkbox, vAutoUpdateCheck gUpdateVars Checked%AutoUpdateCheckCheckStatus%, Auto Update Check +Gui, Add, Checkbox, vPingOnCompletion gUpdateVars Checked%PingOnCompletionCheckStatus%, Discord Ping Upon Finish +; Gui, Add, Checkbox, vAutoUploadErrorLog gUpdateVars Checked%AutoUploadErrorLog%, Auto-Upload Large Errors + + +GroupBoxCheckboxPos := PageTwoXStartPos + MarginSpace +Gui, Add, GroupBox,r8 y+15 x%PageTwoXStartPos% w%PageTwoGroupBoxWidth%, Platforms +; Gui, Add, Text,y+25 x%PageTwoXStartPos%, ---Platforms---- +; Gui, Font, Bold +Gui, Add, Checkbox, xp+10 yp+25 vLocals Checked%LocalsCheckStatus%, Locals +; if(VideoFileSizeInMB < 1792) +; Gui, Add, Checkbox, x+%MarginSpaceDoubled% vFacebook Checked%FacebookCheckStatus%, Facebook + +Gui, Add, Checkbox, x%GroupBoxCheckboxPos% y+%MarginSpace% vBitChute Checked%BitChuteCheckStatus%, BitChute +if(VideoFileSizeInMB < 50) +Gui, Add, Checkbox, vTelegram x+%MarginSpaceDoubled% Checked%TelegramCheckStatus%, Telegram + + +Gui, Add, Checkbox, x%GroupBoxCheckboxPos% y+%MarginSpace% vOdyseeVideo Checked%OdyseeVideoCheckStatus%, Odysee Video +; Gui, Add, Checkbox, x+%MarginSpace% vOdyseeVideoThumb Checked%OdyseeVideoThumbCheckStatus%,Thumbnail +Gui, Add, Checkbox, x%GroupBoxCheckboxPos% y+%MarginSpace% vOdyseeAudio Checked%OdyseeAudioCheckStatus%, Odysee Audio +; Gui, Add, Checkbox, x+%MarginSpace% vOdyseeAudioThumb Checked%OdyseeAudioThumbCheckStatus%, Thumbnail + +Gui, Add, Checkbox, x%GroupBoxCheckboxPos% y+%MarginSpace% vRumble Checked%RumbleCheckStatus%, Rumble + +Gui, Add, Checkbox, vBrighteon y+%MarginSpace% Checked%BrighteonCheckStatus%, Brighteon +Gui, Add, Checkbox, vDailyMotion y+%MarginSpace% Checked%DailyMotionCheckStatus%, DailyMotion +; Gui, Add, Checkbox, vStreamanity Checked%StreamanityCheckStatus%, Streamanity + +; Gui, Font, s12 +gui, Font, Bold +Gui, Add, GroupBox, r6.5 y+15 vImageThumbnail x%PageTwoXStartPos% w%PageTwoGroupBoxWidth%,Thumbnail +gui, Font, Normal +Gui, Add, Picture, xp+10 yp+20 w%ThumbnailPreviewWidth% h-1, %VideoThumbFilepath% + + +gui, Font, Normal +gui, font, s7 +Gui, Add, StatusBar,Center, Total Videos Uploaded: %TotalVideosUploaded% +; SB_SetText("There are " . RowCount . " rows selected.") + +; Show GUI to the user +Gui, +Resize +MaximizeBox +Gui, Show,, %FullScriptName% - Upload Settings - %BodyTextFilePath% +ControlFocus, Edit1, %FullScriptName% + +ToolTip + +; Gui, Maximize +; Gui, Show, w%GuiWidth% h%GuiHeight%, %ScriptName% + +if(SkipToDBInfo){ + gui, submit + goto, DisplayResults +} + + +; Write current project to ini file for easy reloading +IniWrite, %BodyTextFilePath%, %SettingsIniFilepath%, %ScriptSettingsSection%, LastPost + + + +;---Check for Update--- +;------------------------------------------------ + +if(AutoUpdateCheck AND !UpdateAvailable And !SkipUpdateCheckThisRun){ + ; msgbox, checkin for update + ; CheckForUpdates() +} + +Return + +; -------------------------------GUI GoSubs------------------------------- +; Kill the script if user clicks on cancel button +KillScript: +; GuiClose: +ExitApp +Return + +PauseScript: +Pause,Toggle +Return + +CancelPost: +GuiClose: +; ExitApp +Gui, Submit, +Return + +ReloadScript: +Reload +Return + +; Gets activated each time that text gets input into any of the text boxes +; updates the variables with the new text +UpdateVars: +Gui, Submit, NoHide +Return + +SubmitDescription: +Gui, Submit, NoHide +DescriptionCharCount := StrLen(VideoDescription) +GuiControl,, DescriptionCharCount, %DescriptionCharCount% +Return + + + +; Open folder of the project +OpenProjectFolder: +run, %VideoFolderDir% +Return + +ClearVideoLinks: +FileDelete, %VideoLinksIniFile% +Return + +OpenErrorLog: +run, %ErrorLoggingFilePath% +Return + +ToggleTestingMode: +ToggleTestingMode() +run, "%A_ScriptFullPath%" "LastPost" +Return + +ToggleDevMode: +ToggleDevMode() +run, "%A_ScriptFullPath%" "LastPost" +Return + + +OpenGiteaPage: +run, https://git.zinchuk.xyz/yuriy/Freedomain-Video-Uploader +Return + +CompileScript: +IniWrite, %changelog%, %ChangelogIniFilepath%, %ScriptSettingsSection%, Changelog +IniWrite, %ScriptVersion%, %ChangelogIniFilepath%, %ScriptSettingsSection%, ScriptVersion +IniWrite, %UpdateURL%, %ChangelogIniFilepath%, %ScriptSettingsSection%, UpdateURL + +run, "C:\Users\yuriy\Syncthing\Freedomain\Uploaders\Lib\Releases\Compile Scripts to EXE.ahk" VideoUploader Production + +; msgbox, this does nothign yet +Return + +UploadFiles: +; @todo remove this +Return + +SelectVideoFilepath: +FileSelectFile, VideoFilepath,, %FileDir%, Select Video File +GuiControl,, VideoFilepath, %VideoFilepath% +Return + +SelectWAVFilepath: +FileSelectFile, WavAudioFilepath,, %FileDir%, Select WAV File +GuiControl,, WavAudioFilepath, %WavAudioFilepath% +GuiControl,, OdyseeAudio, 1 +GuiControl,, OdyseeAudioThumb, 1 +Return + +SelectMP3Filepath: +FileSelectFile, MP3AudioFilepath,, %FileDir%, Select MP3 File +if(!InStr(MP3AudioFilepath, ".mp3")){ + msgbox, 4096, Error, Selected File is not an .mp3 file. `nPlease try again. + Return +} + +GuiControl,, MP3AudioFilepath, %MP3AudioFilepath% + +Return + +SelectVideoThumbFilepath: +FileSelectFile, VideoThumbFilepath,, %FileDir%, Select Thumbnail File + +if(!InStr(VideoThumbFilepath, FileDir)){ + ; ToolTip, Thumbnail Copied to Project Folder, 850, 0 + TimedToolTip("Thumbnail Copied to Project Folder",,,1000) + SplitPath, VideoThumbFilepath, OutFileName, OutDir, OutExtension, OutNameNoExt, OutDrive + FileCopy, %VideoThumbFilepath%, %FileDir%\*,1 + VideoThumbFilepath = %FileDir%\%OutFileName% + ; Msgbox % "VideoThumbFilepath: " VideoThumbFilepath +} + +GuiControl,, VideoThumbFilepath, %VideoThumbFilepath% +; GuiControl,, ImageThumbnail,%VideoThumbFilepath% +Return + + +; Download updates from google drive and save it to the location of the script and then reload the script +UpdateScript: +UpdateScript() + +; @todo: Save any changes made to the script before installing update +; Changelog := FindUpdateChangeLog(ScriptUpdateFilepath) +Return + +; now defunt, safe to remove +CreateDescriptionForVideosPosting: +; msgbox, here +Gui, VideoDescriptionTrimmer:New, +Gui, Font, s%GuiFontSize% +Gui, Add, Text,, Discord and Telegram have a maximum API post length of 2000 Characters `nwhich the curent description exceeds.`nPlease Trim down the description and then click submit. +Gui, Font, s%GuiFontSize% +Gui, Add, Edit, w800 h500 gUpdateVars vVideoDescriptionForVideosChannel, %VideoDescription% +Gui, Add, Button, gSubmitDescriptionForVideosChannel, Submit +gui, Show,w820, Video Description Trimmer +; msgbox +Return + + +SubmitDescriptionForVideosChannel: +Gui, Submit +; msgbox, submitted +if(CurrentSocialMediaPosting = "Discord") +Goto, SubmitDescriptionForDiscordVideosChannel +if(CurrentSocialMediaPosting = "Telegram") +Goto, SubmitDescriptionForTelegramVideosChannel +if(CurrentSocialMediaPosting = "Telegram Video") +goto, SubmitDescriptionForTelegramVideoUpload +Return + + + +CreateDescriptionForSocialMedia(){ + SplitText = Free Documentaries: + + SocialMediaDescription := StrSplit(VideoDescription, SplitText) + SocialMediaDescription := SocialMediaDescription[1] + + if(strlen(SocialMediaDescription) > 1400){ + SocialMediaDescription := SubStr(SocialMediaDescription, 1, 1400) + SocialMediaDescription .= "..." + } + + Return +} +; -------------------------------Upload Video Functionality------------------------------- +StartScript: +WinGetPos, XPosition, YPosition, , , A +; Msgbox % "XPosition: " XPosition +; Msgbox % "YPosition: " YPosition +Gui, Submit +Gui, Destroy + + + + + +;---Save Testing Mode Info--- +;------------------------------------------------ +if(TestingMode){ ; save currently seelcted sites to ini file for next test + ; IniWrite, %Streamanity%, %SettingsIniFilepath%, Testing, Streamanity + IniWrite, %BitChute%, %SettingsIniFilepath%, Testing, BitChute + IniWrite, %OdyseeVideo%, %SettingsIniFilepath%, Testing, OdyseeVideo + IniWrite, %OdyseeVideoThumb%, %SettingsIniFilepath%, Testing, OdyseeVideoThumb + IniWrite, %OdyseeAudio%, %SettingsIniFilepath%, Testing, OdyseeAudio + IniWrite, %OdyseeAudioThumb%, %SettingsIniFilepath%, Testing, OdyseeAudioThumb + IniWrite, %Rumble%, %SettingsIniFilepath%, Testing, Rumble + IniWrite, %Brighteon%, %SettingsIniFilepath%, Testing, Brighteon + IniWrite, %DailyMotion%, %SettingsIniFilepath%, Testing, DailyMotion + IniWrite, %Locals%, %SettingsIniFilepath%, Testing, Locals + IniWrite, %Telegram%, %SettingsIniFilepath%, Testing, Telegram + IniWrite, %Facebook%, %SettingsIniFilepath%, Testing, Facebook +} + + +;---\Save Testing Mode Info--- +;------------------------------------------------ + +; -------------------------------Save All Info .txt Files------------------------------- + +/*; Msgbox % "NOOriginalVideoTitle: " NOOriginalVideoTitle +if(VideoTitleEmpty){ + ; msgbox, appending title. + FileAppend, %VideoTitle%, %VideoFolderDir%\title.txt +} +if(VideoDescriptionEmpty){ + ; msgbox, appending description + FileAppend, %VideoDescription%, %VideoFolderDir%\body.txt +} +if(VideoTagsEmpty){ + ; msgbox, appending vieo tags + FileAppend, %VideoTags%, %VideoFolderDir%\keywords.txt +} +if(PodcastTagsEmpty){ + ; msgbox, appending vieo tags + FileAppend, %VideoTags%, %VideoFolderDir%\keywords.txt +} +*/ + + +; -------------------------------Save Video Info------------------------------- +; if changes made, delete the original file and save the new content to it + +if(VideoTitle != OriginalVideoTitle){ + VideoTitleFilepath = %VideoFolderDir%\title.txt + + FileDelete, %VideoTitleFilepath% + FileAppend, %VideoTitle%, %VideoTitleFilepath% +} + + +if(VideoTags != OriginalVideoTags){ + VideoTagsFilepath = %VideoFolderDir%\keywords.txt + + FileDelete, %VideoTagsFilepath% + FileAppend, %VideoTags%, %VideoTagsFilepath% +} + + +if(PodcastTags != OriginalPodcastTags){ + PodcastTagsFilepath = %VideoFolderDir%\keywords_podcast.txt + + FileDelete, %PodcastTagsFilepath% + FileAppend, %PodcastTags%, %PodcastTagsFilepath% +} + +if(VideoDescription != OriginalVideoDescription){ + VideoBodyFilepath = %VideoFolderDir%\body.txt + + FileDelete, %VideoBodyFilepath% + FileAppend, %VideoDescription%, %VideoBodyFilepath% +} + + + +; -------------------------------/Save Video Info------------------------------- + +; Save settings to config file +IniWrite, %ReuseTabs%, %SettingsIniFilepath%, General, ReuseTabs +IniWrite, %ShowTooltipProgress%, %SettingsIniFilepath%, General, ShowTooltipProgress +IniWrite, %AutoUpdateCheck%, %SettingsIniFilepath%, General, AutoUpdateCheck +IniWrite, %PingOnCompletion%, %SettingsIniFilepath%, General, PingOnCompletion +IniWrite, %KillLBRYAfterUpload%, %SettingsIniFilepath%, General, KillLBRYAfterUpload + + +if(VideoFilepath = ""){ + Msgbox,4096,Error,No Video Filepath Found.`nPlease Input Video Filepath to Upload a Video. + run, "%A_ScriptFullPath%" "LastPost" + ExitApp +} + +; -------------------------------/Save All Info .txt Files------------------------------- + +; Format the LBRYURLSlug to be API Compatible +if(LBRYURLSlug = "") ; if slug spot is blank, then set it to video title +LBRYURLSlug := VideoTitle +LBRYURLSlug := LBRYCMDTextReplacement(LBRYURLSlug) + +; Msgbox % "LBRYURLSlug: " LBRYURLSlug +; Save the LBRY URL Slug to .ini file in case it's needed later +IniWrite, %LBRYURLSlug%, %VideoLinksIniFile%, Misc, LBRYUrlSlug +IniWrite, %VideoThumbFilepath%, %VideoLinksIniFile%, Misc, VideoThumbFilepath +IniWrite, %PodcastNumber%, %VideoLinksIniFile%, Misc, PodcastNumber + + + +; -------------------------------Log Info To Text------------------------------- + +(Facebook = 1)?(PostedWebsites .= "Facebook|") : () +(Bitchute = 1)?(PostedWebsites .= "Bitchute|") : () +(Locals = 1)?(PostedWebsites .= "Locals|") : () +(Rumble = 1)?(PostedWebsites .= "Rumble|") : () +(Brighteon = 1)?(PostedWebsites .= "Brighteon|") : () +; (Streamanity = 1)?(PostedWebsites .= "Streamanity|") : () +(Telegram = 1)?(PostedWebsites .= "Telegram|") : () +(DailyMotion = 1)?(PostedWebsites .= "DailyMotion|") : () +(OdyseeVideo = 1)?(PostedWebsites .= "OdyseeVideo|") : () +(OdyseeAudio = 1)?(PostedWebsites .= "OdyseeAudio|") : () + + +; Log Basic info to the errorlogging file +Message = Starting Upload For: **%VideoTitle%**`nTo: %PostedWebsites%`nWith %ScriptVersion% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + +Message := "VideoTitle: " VideoTitle +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +Message := "VideoDescription: `n" VideoDescription +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +Message := "VideoTags: " VideoTags +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +Message := "VideoFilepath: " VideoFilepath +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +Message := "VideoThumbFilepath: " VideoThumbFilepath +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +Message := "TotalVideosUploaded: " TotalVideosUploaded +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +; Convert Video Description into javascript text format for sending to selenium +JSVideoDescription := FormatTextToJSText(VideoDescription) +JSVideoTitle := FormatTextToJSText(VideoTitle) + +; Save json description to errorlogging file +; Message = JSVideoDescription: `n" %JSVideoDescription% +; SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") +; -------------------------------/Log Info To Text------------------------------- + + + + +; Create an array out of the keywords to be used in different places +VideoTags := StrReplace(VideoTags, ", ",",") +VideoTags := StrReplace(VideoTags, " ,",",") + +KeywordsArray := StrSplit(VideoTags,",") + +; if(Streamanity){ + ; UploadedToSites .= "Streamanity," + ; Gosub, StreamanityUpload + ; } + + if(Facebook){ + UploadedToSites .= "Facebook," + gosub, FacebookUpload + } + + if(Telegram){ + UploadedToSites .= "Telegram," + gosub, TelegramVideoUpload + } + + ; Call each sub one by one, if errors occur then an upload will be stopped and the next upload will then proceed + if(Locals){ + UploadedToSites .= "Locals," + gosub, LocalsUpload + + } + + if(BitChute){ + UploadedToSites .= "Bitchute," + Gosub, BitChuteUpload + } + + + if(OdyseeVideo){ + UploadedToSites .= "LBRYVideo," + LBRYUploadType := "Video" + Gosub, LBRYVideoUpload + } + if(OdyseeAudio){ + UploadedToSites .= "LBRYAudio," + LBRYUploadType := "Audio" + Gosub, LBRYAudioUpload + } + + if(Rumble){ + UploadedToSites .= "Rumble," + Gosub, RumbleUpload + } + + if(Brighteon){ + UploadedToSites .= "Brighteon," + Gosub, BrighteonUpload + } + + if(DailyMotion){ + UploadedToSites .= "DailyMotion," + Gosub, DailyMotionUpload + + } + + ; grab the LBRY Video/Audio URLs + if(OdyseeVideo){ + LBRYUploadType := "Video" + Gosub, LBRYGetURL + } + if(OdyseeAudio){ + LBRYUploadType := "Audio" + Gosub, LBRYGetURL + } + + if(OdyseeVideoThumb){ + OdyseeUploadType := "Video" + Gosub, OdyseeVideoThumbUpload + } + + if(OdyseeAudioThumb){ + OdyseeUploadType := "Audio" + Gosub, OdyseeAudioThumbUpload + } + + + if(URLOfLastErrorPage != ""){ + Message = Activating Tab of last failed post. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + + FindAndActivateTab(URLOfLastErrorPage) + } + + CurrentSite := "" + + ; if(StreamanityURL AND StreamanityCheckStatus) + + ; this feels soooooooooooooo ineficient, but i'm not sure how else to do this + ; if(StreamanityCheckStatus AND !InStr(StreamanityURL, "streamanity")) ; if checked and URL is blank, report error + ; Status := "Failures" + if(OdyseeVideoCheckStatus and !InStr(OdyseeVideoURL, "odysee")) + Status := "Failures" + else if(OdyseeAudioCheckStatus AND !InStr(OdyseeAudioURL, "odysee")) + Status := "Failures" + else if(BitChuteCheckStatus AND !InStr(BitChuteURL, "bitchute")) + Status := "Failures" + else if(RumbleCheckStatus AND !InStr(RumbleURL, "rumble")) + Status := "Failures" + else if(DailyMotionCheckStatus AND !InStr(DailyMotionURL, "dailymotion")) + Status := "Failures" + else if(BrighteonCheckStatus AND !InStr(BrighteonURL, "brighteon")) + Status := "Failures" + else, + Status := "Success" + + ; DevModeMsgBox(status) + ; Msgbox % "status: " status + + if(Status = "Failures") + Message = Video Uploading Finished WITH Some Failures + else, + Message = All Videos Uploaded Successfully + +/* +if(StreamanityURL != "" AND OdyseeVideoURL != "" AND OdyseeAudioURL != "" and BitChuteURL != "" AND RumbleURL != "" and DailyMotionURL != "" and BrighteonURL != "") +Message = All Videos Uploaded Successfully +else, +Message = Video Uploading Finished WITH Some Failures + +*/ + + +if(PingOnCompletion) +Message = <@%DiscordUsernameID%>: %Message% +else, +Message = %Message% + +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + +DisplayResults: +Gui, Destroy +; @todo: Add a way to check if uploads finished with or without errors +Tooltip ; Remove all tooltips +IniRead, TotalVideosUploaded, %SettingsIniFilepath%, General, TotalVideosUploaded, %A_Space% +; IniRead, StreamanityURL, %VideoLinksIniFile%, URLs, StreamanityURL, %A_Space% +IniRead, BitChuteURL, %VideoLinksIniFile%, URLs, BitChuteURL, %A_Space% + +IniRead, OdyseeVideoURL, %VideoLinksIniFile%, URLs, OdyseeVideoURL, %A_Space% +IniRead, OdyseeVideoThumb, %VideoLinksIniFile%, Misc, OdyseeVideoThumb, %A_Space% +OdyseeVideoThumb := StrReplace(OdyseeVideoThumb, "Thumb:", "") + + +IniRead, OdyseeAudioURL, %VideoLinksIniFile%, URLs, OdyseeAudioURL, %A_Space% +IniRead, OdyseeAudioThumb, %VideoLinksIniFile%, Misc, OdyseeAudioThumb, %A_Space% +OdyseeAudioThumb := StrReplace(OdyseeAudioThumb, "Thumb:", "") + + +IniRead, LocalsURL, %VideoLinksIniFile%, URLs, LocalsURL, %A_Space% +IniRead, RumbleURL, %VideoLinksIniFile%, URLs, RumbleURL, %A_Space% +IniRead, FacebookURL, %VideoLinksIniFile%, URLs, FacebookURL, %A_Space% +IniRead, BrighteonURL, %VideoLinksIniFile%, URLs, BrighteonURL, %A_Space% +IniRead, DailyMotionURL, %VideoLinksIniFile%, URLs, DailyMotionURL, %A_Space% +IniRead, PodcastNumber, %VideoLinksIniFile%, Misc, PodcastNumber, %A_Space% +if(PodcastNumber = "") { + SplitPath, VideoFilepath,,,, VideoNameNoExt + ; Remove the FDR_#### from video title for LBRY URL + if(InStr(VideoNameNoExt, "FDR_")){ + FoundPos := InStr(VideoNameNoExt, "_",,,2) ; get position of second instance of an "_" + if(FoundPos < 11){ + ; FoundPos += 1 + ; Msgbox % "FoundPos: " FoundPos + PodcastNumber := SubStr(VideoNameNoExt,1, FoundPos) + PodcastNumber := StrReplace(PodcastNumber, "FDR", "") + PodcastNumber := StrReplace(PodcastNumber, "_", "") + ; Msgbox % "PodcastNumber: " PodcastNumber + } + } +} + +ButtonHeights := 30 + +Gui, Font, s%GuiFontSize% +Gui, Font, Bold +; Gui, Add, Text,x10 y+10, Podcast #: +Gui, Add, Button, x10 y+%Marginspace% h%ButtonHeights% w%CopyButtonWidths% gCopyPodcastNumber, Podcast # +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% w%ResultEditBoxWidths% gUpdateVars vPodcastNumber, %PodcastNumber% +; Gui, Add, Edit, x+5 h200 w200, This is some text that goes here! + +; Gui, Add, Text,x10 y+20, Title: +; Gui, Font, Bold +; Gui, Add, Button, x10 y+%Marginspace% h%ButtonHeights% w%CopyButtonWidths% gCopyVideoTitle, Title +; Gui, Font, Normal +; Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% w%ResultEditBoxWidths% gUpdateVars vVideoTitle, %VideoTitle% +; Gui, Add, Button, x+1 w20, Copy Title + + +; Gui, Add, Text,x10 y+20, Bitchute: +Gui, Font, Bold +Gui, Add, Button, x10 y+%Marginspace% h%ButtonHeights% w%CopyButtonWidths% gCopyBitChuteURL, Bitchute +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vBitChuteURL w%ResultLBRYURLEditBoxWidths% gUpdateVars , %BitChuteURL% +Gui, Add, Edit, x+5 yp+0 w%ResultLBRYThumbEditBoxWidth% gUpdateVars, Facebook: %FacebookURL% + +; Gui, Add, Button, x+1 w20, Copy BitChute + +; Gui, Add, Text,x10 y+20, Brighteon: +Gui, Font, Bold +Gui, Add, Button, x10 y+%Marginspace% h%ButtonHeights% w%CopyButtonWidths% gCopyBrighteonURL, Brighteon +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vBrighteonURL w%ResultEditBoxWidths% gUpdateVars , %BrighteonURL% + +; Gui, Add, Text,x10 y+20, DailyMotion: +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyDailyMotionURL, DailyMotion +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vDailyMotionURL w%ResultEditBoxWidths% gUpdateVars , %DailyMotionURL% + +; Gui, Add, Text,x10 y+20, Odysee: +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyOdyseeVideoURL, Odysee Video +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vOdyseeVideoURL w%ResultLBRYURLEditBoxWidths% gUpdateVars, %OdyseeVideoURL% +; Gui, Add, Button, x+5 yp+0, Thumb +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vOdyseeVideoThumb w%ResultLBRYThumbEditBoxWidth% gUpdateVars, Thumb: %OdyseeVideoThumb% + +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyOdyseeAudioURL, Odysee Audio +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vOdyseeAudioURL w%ResultLBRYURLEditBoxWidths% gUpdateVars , %OdyseeAudioURL% +; Gui, Add, Button, x+5 yp+0, Thumb +Gui, Add, Edit, x+5 yp+0 vOdyseeAudioThumb w%ResultLBRYThumbEditBoxWidth% gUpdateVars, Thumb: %OdyseeAudioThumb% + +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyRumbleURL, Rumble +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vRumbleURL w%ResultEditBoxWidths% gUpdateVars , %RumbleURL% + +/*Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyStreamanityURL, Streamanity +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vStreamanityURL w%ResultEditBoxWidths% gUpdateVars , %StreamanityURL% + +*/ +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths%, Locals +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vLocalsURL w%ResultEditBoxWidths% gUpdateVars, %LocalsURL% + +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyVideoTags, Video Tags +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vVideoTags w%ResultEditBoxWidths% gUpdateVars , %VideoTags% + +Gui, Font, Bold +Gui, Add, Button, x10 y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyPodcastTags, Podcast Tags +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h%ButtonHeights% vPodcasttags w%ResultEditBoxWidths% gUpdateVars , %Podcasttags% + +Gui, Font, Bold +Gui, Add, Button, x%Marginspace% y+10 h%ButtonHeights% w%CopyButtonWidths% gCopyVideoDescription, Description +Gui, Font, Normal +Gui, Add, Edit, x+5 yp+0 h50 vVideoDescription w%ResultEditBoxWidths% gUpdateVars , %VideoDescription% + +Gui, Font, s%GuiFontSize% +Gui, Font, Bold +Gui, Add, Button, y+%MarginSpace% w%ResultEditBoxHalfWidths%gSendErrorLoggingThroughTelegram, Send Errorlog Through Telegram +Gui, Add, Button, x+%MarginSpace% w%ResultEditBoxHalfWidths% gRetryUpload, Try Failed Again + +Gui, Add, Button, x%ResultEditBoxXPos% w%ResultEditBoxHalfWidths% gUpdateINI, Update Project Files with Changes +Gui, Add, Button, x+%MarginSpace% w%ResultEditBoxHalfWidths% gUploadPodcast, Upload Podcast + + +Gui, Add, Button, x%ResultEditBoxXPos% y+%MarginSpace% w%ResultEditBoxThirdsWidths% gPostToDiscord vPostToDiscordButton, Post to Discord +Gui, Add, Button, x+5 w%ResultEditBoxThirdsWidths% gPostToTelegram vPostToTelegramButton, Post to Telegram +Gui, Add, Button, x+5 w%ResultEditBoxThirdsWidths% gStartSocialMediaPoster, Start Social Media Poster + + +Gui, Add, Button, x%ResultEditBoxXPos% w%ResultEditBoxHalfWidths% gOpenLBRYBlobFilesFolder %ButtonWidths% , Open LBRY Blob Files Folder +Gui, Add, Button, x+%MarginSpace% w%ResultEditBoxHalfWidths% gCancelPost %ButtonWidths% , Close +; Gui, Add, Button, x+%MarginSpace% w%ResultEditBoxHalfWidths% gKillScript %ButtonWidths% , Close +; gui, Add, Text, y+10 + +Gui, Font, s%GuiFontSize% +Gui, Add, Edit,x%ErrorLogEditBoxXPos% y%MarginSpace% h%ErrorLogEditBoxHeight% w%ErrorLogEditBoxWidth%, %ErrorLogVar% + +gui, font, Normal +gui, font, s7 +Gui, Add, StatusBar,, Total Videos Uploaded: %TotalVideosUploaded% +Gui, +Resize +MaximizeBox + +OriginalVideoDescription := VideoDescription +OriginalPodcastTags := PodcastTags + +Gui, Show,,%FullScriptName% - Upload Results + +SaveCurrentChromeVersionToIniFile() + +Return + +OpenLBRYBlobFilesFolder: +run, C:\Users\%A_UserName%\AppData\Local\lbry\lbrynet\blobfiles +Return + +StartSocialMediaPoster: +; IniRead, SocialMediaPosterFilepath, %SettingsIniFilepath%, General, FDRRadioUN, %A_Space% +IniRead, SocialMediaPosterFilepath, %SettingsIniFilepath%, SocialMediaPoster, SocialMediaPosterFilepath, %A_Space% + +if(SocialMediaPosterFilepath = "" or !FileExist(SocialMediaPosterFilepath)){ + OnMessage(0x44, "OnMsgBoxSocialMediaPoster") + MsgBox 0x21, No Filepath Found, Unable to find filepath for Social Media Poster`nWould you like to add it? + OnMessage(0x44, "") + + IfMsgBox OK, { + FileSelectFile, SocialMediaPosterFilepath,,, Please Select Social Media Poster + if(ErrorLevel) + Return + + ; Msgbox % "SocialMediaPosterFilepath: " SocialMediaPosterFilepath + ; if(!InStr(SocialMediaPosterFilepath, ".ahk") OR !InStr(SocialMediaPosterFilepath, ".exe")) + ; Return + + } Else IfMsgBox Cancel, { + Return + } + + ; IniRead, SocialMediaPosterFilepath, %SettingsIniFilepath%, SocialMediaPoster, SocialMediaPosterFilepath, %A_Space% + IniWrite, SocialMediaPosterFilepath, %SettingsIniFilepath%, SocialMediaPoster, SocialMediaPosterFilepath + ; Return + + } + ; msgbox %SocialMediaPosterFilepath% + run, %SocialMediaPosterFilepath% "%VideoLinksIniFile%" + Return + ; Podcast Upload + ;------------------------------------------------ + + UploadPodcast: + CurrentSite := "Podcast" + PodcastTags := StrReplace(PodcastTags, " ,", ",") + PodcastTags := StrReplace(PodcastTags, ", ", ",") + PodcastTags := StrReplace(PodcastTags, " ", "-") + PodcastTags := StrReplace(PodcastTags, "--", "-") + PodcastTags := StrReplace(PodcastTags, "--", "-") + ; Msgbox % "PodcastTags: " PodcastTags + + + + IniRead, FDRRadioURL, %SettingsIniFilepath%, General, FDRRadioURL, %A_Space% + if(FDRRadioURL = ""){ + Message = FDRRadioURL is blank.`nPlease add URL to Settings.ini file under:`n`n[General]`nFDRRadioURL= + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + MsgBox 0x10,, %Message% + Return + } + + IniRead, Username, %SettingsIniFilepath%, General, FDRRadioUN, %A_Space% + IniRead, Password, %SettingsIniFilepath%, General, FDRRadioPW, %A_Space% + + if(Username = "" or Password = ""){ + Message = Username and/or Password are blank.`nPlease add Login to Settings.ini file under:`n`n[General]`nFDRRadioUN=`nFDRRadioPW= + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + + + if(MP3AudioFilepath = ""){ + MsgBox 0x33, Unable to Upload Podcast, No MP3 File Was Found/Selected. `nWould you like to select one now? + + IfMsgBox Yes, { + FileSelectFile, MP3AudioFilepath,, %RootDirToStartIn%, Please Select MP3 File + if(ErrorLevel) + Return + } Else IfMsgBox No, { + Return + } Else IfMsgBox Cancel, { + Return + } + } + + if(!InStr(MP3AudioFilepath, ".mp3")){ + + Message = Unable to upload podcast, no mp3 file was selected. + MsgBox 0x40, Error, %Message% + Return + } + + + Message = Grabbing MP3 file data + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + ; https://www.autohotkey.com/boards/viewtopic.php?t=59882 + Message = Calculating MP3 File Size and Length + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Obj := Filexpro(MP3AudioFilepath,, + , "Length" + , "Size" ) + MP3AudioFilesize := obj["Size"] + MP3AudioLength := obj["Length"] + ; MsgBox % obj["Size"] + + AudioLengthArray := StrSplit(MP3AudioLength,":") + AudioLength_Hours := AudioLengthArray[1] + AudioLength_Minutes := AudioLengthArray[2] + AudioLength_Seconds := AudioLengthArray[3] + ; AudioLength_SecondsOriginal := AudioLength_Seconds + ; AudioLength_Seconds := (AudioLength_Minutes * 60) + ((AudioLength_Hours * 60) * 60) + AudioLength_Seconds + + ; Msgbox % "AudioLength_Hours: " AudioLength_Hours + ; Msgbox % "AudioLength_Minutes: " AudioLength_Minutes + ; Msgbox % "AudioLength_Seconds: " AudioLength_Seconds + ; Msgbox % "AudioLength_SecondsOriginal: " AudioLength_SecondsOriginal + + FileGetSize, OutputVar, %MP3AudioFilepath%, K ; Retrieve the size in Kbytes. + FIlesizeInBytes := OutputVar * 1024 + + + Message = Uploading Podcast Information + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + + + Status := NavigateFromBaseURLTo(FDRRadioURL) + if(Status){ + Message = Upload Failed (E#7295)`nUnable to Navigate to Upload Page`nChrome was closed or Internet down possibly? + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + Message = Logging in + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Xpath = //input[@id='email'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=Username) + if(!Status){ ; if inputting email did NOT fail, then we are on the login page, input the password and then click login. + Xpath = //input[@id='password'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=Password) + + Xpath = //a[@id='loginButton'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + + driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + sleep, 2000 + + try driver.Get(FDRRadioURL) ;Open selected URL + catch e { + Message = Upload Failed (E#7295)`nUnable to Navigate to Upload Page`nChrome was closed or Internet down possibly? + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + } + } + + + + Message = Waiting for Page to Load + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Xpath = //input[@id='num'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=60,SleepLength:=1000) + if(Status){ + Message = New Podcast Page did not load after 60 seconds. Check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Return + } + + Message = Inputting Podcast Info + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + ; Click the "Is Active?" Checkbox + Xpath = //input[@id='isActive'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + + ; Input Podcast Number + Xpath = //input[@id='num'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=PodcastNumber) + + ; Input Podcast Title + Xpath = //input[@id='title'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoTitle) + + ; INput Audio URL + Xpath = //input[@id='url-audio'] + SplitPath, MP3AudioFilepath, MP3AudioNameWithExt + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=MP3AudioNameWithExt) + + ; INput thumbnail URL + Xpath = //input[@id='url-thumbnail'] + SplitPath, VideoThumbFilepath, VideoThumbnailFilenameWithExt + ThumbnailURL = https://cdn.freedomainradio.com/%VideoThumbnailFilenameWithExt% + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=ThumbnailURL) + + ; Input BitChute URL + Xpath = //input[@id='url-bitchute'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=BitChuteURL) + + ; Input Brighteon URL + Xpath = //input[@id='url-brighteon'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=BrighteonURL) + + ; Input DailyMotion URL + Xpath = //input[@id='url-dailymotion'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=DailyMotionURL) + + ; Input LBRY URL + Xpath = //input[@id='url-lbry'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=OdyseeVideoURL) + + ; Input LBRY URL + Xpath = //input[@id='url-locals'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=LocalsURL) + + ; Input Rumble URL + Xpath = //input[@id='url-rumble'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=RumbleURL) + + + ; Soundcloud but actually LBRY Audio URL + Xpath = //input[@id='url-lbry-audio'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=OdyseeAudioURL) + + + ; INput filesize + Xpath = //input[@id='fileSize'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=FIlesizeInBytes) + + ; Msgbox % "FIlesizeInBytes2: " FIlesiz + + ; ToolTip + + + Xpath = //input[@id='lengthHours'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=AudioLength_Hours) + + Xpath = //input[@id='lengthMinutes'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=AudioLength_Minutes) + + Xpath = //input[@id='lengthSeconds'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=AudioLength_Seconds) + + Message = Inputting Description + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Xpath = //textarea[@id='description'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + + ; Input Description + JSVideoDescription := FormatTextToJSText(VideoDescription) + + js = document.getElementById('description').value = "%JSVideoDescription%"; + try driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + + + Message = Inputting Tags + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Podcasttags := StrReplace(Podcasttags, " , ", ",") + Podcasttags := StrReplace(Podcasttags, " ,", ",") + Podcasttags := StrReplace(Podcasttags, ", ", ",") + + ArrayOfPodcastTags := StrSplit(Podcasttags,",") + LengthOfArrayOfPodcastTags := ArrayOfPodcastTags.Length() ; Save total number of items in the array + + try pagehtml := driver.pagesource + ; Msgbox % "pagehtml: " pagehtml + Loop, %LengthOfArrayOfPodcastTags% { + Tag := ArrayOfPodcastTags[A_Index] ; find value from position in array + + SpanID = title">%Tag%
  • 2000 AND VideoDescriptionForVideosChannel = ""){ + goto, CreateDescriptionForVideosPosting +} +*/ +/* +if(SocialMediaDescription = ""){ + CreateDescriptionForSocialMedia() +} +if(SocialMediaDescription > 1000){ ; Telegram has a 1024 char media caption capacity + SocialMediaDescription := SubStr(SocialMediaDescription, 1, 500) +} +*/ +; @todo: split telegram message into multiple posts + + +SubmitDescriptionForTelegramVideosChannel: +TelegramVideoTitle := ASCIISTRReplace(VideoTitle) +TelegramVideoTitle := "*" . TelegramVideoTitle . "*" + +TelegramBodymessage := ASCIISTRReplace(VideoDescription) + + +LineBreakChar = `%0A ; Used for API + +if(BitChuteURL != "") +VideoLinks .= "[BitChute](" . BitChuteURL . ") \| " + +if(BrighteonURL != "") +VideoLinks .= "[Brighteon](" . BrighteonURL . ") \| " + +if(OdyseeVideoURL != "") +VideoLinks .= "[Odysee](" . OdyseeVideoURL . ") \| " + +if(OdyseeAudioURL != "") +VideoLinks .= "[Odysee \(Audio\)](" . OdyseeAudioURL . ") \| " +/* +if(OdyseeVideoURL != "") +VideoLinks .= "[Odysee](" . OdyseeVideoURL . ") \| " + +if(OdyseeAudioURL != "") +VideoLinks .= "[Odysee Audio](" . OdyseeAudioURL . ") \| " + +*/ +if(RumbleURL != "") +VideoLinks .= "[Rumble](" . RumbleURL . ") \| " +/* +if(InStr(StreamanityURL, "https://streamanity.com/video/")) +VideoLinks .= "[Streamanity](" . StreamanityURL . ") \| " + +*/ +if(DailyMotionURL != "") +VideoLinks .= "[DailyMotion](" . DailyMotionURL . ") \| " + + +TelegramMessage := TelegramVideoTitle . "`n" . TelegramBodymessage . "`n" . VideoLinks + + + +StrLenOfMessageAndVideoLinks := StrLen(TelegramVideoTitle) + StrLen(TelegramBodymessage) + StrLen(VideoLinks) +; DevModeMsgBox(StrLenOfMessageAndVideoLinks) + + +if(StrLenOfMessageAndVideoLinks > 1024){ + ; Telegram SendMessage is limited to 4096 characters + if(StrLenOfMessageAndVideoLinks < 4096){ ; split into sendphoto and 1 sendmessage + ; DevModeMsgBox("Less than 4096 chars") + ; Photo and Video Title go into SendPhoto + TelegramVideoTitle := TelegramVideoTitle . "`n" . VideoLinks + Status := SendTelegramPhoto(TelegramBotToken, TelegramBotChatID, VideoThumbFilepath, caption := TelegramVideoTitle ) ; you could add more options; compare the Telegram API docs + + ; Video Description goes into TelegramMessage + Status2 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessage) + + } ; split into 2 SendMessages + else if (StrLenOfMessageAndVideoLinks > 4096 AND StrLenOfMessageAndVideoLinks < 8192){ ; Split into 2 parts + TelegramVideoTitle := TelegramVideoTitle . "`n" . VideoLinks + Status := SendTelegramPhoto(TelegramBotToken, TelegramBotChatID, VideoThumbFilepath, caption := TelegramVideoTitle ) ; you could add more options; compare the Telegram API docs + + TelegramBodymessagePiece := SubStr(TelegramBodymessage, 1, 4096) + Status2 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessagePiece) + + TelegramBodymessagePiece := SubStr(TelegramBodymessage, 4097, 8192) + Status3 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessagePiece) + + } ; split into 3 sendMessages + else if (StrLenOfMessageAndVideoLinks > 8192 AND StrLenOfMessageAndVideoLinks < 12288){ ; Split into 3 parts + TelegramVideoTitle := TelegramVideoTitle . "`n" . VideoLinks + Status := SendTelegramPhoto(TelegramBotToken, TelegramBotChatID, VideoThumbFilepath, caption := TelegramVideoTitle ) ; you could add more options; compare the Telegram API docs + + TelegramBodymessagePiece := SubStr(TelegramBodymessage, 1, 4096) + msgbox % StrLen(TelegramBodymessagePiece) + Status2 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessagePiece) + + + + TelegramBodymessagePiece := SubStr(TelegramBodymessage, 4097, 8192) + msgbox % StrLen(TelegramBodymessagePiece) + DevModeMsgBox(TelegramBodymessagePiece) + Status3 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessagePiece) + + ; TelegramBodymessagePiece := SubStr(TelegramBodymessage, 8193, 12288) + ; Status3 := SendTelegramMessage(TelegramBotToken, TelegramBotChatID, text := TelegramBodymessagePiece) + } + + + } else, { ; if less than 1024 characters, send normally + Status := SendTelegramPhoto(TelegramBotToken, TelegramBotChatID, VideoThumbFilepath, caption := TelegramMessage ) ; you could add more options; compare the Telegram API docs + if(InStr(Status, "error_code")){ + Message = Telegram Post Failed due to an API Issue. Error was saved to ErrorLogging file. Please send it to Yuriy. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ; SaveOrPostProgress(Message:=Status,PostType:=",ErrorLoggingTextFile") + Message = Telegram Error: %Status% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ToolTip + Return + } + + } + ; Msgbox % "SizeOfCaption: " SizeOfCaption + ; SizeOfCaption := SizeOfCaption + + ; Message .= VideoLinks + ; msgbox % StrLen(VideoLinks) + + ; Message := StrReplace(Message, "`n", LineBreakChar) ; replace all new line characters with the global charater + + ; msgbox % StrLen(Message) + + + ; SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordVideos") + + ; SaveOrPostProgress(Message:="Video Links posted to #Videos Successfully.",PostType:="Tooltip,ErrorLoggingTextFile") + Message = Video Links Posted to Telegram Successfully + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + GuiControl,, PostToTelegramButton, Telegram - Posted Successfully + + + ; sleep, 2000 + + + ToolTip + CurrentSite := + Return + ; -------------------------------/Telegram------------------------------- + + + + ; -------------------------------Discord------------------------------- + PostToDiscord: + CurrentSocialMediaPosting := "Discord" + Message = Posting Video Links to Discord + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + IniRead, DiscordVideosWebhookURL, %SettingsIniFilepath%, General, DiscordVideosWebhookURL, %A_Space% + if(DiscordVideosWebhookURL = ""){ + Message = Unable to Grab DiscordVideosWebhookURL from %SettingsIniFilepath%.`nPlease input the URL and then try again. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Msgbox, Unable to Grab DiscordVideosWebhookURL from %SettingsIniFilepath%.`nPlease input the URL and then try again. + Return + } + +/* +; If description is longer than 2k chars, then API will error out. goto section that will allow user to edit video description to shorten it for posting +if(StrLen(SocialMediaDescription) > 2000 AND VideoDescriptionForVideosChannel = ""){ + Goto, CreateDescriptionForVideosPosting +} + +*/ +if(SocialMediaDescription = ""){ + CreateDescriptionForSocialMedia() +} + +; Msgbox % "SocialMediaDescription: " SocialMediaDescription + +SubmitDescriptionForDiscordVideosChannel: +Message := "**" . VideoTitle . "**" . "`n" . SocialMediaDescription . "`n" +; https://stackoverflow.com/questions/63160401/how-to-create-hyperlink-in-discord-in-an-embed-in-general +; Do this with an array!! +; + +if(BitChuteURL != "") +Message .= "[BitChute](<" . BitChuteURL . ">) \| " + +if(BrighteonURL != "") +Message .= "[Brighteon](<" . BrighteonURL . ">) \| " + +if(OdyseeVideoURL != "") +Message .= "[Odysee](<" . OdyseeVideoURL . ">) \| " + +if(OdyseeAudioURL != "") +Message .= "[Odysee (Audio)](<" . OdyseeAudioURL . ">) \| " +/* +if(OdyseeVideoURL != "") +Message .= "[Odysee](<" . OdyseeVideoURL . ") \| " + +if(OdyseeAudioURL != "") +Message .= "[Odysee Audio](<" . OdyseeAudioURL . ") \| " + +*/ +if(RumbleURL != "") +Message .= "[Rumble](<" . RumbleURL . ">) \| " + +/*if(StreamanityURL != "" AND InStr(StreamanityURL, "streamanity.com")) +Message .= "[Streamanity](<" . StreamanityURL . ">) \| " + +*/ +if(DailyMotionURL != "") +Message .= "[DailyMotion](<" . DailyMotionURL . ">)" + + +UploadImageToDiscord(DiscordVideosWebhookURL, Message, VideoThumbFilepath) + + + +SaveOrPostProgress(Message:="Video Links posted to #Videos Successfully.",PostType:="Tooltip,ErrorLoggingTextFile") +GuiControl,, PostToDiscordButton, Discord - Posted Successfully + +sleep, 2000 +ToolTip +; Msgbox,,Success,Video Links posted to #Videos Successfully. +; ToolTip +Return +; -------------------------------/Discord------------------------------- + + + + + +; -------------------------------CopyThis------------------------------- +CopyPodcastNumber: +Clipboard := PodcastNumber +SaveOrPostProgress(Message:=PodcastNumber "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + + +CopyVideoTitle: +Clipboard := VideoTitle +SaveOrPostProgress(Message:=VideoTitle "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyBitChuteURL: +Clipboard := BitChuteURL +SaveOrPostProgress(Message:=BitChuteURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyBrighteonURL: +Clipboard := BrighteonURL +SaveOrPostProgress(Message:=BrighteonURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyDailyMotionURL: +Clipboard := DailyMotionURL +SaveOrPostProgress(Message:=DailyMotionURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyOdyseeVideoURL: +Clipboard := OdyseeVideoURL +SaveOrPostProgress(Message:=OdyseeVideoURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyOdyseeAudioURL: +Clipboard := OdyseeAudioURL +SaveOrPostProgress(Message:=OdyseeAudioURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyRumbleURL: +Clipboard := RumbleURL +SaveOrPostProgress(Message:=RumbleURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +/*CopyStreamanityURL: +Clipboard := StreamanityURL +SaveOrPostProgress(Message:=StreamanityURL "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +*/ +CopyVideoTags: +Clipboard := VideoTags +SaveOrPostProgress(Message:=VideoTags "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyPodcastTags: +Clipboard := PodcastTags +SaveOrPostProgress(Message:=PodcastTags "`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +CopyVideoDescription: +Clipboard := VideoDescription +SaveOrPostProgress(Message:="Video Description`nCopied to Clipboard",PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 1000 +ToolTip +Return + +; @todo: Add thumbnail status to this +; @todo: add podcast tags to this +UpdateINI: +IniWrite, %PodcastNumber%, %VideoLinksIniFile%, URLs, PodcastNumber +IniWrite, %VideoTitle%, %VideoLinksIniFile%, Misc, VideoTitle + +IniWrite, %LBRYVideoURL%, %VideoLinksIniFile%, URLs, LBRYVideoURL +IniWrite, %LBRYAudioURL%, %VideoLinksIniFile%, URLs, LBRYAudioURL + +IniWrite, %OdyseeVideoURL%, %VideoLinksIniFile%, URLs, OdyseeVideoURL + +OdyseeVideoThumb := StrReplace(OdyseeVideoThumb, "Thumb:", "") +IniWrite, %OdyseeVideoThumb%, %VideoLinksIniFile%, Misc, OdyseeVideoThumb + +IniWrite, %OdyseeAudioURL%, %VideoLinksIniFile%, URLs, OdyseeAudioURL +OdyseeAudioThumb := StrReplace(OdyseeAudioThumb, "Thumb:", "") +IniWrite, %OdyseeAudioThumb%, %VideoLinksIniFile%, Misc, OdyseeAudioThumb + +IniWrite, %LocalsURL%, %VideoLinksIniFile%, URLs, LocalsURL + +IniWrite, %RumbleURL%, %VideoLinksIniFile%, URLs, RumbleURL +; IniWrite, %StreamanityURL%, %VideoLinksIniFile%, URLs, StreamanityURL +IniWrite, %DailyMotionURL%, %VideoLinksIniFile%, URLs, DailyMotionURL +IniWrite, %BrighteonURL%, %VideoLinksIniFile%, URLs, BrighteonURL +IniWrite, %BitChuteURL%, %VideoLinksIniFile%, URLs, BitChuteURL + + + +if(VideoDescription != OriginalVideoDescription){ + VideoBodyFilepath = %VideoFolderDir%\body.txt + + FileDelete, %VideoBodyFilepath% + FileAppend, %VideoDescription%, %VideoBodyFilepath% +} + + +if(PodcastTags != OriginalPodcastTags){ + PodcastTagsFilepath = %VideoFolderDir%\keywords_podcast.txt + + FileDelete, %PodcastTagsFilepath% + FileAppend, %PodcastTags%, %PodcastTagsFilepath% +} + +msgbox,4096, Updated!, VideoLinks.ini file updated with any edits that you've made.`n`n%VideoLinksIniFile% + +Return + + +RetryUpload: +run, "%A_ScriptFullPath%" "LastPost" +ExitApp + +ReloadToResults: +run, "%A_ScriptFullPath%" "ShowResults" +ExitApp + + + +SendErrorLoggingThroughTelegram: +Message = Uploading Errorlog to FDRBotTesting Telegram Server. +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + +; Credentials to FDRBotTesting Channel +IniRead, TelegramErrorLogBotToken, %SettingsIniFilepath%, General, TelegramErrorLogBotToken, %A_Space% +IniRead, TelegramErrorLogBotChatID, %SettingsIniFilepath%, General, TelegramErrorLogBotChatID, %A_Space% + + +if(TelegramErrorLogBotToken = "" or TelegramErrorLogBotChatID = ""){ + Message = TelegramErrorLogBotToken and/or TelegramErrorLogBotChatID are blank. Please add them to Settings.ini under: `n`n[General]`nTelegramErrorLogBotToken=`nTelegramErrorLogBotChatID= +} + + +Status := SendTelegramFile(TelegramErrorLogBotToken, TelegramErrorLogBotChatID, ErrorLoggingFilePath, caption := "" ) +if(InStr(Status, "error_code")){ + Message = Telegram Post Failed due to an API Issue. Error was saved to ErrorLogging file. Please send it manually. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ; SaveOrPostProgress(Message:=Status,PostType:=",ErrorLoggingTextFile") + Message = Telegram Error: %Status% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ; msgbox, 4096, Error!, %Message% + ToolTip + Return +} +ToolTip +Message = ErrorLog was successfully uploaded to the FDRBotTesting Telegram Server.`nThank You! +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + +sleep, 5000 +ToolTip +; msgbox, 4096, Success!, %Message% + +; Clipboard := ErrorLoggingFilePath +; Message = %ErrorLoggingFilePath% `n`nwas copied to the clipboard for easy attachment +; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +; msgbox, 4096, Filepath Copied to Clipboard, %ErrorLoggingFilePath%`n`nwas copied to the clipboard for easy attachment. +Return + + + +;--------------Locals---------------------------------- +LocalsUpload: +CurrentSite := "Locals" + +SaveOrPostProgress(Message:="Navigating to Post Creation Page",PostType:="Tooltip,ErrorLoggingTextFile") +; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +IniRead, LocalsPostPageURL, %SettingsIniFilepath%, General, LocalsPostPageURL, %A_Space% +if(LocalsPostPageURL = ""){ + Message = LocalsURL is blank.`nPlease add Locals URL to Settings.ini file under:`n`n[General]`nLocalsPostPageURL= + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + + +Status := NavigateFromBaseURLTo(LocalsPostPageURL) +if(Status = "Failed") +Return + +Message = Waiting for Page to fully load +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +Xpath = //textarea[@id='body'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=10,SleepLength:=1000) +if(Status){ + Message = Page did not load after 10 seconds. Force stopping refresh and trying to continue + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + send, {Escape} ; Temporary workaround, as Page seems to endlessly load for Stef + + Xpath = //textarea[@id='body'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + if(Status){ + SaveOrPostProgress(Message:="Post Failed: Check Login Status, or Website is Down",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; TakeScreenshotOfPage(ScreenShotSavePath) + + Return + } +} + +Xpath = //div[@class='uploadvideo-wrapper']//input[@name='Filedata'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) +if(Status){ + Message = Failed to Upload Video + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + + +Xpath = //input[@id='title'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000,StringTextContent:=VideoTitle) +if(Status){ + Message = Failed to input Title + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +} + +/*Xpath = //textarea[@id='body'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000,StringTextContent:=VideoDescription) +if(Status){ + Message = Failed to input Body + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +} +*/ + +; Input Description +Loop, 5 { ; Attempt to input video description a couple of times + TooltipThis("Inputting Description `nAttempt Number: " A_index) + + if(A_index = 5){ + Clipboard := VideoDescription + Message = Unable to Input Video Description`nDescription copied to clipboard, please paste it in at your earliest convenience. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + js = document.getElementsByName('body')[0].value = "%JSVideoDescription%"; ; Send content through javascript (Great for getting around emoji chrome limitaitons) + try driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + + ; msgbox + driver.findElementsByName("body").item[1].SendKeys(driver.Keys.SPACE) + ; driver.findElementsByID("ELEMENTID").item[1].SendKeys(driver.Keys.ENTER) + ; msgbox + + jsCheck = return document.getElementsByName('body')[0].value; ; Send content through javascript (Great for getting around emoji chrome limitaitons) + try Description := driver.executeScript(jsCheck) ;Executes a Javascript on the webpage, mostly used for buttons. + + + ; try Description := driver.findElementsByName("body").item[1].Attribute("value") ;XPath: ID=site-title & span tag + if(Description != "") + Break + sleep, 2000 +} + +SaveOrPostProgress(Message:="Waiting Video to finish uploading",PostType:="Tooltip,ErrorLoggingTextFile") + +; Xpath = //div[@class='uppy-StatusBar-statusPrimary'] + +; sleep, 30000 ; wait 30 seconds +; sleep, 2000 + +/*; Attach Custom Thumbnail +if(VideoThumbFilepath != ""){ + Message = Attaching Custom Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Xpath = //div[@class='custom-thumb-uploader']//input[@name='Filedata'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + + if(Status){ + Message = Failed to Attach Custom Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + +} + +*/ +sleep, 10000 +Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + jscheck = return document.getElementsByClassName('uppy-StatusBar-statusPrimary')[0].textContent; + try UploadStatus := driver.executeScript(jsCheck) + + ; UploadStatus := StrSplit(UploadStatus, ": ") + ; UploadStatus := UploadStatus[2] + + + ; message = Waiting for Video To Finish Uploading. `nCurrent Status: %UploadStatus% + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + + ; Clipboard := jsCheck + ; msgbox % "textContent: " . textContent + + + /* try UploadStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grabb innertext + catch e { + if(A_index = 1){ + Message = Unable to find Progress Upload Percentage. Upload Most Likely Failed. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + else, + Break + } + */ + + if(InStr(UploadStatus, "100%")){ + Message = Video Upload Complete. Waiting 20 seconds for Video to finalize before submitting. + sleep, 20000 + break + } + + ; if(UploadStatus != ""){ + ; Message = + ; sleep, 30000 ; 30 seconds + ; Continue + + ; } + + if(UploadStatus = "" and A_index = 1){ + Message = Upload Failed. Unable to Grab Upload Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + ; if(UploadStatus = ""){ + ; Break + ; } + + + Status := Check_For_Stuck_Video_Upload(A_index, UploadStatus) + if(Status = "Failed") + Return + } + + /*; attach custom thumbnail + xpath = //label[normalize-space()='Upload Custom Video Thumbnail'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + if(Status){ + Message = Failed to Attach Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; SaveDriverURLOFErrorPage() + ; Return + } + Status := InputFilePathIntoOpenWindow(VideoThumbFilepath) + + */ + + ; DevModeMsgBox("pause") + + ; Click the publish button + js = document.getElementsByName('submitPost')[0].click(); + try driver.executeScript(js) + + sleep, %TimeBetweenPosts% + + try currentpage := driver.url + if(CUrrentpage = LocalsPostPageURL){ + Message = Final page is same as post page. Please double check if post was published successfully. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + ; sleep, 500 + ToolTip + ; AddToTotalPostsPostedCount() + + Message = Trying to Grab Share Link + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + ; Get First word in video title + VideoTitleArray := StrSplit(VideoTitle, " ") + ; Iterate from 1 to the end of the array: + Loop % VideoTitleArray.Length(){ + VideoTitleFirstWord := VideoTitleArray[A_Index] + VideoTitleFirstWord := StrReplace(VideoTitleFirstWord, "_","-") + if(StrLen(VideoTitleFirstWord) > 4) + Break + + ; MsgBox % VideoTitleArray[A_Index] + + } + + Message = VideoTitleFirstWord: %VideoTitleFirstWord% + SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + + ; VideoTitleFirstWord := VideoTitleFirstWord[1] + ; Msgbox % "VideoTitleFirstWord: " VideoTitleFirstWord + +/* ; Format the post title to remove all spaces and special characters to match with Locals Post + ShareLinkFormatted := StrReplace(VideoTitle, " ", "-") + ShareLinkFormatted := StrReplace(ShareLinkFormatted, "?", "") + ShareLinkFormatted := StrReplace(ShareLinkFormatted, "!", "") + ShareLinkFormatted := StrReplace(ShareLinkFormatted, ".", "") + ShareLinkFormatted := StrReplace(ShareLinkFormatted, "", "") + ShareLinkFormattedFirst5Chars := SubStr(ShareLinkFormatted, 1, 5) + + */ + + + + LocalsBaseURL := StrReplace(LocalsURL, "/share/post") + ; Msgbox % "LocalsPostPageURL: " LocalsPostPageURL + ; Msgbox % "LocalsURL: " LocalsURL + ; Msgbox % "LocalsBaseURL: " LocalsBaseURL + loop, 3 { + ElementIndexNum := A_index - 1 + ; Msgbox % "ElementIndexNum: " ElementIndexNum + + + jscheck = return document.getElementsByClassName('post-bottom')[%ElementIndexNum%].outerHTML; + try outerHTML := driver.executeScript(jsCheck) + ; Clipboard := outerHTML + ; msgbox % "outerHTML: " . outerHTML + + if(InStr(OuterHTML,VideoTitleFirstWord)){ + ; MsgBox, found match at %A_index% + ShareLink := StrSplit(OuterHTML, LocalsPostPageURL) + ShareLink := ShareLink[2] + ; Msgbox % "ShareLink: " ShareLink + ShareLink := StrSplit(ShareLink, " class") + ShareLink := ShareLink[1] + ; Msgbox % "ShareLink: " ShareLink + ShareLink := LocalsPostPageURL . ShareLink + ShareLink := StrReplace(ShareLink, """", "") + ShareLink := StrReplace(ShareLink, "#comments", "") + ; Msgbox % "ShareLink: " ShareLink + Break + } + + ShareLink := + } + + + ; ShareLink := "Successful" + + Message = Upload Complete: %ShareLink% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + IniWrite, %ShareLink%, %VideoLinksIniFile%, URLs, LocalsURL + AddToTotalVideosUploadedCount() + + SaveDriverURL() + ; TakeScreenshotOfPage(ScreenShotSavePath) + + + Return + + ; + ;------------------/Locals------------------------------ + + ; + ;--------------------Telegram---------------------------- + TelegramVideoUpload: + + if(VideoFileSizeInMB > 50){ + Message = Telegram Upload Skipped. Video is larger than 50MB + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + CurrentSocialMediaPosting := "Telegram Video" + Message = Uploading Video to Telegram + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + IniRead, TelegramBotToken, %SettingsIniFilepath%, SocialMediaPoster, TelegramBotToken, %A_Space% + IniRead, TelegramBotChatID, %SettingsIniFilepath%, SocialMediaPoster, TelegramBotChatID, %A_Space% + + + LineBreakChar = `%0A ; Used for Telegram API + + SaveOrPostProgress(Message:="Posting to Telegram",PostType:="Tooltip,ErrorLoggingTextFile") + + if(TelegramBotToken = "" Or TelegramBotChatID =""){ + Message = TelegramBotToken or TelegramBotChatID is missing from %SettingsIniFilepath%. `nPlease input them and click the button again. + msgbox, 4096, Error!, %Message% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; Msgbox, 4096, Error!, TelegramBotToken or TelegramBotChatID is missing from %SettingsIniFilepath%. `nPlease input them and rerun the script. + Return + } + + + ; If description is longer than 2k chars, then API will error out. goto section that will allow user to edit video description to shorten it for posting + if(StrLen(SocialMediaDescription) > 2000){ + TelegramVideoUploadDescription := SubStr(SocialMediaDescription, 1, 990) + TelegramVideoUploadDescription .= "...." + ; msgbox, here goes + ; Goto, CreateDescriptionForVideosPosting + } + + + SubmitDescriptionForTelegramVideoUpload: + TelegramVideoTitle := ASCIISTRReplace(VideoTitle) + + TelegramBodymessage := ASCIISTRReplace(TelegramVideoUploadDescription) + + LineBreakChar = `%0A ; Used for API + + + Message := "*" . TelegramVideoTitle . "*" . LineBreakChar . TelegramBodymessage . LineBreakChar + + Message := StrReplace(Message, "`n", LineBreakChar) ; replace all new line characters with the global charater + + ; Msgbox % "Message: " Message + + Status := SendTelegramVideo(TelegramBotToken, TelegramBotChatID, VideoFilepath, caption := Message ) ; you could add more options; compare the Telegram API docs + if(InStr(Status, "error_code")){ + Message = Telegram Post Failed due to an API Issue. Error was saved to ErrorLogging file. Please send it to Yuriy. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ; SaveOrPostProgress(Message:=Status,PostType:=",ErrorLoggingTextFile") + Message = Telegram Error: %Status% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + ToolTip + Return + } + ; msgbox + + + Message = Upload Complete to Telegram + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + IniWrite, Successful, %VideoLinksIniFile%, Misc, Telegram + ; SaveDriverURL() + AddToTotalVideosUploadedCount() + + Return + + ; -------------------------------BitChute------------------------------- + BitChuteUpload: + CurrentSite := "Bitchute" + + Message = Starting Upload + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + Status := NavigateFromBaseURLTo("https://www.bitchute.com/myupload", "BitChute Video Uploader") + if(Status){ + Message = Upload Failed (E#7295)`nUnable to Navigate to Upload Page`nChrome was closed or Internet down possibly? + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + + + Message = Uploading Video + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + ; sleep, 5000 + + ; Try to input video title and if fail try to login again + loop, 2 { + Xpath = //input[@id='title'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000,StringTextContent:=VideoTitle) + + if(!Status) + Break + + ; Try to login + Message = Checking Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + Xpath = //input[@id='id_username'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + if(!Status){ + Xpath = //button[normalize-space()='Submit'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + + Message = Waiting for Upload Page to Load + SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + try driver.executeScript("return document.readyState").equals("complete") + sleep, 5000 + Continue + } + + } + + + ; DevModeMsgBox("stop") + + ; BitchuteDescription := SubStr(VideoDescription, 0, 2995) . "..." + ; JSBitchuteDescription := FormatTextToJSText(BitchuteDescription) + + BitchuteDescription := VideoDescription + if(StrLen(BitchuteDescription) > 2995){ + BitchuteDescription := SubStr(BitchuteDescription, 1, 2995) + JSBitchuteDescription := FormatTextToJSText(BitchuteDescription) + } + else, + JSBitchuteDescription := FormatTextToJSText(BitchuteDescription) + + Message = Inputting Description + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + Loop, 10 { ; Attempt to input video description a couple of times + LogErrorToTextFile("Inputting Description") + + ; Input text + ; try BitChuteUploadProgress := driver.executeScript("return document.getElementsByClassName('progress-bar')[0].innerHTML;") ;navigate using javascript + ; send text to page + ; jsSend = document.getElementsByClassName('form-control')[1].value = "%JSBitchuteDescription%"; + + jsSend = document.getElementById('description').value = "%JSBitchuteDescription%"; + ; try driver.executeScript(js) + + ; Check text in the box + jsCheck = return document.getElementById('description').value; + + ; send text to the page + try driver.executeScript(jsSend) + + ; check contents of page + try VideoDescriptionOnPage := driver.executeScript(jsCheck) ;Executes a Javascript on the webpage, mostly used for buttons. + + if (A_index = 1){ + message := SubStr(VideoDescriptionOnPage, 1, 250) + message = Bitchute Inputted description: %message% + SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile,DiscordErrorLogging") + } + + if(VideoDescriptionOnPage = ""){ + Message = Failed to input Video Description + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + } + + + Message = Inputting Tags + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + ; Convert tags into #hasthtags + Loop, 3 { + Value := KeywordsArray[A_Index] + Value := StrReplace(Value, " ", "") ; Remove spaces if hashtag has two words + ; HashTag := "#" . Value + BitchuteHashtags .= Value . " " + } + + ; input hashtags + Xpath = //input[@placeholder='Search Terms'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=BitchuteHashtags) + + ; Upload Thumbnail + Message = Attaching Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + if(VideoThumbFilepath != ""){ + ; Upload Cover Image Button + Message = Uploading Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + + Xpath = //input[@name='thumbnailInput'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + if(Status){ + Message = Failed to Attach Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + ; sleep, 5000 + } + + ; Upload Video button + Xpath = //input[@name='videoInput'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) + if(Status){ + Message = Failed to Upload Video + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + + Message = Waiting for Video to Finish Uploading`nChecking Progress Every 5 seconds + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + Xpath = //div[@role='progressbar'] ; Xpath to progress % + Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + if(A_index = 5){ ; while waiting for bitchute video to finish uploading, start up lbry + if(OdyseeVideo OR OdyseeAudio){ + SaveOrPostProgress(Message:="Starting up LBRY while waiting for Bitchute Video to finish uploading",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + CheckLBRYProcess() + } + } + ; Selenium + ; try BitChuteUploadProgress := driver.findelementbyxpath(Xpath).Attribute("innerText") ;GREAT FOR GRABBING INNER CONTENTS/Values + + try BitChuteUploadProgress := driver.executeScript("return document.querySelector('.filepond--file-status').innerHTML;") ;navigate using javascript + ; Msgbox % "BitChuteUploadProgress: " BitChuteUploadProgress + + if(BitChuteUploadProgress = ""){ + Message = Unable to Grab Upload Progress, Upload Possibly Failed + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + if(InStr(BitChuteUploadProgress, "Upload complete")){ + Message = Waiting 10 Seconds before clicking "Proceed" button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + sleep, 10000 + Break ; Break out of the loop when 100% upload status + + } + + ; split_text = "> + ; Pull out upload percentage + BitChuteUploadProgress := StrSplit(BitChuteUploadProgress, ">") + BitChuteUploadProgress := BitChuteUploadProgress[2] + BitChuteUploadProgress := StrSplit(BitChuteUploadProgress, "= 5000){ + BrighteonVideoDescription := SubStr(VideoDescription, 1, 4800) + BrighteonVideoDescription .= "...." + JSBrighteonVideoDescription := FormatTextToJSText(BrighteonVideoDescription) + + if(StrLen(JSBrighteonVideoDescription) > 5000){ + BrighteonVideoDescription := SubStr(VideoDescription, 1, 4500) + BrighteonVideoDescription .= "...." + JSBrighteonVideoDescription := FormatTextToJSText(BrighteonVideoDescription) + } + } + +/*; Closing any popups that might appear +loop, 3 { +Xpath = //body/div[@id='__next']/div[@id='modal-root']/div/div/div[1] ; get our free newsletter +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + +; try driver.FindElementByXPath(Xpath).click() + +; If newsletter pop up exists then close it. +Xpath = //div[@class='overlay__close inside'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + + +} +*/ + + +Message = Checking Login Status +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +try CurrentTab := driver.url +if(InStr(CurrentTab, "login")) ; we're logged out +{ + + Message = Closing out of any popups that might appear + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + ; loop, 2 { + Xpath = //body/div[@id='__next']/div[@id='modal-root']/div[2]/div[1]/div[1]//*[local-name()='svg'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + + Xpath = //body/div[@id='__next']/div[@id='modal-root']/div/div/div[1] ; get our free newsletter + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + + ; try driver.FindElementByXPath(Xpath).click() + + ; If newsletter pop up exists then close it. + Xpath = //div[@class='overlay__close inside'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + + + if(AutoLogin){ + Message = Trying to Log Back In + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + js = return document.querySelector("input[placeholder='username/email']").value; + status := try driver.executeScript(JS) ;Execute Javascript + + if(StrLen(Status) > 0){ + ; msgbox, clicking login button + Xpath = //a[normalize-space()='Log In'] ; click login button + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=6,SleepLength:=1000) + + sleep, 2000 + Xpath = //button[@type='submit'] ; click login button on login page + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + try driver.executeScript("return document.readyState").equals("complete") + + sleep, 2000 + } + + + } + else, { + SaveOrPostProgress(Message:="Login Expired. Please log back in",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + } + + + ; Navigate to Upload Page + try driver.executeScript("window.location = 'https://www.brighteon.com/dashboard/video-upload'") ;navigate using javascript + + try driver.executeScript("return document.readyState").equals("complete") + + ; Click out of the "Support free speech" pop-up if it pops up + Xpath = //body/div[@id='__next']/div[@id='modal-root']/div/div/div[1]//*[local-name()='svg'] + try driver.FindElementByXPath(Xpath).click() + + ; Upload Video + Xpath = //input[@type='file'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) + if(Status){ + Message = Failed to Upload Video, Please check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + ; Input Title of the Video + Xpath = /html/body/div/section[2]/div[2]/div/form/div[1]/div[1]/div[2]/div[1]/div/input + try driver.FindElementByXPath(Xpath).SendKeys(VideoTitle) ;Sends Variable to an Xpath Item + + + TooltipThis("Inputting Video Description") + + ; sleep, 5000 + ; @todo this doesn't do anything anymore. + ; DevModeMsgBox("rework me here") + ; Xpath = //textarea[@id='description'] + ; try, driver.FindElementByXPath(XPATH).SendKeys(driver.Keys.SPACE) + + ; sleep, 1000 + + + ; Attempt to input video description a couple of times + Loop, 10 { + Message = Inputting Description. `nAttempt Number: %A_index% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + ; SaveOrPostProgress(Message:=Message,PostType:="DiscordErrorLogging") + + ; SaveOrPostProgress(Message:="Inputting Video Description",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar") + ; TooltipThis("Inputting Description) + + Xpath = //div[@class='e-content e-lib e-keyboard'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoDescription) + if(Status){ + SaveOrPostProgress(Message:="Failed to input Video Description",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + ; DevModeMsgBox("pause") + + ; driver.FindElementByXPath(Xpath).SendKeys(VideoDescription) + + ; js = document.getElementById('description').value = "%JSBrighteonVideoDescription%"; + ; try driver.executeScript(js) + + + ; sleep, 1000 + ; TooltipThis("checking description input") + ; try driver.findElementsByID("description").item[1].SendKeys(driver.Keys.ENTER) + ; sleep, 1000 + + sleep, 5000 + + + js = return document.querySelector("div[class='e-content e-lib e-keyboard'] p").innerText; + try Input_Description := driver.executeScript(JS) ;Execute Javascript + + ; if text in description box is longer than x chars, then description input worked + if(StrLen(Input_Description) > 15){ + Input_Description := SubStr(Description, 1, 200) + Message = Description that got input: %Input_Description% ... + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Break + } + + } + + + + ; Thumbnail + if(VideoThumbFilepath != "") { + TooltipThis("Uploading Thumbnail") + Xpath = //input[@type='file'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + if(Status){ + Message = Failed to Upload Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + } + + + ; Keywords (Tags) + TooltipThis("Inputting Keywords") + XPath = //input[@id='keywords'] + try driver.FindElementByXPath(Xpath).SendKeys(VideoTags) ;Sends Variable to an Xpath Item + catch e { + Message = Error (E#2312)`nVideo Uploaded but Unable to Input Video Tags + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + + + ; double check on video description after inputting tags + js = return document.querySelector("div[class='e-content e-lib e-keyboard'] p").innerText; + try Input_Description := driver.executeScript(JS) ;Execute Javascript + DevModeMsgBox(Input_Description) + + ; if text in description box is longer than x chars, then description input worked + if(StrLen(Input_Description) > 5){ + SaveOrPostProgress(Message:="Video Description second double check was successful",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + } + else, { + SaveOrPostProgress(Message:="Secondary video description check failed",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + + + TooltipThis("Waiting for Video to Finish Uploading") + Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + ; Get progress status through javascript + jsCheck = return document.getElementsByClassName('video-upload--details')[0].textContent; + try ProgressStatus := driver.executeScript(jsCheck) + + if(ProgressStatus = ""){ + Message = Failed to Grab Video Upload Status. Upload Most Likely Failed + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + if(InStr(ProgressStatus, "Upload complete.")){ + Break + } + + ; Pull out progress Percentage from full string + UploadPercent := StrSplit(ProgressStatus, "(") + UploadPercent := UploadPercent[2] + UploadPercent := StrSplit(UploadPercent, ")") + UploadPercent := UploadPercent[1] + + ; Message = Waiting for Video to Finish Uploading`nCurrent Upload Status: %UploadPercent% + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + + Status := Check_For_Stuck_Video_Upload(A_index, UploadPercent) + if(Status = "Failed") + Return + } + + ; Save Video button + TooltipThis("Clicking Save Video Button to finalize Upload") + try BrighteonUploadPageURL := driver.url + try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + + TooltipThis("Waiting for Result page to finish loading") + Loop, 60 { ; 5 loops of 1 minute each + if(A_index = 10){ + Message = Upload Failed: Clicking "Save Video" did not Finalize the Upload + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return ; Break out of gosub + } + js = document.getElementsByClassName('mr-2 btn btn-primary btn-sm')[0].click(); ; Save Video Button + try driver.executeScript(js) + driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + sleep, 5000 ; 30 seconds + try CurrentURL := driver.url + if(BrighteonUploadPageURL != CurrentURL) + Break + } + + + Message = Trying to Grab Uploaded Video URL + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + ; Message = Waiting 60 Seconds Before Checking Results Page for URL + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + ; Navigate to Videos page and loop through the videos and grab the URL of the latest upload + try driver.Get("https://www.brighteon.com/dashboard/videos") ;Open selected URL + try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + + + ; Get First word in video title to use in grabbing video URL + VideoTitleArray := StrSplit(VideoTitle, " ") + ; Iterate from 1 to the end of the array: + Loop % VideoTitleArray.Length(){ + VideoTitleLongWord := VideoTitleArray[A_Index] + ; VideoTitleFirstWord := StrReplace(VideoTitleFirstWord, "_","-") + if(StrLen(VideoTitleLongWord) > 4) + Break + + ; MsgBox % VideoTitleArray[A_Index] + } + + + Message = VideoTitleLongWord: %VideoTitleLongWord% + SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + + + Loop, 4 { + ElementIndexNumber := A_index + 1 + + jsCheck = return document.getElementsByClassName('col')[%ElementIndexNumber%].outerHTML; + try BrighteonURL := driver.executeScript(jsCheck) + + jsCheck = return document.getElementsByClassName('col')[%ElementIndexNumber%].textContent; + try InnerText := driver.executeScript(jsCheck) + + Message = InnerText: %InnerText% + SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + + Message = BrighteonURL: %BrighteonURL% + SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + + ; Msgbox % "VideoTitleLongWord: " VideoTitleLongWord "`nInnerText: " InnerText + ; clipboard := Message + ; msgbox % Message + ; Msgbox % "InnerText: " InnerText . "`n" . "BrighteonURL: " . BrighteonURL + + if(InStr(InnerText, VideoTitleLongWord)){ + BrighteonURL := StrSplit(BrighteonURL, "/dashboard/videos/") + BrighteonURL := BrighteonURL[2] + BrighteonURL := StrSplit(BrighteonURL, "> 3000){ + DailyMotionJSDescription := SubStr(VideoDescription, 1, 2990) + DailyMotionJSDescription := FormatTextToJSText(DailyMotionDescription) + DailyMotionJSDescription .= "....." +} + + +; Input Video Description +Loop, 15 { ; make a couple attempts to input description + TooltipThis("Inputting Video Description`nMight take a couple of attempts due to DailyMotion's code`nAttempt Number:" A_index) + + try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.Space) ; send an ENTER keystroke to make it register that data has been input and refresh + sleep, 500 + ; Clear any text from a previous loop + try driver.findElementsByName("description").item[1].clear() + + ; try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.SPACE) ;;Clicks Item based on the Element Name + + js = document.getElementsByName('description')[0].value = "%JSVideoDescription%"; + try driver.executeScript(js) + + try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.Space) ; send an ENTER keystroke to make it register that data has been input and refresh + + sleep, 15000 ; Description dissapears for some reason instantly after inputting sometimes + try Description := driver.findElementsByName("description").item[1].Attribute("value") + if(strlen(Description) 10){ + try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.Space) ; send an ENTER keystroke to make it register that data has been input and refresh + Break ; break out of the loop + } + + if(A_index = 10){ + ; Clipboard := VideoDescription + Message = Upload Failed (E#7899): Failed to Input video description + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return ; Kick out of the gosub + } + + + try Description := driver.findElementsByName("description").item[1].Attribute("value") + if(StrLen(Description) > 10){ + SaveOrPostProgress(Message:="Description was input successfully",PostType:="Tooltip") + Break ; break out of the loop + } +} + + + +/* +; Input Video Description +Loop, 15 { ; make a couple attempts to input description + TooltipThis("Inputting Video Description") + js = document.getElementsByName('description')[0].value = ""; ; clear any text from box + driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + + ; try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.Space) ; send an ENTER keystroke to make it register that data has been input and refresh + ; sleep, 500 + ; Clear any text from a previous loop + ; try driver.findElementsByName("description").item[1].clear() + + + ; try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.SPACE) ;;Clicks Item based on the Element Name + + ; ValueToCheckOptions = innertext,textContent,InnerHTML,outerHTML,value,href,option value + ; JSText := FormatTextToJSText(TEXT) + js = document.getElementsByName('description')[0].value = "%DailyMotionJSDescription%"; + try driver.executeScript(js) + + sleep, 2000 + + try driver.findElementsByName("description").item[1].SendKeys(driver.Keys.Space) ; send an ENTER keystroke to make it register that data has been input and refresh + + sleep, 2000 + + jsCheck = return document.getElementsByName('description')[0].value; ; Send content through javascript (Great for getting around emoji chrome limitaitons) + DescriptionInput := driver.executeScript(jsCheck) ;Executes a Javascript on the webpage, mostly used for buttons. + ; Msgbox % "DescriptionInput: " DescriptionInput + + if(StrLen(DescriptionInput) > 5) + break +} + + +*/ +; Progress Percentage +TooltipThis("Waiting for Video to Finish Uploading`nChecking Progress Every 5 seconds") +; Xpath = //span[contains(text(),'Upload at')] + +Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + jsCheck = return document.getElementsByClassName('src-routes-media-common-components-progress-bar-index__details--3_P1L')[0].textContent; + try UploadPercentage := driver.executeScript(jsCheck) + + if(UploadPercentage = "") + { + Message = Upload Failed (E#2735)`nUnable to find Progress Upload Percentage + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return ; Kick out of the gosub + } + + if(InStr(UploadPercentage, "100%")) ; If at 100% uploaded, break out of loop + Break + + Status := Check_For_Stuck_Video_Upload(A_index, UploadPercentage) + if(Status = "Failed") + Return + + + ; if(HasVal(Array_Index_Num_of_Upload_StatusChecks, A_index)) { ; 30 minutes and 60 minutes - send a notification message + ; Message = Upload Progress: %UploadPercentage% + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + ; } + } + + ; Grab the Share URL and pull out the Video Link from it. + SaveOrPostProgress(Message:="Grabbing Share URL",PostType:="Tooltip,ErrorLoggingTextFile") + +/*Xpath = //span[contains(text(),'Share link:')] +try ShareLink := driver.findelementbyxpath(Xpath).Attribute("innerText") + +*/ + +jsCheck = return document.getElementsByClassName('src-routes-media-pages-upload-components-slot-index__shareLink--nc1-O')[0].textContent; +try ShareLink := driver.executeScript(jsCheck) + +Message = ShareLink: %ShareLink% +SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile") + +if(!InStr(ShareLink, "https")){ + Message = Upload Successful but Failed to Grab Video URL + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; Return +} + + +DailyMotionURL := StrReplace(ShareLink, "Share link: ","") ; remove the share link text from string + +; Click the publish button +Xpath = //button[@name='submit'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Failed to click Publish button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + + js = document.getElementsByClassName('ant-btn ant-btn-primary ant-btn-sm')[1].click(); + try driver.executeScript(js) +} + + + +Message = Upload Complete: %DailyMotionURL% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +IniWrite, %DailyMotionURL%, %VideoLinksIniFile%, URLs, DailyMotionURL +SaveDriverURL() +AddToTotalVideosUploadedCount() +; TakeScreenshotOfPage(ScreenShotSavePath) + +Return +; -------------------------------/DailyMotion------------------------------- + + + +; -------------------------------streamanity------------------------------- +StreamanityUpload: +Return +CurrentSite := "Streamanity" +SaveOrPostProgress(Message:="Starting Upload",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +URLAttempt := NavigateFromBaseURLTo("https://streamanity.com/upload", "Upload - Streamanity") +if(URLAttempt = "Failed") +Return +driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + +/* +; Connect Wallet Button - if it exists than not logged in +Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[2]/div/div/button +try LoginStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ;GREAT FOR GRABBING INNER CONTENTS/Values +if(LoginStatus != ""){ + Message = Upload Failed (E#8755)`nLogin Cookies have expired. Please Re-login + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +*/ + +/*; Close button on "A new Beginning" popup +; this can probably be removed now. Popup was around as of 2020-10ish or so +Xpath = /html/body/div[3]/div[2]/div/div/a/i +try driver.FindElementByXPath(Xpath).click() ;Clicks on Xpath based on variable. +sleep, 500 +try driver.FindElementByXPath(Xpath).click() ;Clicks on Xpath based on variable. +; sleep, 2000 ; wait for pop up to go away + +*/ + +Message = Checking Login Status +SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + +; Check the page for "Connect Wallet" text which means the user is logged out +try html := driver.pagesource ; save page's entire HTML to a variable +if(InStr(HTML, "Connect Wallet")) +{ + Message = Upload Failed: Please Check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + + +Message = Selecting Video File +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +Xpath = //div[@class='uploader-body']//input[@type='file'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) +if(Status){ + Message = Failed to Upload Video, Please check login status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} +/*Xpath = //div[@class='uploader-body'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +Status := InputFilePathIntoOpenWindow(VideoFilepath) +if(Status) +{ + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +*/ + +if(VideoThumbFilepath != "") { + Message = Uploading Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + Xpath = //input[@accept='image/*'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + if(Status){ + Message = Failed to Upload Thumbnail + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } +/* + Xpath = //div[@class='thumb-cover has-preview'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) + if(Status){ + Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[1]/div/div[2]/div/div/div[2]/div[2]/div[1]/div[1] ; Upload thumbnail + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) + if(Status){ + Message =Upload Error (#5803): Unable to click on Upload Thumbnail button with Relative and Direct Xpath + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + } + + Status := InputFilePathIntoOpenWindow(VideoThumbFilepath) + if(Status) + { + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + */ +} + + +; Input Title +TooltipThis("Inputting Video Title") +Status := js_SendAndCheckWithClassName(ClassName:="ivu-input",ClassIndexNum:=1,ValueToCheck:="value",SleepLength:=1000,JSStringText:=JSVideoTitle) +if(Status){ + Message = Upload Failed: Failed to input Video Title + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + +Xpath = //input[@placeholder="What's the name of your video"] +try driver.FindElementByXPath(Xpath).SendKeys(driver.Keys.SPACE) + +/*Xpath = //input[@placeholder="What's the name of your video"] +try driver.FindElementByXPath(Xpath).clear() ; clear the auto generated video title +catch e { + sleep, 5000 + try driver.FindElementByXPath(Xpath).clear() ; clear the auto generated video title + catch e { + Message = Failed to clear Auto Generated Video Title. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } +} + +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000,StringTextContent:=VideoTitle) +if(Status){ + + Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[1]/div/div[3]/div/div/div/div[2]/div[1]/form/div[1]/div/div/input + try driver.FindElementByXPath(Xpath).clear() + try driver.FindElementByXPath(Xpath).SendKeys(VideoTitle) ;Sends Variable to an Xpath Item + catch e { + Message = Failed to input Video Title through both Relative and Direct Xpath + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Return + } +} + +*/ + +; Input Description +Message = Inputting Description +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +/*Loop, 5 { ; Attempt to input video description a couple of times + Status := js_SendAndCheckWithClassName(ClassName:="ivu-input",ClassIndexNum:=2,ValueToCheck:="value",SleepLength:=2000,JSStringText:=JSVideoDescription) + if(!Status) ; if no errors then text got input correctly, break out of loop + Break + +} + + +*/ + +; Input Description +Loop, 5 { ; Attempt to input video description a couple of times + Message = Inputting Description `nAttempt Number: %A_index% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + ; TooltipThis("Inputting Description `nAttempt Number: " A_index) + + Xpath = //textarea[@placeholder='What is this video about?'] + try DescriptionContents := driver.findelementbyxpath(Xpath).Attribute("value") ;XPath: ID=site-title & span tag + +/* if(A_index = 5){ + Clipboard := VideoDescription + Message = Unable to Input Video Description`nDescription copied to clipboard, please paste it in at your earliest convenience. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + */ + StreamanityVidDescjs = document.getElementsByClassName('ivu-input')[2].value = "%JSVideoDescription%"; ; Send content through javascript (Great for getting around emoji chrome limitaitons) + try driver.executeScript(StreamanityVidDescjs) ;Executes a Javascript on the webpage, mostly used for buttons. + + sleep, 1000 + Xpath = //textarea[@placeholder='What is this video about?'] + try DescriptionContents := driver.findelementbyxpath(Xpath).SendKeys(driver.Keys.SPACE) ;XPath: ID=site-title & span tag + + +/* try driver.executeScript(StreamanityVidDescjs) ;Executes a Javascript on the webpage, mostly used for buttons. + + try StreamanityDescription := driver.findElementsByClass("ivu-input").item[3].Attribute("value") + if(StreamanityDescription != ""){ + try driver.findElementsByClass("ivu-input").item[3].SendKeys(driver.Keys.ENTER) ; Send enter to add extra line to end of description. This is the fix for description not dissapearing upon moneybutton swipe + Break + } + + */ + sleep, 2000 + + + jscheck = return document.getElementsByClassName('ivu-input')[2].value; + if(strlen(jscheck) > 10) ; if no errors then text got input correctly, break out of loop + Break + + + ; sleep, 2000 +} + + + +; Input Video Tags. We need to send them one item at a time to Streamanity +; StreamanityTagsArray := StrSplit(VideoTags,",") + + +Message = Inputting Video Tags +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +; Xpath to Tags Input Box +; Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[1]/div/div[3]/div/div/div/div[2]/div[1]/form/div[3]/div/div/div/div/div/input +Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[1]/div/div[3]/div/div/div/div[2]/div[1]/form/div[3]/div/div/div/div/div/input +; Input Each tag one by one +Loop % KeywordsArray.Length() +{ + Tag := KeywordsArray[A_Index] + ; Msgbox % "Tag: " Tag + try driver.FindElementByXPath(Xpath).SendKeys(Tag) ;Sends Variable to an Xpath Item + try driver.FindElementByXPath(Xpath).SendKeys(driver.Keys.Enter) ;Sends Enter key to Xpath. + ; msgbox, pause + sleep, 250 +} + + +; ASK STEF FOR INPUT HERE +TooltipThis("Waiting for User to Swipe Payment Button") +Xpath = //div[@class='video-title'] +; MsgBox,,Xpath Value,% driver.findelementbyxpath(Xpath).Attribute("value") ;XPath: ID=site-title & span tag + +Loop, 20 { + + if(A_index = 20){ + Message = Payment was not swiped. Skipping to Next Website + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + + try Status := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grabb innertext + if !InStr(Status, "Waiting for payment") + break + + ; otherwise sleep and re-run check + sleep, 5000 +} + + + + + +; Status := StrSplit(status, "`n") +; msgbox % Status[1] +; msgbox % Status[2] + + +; MsgBox,,XPATH Text Content,% driver.findelementbyxpath(Xpath).Attribute("textContent") ;XPath: ID=site-title & span tag +; MsgBox,,HREF Link Location: ,% driver.findelementbyxpath(Xpath).Attribute("href") ;XPath: Href (Link location) value +; MsgBox,,XPATH-ID & Tag,% driver.findelementbyxpath(Xpath).Attribute("outerHTML") ;XPath: ID=site-title & span tag +; MsgBox,,XPATH Option Value,% driver.findelementbyxpath(Xpath).Attribute("option value") ;XPath: ID=site-title & span tag + + + +TooltipThis("Waiting for Video to Finish Uploading") + +; Upload status text at the top left of the page +Xpath = /html/body/div[1]/div[3]/div[2]/div/div/div/div[1]/div/div[1]/div/div[1]/span + +Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + jsCheck = return document.querySelector("div[class='video-title'] span").textContent; + try UploadStatus := driver.executeScript(jsCheck) + + ; try UploadStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grab innertext + + if(UploadStatus = ""){ + Message = Failed to Grab Video Upload Status. Upload Most Likely Failed + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + ; Msgbox % "UploadStatus: " UploadStatus + + if(InStr(UploadStatus, "Complete")){ ; If upload is complete then we're ready to click the Publish Button + sleep, 5000 ; 5 seconds + Break + + + Status := Check_For_Stuck_Video_Upload(A_index, UploadStatus) + if(Status = "Failed") + Return + + ; if(A_index = 240){ + ; Message = Upload Failed. Upload did not complete after 2 hours of waiting. Something possibly went wrong? + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; SaveDriverURLOFErrorPage() + ; Return + ; } + + + ; if(HasVal(Array_Index_Num_of_Upload_StatusChecks, A_index)) { ; 30 minutes and 60 minutes - send a notification message + ; Message = Upload Status: %UploadStatus% + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + ; } + + + } + + } + + ; Publish Button at the very bottom + SaveOrPostProgress(Message:="Trying to Click Publish Button",PostType:="Tooltip,ErrorLoggingTextFile") + Xpath = //span[normalize-space()='P U B L I S H'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) + if(Status){ + Message = Streamanity Upload Incomplete (E#4701)`nVideo Uploaded But Unable to click final "Publish" button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + } + + ; Wait for Confirmation Page to load and grab the Video URL from here + Message = Waiting for Confirmation Page to Load + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + + Xpath = //div[@class='link'] ; Xpath to URL of the video + Loop, 60 { ; loop for a couple of minutes to wait for confirmation page to load + jsCheck = return document.getElementsByClassName('link')[0].textContent; + try StreamanityURL := driver.executeScript(jsCheck) + + if(InStr(StreamanityURL, "https://streamanity.com")) + Break + + if(A_index = 60){ + try PageURL := driver.URL + Message = Upload Complete: But Failed to Grab Video Link`nPage Stuck At at: %PageURL% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + IniWrite, Failed to Grab Link. Please copy and paste into here, %VideoLinksIniFile%, URLs, StreamanityURL + SaveDriverURLOFErrorPage() + Return + } + Sleep, 1000 + } + + if(StreamanityURL = ""){ + Message = Upload Successfull but unable to automatically grab URL. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + + Message = Upload Complete:`n%StreamanityURL% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + IniWrite, %StreamanityURL%, %VideoLinksIniFile%, URLs, StreamanityURL + SaveDriverURL() + AddToTotalVideosUploadedCount() + ; TakeScreenshotOfPage(ScreenShotSavePath) + + Return + ; -------------------------------/streamanity------------------------------- + + + + + + ; -------------------------------LBRY------------------------------- + LBRYVideoUpload: + LBRYAudioUpload: + if(LBRYUploadType = "Video"){ + CurrentSite := "LBRY Video" + IniRead, LBRYPermanentURL, %VideoLinksIniFile%, Misc, LBRYVideoPermanentURL, %A_Space% + + } + if(LBRYUploadType = "Audio"){ + CurrentSite := "LBRY Audio" + IniRead, LBRYPermanentURL, %VideoLinksIniFile%, Misc, LBRYAudioPermanentURL, %A_Space% + } + + ; if LBRY permanent URL was already grabbed before, exit + if(LBRYPermanentURL != "") + Return + + CheckLBRYProcess() ; double check lbry process + + + SaveOrPostProgress(Message:="Starting Upload",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + + ; If LBRY Killer not found, then download it + ; @todo: Add LBRY kill download functionality from gitea +/* + LBRYKillerPath := LibFolder . "\LBRY Process Killer.exe" + if(!FileExist(LBRYKillerPath)){ + + ; Msgbox % "LBRYKillerPath: " LBRYKillerPath + ; Msgbox % "LBRYProcessKillerURL: " LBRYProcessKillerURL + LBRYKillerPath = %A_ScriptDir%\Lib\LBRY Process Killer.exe + LBRYKillerUpdateURL = https://freedomainplaylists.com/wp-content/FreedomainScripts/LBRY`%20Process`%20Killer.exe + + UrlDownloadToFile, %LBRYKillerUpdateURL%, %LBRYKillerPath% + ; msgbox, work? + ; UrlDownloadToFile, URL, Filename + Message = LBRY Process Killer Not Found. Automatically Downloading. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + } + + */ + + TooltipThis("Uploading Video through API") + ; Variables of items that need to be replaced before argument is passed to API + Apostrophe = ' + LBRYTags = ; Create empty variable + SingleQuotationmark = " + EscapedQuotationMark = \" + + ; Replace all items to make text passable to API + LBRYVideoTitle := StrReplace(VideoTitle, SingleQuotationmark, EscapedQuotationMark) ; replace all spaces with dashes + LBRYVideoDescription := StrReplace(VideoDescription, SingleQuotationmark, EscapedQuotationMark) + + if(StrLen(LBRYVideoDescription) >= 5000){ + LBRYVideoDescription := SubStr(LBRYVideoDescription, 1, 4990) + LBRYVideoDescription .= "...." + } + + if(LBRYUploadType = "Video"){ + Message = Uploading through API with URL Slug: %LBRYURLSlug% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + FilePathForLBRYAPI := VideoFilepath + + } + + if(LBRYUploadType = "Audio"){ + ; Replace all items to make text passable to API + LBRYVideoTitle .= " (Audio)" + LBRYURLSlug .= "_Audio" + Message = Uploading through API with URL Slug: %LBRYURLSlug% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + FilePathForLBRYAPI := WavAudioFilepath + } + + ; if no lbry slug, then error out + if(LBRYURLSlug = "" OR LBRYURLSlug = "_Audio"){ + Message = Upload Failed because no URL Slug was provided. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + + + ; loops through array and creates a string of: --tags="tag1" --tags="tag2" --tags="tag3" so that it can be passed to lbrynet + Loop % KeywordsArray.Length(){ + LBRYTags .= "--tags=" . SingleQuotationmark KeywordsArray[A_Index] . SingleQuotationmark . " " + } + + ; Msgbox % "FilePathForLBRYAPI: " FilePathForLBRYAPI + + SplitPath, VideoThumbFilepath, ThumbnailFileNameWExt, OutDir, OutExtension, OutNameNoExt, OutDrive + + FDRThumbnailURL = https://cdn.freedomainradio.com/%ThumbnailFileNameWExt% + message = FDRThumbnailURL: %FDRThumbnailURL% + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") + + ; Msgbox % "FDRThumbnailURL: " FDRThumbnailURL + ; Create API Command and save it to variable + LBRYAPICommand = "%LBRYNetFilepath%" publish --name="%LBRYURLSlug%" --bid="%LBRYNewVideoStakeAmount%" --file_path="%FilePathForLBRYAPI%" --title="%LBRYVideoTitle%" --description="%LBRYVideoDescription%" %LBRYTags% --thumbnail_url="%FDRThumbnailURL%" --channel_id="%LBRYChannelID%" + + ; LogErrorToTextFile(LBRYAPICommand) ; Log to file + LogErrorToTextFile("LBRYAPICommand: " LBRYAPICommand) + + ; Parse returned API json for success status + UploadResult := StdOutToVar(LBRYAPICommand) + if(InStr(UploadResult, "Could not connect")){ + Message = Upload Failed. Reason: %UploadResult% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + if(UploadResult = ""){ + Message = LBRYNet did not return anything. LBRY not running? + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + ; Msgbox % "UploadResult: " UploadResult + try parsed := JSON.Load(UploadResult) + try UploadStatus := parsed.height + + ; Msgbox % "UploadStatus: " UploadStatus + + ; -2 is returned if upload was successful + if(UploadStatus != "-2"){ + ; msgbox, error + ErrorCode := parsed.message + ErrorCode := parsed.message + ErrorCode := StrSplit(ErrorCode, "code") + ErrorCode := ErrorCode[1] + + Message = LBRY Upload Failed`nReason: %ErrorCode% + ; Msgbox % "Message: " Message + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + + + ; Clipboard := UploadResult + ; Msgbox % "UploadResult: " UploadResult + + + LogErrorToTextFile("UploadResult: " UploadResult) + + if(InStr(UploadResult, "Could not connect to daemon")){ + if(LBRYAttemptNumber = 2){ + + Message = Upload Error (E#4081)`nVideo Upload Failed due to daemon not running.`nPlease start it manually and re-run the upload. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + try run, %LBRYKillerPath% "Kill" + catch e { + ; Message = Unable to Kill LBRYKiller.ahk + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + Return + } + else, { ; if attempt number 1 + Process, Close, LBRY.exe ; terminate LBRY if it's running + LBRYAttemptNumber := 2 + Message = Upload Failed (E#1980)`nDue to daemon not running.`nTrying to restart LBRY.exe and try the upload again. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Goto, LBRYVideoUpload + } + } + + ; Clipboard := UploadResult + ; Msgbox % "UploadResult: " UploadResult + +/*if(DevMode){ + Clipboard := UploadResult + Msgbox % "UploadResult: " UploadResult +} +*/ +; Create an object out of the API Return +LBRYJSONResult := JSON.Load(UploadResult) + +if(!InStr(UploadResult, "permanent_url")){ ; if no permanent_url is generated then API issue + LBRYAPIError := LBRYJSONResult.message + ; LBRYAPIError := GetLBRYAPIErrorFromString(UploadResult) + ; if the returned string does not have "permanent_url" in it, then upload failed + Message = Upload Error (E#6930)`nVideo Upload Failed due to API Issue. Please send errorlog to Yuriy. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +if(KillLBRYAfterUpload){ + try run, %LBRYKillerPath% + catch e { + Message = LBRYKiller not found. Unable to find File. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } +} + +; Transform the Upload Result json into the LBRY.tv link +; PermanentURL := GetPermanentLBRYURL(UploadResult) ; get permanentURL from the upload result json +LBRYPermanentURL := LBRYJSONResult.outputs[1].permanent_url +if(LBRYPermanentURL = ""){ + Message = Failed to grab permanent_url with json.ahk. Please send errorlog to Yuriy. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + Return +} + + +Message = Claim Was Successfully Submitted to lbrynet with: %LBRYPermanentURL% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + +; Message = LBRYPermanentURL: %LBRYPermanentURL% +; SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +if(CurrentSite = "LBRY Video"){ + IniWrite, %LBRYPermanentURL%, %VideoLinksIniFile%, Misc, LBRYVideoPermanentURL +} + +if(CurrentSite = "LBRY Audio"){ + IniWrite, %LBRYPermanentURL%, %VideoLinksIniFile%, Misc, LBRYAudioPermanentURL +} +Return + +; -------------------------------LBRY URL------------------------------- + +LBRYGetURL: +if(LBRYUploadType = "Video"){ + + CurrentSite := "LBRY Video" + ; IniWrite, %PermanentURL%, %VideoLinksIniFile%, URLs, LBRYVideoPermanentURL + IniRead, LBRYPermanentURL, %VideoLinksIniFile%, Misc, LBRYVideoPermanentURL, %A_Space% +} +if(LBRYUploadType = "Audio"){ + + CurrentSite := "LBRY Audio" + IniRead, LBRYPermanentURL, %VideoLinksIniFile%, Misc, LBRYAudioPermanentURL, %A_Space% + +} + +if(LBRYPermanentURL = ""){ + Message = Upload Skipped. LBRYPermanentURL is blank (Upload Failed due to some API issue) + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +; Message := "Waiting a couple of minutes for lbrynet blockchain to generate blockchain metadata for newest video" +Message = Waiting for LBRYNet to Generate LBRY URL +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +; sleep, 60000 ; 1 minute +; sleep, 300000 ; sleep for 5 minutes so LBRYNet blockchain has a chance to register the new video ; as recomended by LBRY Devs +; sleep, 360000 ; sleep for 6 minutes so LBRYNet blockchain has a chance to register the new video ; LBRY devs recommend 5 mins + + +LBRYResolveAPICommand = "%LBRYNetFilepath%" resolve %LBRYPermanentURL% ; create variable with the text that's needed for the API command +Message := "LBRYResolveAPICommand: " . LBRYResolveAPICommand ; Save the result to the errorlogging file +SaveOrPostProgress(Message:=Message,PostType:=",ErrorLoggingTextFile") + +; msgbox + +loop, 15 { + LBRYResolveResult := StdOutToVar(LBRYResolveAPICommand) ; Save API call to a variable + + if(A_index = 1 OR a_index = 10){ + Message := "LBRYResolveResult: " . LBRYResolveResult ; Save result to the errorlogging file + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile") + } + + if(InStr(LBRYResolveResult, "could not find claim") AND A_Index < 10) ; try 4 times to get the resolveURL, sometimes the blockchain is quite slow + { + ; @todo: Make it check every 2 minutes? + ; TooltipThis("Not Able to Grab URL from API. `nWaiting another 5 for blockchain to sync claim before trying again") + ; MessageNumber := A_index + 5 + + if(A_index < 5) + Message = Waiting for LBRYNet to Generate LBRY URL`nChecking Every 2 Minutes + if(A_index > 5) + Message = Still Waiting for LBRYNet to Generate LBRY URL`nLBRY Network is most likely congested.`nChecking Every 2 Minutes + + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + ; sleep, 300000 ; 5 minutes + sleep, 120000 ; 2 minute + + Continue + } + + if(InStr(LBRYResolveResult, "could not find claim") AND A_index = 15){ + Message = Failed to Grab URL from LBRY after 30 minutes. Either LBRY IS REALLY congested or there is a bug and the API commands were passed incorrectly. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + if(InStr(LBRYResolveResult, "canonical_url")) + Break +} + + +if(LBRYUploadType = "Video"){ + LBRYVideoURL := GetLBRYCanonicalURL(LBRYResolveResult) ; Transform the API resulting json into the LBRY.tv link + if(LBRYVideoURL = ""){ + Message = Failed to Grab LBRY URL from LBRYNet + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + ; DevModeMsgBox(LBRYVideoURL) + + Message = LBRYVideoURL from GetLBRYCanonicalURL: %LBRYVideoURL% + SaveOrPostProgress(Message, PostType:=",ErrorLoggingTextFile") + + OpenLBRYVideoURL := StrReplace(LBRYVideoURL, "https://lbry.tv", "https://open.lbry.com") + OpenLBRYVideoURL := StrReplace(OpenLBRYVideoURL, "#", ":") + + + OdyseeVideoURL := StrReplace(LBRYVideoURL, "https://lbry.tv", "https://odysee.com") + OdyseeVideoURL := StrReplace(OdyseeVideoURL, "#", ":") + + Message = Upload Complete: <%OpenLBRYVideoURL%> + <%OdyseeVideoURL%> + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") + + IniWrite, %OpenLBRYVideoURL%, %VideoLinksIniFile%, URLs, LBRYVideoURL + IniWrite, %OdyseeVideoURL%, %VideoLinksIniFile%, URLs, OdyseeVideoURL + +} +if(LBRYUploadType = "Audio"){ + LBRYAudioURL := GetLBRYCanonicalURL(LBRYResolveResult) ; Transform the API resulting json into the LBRY.tv link + if(LBRYAudioURL = ""){ + Message = Failed to Grab LBRY URL from LBRYNet + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + Message = LBRYAudioURL from GetLBRYCanonicalURL: %LBRYAudioURL% + SaveOrPostProgress(Message, PostType:=",ErrorLoggingTextFile") + + OpenLBRYAudioURL := StrReplace(LBRYAudioURL, "https://lbry.tv", "https://open.lbry.com") + OpenLBRYAudioURL := StrReplace(OpenLBRYAudioURL, "#", ":") + + OdyseeAudioURL := StrReplace(LBRYAudioURL, "https://lbry.tv", "https://odysee.com") + OdyseeAudioURL := StrReplace(OdyseeAudioURL, "#", ":") + + Message = Upload Complete: <%OpenLBRYAudioURL%> + <%OdyseeAudioURL%> + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,DiscordErrorLogging") + + IniWrite, %OpenLBRYAudioURL%, %VideoLinksIniFile%, URLs, LBRYAudioURL + IniWrite, %OdyseeAudioURL%, %VideoLinksIniFile%, URLs, OdyseeAudioURL +} + + +; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +; SaveDriverURL() +AddToTotalVideosUploadedCount() +Return +; -------------------------------/LBRY Video------------------------------- + + + + + +; -------------------------------LBRY Thumb---Odysee Thumb----------------------- +OdyseeVideoThumbUpload: +OdyseeAudioThumbUpload: + + +if(VideoThumbFilepath = "") { + Message = Thumbnail Upload Skipped. Thumbnail Filepath not provided + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + + +if(OdyseeUploadType = "Audio"){ + OdyseeURLToUploadThumbnailFor := OdyseeAudioURL + CurrentSite := "Odysee Audio" + +} +if(OdyseeUploadType = "Video"){ + OdyseeURLToUploadThumbnailFor := OdyseeVideoURL + CurrentSite := "Odysee Video" +} + + +; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + +if(OdyseeUploadType = "Audio" AND OdyseeAudioURL = "") +{ + Message = Audio Thumbnail Upload Skipped. OdyseeAudioURL is blank. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +if(OdyseeUploadType = "Video" AND OdyseeVideoURL = "") +{ + Message = Video Thumbnail Upload Skipped. OdyseeVideoURL is blank. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +; Msgbox % "LBRYAudioURL: " LBRYAudioURL +; Msgbox % "LBRYUploadType: " LBRYUploadType + + +; Msgbox % "OdyseeURLToUploadThumbnailFor: " OdyseeURLToUploadThumbnailFor + +/*Message = Uploading %OdyseeUploadType% Thumbnail through Odysee. `nNavigating to: %OdyseeURLToUploadThumbnailFor% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + +*/ +Message = Uploading Thumbnail through Odysee +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + +/*try driver.ExecuteScript("window.open();") ;Opens a new Window or tab (Depends on your Chrome Prefs) +catch e { + Message = Failed to Open New Window +} + +try driver.SwitchToNextWindow + +*/ + +URLAttempt := NavigateFromBaseURLTo(OdyseeURLToUploadThumbnailFor) +if(URLAttempt = "Failed"){ + Message =Unable to Navigate to Video Page (E#2816)`nInternet Connectivity issue or LBRY link not properly grabbed from API`nPlease upload Thumbnail manually at your earliest convenience. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} +driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + +TooltipThis("Waiting 10 Seconds for Video Page to Fully Load") +sleep, 10000 + + +/*; Check login status +Message = Checking Login Status +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +try LoginStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grabb innertext + +if(!LoginStatus){ + Message = Upload Failed (E#3985)`nLogin Cookies have expired. Please Re-login + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +*/ + +Message = Checking Login Status +SaveOrPostProgress(Message:=Message,PostType:="Tooltip") +try html := driver.pagesource ; save page's entire HTML to a variable +if(!InStr(HTML, "Edit")){ + Message = Upload Failed: Unable to Find Edit Button: Check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + + +Message = Clicking "Edit" on PageURL %OdyseeURLToUploadThumbnailFor% +SaveOrPostProgress(Message:=Message,PostType:="DiscordErrorLogging") + +; Click Edit button to check if logged in or not. +Xpath = //span[contains(text(),'Edit')] +loop, 3 { + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=5000) + if(Status){ + ; msgbox, click failed + Sleep, 60000 + try driver.executeScript("history.go(0)") ;refresh page + } + else, + Break +} + +if(Status){ + try CurrentPage := driver.url + Message = Unable to click "Edit" button. Most likely Reason is Video is Still Confirming OR Login Cookies Have Expired. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + + +/* +; Close the video preview floating window +Xpath = //button[@title='Close'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) + +*/ + +; "Use thumbnail upload tool" +TooltipThis("Selecting Thumbnail Upload Tool") +Xpath = //span[contains(text(),'Use thumbnail upload tool')] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Thumbnail Upload Failed (E#5617)`nUnable to click on "Use thumbnail upload tool" + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + +/* +try CurrentPage := driver.url +Message = Trying to Click Browse for Thumbnail Button on Page: %CurrentPage% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +*/ +/* +Xpath = /html/body/div/div/div[1]/main/div/div/section[2]/div/div/fieldset-section/input-submit/button/span/span +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Failed to Click "Browse" button with Direct Xpath to input thumbnail filepath. Trying with Relative + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + +} + +*/ + +/*; Select Use Thumbnail upload tool button +Xpath = //span[contains(text(),'Use thumbnail upload tool')] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Failed to click "Use Thumbanil Upload Tool" + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +} + +*/ +/* +Xpath = //div[@class='card__main-actions']//div//span[@class='button__label'][normalize-space()='Browse'] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Failed to click "Browse" button using relative and direct Xpath + + Xpath = //div[@class='card__main-actions']//div//button[@aria-label='Browse'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) + if(Status){ + Message = Failed to click "Browse" button using Relative Xpath of parent element as well + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } +} + +*/ + + +/* +Message = Trying to select thumbnail to upload +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +*/ + +/* +Status := InputFilePathIntoOpenWindow(VideoThumbFilepath) +if(Status) +{ + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + +*/ + +Xpath = //input[@accept='.png, .jpg, .jpeg, .gif'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) +if(Status){ + Message = Failed to Upload Thumbnail Image + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + ; Return +} +; try driver.FindElementByXPath(Xpath).SendKeys(VideoThumbFilepath) + + +; "Upload thumbnail" popup +; Confirmation Upload Popup - popup box +Xpath = //span[contains(text(),'Upload')] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000) +if(Status){ + Message = Thumbnail Upload Failed (E#2866)`nUnable to click upload confirmation button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} +/* +Xpath = /html/body/div[4]/div/div/div/button[1]/span/span +loop, 15 { + if(A_index = 15){ + Message = Thumbnail Upload Failed (E#2866)`nUnable to click upload confirmation button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Break + } + try driver.FindElementByXPath(Xpath).click() ;click on confirmaiton button + catch e { + Sleep, 1000 + Continue + } + Break +} + +*/ +/*; "Upload Complete" Text +Xpath = /html/body/div/div/div[1]/main/div/div/section[2]/div/div/div/div[2]/p +Loop, 15 { + if(A_index = 15){ + Message = Thumbnail Upload Failed (E#5580)`nUnable to find upload confirmation text on page. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Break + } + try UploadStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text + if(!InStr(UploadStatus, "Complete")) + { + sleep, 2000 + Continue + } + Break +} +*/ + +; sleep, 5000 ; sleep 5 seconds for everything to catch up. + +Message = Waiting for Thumbnail to Finish Uploading +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") +sleep, 5000 + +; Hit the save button +Xpath = //button[@class='button button--primary'] ; Save button popup +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=5000) +if(Status = Failed){ +/* Message = Failed to click last "Save" button. Please click it to finalize the upload. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + */ +} + +sleep, 5000 + +; Click off the confirmation popup and Check the "Skip Preview and Confirmation" checkbox +; xpath = //label[normalize-space()='Skip preview and confirmation'] +; try SkipPreviewCheck := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grabb innertext + +; if(SkipPreviewCheck != ""){ + ; Check skip preview checkbox so the box doesn't pop up again + + TooltipThis("Checking for Confirmation Popup") + xpath = //label[normalize-space()='Skip preview and confirmation'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + + Message = Unchecked "Confirm Edit" on each video Checkbox + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + ; msgbox ? + + ; Save Button + Xpath = //button[@aria-label='Save'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=1,SleepLength:=1000) + ; } + + + Message = Thumbnail Uploaded Successfully + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + if(OdyseeUploadType = "Video") + IniWrite, Successful, %VideoLinksIniFile%, Misc, OdyseeVideoThumb + if(OdyseeUploadType = "Audio") + IniWrite, Successful, %VideoLinksIniFile%, Misc, OdyseeAudioThumb + + ; TakeScreenshotOfPage(ScreenShotSavePath) + + Return + + + ; ---------------------/LBRY Thumb--------/Odysee Thumb----------------------- + + + + + + ; -------------------------------Rumble------------------------------- + RumbleUpload: + CurrentSite := "Rumble" + SaveOrPostProgress(Message:="Starting Upload",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + URLAttempt := NavigateFromBaseURLTo("https://rumble.com/upload.php") + if(URLAttempt) + Return + try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + +/* +; "Select Video to Upload" Button +Xpath = /html/body/main/div/div/div/section/form[1]/div/div[1] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) +if(Status){ + Message =Upload Skipped (E#6044)`nLogin Cookies have expired. Please Re-login + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + + +Status := InputFilePathIntoOpenWindow(VideoFilepath) +if(Status) +{ + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return +} + + +*/ + +Loop, 2 { + Xpath = //input[@name='Filedata'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) + if(Status){ + Message = Trying to Log Back In + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + + Xpath = //button[normalize-space()='Sign in'] + Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) + sleep, 5000 + Continue + } +} +; Input Title +try driver.findElementsByName("title").item[1].SendKeys(VideoTitle) ;selects element based on Name and sends variable to it. +catch e { + Message = Video Upload Failed, Please Check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} +; Input Description +Loop, 5 { ; Attempt to input video description a couple of times + TooltipThis("Inputting Description `nAttempt Number: " A_index) + + status := js_SendAndCheckWithID(Element:="description",ValueToCheck:="value",SleepLength:=3000,JSStringText:=JSVideoDescription) + if(!Status) + Break + +/* if(A_index = 5){ + Clipboard := VideoDescription + Message = Unable to Input Video Description`nDescription copied to clipboard, please paste it in at your earliest convenience. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + js = document.getElementsByName('description')[1].value = "%JSVideoDescription%"; ; Send content through javascript (Great for getting around emoji chrome limitaitons) + try driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + + try Description := driver.findElementsByName("description").item[2].Attribute("value") ;XPath: ID=site-title & span tag + if(Description != "") + Break + sleep, 2000 + */ +} + + + + +; sleep, 5000 + + +Message = Selecting "Freedomain" Channel +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +try driver.findElementsByID("channelId").item[1].click() + +sleep, 500 +; //option[@value='762377'] +Xpath = //option[@value='294021'] +try driver.FindElementByXPath(Xpath).click() +catch e { + Message = Failed to click on Channel using %ChannelIDNumber%.`nPlease send ErrorLog to Yuriy. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +} +; sleep, 2000 + + + +; Input Tags +Message = Inputting Tags +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +driver.findElementsByName("tags").item[1].SendKeys(VideoTags) ;selects element based on Name and sends variable to it. + + + +; Custom Thumbnail +if(VideoThumbFilepath != "") { + TooltipThis("Uploading Thumbnail") + Xpath = //input[@name='customThumb'] + Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoThumbFilepath) + if(Status){ + Message = Failed to Upload Thumbanil + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + } + + + ; @todo: Add a check to see if progress gets stuck + ; Check Upload Percentage + TooltipThis("Waiting for Video to Finish Uploading`nChecking Progress Every 5 Seconds") + Loop, %Number_of_loops_to_Check_Upload_status% { + sleep, %Time_Between_Loops_Upload_Status% + + jscheck = return document.getElementsByClassName('num_percent')[0].textContent; + try RumbleUploadPercent := driver.executeScript(jsCheck) + + ; try RumbleUploadPercent := driver.findelementbyxpath(Xpath).Attribute("textContent") + RumbleUploadPercent := StrSplit(RumbleUploadPercent, " ") + RumbleUploadPercent := RumbleUploadPercent[1] + + if(InStr(RumbleUploadPercent, "100%")) ; once variable contains 100%, then we can break out of loop and continue + Break + + + Status := Check_For_Stuck_Video_Upload(A_index, RumbleUploadPercent) + if(Status = "Failed") + Return + ; if(HasVal(Array_Index_Num_of_Upload_StatusChecks, A_index)) { ; 30 minutes and 60 minutes - send a notification message + ; Message = Upload Progress: %RumbleUploadPercent% + ; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") + ; } + + } + + ; Msgbox % "RumbleUploadPercent: " RumbleUploadPercent + + ; Click on one of the video thumbnail options first + ; Seems to be a bug on rumble, in order to be able to select a custom thumb through js, gotta select on of the generated ones first. + ; Xpath = /html/body/main/div/div/div/section/form[1]/div/div[2]/div[3]/a[2] ; thumbnail option #3 + ; try driver.FindElementByXPath(Xpath).click() ;Clicks on Xpath based on variable. + + + + +/* + js = document.getElementById('customThumb').click(); + driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + Status := InputFilePathIntoOpenWindow(VideoThumbFilepath) + if(Status) + { + Message = Upload Failed:`nUnable to Find "Open File" window to input filepath into + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + + */ + + +} + +try UploadPageURL := driver.URL + +; Submit Button +js = document.getElementById('submitForm').click(); +try driver.executeScript(js) ; + + +driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + +; Select Rumble Only Licensing +js = document.getElementsByClassName('greenLink mRight last')[0].click(); ; Send content through javascript (Great for getting around emoji chrome limitaitons) +try driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + +; Check off condition 1 +js = document.getElementById("crights").click() +try driver.executeScript(js) + +; Check off condition 2 +js = document.getElementById("cterms").click() +try driver.executeScript(js) + +; Click the Submit Button +js = document.getElementById("submitForm2").click() +try driver.executeScript(js) + + +; Loop until able to grab the direct link from the result page. +Loop, 24 { + TooltipThis("Waiting for Result Page to load to grab Video URL") + Sleep, 5000 + + js = return document.getElementById("error_files_2").textContent; + RumbleError := driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + if(RumbleError != "") { + Message = Rumble Upload Failed due to:`n%RumbleError% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } + + js = return document.getElementById('direct').value; + try RumbleURL := driver.executeScript(js) ;Executes a Javascript on the webpage, mostly used for buttons. + +/* try RumbleURL := driver.findElementsByID("direct").item[1].Attribute("value") ;grab Direct Link from the result page + catch e { ; if not able to grab it, then sleep for 5 seconds and then loop again + Continue + } + */ + if(RumbleURL != ""){ ; If URL is grabbed from result page, then kick out of loop + Break + } + if(A_Index = 10) ; if looped for 5 minutes and still no URL grabbed + { ; @todo: add error check if submit button clicked and error appears + + Xpath = /html/body/main/div/div/div/section/form[2]/div/div[9] ; grab inner content of where error usually appears. + try RumbleUploadError := driver.findelementbyxpath(Xpath).Attribute("innerText") ; Grabb innertext + ; Msgbox % "UseThumbUploadToolTextExist: " UseThumbUploadToolTextExist + + + Message = Upload Error (E#1341)`nVideo Uploaded but not able to be finalized.`nPlease fix the issue and click the final submit button. `nError: %RumbleUploadError% + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return + } +} + +IniWrite, %RumbleURL%, %VideoLinksIniFile%, URLs, RumbleURL + +Message = Upload Complete: %RumbleURL% +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +SaveDriverURL() +AddToTotalVideosUploadedCount() +; TakeScreenshotOfPage(ScreenShotSavePath) + +Return + +; -------------------------------/Rumble------------------------------- + + +;---Facebook--- +;------------------------------------------------ +FacebookUpload: +CurrentSite := "Facebook" +SaveOrPostProgress(Message:="Starting Upload",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +URLAttempt := NavigateFromBaseURLTo("https://www.facebook.com/") +if(URLAttempt) +Return +try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding + + +; Create a description for Facebook +SplitText = Free Documentaries: +FacebookDescription := StrSplit(VideoDescription, SplitText) +FacebookDescription := FacebookDescription[1] +FacebookTitleAndDescription := VideoTitle . "`n`n" . FacebookDescription +JSFacebookTitleAndDescription := FormatTextToJSText(FacebookTitleAndDescription) + + +Message = Calculating Video Length +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + +try Obj := Filexpro(VideoFilepath,, + , "Length" + , "Size" ) +VideoFilesize := obj["Size"] +VideoLength := obj["Length"] + +; Msgbox % "VideoLength: " VideoLength + +VideoLengthArray := StrSplit(VideoLength, ":") +VideoLengthInMinutes := (VideoLengthArray[1] * 60) + VideoLengthArray[2] +; Msgbox % "VideoLengthInMinutes: " VideoLengthInMinutes + +if(VideoLengthInMinutes >= 240){ + Message = Skipped: Longer than 240 Minutes + IniWrite, %Message%, %VideoLinksIniFile%, URLs, FacebookURL + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + + +; Upload Video +Xpath = //div[@aria-label='Create a post']//div//input[@type='file'] +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath) +if(Status){ + Message =Post Failed: Check Login Status + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + +; +Message = Waiting 15 Seconds for Video Preview to Load +SaveOrPostProgress(Message:=Message,PostType:="Tooltip") +sleep, 15000 + +Xpath = //div[@data-block='true']//div +Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=3,SleepLength:=2000,StringTextContent:=FacebookTitleAndDescription) +if(Status){ + Message = Failed to Input Video Description + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} +; msgbox + +; Click submit button +xpath = //div[@aria-label='Post']//div//div//div//span[contains(text(),'Post')] +Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000) +if(Status){ + Message = Failed to click "Post" button + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + SaveDriverURLOFErrorPage() + Return +} + + +IniWrite, Submitted, %VideoLinksIniFile%, URLs, FacebookURL + +Message = Upload Started Successfully +SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging") +SaveDriverURL() +AddToTotalVideosUploadedCount() +Return + +;---\Facebook--- +;------------------------------------------------ + + +; -------------------------------Functions------------------------------- +CheckLBRYProcess(){ + ; Check if LBRY Process exists + Process, Exist,LBRY.exe + if(ErrorLevel = 0) ; if doesn't exist + { + Message = Not Running. Starting up LBRY.exe + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + LBRYExeFilepath = C:\Program Files\LBRY\LBRY.exe + if(!FileExist(LBRYExeFilepath)){ + Message = Failed to Find LBRY.exe executable. LBRY not installed? + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + try run, "%LBRYExeFilepath%" + Message = Waiting 1 Minute for LBRY to start up + SaveOrPostProgress(Message:=Message,PostType:="Tooltip") + Sleep, 60000 ; 1 minute + + Process, Exist,LBRY.exe + if(ErrorLevel = 0) ; if doesn't exist + { + Message = Failed to Start LBRY.exe after 60 seconds of waiting + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + Return + } + WinMinimize, LBRY + } + Return +} + + +GetPermanentLBRYURL(UploadResult){ + SingleQuotationmark = " + + UploadResult := StrSplit(UploadResult, "`n") ; split results by new line + + ; Iterate through the array of the results + Loop % UploadResult.Length() { + PermanentURL := UploadResult[A_Index] + if(InStr(PermanentURL, "permanent_url")) + Break + } + + ; Starting Result: "permanent_url": "lbry://Test-Video-161-Numbered#c9ad9afe54c7178d6f870b59bbe129aef8efc3ff", + PermanentURL := StrSplit(PermanentURL, "lbry:") + PermanentURL := "lbry:" . PermanentURL[2] + PermanentURL := StrReplace(PermanentURL, ",", "") + PermanentURL := StrReplace(PermanentURL, SingleQuotationmark, "") + PermanentURL := StrReplace(PermanentURL, "`n", "") + PermanentURL := StrReplace(PermanentURL, "`r", "") + + ; End Result lbry://Test-Video-161-Numbered#c9ad9afe54c7178d6f870b59bbe129aef8efc3ff + Return PermanentURL +} + + +GetLBRYCanonicalURL(LBRYJSONObject){ ; input json string + ; ResolveURL := StrSplit(LBRYResolveAPICommand, "lbry://") + ; ResolveURL := "lbry://" . ResolveURL[2] + ; StrReplace(Haystack, SearchText [, ReplaceText, OutputVarCount, Limit := -1]) + LBRYPermanentURLJsonOBJ := StrReplace(LBRYJSONObject, LBRYPermanentURL, "LBRYPermanentURL") + ; clipboard := LBRYPermanentURLJsonOBJ + ; DevModeMsgBox(LBRYPermanentURLJsonOBJ) + + try parsed := JSON.Load(LBRYPermanentURLJsonOBJ) + try LBRYCanonicalURL := parsed.LBRYPermanentURL.canonical_url + + ; DevModeMsgBox(LBRYCanonicalURL) + + if(LBRYCanonicalURL = ""){ + Return "" ; return blank + } + + ; otherwise return the LBRY url + LBRYCanonicalURL := StrReplace(LBRYCanonicalURL, "lbry://", "https://lbry.tv/") + Return LBRYCanonicalURL +} + + +LBRYCMDTextReplacement(LBRYURLSlug){ + SingleQUote = " + LBRYURLSlug := StrReplace(LBRYURLSlug, " ", "_") ; replace all spaces with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, ":", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, ",", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "?", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "!", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "`;", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "/", "_") ; replace all colons with dashes + ; LBRYURLSlug := StrReplace(LBRYURLSlug, "?", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "<", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, ">", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, SingleQUote, "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "'", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "=", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, ";", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, ")", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "(", "") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "___", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "__", "_") ; replace all colons with dashes + LBRYURLSlug := StrReplace(LBRYURLSlug, "__", "_") ; replace all colons with dashes + Return LBRYURLSlug +} + +GetLBRYAPIErrorFromString(UploadResult){ + UploadResultArray := StrSplit(UploadResult, "message") + LBRYAPIError := UploadResultArray[2] + ; LBRYAPIErrorStrLen := StrLen(LBRYAPIError) + + ; LBRYAPIErrorStrToTrim := LBRYAPIErrorStrLen - 3 + ; Msgbox % "LBRYAPIErrorStrToTrim: " LBRYAPIErrorStrToTrim + LBRYAPIError := SubStr(LBRYAPIError, 4) + LBRYAPIError := StrReplace(LBRYAPIError, "}", "") + + + ; Msgbox % "LBRYAPIError: " LBRYAPIError + Return LBRYAPIError + +} + + +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 + + + + SaveDriverURL() + AddToTotalVideosUploadedCount(){ + IniRead, TotalVideosUploaded, %SettingsIniFilepath%, General, TotalVideosUploaded, %A_Space% + TotalVideosUploaded += 1 + IniWrite, %TotalVideosUploaded%, %SettingsIniFilepath%, General, TotalVideosUploaded + } + + + + 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 + } + } + + + + 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 \ No newline at end of file diff --git a/Lib/Auto Update Selenium Chromedriver.ahk b/Lib/Auto Update Selenium Chromedriver.ahk new file mode 100644 index 0000000..1f27641 --- /dev/null +++ b/Lib/Auto Update Selenium Chromedriver.ahk @@ -0,0 +1,174 @@ +; ENVIRONMENT +;------------------------------------------------ +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +;#Warn ; Enable warnings to assist with detecting common errors. +;DetectHiddenWindows, On +#SingleInstance, Force +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +;SetKeyDelay, 500 +CoordMode, ToolTip, Screen +CoordMode, Mouse, Screen +;#NoTrayIcon +;Menu, Tray, Icon, ..\Icons\ICONNAMEHERE + +; Notes/Extra Info/#Includes +;------------------------------------------------ +; https://old.reddit.com/r/PowerShell/comments/nksoh1/keeping_selenium_chromedriver_uptodate/ + + +; VARIABLES +;------------------------------------------------ + + + +; MAIN SCRIPT +;------------------------------------------------ +#Include C:\Users\%A_UserName%\Documents\Autohotkey\Lib\RunCMD.ahk +#include C:\Users\%A_username%\Documents\Autohotkey\Lib\URLDownloadToVar.ahk + + + +; MAIN SCRIPT +;------------------------------------------------ +; MsgBox A_IsAdmin: %A_IsAdmin%`nCommand line: %full_command_line% + + +; run as admin +full_command_line := DllCall("GetCommandLine", "str") +; Msgbox % "full_command_line: " full_command_line +if not (A_IsAdmin or RegExMatch(full_command_line, " /restart(?!\S)")) +{ + try + { + if A_IsCompiled + Run *RunAs "%A_ScriptFullPath%" /restart + else + Run *RunAs "%A_AhkPath%" /restart "%A_ScriptFullPath%" + } + ; ExitApp +} + + +if(!A_IsAdmin){ + MsgBox 0x40040, Information, Failed to get Administrator Authentication which is only needed for copying the chromedriver.exe file into /Program Files/SeleniumBasic. `n`nPress OK to continue and to just download the chromedriver.exe file to the current folder. `n(You will have to move it manually into /Program Files/Selenium Basic) +} + + +ToolTip, Downloading Chromedriver for your installed chrome version, 850, 0 + +; ChromeFilepath = C:\Program Files\Chromium\Application\chrome.exe + +IniRead, ChromeFilepath, C:\Users\%A_username%\Documents\Autohotkey\Lib\ScriptSettings.ini, Selenium, %A_Computername%, %A_Space% +; Msgbox % "ChromeFilepath: " ChromeFilepath + +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 + } + else, { + IniRead, ChromeFilepath, C:\Users\%A_username%\Documents\Autohotkey\Lib\ScriptSettings.ini, Selenium, %A_Computername%, "Filepath not found" + if(!FileExist(ChromeFilepath)){ + msgbox, Chrome.exe not found. Exiting + ExitApp + } + } +} +; Msgbox % "ChromeFilepath: " ChromeFilepath + + + /* IniRead, ChromeFilepath, C:\Users\%A_username%\Documents\Autohotkey\Lib\ScriptSettings.ini, Selenium, %A_Computername%, "Filepath not found" + if(!FileExist(ChromeFilepath)){ + msgbox, Chrome.exe not found. Exiting + ExitApp + } + + */ + ; ChromeFilepath = C:\Users\%A_username%\Downloads\chromedriver.exe + + ; VARIABLES + ;------------------------------------------------ + ChromeDriverZipSavePath = C:\Users\%A_username%\Downloads\chromedriver.zip + ChromeDriverExeExtractParentFolderPath = C:\Users\%A_username%\Downloads\ + ChromeDriverExeExtractedFilepath = %ChromeDriverExeExtractParentFolderPath%chromedriver.exe + ChromeDriverFinalDestination = C:\Program Files\SeleniumBasic\chromedriver.exe + ; Msgbox % "ChromeFilepath: " ChromeFilepath + + ; Check Chrome Version + ; ChromeFilepath = C:\Program Files\Chromium\Application\chrome.exe + Command = powershell (Get-Item '%ChromeFilepath%').VersionInfo.ProductVersion + ; Command := "powershell (Get-Item 'C:\Program Files\Chromium\Application\chrome.exe').VersionInfo | Select-Object ProductVersion" + + Chromeversion := RunCMD(Command) + Chromeversion := SubStr(Chromeversion, 1, 2) + ; Msgbox % "Chromeversion: " Chromeversion + + ; Chromeversion := + + if(Chromeversion = ""){ + MsgBox 0x40040, Information, Failed to grab chrome version.`n`nMost Likely reason is that the chrome filepath is incorrect: `nGiven Chrome Filepath:`n%ChromeFilepath% + ExitApp + } + + ; Msgbox % "Chromeversion: " Chromeversion + + ; Query what the latest release chromedriver for the current chrome version is + URL = https://chromedriver.storage.googleapis.com/LATEST_RELEASE_%Chromeversion% + URLContents := URLDownloadToVar(URL) + + ; Msgbox % "URLContents: " URLContents + + ; Chromedriver is always saved in the following format: + url = https://chromedriver.storage.googleapis.com/%URLContents%/chromedriver_win32.zip + + ; Donwload chromedriver + UrlDownloadToFile, %url%, %ChromeDriverZipSavePath% + + ChromeDriverZipSavePath = '%ChromeDriverZipSavePath%' + ChromeDriverExeExtractPath = '%ChromeDriverExeExtractPath%' + + + ; Extract the downloaded zip file using powershell + Command = powershell Expand-Archive -LiteralPath %ChromeDriverZipSavePath% -DestinationPath %ChromeDriverExeExtractParentFolderPath% -Force + ; Clipboard := Command + ; Msgbox % "Command: " Command + ; Command := "powershell (Get-Item 'C:\Program Files\Chromium\Application\chrome.exe').VersionInfo.ProductVersion" + ; Command := "powershell (Get-Item 'C:\Program Files\Chromium\Application\chrome.exe').VersionInfo | Select-Object ProductVersion" + + PowerShellReturn := RunCMD(Command) + Msgbox % "PowerShellReturn: " PowerShellReturn + + if(!FileExist(ChromeDriverExeExtractedFilepath)){ + Msgbox, Extracting failed for some reason. `nYou can find the downloaded .zip file in %ChromeDriverZipSavePath%`n`nClick OK to Exit + ExitApp + } + + if(!A_IsAdmin){ + Msgbox, Chromedriver was successfully downloaded to:`n %ChromeDriverExeExtractedFilepath%. `n`nPlease copy it over manually to:`n %ChromeDriverFinalDestination%`n`nClick OK to Exit + ExitApp + } + + ; If run as admin, copy over to Program FIles + if(A_IsAdmin){ + FileMove, %ChromeDriverExeExtractedFilepath%, %ChromeDriverFinalDestination%, 1 + if(ErrorLevel){ + msgbox, Failed to move chromedriver.exe to /Program Files/SeleniumBasic. `n`nMost Likely reason is that ChromeDriver is currently running in the background because of a recently run script. `nPlease Copy it over manually`n`nClick OK to exit. + ExitApp + } + } + + msgbox, Chromedriver.exe successfully copied to: `n%ChromeDriverFinalDestination% `n`nClick OK to Exit. + + + ExitApp + + + + + + + ; Functions +;------------------------------------------------ \ No newline at end of file diff --git a/Lib/ChromeAutomationFunctions.ahk b/Lib/ChromeAutomationFunctions.ahk new file mode 100644 index 0000000..07fc606 --- /dev/null +++ b/Lib/ChromeAutomationFunctions.ahk @@ -0,0 +1,216 @@ +; 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" +} + + + +; 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--- +;------------------------------------------------ diff --git a/Lib/Json.ahk b/Lib/Json.ahk new file mode 100644 index 0000000..e5b3d19 --- /dev/null +++ b/Lib/Json.ahk @@ -0,0 +1,374 @@ +/** + * Lib: JSON.ahk + * JSON lib for AutoHotkey. + * Version: + * v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)] + * License: + * WTFPL [http://wtfpl.net/] + * Requirements: + * Latest version of AutoHotkey (v1.1+ or v2.0-a+) + * Installation: + * Use #Include JSON.ahk or copy into a function library folder and then + * use #Include + * Links: + * GitHub: - https://github.com/cocobelgica/AutoHotkey-JSON + * Forum Topic - http://goo.gl/r0zI8t + * Email: - cocobelgica gmail com + */ + + +/** + * Class: JSON + * The JSON object contains methods for parsing JSON and converting values + * to JSON. Callable - NO; Instantiable - YES; Subclassable - YES; + * Nestable(via #Include) - NO. + * Methods: + * Load() - see relevant documentation before method definition header + * Dump() - see relevant documentation before method definition header + */ +class JSON +{ + /** + * Method: Load + * Parses a JSON string into an AHK value + * Syntax: + * value := JSON.Load( text [, reviver ] ) + * Parameter(s): + * value [retval] - parsed value + * text [in, ByRef] - JSON formatted string + * reviver [in, opt] - function object, similar to JavaScript's + * JSON.parse() 'reviver' parameter + */ + class Load extends JSON.Functor + { + Call(self, ByRef text, reviver:="") + { + this.rev := IsObject(reviver) ? reviver : false + ; Object keys(and array indices) are temporarily stored in arrays so that + ; we can enumerate them in the order they appear in the document/text instead + ; of alphabetically. Skip if no reviver function is specified. + this.keys := this.rev ? {} : false + + static quot := Chr(34), bashq := "\" . quot + , json_value := quot . "{[01234567890-tfn" + , json_value_or_array_closing := quot . "{[]01234567890-tfn" + , object_key_or_object_closing := quot . "}" + + key := "" + is_key := false + root := {} + stack := [root] + next := json_value + pos := 0 + + while ((ch := SubStr(text, ++pos, 1)) != "") { + if InStr(" `t`r`n", ch) + continue + if !InStr(next, ch, 1) + this.ParseError(next, text, pos) + + holder := stack[1] + is_array := holder.IsArray + + if InStr(",:", ch) { + next := (is_key := !is_array && ch == ",") ? quot : json_value + + } else if InStr("}]", ch) { + ObjRemoveAt(stack, 1) + next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}" + + } else { + if InStr("{[", ch) { + ; Check if Array() is overridden and if its return value has + ; the 'IsArray' property. If so, Array() will be called normally, + ; otherwise, use a custom base object for arrays + static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0 + + ; sacrifice readability for minor(actually negligible) performance gain + (ch == "{") + ? ( is_key := true + , value := {} + , next := object_key_or_object_closing ) + ; ch == "[" + : ( value := json_array ? new json_array : [] + , next := json_value_or_array_closing ) + + ObjInsertAt(stack, 1, value) + + if (this.keys) + this.keys[value] := [] + + } else { + if (ch == quot) { + i := pos + while (i := InStr(text, quot,, i+1)) { + value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c") + + static tail := A_AhkVersion<"2" ? 0 : -1 + if (SubStr(value, tail) != "\") + break + } + + if (!i) + this.ParseError("'", text, pos) + + value := StrReplace(value, "\/", "/") + , value := StrReplace(value, bashq, quot) + , value := StrReplace(value, "\b", "`b") + , value := StrReplace(value, "\f", "`f") + , value := StrReplace(value, "\n", "`n") + , value := StrReplace(value, "\r", "`r") + , value := StrReplace(value, "\t", "`t") + + pos := i ; update pos + + i := 0 + while (i := InStr(value, "\",, i+1)) { + if !(SubStr(value, i+1, 1) == "u") + this.ParseError("\", text, pos - StrLen(SubStr(value, i+1))) + + uffff := Abs("0x" . SubStr(value, i+2, 4)) + if (A_IsUnicode || uffff < 0x100) + value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6) + } + + if (is_key) { + key := value, next := ":" + continue + } + + } else { + value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos) + + static number := "number", integer :="integer" + if value is %number% + { + if value is %integer% + value += 0 + } + else if (value == "true" || value == "false") + value := %value% + 0 + else if (value == "null") + value := "" + else + ; we can do more here to pinpoint the actual culprit + ; but that's just too much extra work. + this.ParseError(next, text, pos, i) + + pos += i-1 + } + + next := holder==root ? "" : is_array ? ",]" : ",}" + } ; If InStr("{[", ch) { ... } else + + is_array? key := ObjPush(holder, value) : holder[key] := value + + if (this.keys && this.keys.HasKey(holder)) + this.keys[holder].Push(key) + } + + } ; while ( ... ) + + return this.rev ? this.Walk(root, "") : root[""] + } + + ParseError(expect, ByRef text, pos, len:=1) + { + static quot := Chr(34), qurly := quot . "}" + + line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length() + col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1)) + msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}" + , (expect == "") ? "Extra data" + : (expect == "'") ? "Unterminated string starting at" + : (expect == "\") ? "Invalid \escape" + : (expect == ":") ? "Expecting ':' delimiter" + : (expect == quot) ? "Expecting object key enclosed in double quotes" + : (expect == qurly) ? "Expecting object key enclosed in double quotes or object closing '}'" + : (expect == ",}") ? "Expecting ',' delimiter or object closing '}'" + : (expect == ",]") ? "Expecting ',' delimiter or array closing ']'" + : InStr(expect, "]") ? "Expecting JSON value or array closing ']'" + : "Expecting JSON value(string, number, true, false, null, object or array)" + , line, col, pos) + + static offset := A_AhkVersion<"2" ? -3 : -4 + throw Exception(msg, offset, SubStr(text, pos, len)) + } + + Walk(holder, key) + { + value := holder[key] + if IsObject(value) { + for i, k in this.keys[value] { + ; check if ObjHasKey(value, k) ?? + v := this.Walk(value, k) + if (v != JSON.Undefined) + value[k] := v + else + ObjDelete(value, k) + } + } + + return this.rev.Call(holder, key, value) + } + } + + /** + * Method: Dump + * Converts an AHK value into a JSON string + * Syntax: + * str := JSON.Dump( value [, replacer, space ] ) + * Parameter(s): + * str [retval] - JSON representation of an AHK value + * value [in] - any value(object, string, number) + * replacer [in, opt] - function object, similar to JavaScript's + * JSON.stringify() 'replacer' parameter + * space [in, opt] - similar to JavaScript's JSON.stringify() + * 'space' parameter + */ + class Dump extends JSON.Functor + { + Call(self, value, replacer:="", space:="") + { + this.rep := IsObject(replacer) ? replacer : "" + + this.gap := "" + if (space) { + static integer := "integer" + if space is %integer% + Loop, % ((n := Abs(space))>10 ? 10 : n) + this.gap .= " " + else + this.gap := SubStr(space, 1, 10) + + this.indent := "`n" + } + + return this.Str({"": value}, "") + } + + Str(holder, key) + { + value := holder[key] + + if (this.rep) + value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined) + + if IsObject(value) { + ; Check object type, skip serialization for other object types such as + ; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc. + static type := A_AhkVersion<"2" ? "" : Func("Type") + if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") { + if (this.gap) { + stepback := this.indent + this.indent .= this.gap + } + + is_array := value.IsArray + ; Array() is not overridden, rollback to old method of + ; identifying array-like objects. Due to the use of a for-loop + ; sparse arrays such as '[1,,3]' are detected as objects({}). + if (!is_array) { + for i in value + is_array := i == A_Index + until !is_array + } + + str := "" + if (is_array) { + Loop, % value.Length() { + if (this.gap) + str .= this.indent + + v := this.Str(value, A_Index) + str .= (v != "") ? v . "," : "null," + } + } else { + colon := this.gap ? ": " : ":" + for k in value { + v := this.Str(value, k) + if (v != "") { + if (this.gap) + str .= this.indent + + str .= this.Quote(k) . colon . v . "," + } + } + } + + if (str != "") { + str := RTrim(str, ",") + if (this.gap) + str .= stepback + } + + if (this.gap) + this.indent := stepback + + return is_array ? "[" . str . "]" : "{" . str . "}" + } + + } else ; is_number ? value : "value" + return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value) + } + + Quote(string) + { + static quot := Chr(34), bashq := "\" . quot + + if (string != "") { + string := StrReplace(string, "\", "\\") + ; , string := StrReplace(string, "/", "\/") ; optional in ECMAScript + , string := StrReplace(string, quot, bashq) + , string := StrReplace(string, "`b", "\b") + , string := StrReplace(string, "`f", "\f") + , string := StrReplace(string, "`n", "\n") + , string := StrReplace(string, "`r", "\r") + , string := StrReplace(string, "`t", "\t") + + static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]" + while RegExMatch(string, rx_escapable, m) + string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value))) + } + + return quot . string . quot + } + } + + /** + * Property: Undefined + * Proxy for 'undefined' type + * Syntax: + * undefined := JSON.Undefined + * Remarks: + * For use with reviver and replacer functions since AutoHotkey does not + * have an 'undefined' type. Returning blank("") or 0 won't work since these + * can't be distnguished from actual JSON values. This leaves us with objects. + * Replacer() - the caller may return a non-serializable AHK objects such as + * ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to + * mimic the behavior of returning 'undefined' in JavaScript but for the sake + * of code readability and convenience, it's better to do 'return JSON.Undefined'. + * Internally, the property returns a ComObject with the variant type of VT_EMPTY. + */ + Undefined[] + { + get { + static empty := {}, vt_empty := ComObject(0, &empty, 1) + return vt_empty + } + } + + class Functor + { + __Call(method, ByRef arg, args*) + { + ; When casting to Call(), use a new instance of the "function object" + ; so as to avoid directly storing the properties(used across sub-methods) + ; into the "function object" itself. + if IsObject(method) + return (new this).Call(method, arg, args*) + else if (method == "") + return (new this).Call(arg, args*) + } + } +} diff --git a/Lib/RunCMD.ahk b/Lib/RunCMD.ahk new file mode 100644 index 0000000..6ba4456 --- /dev/null +++ b/Lib/RunCMD.ahk @@ -0,0 +1,55 @@ + ; PowerShell +; https://www.autohotkey.com/boards/viewtopic.php?p=341237#p341237 + + + + + +; msgbox % RunCMD("ipconfig") + +RunCMD(CmdLine, WorkingDir:="", Codepage:="CP0", Fn:="RunCMD_Output") { ; RunCMD v0.94 +Local ; RunCMD v0.94 by SKAN on D34E/D37C @ autohotkey.com/boards/viewtopic.php?t=74647 +Global A_Args ; Based on StdOutToVar.ahk by Sean @ autohotkey.com/board/topic/15455-stdouttovar + + Fn := IsFunc(Fn) ? Func(Fn) : 0 +, DllCall("CreatePipe", "PtrP",hPipeR:=0, "PtrP",hPipeW:=0, "Ptr",0, "Int",0) +, DllCall("SetHandleInformation", "Ptr",hPipeW, "Int",1, "Int",1) +, DllCall("SetNamedPipeHandleState","Ptr",hPipeR, "UIntP",PIPE_NOWAIT:=1, "Ptr",0, "Ptr",0) + +, P8 := (A_PtrSize=8) +, VarSetCapacity(SI, P8 ? 104 : 68, 0) ; STARTUPINFO structure +, NumPut(P8 ? 104 : 68, SI) ; size of STARTUPINFO +, NumPut(STARTF_USESTDHANDLES:=0x100, SI, P8 ? 60 : 44,"UInt") ; dwFlags +, NumPut(hPipeW, SI, P8 ? 88 : 60) ; hStdOutput +, NumPut(hPipeW, SI, P8 ? 96 : 64) ; hStdError +, VarSetCapacity(PI, P8 ? 24 : 16) ; PROCESS_INFORMATION structure + + If not DllCall("CreateProcess", "Ptr",0, "Str",CmdLine, "Ptr",0, "Int",0, "Int",True + ,"Int",0x08000000 | DllCall("GetPriorityClass", "Ptr",-1, "UInt"), "Int",0 + ,"Ptr",WorkingDir ? &WorkingDir : 0, "Ptr",&SI, "Ptr",&PI) + Return Format("{1:}", "", ErrorLevel := -1 + ,DllCall("CloseHandle", "Ptr",hPipeW), DllCall("CloseHandle", "Ptr",hPipeR)) + + DllCall("CloseHandle", "Ptr",hPipeW) +, A_Args.RunCMD := { "PID": NumGet(PI, P8? 16 : 8, "UInt") } +, File := FileOpen(hPipeR, "h", Codepage) + +, LineNum := 1, sOutput := "" + While (A_Args.RunCMD.PID + DllCall("Sleep", "Int",0)) + and DllCall("PeekNamedPipe", "Ptr",hPipeR, "Ptr",0, "Int",0, "Ptr",0, "Ptr",0, "Ptr",0) + While A_Args.RunCMD.PID and (Line := File.ReadLine()) + sOutput .= Fn ? Fn.Call(Line, LineNum++) : Line + + A_Args.RunCMD.PID := 0 +, hProcess := NumGet(PI, 0) +, hThread := NumGet(PI, A_PtrSize) + +, DllCall("GetExitCodeProcess", "Ptr",hProcess, "PtrP",ExitCode:=0) +, DllCall("CloseHandle", "Ptr",hProcess) +, DllCall("CloseHandle", "Ptr",hThread) +, DllCall("CloseHandle", "Ptr",hPipeR) + +, ErrorLevel := ExitCode + +Return sOutput +} diff --git a/Lib/SChrome.ahk b/Lib/SChrome.ahk new file mode 100644 index 0000000..535dcc8 --- /dev/null +++ b/Lib/SChrome.ahk @@ -0,0 +1,54 @@ +; Written by AHK_User 2019-10-11 +; Special thanks to tmplinshi, CH HAN and Joe Glines +; https://www.autohotkey.com/boards/viewtopic.php?f=7&t=32323&p=296136&hilit=schrome_get#p296136 +;Driver := SChrome_Get("https://stackoverflow.com/questions/37088589/selenium-wont-open-a-new-url-in-a-new-tab-python-chrome/39353910#39353910",,"Tab") + +; Written by AHK_User 2019-10-11 +; Special thanks to tmplinshi, CH HAN and Joe Glines + +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 + { + While(WinExist("ahk_exe chrome.exe")) { + WinClose, ahk_exe chrome.exe + } + Process, WaitClose, chrome.exe + } + Else{ + Exit + } + } + } + + if(URL!="" or !winExist("ahk_class Chrome_WidgetWin_1")){ + ; run % "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --remote-debugging-port=" IP_Port_Nr ( winExist("ahk_class Chrome_WidgetWin_1") ? " --new-window " : " " ) URL + if(A_ComputerName = "WLatitude") + { + run, C:\Software\Chromium\chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" ; %URL% + ; sleep, 1000 + ; run, C:\Software\Chromium\chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" --new-window %URL% + } + else, + { + run, chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" %URL% + ; sleep, 1000 + ; run, chrome.exe --remote-debugging-port=%IP_Port_Nr% --profile-directory="%Profile%" --new-window %URL% + + } + } + + Driver := ComObjCreate("Selenium.ChromeDriver") + Driver.SetCapability("debuggerAddress", IP_Port) + Driver.Start() + return Driver +} \ No newline at end of file diff --git a/Lib/SharedFunctions.ahk b/Lib/SharedFunctions.ahk new file mode 100644 index 0000000..f21a3ea --- /dev/null +++ b/Lib/SharedFunctions.ahk @@ -0,0 +1,1521 @@ +;---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 + + + + +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 + + parsed := JSON.Load(data) + + UpdateVersionNumber := parsed.1.name + + if(ScriptVersion = UpdateVersionNumber OR 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") + ; 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 + ; DevModeMsgBox(TotalTabsFound) + + ; 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%`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 + + ; DevModeMsgBox(Title) + ; DevModeMsgBox(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 + ; / END OF 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, + } + + CheckCurrentTabForCurrentSite(){ + try CurrentTabURL := driver.url + + if(!InStr(CurrentTabURL, CurrentSite)){ + Message = Chromedriver failed to switch to %CurrentSite%. Please see errorlog for website it got stuck on. + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + return "Failed" + } + + + + + ; msgbox % InStr(CurrentTabURL,CurrentSite) + + } + + + ; -------------------------------NavigateFromBaseURLTo------------------------------- + NavigateFromBaseURLTo(URL, TabTitle := ""){ + 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 base url is not in tab array, create new tab and push url to array + if(!HasSubstringVal(DriverURLArray, URLBase)) + { + try CurrentTabTitle := driver.window.title + + ; if currently in new tab navigate to the site in the current tab + if(CurrentTabTitle = "New Tab"){ + 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" + } + } + return + } + else, { + try, run "%ChromeFilepath%" "%URL%" + DriverURLArray.Push(URL) ; Append an item to the array + NewTabCreated := 1 + ; sleep, 2000 + } + + + + } + + Message = Finding Tab + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile") + + TabFoundSuccessfully := + + NumberOfTabLoops := DriverURLArray.Length() + + ; loop through tabs to find matching tab + loop % NumberOfTabLoops { + try driver.SwitchToNextWindow() + + ; sleep, 1000 + ; msgbox, looping through tabs + try CurrentTabTitle := driver.window.title + try CurrentTabURL := driver.Url + + ; DevModeMsgBox(CurrentTabURL) + ; DevModeMsgBox(CurrentTabTitle) + + ; 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 + } + + + if(InStr(CurrentTabURL, URLBase)){ + Message = CurrentTabURL is %CurrentTabURL% and it contains %URLBase% + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile") + + ; msgbox, found it.`n%CurrentTabTitle% = %PageTitle%`n%CurrentTabURL% = %URLBase% + TabFoundSuccessfully := 1 + ; message = %CurrentTabTitle%: %PageTitle% + ; DevModeMsgBox(message) + ; msgbox %CurrentTabURL% = %URL% + Break + } + } + + ; if failed to switch to tab and a new tab was not created, then chrome failed to switch to the tab + ; this happens sometimes. most likely to a chromedriver bug or maybe tab being offloaded? + if(!TabFoundSuccessfully AND !NewTabCreated){ + ; @todo : not sure how to best solve this problem currently. It doesn't happen very often. + ; last time it happened was when there were only 2 chrome tabs open, gab + subscribestar. chrome was stuck on subscribestar page and wouldn't nextwindow() to gab + } + + ; Message = TabFoundSuccessfully: %TabFoundSuccessfully% + ; DevModeMsgBox(Message) + + 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 + } + } + } + + ; ; 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.Timeout := 1000 + Driver := ComObjCreate("Selenium.ChromeDriver") + Driver.SetCapability("debuggerAddress", IP_Port) + + SaveOrPostProgress(Message:="Trying to connect to Chrome.`nIf stuck here check for dialog popups in one of your tabs `nOR your ChromeDriver version`nClose chrome to break out of program being stuck.",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar") + + ; set selenium timeout to 1 second, instead of default 5 seconds + + + try Driver.Start() + catch e { + ShowSeleniumErrorMsgbox() + } + + return Driver + } + ; -------------------------------/SChrome_Get------------------------------- + + ShowSeleniumErrorMsgbox(){ + GetChromeVersionCommand = powershell (Get-Item '%ChromeFilepath%').VersionInfo.ProductVersion + Chromeversion := RunCMD(GetChromeVersionCommand) + ChromeVersion := StrReplace(ChromeVersion, "`n", "") + + Message = Failed to connect to Chrome + SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + +/* + ; check for alert popup + try alertText := driver.SwitchToAlert().Text + ; DevModeMsgBox(alertText) + if(alertText){ + Message = Alert Popup Text: %alertText% + SaveOrPostProgress(Message:=Message,PostType:="ErrorLoggingTextFile,ErrorSummaryVar") + SaveOrPostProgress(Message:="Chrome stuck on alert popup",PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging") + DevModeMsgBox("alert popup found") + } + + */ + + ; Msgbox % "alertText: " alertText + + ; 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 with your Last Post`nClick "ChromeDriver" to open up the ChromeDriver download page. `n`nClick "Instructions" to open up installation instructions in your default browser.`n`n Information:`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 + run, "%A_ScriptFullPath%" "LastPost" + ExitApp + ; open chromedriver site + } Else IfMsgBox Cancel, { + run, "https://git.zinchuk.xyz/yuriy/Freedomain-Social-Media-Poster#installation" + run, "%A_ScriptFullPath%" "LastPost" + 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() + + } + +} diff --git a/Lib/StdOutToVar.ahk b/Lib/StdOutToVar.ahk new file mode 100644 index 0000000..5525d35 --- /dev/null +++ b/Lib/StdOutToVar.ahk @@ -0,0 +1,56 @@ +; Edited by Masonjar13 to be compatible with 32 and 64-bit (2015) + +;msgbox % StdOutToVar("ipconfig") + +StdOutToVar( sCmd ) { ; GAHK32 ; Modified Version : SKAN 05-Jul-2013 http://goo.gl/j8XJXY + ; msgbox, getting stdout + Static StrGet := "StrGet" ; Original Author : Sean 20-Feb-2007 http://goo.gl/mxCdn + + DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 ) + DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 ) + + if(a_ptrSize=8){ + VarSetCapacity( STARTUPINFO, 104, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 + NumPut( 104, STARTUPINFO, 0 ) ; cbSize + NumPut( 0x100, STARTUPINFO, 60 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 + NumPut( hPipeWrite, STARTUPINFO, 88 ) ; hStdOutput + NumPut( hPipeWrite, STARTUPINFO, 96 ) ; hStdError + VarSetCapacity( PROCESS_INFORMATION, 32 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI + }else{ + VarSetCapacity( STARTUPINFO, 68, 0 ) ; STARTUPINFO ; http://goo.gl/fZf24 + NumPut( 68, STARTUPINFO, 0 ) ; cbSize + NumPut( 0x100, STARTUPINFO, 44 ) ; dwFlags => STARTF_USESTDHANDLES = 0x100 + NumPut( hPipeWrite, STARTUPINFO, 60 ) ; hStdOutput + NumPut( hPipeWrite, STARTUPINFO, 64 ) ; hStdError + VarSetCapacity( PROCESS_INFORMATION, 16 ) ; PROCESS_INFORMATION ; http://goo.gl/b9BaI + } + If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ; http://goo.gl/USC5a + , UInt,1, UInt,0x08000000, UInt,0, UInt,0 + , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) + Return "" + , DllCall( "CloseHandle", UInt,hPipeWrite ) + , DllCall( "CloseHandle", UInt,hPipeRead ) + , DllCall( "SetLastError", Int,-1 ) + + hProcess := NumGet( PROCESS_INFORMATION, 0 ) + if(a_is64bitOS) + hThread := NumGet( PROCESS_INFORMATION, 8 ) + else + hThread := NumGet( PROCESS_INFORMATION, 4 ) + + DllCall( "CloseHandle", UInt,hPipeWrite ) + + AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" ) ; A_IsClassic + VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 + + While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 ) + sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) + ? Buffer : %StrGet%( &Buffer, nSz, "CP850" ) + + DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode ) + DllCall( "CloseHandle", UInt,hProcess ) + DllCall( "CloseHandle", UInt,hThread ) + DllCall( "CloseHandle", UInt,hPipeRead ) + +Return sOutput, DllCall( "SetLastError", UInt,ExitCode ) +} diff --git a/Lib/TestSeleniumInstall.ahk b/Lib/TestSeleniumInstall.ahk new file mode 100644 index 0000000..f745765 --- /dev/null +++ b/Lib/TestSeleniumInstall.ahk @@ -0,0 +1,57 @@ +;---ENVIRONMENT--------------------------------------------------------------------- +#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. +;#Warn ; Enable warnings to assist with detecting common errors. +;DetectHiddenWindows, On +#SingleInstance, Force +SendMode Input ; Recommended for new scripts due to its superior speed and reliability. +SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. +;SetKeyDelay, 500 +CoordMode, ToolTip, Screen +CoordMode, Mouse, Screen +;#NoTrayIcon +;Menu, Tray, Icon, ..\Icons\ICONNAMEHERE + +;---Notes/Extra Info/#Includes------------------------------------------------------ +#include %A_ScriptDir%/Lib/Schrome.ahk ; used for chrome debugging mode connection + + +;---VARIABLES----------------------------------------------------------------------- +IniRead, ChromeProfile, Settings.ini, General, ChromeProfile + + +;---MAIN SCRIPT--------------------------------------------------------------------- +driver:= ComObjCreate("Selenium.CHROMEDriver") ;Select and Create Chrome driver instance +driver.AddArgument("disable-infobars") ;Hides 'Chrome is being controlled by automated test software' message +driver.AddArgument("--start-maximized") ; Maximize Chrome Browser +driver.AddArgument("--disable-gpu") +;driver.AddArgument("--headless") +try driver.Get("https://duckduckgo.com/") ;Open selected URL +/*catch e { + Msgbox,4096,Error, Unable to connect to Chrome COM Object. `nMost likely issue is that .Net framework 3.5 is not installed.`nMake sure it is installed by navigating to Start > Turn Windows features on and Off > .NET Framekwork 3.5 > TRUE`n`nAnother possibility is that you don't have chromedriver.exe in: C:\Program Files\SeleniumBasic\chromedriver.exe + ExitApp +} +*/ + +try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding +msgbox,4096,Success,If you installed Selenium correctly, A chrome window should have opened up and navigated to duckdcukgo.com. `nClick OK to close and to do a chrome profile test +; Msgbox % "ChromeProfile: " ChromeProfile +Driver := SChrome_Get("https://www.bitchute.com/", ChromeProfile) ; open new tab page with with specified profile + + + Msgbox,4096,Success?, If everything worked correctly you should have received a prompt to reopen chrome in debugging mode and then opened up chrome with the profile you have set in settings.ini and opened up BitChute.com`n`nClick OK to exit this script + + +ExitApp + + + + + + + + + + + + +;---FUNCTIONS-----------------------------------------------------------------------