Compare commits

...

12 Commits
1.2 ... main

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

@ -0,0 +1,84 @@
;---ENVIRONMENT---------------------------------------------------------------------
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
;#Warn ; Enable warnings to assist with detecting common errors.
;DetectHiddenWindows, On
#SingleInstance, Force
DetectHiddenWindows, ON
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, RMScriptManager.ico
;---Notes/Extra Info/#Includes------------------------------------------------------
;---VARIABLES-----------------------------------------------------------------------
ScriptName = Freedomain Livestream Scheduler
AHKFilepath = %A_ScriptDir%\%ScriptName%.ahk
Exefilepath = %A_ScriptDir%\%ScriptName%.exe
icopath = %A_ScriptDir%\Assets\Icon.ico
VersionIniFP = %A_ScriptDir%\Version.ini
;---MAIN SCRIPT---------------------------------------------------------------------
; Bump the version number in the version.ini file
IniRead, VersionNumber, %VersionIniFP%, %ScriptName%, Version, 0.0 ; , Filename, Section, Key [, Default]
VersionNumber += .01
VersionNumber := SubStr(VersionNumber, 1, 4)
IniWrite, %VersionNumber%, %VersionIniFP%,%ScriptName%, Version
; Kill any active intances of the uploaders so the .exe file can be overwriten by the compilation
process, close, %ScriptName%.exe
sleep, 1000
; Delete the .exe file so it can be repalced
if(FileExist(Exefilepath)){
FileDelete, %Exefilepath%
if(ErrorLevel){
msgbox, failed to delete Exe file. Please delete manually and re-run the compiler.
ExitApp
}
}
if(!FileExist(AHKFilepath)){
msgbox, %AHKFilepath% does not exist`nExiting
ExitApp
}
if(!FileExist(icopath)){
msgbox, %icopath% does not exist`nExiting
ExitApp
}
run, %comspec% /c ""C:\Program Files\AutoHotkey\Compiler\Ahk2Exe.exe" /in "%AHKFilepath%" /out "%exefilepath%" /icon "%icopath%""
; OldNotify(ScriptToCompile,"Compiled Successfully",5)
; sleep, 5000
ExitApp
;---FUNCTIONS-----------------------------------------------------------------------

@ -27,11 +27,11 @@ VersionIniFP = %A_ScriptDir%\Version.ini
;---MAIN SCRIPT---------------------------------------------------------------------
; Bump the version number in the version.ini file
IniRead, VersionNumber, %VersionIniFP%, %ScriptName%, Version, 0.0 ; , Filename, Section, Key [, Default]
IniRead, VersionNumber, %VersionIniFP%, Livestream-Scheduler, Version, 0.0 ; , Filename, Section, Key [, Default]
VersionNumber += .01
VersionNumber := SubStr(VersionNumber, 1, 4)
IniWrite, %VersionNumber%, %VersionIniFP%,%ScriptName%, Version
IniWrite, %VersionNumber%, %VersionIniFP%,Livestream-Scheduler, Version

