From 62968654d2544d4e924991566e2e50e87184f92c Mon Sep 17 00:00:00 2001 From: Logan Cusano Date: Sun, 27 Feb 2022 13:40:21 -0500 Subject: [PATCH] v2.0.1 - Args - Better configs - Other shit too, idr --- BotResources.py | 12 ++- bot.py | 123 ++++++++++++++---------- main.py | 73 ++++++++++++-- opus/{libopus.dll => libopus_amd64.dll} | Bin opus/{libopus.so => libopus_armv7l.so} | Bin 5 files changed, 146 insertions(+), 62 deletions(-) rename opus/{libopus.dll => libopus_amd64.dll} (100%) rename opus/{libopus.so => libopus_armv7l.so} (100%) diff --git a/BotResources.py b/BotResources.py index b205b11..b0d9ec6 100644 --- a/BotResources.py +++ b/BotResources.py @@ -2,8 +2,13 @@ import sound import configparser from os.path import exists -PDB_ACCEPTABLE_HANDLERS = ['gqrx', 'op25'] -PDB_KNOWN_BOT_IDS = [756327271597473863, 915064996994633729, 943742040255115304] +PDB_ACCEPTABLE_HANDLERS = {'gqrx': { + 'Modes': ['wfm', 'fm'] + }, + 'op25': { + 'Modes': ['d', 'p25'] + }} +PDB_KNOWN_BOT_IDS = {756327271597473863: "Greada", 915064996994633729: "Jorn", 943742040255115304: "Brent"} def check_if_config_exists(): @@ -172,7 +177,8 @@ def get_handler(): handler = str(input(f"Please enter the name of the handler you would like to use:\t")) if handler in PDB_ACCEPTABLE_HANDLERS: return handler - elif handler == '': + elif handler == ['', "none"]: + handler = "None" return handler diff --git a/bot.py b/bot.py index bf204bf..d08269a 100644 --- a/bot.py +++ b/bot.py @@ -116,7 +116,8 @@ class Bot(commands.Bot): @self.command(help="Use this command to have the bot leave your channel", brief="Leaves the current voice channel") - async def leave(ctx): + async def leave(ctx, member: discord.Member = None): + member = member or ctx.author.display_name if self.Bot_Connected: # Stop the sound handlers self.streamHandler.clean_up() @@ -128,9 +129,23 @@ class Bot(commands.Bot): self.stop_sdr() # 'Unlock' the bot self.Bot_Connected = False + await ctx.send(f"Goodbye {str(member).capitalize()}.") + else: + await ctx.send(f"{str(member).capitalize()}, I'm not in a channel") # Add commands for GQRX and OP25 - if self.Handler == 'gqrx' or self.Handler == 'op25': + if self.Handler in BotResources.PDB_ACCEPTABLE_HANDLERS.keys(): + # Command to display the current config + @self.command(name='displayprofile', help="Use this command to display the current configuration of the bot.\n" + "Example command:\n" + "\t@ displayprofile", + breif="Display current bot config") + async def _displayprofile(ctx, member: discord.Member = None): + member = member or ctx.author.display_name + message = self.display_current_radio_config() + await ctx.send(f"Ok {str(member).capitalize()}\n{message}") + + # Command to change the current frequency and mode @self.command(name='chfreq', help="Use this command to change the frequency the bot is listening to.\n" "Example GQRX command:\n" "\tTune to 104.7Mhz Wideband FM (Radio) - '@ chfreq wfm 104700000\n" @@ -140,21 +155,13 @@ class Bot(commands.Bot): brief="Changes radio frequency") async def chfreq(ctx, mode: str, freq: str, member: discord.Member = None): # Possible band-types that can be used - possible_modes = [] - - if self.Handler == 'gqrx': - possible_modes = ['wfm', 'fm'] - - elif self.Handler == 'op25': - possible_modes = ['d', 'p25'] - member = member or ctx.author.display_name # Check to make sure the frequency input matches the syntax needed if len(freq) >= 6: self.freq = freq # Check to make sure the selected mode is valid - if mode in possible_modes: + if mode in self.possible_modes: self.mode = mode await ctx.send(f"Ok {str(member).capitalize()}, I'm changing the mode to " @@ -169,7 +176,7 @@ class Bot(commands.Bot): await self.set_activity() else: await ctx.send(f"{str(member).capitalize()}, {mode} is not valid." - f" You may only enter {possible_modes}") + f" You may only enter {self.possible_modes}") else: await ctx.send(f"{str(member).capitalize()}, {freq} is not valid. " f"Please refer to the help page '@ help chfreq'") @@ -208,12 +215,6 @@ class Bot(commands.Bot): else: await ctx.send(f"{str(member).capitalize()}, there is no profile with the name '{profile_name}'") - @self.command(name='displayprofile', hidden=True) - async def _displayprofile(ctx, member: discord.Member = None): - member = member or ctx.author.display_name - message = self.display_current_radio_config() - await ctx.send(f"Ok {str(member).capitalize()}\n{message}") - # Hidden admin commands @self.command(name='reload', hidden=True) async def _reload(ctx, module: str, member: discord.Member = None): @@ -249,20 +250,21 @@ class Bot(commands.Bot): async def check_other_bots_online(self): print('Checking if other bots are online') channel = self.get_channel(self.Default_Channel_ID) - print(f"Channel to be tested in: {channel}") + print(f"Testing in: {channel}") bots_online = [] def verify_bot_msg(msg): - if msg.author.id in BotResources.PDB_KNOWN_BOT_IDS: - bots_online.append(msg.author.id) + if msg.author.id in BotResources.PDB_KNOWN_BOT_IDS.keys(): + bots_online.append(BotResources.PDB_KNOWN_BOT_IDS[msg.author.id]) await self.wait_until_ready() + # Send the ping command with the prefix the current bot is using await channel.send(f"{self.Command_Prefix}ping") seconds_waited = 0 - while seconds_waited < 2: + while seconds_waited < 3: try: await self.wait_for("message", check=verify_bot_msg, timeout=1) except asyncio.exceptions.TimeoutError: @@ -281,35 +283,46 @@ class Bot(commands.Bot): print("Starting GQRX handler") from gqrxHandler import GQRXHandler self.GQRXHandler = GQRXHandler() + self.possible_modes = BotResources.PDB_ACCEPTABLE_HANDLERS['gqrx']['Modes'] elif self.Handler == 'op25': print("Starting OP25 handler") from op25Handler import OP25Handler self.OP25Handler = OP25Handler() + self.possible_modes = BotResources.PDB_ACCEPTABLE_HANDLERS['op25']['Modes'] # Load the proper OPUS library for the device being used def load_opus(self): # Check the system type and load the correct library - if self.system_os_type == 'Linux_32': - discord.opus.load_opus('./opus/libopus.so') - elif self.system_os_type == 'Linux_64': + + # Linux ARM AARCH64 running 32bit OS + if self.system_os_type == 'Linux_ARMv7l': + discord.opus.load_opus('./opus/libopus_armv7l.so') + # Linux ARM AARCH64 running 64bit OS + if self.system_os_type == 'Linux_AARCH64': discord.opus.load_opus('./opus/libopus_aarcch64.so') - elif self.system_os_type == 'Windows': - discord.opus.load_opus('./opus/libopus.dll') + # Windows 64bit + if self.system_os_type == 'Windows_x64': + discord.opus.load_opus('./opus/libopus_amd64.dll') - # Check to make sure the selected device is still available and has not changed it's index - def check_device(self): - for device, index in self.Devices_List: - if int(index) == self.DEVICE_ID and str(device) == self.DEVICE_NAME: - return True + # Check to make sure the selected device is still available and has not changed its index + def check_device(self, _override): + # Check to see if an override has been passed + if not _override: + for device, index in self.Devices_List: + if int(index) == self.DEVICE_ID and str(device) == self.DEVICE_NAME: + return True - for device, index in self.Devices_List: - if str(device) == self.DEVICE_NAME: - self.DEVICE_ID = int(index) - return True + for device, index in self.Devices_List: + if str(device) == self.DEVICE_NAME: + self.DEVICE_ID = int(index) + return True + else: + return False else: - return False + # If an override has been passed just reply true + return True # Search the ./modules folder for any modules to load async def check_for_modules(self): @@ -337,18 +350,19 @@ class Bot(commands.Bot): # Check and store the OS type of the system for later use def check_os_type(self): + processor = platform.machine() if os.name == 'nt': - self.system_os_type = 'Windows' + if processor == "AMD64": + self.system_os_type = 'Windows_x64' else: - processor = platform.architecture()[0] - if processor == "64bit": - self.system_os_type = 'Linux_64' - elif processor == "32bit": - self.system_os_type = 'Linux_32' + if processor == "aarch64": + self.system_os_type = 'Linux_AARCH64' + elif processor == "armv7l": + self.system_os_type = 'Linux_ARMv7l' # Check to see if there is only one frequency def start_sdr(self): - if self.Handler in ['gqrx', 'op25']: + if self.Handler in BotResources.PDB_ACCEPTABLE_HANDLERS.keys(): if type(self.freq) == str: # Single freq sent # Stop the SDR if it is running @@ -372,6 +386,7 @@ class Bot(commands.Bot): def stop_sdr(self): if self.sdr_started: # Wait for the running processes to close + # Close the OP25 handler if self.Handler == 'op25': self.OP25Handler.close_op25() # self.OP25Handler.join() @@ -381,7 +396,7 @@ class Bot(commands.Bot): # Set the activity of the bot async def set_activity(self, connected=True): if connected: - if self.Handler in ['gqrx', 'op25']: + if self.Handler in BotResources.PDB_ACCEPTABLE_HANDLERS.keys(): if self.profile_name is None: await self.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name=f"{self.freq[:-1]}" @@ -399,12 +414,14 @@ class Bot(commands.Bot): await self.change_presence(activity=discord.Game(name=f"@ me"), status=discord.Status.idle) # Save the current radio settings as a profile - async def save_radio_config(self, profile_name): + async def save_radio_config(self, profile_name: str): config = configparser.SafeConfigParser() if os.path.exists('./profiles.ini'): config.read('./profiles.ini') + profile_name = str(profile_name).upper() + if not config.has_section(str(profile_name)): config.add_section(str(profile_name)) @@ -426,11 +443,11 @@ class Bot(commands.Bot): config = configparser.ConfigParser() if os.path.exists('./profiles.ini'): config.read('./profiles.ini') - if config.has_section(str(profile_name)): - self.profile_name = profile_name - self.freq = config[str(profile_name)]['Frequency'] - self.mode = config[str(profile_name)]['Mode'] - self.squelch = float(config[str(profile_name)]['Squelch']) + if config.has_section(str(profile_name).upper()): + self.profile_name = str(profile_name).upper() + self.freq = config[self.profile_name]['Frequency'] + self.mode = config[self.profile_name]['Mode'] + self.squelch = float(config[self.profile_name]['Squelch']) if self.sdr_started: self.start_sdr() @@ -445,9 +462,9 @@ class Bot(commands.Bot): def display_current_radio_config(self): message_body = "" if self.profile_name: - message_body += f"Profile Name: {self.profile_name}\n" + message_body += f"Profile Name: {str(self.profile_name).upper()}\n" message_body += f"Frequency: {self.freq}\n" \ - f"Mode: {self.mode}\n" + f"Mode: {str(self.mode).upper()}\n" if self.squelch: message_body += f"Squelch: {self.squelch}" diff --git a/main.py b/main.py index 3c322b2..f401c0e 100644 --- a/main.py +++ b/main.py @@ -30,35 +30,96 @@ def main(**passed_config): print('Checking config file...') if not check_if_config_exists(): print("No config file exists, please enter this information now") - write_config_file(init=True, **passed_config) + write_config_file(init=True) config = read_config_file() # Overwrite config options if they were passed for sub in config: # checking if key present in other dictionary - if sub in passed_config: + if sub in passed_config and passed_config[sub]: config[sub] = passed_config[sub] print('Starting Bot...') - discord_bot_client = bot.Bot(Token=config['Bot Token'], Device_ID=config['Device ID'], Device_Name=config['Device Name'], - Mention_Group=config['Mention Group'], Channel_ID=config['Channel ID'], Handler=config['Handler']) + discord_bot_client = bot.Bot(Token=config['Bot Token'], Device_ID=config['Device ID'], + Device_Name=config['Device Name'], Mention_Group=config['Mention Group'], + Channel_ID=config['Channel ID'], Handler=config['Handler']) print(f"Verifying audio device:\t{config['Device Name']}") - if not discord_bot_client.check_device(): + if not discord_bot_client.check_device(_override=bool("Device ID" in passed_config.keys())): raise BotDeviceNotFound(config['Device Name']) discord_bot_client.start_bot() +def cmd_arguments(): + parser = argparse.ArgumentParser(description='Discord Bot Gang - Premium Discord Bot\n' + 'The more you listen, the less you can see') + # Add the arguments + + # Arg to override bot token + parser.add_argument('-t', '--token', + metavar='Bot Token', + dest='Bot Token', + type=str, + help='Override saved bot token') + + # Arg to override the input device in the config + parser.add_argument('-i', '--input_device_id', + metavar='Device ID', + dest='Device ID', + type=int, + help='Override saved input device') + + # Arg to override mention group + parser.add_argument('-m', '--mention', + metavar='Mention Group', + dest='Mention Group', + type=str, + help='Override saved mention group') + + # Arg to override default channel to send messages + parser.add_argument('-c', '--channel', + metavar='Channel ID', + dest='Channel ID', + type=int, + help='Override saved sending channel') + + # Arg to override handler + parser.add_argument('-u', '--handler', + metavar='Handler', + dest='Handler', + type=str, + help='Override saved SDR handler') + + # Arg to save the overridden arguments + #parser.add_argument('-s', '--save', + # metavar='save_overrides', + # dest='save_overrides', + # type=str, + # help='Save the overridden arguments passed') + + # Retrieve the args + args = vars(parser.parse_args()) + + return args + if __name__ == '__main__': + args = cmd_arguments() + + if not all(args.values()): + print("Passed arguments:") + for arg in args: + if args[arg]: + print(f"\t{arg}:\t{args[arg]}") + try: print('Starting...') while True: try: - main() + main(**args) except BotDeviceNotFound: print("Restarting...") time.sleep(2) diff --git a/opus/libopus.dll b/opus/libopus_amd64.dll similarity index 100% rename from opus/libopus.dll rename to opus/libopus_amd64.dll diff --git a/opus/libopus.so b/opus/libopus_armv7l.so similarity index 100% rename from opus/libopus.so rename to opus/libopus_armv7l.so