From a2e33d2b1375f2c41da2f3fc094f30e495aed820 Mon Sep 17 00:00:00 2001 From: pedro Date: Wed, 16 Oct 2024 00:26:20 +0200 Subject: [PATCH] add logger and locale for spanish --- Makefile | 12 ++++ deploy-workbench.sh | 13 +++- locale/es/LC_MESSAGES/messages.mo | Bin 0 -> 2335 bytes locale/es/LC_MESSAGES/messages.po | 107 ++++++++++++++++++++++++++++++ requirements.txt | 2 - workbench-script.py | 79 ++++++++++++++-------- 6 files changed, 181 insertions(+), 32 deletions(-) create mode 100644 locale/es/LC_MESSAGES/messages.mo create mode 100644 locale/es/LC_MESSAGES/messages.po delete mode 100644 requirements.txt diff --git a/Makefile b/Makefile index 8c0d811..fdc7099 100644 --- a/Makefile +++ b/Makefile @@ -43,3 +43,15 @@ boot_iso_uefi_secureboot: -enable-kvm -m 2G -vga qxl -netdev user,id=wan -device virtio-net,netdev=wan,id=nic1 \ -drive file=deploy/iso/workbench_debug.iso,cache=none,if=virtio,format=raw,index=0,media=disk \ -boot menu=on + +es_gen_po: + cp locale/es/LC_MESSAGES/messages.po locale/es/LC_MESSAGES/messages.pot.bak + pygettext3 -p locale/es/LC_MESSAGES/ workbench-script.py + # src https://stackoverflow.com/questions/7496156/gettext-how-to-update-po-and-pot-files-after-the-source-is-modified + msgmerge -N locale/es/LC_MESSAGES/messages.pot.bak locale/es/LC_MESSAGES/messages.pot > locale/es/LC_MESSAGES/messages.po + rm locale/es/LC_MESSAGES/messages.pot.bak + rm locale/es/LC_MESSAGES/messages.pot + + +es_gen_mo: + msgfmt locale/es/LC_MESSAGES/messages.po -o locale/es/LC_MESSAGES/messages.mo diff --git a/deploy-workbench.sh b/deploy-workbench.sh index a0e4d79..3a55c60 100755 --- a/deploy-workbench.sh +++ b/deploy-workbench.sh @@ -255,11 +255,10 @@ END prepare_app() { # prepare app during prepare_chroot_env - # Install hardware_metadata module workbench_dir="${ISO_PATH}/chroot/opt/workbench" ${SUDO} mkdir -p "${workbench_dir}" ${SUDO} cp workbench-script.py "${workbench_dir}/" - ${SUDO} cp requirements.txt "${workbench_dir}/" + ${SUDO} cp -arp locale "${workbench_dir}/" # startup script execution cat > "${ISO_PATH}/chroot/root/.profile" <1d;G^!r@o4C zJ&DhA_44;{wR70_yO<%;BDXwz%PJnz;A$01AhWO z2>cWH8SpRQi@*$v&H}##J`emJ*aiL!>;RuV1s*s{0YAm>+t`Gk{|)>Qc;%sL{dYht ziGBexzh8l`15cl>@~8vxDCz@02VMj6`M(3t0sjH=`R5+4_+19Rhu=Q}aeUAPx8Xu) z*b9`RC#px$qjO{qNG)7v@Xa|duE*v#j{qOXr^de<-pgs>l^&Bfpy_NRoxYk?}Z5lmN<7&_KHMdUM zcp8~fX9?{&J~ophQRbdzA}?iFQRZ0)3v3pKNcRKj1&L_WO5s6z zvDFcxBs?*#sM+0$wwV^CM;Jo|PQM;f=|Lu=p~yTUHzJc3$ymB!?EX;dbdp5t123Q}uQ*QI1?{RpDt`I!{B%L`gWZ#`uIbO`fAqP?1b{K{r&MbBxl^ ztjHz03X+z(bYhsxC~ORUIKLycflO87I2Lc+NzYB}5~bBT(+=UKwXE*4FOz7;nvZdI z+{)ss(mE8hPCJdwD~-!dy4vjTwtC%KUlzvtxZ}nui{CECE*_XV)pmMuU(OV-iMP;D zb-LDU^y5x1-fGZ0y?Uqh%KN=;v(^^Q#{(<0%LRr3GqcxjQ@7D+(#2+{(Q036Y;E0d2!q4XP+PK1RhZ|)7Y;|r@erZti_ZbIw~g4OB5Q283`GDN!?j3a@P&4eYHV{X%l zw1&_Mxj+?BuF4h?>KLzP&}ADlX9#1#t*Sk*hK30`U%s5jqt)-kr}v#SGl?sxWY1wm5xv@wh{K8B&REZ-!}tUYmecCCHe0>b&<7P~3cFLV9ub5f!F63(&p=5HL07KR zbpG%TSCMT;F*OjL3XAsIpz0;8hMk6YM%>bZPWq12)%j3`4!^yrFt_5Ep@b^n`CJvW z)v^Nr6Ir>q;|`ihjWl2*pOg~Kh?}_^IVnh1dR20PKsJSAxX@dcUS@+jmr&c_KLW!G z$C9ZjRF34}Y0@6vVNaa<6doDw&dR9p*Hz8OYHCgtFQJ`PtAg5b-$L4V4@@;|(Z9lT B#Q^{S literal 0 HcmV?d00001 diff --git a/locale/es/LC_MESSAGES/messages.po b/locale/es/LC_MESSAGES/messages.po new file mode 100644 index 0000000..c19de48 --- /dev/null +++ b/locale/es/LC_MESSAGES/messages.po @@ -0,0 +1,107 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-15 21:15+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: workbench-script.py:48 workbench-script.py:53 +msgid "Running command `%s`" +msgstr "Ejecutando comando `%s`" + +#: workbench-script.py:284 +msgid "Created snapshots directory at '%s'" +msgstr "Creado directorio de snapshots en '%s'" + +#: workbench-script.py:287 +msgid "Snapshot written in path '%s'" +msgstr "Snapshot escrito en ruta '%s'" + +#: workbench-script.py:290 +msgid "" +"Attempting to save file in actual path. Reason: Failed to write in snapshots " +"directory:\n" +" %s." +msgstr "" +"Probando de guardar el fichero en la ruta actual. Motivo: Fallo al intentar " +"escribir en el directorio de snapshots:\n" +" %s." + +#: workbench-script.py:297 +msgid "Snapshot written in fallback path '%s'" +msgstr "Snapshot escrito en ruta alternativa '%s'" + +#: workbench-script.py:299 +msgid "" +"Could not save snapshot locally. Reason: Failed to write in fallback path:\n" +" %s" +msgstr "" +"No pude guardar snapshots localmente. Motivo: Fallo al escribir en la ruta " +"alternativa:\n" +" %s" + +#: workbench-script.py:316 +msgid "Snapshot successfully sent to '%s'" +msgstr "Snapshot enviado con éxito a '%s'" + +#: workbench-script.py:331 +msgid "" +"Snapshot not remotely sent to URL '%s'. Do you have internet? Is your server " +"up & running? Is the url token authorized?\n" +" %s" +msgstr "" +"Snapshot no enviado remotamente a la URL '%s'. Tienes internet? Está el " +"servidor en marcha? Está autorizado el url token?\n" +" %s" + +#: workbench-script.py:342 +msgid "Found config file in path: %s." +msgstr "Encontrado fichero de configuración en ruta: %s." + +#: workbench-script.py:353 +msgid "Config file '%s' not found. Using default values." +msgstr "" +"Fichero de configuración '%s' no encontrado. Utilizando valores por defecto." + +#: workbench-script.py:373 +msgid "workbench-script.py [-h] [--config CONFIG]" +msgstr "" + +#: workbench-script.py:374 +msgid "Optional config loader for workbench." +msgstr "Cargador opcional de configuración para workbench" + +#: workbench-script.py:377 +msgid "" +"path to the config file. Defaults to 'settings.ini' in the current directory." +msgstr "" +"ruta al fichero de configuración. Por defecto es 'settings.ini' en el " +"directorio actual" + +#: workbench-script.py:410 +msgid "START" +msgstr "INICIO" + +#: workbench-script.py:423 +msgid "" +"This script must be run as root. Collected data will be incomplete or " +"unusable" +msgstr "" +"Es conveniente que este script sea ejecutado como administrador (root). Los " +"datos recopilados serán incompletos o no usables." + +#: workbench-script.py:441 +msgid "END" +msgstr "FIN" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e3c22db..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -ntplib -requests diff --git a/workbench-script.py b/workbench-script.py index 7cc19bf..dc9c729 100644 --- a/workbench-script.py +++ b/workbench-script.py @@ -8,6 +8,10 @@ import argparse import configparser import urllib.request +import gettext +import locale +import logging + from datetime import datetime @@ -33,7 +37,7 @@ def logs(f): try: return f(*args, **kwargs) except Exception as err: - print(err) + logger.error(err) return '' return wrapper @@ -41,12 +45,12 @@ def logs(f): @logs def exec_cmd(cmd): - print(f'workbench: INFO: running command `{cmd}`') + logger.info(_('Running command `%s`'), cmd) return os.popen(cmd).read() @logs def exec_cmd_erase(cmd): - print(cmd) + logger.info(_('Running command `%s`'), cmd) return '' # return os.popen(cmd).read() @@ -277,23 +281,22 @@ def save_snapshot_in_disk(snapshot, path): try: if not os.path.exists(snapshot_path): os.makedirs(snapshot_path) - print(f"workbench: INFO: Created snapshots directory at '{snapshot_path}'") - + logger.info(_("Created snapshots directory at '%s'"), snapshot_path) with open(filename, "w") as f: f.write(json.dumps(snapshot)) - print(f"workbench: INFO: Snapshot written in path '{filename}'") + logger.info(_("Snapshot written in path '%s'"), filename) except Exception as e: try: - print(f"workbench: WARNING: Attempting to save in actual path. Reason: Failed to write in snapshots directory:\n {e}.") + logger.warning(_("Attempting to save file in actual path. Reason: Failed to write in snapshots directory:\n %s."), e) fallback_filename = "{}/{}_{}.json".format( path, datetime.now().strftime("%Y%m%d-%H_%M_%S"), snapshot['uuid']) with open(fallback_filename, "w") as f: f.write(json.dumps(snapshot)) - print(f"workbench: INFO: Snapshot written in fallback path '{fallback_filename}'") + logger.warning(_("Snapshot written in fallback path '%s'"), fallback_filename) except Exception as e: - print(f"workbench: ERROR: Could not save snapshot locally. Reason: Failed to write in fallback path:\n {e}") + logger.error(_("Could not save snapshot locally. Reason: Failed to write in fallback path:\n %s"), e) # TODO sanitize url, if url is like this, it fails # url = 'http://127.0.0.1:8000/api/snapshot/' @@ -310,13 +313,7 @@ def send_snapshot_to_devicehub(snapshot, token, url): response_text = response.read().decode('utf-8') if 200 <= status_code < 300: - print(f"workbench: INFO: Snapshot successfully sent to '{url}'") - else: - txt = "workbench: ERROR: Failed to send snapshot. HTTP {}: {}".format( - status_code, - response_text - ) - raise Exception(txt) + logger.info(_("Snapshot successfully sent to '%s'"), url) try: response = json.loads(response_text) @@ -328,10 +325,10 @@ def send_snapshot_to_devicehub(snapshot, token, url): if response.get("dhid"): print("dhid: {}".format(response['dhid'])) except Exception: - print(response_text) + logger.error(response_text) except Exception as e: - print(f"workbench: ERROR: Snapshot not remotely sent to URL '{url}'. Do you have internet? Is your server up & running? Is the url token authorized?\n {e}") + logger.error(_("Snapshot not remotely sent to URL '%s'. Do you have internet? Is your server up & running? Is the url token authorized?\n %s"), url, e) def load_config(config_file="settings.ini"): """ @@ -342,7 +339,7 @@ def load_config(config_file="settings.ini"): if os.path.exists(config_file): # If config file exists, read from it - print(f"workbench: INFO: Found config file in path: '{config_file}'.") + logger.info(_("Found config file in path: %s."), config_file) config.read(config_file) path = config.get('settings', 'path', fallback=os.getcwd()) # TODO validate that has http:// start @@ -353,7 +350,7 @@ def load_config(config_file="settings.ini"): erase = config.get('settings', 'erase', fallback=None) legacy = config.get('settings', 'legacy', fallback=None) else: - print(f"workbench: ERROR: Config file '{config_file}' not found. Using default values.") + logger.error(_("Config file '%s' not found. Using default values."), config_file) path = os.path.join(os.getcwd()) url, token, device, erase, legacy = None, None, None, None, None @@ -370,17 +367,45 @@ def parse_args(): """ Parse config argument, if available """ - parser = argparse.ArgumentParser(description="Optional config loader for workbench.") + parser = argparse.ArgumentParser( + usage=_("workbench-script.py [-h] [--config CONFIG]"), + description=_("Optional config loader for workbench.")) parser.add_argument( '--config', - help="Path to the config file. Defaults to 'settings.ini' in the current directory.", + help=_("path to the config file. Defaults to 'settings.ini' in the current directory."), default="settings.ini" # Fallback to 'settings.ini' by default ) return parser.parse_args() +def prepare_lang(): + locale_path = os.path.join(os.path.dirname(__file__), 'locale') + domain = 'messages' + gettext.bindtextdomain(domain, locale_path) + gettext.textdomain(domain) + global _ + # with LANG=es_ES.UTF-8, it detects spanish + _ = gettext.gettext + # # this would force it to spanish + # lang = gettext.translation(domain, localedir=locale_path, languages=['es']) + # lang.install() + # _ = lang.gettext + +def prepare_logger(): + global logger + logger = logging.getLogger(__name__) + logger.setLevel(logging.INFO) + + console_handler = logging.StreamHandler() + console_handler.setLevel(logging.INFO) + formatter = logging.Formatter('[%(asctime)s] workbench: %(levelname)s: %(message)s') + console_handler.setFormatter(formatter) + logger.addHandler(console_handler) + def main(): - vline='\n___________\n\n' - print(f"{vline}workbench: START\n") + prepare_lang() + prepare_logger() + + logger.info(_("START")) # Parse the command-line arguments args = parse_args() @@ -393,7 +418,7 @@ def main(): # TODO show warning if non root, means data is not complete # if annotate as potentially invalid snapshot (pending the new API to be done) if os.geteuid() != 0: - print("workbench: WARNING: This script must be run as root. Collected data will be incomplete or unusable") + logger.warning(_("This script must be run as root. Collected data will be incomplete or unusable")) all_disks = get_disks() snapshot = gen_snapshot(all_disks) @@ -405,13 +430,13 @@ def main(): if config.get("legacy"): convert_to_legacy_snapshot(snapshot) - + save_snapshot_in_disk(snapshot, config['path']) if config['url']: send_snapshot_to_devicehub(snapshot, config['token'], config['url']) - print(f"\nworkbench: END{vline}") + logger.info(_("END")) if __name__ == '__main__':