diff --git a/README.md b/README.md index 5f10b73..622b4dc 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,21 @@ # Discord-Radio-Bot This project is intended to allow users in discord to be able to listen to their favorite radio stations, *music or other ;)*, while talking to their friends. +## Setup +1. Install Python 3.X +2. Install the pip packages found in the 'Requirements.txt' file +3. Run ```main.py``` with Python +4. Follow the prompts in the terminal + +### Understanding Audio Input +This title can be a bit confusing. The bot will display both 'input' and 'output' devices but not always *all* devices connected. +Voicemeeter is **highly** recommended for this bot. See a detailed guide on how to use Voicemeeter Banana's (identical in function to Potato or Voicemeeter) I/O [here](https://gist.github.com/Immotay/fa47b1105aaed89a284106ae2ee9b66f). + +### Changing audio sources +To change the audio source, simply delete the ```config.ini``` that was generated and restart the bot. +It will re-do the setup and allow you to select a new device. + ###To-Do -- Move cogs to their own files - Interact with soapysdr directly from the bot - Allow chat interaction with soapysdr - Transcode radio transmissions to text diff --git a/bot.py b/bot.py index 7383c8b..d3b0cda 100644 --- a/bot.py +++ b/bot.py @@ -1,67 +1,8 @@ +import os + import discord import sound -import asyncio -import datetime from discord.ext import commands -from discord.ext.tasks import loop - - -class WillieTimer(commands.Cog): - def __init__(self, bot, mention_group='Superadmins', channel_id=757379843792044102): - self.bot = bot - self.mention_group = str(mention_group) - self.channel_id = int(channel_id) - - @loop(minutes=1) - async def bg_timer(self): - await self.bot.wait_until_ready() - seconds_until_next_minute = int(60 - int(datetime.datetime.now().strftime('%S'))) - if not seconds_until_next_minute <= 2: - await asyncio.sleep(seconds_until_next_minute) - if datetime.datetime.now().strftime('%H:%M') in ("04:20", "16:20"): - print(f"It's {datetime.datetime.now().strftime('%H:%M:%S')}!") - channel = self.bot.get_channel(id=self.channel_id) - guild = channel.guild - role_id = discord.utils.get(guild.roles, name=self.mention_group) - print(role_id) - print(role_id.id) - await channel.send(f"<@&{role_id.id}> It's 4:20! It's time to light up!") - - @commands.command() - async def start420(self, ctx, *, member: discord.Member = None): - member = member or ctx.author.display_name - await ctx.send(f"Thanks {member.display_name}, Willie will be in touch soon...") - self.bg_timer.start() - - @commands.command() - async def stop420(self, ctx, *, member: discord.Member = None): - member = member or ctx.author.display_name - await ctx.send(f"Ok {member}, Willie will go back to writing music...") - self.bg_timer.stop() - - @commands.command() - async def chchn(self, ctx, message, *, member: discord.Member = None): - member = member or ctx.author.display_name - try: - message = int(message) - if message and len(str(message)) == len(str(self.channel_id)): - self.channel_id = message - print(message) - except: - await ctx.send(f"{member}, {message} is not a valid channel ID, please try again") - pass - - @commands.command() - async def chmtn(self, ctx, message, *, member: discord.Member = None): - member = member or ctx.author.display_name - try: - message = str(message) - if message and len(str(message)) == len(str(self.channel_id)): - self.mention_group = message - print(message) - except: - await ctx.send(f"{member}, {message} is not a valid role, please try again") - pass class Bot(commands.Bot): @@ -74,16 +15,18 @@ class Bot(commands.Bot): self.add_commands() + self.check_for_modules() + def start_bot(self): - self.add_cog(WillieTimer(self)) + #self.add_cog(WillieTimer(self)) self.run(self.BOT_TOKEN) def add_commands(self): - @self.command() + @self.command(help="Use this to test if the bot is alive", brief="Sends a 'pong' in response") async def ping(ctx): await ctx.send('pong') - @self.command() + @self.command(help="Use this command to join the bot to your channel", brief="Joins the voice channel that the caller is in") async def join(ctx, *, member: discord.Member = None): member = member or ctx.author.display_name await self.wait_until_ready() @@ -102,7 +45,7 @@ class Bot(commands.Bot): else: await ctx.send("Opus won't load") - @self.command() + @self.command(help="Use this command to have the bot leave your channel", brief="Leaves the current voice channel") async def leave(ctx): await ctx.voice_client.disconnect() @@ -118,3 +61,9 @@ class Bot(commands.Bot): else: return False + + def check_for_modules(self): + for folder_name in os.listdir("modules"): + if os.path.exists(os.path.join("modules", folder_name, "cog.py")): + print(f"Loaded extension: {folder_name}") + self.load_extension(f"modules.{folder_name}.cog") \ No newline at end of file diff --git a/modules/WillieTimer/cog.py b/modules/WillieTimer/cog.py new file mode 100644 index 0000000..537924d --- /dev/null +++ b/modules/WillieTimer/cog.py @@ -0,0 +1,70 @@ +import asyncio +import datetime +import discord +from discord.ext import commands +from discord.ext.tasks import loop + + +class WillieTimer(commands.Cog): + def __init__(self, bot, mention_group='Superadmins', channel_id=757379843792044102): + self.bot = bot + self.mention_group = str(mention_group) + self.channel_id = int(channel_id) + + @loop(minutes=1) + async def bg_timer(self): + await self.bot.wait_until_ready() + seconds_until_next_minute = int(60 - int(datetime.datetime.now().strftime('%S'))) + if not seconds_until_next_minute <= 2: + await asyncio.sleep(seconds_until_next_minute) + if datetime.datetime.now().strftime('%H:%M') in ("04:20", "16:20"): + print(f"It's {datetime.datetime.now().strftime('%H:%M:%S')}!") + channel = self.bot.get_channel(id=self.channel_id) + guild = channel.guild + role_id = discord.utils.get(guild.roles, name=self.mention_group) + print(role_id) + print(role_id.id) + await channel.send(f"<@&{role_id.id}> It's 4:20! It's time to light up!") + + @commands.command(help="Use this command to start the background task to wait for 4:20", + brief="Starts the 4:20 clock") + async def start420(self, ctx, *, member: discord.Member = None): + member = member or ctx.author.display_name + await ctx.send(f"Thanks {member}, Willie will be in touch soon...") + self.bg_timer.start() + + @commands.command(help="", brief="Stops the 4:20 clock") + async def stop420(self, ctx, *, member: discord.Member = None): + member = member or ctx.author.display_name + await ctx.send(f"Ok {member}, Willie will go back to writing music...") + self.bg_timer.stop() + + @commands.command(help="Example '@Greada chchn 757379843792044102'", + brief="Change the channel the bot chats in at 4:20") + async def chchn(self, ctx, message, *, member: discord.Member = None): + member = member or ctx.author.display_name + try: + message = int(message) + if message and len(str(message)) == len(str(self.channel_id)): + self.channel_id = message + print(message) + except: + await ctx.send(f"{member}, {message} is not a valid channel ID, please try again") + pass + + @commands.command(help="Example '@Greada chmtn 'Willies Friends'", + brief="Use this command to change who the bot mentions at 4:20") + async def chmtn(self, ctx, message, *, member: discord.Member = None): + member = member or ctx.author.display_name + try: + message = str(message) + if message and len(str(message)) == len(str(self.channel_id)): + self.mention_group = message + print(message) + except: + await ctx.send(f"{member}, {message} is not a valid role, please try again") + pass + + +def setup(bot: commands.Bot): + bot.add_cog(WillieTimer(bot))