Advertisement
HamBrick327

grooby 8/7/23

Aug 8th, 2023
31
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.12 KB | None | 0 0
  1. from disnake.ext import commands
  2. from pytube import Playlist, YouTube
  3. from youtubesearchpython import VideosSearch
  4. # from time import sleep
  5. # import threading
  6. import disnake
  7. import os
  8. import asyncio
  9. # import youtube_dl
  10.  
  11. '''
  12. TODO add pause/resume, maybe with nested bot events NOT WITH NESTED BOT COMMANDS
  13. TODO add loop command
  14. TODO add skip command
  15. TODO add reactions to avoid spam (maybe)
  16.  
  17. BUG doesn't remove the last song from queue
  18. BUG thinks it's in a vc when it is, in fact, not
  19. FEATURE refuses to play megalovania
  20.  
  21.  
  22. TODO refactor to use the youtube API directly instead of uisng the pytube library *pain*
  23. '''
  24.  
  25.  
  26. if os.name == "posix":
  27. exe = 'ffmpeg'
  28. elif os.name == "nt":
  29. exe = 'C:/ffmpeg-5.1.2-essentials_build/bin/ffmpeg.exe'
  30. ## setting the cwd because I want to run the bot on startup and I'm too lazy to find the correct solution
  31. os.chdir("Y:\\Dropbox\\Programming\\python\\chineseGroovy")
  32.  
  33. cwd = os.getcwd()
  34. queue = os.path.join(os.getcwd(), "queue")
  35. hardcoded = os.path.join(cwd, "hardcodedAudio")
  36. token = os.getenv('GROOBYTOKEN')
  37.  
  38.  
  39. def clearQ():
  40. for file in os.listdir(queue):
  41. if file.endswith(".mp3") or file.endswith(".mp4"):
  42. os.remove(os.path.join(queue, file))
  43.  
  44. def getAudio(url):
  45. ## doing it the pytube way
  46. video = YouTube(url)
  47. audio = video.streams.filter(only_audio=True).first() ## download only the video's audio, but still as a mp4 file
  48. output = audio.download(output_path=queue) ## set the output destination
  49.  
  50. ## change the file extension, ooga booga style
  51. name, ext = os.path.splitext(output)
  52. ext = '.mp3'
  53. os.rename(output, (name + ext))
  54. return name
  55.  
  56. ## bot settings
  57. command_sync_flags = commands.CommandSyncFlags.none()
  58. command_sync_flags.sync_commands = False
  59. intents = disnake.Intents.default()
  60. intents.message_content = True
  61. intents.messages = True
  62. intents.voice_states = True
  63.  
  64.  
  65. bot = commands.Bot(
  66. command_prefix='-',
  67. command_sync_flags=command_sync_flags,
  68. intents=intents
  69. )
  70.  
  71. @bot.event
  72. async def on_ready():
  73. print("bot is ready")
  74.  
  75. @bot.command() ## has the bot join the user's voice channel
  76. async def join(ctx):
  77. ctx.send("-join is no longer a valid command, use -play <song name> instead")
  78.  
  79.  
  80. @bot.command() ## plays bruh the same way the chatGTP code does, just with @bot instead of @client
  81. async def bruh(ctx):
  82. await ctx.send("moment")
  83. voice_channel = ctx.author.voice.channel
  84. vc = await voice_channel.connect()
  85.  
  86. vc.play(disnake.FFmpegPCMAudio("./bruh.mp3", executable=exe))
  87.  
  88. while vc.is_playing():
  89. await asyncio.sleep(1)
  90. vc.stop()
  91. await vc.disconnect()
  92.  
  93. @bot.command() ## THE ACTUAL PLAY COMMAND 23:49 1/20
  94. async def play(ctx):
  95.  
  96.  
  97. if ctx.message.guild.voice_client == None:
  98. ## connect to the user's voice channel
  99. voice_channel = ctx.author.voice.channel
  100. vc = await voice_channel.connect()
  101. else:
  102. vc = ctx.message.guild.voice_client
  103.  
  104.  
  105. ## if the query is megalovania because searching for megalovania isn't allowed
  106. if ctx.message.content.endswith("megalovania"): ## IF YOU CHANGE THE BOT PREFIX CHANGE THE HARD CODED TEXT
  107.  
  108. if os.name == 'posix':
  109. os.system("cp ./hardcodedAudio/Megalovania.mp3 ./queue/")
  110. elif os.name == 'nt':
  111. os.system('copy ./hardcodedAudio\\Megalovania.mp3 ./queue\\')
  112.  
  113. vc.play(disnake.FFmpegPCMAudio(os.path.join(queue, "Undertale - Megalovania.mp3"), executable=exe))
  114. await ctx.send("no")
  115. await vc.disconnect()
  116. return
  117.  
  118. ## if the query is dsi shop theme because searching for it breaks bot
  119. if ctx.message.content.endswith("dsi shop theme"): ## IF YOU CHANGE THE BOT PREFIX CHANGE THE HARD CODED TEXT
  120.  
  121. if os.name == 'posix':
  122. os.system('cp ./hardcodedAudio/Nintendo DSi Shop Theme 10 HOUR LOOP.mp3 ./queue/')
  123. elif os.name == 'nt':
  124. os.system('copy ./hardcodedAudio\\Nintendo DSi Shop Theme 10 HOUR LOOP.mp3 ./queue\\')
  125.  
  126. vc.play(disnake.FFmpegPCMAudio(os.path.join(queue, "Nintendo DSi Shop Theme 10 HOUR LOOP.mp3"), executable=exe))
  127. await ctx.send("Now playing **Nintendo DSi Shop Theme 10 HORUR LOOP**")
  128. while vc.is_playing() or vc.is_paused():
  129. await asyncio.sleep(1)
  130.  
  131.  
  132. await ctx.send("Grooby:tm: is contemplating life...")
  133. name = ''
  134. if not ctx.message.content.endswith("-play"): ## if the command is followed by an argument
  135. argument = ctx.message.content.split(" ", 1)[1]
  136. if "://" in argument:
  137. name = getAudio(argument)
  138.  
  139. print(name, " downloaded")
  140.  
  141. elif "playlist" in argument: ## if the link is a playlist
  142. playlist = Playlist(argument)
  143. print(f"Number of videos in plalist: {len(playlist.video_urls)}") ################## I hope this works but it probably won't ################
  144.  
  145. for i in range(len(playlist.video_urls)):
  146. url = playlist.video_urls[i]
  147.  
  148. getAudio(url)
  149. else:
  150. search = VideosSearch(argument, limit=1)
  151.  
  152. name = getAudio(search.result()['result'][0]['link'])
  153. else:
  154. await ctx.send("actually give me a song to play")
  155.  
  156. directory = os.listdir(queue)
  157.  
  158. ## playing the generated mp3 file
  159. print("name1: ", name)
  160. print("directory: ", directory[0])
  161.  
  162. while directory != []:
  163. name = os.path.join(queue, directory[0])
  164. print("name2: ", name)
  165. vc.play(disnake.FFmpegPCMAudio(name, executable=exe))
  166. await ctx.send(f"now playing **{directory[0].replace('.mp3', '')}**")
  167.  
  168. while vc.is_playing() or vc.is_paused(): ## while the bot is playing audio
  169. await asyncio.sleep(1)
  170. directory = os.listdir(queue)
  171.  
  172. try:
  173. os.remove(name) ## avoiding the bug that might be caused by the -skip command
  174. except:
  175. pass
  176.  
  177. directory = os.listdir(queue)
  178.  
  179. print("directory2: ", os.listdir(queue))
  180.  
  181. # os.remove(name + ".mp3")
  182. directory = os.listdir(queue)
  183.  
  184. vc.stop()
  185. await vc.disconnect() ## bot disconnects when it is done playing audio
  186.  
  187.  
  188. @bot.command() ## leaves voice channel
  189. async def leave(ctx):
  190. vc = ctx.message.guild.voice_client
  191. await vc.disconnect()
  192. await ctx.send("left the vc")
  193. await asyncio.sleep(1)
  194. clearQ()
  195.  
  196. @bot.command() ## same as the leave
  197. async def stop(ctx):
  198. vc = ctx.message.guild.voice_client
  199. await vc.disconnect()
  200. await ctx.send("left the vc")
  201. await asyncio.sleep(1)
  202. clearQ()
  203.  
  204. @bot.command() ## the same as the leave command
  205. async def begone(ctx):
  206. vc = ctx.message.guild.voice_client
  207. await vc.disconnect()
  208. await ctx.send("left the vc")
  209. await asyncio.sleep(1)
  210. clearQ()
  211.  
  212. @bot.command() ## creator credits credits
  213. async def credits(ctx):
  214. credited = True
  215.  
  216. if ctx.author.voice.channel != None:
  217. voice_channel = ctx.author.voice.channel
  218. vc = await voice_channel.connect()
  219. vc.play(disnake.FFmpegPCMAudio(os.path.join(cwd, "credits.mp3"), executable=exe))
  220.  
  221. while vc.is_playing():
  222. await asyncio.sleep(1)
  223.  
  224. ## this code is horrible but idc
  225. if credited:
  226. await ctx.send("Side Character: Family Guy")
  227. await asyncio.sleep(5)
  228. await ctx.send("Emotional Support: Deaner")
  229. await asyncio.sleep(5)
  230. await ctx.send("The actual programmer: HoomBrook")
  231. credited = False
  232. vc.stop()
  233. await vc.disconnect()
  234.  
  235. @bot.command(name="clear", aliases=["clearQ", "clearQueue"]) ## clear queue
  236. async def clear(ctx):
  237. if ctx.author.voice.channel == ctx.message.guild.voice_client:
  238. clearQ()
  239. await ctx.send("queue cleared")
  240.  
  241. @bot.command()
  242. async def nowplaying(ctx):
  243. directory = os.listdir(queue)
  244. directory = [os.path.join(os.getcwd(), "queue", f) for f in directory]
  245. directory.sort(key=lambda x: os.path.getmtime(x))
  246. [i.replace(os.getcwd(), '') for i in directory]
  247.  
  248. # await ctx.send(f"now playing **{directory[0].replace((queue + "\\"), '').replace('.mp3', '')}**")
  249.  
  250. @bot.command()
  251. async def pause(ctx):
  252. vc = ctx.message.guild.voice_client
  253. if type(vc) != None:
  254. try:
  255. vc.pause()
  256. await ctx.send("paused audio")
  257. except:
  258. await ctx.send("nothing to pause")
  259. else:
  260. await ctx.send("not in vc")
  261.  
  262. @bot.command()
  263. async def resume(ctx):
  264. vc = ctx.message.guild.voice_client
  265. if type(vc) != None:
  266. if vc.is_paused():
  267. vc.resume()
  268. else:
  269. await ctx.send("Nothing to resume")
  270. else:
  271. await ctx.send("not in vc")
  272.  
  273. @bot.command()
  274. async def skip(ctx):
  275. vc = ctx.message.guild.voice_client
  276. directory = os.listdir(queue)
  277. directory = [os.path.join(os.getcwd(), "queue", f) for f in directory]
  278. directory.sort(key=lambda x: os.path.getmtime(x))
  279.  
  280. vc.stop()
  281. print("skip directory: ", directory)
  282. os.remove(os.path.join(queue, directory[0]))
  283. print("skip directory2: ", directory)
  284. await ctx.send("track skipped")
  285.  
  286. @bot.command()
  287. async def down(ctx):
  288. print(ctx.message.author)
  289. print(ctx.message.author.id)
  290. if ctx.message.author == "HamBrick":
  291. print("owner detected, bot is changing status")
  292. bot.status("Bot is currently down")
  293.  
  294. @bot.command()
  295. async def up(ctx):
  296. print(ctx.message.author)
  297. print(ctx.message.author.id)
  298. if ctx.message.author == "HamBrick":
  299. print("owner dectected, but is now up")
  300. bot.status("Bot is now up!")
  301.  
  302. @bot.command() ## the same as the leave command
  303. async def jace(ctx):
  304. clearQ()
  305.  
  306. if ctx.author.voice.channel != None:
  307. voice_channel = ctx.author.voice.channel
  308. vc = await voice_channel.connect()
  309. vc.play(disnake.FFmpegPCMAudio(os.path.join(hardcoded, "jace.mp3"), executable=exe))
  310.  
  311. while vc.is_playing():
  312. await asyncio.sleep(1)
  313.  
  314. vc.stop()
  315. await vc.disconnect()
  316.  
  317. bot.run(token)
  318.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement