def live_plugin_check(self): if GM.safe_mode: length_check = 2 else: length_check = len([f for f in os.listdir(utils.get_plugin_dir()) if f != "__pycache__"]) if length_check != len(self.bot_plugins): reg_print("Plugin change detected... adding to plugin cache.") GM.logger.warning("Plugin change detected... adding to plugin cache.") self.refresh_plugins()
def join_server(self): GM.mumble.start() GM.mumble.is_ready() self.bot_status = "Online" GM.mumble.users.myself.comment( f"This is {utils.get_bot_name()} [{utils.get_version()}].<br>{utils.get_known_bugs()}<br>") GM.mumble.set_bandwidth(192000) GM.mumble.channels.find_by_name(utils.get_default_channel()).move_in() utils.mute() GM.mumble.channels[GM.mumble.users.myself['channel_id']].send_text_message(f"{utils.get_bot_name()} is Online.") reg_print(f"\nJJMumbleBot is {self.status()}\n")
def plugin_privilege_checker(text, command, priv_path): if not privileges_check( GM.mumble.users[text.actor]) >= plugin_privileges_check( command, priv_path): reg_print( f"User [{GM.mumble.users[text.actor]['name']}] does not have the user privileges to use this command: [{command}]" ) GM.gui.quick_gui( f"User [{GM.mumble.users[text.actor]['name']}] does not have the user privileges to use this command: [{command}]", text_type='header', box_align='left') return False return True
def initialize_plugins_safe(self): # Load Plugins reg_print("######### Initializing Plugins - Safe Mode #########") sys.path.insert(0, utils.get_plugin_dir()) all_imports = [name for name in os.listdir(utils.get_plugin_dir()) if os.path.isdir(os.path.join(utils.get_plugin_dir(), name)) and name != "__pycache__"] for p_file in all_imports: if p_file == "help": continue elif p_file == "bot_commands": self.bot_plugins[p_file] = __import__(f'{p_file}.{p_file}', fromlist=['*']).Plugin() help_plugin = __import__('help.help') self.bot_plugins['help'] = help_plugin.help.Plugin(self.bot_plugins) sys.path.pop(0) reg_print("######### Plugins Initialized - Safe Mode #########")
def exit(self): GM.gui.quick_gui( f"{utils.get_bot_name()} is being shutdown.", text_type='header', box_align='left', ignore_whisper=True, ) for plugin in self.bot_plugins.values(): plugin.quit() utils.clear_directory(utils.get_temporary_img_dir()) reg_print("Cleared temporary directories.") if self.web_thr: from helpers.web_handler import stop_web stop_web() self.web_thr.join() reg_print("JJMumbleBot Web Interface was disconnected.") GM.logger.info("JJMumbleBot Web Interface was disconnected.") self.exit_flag = True
def initialize_plugins(self): # Load Plugins reg_print("######### Initializing Plugins #########") sys.path.insert(0, utils.get_plugin_dir()) all_imports = [name for name in os.listdir(utils.get_plugin_dir()) if os.path.isdir(os.path.join(utils.get_plugin_dir(), name)) and name != "__pycache__"] for p_file in all_imports: if p_file == "youtube" or p_file == "help": continue self.bot_plugins[p_file] = __import__(f'{p_file}.{p_file}', fromlist=['*']).Plugin() # Import the help and youtube plugins separately. help_plugin = __import__('help.help') youtube_plugin = __import__('youtube.youtube') # Assign audio plugins manually. self.bot_plugins['youtube'] = youtube_plugin.youtube.Plugin() self.bot_plugins.get('youtube').set_sound_board_plugin(self.bot_plugins.get('sound_board')) self.bot_plugins.get('sound_board').set_youtube_plugin(self.bot_plugins.get('youtube')) self.bot_plugins['help'] = help_plugin.help.Plugin(self.bot_plugins) sys.path.pop(0) reg_print("######### Plugins Initialized #########")
def refresh_plugins(self): reg_print("Refreshing all plugins...") GM.gui.quick_gui( f"{utils.get_bot_name()} is refreshing all plugins.", text_type='header', box_align='left', ignore_whisper=True) for plugin in self.bot_plugins.values(): plugin.quit() self.bot_plugins.clear() if GM.safe_mode: self.initialize_plugins_safe() else: self.initialize_plugins() pv.setup_privileges() reg_print("All plugins refreshed.") GM.gui.quick_gui( f"{utils.get_bot_name()} has refreshed all plugins.", text_type='header', box_align='left', ignore_whisper=True) GM.logger.info("JJ Mumble Bot has refreshed all plugins.")
def remote_command(self, message): if message[0] == self.cmd_token: GM.logger.info(f"Commands Received: [RemoteWebCall] -> {message}]") self.live_plugin_check() text = RemoteTextMessage(channel_id=GM.mumble.users.myself['channel_id'], session=GM.mumble.users.myself['session'], message=message, actor=GM.mumble.users.myself['session']) all_commands = [msg.strip() for msg in message.split(';')] # add to command history cmd_list = [GM.cmd_history.insert(cmd) for cmd in all_commands] if len(all_commands) > self.multi_cmd_limit: reg_print( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") GM.logger.warning( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") return # Iterate through all commands provided and generate commands. for i, item in enumerate(all_commands): # Generate command with parameters # new_text = copy.deepcopy(text) new_text = RemoteTextMessage(channel_id=GM.mumble.users.myself['channel_id'], session=GM.mumble.users.myself['session'], message=message, actor=GM.mumble.users.myself['session']) new_text.message = item new_command = None try: new_command = Command(item[1:].split()[0], new_text) except IndexError: continue if new_command.command in aliases.aliases: alias_commands = [msg.strip() for msg in aliases.aliases[new_command.command].split('|')] if len(alias_commands) > self.multi_cmd_limit: reg_print( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") GM.logger.warning( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") return for x, sub_item in enumerate(alias_commands): # sub_text = copy.deepcopy(text) sub_text = RemoteTextMessage(channel_id=GM.mumble.users.myself['channel_id'], session=GM.mumble.users.myself['session'], message=message, actor=GM.mumble.users.myself['session']) if len(item[1:].split()) > 1: sub_text.message = f"{sub_item} {item[1:].split(' ', 1)[1]}" else: sub_text.message = sub_item sub_command = None try: sub_command = Command(sub_item[1:].split()[0], sub_text) except IndexError: continue self.command_queue.insert(sub_command) else: # Insert command into the command queue self.command_queue.insert(new_command) # Process commands if the queue is not empty while not self.command_queue.is_empty(): # Process commands in the queue self.process_command_queue(self.command_queue.pop()) time.sleep(self.tick_rate)
def __init__(self): print("JJ Mumble Bot Initializing...") # Core access. GM.jjmumblebot = self # Initialize configs. GM.cfg.read(utils.get_config_dir()) # Initialize up-time tracker. GM.start_seconds = time.time() # Initialize application logging. logging.getLogger('chardet.charsetprober').setLevel(logging.INFO) log_file_name = f"{GM.cfg['Bot_Directories']['LogDirectory']}/runtime.log" GM.logger = logging.getLogger("RuntimeLogging") GM.logger.setLevel(logging.DEBUG) handler = TimedRotatingFileHandler(log_file_name, when='midnight', backupCount=30) handler.setLevel(logging.INFO) log_formatter = logging.Formatter('%(asctime)s - [%(levelname)s] - %(message)s') handler.setFormatter(log_formatter) GM.logger.addHandler(handler) GM.logger.info("######################################") GM.logger.info("Initializing JJMumbleBot...") GM.logger.info("Application configs have been read successfully.") # Initialize system arguments. if sys.argv: for item in sys.argv: # Enable safe mode. if item == "-safe": GM.safe_mode = True print('Safe mode has been enabled.') GM.logger.info("Safe mode has been enabled through system arguments.") # Enable debug mode. if item == "-debug": GM.debug_mode = True print('Debug mode has been enabled.') GM.logger.info("Debug mode has been enabled through system arguments.") # Enable quiet mode. if item == "-quiet": GM.quiet_mode = True print('Quiet mode has been enabled.') GM.logger.info("Quiet mode has been enabled through system arguments.") # Enable verbose mode. if item == "-verbose": GM.verbose_mode = True print('Verbose mode has been enabled.') GM.logger.info("Verbose mode has been enabled through system arguments.") # Initialize command queue. cmd_queue_lim = int(GM.cfg['Main_Settings']['CommandQueueLimit']) self.command_queue = QueueHandler(cmd_queue_lim) # Initialize command history tracker. cmd_history_lim = int(GM.cfg['Main_Settings']['CommandHistoryLimit']) GM.cmd_history = CMDQueue(cmd_history_lim) # Run Debug Mode tests. if GM.debug_mode: self.config_debug() # Retrieve mumble client data from configs. server_ip = GM.cfg['Connection_Settings']['ServerIP'] server_pass = GM.cfg['Connection_Settings']['ServerPassword'] server_port = int(GM.cfg['Connection_Settings']['ServerPort']) user_id = GM.cfg['Connection_Settings']['UserID'] user_cert = GM.cfg['Connection_Settings']['UserCertification'] GM.logger.info("Retrieved server information from application configs.") # Set main logic loop tick rate. self.tick_rate = float(GM.cfg['Main_Settings']['CommandTickRate']) # Set multi-command limit. self.multi_cmd_limit = int(GM.cfg['Main_Settings']['MultiCommandLimit']) # Set the command token. self.cmd_token = GM.cfg['Main_Settings']['CommandToken'] if len(self.cmd_token) != 1: print("ERROR: The command token must be a single character! Reverting to the default: '!' token.") GM.logger.critical( "ERROR: The command token must be a single character! Reverting to the default: '!' token.") self.cmd_token = '!' # Initialize mumble client. GM.mumble = pymumble.Mumble(server_ip, user=user_id, port=server_port, certfile=user_cert, password=server_pass) # Initialize mumble callbacks. GM.mumble.callbacks.set_callback("text_received", self.message_received) # Set mumble codec profile. GM.mumble.set_codec_profile("audio") # Create temporary directories. utils.make_directory(GM.cfg['Media_Directories']['TemporaryImageDirectory']) GM.logger.info("Initialized temporary directories.") # Create any missing permanent directories. utils.make_directory(GM.cfg['Media_Directories']['PermanentMediaDirectory'] + "sound_board/") utils.make_directory(GM.cfg['Media_Directories']['PermanentMediaDirectory'] + "images/") GM.logger.info("Initialized permanent directories.") # Setup privileges. pv.setup_privileges() GM.logger.info("Initialized user privileges.") # Setup aliases. aliases.setup_aliases() GM.logger.info("Initialized aliases.") # Initialize PGUI. GM.gui = PseudoGUI() GM.logger.info("Initialized pseudo graphical user interface.") # Initialize plugins. if GM.safe_mode: self.initialize_plugins_safe() self.tick_rate = 0.2 GM.logger.info("Initialized plugins with safe mode.") else: self.initialize_plugins() GM.logger.info("Initialized plugins.") # Run a plugin callback test. self.plugin_callback_test() GM.logger.info("Plugin callback test successful.") print("JJ Mumble Bot initialized!\n") # Initialize the web interface. if GM.cfg.getboolean('Connection_Settings', 'EnableWebInterface'): from helpers.web_handler import init_web self.web_thr = threading.Thread(target=init_web) self.web_thr.start() reg_print("JJMumbleBot Web Service was initialized.") GM.logger.info("JJMumbleBot Web Service was initialized.") # Join the server after all initialization is complete. self.join_server() GM.logger.info("JJ Mumble Bot has fully initialized and joined the server.") self.loop()
def message_received(self, text): message = text.message.strip() user = GM.mumble.users[text.actor] if "<img" in message: reg_print(f"Message Received: [{user['name']} -> Image Data]") elif "<a href=" in message: reg_print(f"Message Received: [{user['name']} -> Hyperlink Data]") else: reg_print(f"Message Received: [{user['name']} -> {message}]") if message[0] == self.cmd_token: GM.logger.info(f"Commands Received: [{user['name']} -> {message}]") self.live_plugin_check() # example input: !version ; !about ; !yt twice ; !p ; !status all_commands = [msg.strip() for msg in message.split(';')] # example output: ["!version", "!about", "!yt twice", "!p", "!status"] # add to command history cmd_list = [GM.cmd_history.insert(cmd) for cmd in all_commands] if len(all_commands) > self.multi_cmd_limit: reg_print( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") GM.logger.warning( f"The multi-command d! The multi-command limit is {self.multi_cmd_limit} commands per line.") return # Iterate through all commands provided and generate commands. for i, item in enumerate(all_commands): # Generate command with parameters new_text = copy.deepcopy(text) new_text.message = item new_command = None try: new_command = Command(item[1:].split()[0], new_text) except IndexError: continue if new_command.command in aliases.aliases: alias_commands = [msg.strip() for msg in aliases.aliases[new_command.command].split('|')] if len(alias_commands) > self.multi_cmd_limit: reg_print( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") GM.logger.warning( f"The multi-command limit was reached! The multi-command limit is {self.multi_cmd_limit} commands per line.") return for x, sub_item in enumerate(alias_commands): sub_text = copy.deepcopy(text) if len(item[1:].split()) > 1: sub_text.message = f"{sub_item} {item[1:].split(' ', 1)[1]}" else: sub_text.message = sub_item sub_command = None try: sub_command = Command(sub_item[1:].split()[0], sub_text) except IndexError: continue self.command_queue.insert(sub_command) else: # Insert command into the command queue self.command_queue.insert(new_command) # Process commands if the queue is not empty while not self.command_queue.is_empty(): # Process commands in the queue self.process_command_queue(self.command_queue.pop()) time.sleep(self.tick_rate)
def plugin_callback_test(self): # Plugin Callback Tests reg_print("######### Running plugin callback tests #########") for plugin in self.bot_plugins.values(): plugin.plugin_test() reg_print("######### Plugin callback tests complete #########")
def process_command(self, text): message = text.message.strip() message_parse = message[1:].split(' ', 1) all_messages = message[1:].split() command = message_parse[0] if command == "echo": if not pv.plugin_privilege_checker(text, command, self.priv_path): return parameter = message_parse[1] GM.gui.quick_gui(parameter, text_type='header', box_align='left', ignore_whisper=True) GM.logger.info(f"Echo:[{parameter}]") return elif command == "log": if not pv.plugin_privilege_checker(text, command, self.priv_path): return debug_print(f"Manually Logged: [{message_parse[1]}]") GM.logger.info(f"Manually Logged: [{message_parse[1]}]") return elif command == "spam_test": if not pv.plugin_privilege_checker(text, command, self.priv_path): return for i in range(10): GM.gui.quick_gui("This is a spam test message...", text_type='header', box_align='left', ignore_whisper=True) GM.logger.info( f"A spam_test was conducted by: {GM.mumble.users[text.actor]['name']}." ) return elif command == "msg": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.quick_gui(message[1:].split(' ', 2)[2], text_type='header', box_align='left', user=all_messages[1], ignore_whisper=True) GM.logger.info( f"Msg:[{all_messages[1]}]->[{message[1:].split(' ', 2)[2]}]") return elif command == "move": if not pv.plugin_privilege_checker(text, command, self.priv_path): return parameter = message_parse[1] channel_name = parameter if channel_name == "default" or channel_name == "Default": channel_name = utils.get_default_channel() channel_search = utils.get_channel(channel_name) if channel_search is None: return else: channel_search.move_in() GM.gui.quick_gui( f"{utils.get_bot_name()} was moved by {GM.mumble.users[text.actor]['name']}", text_type='header', box_align='left', ignore_whisper=True) GM.logger.info( f"Moved to channel: {channel_name} by {GM.mumble.users[text.actor]['name']}" ) return elif command == "make": if not pv.plugin_privilege_checker(text, command, self.priv_path): return parameter = message_parse[1] channel_name = parameter utils.make_channel(utils.get_my_channel(), channel_name) GM.logger.info( f"Made a channel: {channel_name} by {GM.mumble.users[text.actor]['name']}" ) return elif command == "leave": if not pv.plugin_privilege_checker(text, command, self.priv_path): return utils.leave() GM.logger.info("Returned to default channel.") return elif command == "joinme": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.quick_gui( f"Joining user: {GM.mumble.users[text.actor]['name']}", text_type='header', box_align='left', ignore_whisper=True) GM.mumble.channels[GM.mumble.users[text.actor] ['channel_id']].move_in() GM.logger.info( f"Joined user: {GM.mumble.users[text.actor]['name']}") return elif command == "privileges": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.quick_gui(f"{pv.get_all_privileges()}", text_type='header', box_align='left', text_align='left', user=GM.mumble.users[text.actor]['name'], ignore_whisper=True) return elif command == "setprivileges": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: username = all_messages[1] level = int(all_messages[2]) result = pv.set_privileges(username, level, GM.mumble.users[text.actor]) if result: GM.gui.quick_gui( f"User: {username} privileges have been modified.", text_type='header', box_align='left', user=GM.mumble.users[text.actor]['name'], ignore_whisper=True) GM.logger.info(f"Modified user privileges for: {username}") except Exception: reg_print( "Incorrect format! Format: !setprivileges 'username' 'level'" ) GM.gui.quick_gui( "Incorrect format! Format: !setprivileges 'username' 'level'", text_type='header', box_align='left', user=GM.mumble.users[text.actor]['name'], ignore_whisper=True) return return elif command == "addprivileges": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: username = all_messages[1] level = int(all_messages[2]) result = pv.add_to_privileges(username, level) if result: GM.gui.quick_gui( f"Added a new user: {username} to the user privileges.", text_type='header', box_align='left', user=GM.mumble.users[text.actor]['name'], ignore_whisper=True) GM.logger.info( f"Added a new user: {username} to the user privileges." ) except Exception: reg_print( "Incorrect format! Format: !addprivileges 'username' 'level'" ) GM.gui.quick_gui( "Incorrect format! Format: !addprivileges 'username' 'level'", text_type='header', box_align='left', user=GM.mumble.users[text.actor]['name'], ignore_whisper=True) return return elif command == "blacklist": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: parameter = all_messages[1] reason = "No reason provided." print(len(message[1:].split())) if len(message[1:].split()) >= 3: reason = message[1:].split(' ', 2)[2] result = pv.add_to_blacklist(parameter, GM.mumble.users[text.actor]) if result: GM.gui.quick_gui( f"User: {parameter} added to the blacklist.<br>Reason: {reason}", text_type='header', box_align='left', text_align='left') GM.logger.info( f"Blacklisted user: {parameter} <br>Reason: {reason}") except IndexError: GM.gui.quick_gui(pv.get_blacklist(), text_type='header', box_align='left', text_align='left') return elif command == "whitelist": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: parameter = message_parse[1] result = pv.remove_from_blacklist(parameter) if result: GM.gui.quick_gui( f"User: {parameter} removed from the blacklist.", text_type='header', box_align='left') GM.logger.info( f"User: {parameter} removed from the blacklist.") except IndexError: GM.gui.quick_gui("Command format: !whitelist username", text_type='header', box_align='left') return return
def process_command(self, text): message = text.message.strip() message_parse = message[1:].split(' ', 1) command = message_parse[0] if command == "help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.help_data.split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold(f"{utils.get_bot_name()} General Help Commands")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print("Displayed general help screen in the channel.") GM.logger.info("Displayed general help screen in the channel.") return elif command == "bot_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get( "bot_commands").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Bot_Commands Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("bot_commands").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print( "Displayed bot commands plugin help screen in the channel.") GM.logger.info( "Displayed bot commands plugin help screen in the channel.") return elif command == "whisper_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get("whisper").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Whisper Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("whisper").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print("Displayed whisper plugin help screen in the channel.") GM.logger.info( "Displayed whisper plugin help screen in the channel.") return elif command == "sound_board_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get( "sound_board").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Sound_Board Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("sound_board").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print( "Displayed sound_board plugin help screen in the channel.") GM.logger.info( "Displayed sound_board plugin help screen in the channel.") return elif command == "youtube_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get("youtube").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Youtube Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("youtube").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print("Displayed youtube plugin help screen in the channel.") GM.logger.info( "Displayed youtube plugin help screen in the channel.") return elif command == "images_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get("images").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Images Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("images").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print("Displayed images plugin help screen in the channel.") GM.logger.info( "Displayed images plugin help screen in the channel.") return elif command == "uptime_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get("uptime").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Uptime Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("uptime").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print("Displayed uptime plugin help screen in the channel.") GM.logger.info( "Displayed uptime plugin help screen in the channel.") return elif command == "randomizer_help": if not pv.plugin_privilege_checker(text, command, self.priv_path): return GM.gui.open_box() all_help_lines = [ msg.strip() for msg in self.bot_plugins.get( "randomizer").help().split('<br>') ] content = GM.gui.make_content( f'<font color="red">#####</font> ' f'{GUIHelper.bold("Randomizer Plugin Help")} ' f'<font color="red">#####</font>') GM.gui.append_row(content) content = GM.gui.make_content( f'Plugin Version: {self.bot_plugins.get("randomizer").get_plugin_version()}<br>', text_color='cyan') GM.gui.append_row(content) for i, item in enumerate(all_help_lines): content = GM.gui.make_content(f'{item}', 'header', text_color='yellow', text_align="left") GM.gui.append_row(content) GM.gui.close_box() GM.gui.display_box(channel=utils.get_my_channel()) reg_print( "Displayed randomizer plugin help screen in the channel.") GM.logger.info( "Displayed randomizer plugin help screen in the channel.") return
def process_command(self, text): message = text.message.strip() message_parse = message[1:].split(' ', 1) all_messages = message[1:].split() command = message_parse[0] if command == "song": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.current_song_info is not None: GM.gui.quick_gui_img(f"{utils.get_temporary_img_dir()}", f"{YH.current_song_info['img_id']}", caption=f"Now playing: {YH.current_song_info['main_title']}", format=True, img_size=32768) GM.logger.info("Displayed current song in the youtube plugin.") else: GM.gui.quick_gui( f"{utils.get_bot_name()} is not playing anything right now.", text_type='header', box_align='left') return elif command == "autoplay": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.autoplay: YH.autoplay = False; GM.gui.quick_gui( "Autoplay has been disabled.", text_type='header', box_align='left') GM.logger.info("Autoplay has been disabled in the youtube plugin.") else: YH.autoplay = True GM.gui.quick_gui( "Autoplay has been enabled.", text_type='header', box_align='left') GM.logger.info("Autoplay has been enabled in the youtube plugin.") return elif command == "shuffle": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.music_thread is not None: if not YH.queue_instance.is_empty(): YH.queue_instance.shuffle() YM.download_next() GM.gui.quick_gui( "The youtube queue has been shuffled.", text_type='header', box_align='left') GM.logger.info("The youtube audio queue was shuffled.") return elif command == "next": if not pv.plugin_privilege_checker(text, command, self.priv_path): return YM.next() return elif command == "remove": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.music_thread is not None: if YH.queue_instance.is_empty(): GM.gui.quick_gui( "The youtube queue is empty, so I can't remove tracks.", text_type='header', box_align='left') return rem_val = int(message[1:].split(' ', 1)[1]) if rem_val > YH.queue_instance.size() - 1 or rem_val < 0: GM.gui.quick_gui( f"You can't remove tracks beyond the length of the current queue.", text_type='header', box_align='left') return removed_item = YH.queue_instance.remove(rem_val) GM.gui.quick_gui( f"Removed track: [{rem_val}]-{removed_item['main_title']} from the queue.", text_type='header', box_align='left') GM.logger.info(f"Removed track #{rem_val} from the youtube audio queue.") return elif command == "skipto": if not pv.plugin_privilege_checker(text, command, self.priv_path): return skip_val = int(message[1:].split(' ', 1)[1]) YM.skipto(skip_val) GM.logger.info(f"The youtube audio queue skipped to track #{skip_val}.") return elif command == "stop": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.music_thread is not None: GM.gui.quick_gui( "Stopping youtube audio thread.", text_type='header', box_align='left') YH.queue_instance.clear() YM.stop_audio() utils.clear_directory(utils.get_temporary_img_dir()) YH.queue_instance = qh.QueueHandler(YH.max_queue_size) GM.logger.info("The youtube audio thread was stopped.") return return elif command == "clear": if not pv.plugin_privilege_checker(text, command, self.priv_path): return reg_print("Clearing youtube queue.") YM.clear_queue() GM.gui.quick_gui( "Cleared youtube queue.", text_type='header', box_align='left') GM.logger.info("The youtube queue was cleared.") return elif command == "max_duration": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: new_max = int(message[1:].split(' ', 1)[1]) YM.set_max_track_duration(new_max) GM.gui.quick_gui( f"Set youtube track max duration to {YH.max_track_duration}", text_type='header', box_align='left') GM.logger.info(f"The youtube track max duration was set to {YH.max_track_duration}.") except IndexError: GM.gui.quick_gui( f"Current youtube track max duration: {YH.max_track_duration}", text_type='header', box_align='left') return elif command == "volume": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: vol = float(message[1:].split(' ', 1)[1]) except IndexError: GM.gui.quick_gui( f"Current youtube volume: {YH.volume}", text_type='header', box_align='left') return if vol > 1: GM.gui.quick_gui( "Invalid Volume Input: [0-1]", text_type='header', box_align='left') return if vol < 0: GM.gui.quick_gui( "Invalid Volume Input: [0-1]", text_type='header', box_align='left') return YH.volume = vol GM.gui.quick_gui( f"Set volume to {YH.volume}", text_type='header', box_align='left') GM.logger.info(f"The youtube audio volume was changed to {YH.volume}.") return elif command == "youtube": if not pv.plugin_privilege_checker(text, command, self.priv_path): return try: search_term = message_parse[1] except IndexError: return YH.all_searches = YM.get_search_results(search_term) search_results = YM.get_choices(YH.all_searches) GM.gui.quick_gui( f"{search_results}\nWhich one would you like to play?", text_type='header', box_align='left', text_align='left') GM.logger.info("Displayed youtube search results.") YH.can_play = True return elif command == "queue": if not pv.plugin_privilege_checker(text, command, self.priv_path): return queue_results = YM.get_queue() if queue_results is not None: cur_text = "" for i, item in enumerate(queue_results): cur_text += f"{item}" if i % 50 == 0 and i != 0: GM.gui.quick_gui( f"{cur_text}", text_type='header', box_align='left', text_align='left') cur_text = "" if cur_text != "": GM.gui.quick_gui( f"{cur_text}", text_type='header', box_align='left', text_align='left') GM.logger.info("Displayed current youtube queue.") return else: GM.gui.quick_gui( "The youtube queue is empty.", text_type='header', box_align='left') return elif command == "playlist": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if len(message_parse) == 2: stripped_url = BeautifulSoup(message_parse[1], features='html.parser').get_text() if "youtube.com" in stripped_url or "youtu.be" in stripped_url: if YH.queue_instance.is_full(): GM.gui.quick_gui( "The youtube queue is full!", text_type='header', box_align='left') return all_song_data = YM.download_playlist(stripped_url) if all_song_data is None: return self.sound_board_plugin.clear_audio_thread() for i, song_data in enumerate(all_song_data): YH.queue_instance.insert(song_data) GM.gui.quick_gui( f"Playlist generated: {stripped_url}", text_type='header', box_align='left') GM.logger.info(f"Generated playlist: {stripped_url}") if not YH.is_playing: YM.download_next() YM.play_audio() return else: GM.gui.quick_gui( "The given link was not identified as a youtube video link!", text_type='header', box_align='left') return elif command == "linkfront": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if len(message_parse) == 2: stripped_url = BeautifulSoup(message_parse[1], features='html.parser').get_text() if "youtube.com" in stripped_url or "youtu.be" in stripped_url: if YH.queue_instance.is_full(): GM.gui.quick_gui( "The youtube queue is full!", text_type='header', box_align='left') return song_data = YM.download_song_name(stripped_url) if song_data is None: GM.gui.quick_gui( "ERROR: The chosen stream was either too long or a live stream.", text_type='header', box_align='left') return song_data['main_url'] = stripped_url self.sound_board_plugin.clear_audio_thread() YH.queue_instance.insert_priority(song_data) GM.gui.quick_gui( f"Added to front of queue: {stripped_url}", text_type='header', box_align='left') GM.logger.info("Direct link added to the front of the youtube queue.") if not YH.is_playing: YM.download_next() YM.play_audio() return else: GM.gui.quick_gui( "The given link was not identified as a youtube video link!", text_type='header', box_align='left') return elif command == "link": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if len(message_parse) == 2: stripped_url = BeautifulSoup(message_parse[1], features='html.parser').get_text() if "youtube.com" in stripped_url or "youtu.be" in stripped_url: if YH.queue_instance.is_full(): GM.gui.quick_gui( "The youtube queue is full!", text_type='header', box_align='left') return song_data = YM.download_song_name(stripped_url) if song_data is None: GM.gui.quick_gui( "ERROR: The chosen stream was either too long or a live stream.", text_type='header', box_align='left') return song_data['main_url'] = stripped_url self.sound_board_plugin.clear_audio_thread() YH.queue_instance.insert(song_data) GM.gui.quick_gui( f"Added to queue: {stripped_url}", text_type='header', box_align='left') GM.logger.info("Direct link added to youtube queue.") if not YH.is_playing: YM.download_next() YM.play_audio() return else: GM.gui.quick_gui( "The given link was not identified as a youtube video link!", text_type='header', box_align='left') return elif command == "play": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.can_play: if YH.queue_instance.is_full(): GM.gui.quick_gui( "The youtube queue is full!", text_type='header', box_align='left') return self.sound_board_plugin.clear_audio_thread() if len(all_messages) == 1: song_data = YM.download_song_name( "https://www.youtube.com" + YH.all_searches[0]['href']) if song_data is None: GM.gui.quick_gui( f"The chosen video is too long. The maximum video length is {(YH.max_track_duration/60)} minutes", text_type='header', box_align='left') return song_data['main_url'] = "https://www.youtube.com" + YH.all_searches[0]['href'] GM.gui.quick_gui( f"Automatically chosen: {YH.all_searches[0]['title']}", text_type='header', box_align='left') YH.can_play = False YH.queue_instance.insert(song_data) if not YH.is_playing: YM.download_next() YM.play_audio() elif len(all_messages) == 2: if 9 >= int(all_messages[1]) >= 0: song_data = YM.download_song_name( "https://www.youtube.com" + YH.all_searches[int(all_messages[1])]['href']) if song_data is None: utils.echo(utils.get_my_channel(), f"The chosen video is too long. The maximum video length is {(YH.max_track_duration/60)} minutes") return song_data['main_url'] = "https://www.youtube.com" + YH.all_searches[int(all_messages[1])]['href'] GM.gui.quick_gui( f"You've chosen: {YH.all_searches[int(all_messages[1])]['title']}", text_type='header', box_align='left') YH.can_play = False else: GM.gui.quick_gui( "Invalid choice! Valid Range [0-9]", text_type='header', box_align='left') YH.can_play = False return YH.queue_instance.insert(song_data) if not YH.is_playing: YM.download_next() YM.play_audio() elif len(all_messages) == 3: if 9 >= int(all_messages[1]) >= 0: song_data = YM.download_song_name( "https://www.youtube.com" + YH.all_searches[int(all_messages[1])]['href']) if song_data is None: GM.gui.quick_gui( f"The chosen video is too long. The maximum video length is {(YH.max_track_duration/60)} minutes", text_type='header', box_align='left') return song_data['main_url'] = "https://www.youtube.com" + YH.all_searches[int(all_messages[1])]['href'] GM.gui.quick_gui( f"You've chosen: {YH.all_searches[int(all_messages[1])]['title']}", text_type='header', box_align='left') YH.can_play = False else: GM.gui.quick_gui( "Invalid choice! Valid Range [0-9]", text_type='header', box_align='left') YH.can_play = False return count = int(all_messages[2]) for i in range(count): YH.queue_instance.insert(song_data) if not YH.is_playing: YM.download_next() YM.play_audio() return elif command == "replay": if not pv.plugin_privilege_checker(text, command, self.priv_path): return if YH.music_thread is not None: if YH.current_song is not None and YH.current_song_info is not None: YH.queue_instance.insert_priority(YH.current_song_info) YM.stop_audio() YM.download_next() YM.play_audio() else: GM.gui.quick_gui( "There is no track available to replay.", text_type='header', box_align='left') return return
def process_command(self, text): message = text.message.strip() message_parse = message[1:].split(' ', 1) command = message_parse[0] if command == "post": if not pv.plugin_privilege_checker(text, command, self.priv_path): return img_url = message_parse[1] # Download image img_url = ''.join( BeautifulSoup(img_url, 'html.parser').findAll(text=True)) IH.download_image_stream(img_url) # Format image time.sleep(1) img_ext = img_url.rsplit('.', 1)[1] formatted_string = IH.format_image("image", img_ext, utils.get_temporary_img_dir()) reg_print("Posting an image to the mumble channel chat.") # Display image with PGUI system GM.gui.quick_gui_img( f"{utils.get_temporary_img_dir()}", formatted_string, bgcolor=GM.cfg['Plugin_Settings']['Images_FrameColor'], cellspacing=GM.cfg['Plugin_Settings']['Images_FrameSize'], format=False) GM.logger.info( f"Posted an image to the mumble channel chat from: {message_parse[1]}." ) return elif command == "img": if not pv.plugin_privilege_checker(text, command, self.priv_path): return parameter = message_parse[1] if not os.path.isfile(utils.get_permanent_media_dir() + f"images/{parameter}.jpg"): GM.gui.quick_gui("The image does not exist.", text_type='header', box_align='left') return False # Format image img_data = parameter.rsplit('.', 1) formatted_string = IH.format_image( img_data[0], "jpg", utils.get_permanent_media_dir() + "images/") reg_print("Posting an image to the mumble channel chat.") # Display image with PGUI system GM.gui.quick_gui_img( f"{utils.get_permanent_media_dir()}images/", formatted_string, bgcolor=GM.cfg['Plugin_Settings']['Images_FrameColor'], cellspacing=GM.cfg['Plugin_Settings']['Images_FrameSize'], format=False) GM.logger.info( "Posted an image to the mumble channel chat from local files.") return elif command == "imglist": if not pv.plugin_privilege_checker(text, command, self.priv_path): return file_counter = 0 gather_list = [] internal_list = [] for file_item in os.listdir(utils.get_permanent_media_dir() + "images/"): if file_item.endswith(".jpg"): gather_list.append(f"{file_item}") file_counter += 1 gather_list.sort(key=str.lower) for i, item in enumerate(gather_list): internal_list.append( f"<br><font color='{GM.cfg['PGUI_Settings']['IndexTextColor']}'>[{i}]</font> - [{item}]" ) cur_text = f"<font color='{GM.cfg['PGUI_Settings']['HeaderTextColor']}'>Local Image Files:</font>" if len(internal_list) == 0: cur_text += "<br>There are no local image files available." GM.gui.quick_gui(cur_text, text_type='header', box_align='left', user=GM.mumble.users[text.actor]['name']) GM.logger.info("Displayed a list of all local image files.") return for i, item in enumerate(internal_list): cur_text += item if i % 50 == 0 and i != 0: GM.gui.quick_gui(cur_text, text_type='header', box_align='left', text_align='left', user=GM.mumble.users[text.actor]['name']) cur_text = "" if cur_text != "": GM.gui.quick_gui(cur_text, text_type='header', box_align='left', text_align='left', user=GM.mumble.users[text.actor]['name']) GM.logger.info("Displayed a list of all local image files.") return elif command == "imglist_echo": if not pv.plugin_privilege_checker(text, command, self.priv_path): return file_counter = 0 gather_list = [] internal_list = [] for file_item in os.listdir(utils.get_permanent_media_dir() + "images/"): if file_item.endswith(".jpg"): gather_list.append(f"{file_item}") file_counter += 1 gather_list.sort(key=str.lower) for i, item in enumerate(gather_list): internal_list.append( f"<br><font color='{GM.cfg['PGUI_Settings']['IndexTextColor']}'>[{i}]</font> - [{item}]" ) cur_text = f"<font color='{GM.cfg['PGUI_Settings']['HeaderTextColor']}'>Local Image Files:</font>" if len(internal_list) == 0: cur_text += "<br>There are no local image files available." GM.gui.quick_gui(cur_text, text_type='header', box_align='left') GM.logger.info("Displayed a list of all local image files.") return for i, item in enumerate(internal_list): cur_text += item if i % 50 == 0 and i != 0: GM.gui.quick_gui(cur_text, text_type='header', box_align='left', text_align='left') cur_text = "" if cur_text != "": GM.gui.quick_gui(cur_text, text_type='header', box_align='left', text_align='left') GM.logger.info("Displayed a list of all local image files.") return