def update_hifumi(): """ Updates Hifumi via Git. Useful if something wents wrong or if a new version comes out. :return: Git call, then exit code. 0 if went fine, 1 or exception if error ocurred. """ if get_latest_release() == __version__: info("Hifumi is already the latest version." "No need to perform an update right now!") else: try: code = subprocess.call(("git", "pull", "--ff-only")) except subprocess.CalledProcessError: error("\nError: Git not found. It's either not installed or " "not in the PATH environment variable. Please fix this!") return if not code: info("\nHifumi is now updated successfully!") sample_file = Path('./config/sample_settings.py') if sample_file.is_file(): sample_file.unlink() else: error("\nUh oh! An error ocurred and " "update is going to be aborted.\n" "This error might be caused from " "the environment edits you made. " "Please fix this by going to the maintenance menu.")
def string_errors(): """ Returns string errors if found, should be invoked only by detect_errors function. :return: String errors """ interpreter = sys.executable.split('/')[-1] if not interpreter: raise RuntimeError("Couldn't find Python's interpreter") if not is_git(): warning("This installation was not done via Git\n" "You probably won't be able to update some things that " "require this util, " "for example the bot environment. Please " "read the license file for more information. " "If you got this from another " "source, please reinstall Hifumi" "as it follows in the guide. " "http://www.hifumibot.xyz/docs\n\n") if not is_git_installed(): warning("Git not found. This means that it's either not " "installed or not in the PATH environment variable like " "it should be.\n\n") if not is_ffmpeg_installed(): error("FFMPEG not found. This means that it's either not " "installed or not in the PATH environment variable like " "it should be. This program is needed to run music commands, " "so please install it before continue!\n\n") if not verify_requirements(): if IS_WINDOWS: additional_str = "the required programs" elif IS_MAC: additional_str = "the required packages and programs" else: additional_str = "the required packages via terminal" error("It looks like you're missing some " "packages, please install them or " "you won't be able to run Hifumi. " "For that, proceed to step 4.\n" "Make sure to install the pip modules " "and " + additional_str + " to ensure " "a great run instead of bad things.\n\n") if not admin_running(): if IS_WINDOWS or IS_MAC: note = "executing Python shell in administrator mode" else: note = "doing sudo " + interpreter + " launcher.py or run as root" warning("Process is not running as administrator. Administrator " "action perfomance can fail sometimes if administrator " "permissions are disabled. Please restart Hifumi by " + note + ".\n\n")
def edit_settings(): """ Opens settings.py file in the notepad if present. :return: The action or an exception if an error ocurred. """ path = Path('./config/settings.yml') sample_path = Path('./config/sample_settings.yml') if path.is_file(): __edit_settings(path) elif not path.is_file() and sample_path.is_file(): info("It looks like it's your first time running Hifumi launcher.\n" "sample_settings.yml is going to be renamed to settings.yml.\n") pause() sample_path.rename(str(path)) edit_settings() else: error("An error ocurred while opening the " "settings into editor. If the file does not exist, " "please reinstall Hifumi from zero.\n") pause()
def run_unittest(): """ Runs the unit test provider :return: Unit test script """ clear_screen() warning("You're about to run unit test provider. This " "function is aimed for advanced users. Make " "sure to use it properly, preferably for testing, " "otherwise bad things can happen. Please refer " "to the 'Unit testing' section from the docs for " "details. Continue?") if user_pick_yes_no(): if unittest is None: error("'unittest' module not found. Please install all " "requirements from update menu.") pause() main() else: try: os.chdir(str(Path('tests').absolute())) run_tests(os.curdir) os.chdir(str(Path('..').absolute())) pause() except Exception as e: error("Something went wrong. Unit test interrupted!\n") error(str(e)) pause() else: main()
def stop_hifumi(): """ Stops Hifumi from running if started with PM2 :return: Exit code, 0 if fine, else more than 0. """ interpreter = sys.executable.split('/')[-1] if not interpreter: raise RuntimeError("Couldn't find Python interpreter") run_script = Path("./run.py") # Don't worry about shard mode, that's toggleable via settings.py if not run_script.is_file(): error("Hifumi's main file to run is not available. " "Please reinstall Hifumi!") pause() main() code = subprocess.call(['pm2', 'stop', 'run.py']) if code is 0: info("Hifumi has been terminated successfully.") else: # If error error("Hifumi is not registered into PM2. No need to use this now.") pause()
def update_pip(): """ Updates pip, a.k.a the Python package manager. :return: Pip call, then exit code. 0 if everything is fine, 1 if error ocurred. """ interpreter = sys.executable.split('/')[-1] if not interpreter: error("Python interpreter not found.") return args = [interpreter, "-m", "pip", "install", "--upgrade", "pip"] code = subprocess.call(args) if code == 0: info("\nPip updated successfully to the latest version!") else: error( "\nUh oh! An error ocurred and installation is going " "to be aborted.\nPlease fix the error above basing in the docs.\n")
def computer_meets_color(): """ Installs the required requirements for the console logging in color. :return: Pip call, then exit code. 0 if everything is fine, 1 if error ocurred. """ interpreter = sys.executable.split('/')[-1] if not interpreter: error("Python interpreter not found.") return base_arg = [ interpreter, "-m", "pip", "install", "--upgrade", str(REQS_DIR) ] update_packages = ['colorama', 'colorlog', 'requests'] codes = [subprocess.call(base_arg + [p]) for p in update_packages] if any(codes): error("\nUh oh! An error ocurred and installation is going to " "be aborted.\nPlease fix the error above basing in the docs.\n") exit(1)
def run_hifumi(autorestart): """ Start Hifumi, autorestart is toggleable. :return: Exit code, 0 if fine, else more than 0. """ interpreter = sys.executable.split('/')[-1] if not interpreter: raise RuntimeError("Couldn't find Python interpreter") if not verify_requirements(): error("You don't have the requirements that are needed to " "start the bot. Please install them first and try again.") pause() main() run_script = Path('./run.py') # Don't worry about shard mode, that's toggleable via settings.py if not run_script.is_file(): error("Hifumi's main file to run is not available. " "Please reinstall Hifumi!") pause() main() try: if autorestart: cmd = ("pm2", "start", "run.py", "--name=Hifumi", "--interpreter=" + interpreter) code = subprocess.call(cmd) else: cmd = (interpreter, "run.py") info("Hifumi is now started as single session! " "To shutdown the bot, press CTRL+Z anytime.") code = subprocess.call(cmd) except KeyboardInterrupt: # Triggered! code = 0 if not autorestart and code is 0: # If no error info("Hifumi has been terminated recently. Exit code: %d" % code) elif not autorestart and code is not 0: # If error error("Hifumi has been terminated recently. Exit code: %d" % code) elif autorestart and code is not 0: clear_screen() info("Hifumi is already started! Restarting instead...") cmd = ("pm2", "restart", "run.py") subprocess.call(cmd) elif autorestart and code is 0: info("Hifumi has been started successfully!") else: # If error error("Hifumi has been terminated recently. Exit code: %d" % code) pause()
def reset_hifumi(reqs=False, data=False, cogs=False, git_reset=False): """ Resets Hifumi or any of its properties (enabled to True boolean). If all of the parameters are enabled, Hifumi will get a 'factory reset'. :param reqs: Choose to reset the local packages. :param data: Choose to reset the data folder. :param cogs: Choose to reset the cogs (command modules). :param git_reset: Choose to replace all the environment with the latest commit. :return: For reqs, data, cogs. Folder removing and result or exception (FileNotFoundError or another). If git_reset an exit code. 0 if went fine, 1 if otherwise. """ if reqs: try: shutil.rmtree(str(REQS_DIR), onerror=remove_readonly) info("Installed local packages wiped successfully!") except FileNotFoundError: pass except Exception as e: error("Uh oh! An error ocurred: {}".format(e)) if data: try: shutil.rmtree("data", onerror=remove_readonly) info("'data' folder has been wiped.") except FileNotFoundError: pass except Exception as e: error("Uh oh! An error ocurred: {}".format(e)) if cogs: try: shutil.rmtree("cogs", onerror=remove_readonly) info("'cogs' folder has been wiped.") except FileNotFoundError: pass except Exception as e: error("An error occurred when trying to remove the 'cogs' folder: " "{}".format(e)) if git_reset: code = subprocess.call(("git", "reset", "--hard")) if code == 0: info("Hifumi repaired successfully! to the last local commit. " "If the bot is started, please restart it to make effect.") else: error("The repair has failed.")
def run(): """ Main function of the program :return: An initialization request to the program or an error if Python/pip is wrong. """ os.chdir(str(Path(__file__).parent)) if not logger_success: computer_meets_color() # lol main() if not SYSTEM_OK: error("Sorry! This operation system is not compatible with " "Hifumi's environment and might not run at all. Hifumi " "is only supported for Windows, Mac, Linux and " "Raspberry Pi. Please install one of those OS and try " "again.") exit(1) elif not PYTHON_OK: error("Sorry! This Python version is not compatible. Hifumi needs " "Python 3.6 or higher. You have Python version {}.\n".format( platform.python_version()) + " Install the required " "version and try again.\n") exit(1) elif not pip: error("Hey! Python is installed but you are missing the pip module." "\nPlease reinstall Python without " "unchecking any option during the setup >_<") exit(1) else: info("Initializating...") if IS_LINUX and not is_command(): info( "We detected this launcher is not a bash command. Would you like " "to create a bash command to execute this launcher?") if user_pick_yes_no(): bash_command() elif detect_errors(): clear_screen() print("You got some warnings/errors. It's highly recommended " "to fix them before you continue.\n") string_errors() pause() clear_screen() else: main()
def install_reqs(): """ Installs the required requirements for the environment. :return: Pip call, then exit code. 0 if everything is fine, 1 if error ocurred. """ remove_reqs_readonly() interpreter = sys.executable.split('/')[-1] if not interpreter: error("Python interpreter not found.") return txt = REQS_TXT args = [ interpreter, "-m", "pip", "install", "--upgrade", "--target", str(REQS_DIR), "-r", txt ] if IS_MAC: args.remove("--target") args.remove(str(REQS_DIR)) code = subprocess.call(args) if code == 0: info("\nPython requirements installed successfully! " "Now installing PM2...") pm2_str = subprocess.call(['npm', 'install', 'pm2', '-g']) if pm2_str == 0: info("\nPM2 installed successfully!") else: error("\nUh oh! An error ocurred and installation is going to be " "aborted.\nPlease fix the error above basing in the docs.\n") else: error("\nUh oh! An error ocurred and installation is going to " "be aborted.\nPlease fix the error above basing in the docs.\n")