diff --git a/.gitignore b/.gitignore index 2c32b44..704d466 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ received_memory.json translation_report.txt translationcompleteness.py modules/volta +log.txt \ No newline at end of file diff --git a/bot.py b/bot.py index 9755f8e..8cb283d 100644 --- a/bot.py +++ b/bot.py @@ -11,9 +11,25 @@ import uuid import asyncio import sys from typing import List, Dict, Set, Optional, Tuple, Any, Union, Callable, Coroutine, TypeVar, Type - +import logging from modules.globalvars import * from modules.prestartchecks import start_checks +from modules.logger import GooberFormatter +import logging + +logger = logging.getLogger("goober") +logger.setLevel(logging.DEBUG) + +console_handler = logging.StreamHandler() +console_handler.setLevel(logging.DEBUG) +console_handler.setFormatter(GooberFormatter()) + +file_handler = logging.FileHandler("log.txt", mode="w+", encoding="UTF-8") +file_handler.setLevel(logging.DEBUG) +file_handler.setFormatter(GooberFormatter(colors=False)) + +logger.addHandler(console_handler) +logger.addHandler(file_handler) # Print splash text and check for updates print(splashtext) # Print splash text (from modules/globalvars.py) @@ -65,7 +81,7 @@ bot: commands.Bot = commands.Bot( memory: List[str] = load_memory() markov_model: Optional[markovify.Text] = load_markov_model() if not markov_model: - print(f"{RED}{(_('markov_model_not_found'))}{RESET}") + logger.error(_('markov_model_not_found')) memory = load_memory() markov_model = train_markov_model(memory) @@ -79,9 +95,9 @@ async def load_cogs_from_folder(bot, folder_name="assets/cogs"): module_path = folder_name.replace("/", ".").replace("\\", ".") + f".{cog_name}" try: await bot.load_extension(module_path) - print(f"{GREEN}{(_('loaded_cog'))} {cog_name}{RESET}") + logger.info(f"{(_('loaded_cog'))} {cog_name}") except Exception as e: - print(f"{RED}{(_('cog_fail'))} {cog_name} {e}{RESET}") + logger.error(f"{(_('cog_fail'))} {cog_name} {e}") traceback.print_exc() async def fetch_active_users() -> str: @@ -92,7 +108,7 @@ async def fetch_active_users() -> str: else: return "?" except Exception as e: - print(f"{RED}{(_('error_fetching_active_users'))}{RESET} {e}") + logger.e(f"{_('error_fetching_active_users')} {RESET} {e}") return "?" async def send_alive_ping_periodically() -> None: @@ -100,7 +116,7 @@ async def send_alive_ping_periodically() -> None: try: requests.post(f"{VERSION_URL}/aliveping", json={"name": NAME}) except Exception as e: - print(f"{RED}{(_('error_sending_alive_ping'))}{RESET} {e}") + logger.error(f"{(_('error_sending_alive_ping'))}{RESET} {e}") await asyncio.sleep(60) # Event: Called when the bot is ready @@ -117,21 +133,21 @@ async def on_ready() -> None: await load_cogs_from_folder(bot) try: synced: List[discord.app_commands.AppCommand] = await bot.tree.sync() - print(f"{GREEN}{_('synced_commands')} {len(synced)} {(_('synced_commands2'))} {RESET}") + logger.info(f"{_('synced_commands')} {len(synced)} {(_('synced_commands2'))}") slash_commands_enabled = True ping_server() # ping_server from modules/central.py active_users: str = await fetch_active_users() - print(f"{GREEN}{(_('active_users:'))} {active_users}{RESET}") - print(f"{GREEN}{(_('started')).format(name=NAME)}{RESET}") + logger.info(f"{(_('active_users:'))} {active_users}") + logger.info(f"{(_('started')).format(name=NAME)}") bot.loop.create_task(send_alive_ping_periodically()) except discord.errors.Forbidden as perm_error: - print(f"{RED}Permission error while syncing commands: {perm_error}{RESET}") - print(f"{RED}Make sure the bot has the 'applications.commands' scope and is invited with the correct permissions.{RESET}") + logger.error(f"Permission error while syncing commands: {perm_error}") + logger.error("Make sure the bot has the 'applications.commands' scope and is invited with the correct permissions.") quit() except Exception as e: - print(f"{RED}{(_('fail_commands_sync'))} {e}{RESET}") + logger.error(f"{_('fail_commands_sync')} {e}") traceback.print_exc() quit() @@ -181,13 +197,13 @@ async def retrain(ctx: commands.Context) -> None: for i, data in enumerate(memory): processed_data += 1 if processed_data % 1000 == 0 or processed_data == data_size: - await send_message(ctx, f"{(_('command_markov_retraining')).format(processed_data=processed_data, data_size=data_size)}", edit=True, message_reference=processing_message_ref) + await send_message(ctx, f"{_('command_markov_retraining').format(processed_data=processed_data, data_size=data_size)}", edit=True, message_reference=processing_message_ref) global markov_model markov_model = train_markov_model(memory) save_markov_model(markov_model) - await send_message(ctx, f"{(_('command_markov_retrain_successful')).format(data_size=data_size)}", edit=True, message_reference=processing_message_ref) + await send_message(ctx, f"{_('command_markov_retrain_successful').format(data_size=data_size)}", edit=True, message_reference=processing_message_ref) # Command: Generate a sentence using the Markov model @bot.hybrid_command(description=f"{(_('command_desc_talk'))}") @@ -219,7 +235,7 @@ async def talk(ctx: commands.Context, sentence_size: int = 5) -> None: combined_message: str = f"{coherent_response}\n[jif]({gif_url})" else: combined_message: str = coherent_response - print(combined_message) + logger.info(combined_message) os.environ['gooberlatestgen'] = combined_message await send_message(ctx, combined_message) else: @@ -247,7 +263,7 @@ async def impact(ctx: commands.Context) -> None: else: fallback_image: Optional[str] = get_random_asset_image() if fallback_image is None: - await ctx.reply((_('no_image_available'))) + await ctx.reply(_('no_image_available')) return temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1]) shutil.copy(fallback_image, temp_input) @@ -255,7 +271,7 @@ async def impact(ctx: commands.Context) -> None: else: fallback_image = get_random_asset_image() if fallback_image is None: - await ctx.reply((_('no_image_available'))) + await ctx.reply(_('no_image_available')) return temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1]) shutil.copy(fallback_image, temp_input) @@ -266,7 +282,7 @@ async def impact(ctx: commands.Context) -> None: if output_path is None or not os.path.isfile(output_path): if temp_input and os.path.exists(temp_input): os.remove(temp_input) - await ctx.reply((_('failed_generate_image'))) + await ctx.reply(_('failed_generate_image')) return await ctx.send(file=discord.File(output_path)) @@ -296,7 +312,7 @@ async def demotivator(ctx: commands.Context) -> None: else: fallback_image: Optional[str] = get_random_asset_image() if fallback_image is None: - await ctx.reply((_('no_image_available'))) + await ctx.reply(_('no_image_available')) return temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1]) shutil.copy(fallback_image, temp_input) @@ -304,7 +320,7 @@ async def demotivator(ctx: commands.Context) -> None: else: fallback_image = get_random_asset_image() if fallback_image is None: - await ctx.reply((_('no_image_available'))) + await ctx.reply(_('no_image_available')) return temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1]) shutil.copy(fallback_image, temp_input) @@ -375,7 +391,7 @@ async def on_message(message: discord.Message) -> None: return if message.content.startswith((f"{PREFIX}talk", f"{PREFIX}mem", f"{PREFIX}help", f"{PREFIX}stats", f"{PREFIX}")): - print(f"{(_('command_ran')).format(message=message)}") + logger.info(f"{(_('command_ran')).format(message=message)}") await bot.process_commands(message) return @@ -399,14 +415,14 @@ async def on_message(message: discord.Message) -> None: try: await message.add_reaction(emoji) except Exception as e: - print(f"Failed to react with emoji: {e}") + logger.info(f"Failed to react with emoji: {e}") await bot.process_commands(message) # Event: Called on every interaction (slash command, etc.) @bot.event async def on_interaction(interaction: discord.Interaction) -> None: - print(f"{(_('command_ran_s')).format(interaction=interaction)}{interaction.data['name']}") + logger.info(f"{(_('command_ran_s')).format(interaction=interaction)}{interaction.data['name']}") # Global check: Block blacklisted users from running commands @bot.check @@ -415,11 +431,11 @@ async def block_blacklisted(ctx: commands.Context) -> bool: try: if isinstance(ctx, discord.Interaction): if not ctx.response.is_done(): - await ctx.response.send_message((_('blacklisted')), ephemeral=True) + await ctx.response.send_message(_('blacklisted'), ephemeral=True) else: - await ctx.followup.send((_('blacklisted')), ephemeral=True) + await ctx.followup.send(_('blacklisted'), ephemeral=True) else: - await ctx.send((_('blacklisted_user')), ephemeral=True) + await ctx.send(_('blacklisted_user'), ephemeral=True) except: pass return False @@ -483,7 +499,7 @@ async def mem(ctx: commands.Context) -> None: return command: str = """curl -F "reqtype=fileupload" -F "time=1h" -F "fileToUpload=@memory.json" https://litterbox.catbox.moe/resources/internals/api.php""" memorylitter: subprocess.CompletedProcess = subprocess.run(command, shell=True, capture_output=True, text=True) - print(memorylitter) + logger.debug(memorylitter) await send_message(ctx, memorylitter.stdout.strip()) # Helper: Improve sentence coherence (simple capitalization fix) diff --git a/modules/central.py b/modules/central.py index 335e6ef..6293bbb 100644 --- a/modules/central.py +++ b/modules/central.py @@ -3,17 +3,19 @@ import os import modules.globalvars as gv from modules.volta.main import _ from modules.markovmemory import get_file_info +import logging +logger = logging.getLogger("goober") # Ping the server to check if it's alive and send some info def ping_server(): if gv.ALIVEPING == "false": # If pinging is disabled, print message and set environment variable - print(f"{gv.YELLOW}{(_('pinging_disabled'))}{gv.RESET}") + print(f"{gv.YELLOW}{(_('pinging_disabled'))}") os.environ['gooberauthenticated'] = 'No' return # Get server alert message goobres = requests.get(f"{gv.VERSION_URL}/alert") - print(f"{(_('goober_server_alert'))}{goobres.text}") + logger.info(f"{(_('goober_server_alert'))}{goobres.text}") # Gather file info for payload file_info = get_file_info(gv.MEMORY_FILE) payload = { @@ -28,15 +30,15 @@ def ping_server(): response = requests.post(gv.VERSION_URL+"/ping", json=payload) if response.status_code == 200: # Success: print message and set environment variable - print(f"{gv.GREEN}{(_('goober_ping_success')).format(NAME=gv.NAME)}{gv.RESET}") + logger.info(f"{(_('goober_ping_success')).format(NAME=gv.NAME)}") os.environ['gooberauthenticated'] = 'Yes' else: # Failure: print error and set environment variable - print(f"{gv.RED}{(_('goober_ping_fail'))} {response.status_code}{gv.RESET}") + logger.error(f"{(_('goober_ping_fail'))} {response.status_code}") os.environ['gooberauthenticated'] = 'No' except Exception as e: # Exception: print error and set environment variable - print(f"{gv.RED}{(_('goober_ping_fail2'))} {str(e)}{gv.RESET}") + logger.error(f"{(_('goober_ping_fail2'))} {str(e)}") os.environ['gooberauthenticated'] = 'No' # Check if a given name is available for registration @@ -52,11 +54,11 @@ def is_name_available(NAME): return data.get("available", False) else: # Print error if request failed - print(f"{(_('name_check'))}", response.json()) + logger.e(f"{(_('name_check'))}", response.json()) return False except Exception as e: # Print exception if request failed - print(f"{(_('name_check2'))}", e) + logger.error(f"{(_('name_check2'))}", e) return False # Register a new name with the server @@ -70,7 +72,7 @@ def register_name(NAME): if os.getenv("gooberTOKEN"): return # Name taken: print error and exit - print(f"{gv.RED}{(_('name_taken'))}{gv.RESET}") + logger.critical(f"{(_('name_taken'))}") quit() # Register the name response = requests.post(f"{gv.VERSION_URL}/register", json={"name": NAME}, headers={"Content-Type": "application/json"}) @@ -79,18 +81,18 @@ def register_name(NAME): token = data.get("token") if not os.getenv("gooberTOKEN"): # Print instructions to add token and exit - print(f"{gv.GREEN}{(_('add_token')).format(token=token)} gooberTOKEN=.{gv.gv.RESET}") + logger.info(f"{(_('add_token')).format(token=token)} gooberTOKEN=.") quit() else: print(f"{gv.GREEN}{gv.gv.RESET}") return token else: # Print error if registration failed - print(f"{gv.RED}{(_('token_exists')).format()}{gv.RESET}", response.json()) + logger.critical(f"{gv.RED}{(_('token_exists')).format()}", response.json()) return None except Exception as e: # Print exception if registration failed - print(f"{gv.RED}{(_('registration_error')).format()}{gv.RESET}", e) + logger.critical(f"{gv.RED}{(_('registration_error')).format()}", e) return None # Attempt to register the name at module load diff --git a/modules/globalvars.py b/modules/globalvars.py index 2356a2e..41ba19d 100644 --- a/modules/globalvars.py +++ b/modules/globalvars.py @@ -10,6 +10,7 @@ ANSI = "\033[" RED = f"{ANSI}31m" GREEN = f"{ANSI}32m" YELLOW = f"{ANSI}33m" +PURPLE = f"{ANSI}35m" DEBUG = f"{ANSI}1;30m" RESET = f"{ANSI}0m" VERSION_URL = "https://goober.expect.ovh" @@ -40,5 +41,5 @@ latest_version = "0.0.0" local_version = "2.1.3" os.environ['gooberlocal_version'] = local_version REACT = os.getenv("REACT") -beta = False # this makes goober think its a beta version, so it will not update to the latest stable version or run any version checks +beta = True # this makes goober think its a beta version, so it will not update to the latest stable version or run any version checks \ No newline at end of file diff --git a/modules/logger.py b/modules/logger.py new file mode 100644 index 0000000..76f5f10 --- /dev/null +++ b/modules/logger.py @@ -0,0 +1,25 @@ +import logging +from modules.globalvars import * + +class GooberFormatter(logging.Formatter): + def __init__(self, colors: bool = True): # Disable colors for TXT output + self.colors = colors + + self._format = f"[ %(levelname)-8s ]: %(message)s {DEBUG} [%(asctime)s.%(msecs)03d] (%(filename)s:%(funcName)s) {RESET}" + + self.FORMATS = { + logging.DEBUG: DEBUG + self._format + RESET, + logging.INFO: self._format.replace("%(levelname)-8s", f"{GREEN}%(levelname)-8s{RESET}"), + logging.WARNING: YELLOW + self._format + RESET, + logging.ERROR: RED + self._format + RESET, + logging.CRITICAL: PURPLE + self._format + RESET + } + + def format(self, record: logging.LogRecord): + if self.colors: + log_fmt = self.FORMATS.get(record.levelno) # Add colors + else: + log_fmt = self._format # Just use the default format + + formatter = logging.Formatter(log_fmt, datefmt="%m/%d/%y %H:%M:%S") + return formatter.format(record) diff --git a/modules/markovmemory.py b/modules/markovmemory.py index eae003e..f903f59 100644 --- a/modules/markovmemory.py +++ b/modules/markovmemory.py @@ -4,7 +4,8 @@ import markovify import pickle from modules.globalvars import * from modules.volta.main import _ - +import logging +logger = logging.getLogger("goober") # Get file size and line count for a given file path def get_file_info(file_path): try: @@ -47,15 +48,15 @@ def train_markov_model(memory, additional_data=None): def save_markov_model(model, filename='markov_model.pkl'): with open(filename, 'wb') as f: pickle.dump(model, f) - print(f"Markov model saved to {filename}.") + logger.info(f"Markov model saved to {filename}.") # Load the Markov model from a pickle file def load_markov_model(filename='markov_model.pkl'): try: with open(filename, 'rb') as f: model = pickle.load(f) - print(f"{GREEN}{_('model_loaded')} {filename}.{RESET}") + logger.info(f"{_('model_loaded')} {filename}.{RESET}") return model except FileNotFoundError: - print(f"{RED}{filename} {_('not_found')}{RESET}") + logger.error(f"{filename} {_('not_found')}{RESET}") return None \ No newline at end of file diff --git a/modules/prestartchecks.py b/modules/prestartchecks.py index 1f4b736..60c1d76 100644 --- a/modules/prestartchecks.py +++ b/modules/prestartchecks.py @@ -10,6 +10,9 @@ import json import re from spacy.util import is_package import importlib.metadata +import logging + +logger = logging.getLogger("goober") # import shutil psutilavaliable = True @@ -18,20 +21,20 @@ try: import psutil except ImportError: psutilavaliable = False - print(RED, _('missing_requests_psutil'), RESET) + logger.error(_('missing_requests_psutil')) def check_for_model(): if is_package("en_core_web_sm"): - print("Model is installed.") + logger.info("Model is installed.") else: - print("Model is not installed.") + logger.info("Model is not installed.") def iscloned(): if os.path.exists(".git"): return True else: - print(f"{RED}{(_('not_cloned'))}{RESET}") + logger.error(f"{_('not_cloned')}") sys.exit(1) def get_stdlib_modules(): @@ -63,7 +66,7 @@ def check_requirements(): requirements_path = os.path.abspath(os.path.join(parent_dir, '..', 'requirements.txt')) if not os.path.exists(requirements_path): - print(f"{RED}{(_('requirements_not_found')).format(path=requirements_path)}{RESET}") + logger.error(f"{(_('requirements_not_found')).format(path=requirements_path)}") return with open(requirements_path, 'r') as f: @@ -95,9 +98,9 @@ def check_requirements(): continue requirements.add(pkg) except Exception as e: - print(f"{YELLOW}{(_('warning_failed_parse_imports')).format(filename=filename, error=e)}{RESET}") + logger.warning(f"{(_('warning_failed_parse_imports')).format(filename=filename, error=e)}") else: - print(f"{YELLOW}{(_('cogs_dir_not_found')).format(path=cogs_dir)}{RESET}") + logger.warning(f"{(_('cogs_dir_not_found')).format(path=cogs_dir)}") installed_packages = {dist.metadata['Name'].lower() for dist in importlib.metadata.distributions()} missing = [] @@ -110,16 +113,16 @@ def check_requirements(): check_name = PACKAGE_ALIASES.get(req, req).lower() if check_name in installed_packages: - print(f"[ {GREEN}{(_('ok_installed')).format(package=check_name)}{RESET} ] {check_name}") + logger.info(f"{_('ok_installed').format(package=check_name)} {check_name}") else: - print(f"[ {RED}{(_('missing_package')).format(package=check_name)}{RESET} ] {check_name} {(_('missing_package2'))}") + logger.error(f"{(_('missing_package')).format(package=check_name)} {check_name} {(_('missing_package2'))}") missing.append(check_name) if missing: - print(RED, _('missing_packages_detected'), RESET) + logger.error(_('missing_packages_detected')) for pkg in missing: print(f" - {pkg}") - print((_('telling_goober_central')).format(url=VERSION_URL)) + logger.info((_('telling_goober_central')).format(url=VERSION_URL)) payload = { "name": NAME, "version": local_version, @@ -129,10 +132,10 @@ def check_requirements(): try: requests.post(VERSION_URL + "/ping", json=payload) # type: ignore except Exception as e: - print(f"{RED}{(_('failed_to_contact')).format(url=VERSION_URL, error=e)}{RESET}") + logger.error(f"{(_('failed_to_contact')).format(url=VERSION_URL, error=e)}") sys.exit(1) else: - print(_('all_requirements_satisfied')) + logger.info(_('all_requirements_satisfied')) def check_latency(): host = "1.1.1.1" @@ -158,16 +161,16 @@ def check_latency(): match = re.search(latency_pattern, result.stdout) if match: latency_ms = float(match.group(1)) - print((_('ping_to')).format(host=host, latency=latency_ms)) + logger.info((_('ping_to')).format(host=host, latency=latency_ms)) if latency_ms > 300: - print(f"{YELLOW}{(_('high_latency'))}{RESET}") + logger.warning(f"{(_('high_latency'))}") else: - print(f"{YELLOW}{(_('could_not_parse_latency'))}{RESET}") + logger.warning((_('could_not_parse_latency'))) else: print(result.stderr) - print(f"{RED}{(_('ping_failed')).format(host=host)}{RESET}") + logger.error(f"{(_('ping_failed')).format(host=host)}{RESET}") except Exception as e: - print(f"{RED}{(_('error_running_ping')).format(error=e)}{RESET}") + logger.error((_('error_running_ping')).format(error=e)) def check_memory(): if psutilavaliable == False: @@ -178,21 +181,21 @@ def check_memory(): used_memory = memory_info.used / (1024 ** 3) free_memory = memory_info.available / (1024 ** 3) - print((_('memory_usage')).format(used=used_memory, total=total_memory, percent=(used_memory / total_memory) * 100)) + logger.info((_('memory_usage')).format(used=used_memory, total=total_memory, percent=(used_memory / total_memory) * 100)) if used_memory > total_memory * 0.9: print(f"{YELLOW}{(_('memory_above_90')).format(percent=(used_memory / total_memory) * 100)}{RESET}") - print((_('total_memory')).format(total=total_memory)) - print((_('used_memory')).format(used=used_memory)) + logger.info((_('total_memory')).format(total=total_memory)) + logger.info((_('used_memory')).format(used=used_memory)) if free_memory < 1: - print(f"{RED}{(_('low_free_memory')).format(free=free_memory)}{RESET}") + logger.warning(f"{(_('low_free_memory')).format(free=free_memory)}") sys.exit(1) except ImportError: - print(_('psutil_not_installed')) # todo: translate this into italian and put it in the translations "psutil is not installed. Memory check skipped." + logger.error(_('psutil_not_installed')) # todo: translate this into italian and put it in the translations "psutil is not installed. Memory check skipped." def check_cpu(): if psutilavaliable == False: return - print((_('measuring_cpu'))) + logger.info((_('measuring_cpu'))) cpu_per_core = psutil.cpu_percent(interval=1, percpu=True) # type: ignore for idx, core_usage in enumerate(cpu_per_core): bar_length = int(core_usage / 5) @@ -203,33 +206,33 @@ def check_cpu(): color = YELLOW else: color = GREEN - print((_('core_usage')).format(idx=idx, bar=bar, usage=core_usage)) + logger.info((_('core_usage')).format(idx=idx, bar=bar, usage=core_usage)) total_cpu = sum(cpu_per_core) / len(cpu_per_core) - print((_('total_cpu_usage')).format(usage=total_cpu)) + logger.info((_('total_cpu_usage')).format(usage=total_cpu)) if total_cpu > 85: - print(f"{YELLOW}{(_('high_avg_cpu')).format(usage=total_cpu)}{RESET}") + logger.warning(f"{(_('high_avg_cpu')).format(usage=total_cpu)}") if total_cpu > 95: - print(f"{RED}{(_('really_high_cpu'))}{RESET}") + logger.error(_('really_high_cpu')) sys.exit(1) def check_memoryjson(): try: - print((_('memory_file')).format(size=os.path.getsize(MEMORY_FILE) / (1024 ** 2))) + logger.info((_('memory_file')).format(size=os.path.getsize(MEMORY_FILE) / (1024 ** 2))) if os.path.getsize(MEMORY_FILE) > 1_073_741_824: - print(f"{YELLOW}{(_('memory_file_large'))}{RESET}") + logger.warning(f"{(_('memory_file_large'))}") try: with open(MEMORY_FILE, 'r', encoding='utf-8') as f: json.load(f) except json.JSONDecodeError as e: - print(f"{RED}{(_('memory_file_corrupted')).format(error=e)}{RESET}") - print(f"{YELLOW}{(_('consider_backup_memory'))}{RESET}") + logger.error(f"{(_('memory_file_corrupted')).format(error=e)}") + logger.warning(f"{(_('consider_backup_memory'))}") except UnicodeDecodeError as e: - print(f"{RED}{(_('memory_file_encoding')).format(error=e)}{RESET}") - print(f"{YELLOW}{(_('consider_backup_memory'))}{RESET}") + logger.error(f"{(_('memory_file_encoding')).format(error=e)}") + logger.warning(f"{(_('consider_backup_memory'))}") except Exception as e: - print(f"{RED}{(_('error_reading_memory')).format(error=e)}{RESET}") + logger.error(f"{(_('error_reading_memory')).format(error=e)}") except FileNotFoundError: - print(f"{YELLOW}{(_('memory_file_not_found'))}{RESET}") + logger(f"{(_('memory_file_not_found'))}") def presskey2skip(timeout): if os.name == 'nt': @@ -265,9 +268,9 @@ def presskey2skip(timeout): beta = beta def start_checks(): if CHECKS_DISABLED == "True": - print(f"{YELLOW}{(_('checks_disabled'))}{RESET}") + logger.warning(f"{(_('checks_disabled'))}") return - print(_('running_prestart_checks')) + logger.info(_('running_prestart_checks')) check_for_model() iscloned() check_missing_translations() @@ -279,13 +282,13 @@ def start_checks(): if os.path.exists(".env"): pass else: - print(f"{YELLOW}{(_('env_file_not_found'))}{RESET}") + logger.warning(f"{(_('env_file_not_found'))}") sys.exit(1) if beta == True: - print(f"{YELLOW}this build isnt finished yet, some things might not work as expected{RESET}") + logger.warning(f"this build isnt finished yet, some things might not work as expected") else: pass - print(_('continuing_in_seconds').format(seconds=5)) + logger.info(_('continuing_in_seconds').format(seconds=5)) presskey2skip(timeout=5) os.system('cls' if os.name == 'nt' else 'clear') print(splashtext) \ No newline at end of file diff --git a/modules/sentenceprocessing.py b/modules/sentenceprocessing.py index c470aef..993ba90 100644 --- a/modules/sentenceprocessing.py +++ b/modules/sentenceprocessing.py @@ -6,17 +6,20 @@ import spacy from spacy.tokens import Doc from spacytextblob.spacytextblob import SpacyTextBlob +import logging +logger = logging.getLogger("goober") + def check_resources(): try: nlp = spacy.load("en_core_web_sm") except OSError: - print((_('spacy_model_not_found'))) + logging.critical((_('spacy_model_not_found'))) spacy.cli.download("en_core_web_sm") nlp = spacy.load("en_core_web_sm") if "spacytextblob" not in nlp.pipe_names: nlp.add_pipe("spacytextblob") - print((_('spacy_initialized'))) + logger.info((_('spacy_initialized'))) check_resources() @@ -28,8 +31,8 @@ def is_positive(sentence): doc = nlp(sentence) sentiment_score = doc._.polarity # from spacytextblob - debug_message = f"{DEBUG}{(_('sentence_positivity'))} {sentiment_score}{RESET}" - print(debug_message) + debug_message = f"{(_('sentence_positivity'))} {sentiment_score}{RESET}" + logger.debug(debug_message) return sentiment_score > 0.6 # had to raise the bar because it kept saying "death to jews" was fine and it kept reacting to them diff --git a/modules/version.py b/modules/version.py index f876123..d1493ab 100644 --- a/modules/version.py +++ b/modules/version.py @@ -3,7 +3,8 @@ from modules.globalvars import * import requests import subprocess import sys - +import logging +logger = logging.getLogger("goober") launched = False # Run a shell command and return its output @@ -27,11 +28,11 @@ def auto_update(branch='main', remote='origin'): if is_remote_ahead(branch, remote): print(_( "remote_ahead").format(remote=remote, branch=branch)) pull_result = run_cmd(f'git pull {remote} {branch}') - print(pull_result) - print(_( "please_restart")) + logger.info(pull_result) + logger.info(_( "please_restart")) sys.exit(0) else: - print(_( "local_ahead").format(remote=remote, branch=branch)) + logger.info(_( "local_ahead").format(remote=remote, branch=branch)) # Fetch the latest version info from the update server def get_latest_version_info(): @@ -40,10 +41,10 @@ def get_latest_version_info(): if response.status_code == 200: return response.json() else: - print(f"{RED}{_( 'version_error')} {response.status_code}{RESET}") + logger.error(f"{RED}{_( 'version_error')} {response.status_code}{RESET}") return None except requests.RequestException as e: - print(f"{RED}{_( 'version_error')} {e}{RESET}") + logger.error(f"{RED}{_( 'version_error')} {e}{RESET}") return None # Check if an update is available and perform update if needed @@ -54,7 +55,7 @@ def check_for_update(): latest_version_info = get_latest_version_info() if not latest_version_info: - print(f"{_('fetch_update_fail')}") + logger.error(f"{_('fetch_update_fail')}") return None, None latest_version = latest_version_info.get("version") @@ -62,25 +63,25 @@ def check_for_update(): download_url = latest_version_info.get("download_url") if not latest_version or not download_url: - print(f"{RED}{_(LOCALE, 'invalid_server')}{RESET}") + logger.error(f"{RED}{_(LOCALE, 'invalid_server')}{RESET}") return None, None # Check if local_version is valid if local_version == "0.0.0" or None: - print(f"{RED}{_('cant_find_local_version')}{RESET}") + logger.error(f"{RED}{_('cant_find_local_version')}{RESET}") return # Compare local and latest versions if local_version < latest_version: - print(f"{YELLOW}{_('new_version').format(latest_version=latest_version, local_version=local_version)}{RESET}") - print(f"{YELLOW}{_('changelog').format(VERSION_URL=VERSION_URL)}{RESET}") + logger.info(f"{YELLOW}{_('new_version').format(latest_version=latest_version, local_version=local_version)}{RESET}") + logger.info(f"{YELLOW}{_('changelog').format(VERSION_URL=VERSION_URL)}{RESET}") auto_update() elif beta == True: - print(f"{YELLOW}You are running an \"unstable\" version of Goober, do not expect it to work properly.\nVersion {local_version}{RESET}") + logger.warning(f"You are running an \"unstable\" version of Goober, do not expect it to work properly.\nVersion {local_version}{RESET}") elif local_version > latest_version: - print(f"{YELLOW}{_('modification_warning')}{RESET}") + logger.warning(f"{_('modification_warning')}") elif local_version == latest_version: - print(f"{GREEN}{_('latest_version')} {local_version}{RESET}") - print(f"{_('latest_version2').format(VERSION_URL=VERSION_URL)}\n\n") + logger.info(f"{_('latest_version')} {local_version}") + logger.info(f"{_('latest_version2').format(VERSION_URL=VERSION_URL)}\n\n") launched = True return latest_version \ No newline at end of file