@ -53,8 +53,6 @@ CheckIfUpdateInstalled(PassedInArgument)
; VARIABLES
;------------------------------------------------
@ -66,10 +64,13 @@ global FullScriptName
global PostStatusesFilepath
global ErrorLoggingDirectory
global ConfirmBeforeSubmit
global DiscordErrorLoggingWebhookBotURL
global DiscordVideosWebhookURL
global VideoFolderDir
global LogErrorsToMsgbox
global ErrorLogToDiscord
; global LogErrorsToTextFile
global CurrentSite
global Driver
@ -105,12 +106,18 @@ FileInstall, Version.ini, %A_ScriptDir%\Lib\Version.ini, 1
IniRead, ScriptVersion, %A_ScriptDir%\Lib\Version.ini,%ScriptSettingsSection%, Version, 0.0
; IniRead, ScriptName, %A_ScriptDir%\Lib\Version.ini,%ScriptSettingsSection%, Name, %ScriptSettingsSection%
global ScriptName := "Livestream Scheduler"
global ScriptAbbreviatedName := "FLS" ; used for error logging
global ScriptName
ScriptName := "Freedomain Livestream Scheduler"
global ScriptAbbreviatedName
ScriptAbbreviatedName := "FLS" ; used for error logging
FullScriptName := ScriptName . " - " . ScriptVersion
global GitReleasesAPIURL
GitReleasesAPIURL = https://freedomain.dev/api/v1/repos/yuriy/livestream-scheduler/releases
; Read Info From Files
@ -145,99 +152,172 @@ LivestreamThumbnail := ThumbnailJPGFilepath
if(FileExist(ThumbnailJPEGFilepath))
LivestreamThumbnail := ThumbnailJPEGFilepath
}
; Read settings.ini
; ------------------------------------------------
IniRead, ConfirmBeforeSubmit, %SettingsIniFilepath%, %ScriptSettingsSection%, ConfirmBeforeSubmit, 1
IniRead, AutoUpdateCheck, %SettingsIniFilepath%, %ScriptSettingsSection%, AutoUpdateCheck, 1
IniRead, ErrorLogToDiscord, %SettingsIniFilepath%, %ScriptSettingsSection%, ErrorLogToDiscord, 1
if(ErrorLogToDiscord){
; Discord
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")
}
}
; GUI Variables
; ------------------------------------------------
IniRead, XPosition, %SettingsIniFilepath%, %ScriptSettingsSection%, XPosition, 0
IniRead, YPosition, %SettingsIniFilepath%, %ScriptSettingsSection%, YPosition, 0
GuiFontSize = 15
MarginSize := 10
MarginSizeDoubled := MarginSize * 2
ButtonHeights := 30
ThumbnailPreviewWidth := 200
ThumbnailPreviewWidth := 150
GuiHeight := 500
VerticalLineHeight := GuiHeight - 100
GuiHeight := 550
; Column One
ColumnOneWidth := 500
ColumnOneWidth := 550
ColumnOneEditBoxWidth := ColumnOneWidth - (MarginSize * 2)
GuiFontSize = 15
ColumnOneEditBoxHalfWidth := (ColumnOneEditBoxWidth / 2) + 5
; Column Two
ColumnTwoXPosition := ColumnOneWidth + (MarginSize * 2)
ColumnTwoVerticalLineXPosition := ColumnTwoXPosition - (MarginSize * 2)
ColumnTwoEditBoxWidth := 200
ColumnTwoEditBoxHalfWidth := ColumnTwoEditBoxWidth / 2
; Column Three
ColumnThreeXPosition := ColumnTwoXPosition + ColumnTwoEditBoxWidth + (MarginSizeDoubled * 2)
ColumnThreeVerticalLineXPosition := ColumnThreeXPosition - (MarginSize * 2)
ColumnThreeEditBoxWidth := 180
GUIWidth := ColumnThreeXPosition + ColumnThreeEditBoxWidth + MarginSize
; Results Screen
ResultButtonWidth := 250
ResultButtonEditWidth := 250
ResultButtonHeights := 30
ResultButtonEditWidth := 350
ResultButtonHeights := 35
ResultButtonDoubleHeights := ResultButtonHeights * 2
ResultButtonAndEditWidth := ResultButtonWidth + ResultButtonEditWidth + MarginSize
; START OF GUI
; ------------------------------------------------
Gui, Font, s%GuiFontSize%
Gui, Margin, %MarginSize%, %MarginSize%
; Gui Color, 0193C4
; Column One
;------------------------------------------------
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Text,, Title
Gui, Add, Text,x%MarginSize%, Title
Gui, Font, s10
Gui, Font, Normal
Gui, Add, Edit,w%ColumnOneEditBoxWidth% vLivestreamTitle, %LivestreamTitle%
Gui, Add, Button, x+%MarginSize% gPasteClipboardToEditBox vPasteClipboardToFLSTitle, Paste Clipboard
Gui, Font, s%GuiFontSize%
Gui, Font, Normal
Gui, Add, Edit,x%MarginSize% w%ColumnOneEditBoxWidth% vLivestreamTitle, %LivestreamTitle%
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Text,, Description
Gui, Font, s10
Gui, Font, Normal
Gui, Add, Edit,w%ColumnOneEditBoxWidth% h150 vLivestreamDescription, %LivestreamDescription%
Gui, Add, Button, x+%MarginSize% gPasteClipboardToEditBox vPasteClipboardToFLSDescription, Paste Clipboard
Gui, Font, s%GuiFontSize%
Gui, Font, Normal
Gui, Add, Edit,x%MarginSize% w%ColumnOneEditBoxWidth% h200 vLivestreamDescription, %LivestreamDescription%
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Text,, Tags (Comma Seperated)
Gui, Font, Normal
Gui, Add, Edit,w%ColumnOneEditBoxWidth% vLivestreamTags, %LivestreamTags%
Gui, Font, s10
Gui, Font, Normal
Gui, Add, Button, x+%MarginSize% gPasteClipboardToEditBox vPasteClipboardToFLSTags, Paste Clipboard
Gui, Font, Bold
Gui, Add, Text,, Thumbnail
Gui, Font, s%GuiFontSize%
Gui, Font, Normal
Gui, Add, Button, x+%MarginSize% yp-3 gSelectThumbnail, Select
Gui, Add, Picture, x%MarginSize% w%ThumbnailPreviewWidth% h-1 vThumbnailPreview, %LivestreamThumbnail%
Gui, Add, Edit,x%MarginSize% w%ColumnOneEditBoxWidth% vLivestreamTags, %LivestreamTags%
; Buttons at Bottom of Page
; ------------------------------------------------
; Start with Column one and go across
ScheduleButtonWidths := 250
ScheduleButtonHeight := 55
ScheduleButtonHalfHeight := ScheduleButtonHeight / 2
Gui, add, Text, x0 y+%marginsizeDoubled% w%GUIWidth% 0x10
; Gui, Add, Edit,w%ColumnOneEditBoxWidth% h150 vLivestreamDescription, This livestream is happening soon!
Gui, Font, s10
Gui, Font, Bold
Gui, Add, Button, x%MarginSize% yp+%marginsizeDoubled% w%ColumnTwoEditBoxWidth% h%ScheduleButtonHalfHeight% gLoadPrevious , Load Previous
Gui, Add, Button, y+0 w%ColumnTwoEditBoxWidth% h%ScheduleButtonHalfHeight% gShowResultsScreen , Show Results
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Button, x+%marginsize% yp-%ScheduleButtonHalfHeight% w%ScheduleButtonWidths% h%ScheduleButtonHeight% gSaveAsTemplate, Save As Template
Gui, Add, Button,x+%marginsize% gSchedulePost h%ScheduleButtonHeight% w%ScheduleButtonWidths% gLoadTemplate, Load Template
Gui, Add, Button, x+%marginsize% gSchedulePost h%ScheduleButtonHeight% w%ScheduleButtonWidths% gSchedulePost, Schedule
; Column Two
; ------------------------------------------------
Gui, add, text, x%ColumnTwoVerticalLineXPosition% y%marginSize% h%VerticalLineHeight% 0x11 ;Vertical Line > Etched Gray
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
; Gui, Add, Text, , Settings
Gui, Add, Text,y0 x%ColumnTwoXPosition%, Settings
; Gui, Add, Text, , Thumbnail
Gui, Add, GroupBox, r2.5 x%ColumnTwoXPosition% y%marginSize% vImageThumbnail w%ColumnTwoEditBoxWidth%,Thumbnail
Gui, Font, s10
Gui, Font, Normal
Gui, Font, s8
Gui, Add, Checkbox, vConfirmBeforeSubmit checked, Confirm Before Submit
Gui, Add, Button, xp+120 yp-3 gSelectThumbnail, Select
; Gui, Font, Normal
; Gui, Font, s%GuiFontSize%
Gui, Add, Picture, x%ColumnTwoXPosition% y+%marginsize% w%ThumbnailPreviewWidth% h-1 vThumbnailPreview, %LivestreamThumbnail%
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
; Gui, Add, Text, , Settings
Gui, Add, Text, y+%MarginSizeDoubled% , Date and Time
Gui, Add, Text, x%ColumnTwoXPosition% yp+100 , Date and Time
Gui, Font, Normal
Gui, Add, DateTime, vLivestreamDate w%ColumnTwoEditBoxWidth%, MM/dd/yyyy
@ -253,23 +333,67 @@ Gui, Font, Bold
Gui, Add, Text,y+%MarginSizeDoubled% x%ColumnTwoXPosition%, Platforms
Gui, Font, Normal
Gui, Font, s8
Gui, Add, Button, x+%marginsize% yp+5 gUncheckAllPlatforms, Uncheck All
; Gui, Add, Checkbox,, Dlive
Gui, Font, s%GuiFontSize%
Gui, Add, Checkbox,x%ColumnTwoXPosition% y+%marginsize% checked vOdysee, Odysee
Gui, Add, Checkbox, x+%marginSize% yp+0 checked vLocals, Locals
Gui, Add, Checkbox,x%ColumnTwoXPosition% y+%marginsize% checked vRumble, Rumble
Gui, Font, S8
Gui, Add, Checkbox, x+10 yp+5 Checked vInputRumbleCustomRTMP, Input RTMP
Gui, Add, Checkbox, vOdysee, Odysee
Gui, Add, Checkbox, vLocals, Locals
Gui, Add, Checkbox,checked vRumble, Rumble
Gui, add, text, x%ColumnThreeVerticalLineXPosition% y%marginSize% h%VerticalLineHeight% 0x11 ;Vertical Line > Etched Gray
; Column Three
; ------------------------------------------------
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Button,gSchedulePost w%ColumnTwoEditBoxWidth% gSaveAsTemplate y+50, Save as Template
Gui, Add, Button,gSchedulePost w%ColumnTwoEditBoxWidth% gLoadTemplate, Load Template
Gui, Add, Text,y%MarginSize% x%ColumnThreeXPosition%, Settings
Gui, Font, s15
Gui, Add, Button,gSchedulePost w%ColumnTwoEditBoxWidth% h40, Schedule
Gui, Font, s12
Gui, Font, Normal
Gui, Add, Checkbox, vAutoUpdateCheck Checked%AutoUpdateCheck%, Auto Update Check
Gui, Add, Checkbox, vErrorLogToDiscord Checked%ErrorLogToDiscord%, Error Log to Discord
Gui, Add, Checkbox, vConfirmBeforeSubmit checked%ConfirmBeforeSubmit%, Confirm Before Submit
Gui, Font, s%GuiFontSize%
Gui, Font, Bold
Gui, Add, Text, y+%MarginSizeDoubled% x%ColumnThreeXPosition%, System
Gui, Font, S10
/*if(UpdateAvailable)
Gui, Add, Button, cRed w%ColumnTwoEditBoxWidth% center vUpdateAvailable gUpdateScript, %ScriptAbbreviatedName% Update Available!
else,
*/
Gui, Add, Button, w%ColumnThreeEditBoxWidth% center vUpdateAvailable gUpdateScript, %ScriptAbbreviatedName% Up-to-Date
/*if(ChromeUpdateAvailable)
Gui, Add, Button, cRed w%ColumnThreeEditBoxWidth% center vChromeUpdateAvailable gUpdateChrome,Chrome Update Available!
else,
*/
Gui, Add, Button, w%ColumnThreeEditBoxWidth% center vChromeUpdateAvailable gUpdateChrome, Chrome Up-to-Date
Gui, Add, Button, x%ColumnThreeXPosition% y+%MarginSize% w%ColumnThreeEditBoxWidth% center gOpenGiteaPage, Report Bug
Gui, Show, h%GuiHeight% w%GUIWidth% x%XPosition% y%YPosition%, %FullScriptName%
;---Check for Updates---
;------------------------------------------------
if(AutoUpdateCheck AND !UpdateAvailable){
SetTimer, CheckForUpdates, -1000
}
Gui, Show, h%GuiHeight%
Return
@ -283,12 +407,22 @@ Return
UncheckAllPlatforms:
GuiControl,,Odysee,0
GuiControl,,Locals,0
GuiControl,,Rumble,0
GuiControl,,InputRumbleCustomRTMP,0
Return
; Functions
;------------------------------------------------
GUIUpdateVars:
Gui, Submit, NoHide
Return
SaveAsTemplate:
Gui, submit, NoHide ; Update variables for all modified fields
@ -318,13 +452,20 @@ if(LivestreamThumbnail){ ; copy thumbnail into folder
Return
LoadPrevious:
LoadTemplate:
Message = Loading Template
if(A_GuiControl = "Load Previous"){
ErrorLoggingDirectory = %A_ScriptDir%\Lib\ErrorLogging
Message = Loading Previous Post
}
if(A_GuiControl = "Load Template"){
ErrorLoggingDirectory = %A_ScriptDir%\Lib\Templates-%ScriptAbbreviatedName%\
Message = Loading Template
}
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,DiscordErrorLogging")
ErrorLoggingDirectory = %A_ScriptDir%\Lib\Templates-%ScriptAbbreviatedName%\
; ErrorLoggingDirectory = %A_ScriptDir%\Lib\Templates-%ScriptAbbreviatedName%\
FileSelectFolder, ErrorLoggingDirectory, %ErrorLoggingDirectory%
if(ErrorLevel){
Tooltip
@ -338,8 +479,8 @@ ExitApp
SelectThumbnail:
FileSelectFile, LivestreamThumbnail,
GuiControl, , ThumbnailPreview, *w%ThumbnailPreviewWidth% *h-1 %LivestreamThumbnail%
; Msgbox % "ThumbnailPreviewWidth: " ThumbnailPreviewWidth
GuiControl, , ThumbnailPreview, *h130 *w-1 %LivestreamThumbnail%
Return
@ -349,6 +490,15 @@ Return
SchedulePost:
Gui, submit, NoHide
WinGetPos, XPosition, YPosition, , , A
; Save Settings.ini
; ------------------------------------------------
IniWrite, %ConfirmBeforeSubmit%, %SettingsIniFilepath%, %ScriptSettingsSection%, ConfirmBeforeSubmit
IniWrite, %AutoUpdateCheck%, %SettingsIniFilepath%, %ScriptSettingsSection%, AutoUpdateCheck
IniWrite, %ErrorLogToDiscord%, %SettingsIniFilepath%, %ScriptSettingsSection%, ErrorLogToDiscord
IniWrite, %XPosition%, %SettingsIniFilepath%, %ScriptSettingsSection%, XPosition
IniWrite, %YPosition%, %SettingsIniFilepath%, %ScriptSettingsSection%, YPosition
; Re-use an existing errorlog or create new directory
@ -387,10 +537,16 @@ if(Rumble)
gosub, RumbleSchedule
if(InputRumbleCustomRTMP){
gosub, RumbleSetRTMP
}
; msgbox, done!
; Gui, Add,
ShowResultsScreen:
ToolTip ; hide any existing tooltips
Gui, Destroy
@ -413,35 +569,74 @@ IniRead, LocalsRTMPKey, %PostStatusesFilepath%, Livestream,LocalsRTMPKey, %A_Spa
IniRead, LocalsLivestreamURL, %PostStatusesFilepath%, Livestream,LocalsLivestreamURL, %A_Space%
IniRead, OdyseeLivestreamURL, %PostStatusesFilepath%, Livestream,OdyseeLivestreamURL, %A_Space%
IniRead, OdyseeRTMPKey, %PostStatusesFilepath%, Livestream,OdyseeRTMPKey, %A_Space%
IniRead, OdyseeRTMPURL, %PostStatusesFilepath%, Livestream,OdyseeRTMPURL, %A_Space%
IniRead, RumbleLivestreamURL, %PostStatusesFilepath%, Livestream,RumbleLivestreamURL, %A_Space%
IniRead, RumbleCustomRTMPs, %PostStatusesFilepath%, Livestream,RumbleCustomRTMPs, %A_Space%
Gui, Font, Bold
Gui, Font, s%GuiFontSize%
Gui, Add, Button,x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Locals RTMP URL
Gui, Add, Button,x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Copy Title
Gui, Add, Button, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% center gResultsGUIAction, Copy Description
Gui, add, text, x%MarginSize% y+%marginsize% w%ResultButtonAndEditWidth% 0x10 ;Horizontal Line > Etched Gray
Gui, Add, Button,x%MarginSize% yp+%marginsizeDoubled% h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Locals RTMP URL
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vLocalsRTMPURL center, %LocalsRTMPURL%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Locals RTMP Key
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vLocalsRTMPKey center, %LocalsRTMPKey%
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vLocalsRTMPKey gGUIUpdateVars center, %LocalsRTMPKey%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Locals URL
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vLocalsLivestreamURL center, %LocalsLivestreamURL%
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vLocalsLivestreamURL gGUIUpdateVars center, %LocalsLivestreamURL%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Odysee RTMP URL
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vOdyseeRTMPURL gGUIUpdateVars center, %OdyseeRTMPURL%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Odysee RTMP Key
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vOdyseeRTMPKey gGUIUpdateVars center, %OdyseeRTMPKey%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Odysee URL
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vOdyseeLivestreamURL center, %OdyseeLivestreamURL%
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vOdyseeLivestreamURL gGUIUpdateVars center, %OdyseeLivestreamURL%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, Rumble URL
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vRumbleLivestreamURL center, %RumbleLivestreamURL%
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vRumbleLivestreamURL gGUIUpdateVars center, %RumbleLivestreamURL%
Gui, Font, s10
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth% gResultsGUIAction, RTMPs Updated on Rumble
Gui, Add, Edit, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% vRumbleCustomRTMPs gGUIUpdateVars center, %RumbleCustomRTMPs%
Gui, Font, s%GuiFontSize%
Gui, Add, Button, x%MarginSize% y+10 h%ResultButtonHeights% w%ResultButtonWidth%
Gui, Add, Button, x+5 yp+0 h%ResultButtonHeights% w%ResultButtonEditWidth% gResultsGUIAction ,Save Changes
Gui, add, text, x%MarginSize% y+%marginsize% w%ResultButtonAndEditWidth% 0x10 ;Horizontal Line > Etched Gray
Gui, Font, s%GuiFontSize%
Gui, Add, Button, x%MarginSize% yp+%marginsize% h%ResultButtonHeights% w%ResultButtonWidth% gStartSMP, Start SMP
Gui, Add, Button, x+%marginsize% h%ResultButtonHeights% w%ResultButtonEditWidth% gUpdateRedirects, Update M.M. Redirects
Gui, Add, Button, x%MarginSize% h%ResultButtonHeights% w%ResultButtonWidth%
Gui, Add, Button, x+%marginsize% h%ResultButtonHeights% w%ResultButtonEditWidth% gRetryUpload ,Try Failed Again
Gui, Font, s%GuiFontSize%
Gui, Add, Button, y%MarginSize% w%ResultButtonEditWidth% Center, Error Log
Gui, Font, s8
Gui, Font, Normal
Gui, Add, Edit, y+5 h450 w%ResultButtonEditWidth%, %ErrorLogVar%
Gui, Add, Button, x%MarginSize% gResultsGUIAction h%ResultButtonHeights% w%ResultButtonEditWidth%,Copy Title
Gui, Add, Button, x+%marginsize% gResultsGUIAction h%ResultButtonHeights% w%ResultButtonEditWidth%,Copy Description
Gui, Add, Button, x%MarginSize% h%ResultButtonHeights% w%ResultButtonEditWidth%,
Gui, Add, Button, x+%marginsize% gRetryUpload h%ResultButtonHeights% w%ResultButtonEditWidth%,Try Failed Again
; Gui, Add, Button, x%MarginSize% gRetryUpload h%ResultButtonHeights% w%ResultButtonEditWidth%,Try Failed Again
Gui, Show
Gui, Show, x%XPosition% y%YPosition% w%GUIWidth%, %FullScriptName% - Results
Return
@ -449,9 +644,75 @@ Return
; GoSubs
; ------------------------------------------------
OpenGiteaPage:
run, https://freedomain.dev/yuriy/video-uploader/issues
Return
StartSMP:
; IniWrite, %A_ScriptFullPath%, %SettingsIniFilepath%, Filepaths, SMPFilepath
IniRead, SocialMediaPosterFilepath, %SettingsIniFilepath%, Filepaths, SocialMediaPosterFilepath, %A_Space%
if(SocialMediaPosterFilepath = "" or !FileExist(SocialMediaPosterFilepath)){
OnMessage(0x44, "OnMsgBoxSocialMediaPoster")
MsgBox 0x21, Filepath Not 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 Filepath
if(ErrorLevel)
Return
if(!InStr(SocialMediaPosterFilepath, ".exe"))
Return
} Else IfMsgBox Cancel, {
Return
}
IniWrite, %SocialMediaPosterFilepath%, %SettingsIniFilepath%, Filepaths, SocialMediaPosterFilepath
}
run, %SocialMediaPosterFilepath% %StatusFileFilePath%
Return
/*
*/
UpdateRedirects:
gosub, MediaManagerUpdate
Return
ResultsGUIAction:
; Msgbox % "A_GuiControl: " A_GuiControl
if(A_GuiControl = "Open Post Folder"){
run, %ErrorLoggingDirectory%
Return
}
if(A_GuiControl = "Save Changes"){
Message = Changes Saved Successfully
SaveOrPostProgress(Message:=Message,PostType:="Tooltip")
IniWrite, %LocalsRTMPURL%, %PostStatusesFilepath%, Livestream,LocalsRTMPURL
IniWrite, %LocalsRTMPKey%, %PostStatusesFilepath%, Livestream,LocalsRTMPKey
IniWrite, %LocalsLivestreamURL%, %PostStatusesFilepath%, Livestream,LocalsLivestreamURL
IniWrite, %RumbleLivestreamURL%, %PostStatusesFilepath%, Livestream,RumbleLivestreamURL
IniWrite, %RumbleCustomRTMPs%, %PostStatusesFilepath%, Livestream,RumbleCustomRTMPs
IniWrite, %OdyseeLivestreamURL%, %PostStatusesFilepath%, Livestream,OdyseeLivestreamURL
IniWrite, %OdyseeRTMPURL%, %PostStatusesFilepath%, Livestream,OdyseeRTMPURL
IniWrite, %OdyseeRTMPKey%, %PostStatusesFilepath%, Livestream,OdyseeRTMPKey
sleep, 1000
Tooltip
Return
}
Message = Copying %A_GuiControl% to Clipboard
SaveOrPostProgress(Message:=Message,PostType:="Tooltip")
@ -470,6 +731,13 @@ if(A_GuiControl = "Rumble URL"){
if(A_GuiControl = "Odysee URL"){
Clipboard := OdyseeLivestreamURL
}
if(A_GuiControl = "Odysee RTMP URL "){
Clipboard := OdyseeRTMPURL
}
if(A_GuiControl = "Odysee RTMP Key "){
Clipboard := OdyseeRTMPKey
}
if(A_GuiControl = "Locals URL"){
Clipboard := LocalsLivestreamURL
@ -483,6 +751,8 @@ if(A_GuiControl = "Locals RTMP Key"){
Clipboard := LocalsRTMPKey
}
sleep, 1000
ToolTip
Return
@ -506,6 +776,12 @@ Return
#Include %A_ScriptDir%\Modules\Odysee-Schedule.ahk
#Include %A_ScriptDir%\Modules\Odysee-Grab-URL.ahk
#Include %A_ScriptDir%\Modules\Rumble-Schedule.ahk
#Include %A_ScriptDir%\Modules\Rumble-Set-RTMP.ahk
#Include %A_ScriptDir%\Modules\Media-Manager-Update-Redirects.ahk
#Include %A_ScriptDir%\Lib\Freedomain-Posters-Shared-Functions\Shared-GoTos.ahk
; Misc

@ -1 +1 @@
Subproject commit 124a26c3b03e5f1292691909c20a116f64957955
Subproject commit cf56ae8136def874793895733d595349b20d9c19

@ -34,7 +34,6 @@ CheckForAlerts()
; Input Title and Description into Create a Livestream - First Screen
; ------------------------------------------------
Xpath = //input[@id='title']
; try, driver.FindElementByXPath(Xpath).SendKeys("TEST STRINGHERE")
Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=LivestreamTitle)
if(Status){
@ -96,6 +95,39 @@ try, driver.FindElementByXPath(Xpath).SendKeys(driver.Keys.BackSpace).SendKeys(d
Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=LocalsLivestreamTime)
; Upload Custom Thumbnail
; ------------------------------------------------
if(Livestreamthumbnail){
Message = Uploading Thumbnail
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
; this `label` element is a child of the thumbnail input element.
xpath = (//label[@id='photo-upload-btn'])[2]
; the element ID for input elements seems to change/be generated each time the page is generated
XpathIDForUploads := GetHTMLValueFromXpathOuterHTML(XPATH, "label for")
if(XpathIDForUploads = "Failed"){
Message = Failed to grab element needed for uploading thumbnail. Please attach thumbnail manually.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
ThubmnailInputXpath = (//input[@id='%XpathIDForUploads%'])[1]
Status := Selenium_LoopToSendValueToXpath(Xpath:=ThubmnailInputXpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=Livestreamthumbnail)
if(Status){
Message = Failed to upload livestream thumbnail
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
Sleep, 2000
}
if(ConfirmBeforeSubmit){
OnMessage(0x44, "OnMsgBoxUserConfirmation")
MsgBox 0x21, User Confirmation, Please check that all data was input correctly and fix any mistakes and then click PROCEED to finalize the Upload.`n`nClick STOP to cancel the rest of this Upload and move on to the next website.
@ -120,18 +152,23 @@ if(Status){
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
LivestreamURL := GrabLocalsPostURLUsingTitle(LivestreamTitle)
LocalsLivestreamURL := GrabLocalsPostURLUsingTitle(LivestreamTitle)
if(!InStr(LivestreamURL, "https")){
if(!InStr(LocalsLivestreamURL, "https")){
; If url was not grabbed. wait 1 minute, reload page and then try grabbing URL again
; @todo
}
; Navigate to the post
; Navigate to the Post and Grab the URL
; ------------------------------------------------
Message = Navigating to Livestream Page to grab RTMP Settings
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
try, driver.Get(LivestreamURL) ;Open selected URL
try, driver.Get(LocalsLivestreamURL) ;Open selected URL
driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
@ -182,7 +219,7 @@ LocalsRTMPKey := GetHTMLValueFromXpathOuterHTML(XPATH, "value")
IniWrite, %LocalsRTMPURL%, %PostStatusesFilepath%, Livestream,LocalsRTMPURL
IniWrite, %LocalsRTMPKey%, %PostStatusesFilepath%, Livestream,LocalsRTMPKey
IniWrite, %LivestreamURL%, %PostStatusesFilepath%, Livestream,LivestreamURL
IniWrite, %LocalsLivestreamURL%, %PostStatusesFilepath%, Livestream,LocalsLivestreamURL
ToolTip
Return

@ -0,0 +1,119 @@
MediaManagerUpdate:
; ------------------------------------------------
CurrentSite := "Media Manager"
SaveOrPostProgress(Message:="Navigating to Website",PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
IniRead, FDRRadioURL, %SettingsIniFilepath%, General, FDRRadioURL, %A_Space%
if(FDRRadioURL = ""){
Message = FDRRadioURL is blank in Settings.ini. Please add it to the following location: [General]`nFDRRadioURL=
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
FDRRadioBaseURL := "https://" . ExtractBaseURL(FDRRadioURL)
FDRRadioURL := FDRRadioBaseURL . "/manage/"
Status := NavigateFromBaseURLTo(FDRRadioURL)
if(Status)
Return
CheckForAlerts()
Message = Checking Login Status
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
Try, PageURL := driver.Url
if(InStr(PageURL, "/NotLoggedIn")){
Message = Logged out. Trying to log back in.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
Xpath = (//span[contains(text(),'Login')])[1]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
sleep, 1000
Try, PageURL := driver.Url
if(InStr(PageURL, "/NotLoggedIn")){
Message = Failed to log back in automatically. Please login and try again.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
}
Message = Updating Redirect URLs
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
; URL for each redirect
LocalsLiveRedirectURL := FDRRadioBaseURL . "/manage/#/Redirects/Modify?redirectID=738"
RumbleLiveRedirectURL := FDRRadioBaseURL . "/manage/#/Redirects/Modify?redirectID=739"
OdyseeLiveRedirectURL := FDRRadioBaseURL . "/manage/#/Redirects/Modify?redirectID=742"
; read the url's from the status file
IniRead, LocalsLivestreamURL, %PostStatusesFilepath%, Livestream,LocalsLivestreamURL, %A_Space%
IniRead, RumbleLivestreamURL, %PostStatusesFilepath%, Livestream,RumbleLivestreamURL, %A_Space%
IniRead, OdyseeLivestreamURL, %PostStatusesFilepath%, Livestream,OdyseeLivestreamURL, %A_Space%
if(LocalsLivestreamURL)
UpdateMediaManagerRedirect(LocalsLiveRedirectURL, LocalsLivestreamURL)
else, {
Message = LocalsLivestreamURL is blank. Skipping
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
if(RumbleLivestreamURL)
UpdateMediaManagerRedirect(RumbleLiveRedirectURL, RumbleLivestreamURL)
else, {
Message = RumbleLivestreamURL is blank. Skipping
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
if(OdyseeLivestreamURL)
UpdateMediaManagerRedirect(OdyseeLiveRedirectURL, OdyseeLivestreamURL)
else, {
Message = OdyseeLivestreamURL is blank. Skipping
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
UpdateMediaManagerRedirect(MediaManagerRedirectPageURL, RedirectURL){
try, driver.Get(MediaManagerRedirectPageURL) ;Open selected URL
try, driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
Xpath = (//input[@id='destinationURL'])[1]
Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=RedirectURL, ClearElement := 1)
; Snippet to for check:
if (ConfirmBeforeSubmit && ConfirmBeforeSubmitMsgboxFunc() != true) {
Message = User Selected STOP button when asked for confirmation. Cancelling Rest of Site Upload.
SaveOrPostProgress(Message:=Message, PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
return
}
; Save button
Xpath = (//span[contains(text(),'Save')])[1]
Status := Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to click Save button
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
Sleep, 1000
Return "Success"
}

@ -43,9 +43,10 @@ OdyseeLivestreamSlug := "livestream-" . OdyseeLivestreamDate
OdyseeURLSLUG := LBRYCMDTextReplacement(OdyseeLivestreamSlug)
IniWrite, %OdyseeURLSLUG%, %PostStatusesFilepath%, Livestream,OdyseeURLSLUG
Xpath = (//div[@class='form-field__prefix'])[1]
/*Xpath = (//div[@class='form-field__prefix'])[1]
try OdyseeChannelURL := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
*/
Message = Inputting Livestream Information
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
@ -231,18 +232,85 @@ if(LivestreamThumbnail != ""){
Message = Submitting Livestream
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
; Click Create Button in the confirmation popup
; Click Create Button at bottom of the screen
Xpath = //span[contains(text(),'Create')]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000)
if(Status){
Message = Failed to click "Create" button at the bottom of page
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
sleep, 1000
; Click confirm button in the popup
Xpath = //button[@aria-label='Confirm']//span[@class='button__content']
Xpath = //span[contains(text(),'Confirm')]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000)
if(Status){
Message = Failed to click "Confirm" button in confirmation popup
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
OdyseeLivestreamURL := "https://" . OdyseeChannelURL . OdyseeURLSLUG
; OdyseeURL := "https://" . OdyseeURL
IniRead, OdyseeChannelURL, %SettingsIniFilepath%, %ScriptSettingsSection%, OdyseeChannelURL, %A_Space%
if(!OdyseeChannelURL){
OdyseeChannelURL := "https://odysee.com/@freedomain:b/"
IniWrite, %OdyseeChannelURL%, %SettingsIniFilepath%, %ScriptSettingsSection%, OdyseeChannelURL
}
OdyseeLivestreamURL := OdyseeChannelURL . OdyseeURLSLUG
IniWrite, %OdyseeLivestreamURL%, %PostStatusesFilepath%, Livestream,OdyseeLivestreamURL
; Grab RTMP Settings
Message = Waiting for Confirmation Screen to grab RTMP Settings
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
Xpath = (//span[contains(text(),'View Livestream Settings')])[1]
loop, 60 {
try, InnerText := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
if(InnerText = "View Livestream Settings"){
break
}
sleep, 1000
}
; click on the "View livestream Settings" button
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=5,SleepLength:=1000)
if(Status){
Message = Failed to click on -View Livestream Settings- Button
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
; Grab the Stream URL and Key
Xpath = (//input[@name='stream-server'])[1]
loop, 5 {
Try OdyseeRTMPURL := driver.findelementbyxpath(Xpath).Attribute("value") ;Xpath Value
if(OdyseeRTMPURL)
break
else,
sleep, 1000
}
Xpath = (//input[@name='livestream-key'])[1]
Try OdyseeRTMPKey := driver.findelementbyxpath(Xpath).Attribute("value") ;Xpath Value
if(OdyseeRTMPKey = ""){
Message = Failed to grab Odysee RTMP Key. Page did not load?
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
IniWrite, %OdyseeRTMPURL%, %PostStatusesFilepath%, Livestream,OdyseeRTMPURL
IniWrite, %OdyseeRTMPKey%, %PostStatusesFilepath%, Livestream,OdyseeRTMPKey
Return

@ -9,9 +9,6 @@ Status := NavigateFromBaseURLTo("https://studio.rumble.com/api/signin")
if(Status)
Return
try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
CheckForAlerts()
Message = Checking Login Status
@ -43,11 +40,14 @@ if(InStr(CurrentURL, "/sso/auth/consent")){
Message = Scheduling new stream and inputting information
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
; Schedule new stream
; Schedule a stream button
Xpath = //div[normalize-space()='Schedule a stream']
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to click "Schedule a Stream" button. Livestream Already exists?
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
Xpath = (//h2[normalize-space()='Select a template (optional)'])
try ElementInnerText := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
@ -174,11 +174,37 @@ if(Status){
; Select each Secondary Platform checkbox
; ------------------------------------------------
IniRead, RumbleSecondaryPlatformsList, %SettingsIniFilepath%, %ScriptSettingsSection%, RumbleSecondaryPlatformsList, %A_Space%
if(RumbleSecondaryPlatformsList = ""){
; if variable is empty, get all items in the list and write them to .ini file
Loop, 10 {
IndexPlusOne := A_index + 1
Xpath = (//div[@class='flex shrink-0 items-center gap-x-4'])[%A_index%]
XpathCheckbox = (//div[@class='relative shrink-0'])[%IndexPlusOne%]
try SecondaryPlatformCheckboxName := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
if(SecondaryPlatformCheckboxName = "Add new destination" OR SecondaryPlatformCheckboxName = ""){
Break
}
RumbleSecondaryPlatformsList .= SecondaryPlatformCheckboxName . "--"
}
IniWrite, %RumbleSecondaryPlatformsList%, %SettingsIniFilepath%, %ScriptSettingsSection%, RumbleSecondaryPlatformsList
MsgBox 0x40, Rumble Secondary Platforms List Generated, Rumble Secondary Platforms List was genearted and all the available options were added to it.`n`nPlease edit the settings.ini file and remove any platforms you do not need selected from the follwoing KEY:`n`n[%ScriptSettingsSection%]`nRumbleSecondaryPlatformsList=
}
Loop, 10 {
IndexPlusOne := A_index + 1
Xpath = (//div[@class='flex shrink-0 items-center gap-x-4'])[%A_index%]
XpathCheckbox = (//div[@class='relative shrink-0'])[%IndexPlusOne%]
XpathCheckbox = (//div[@class='relative shrink-0'])[%A_index%]
try SecondaryPlatformCheckboxName := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
@ -187,6 +213,9 @@ Loop, 10 {
Break
}
if(!InStr(RumbleSecondaryPlatformsList,SecondaryPlatformCheckboxName))
Continue
Status := Selenium_LoopToClickXpath(Xpath:=XpathCheckbox,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to check off the checkbox for: %SecondaryPlatformCheckboxName%
@ -215,358 +244,77 @@ if(ConfirmBeforeSubmit){
*/
; click the "next" button to finalize the upload
Xpath = (//button[@class='rounded-full px-6 py-2 bg-primary hover:brightness-[0.92] cursor-pointer'])[1]
Xpath = (//span[normalize-space()='Next'])[1]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to click "Next" to finalize the upload
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
try, driver.get("https://rumble.com/account/live-streaming")
Xpath = (//a[normalize-space()='Livestream Coming Soonish!'])[1]
; Try ElementOuterHTML := driver.findelementbyxpath(Xpath).Attribute("outerHTML") ;XPATH-ID & Tag
RumbleURLSlug := GetHTMLValueFromXpathOuterHTML(XPATH, "href")
if(RumbleURLSlug = "" or RumbleURLSlug = "Failed"){
Message = Failed to grab Rumble URL Slug from Livestreams Page
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
RumbleLivestreamURL := "https://rumble.com" . RumbleURLSlug
IniWrite, %RumbleLivestreamURL%, %PostStatusesFilepath%, Livestream,RumbleLivestreamURL
return
try CurrentURL := driver.URL
if(InStr(CurrentURL, "/login.php")){
if(AutoLogin){
Message = Logging in Automatically by clicking into the UN+PW fields for info to register
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
; have to click into username and password field for page to register that there's input
; clicking with JS doesn't make it register, but with xpath selenium it does
Xpath = //input[@id='login-username']
driver.FindElementByXPath(Xpath).click()
Xpath = //input[@id='login-password']
driver.FindElementByXPath(Xpath).click()
js = document.querySelector("button[type='submit']").click();
driver.executeScript(js)
; Do a double check to make sure that login worked
Message = Checking Login Status
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
try CurrentURL := driver.URL
if(!InStr(CurrentURL, "/upload")){
Message = Failed to log back in. Please Log Back In Manually
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return
}
}
else, { ; notify user and return
Message = Login Expired. Please Log Back in
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return
}
Message = Waiting 5 seconds for page to fully load
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
sleep, 5000
}
; CheckForAlerts()
Message = Uploading Video File
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
Xpath = //input[@id='Filedata']
Status := Selenium_LoopToSendValueToXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=VideoFilepath)
if(Status){
try, CurrentURL := GetCurrentTabURlBase()
Message = Failed to Upload Video File`nCurrent Tab URL: %CurrentURL%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return
}
; 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 Channel
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
; try driver.findElementsByID("channelId").item[1].click()
; @todo replace with regex
js = return document.querySelector("#channelId").innerHTML;
try, ChannelIDNumber := driver.executeScript(js)
; Msgbox % "ChannelIDNumber: " ChannelIDNumber
ChannelIDNumber := StrSplit(ChannelIDNumber, "option value=")
; Msgbox % "ChannelIDNumber: " ChannelIDNumber
ChannelIDNumber := ChannelIDNumber[3]
; Msgbox % "ChannelIDNumber: " ChannelIDNumber
SingleQuote = "
ChannelIDNumber := StrSplit(ChannelIDNumber, "data-private")
ChannelIDNumber := ChannelIDNumber[1]
ChannelIDNumber := StrReplace(ChannelIDNumber, SingleQuote, "")
ChannelIDNumber := StrReplace(ChannelIDNumber, " ", "")
; Msgbox % "ChannelIDNumber: " ChannelIDNumber
; js = return document.querySelector("#channelId").value;
; try, ChannelIDNumber := driver.executeScript(js)
; Msgbox % "ChannelIDNumber: " ChannelIDNumber
if(ChannelIDNumber = ""){
Message = ChannelIDNumber is blank. Unable to select Upload Channel
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return
}
Message = Waiting 15 seconds before Navigating to Rumble and Grabbing Livestream URL
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
sleep, 15000
ChannelIDNumber = 6070526 ; freedomain
; ChannelIDNumber = 762377 ; personal
Xpath = //option[@value='%ChannelIDNumber%']
try driver.FindElementByXPath(Xpath).click()
try, driver.get("https://rumble.com/account/live-streaming")
catch e {
Message = Failed to click on Channel using %ChannelIDNumber%.
Message = Failed to Navigate to Rumble.com
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
SaveDriverURLOFErrorPage()
Return
; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
; SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
}
try, driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
; Input Tags
Message = Inputting Tags
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile")
try driver.findElementsByName("tags").item[1].SendKeys(VideoTags) ;selects element based on Name and sends variable to it.
Xpath = (//span[@class='video-info-status recorder'])[1]
; 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")
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
Loop, 5 {
if(A_index = 5){
Message = Failed to grab livestream URL. `nAfter 5 checks the top livestream is still not in -Waiting for Stream- status.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
*/
try StreamStatus := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
if(StreamStatus != "Waiting for Stream"){
Message = First Livestream on the list is not in -Waiting for Stream- status.`nWaiting 30 seconds and checking again.
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
sleep, 30000
try, driver.executeScript("history.go(0)") ;refresh page
try, driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
}
else,
break
}
if(ConfirmBeforeSubmit)
msgbox, Please check that all data was input correctly and then click OK to Publish Video
try UploadPageURL := driver.URL
Xpath = (//h2[@class='video-title'])[1]
; Submit Button
js = document.getElementById('submitForm').click();
try driver.executeScript(js) ;
try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
RumbleURLSlug := GetHTMLValueFromXpathOuterHTML(XPATH, "href")
if(RumbleURLSlug = "" or RumbleURLSlug = "Failed"){
Message = Failed to grab Rumble URL Slug from Livestreams Page
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
RumbleLivestreamURL := "https://rumble.com" . RumbleURLSlug
; 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.
IniWrite, %RumbleLivestreamURL%, %PostStatusesFilepath%, Livestream,RumbleLivestreamURL
; 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)
return
; 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()
Return

@ -0,0 +1,98 @@
RumbleSetRTMP:
;------------------------------------------------
CurrentSite := "Rumble Studio"
Status := NavigateFromBaseURLTo("https://studio.rumble.com/settings/connections")
if(Status)
Return
try driver.executeScript("return document.readyState").equals("complete") ; wait until page loads completely before proceeding
CheckForAlerts()
Message = Inputting Custom RTMP Settings into Rumble Studio
SaveOrPostProgress(Message,PostType:="Tooltip,ErrorLoggingTextFile,DiscordErrorLogging")
IniRead, LocalsRTMPURL, %PostStatusesFilepath%, Livestream,LocalsRTMPURL, %A_Space%
IniRead, LocalsRTMPKey, %PostStatusesFilepath%, Livestream,LocalsRTMPKey, %A_Space%
IniRead, OdyseeRTMPKey, %PostStatusesFilepath%, Livestream,OdyseeRTMPKey, %A_Space%
IniRead, OdyseeRTMPURL, %PostStatusesFilepath%, Livestream,OdyseeRTMPURL, %A_Space%
if(LocalsRTMPURL = ""){
Message = Skipping. No LocalsRTMPURL in Status.ini file
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
if(OdyseeRTMPURL = ""){
Message = Skipping. No OdyseeRTMPURL in Status.ini file
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
Loop, 10 {
; IndexPlusOne := A_index + 1
IndexMinusOne := A_index - 1
Xpath = (//div[@class='flex shrink-0 items-center gap-x-4'])[%A_index%]
XpathCheckbox = (//img[@alt='More options'])[%IndexMinusOne%]
try SecondaryPlatformCheckboxName := driver.findelementbyxpath(Xpath).Attribute("innerText") ;XPATH Inner Text
if(SecondaryPlatformCheckboxName = "LOCALS RTMP USE" OR SecondaryPlatformCheckboxName = "ODYSEE RTMP"){
if(SecondaryPlatformCheckboxName = "LOCALS RTMP USE"){
SiteRTMPURL := LocalsRTMPURL
SiteRTMPKey := LocalsRTMPKey
}
if(SecondaryPlatformCheckboxName = "ODYSEE RTMP"){
SiteRTMPURL := OdyseeRTMPURL
SiteRTMPKey := OdyseeRTMPKey
}
Status := Selenium_LoopToClickXpath(Xpath:=XpathCheckbox,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to click into 3 dot menu for %SecondaryPlatformCheckboxName%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
; click Edit RTMP in the popup menu
Xpath = (//span[normalize-space()='Edit RTMP'])[1]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to click into 3 dot menu for %SecondaryPlatformCheckboxName%
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
}
; Input New RTMP Info
XpathRTMP = (//input[@placeholder='Enter the RTMP URL'])[1]
XpathStreamkey = (//input[@placeholder='Enter the stream key'])[1]
Status := Selenium_LoopToSendValueToXpath(Xpath:=XpathRTMP,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=SiteRTMPURL,ClearElement:=1)
Status := Selenium_LoopToSendValueToXpath(Xpath:=XpathStreamkey,NumOfLoops:=2,SleepLength:=1000,StringTextContent:=SiteRTMPKey,ClearElement:=1)
; click save button
Xpath = (//button[@class='rounded-full block px-6 py-2 bg-primary hover:brightness-[0.92] cursor-pointer'])[1]
Status := Selenium_LoopToClickXpath(Xpath:=Xpath,NumOfLoops:=2,SleepLength:=1000)
if(Status){
Message = Failed to Click Save Button for %SecondaryPlatformCheckboxName% modified RMTP Settings
SaveOrPostProgress(Message:=Message,PostType:="Tooltip,ErrorLoggingTextFile,ErrorSummaryVar,DiscordErrorLogging")
Return
}
break
}
}
RumbleCustomRTMPs := "Success"
IniWrite, %RumbleCustomRTMPs%, %PostStatusesFilepath%, Livestream,RumbleCustomRTMPs

@ -1,3 +1,13 @@
# Freedomain-Livestream-Scheduler
Livestream Scheduler written for the [Freedomain Philosophy Show](https://freedomain.com/)
![Alt text](Assets/Preview.png "Screenshot of Main Window")
## Features
Automated scheduling of livestreams on the following platforms using Selenium Chrome automation.
* Odysee
* Locals
* Rumble
- The RTMP information from each platform will be grabbed at the end of the schedule and then input into Rumble Studio for Livestreaming.

Binary file not shown.
Loading…
Cancel
Save