Compare commits

...

3 commits

Author SHA1 Message Date
febb7556cf
Never use except exception it's a bad idea 2024-08-04 17:20:54 -04:00
5cb5bcad23
add voteskip 2024-08-04 17:10:12 -04:00
95af2f6c82
further improvements to youtube handler 2024-08-04 12:33:31 -04:00

76
bot.py
View file

@ -3,6 +3,7 @@ from selenium import webdriver
from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import NoSuchElementException, ElementNotVisibleException, TimeoutException
from time import sleep from time import sleep
import time import time
import disnake import disnake
@ -24,12 +25,13 @@ logger.addHandler(handler)
queue = [] queue = []
user_queue = [] user_queue = []
skip_list = []
shuffle = False shuffle = False
load_dotenv() load_dotenv()
options = Options() options = Options()
options.profile = webdriver.FirefoxProfile(os.getenv("PROFILE_PATH")) options.profile = webdriver.FirefoxProfile(os.getenv("PROFILE_PATH"))
driver = webdriver.Firefox(options=options) driver = webdriver.Firefox(options=options)
intents = disnake.Intents.default() intents = disnake.Intents.all()
intents.message_content = False intents.message_content = False
bot = commands.Bot(intents=intents, command_prefix=".", test_guilds=[int(os.getenv("GUILD_ID"))]) bot = commands.Bot(intents=intents, command_prefix=".", test_guilds=[int(os.getenv("GUILD_ID"))])
@ -41,29 +43,28 @@ async def on_ready():
def play_video(videourl): def play_video(videourl):
driver.get(videourl) driver.get(videourl)
try: try:
elem = WebDriverWait(driver, 5, 0.2, None).until(lambda x: x.find_element(By.CLASS_NAME, "ytp-fullscreen-button")) elem = WebDriverWait(driver, 8, 0.2, None).until(lambda x: x.find_element(By.CLASS_NAME, "ytp-fullscreen-button"))
sleep(1) sleep(1)
elem.send_keys(Keys.RETURN) elem.send_keys(Keys.RETURN)
except Exception: except (NoSuchElementException,TimeoutException) as e:
print(e)
return #if this errors there is no fullscreen options, such as playlists, so skip the link return #if this errors there is no fullscreen options, such as playlists, so skip the link
try: try:
elem = driver.find_element(By.XPATH, '//button[@data-tooltip-target-id="ytp-autonav-toggle-button"][@aria-label="Autoplay is on"]') elem = driver.find_element(By.XPATH, '//button[@data-tooltip-target-id="ytp-autonav-toggle-button"][@aria-label="Autoplay is on"]')
elem.send_keys(Keys.RETURN) elem.send_keys(Keys.RETURN)
except Exception: except (NoSuchElementException,ElementNotVisibleException,TimeoutException):
pass pass
#TODO: see if this is actually needed
try: try:
elem = WebDriverWait(driver, 10, 0.2, (ElementNotVisibleException)).until(lambda x: x.find_element(By.XPATH, '//button[@aria-label="Dismiss"]').is_displayed()) elem = WebDriverWait(driver, 5, 0.2, (NoSuchElementException,ElementNotVisibleException)).until(lambda x: x.find_element(By.XPATH, '//button[@aria-label="Dismiss"]'))
elem.send_keys(Keys.RETURN) elem.send_keys(Keys.RETURN)
except Exception: except (NoSuchElementException,ElementNotVisibleException,TimeoutException) as e:
pass print(e)
try: try:
endscreen = driver.find_element(By.CLASS_NAME, "html5-endscreen") elem = WebDriverWait(driver, (float(os.getenv("MAX_MIN")) * 60), 1, None).until(lambda x: x.find_element(By.CLASS_NAME, "html5-endscreen").is_displayed())
timeout = (float(os.getenv("MAX_MIN")) * 60) + time.time() except (NoSuchElementException,ElementNotVisibleException,TimeoutException) as e:
except Exception: print(e)
sleep(1)
return #same as above return #same as above
while str(endscreen.get_attribute('style')) == "display: none;" and time.time() < timeout:
pass
sleep(1) sleep(1)
return return
@ -192,6 +193,7 @@ async def toggleplayback(inter: disnake.AppCmdInter):
@bot.slash_command( @bot.slash_command(
name="skip", name="skip",
description="skips the current video", description="skips the current video",
default_member_permissions=disnake.Permissions(8192),
) )
async def skip(inter: disnake.AppCmdInter): async def skip(inter: disnake.AppCmdInter):
await inter.response.defer(ephemeral=False) await inter.response.defer(ephemeral=False)
@ -202,6 +204,7 @@ async def skip(inter: disnake.AppCmdInter):
except asyncio.CancelledError: except asyncio.CancelledError:
queue.pop(0) queue.pop(0)
user_queue.pop(0) user_queue.pop(0)
skip_list.clear()
if len(queue) < 1: if len(queue) < 1:
driver.get(f"file://{os.getcwd()}/waitingforvideo.png") driver.get(f"file://{os.getcwd()}/waitingforvideo.png")
driver.fullscreen_window() driver.fullscreen_window()
@ -209,6 +212,51 @@ async def skip(inter: disnake.AppCmdInter):
queuetask = asyncio.create_task(queuehandler()) queuetask = asyncio.create_task(queuehandler())
await inter.edit_original_response("skipped") await inter.edit_original_response("skipped")
@bot.slash_command(
name="voteskip",
description="vote to skip the current video",
)
async def voteskip(inter: disnake.AppCmdInter):
await inter.response.defer(ephemeral=False)
if not inter.user.voice:
await inter.edit_original_response("You are not in the voice channel")
return
if inter.user.id in skip_list:
await inter.edit_original_response("You have already voted to skip this video")
return
vc = inter.user.voice.channel.members #this could be better due to potential for abuse, but it's fine for now
print(inter.user.voice.channel.name)
broadcaster = False
for m in vc:
if m.voice.self_video or m.voice.self_stream:
broadcaster = True
break
if not broadcaster:
await inter.edit_original_response("No one is playing video so how can this be the correct vc?")
return
skip_list.append(inter.user.id)
print(len(skip_list))
print(math.floor(len(vc)/2))
print(vc)
if len(skip_list) >= (math.floor(len(vc)/2)):
global queuetask
queuetask.cancel()
try:
await queuetask
except asyncio.CancelledError:
queue.pop(0)
user_queue.pop(0)
skip_list.clear()
if len(queue) < 1:
driver.get(f"file://{os.getcwd()}/waitingforvideo.png")
driver.fullscreen_window()
else:
queuetask = asyncio.create_task(queuehandler())
await inter.edit_original_response("skipped as sufficient votes were reached")
else:
await inter.edit_original_response(f"**{inter.user.display_name}** has voted to skip the video, {len(skip_list)}/{math.floor(len(vc)/2)}")
@bot.slash_command( @bot.slash_command(
name="remove", name="remove",
description="removes a video from the queue", description="removes a video from the queue",
@ -235,10 +283,10 @@ async def queuehandler():
random.shuffle(user_queue) random.shuffle(user_queue)
print(queue) print(queue)
print(user_queue) print(user_queue)
driver.maximize_window()
await loop.run_in_executor(None, play_video, queue[0]) await loop.run_in_executor(None, play_video, queue[0])
queue.pop(0) queue.pop(0)
user_queue.pop(0) user_queue.pop(0)
skip_list.clear()
driver.get(f"file://{os.getcwd()}/waitingforvideo.png") driver.get(f"file://{os.getcwd()}/waitingforvideo.png")
driver.fullscreen_window() driver.fullscreen_window()