the translation update

This commit is contained in:
WhatDidYouExpect 2025-07-01 16:21:34 +02:00
parent 2e3c6942b6
commit d122c5ffe9
22 changed files with 345 additions and 84 deletions

123
assets/locales/en.json Normal file
View file

@ -0,0 +1,123 @@
{
"already_started": "I've already started! I'm not updating...",
"please_restart": "Please Restart goober!",
"local_ahead": "Local {remote}/{branch} is ahead and/or up to par. Not Updating...",
"remote_ahead": "Remote {remote}/{branch} is ahead. Updating...",
"cant_find_local_version": "I can't find the local_version variable! Or it's been tampered with and it's not an integer!",
"running_prestart_checks": "Running pre-start checks...",
"continuing_in_seconds": "Continuing in {seconds} seconds... Press any key to skip.",
"missing_requests_psutil": "Missing requests and psutil! Please install them using pip: `pip install requests psutil`",
"requirements_not_found": "requirements.txt not found at {path} was it tampered with?",
"warning_failed_parse_imports": "Warning: Failed to parse imports from {filename}: {error}",
"cogs_dir_not_found": "Cogs directory not found at {path}, skipping scan.",
"std_lib_local_skipped": "STD LIB / LOCAL {package} (skipped check)",
"ok_installed": "OK",
"missing_package": "MISSING",
"missing_package2": "is not installed",
"missing_packages_detected": "Missing packages detected:",
"telling_goober_central": "Telling goober central at {url}",
"failed_to_contact": "Failed to contact {url}: {error}",
"all_requirements_satisfied": "All requirements are satisfied.",
"ping_to": "Ping to {host}: {latency} ms",
"high_latency": "High latency detected! You may experience delays in response times.",
"could_not_parse_latency": "Could not parse latency.",
"ping_failed": "Ping to {host} failed.",
"error_running_ping": "Error running ping: {error}",
"memory_usage": "Memory Usage: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Memory usage is above 90% ({percent}%). Consider freeing up memory.",
"total_memory": "Total Memory: {total} GB",
"used_memory": "Used Memory: {used} GB",
"low_free_memory": "Low free memory detected! Only {free} GB available.",
"measuring_cpu": "Measuring CPU usage per core...",
"core_usage": "Core {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Total CPU Usage: {usage}%",
"high_avg_cpu": "High average CPU usage: {usage}%",
"really_high_cpu": "Really high CPU load! System may throttle or hang.",
"memory_file": "Memory file: {size} MB",
"memory_file_large": "Memory file is 1GB or higher, consider clearing it to free up space.",
"memory_file_corrupted": "Memory file is corrupted! JSON decode error: {error}",
"consider_backup_memory": "Consider backing up and recreating the memory file.",
"memory_file_encoding": "Memory file has encoding issues: {error}",
"error_reading_memory": "Error reading memory file: {error}",
"memory_file_not_found": "Memory file not found.",
"modification_warning": "Goober has been modified! Any changes will be lost in an update!",
"reported_version": "Reported Version:",
"current_hash": "Current Hash:",
"not_found": "is not found!",
"version_error": "Unable to fetch version info. Status code",
"loaded_cog": "Loaded cog:",
"loaded_cog2": "Loaded module:",
"cog_fail": "Failed to load cog:",
"cog_fail2": "Failed to load module:",
"no_model": "No saved Markov model found. Starting from scratch.",
"folder_created": "Folder '{folder_name}' created.",
"folder_exists": "Folder '{folder_name}' already exists. skipping...",
"logged_in": "Logged in as",
"synced_commands": "Synced",
"synced_commands2": "commands!",
"fail_commands_sync": "Failed to sync commands:",
"started": "{name} has started!",
"name_check": "Error checking name availability:",
"name_taken": "Name is already taken. Please choose a different name.",
"name_check2": "Error during name availability check:",
"add_token": "Token: {token}\nPlease add this token to your .env file as",
"token_exists": "Token already exists in .env. Continuing with the existing token.",
"registration_error": "Error during registration:",
"version_backup": "Backup created:",
"backup_error": "Error: {LOCAL_VERSION_FILE} not found for backup.",
"model_loaded": "Markov model loaded from",
"fetch_update_fail": "Could not fetch update information.",
"invalid_server": "Error: Invalid version information received from server.",
"goober_server_alert": "Alert from goober central!\n",
"new_version": "New version available: {latest_version} (Current: {local_version})",
"changelog": "Check {VERSION_URL}/goob/changes.txt to check out the changelog\n\n",
"invalid_version": "The version: {local_version} isnt valid!",
"invalid_version2": "If this is intended then ignore this message, else press Y to pull a valid version from the server regardless of the version of goober currently running",
"invalid_version3": "The current version will be backed up to current_version.bak..",
"input": "(Y or any other key to ignore....)",
"modification_ignored": "You've modified",
"modification_ignored2": "IGNOREWARNING is set to false..",
"latest_version": "You're using the latest version:",
"latest_version2": "Check {VERSION_URL}/goob/changes.txt to check out the changelog",
"pinging_disabled": "Pinging is disabled! Not telling the server im on...",
"goober_ping_success": "Logged into goober central as {NAME}",
"goober_ping_fail": "Failed to send data. Server returned status code:",
"goober_ping_fail2": "An error occurred while sending data:",
"sentence_positivity": "Positivity of sentence is:",
"command_edit_fail": "Failed to edit message:",
"command_desc_retrain": "Retrains the Markov model manually.",
"command_markov_retrain": "Retraining the Markov model... Please wait.",
"command_markov_memory_not_found": "Error: memory file not found!",
"command_markov_memory_is_corrupt": "Error: memory file is corrupt!",
"command_markov_retraining": "Processing {processed_data}/{data_size} data points...",
"command_markov_retrain_successful": "Markov model retrained successfully using {data_size} data points!",
"command_desc_talk":"talks n like stuf",
"command_talk_insufficent_text": "I need to learn more from messages before I can talk.",
"command_talk_generation_fail": "I have nothing to say right now!",
"command_desc_help": "help",
"command_help_embed_title": "Bot Help",
"command_help_embed_desc": "List of commands grouped by category.",
"command_help_categories_general": "General",
"command_help_categories_admin": "Administration",
"command_help_categories_custom": "Custom Commands",
"command_ran": "Info: {message.author.name} ran {message.content}",
"command_ran_s": "Info: {interaction.user} ran ",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Bot Latency:",
"command_ping_footer": "Requested by",
"command_about_desc": "about",
"command_about_embed_title": "About me",
"command_about_embed_field1": "Name",
"command_about_embed_field2name": "Version",
"command_about_embed_field2value": "Local: {local_version} \nLatest: {latest_version}",
"command_desc_stats": "stats",
"command_stats_embed_title": "Bot stats",
"command_stats_embed_desc": "Data about the the bot's memory.",
"command_stats_embed_field1name": "File Stats",
"command_stats_embed_field1value": "Size: {file_size} bytes\nLines: {line_count}",
"command_stats_embed_field2name": "Version",
"command_stats_embed_field2value": "Local: {local_version} \nLatest: {latest_version}",
"command_stats_embed_field3name": "Variable Info",
"command_stats_embed_field3value": "Name: {NAME} \nPrefix: {PREFIX} \nOwner ID: {ownerid} \nCooldown: {cooldown_time} \nPing line: {PING_LINE} \nMemory Sharing Enabled: {showmemenabled} \nUser Training Enabled: {USERTRAIN_ENABLED}\nSong: {song} \nSplashtext: ```{splashtext}```"
}

