spun off the translation into its own thing that works with anything
This commit is contained in:
parent
cd6ce96b36
commit
b89390e713
18 changed files with 248 additions and 80 deletions
|
@ -1,7 +1,7 @@
|
|||
import requests
|
||||
import os
|
||||
import modules.globalvars as gv
|
||||
from modules.translations import _
|
||||
from modules.volta.main import _
|
||||
from modules.markovmemory import get_file_info
|
||||
|
||||
# Ping the server to check if it's alive and send some info
|
||||
|
|
|
@ -3,7 +3,7 @@ import json
|
|||
import markovify
|
||||
import pickle
|
||||
from modules.globalvars import *
|
||||
from modules.translations import _
|
||||
from modules.volta.main import _
|
||||
|
||||
# Get file size and line count for a given file path
|
||||
def get_file_info(file_path):
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
from modules.globalvars import *
|
||||
from modules.translations import _
|
||||
from modules.volta.main import _, get_translation, load_translations, set_language, translations
|
||||
|
||||
import time
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
import sysconfig
|
||||
import ast
|
||||
import json
|
||||
import re
|
||||
import importlib.metadata
|
||||
|
||||
# import shutil
|
||||
psutilavaliable = True
|
||||
try:
|
||||
|
@ -16,30 +20,56 @@ except ImportError:
|
|||
psutilavaliable = False
|
||||
print(RED, _('missing_requests_psutil'), RESET)
|
||||
|
||||
def check_missing_translations():
|
||||
if LOCALE == "en":
|
||||
print("Locale is English, skipping missing key check.")
|
||||
return
|
||||
load_translations()
|
||||
|
||||
import re
|
||||
import importlib.metadata
|
||||
en_keys = set(translations.get("en", {}).keys())
|
||||
locale_keys = set(translations.get(LOCALE, {}).keys())
|
||||
|
||||
missing_keys = en_keys - locale_keys
|
||||
total_keys = len(en_keys)
|
||||
missing_count = len(missing_keys)
|
||||
|
||||
if missing_count > 0:
|
||||
percent_missing = (missing_count / total_keys) * 100
|
||||
print(f"{YELLOW}Warning: {missing_count}/{total_keys} keys missing in locale '{LOCALE}' ({percent_missing:.1f}%)!{RESET}")
|
||||
for key in sorted(missing_keys):
|
||||
print(f" - {key}")
|
||||
time.sleep(5)
|
||||
else:
|
||||
print("All translation keys present for locale:", LOCALE)
|
||||
|
||||
|
||||
|
||||
def get_stdlib_modules():
|
||||
stdlib_path = pathlib.Path(sysconfig.get_paths()['stdlib'])
|
||||
modules = set()
|
||||
if hasattr(sys, 'builtin_module_names'):
|
||||
modules.update(sys.builtin_module_names)
|
||||
for file in stdlib_path.glob('*.py'):
|
||||
if file.stem != '__init__':
|
||||
modules.add(file.stem)
|
||||
for folder in stdlib_path.iterdir():
|
||||
if folder.is_dir() and (folder / '__init__.py').exists():
|
||||
modules.add(folder.name)
|
||||
for file in stdlib_path.glob('*.*'):
|
||||
if file.suffix in ('.so', '.pyd'):
|
||||
modules.add(file.stem)
|
||||
|
||||
return modules
|
||||
|
||||
def check_requirements():
|
||||
STD_LIB_MODULES = {
|
||||
"os", "sys", "time", "ast", "asyncio", "re", "subprocess", "json",
|
||||
"datetime", "threading", "math", "logging", "functools", "itertools",
|
||||
"collections", "shutil", "socket", "types", "enum", "pathlib",
|
||||
"inspect", "traceback", "platform", "typing", "warnings", "email",
|
||||
"http", "urllib", "argparse", "io", "copy", "pickle", "gzip", "csv",
|
||||
}
|
||||
STD_LIB_MODULES = get_stdlib_modules()
|
||||
PACKAGE_ALIASES = {
|
||||
"discord": "discord.py",
|
||||
"better_profanity": "better-profanity",
|
||||
|
||||
}
|
||||
|
||||
parent_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
requirements_path = os.path.join(parent_dir, '..', 'requirements.txt')
|
||||
requirements_path = os.path.abspath(requirements_path)
|
||||
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}")
|
||||
|
@ -52,7 +82,7 @@ def check_requirements():
|
|||
if line.strip() and not line.startswith('#')
|
||||
}
|
||||
|
||||
cogs_dir = os.path.abspath(os.path.join(parent_dir, '..', 'cogs'))
|
||||
cogs_dir = os.path.abspath(os.path.join(parent_dir, '..', 'assets', 'cogs'))
|
||||
if os.path.isdir(cogs_dir):
|
||||
for filename in os.listdir(cogs_dir):
|
||||
if filename.endswith('.py'):
|
||||
|
@ -106,7 +136,7 @@ def check_requirements():
|
|||
"token": gooberTOKEN
|
||||
}
|
||||
try:
|
||||
response = requests.post(VERSION_URL + "/ping", json=payload)
|
||||
requests.post(VERSION_URL + "/ping", json=payload)
|
||||
except Exception as e:
|
||||
print(f"{RED}{(_('failed_to_contact')).format(url=VERSION_URL, error=e)}{RESET}")
|
||||
sys.exit(1)
|
||||
|
@ -247,6 +277,7 @@ def start_checks():
|
|||
print(f"{YELLOW}{(_('checks_disabled'))}{RESET}")
|
||||
return
|
||||
print(_('running_prestart_checks'))
|
||||
check_missing_translations()
|
||||
check_requirements()
|
||||
check_latency()
|
||||
check_memory()
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import re
|
||||
from modules.globalvars import *
|
||||
from modules.translations import _
|
||||
from modules.volta.main import _
|
||||
|
||||
import spacy
|
||||
from spacy.tokens import Doc
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import os
|
||||
import json
|
||||
import pathlib
|
||||
from modules.globalvars import RED, RESET, LOCALE
|
||||
|
||||
# Load translations at module import
|
||||
def load_translations():
|
||||
translations = {}
|
||||
translations_dir = pathlib.Path(__file__).parent.parent / 'assets' / 'locales'
|
||||
for filename in os.listdir(translations_dir):
|
||||
if filename.endswith(".json"):
|
||||
lang_code = filename.replace(".json", "")
|
||||
with open(translations_dir / filename, "r", encoding="utf-8") as f:
|
||||
translations[lang_code] = json.load(f)
|
||||
return translations
|
||||
|
||||
translations = load_translations()
|
||||
|
||||
|
||||
def set_language(lang: str):
|
||||
global LOCALE
|
||||
LOCALE = lang if lang in translations else "en"
|
||||
|
||||
def get_translation(lang: str, key: str):
|
||||
lang_translations = translations.get(lang, translations["en"])
|
||||
if key not in lang_translations:
|
||||
print(f"{RED}Missing key: {key} in language {lang}{RESET}")
|
||||
return lang_translations.get(key, key)
|
||||
|
||||
def _(key: str) -> str:
|
||||
return get_translation(LOCALE, key)
|
|
@ -2,7 +2,7 @@ import sys
|
|||
import traceback
|
||||
import os
|
||||
from modules.globalvars import RED, RESET, splashtext
|
||||
from modules.translations import _
|
||||
from modules.volta.main import _
|
||||
|
||||
def handle_exception(exc_type, exc_value, exc_traceback, *, context=None):
|
||||
os.system('cls' if os.name == 'nt' else 'clear')
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from modules.translations import _
|
||||
from modules.volta.main import _
|
||||
from modules.globalvars import *
|
||||
import requests
|
||||
import subprocess
|
||||
|
@ -18,18 +18,18 @@ def is_remote_ahead(branch='main', remote='origin'):
|
|||
# Automatically update the local repository if the remote is ahead
|
||||
def auto_update(branch='main', remote='origin'):
|
||||
if launched == True:
|
||||
print((_('already_started')))
|
||||
print(_("already_started"))
|
||||
return
|
||||
if AUTOUPDATE != "True":
|
||||
pass # Auto-update is disabled
|
||||
if is_remote_ahead(branch, remote):
|
||||
print((_('remote_ahead')).format(remote=remote, branch=branch))
|
||||
print(_( "remote_ahead").format(remote=remote, branch=branch))
|
||||
pull_result = run_cmd(f'git pull {remote} {branch}')
|
||||
print(pull_result)
|
||||
print((_('please_restart')))
|
||||
print(_( "please_restart"))
|
||||
sys.exit(0)
|
||||
else:
|
||||
print((_('local_ahead')).format(remote=remote, branch=branch))
|
||||
print(_( "local_ahead").format(remote=remote, branch=branch))
|
||||
|
||||
# Fetch the latest version info from the update server
|
||||
def get_latest_version_info():
|
||||
|
@ -38,23 +38,21 @@ def get_latest_version_info():
|
|||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
print(f"{RED}{(_('version_error'))} {response.status_code}{RESET}")
|
||||
print(f"{RED}{_( 'version_error')} {response.status_code}{RESET}")
|
||||
return None
|
||||
except requests.RequestException as e:
|
||||
print(f"{RED}{(_('version_error'))} {e}{RESET}")
|
||||
print(f"{RED}{_( 'version_error')} {e}{RESET}")
|
||||
return None
|
||||
|
||||
# Check if an update is available and perform update if needed
|
||||
def check_for_update():
|
||||
global latest_version, local_version, launched
|
||||
launched = True
|
||||
if ALIVEPING != "True":
|
||||
return # Update check is disabled
|
||||
|
||||
return
|
||||
global latest_version, local_version
|
||||
|
||||
latest_version_info = get_latest_version_info()
|
||||
if not latest_version_info:
|
||||
print(f"{(_('fetch_update_fail'))}")
|
||||
print(f"{_('fetch_update_fail')}")
|
||||
return None, None
|
||||
|
||||
latest_version = latest_version_info.get("version")
|
||||
|
@ -62,20 +60,24 @@ def check_for_update():
|
|||
download_url = latest_version_info.get("download_url")
|
||||
|
||||
if not latest_version or not download_url:
|
||||
print(f"{RED}{(_('invalid_server'))}{RESET}")
|
||||
print(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}")
|
||||
print(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}")
|
||||
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}")
|
||||
auto_update()
|
||||
elif local_version > latest_version and beta == True:
|
||||
print(f"{YELLOW}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}")
|
||||
elif local_version == latest_version:
|
||||
print(f"{GREEN}{(_('latest_version'))} {local_version}{RESET}")
|
||||
print(f"{(_('latest_version2')).format(VERSION_URL=VERSION_URL)}\n\n")
|
||||
print(f"{GREEN}{_('latest_version')} {local_version}{RESET}")
|
||||
print(f"{_('latest_version2').format(VERSION_URL=VERSION_URL)}\n\n")
|
||||
return latest_version
|
93
modules/volta/main.py
Normal file
93
modules/volta/main.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
import os
|
||||
import json
|
||||
import pathlib
|
||||
import threading
|
||||
import time
|
||||
from dotenv import load_dotenv
|
||||
from modules.globalvars import RED, RESET
|
||||
|
||||
load_dotenv()
|
||||
|
||||
LOCALE = os.getenv("locale")
|
||||
module_dir = pathlib.Path(__file__).parent.parent
|
||||
working_dir = pathlib.Path.cwd()
|
||||
EXCLUDE_DIRS = {'.git', '__pycache__'}
|
||||
|
||||
locales_dirs = []
|
||||
|
||||
def find_locales_dirs(base_path):
|
||||
found = []
|
||||
for root, dirs, files in os.walk(base_path):
|
||||
dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS]
|
||||
|
||||
if 'locales' in dirs:
|
||||
locales_path = pathlib.Path(root) / 'locales'
|
||||
found.append(locales_path)
|
||||
dirs.remove('locales')
|
||||
return found
|
||||
|
||||
locales_dirs.extend(find_locales_dirs(module_dir))
|
||||
if working_dir != module_dir:
|
||||
locales_dirs.extend(find_locales_dirs(working_dir))
|
||||
|
||||
translations = {}
|
||||
_file_mod_times = {}
|
||||
|
||||
def load_translations():
|
||||
global translations, _file_mod_times
|
||||
translations.clear()
|
||||
_file_mod_times.clear()
|
||||
|
||||
for locales_dir in locales_dirs:
|
||||
for filename in os.listdir(locales_dir):
|
||||
if filename.endswith(".json"):
|
||||
lang_code = filename[:-5]
|
||||
file_path = locales_dir / filename
|
||||
try:
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
if lang_code not in translations:
|
||||
translations[lang_code] = {}
|
||||
translations[lang_code].update(data)
|
||||
_file_mod_times[(lang_code, file_path)] = file_path.stat().st_mtime
|
||||
except Exception as e:
|
||||
print(f"{RED}Failed loading {file_path}: {e}{RESET}")
|
||||
|
||||
def reload_if_changed():
|
||||
while True:
|
||||
for (lang_code, file_path), last_mtime in list(_file_mod_times.items()):
|
||||
try:
|
||||
current_mtime = file_path.stat().st_mtime
|
||||
if current_mtime != last_mtime:
|
||||
print(f"{RED}Translation file changed: {file_path}, reloading...{RESET}")
|
||||
load_translations()
|
||||
break
|
||||
except FileNotFoundError:
|
||||
print(f"{RED}Translation file removed: {file_path}{RESET}")
|
||||
_file_mod_times.pop((lang_code, file_path), None)
|
||||
if lang_code in translations:
|
||||
translations.pop(lang_code, None)
|
||||
|
||||
def set_language(lang: str):
|
||||
global LOCALE
|
||||
if lang in translations:
|
||||
LOCALE = lang
|
||||
else:
|
||||
print(f"{RED}Language '{lang}' not found, defaulting to 'en'{RESET}")
|
||||
LOCALE = "en"
|
||||
|
||||
def get_translation(lang: str, key: str):
|
||||
lang_translations = translations.get(lang, {})
|
||||
if key in lang_translations:
|
||||
return lang_translations[key]
|
||||
fallback = translations.get("en", {}).get(key, key)
|
||||
print(f"{RED}Missing key: '{key}' in language '{lang}', falling back to: '{fallback}'{RESET}")
|
||||
return fallback
|
||||
|
||||
def _(key: str) -> str:
|
||||
return get_translation(LOCALE, key)
|
||||
|
||||
load_translations()
|
||||
|
||||
watchdog_thread = threading.Thread(target=reload_if_changed, daemon=True)
|
||||
watchdog_thread.start()
|
Loading…
Add table
Add a link
Reference in a new issue