From 5fad615f39dd4e8fcbac887f547feed3a3657475 Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sat, 11 Dec 2021 00:54:10 -0500 Subject: [PATCH] Added Digital2Discord module Updated bot to allow live reloading Updated WillieTimer with a lock to ensure two sessions are not opened, causing an error Added output for config keys Updated README.md --- BotResources.py | 6 +++ README.md | 10 ++-- bot.py | 20 +++++++ modules/Digital2Discord/cog.py | 56 ++++++++++++++++++++ modules/{.WillieTimer => WillieTimer}/cog.py | 28 ++++++++-- 5 files changed, 110 insertions(+), 10 deletions(-) create mode 100644 modules/Digital2Discord/cog.py rename modules/{.WillieTimer => WillieTimer}/cog.py (72%) diff --git a/BotResources.py b/BotResources.py index 9f12683..fe7e26f 100644 --- a/BotResources.py +++ b/BotResources.py @@ -5,6 +5,7 @@ from os.path import exists def check_if_config_exists(): if exists('./config.ini'): config = configparser.SafeConfigParser() + config.read('./config.ini') if config.has_section('Bot_Info') and config.has_section('Device'): return True else: @@ -24,6 +25,11 @@ def read_config_file(): 'Mention Group': str(config['Bot_Info']['Mention_Group']), 'Channel ID': int(config['Bot_Info']['Channel_ID']) } + + print("Found config options:") + for key in config_return.keys(): + print(f"\t{key} : {config_return[key]}") + return config_return diff --git a/README.md b/README.md index 3036a56..6bbab03 100644 --- a/README.md +++ b/README.md @@ -19,13 +19,13 @@ It will re-do the setup and allow you to select a new device. ### To-Do - [ ] Add method for user to change audio device without redoing entire config file -- [X] Update WillieTimer with replies to all msgs - - [X] Add saving of changes to mention and channel - - [ ] Add a pool of responses to 4:20 -- [ ] Send a message details of digital comms - - [ ] Send only one message at join and update this message with details of digital comms - [ ] Interact with soapysdr directly from the bot - [ ] Allow chat interaction with soapysdr - [ ] Transcode radio transmissions to text - [x] Move cogs to their own files - [X] Add a disable function for cogs +- [X] Send a message details of digital comms + - [X] Send only one message at join and update this message with details of digital comms +- [X] Update WillieTimer with replies to all msgs + - [X] Add saving of changes to mention and channel + - [X] Add a pool of responses to 4:20 \ No newline at end of file diff --git a/bot.py b/bot.py index 0ee622e..43f5b61 100644 --- a/bot.py +++ b/bot.py @@ -52,6 +52,15 @@ class Bot(commands.Bot): async def leave(ctx): await ctx.voice_client.disconnect() + @self.command(name='reload', hidden=True) + async def _reload(ctx, module: str, member: discord.Member = None): + """Reloads a module.""" + member = member or ctx.author.display_name + if self.reload_modules(module): + await ctx.send(f"Ok {member}, I reloaded {module}") + else: + await ctx.send(f"{member}, something went wrong. Please check the console") + def check_device(self): for device, index in self.Devices_List: if int(index) == self.DEVICE_ID and str(device) == self.DEVICE_NAME: @@ -72,3 +81,14 @@ class Bot(commands.Bot): elif 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") + + def reload_modules(self, module): + try: + self.unload_extension(f"modules.{module}.cog") + print(f"Unloaded {module}") + self.load_extension(f"modules.{module}.cog") + print(f"Loaded {module}") + return True + except Exception as e: + print(e) + return False diff --git a/modules/Digital2Discord/cog.py b/modules/Digital2Discord/cog.py new file mode 100644 index 0000000..536dc0e --- /dev/null +++ b/modules/Digital2Discord/cog.py @@ -0,0 +1,56 @@ +import re +import discord +from discord.ext import commands +from discord.ext.tasks import loop + +regex_string = re.compile('(?:\d{4}/\d{2}/\d{2})[ ]*(?:\d{2}:\d{2}:\d{2})[ ]*(?:Group call;)[ ]*(?:TG=\d*)[ ]*(?:\[[A-Za-z]+\])?[ ]*(?:RID=(\d+))[ ]*(?:\[([-0-9A-Za-z]+)\])?[ ]*(?:[0-9]+s)?') + +class Discord2Digital(commands.Cog): + def __init__(self, bot): #, mention_group='Superadmins', channel_id=757379843792044102): + self.bot = bot + self.message = None + self.last_radio_id = "-" + self.lock = False + + @loop(seconds=.25) + async def file_watcher(self): + with open('C:/Users/Logan/Downloads/Installers/Cubic-Build/DSDPlus/DSDPlus.event', 'r') as event_file: + event = event_file.readlines()[-1] + cur_radio_id = regex_string.findall(str(event)) + if cur_radio_id and cur_radio_id != self.last_radio_id: + self.last_radio_id = cur_radio_id + radio_id = cur_radio_id[0][0] + if cur_radio_id[0][1]: + message_name = cur_radio_id[0][1] + embed_msg = discord.Embed(title="Last Known Radio ID", description=f"{radio_id}", color=0x00ff00) + if 'message_name' in locals(): + embed_msg.add_field(name="Unit Name", value=f"{message_name}", inline=True) + await self.message.edit(embed=embed_msg) + + @commands.command(help="This command will start the display of Radio IDs and Unit names (if known) for digital comms", + brief="Starts the display for digital comms") + async def display_rid(self, ctx, *, member: discord.Member = None): + member = member or ctx.author.display_name + if not self.lock: + await ctx.send(f"Ok {member}, I will display the Radio IDs of digital communications") + embed_msg = discord.Embed(title="Last Known Radio ID", description=f"-", color=0x00ff00) + self.message = await ctx.send(embed=embed_msg) + self.lock = True + self.file_watcher.start() + else: + await ctx.send(f"{member}, there's already a display running. If you want me to stop it, @ me and say 'stop_display'") + + @commands.command(help="", brief="Stops the digital comm display") + async def stop_display(self, ctx, member: discord.Member = None): + member = member or ctx.author.display_name + if self.lock: + self.file_watcher.stop() + self.message.delete() + print('Stopping monitor') + self.lock = False + else: + await ctx.send(f"{member}, there's no display running. If you want me to start one, @ me and say 'display_rid'") + + +def setup(bot: commands.Bot): + bot.add_cog(Discord2Digital(bot)) diff --git a/modules/.WillieTimer/cog.py b/modules/WillieTimer/cog.py similarity index 72% rename from modules/.WillieTimer/cog.py rename to modules/WillieTimer/cog.py index 3230130..79d718c 100644 --- a/modules/.WillieTimer/cog.py +++ b/modules/WillieTimer/cog.py @@ -1,6 +1,7 @@ import asyncio import datetime import discord +from random import choice from discord.ext import commands from discord.ext.tasks import loop from BotResources import write_config_file @@ -11,6 +12,15 @@ class WillieTimer(commands.Cog): self.bot = bot self.mention_group = str(self.bot.Default_Mention_Group) self.channel_id = int(self.bot.Default_Channel_ID) + self.lock = False + self.message_pool = [ + "It's 4:20! It's time to light up!", + "Willie wanted to let you know that IT'S 4:20!", + "Can you smell what the rock is cooking? No? PROBABLY BECAUSE IT'S 4:20!", + "Oh say can you see. By the blunts early light. IT'S 4:20!", + "Hey, are you busy? I just wanted to let you know IT'S 4:20!", + "You know, the funny thing about time is we often forget to pay attention to it and we miss out on things. ALMOST LIKE 4:20! LIGHT UP!" + ] @loop(minutes=1) async def bg_timer(self): @@ -21,20 +31,28 @@ class WillieTimer(commands.Cog): 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) - await channel.send(f"<@&{self.bot_get_role().id}> It's 4:20! It's time to light up!") + await channel.send(f"<@&{self.bot_get_role().id}> {choice(self.message_pool)}") @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() + if not self.lock: + await ctx.send(f"Thanks {member}, Willie will be in touch soon...") + self.lock = True + self.bg_timer.start() + else: + await ctx.send(f"I already told Willie {member}, if you want me to tell him to stop, @ me and say 'stop420'") @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() + if self.lock: + await ctx.send(f"Ok {member}, Willie will go back to writing music...") + self.bg_timer.stop() + self.lock = False + else: + await ctx.send(f"{member} I haven't told Willie yet. If you want me to, @ me and say 'start420'") @commands.command(help="Example '@Greada chchn 757379843792044102'", brief="Change the channel the bot chats in at 4:20")