View file

@ -1,4 +1,46 @@
{ {
"already_started": "Olen jo käynnistynyt! En päivitä...",
"please_restart": "Käynnistä uudelleen, hölmö!",
"local_ahead": "Paikallinen {remote}/{branch} on edellä ja/tai ajan tasalla. Ei päivitystä...",
"remote_ahead": "Etärepositorio {remote}/{branch} on edellä. Päivitetään...",
"cant_find_local_version": "En löydä muuttujaa local_version! Tai sitä on muokattu eikä se ole kokonaisluku!",
"running_prestart_checks": "Suoritetaan esikäynnistystarkistuksia...",
"continuing_in_seconds": "Jatketaan {seconds} sekunnin kuluttua... Paina mitä tahansa näppäintä ohittaaksesi.",
"missing_requests_psutil": "Kirjastot requests ja psutil puuttuvat! Asenna ne komennolla: `pip install requests psutil`",
"requirements_not_found": "Tiedostoa requirements.txt ei löytynyt polusta {path} onko sitä muokattu?",
"warning_failed_parse_imports": "Varoitus: Tuontien jäsentäminen epäonnistui tiedostossa {filename}: {error}",
"cogs_dir_not_found": "Cogs-hakemistoa ei löytynyt polusta {path}, ohitetaan tarkistus.",
"std_lib_local_skipped": "STD LIB / PAIKALLINEN {package} (tarkistus ohitettu)",
"ok_installed": "OK",
"missing_package": "PUUTTUU",
"missing_package2": "ei ole asennettu",
"missing_packages_detected": "Puuttuvia kirjastoja havaittu:",
"telling_goober_central": "Ilmoitetaan goober-keskukselle osoitteessa {url}",
"failed_to_contact": "Yhteyden muodostus epäonnistui osoitteeseen {url}: {error}",
"all_requirements_satisfied": "Kaikki vaatimukset täyttyvät.",
"ping_to": "Ping osoitteeseen {host}: {latency} ms",
"high_latency": "Korkea viive havaittu! Vasteajat saattavat hidastua.",
"could_not_parse_latency": "Viivettä ei voitu tulkita.",
"ping_failed": "Ping osoitteeseen {host} epäonnistui.",
"error_running_ping": "Virhe ping-komennon suorittamisessa: {error}",
"memory_usage": "Muistin käyttö: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Muistin käyttö ylittää 90 % ({percent}%). Harkitse muistintilan vapauttamista.",
"total_memory": "Kokonaismuisti: {total} GB",
"used_memory": "Käytetty muisti: {used} GB",
"low_free_memory": "Vähän vapaata muistia! Vain {free} GB jäljellä.",
"measuring_cpu": "Mitataan suorittimen käyttöä ytimittäin...",
"core_usage": "Ydin {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Kokonaisprosessorin käyttö: {usage}%",
"high_avg_cpu": "Korkea keskimääräinen prosessorin käyttö: {usage}%",
"really_high_cpu": "Erittäin korkea prosessorikuorma! Järjestelmä saattaa hidastua tai jumittua.",
"memory_file": "Muistitiedosto: {size} MB",
"memory_file_large": "Muistitiedosto on 1 GB tai suurempi harkitse sen tyhjentämistä tilan vapauttamiseksi.",
"memory_file_corrupted": "Muistitiedosto on vioittunut! JSON purkuvirhe: {error}",
"consider_backup_memory": "Harkitse muistitiedoston varmuuskopioimista ja uudelleenluontia.",
"memory_file_encoding": "Muistitiedostossa on koodausongelmia: {error}",
"error_reading_memory": "Virhe muistitiedoston lukemisessa: {error}",
"memory_file_not_found": "Muistitiedostoa ei löytynyt.",
"modification_warning": "Gooberia on muokattu! Ohitetaan palvelimen tarkistus kokonaan...", "modification_warning": "Gooberia on muokattu! Ohitetaan palvelimen tarkistus kokonaan...",
"reported_version": "Ilmoitettu versio:", "reported_version": "Ilmoitettu versio:",
"current_hash": "Tämänhetkinen hash:", "current_hash": "Tämänhetkinen hash:",

122
assets/locales/it.json Normal file
View file

@ -0,0 +1,122 @@
{
"already_started": "Sono già avviato! Non aggiorno...",
"please_restart": "Riavvia goober!",
"local_ahead": "Il ramo locale {remote}/{branch} è aggiornato o avanti. Nessun aggiornamento...",
"remote_ahead": "Il ramo remoto {remote}/{branch} è avanti. Aggiornamento in corso...",
"cant_find_local_version": "Impossibile trovare la variabile local_version! O è stata manomessa e non è un intero!",
"running_prestart_checks": "Esecuzione dei controlli pre-avvio...",
"continuing_in_seconds": "Continuo tra {seconds} secondi... Premi un tasto per saltare.",
"missing_requests_psutil": "Mancano requests e psutil! Installali con pip: `pip install requests psutil`",
"requirements_not_found": "requirements.txt non trovato in {path} è stato manomesso?",
"warning_failed_parse_imports": "Attenzione: impossibile analizzare le importazioni da {filename}: {error}",
"cogs_dir_not_found": "Cartella cogs non trovata in {path}, scansione saltata.",
"std_lib_local_skipped": "LIB STD / LOCALE {package} (controllo saltato)",
"ok_installed": "OK",
"missing_package": "MANCATE",
"missing_package2": "non è installato",
"missing_packages_detected": "Pacchetti mancanti rilevati:",
"telling_goober_central": "Segnalazione a goober central su {url}",
"failed_to_contact": "Impossibile contattare {url}: {error}",
"all_requirements_satisfied": "Tutti i requisiti sono soddisfatti.",
"ping_to": "Ping a {host}: {latency} ms",
"high_latency": "Latenza elevata rilevata! Potresti riscontrare ritardi nelle risposte.",
"could_not_parse_latency": "Impossibile analizzare la latenza.",
"ping_failed": "Ping a {host} fallito.",
"error_running_ping": "Errore durante l'esecuzione del ping: {error}",
"memory_usage": "Utilizzo memoria: {used} GB / {total} GB ({percent}%)",
"memory_above_90": "Utilizzo memoria sopra il 90% ({percent}%). Considera di liberare memoria.",
"total_memory": "Memoria totale: {total} GB",
"used_memory": "Memoria usata: {used} GB",
"low_free_memory": "Poca memoria libera! Solo {free} GB disponibili.",
"measuring_cpu": "Misurazione utilizzo CPU per core...",
"core_usage": "Core {idx}: [{bar}] {usage}%",
"total_cpu_usage": "Utilizzo totale CPU: {usage}%",
"high_avg_cpu": "Utilizzo medio CPU elevato: {usage}%",
"really_high_cpu": "Carico CPU molto alto! Il sistema potrebbe rallentare o bloccarsi.",
"memory_file": "File memoria: {size} MB",
"memory_file_large": "Il file di memoria è 1GB o più, valuta di svuotarlo.",
"memory_file_corrupted": "File memoria corrotto! Errore JSON decode: {error}",
"consider_backup_memory": "Valuta di fare un backup e ricreare il file di memoria.",
"memory_file_encoding": "Problemi di codifica nel file memoria: {error}",
"error_reading_memory": "Errore nella lettura del file memoria: {error}",
"memory_file_not_found": "File memoria non trovato.",
"modification_warning": "Goober è stato modificato! Verifiche del server saltate completamente...",
"reported_version": "Versione segnalata:",
"current_hash": "Hash attuale:",
"not_found": "non trovato!",
"version_error": "Impossibile recuperare le informazioni sulla versione. Codice di stato",
"loaded_cog": "Cog caricato:",
"cog_fail": "Impossibile caricare il cog:",
"loaded_cog2": "Module caricato:",
"cog_fail2": "Impossibile caricare il module:",
"no_model": "Nessun modello Markov salvato trovato. Iniziamo da zero.",
"folder_created": "Cartella '{folder_name}' creata.",
"folder_exists": "La cartella '{folder_name}' esiste già. Saltando...",
"logged_in": "Accesso effettuato come",
"synced_commands": "Sincronizzati",
"synced_commands2": "comandi!",
"fail_commands_sync": "Impossibile sincronizzare i comandi:",
"started": "{name} è stato avviato!",
"name_check": "Errore nel controllo disponibilità del nome:",
"name_taken": "Il nome è già preso. Scegli un nome diverso.",
"name_check2": "Errore durante il controllo della disponibilità del nome:",
"add_token": "Token: {token}\nAggiungi questo token al tuo file .env come",
"token_exists": "Il token esiste già in .env. Continuando con il token esistente.",
"goober_server_alert": "Avviso da goober central!\n",
"registration_error": "Errore durante la registrazione:",
"version_backup": "Backup creato:",
"backup_error": "Errore: {LOCAL_VERSION_FILE} non trovato per il backup.",
"model_loaded": "Modello Markov caricato da",
"fetch_update_fail": "Impossibile recuperare le informazioni sull'aggiornamento.",
"invalid_server": "Errore: informazioni sulla versione non valide ricevute dal server.",
"new_version": "Nuova versione disponibile: {latest_version} (Attuale: {local_version})",
"changelog": "Controlla {VERSION_URL}/goob/changes.txt per vedere il changelog\n\n",
"invalid_version": "La versione: {local_version} non è valida!",
"invalid_version2": "Se è intenzionale ignora questo messaggio, altrimenti premi Y per scaricare una versione valida dal server indipendentemente dalla versione attuale di goober",
"invalid_version3": "La versione attuale sarà salvata come current_version.bak..",
"input": "(Y o qualsiasi altro tasto per ignorare....)",
"modification_ignored": "Hai modificato",
"modification_ignored2": "IGNOREWARNING è impostato su false..",
"latest_version": "Stai utilizzando l'ultima versione:",
"latest_version2": "Controlla {VERSION_URL}/goob/changes.txt per vedere il changelog",
"pinging_disabled": "Il ping è disabilitato! Non dico al server che sono online...",
"goober_ping_success": "Accesso a goober central come {NAME}",
"goober_ping_fail": "Impossibile inviare i dati. Il server ha restituito il codice di stato:",
"goober_ping_fail2": "Si è verificato un errore durante l'invio dei dati:",
"sentence_positivity": "La positività della frase è:",
"command_edit_fail": "Impossibile modificare il messaggio:",
"command_desc_retrain": "Rafforza manualmente il modello Markov.",
"command_markov_retrain": "Rafforzamento del modello Markov in corso... Attendere.",
"command_markov_memory_not_found": "Errore: file di memoria non trovato!",
"command_markov_memory_is_corrupt": "Errore: file di memoria corrotto!",
"command_markov_retraining": "Elaborazione di {processed_data}/{data_size} punti dati...",
"command_markov_retrain_successful": "Modello Markov rafforzato con successo utilizzando {data_size} punti dati!",
"command_desc_talk": "parla n come stuf",
"command_talk_insufficent_text": "Ho bisogno di imparare di più dai messaggi prima di poter parlare.",
"command_talk_generation_fail": "Non ho nulla da dire in questo momento!",
"command_desc_help": "aiuto",
"command_help_embed_title": "Aiuto Bot",
"command_help_embed_desc": "Elenco dei comandi raggruppati per categoria.",
"command_help_categories_general": "Generale",
"command_help_categories_admin": "Amministrazione",
"command_help_categories_custom": "Comandi personalizzati",
"command_ran": "Info: {message.author.name} ha eseguito {message.content}",
"command_desc_ping": "ping",
"command_ping_embed_desc": "Latenza del bot:",
"command_ping_footer": "Richiesto da",
"command_about_desc": "informazioni",
"command_about_embed_title": "Informazioni su di me",
"command_about_embed_field1": "Nome",
"command_about_embed_field2name": "Versione",
"command_about_embed_field2value": "Locale: {local_version} \nUltima: {latest_version}",
"command_desc_stats": "statistiche",
"command_stats_embed_title": "Statistiche del bot",
"command_stats_embed_desc": "Dati sulla memoria del bot.",
"command_stats_embed_field1name": "Statistiche del file",
"command_stats_embed_field1value": "Dimensione: {file_size} byte\nLinee: {line_count}",
"command_stats_embed_field2name": "Versione",
"command_stats_embed_field2value": "Locale: {local_version} \nUltima: {latest_version}",
"command_stats_embed_field3name": "Informazioni sulle variabili",
"command_stats_embed_field3value": "Nome: {NAME} \nPrefisso: {PREFIX} \nID Proprietario: {ownerid} \nCooldown: {cooldown_time} \nLinea ping: {PING_LINE} \nMemoria Condivisa Abilitata: {showmemenabled} \nAddestramento Utente Abilitato: {USERTRAIN_ENABLED}\nCanzone: {song} \nSplashtext: ```{splashtext}```"
}

21
bot.py
View file

@ -78,14 +78,14 @@ def download_json():
download_json() download_json()
# Dynamically load all cogs (extensions) from the cogs folder # Dynamically load all cogs (extensions) from the cogs folder
async def load_cogs_from_folder(bot, folder_name="cogs"): async def load_cogs_from_folder(bot, folder_name="assets/cogs"):
# Loads all Python files in the cogs folder as Discord bot extensions
for filename in os.listdir(folder_name): for filename in os.listdir(folder_name):
if filename.endswith(".py") and not filename.startswith("_"): if filename.endswith(".py") and not filename.startswith("_"):
cog_name = filename[:-3] cog_name = filename[:-3]
module_path = folder_name.replace("/", ".").replace("\\", ".") + f".{cog_name}"
try: try:
await bot.load_extension(f"{folder_name}.{cog_name}") await bot.load_extension(module_path)
print(f"{GREEN}{get_translation(LOCALE, 'loaded_cog')} {cog_name}{RESET}") # get_translation from modules/translations.py print(f"{GREEN}{get_translation(LOCALE, 'loaded_cog')} {cog_name}{RESET}")
except Exception as e: except Exception as e:
print(f"{RED}{get_translation(LOCALE, 'cog_fail')} {cog_name} {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'cog_fail')} {cog_name} {e}{RESET}")
traceback.print_exc() traceback.print_exc()
@ -168,9 +168,6 @@ async def on_command_error(ctx, error):
) )
# Command: Retrain the Markov model from memory # Command: Retrain the Markov model from memory
@bot.hybrid_command(description=f"{get_translation(LOCALE, 'command_desc_retrain')}") @bot.hybrid_command(description=f"{get_translation(LOCALE, 'command_desc_retrain')}")
async def retrain(ctx): async def retrain(ctx):
@ -263,7 +260,7 @@ async def image(ctx):
else: else:
fallback_image = get_random_asset_image() fallback_image = get_random_asset_image()
if fallback_image is None: if fallback_image is None:
await ctx.reply("No image available to process.") await ctx.reply(get_translation(LOCALE, "no_image_available"))
return return
temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1]) temp_input = tempfile.mktemp(suffix=os.path.splitext(fallback_image)[1])
shutil.copy(fallback_image, temp_input) shutil.copy(fallback_image, temp_input)
@ -283,7 +280,7 @@ async def image(ctx):
if output_path is None or not os.path.isfile(output_path): if output_path is None or not os.path.isfile(output_path):
if temp_input and os.path.exists(temp_input): if temp_input and os.path.exists(temp_input):
os.remove(temp_input) os.remove(temp_input)
await ctx.reply("Failed to generate text on the image.") await ctx.reply(get_translation(LOCALE, "failed_generate_image"))
return return
await ctx.send(file=discord.File(output_path)) await ctx.send(file=discord.File(output_path))
@ -373,11 +370,11 @@ async def block_blacklisted(ctx):
try: try:
if isinstance(ctx, discord.Interaction): if isinstance(ctx, discord.Interaction):
if not ctx.response.is_done(): if not ctx.response.is_done():
await ctx.response.send_message("You are blacklisted.", ephemeral=True) await ctx.response.send_message(get_translation(LOCALE, "blacklisted"), ephemeral=True)
else: else:
await ctx.followup.send("You are blacklisted.", ephemeral=True) await ctx.followup.send(get_translation(LOCALE, "blacklisted"), ephemeral=True)
else: else:
await ctx.send("You are blacklisted.", ephemeral=True) await ctx.send(get_translation(LOCALE, "blacklisted_user"), ephemeral=True)
except: except:
pass pass
return False return False

View file

@ -1,13 +0,0 @@
import discord
from discord.ext import commands
class Hello(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.command()
async def hello(self, ctx):
await ctx.send("Hello, world!")
async def setup(bot):
await bot.add_cog(Hello(bot))

View file

@ -39,5 +39,5 @@ arch = platform.machine()
slash_commands_enabled = False slash_commands_enabled = False
launched = False launched = False
latest_version = "0.0.0" latest_version = "0.0.0"
local_version = "1.0.3" local_version = "1.0.4"
os.environ['gooberlocal_version'] = local_version os.environ['gooberlocal_version'] = local_version

View file

@ -1,3 +1,6 @@
from modules.globalvars import *
from modules.translations import get_translation
import time import time
import os import os
import sys import sys
@ -11,11 +14,13 @@ try:
import psutil import psutil
except ImportError: except ImportError:
psutilavaliable = False psutilavaliable = False
print("Missing requests and psutil! Please install them using pip: `pip install requests psutil`") print(RED, get_translation(LOCALE, 'missing_requests_psutil'), RESET)
import re import re
import importlib.metadata import importlib.metadata
from modules.globalvars import *
def check_requirements(): def check_requirements():
@ -37,7 +42,7 @@ def check_requirements():
requirements_path = os.path.abspath(requirements_path) requirements_path = os.path.abspath(requirements_path)
if not os.path.exists(requirements_path): if not os.path.exists(requirements_path):
print(f"{RED}requirements.txt not found at {requirements_path} was it tampered with?{RESET}") print(f"{RED}{get_translation(LOCALE, 'requirements_not_found').format(path=requirements_path)}{RESET}")
return return
with open(requirements_path, 'r') as f: with open(requirements_path, 'r') as f:
@ -69,31 +74,31 @@ def check_requirements():
continue continue
requirements.add(pkg) requirements.add(pkg)
except Exception as e: except Exception as e:
print(f"{YELLOW}Warning: Failed to parse imports from {filename}: {e}{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'warning_failed_parse_imports').format(filename=filename, error=e)}{RESET}")
else: else:
print(f"{YELLOW}Cogs directory not found at {cogs_dir}, skipping scan.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'cogs_dir_not_found').format(path=cogs_dir)}{RESET}")
installed_packages = {dist.metadata['Name'].lower() for dist in importlib.metadata.distributions()} installed_packages = {dist.metadata['Name'].lower() for dist in importlib.metadata.distributions()}
missing = [] missing = []
for req in sorted(requirements): for req in sorted(requirements):
if req in STD_LIB_MODULES or req == 'modules': if req in STD_LIB_MODULES or req == 'modules':
print(f"{GREEN}STD LIB / LOCAL{RESET} {req} (skipped check)") print(get_translation(LOCALE, "std_lib_local_skipped").format(package=req))
continue continue
check_name = PACKAGE_ALIASES.get(req, req).lower() check_name = PACKAGE_ALIASES.get(req, req).lower()
if check_name in installed_packages: if check_name in installed_packages:
print(f"[{GREEN} OK {RESET}] {check_name}") print(f"[ {GREEN}{get_translation(LOCALE, 'ok_installed').format(package=check_name)}{RESET} ] {check_name}")
else: else:
print(f"[ {RED}MISSING{RESET} ] {check_name} is not installed") print(f"[ {RED}{get_translation(LOCALE, 'missing_package').format(package=check_name)}{RESET} ] {check_name} {get_translation(LOCALE, 'missing_package2')}")
missing.append(check_name) missing.append(check_name)
if missing: if missing:
print("\nMissing packages detected:") print(RED, get_translation(LOCALE, "missing_packages_detected"), RESET)
for pkg in missing: for pkg in missing:
print(f" - {pkg}") print(f" - {pkg}")
print(f"Telling goober central at {VERSION_URL}") print(get_translation(LOCALE, "telling_goober_central").format(url=VERSION_URL))
payload = { payload = {
"name": NAME, "name": NAME,
"version": local_version, "version": local_version,
@ -103,10 +108,10 @@ def check_requirements():
try: try:
response = requests.post(VERSION_URL + "/ping", json=payload) response = requests.post(VERSION_URL + "/ping", json=payload)
except Exception as e: except Exception as e:
print(f"{RED}Failed to contact {VERSION_URL}: {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'failed_to_contact').format(url=VERSION_URL, error=e)}{RESET}")
sys.exit(1) sys.exit(1)
else: else:
print("\nAll requirements are satisfied.") print(get_translation(LOCALE, "all_requirements_satisfied"))
def check_latency(): def check_latency():
host = "1.1.1.1" host = "1.1.1.1"
@ -129,23 +134,19 @@ def check_latency():
if result.returncode == 0: if result.returncode == 0:
print(result.stdout) print(result.stdout)
# Try to extract latency
match = re.search(latency_pattern, result.stdout) match = re.search(latency_pattern, result.stdout)
if match: if match:
latency_ms = float(match.group(1)) latency_ms = float(match.group(1))
print(f"Ping to {host}: {latency_ms:.2f} ms") print(get_translation(LOCALE, "ping_to").format(host=host, latency=latency_ms))
if latency_ms > 300: if latency_ms > 300:
print(f"{YELLOW}High latency detected! You may experience delays in response times.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'high_latency')}{RESET}")
else: else:
print(f"{YELLOW}Could not parse latency.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'could_not_parse_latency')}{RESET}")
else: else:
print(result.stderr) print(result.stderr)
print(f"{RED}Ping to {host} failed.{RESET}") print(f"{RED}{get_translation(LOCALE, 'ping_failed').format(host=host)}{RESET}")
except Exception as e: except Exception as e:
print(f"{RED}Error running ping: {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'error_running_ping').format(error=e)}{RESET}")
def check_memory(): def check_memory():
if psutilavaliable == False: if psutilavaliable == False:
@ -156,14 +157,13 @@ def check_memory():
used_memory = memory_info.used / (1024 ** 3) used_memory = memory_info.used / (1024 ** 3)
free_memory = memory_info.available / (1024 ** 3) free_memory = memory_info.available / (1024 ** 3)
print(f"Memory Usage: {used_memory:.2f} GB / {total_memory:.2f} GB ({(used_memory / total_memory) * 100:.2f}%)") print(get_translation(LOCALE, "memory_usage").format(used=used_memory, total=total_memory, percent=(used_memory / total_memory) * 100))
if used_memory > total_memory * 0.9: if used_memory > total_memory * 0.9:
print(f"{YELLOW}Memory usage is above 90% ({(used_memory / total_memory) * 100:.2f}%). Consider freeing up memory.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'memory_above_90').format(percent=(used_memory / total_memory) * 100)}{RESET}")
print(f"Total Memory: {total_memory:.2f} GB") print(get_translation(LOCALE, "total_memory").format(total=total_memory))
print(f"Used Memory: {used_memory:.2f} GB") print(get_translation(LOCALE, "used_memory").format(used=used_memory))
if free_memory < 1: if free_memory < 1:
print(f"{RED}Low free memory detected! Only {free_memory:.2f} GB available.{RESET}") print(f"{RED}{get_translation(LOCALE, 'low_free_memory').format(free=free_memory)}{RESET}")
sys.exit(1) sys.exit(1)
except ImportError: except ImportError:
print("psutil is not installed. Memory check skipped.") print("psutil is not installed. Memory check skipped.")
@ -171,7 +171,7 @@ def check_memory():
def check_cpu(): def check_cpu():
if psutilavaliable == False: if psutilavaliable == False:
return return
print("Measuring CPU usage per core...") print(get_translation(LOCALE, "measuring_cpu"))
cpu_per_core = psutil.cpu_percent(interval=1, percpu=True) cpu_per_core = psutil.cpu_percent(interval=1, percpu=True)
for idx, core_usage in enumerate(cpu_per_core): for idx, core_usage in enumerate(cpu_per_core):
bar_length = int(core_usage / 5) bar_length = int(core_usage / 5)
@ -182,38 +182,33 @@ def check_cpu():
color = YELLOW color = YELLOW
else: else:
color = GREEN color = GREEN
print(f"Core {idx}: {color}[{bar}] {core_usage:.2f}%{RESET}") print(get_translation(LOCALE, "core_usage").format(idx=idx, bar=bar, usage=core_usage))
total_cpu = sum(cpu_per_core) / len(cpu_per_core) total_cpu = sum(cpu_per_core) / len(cpu_per_core)
print(f"Total CPU Usage: {total_cpu:.2f}%") print(get_translation(LOCALE, "total_cpu_usage").format(usage=total_cpu))
if total_cpu > 85: if total_cpu > 85:
print(f"{YELLOW}High average CPU usage: {total_cpu:.2f}%{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'high_avg_cpu').format(usage=total_cpu)}{RESET}")
if total_cpu > 95: if total_cpu > 95:
print(f"{RED}Really high CPU load! System may throttle or hang.{RESET}") print(f"{RED}{get_translation(LOCALE, 'really_high_cpu')}{RESET}")
sys.exit(1) sys.exit(1)
def check_memoryjson(): def check_memoryjson():
try: try:
print(f"Memory file: {os.path.getsize(MEMORY_FILE) / (1024 ** 2):.2f} MB") print(get_translation(LOCALE, "memory_file").format(size=os.path.getsize(MEMORY_FILE) / (1024 ** 2)))
if os.path.getsize(MEMORY_FILE) > 1_073_741_824: if os.path.getsize(MEMORY_FILE) > 1_073_741_824:
print(f"{YELLOW}Memory file is 1GB or higher, consider clearing it to free up space.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'memory_file_large')}{RESET}")
# Check for corrupted memory.json file
try: try:
with open(MEMORY_FILE, 'r', encoding='utf-8') as f: with open(MEMORY_FILE, 'r', encoding='utf-8') as f:
json.load(f) json.load(f)
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
print(f"{RED}Memory file is corrupted! JSON decode error: {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'memory_file_corrupted').format(error=e)}{RESET}")
print(f"{YELLOW}Consider backing up and recreating the memory file.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'consider_backup_memory')}{RESET}")
except UnicodeDecodeError as e: except UnicodeDecodeError as e:
print(f"{RED}Memory file has encoding issues: {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'memory_file_encoding').format(error=e)}{RESET}")
print(f"{YELLOW}Consider backing up and recreating the memory file.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'consider_backup_memory')}{RESET}")
except Exception as e: except Exception as e:
print(f"{RED}Error reading memory file: {e}{RESET}") print(f"{RED}{get_translation(LOCALE, 'error_reading_memory').format(error=e)}{RESET}")
except FileNotFoundError: except FileNotFoundError:
print(f"{YELLOW}Memory file not found.{RESET}") print(f"{YELLOW}{get_translation(LOCALE, 'memory_file_not_found')}{RESET}")
def presskey2skip(timeout): def presskey2skip(timeout):
if os.name == 'nt': if os.name == 'nt':
@ -248,18 +243,13 @@ def presskey2skip(timeout):
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
def start_checks(): def start_checks():
print("Running pre-start checks...") print(get_translation(LOCALE, "running_prestart_checks"))
check_requirements() check_requirements()
check_latency() check_latency()
check_memory() check_memory()
check_memoryjson() check_memoryjson()
check_cpu() check_cpu()
print("Continuing in 5 seconds... Press any key to skip.") print(get_translation(LOCALE, "continuing_in_seconds").format(seconds=5))
presskey2skip(timeout=5) presskey2skip(timeout=5)
os.system('cls' if os.name == 'nt' else 'clear') os.system('cls' if os.name == 'nt' else 'clear')
# i decided to experiment with this instead of the above line but it doesn't work too well so that's why i'm not using it
# print("\n" * (shutil.get_terminal_size(fallback=(80, 24))).lines, end="")
print(splashtext) print(splashtext)

View file

@ -10,7 +10,7 @@ def load_translations():
""" """
translations = {} translations = {}
# Get the path to the 'locales' directory (one level up from this file) # Get the path to the 'locales' directory (one level up from this file)
translations_dir = pathlib.Path(__file__).parent.parent / 'locales' translations_dir = pathlib.Path(__file__).parent.parent / 'assets' / 'locales'
# Iterate over all files in the 'locales' directory # Iterate over all files in the 'locales' directory
for filename in os.listdir(translations_dir): for filename in os.listdir(translations_dir):
if filename.endswith(".json"): if filename.endswith(".json"):

View file

@ -18,18 +18,18 @@ def is_remote_ahead(branch='main', remote='origin'):
# Automatically update the local repository if the remote is ahead # Automatically update the local repository if the remote is ahead
def auto_update(branch='main', remote='origin'): def auto_update(branch='main', remote='origin'):
if launched == True: if launched == True:
print("I've already started! Im not updating...") print(get_translation(LOCALE, "already_started"))
return return
if AUTOUPDATE != "True": if AUTOUPDATE != "True":
pass # Auto-update is disabled pass # Auto-update is disabled
if is_remote_ahead(branch, remote): if is_remote_ahead(branch, remote):
print(f"Remote {remote}/{branch} is ahead. Updating...") print(get_translation(LOCALE, "remote_ahead").format(remote=remote, branch=branch))
pull_result = run_cmd(f'git pull {remote} {branch}') pull_result = run_cmd(f'git pull {remote} {branch}')
print(pull_result) print(pull_result)
print("Please Restart goober!") print(get_translation(LOCALE, "please_restart"))
sys.exit(0) sys.exit(0)
else: else:
print(f"Local {remote}/{branch} is ahead and/or up to par. Not Updating...") print(get_translation(LOCALE, "local_ahead").format(remote=remote, branch=branch))
# Fetch the latest version info from the update server # Fetch the latest version info from the update server
def get_latest_version_info(): def get_latest_version_info():
@ -65,7 +65,7 @@ def check_for_update():
# Check if local_version is valid # Check if local_version is valid
if local_version == "0.0.0" or None: if local_version == "0.0.0" or None:
print(f"{RED}I cant find the local_version variable! Or its been tampered with and its not an interger!{RESET}") print(f"{RED}{get_translation(LOCALE, 'cant_find_local_version')}{RESET}")
return return
# Compare local and latest versions # Compare local and latest versions