MqlCIByLeo/Src/Py/compiler.py

127 lines
4.5 KiB
Python
Raw Permalink Normal View History

2026-03-09 21:36:27 -05:00
import subprocess
import os
import argparse
2026-03-10 09:19:00 -05:00
import shutil
def move_to_experts(mql5_full_path: str, mql5_root: str) -> str:
# Lista de carpetas base permitidas
bases : list[str] = ["Experts", "Scripts", "Shared Projects", "Libraries", "Includes", "Services"]
# Convertir paths a formato absoluto normalizado
mql5_full_path = os.path.normpath(mql5_full_path)
# Buscar la carpeta base en el path
parts = mql5_full_path.split(os.sep)
base_idx = -1
for i, part in enumerate(parts):
if part in bases:
base_idx = i
break
# si es esperts entonces retonarmos tal cual no hace falta.. hacer nada
if parts[base_idx] == "Experts":
return mql5_full_path
# Si no estamos en una carpeta "base", retonrans la ubicaicon actual
if base_idx == -1:
print("No se detectó una carpeta base valida. Abortando move.")
return mql5_full_path
# Extraer sub-ruta: desde la carpeta base hasta el archivo (sin el archivo)
# Ejemplo: Si path es /MQL5/Shared Projects/TbpWrraper/Workflows/EA.mq5
# base_idx apunta a 'Shared Projects', queremos ['Shared Projects', 'TbpWrraper', 'Workflows']
sub_path_parts = parts[base_idx:-1]
# onstruir ruta destino en Experts
# Resultado: /MQL5/Experts/Shared Projects/TbpWrraper/Workflows/
experts_dir = os.path.join(mql5_root, "Experts", *sub_path_parts)
# Crear directorios y hacer el link
if not os.path.exists(experts_dir):
os.makedirs(experts_dir)
source_ex5 = os.path.splitext(mql5_full_path)[0] + ".ex5"
dest_ex5 = os.path.join(experts_dir, os.path.basename(source_ex5))
if os.path.exists(dest_ex5):
os.remove(dest_ex5)
shutil.move(source_ex5, dest_ex5)
return dest_ex5
2026-03-09 21:36:27 -05:00
2026-03-10 07:36:09 -05:00
def CompileFileWithLogFile(metaeditor_path: str, mql5_full_path: str, timeout_sec: int = 60, wineprefix: str = "/home/leoxd/.mt5") -> tuple[bool, str]:
2026-03-09 21:52:39 -05:00
print(f"Metaeditor path = {metaeditor_path}")
print(f"MQL5 path = {mql5_full_path}")
2026-03-10 09:19:00 -05:00
# target dir
target_dir = os.path.dirname(mql5_full_path)
2026-03-10 07:36:09 -05:00
# env config
env = os.environ.copy()
env["WINEPREFIX"] = wineprefix
env["WINEDEBUG"] = "-all,err+all" # Solo muestra errores críticos
env["DISPLAY"] = ":99"
2026-03-10 09:19:00 -05:00
# cmd
cmd = [
"wine",
metaeditor_path,
"/portable",
f"/compile:{os.path.basename(mql5_full_path)}", # Sin comillas extra, Wine las manejará mejor así
"/log"
]
2026-03-10 07:36:09 -05:00
2026-03-10 09:19:00 -05:00
print(f"Ejecutando en CWD: {target_dir}")
2026-03-10 07:36:09 -05:00
print(f"CMD: {' '.join(cmd)}")
2026-03-09 21:36:27 -05:00
try:
# Ejecutamos el comando y esperamos (timeout en segundos)
2026-03-10 09:19:00 -05:00
result = subprocess.run(cmd, timeout=timeout_sec, capture_output=True, text=True, env=env, cwd=target_dir)
2026-03-10 07:36:09 -05:00
2026-03-09 22:05:03 -05:00
print(f"STDOUT: {result.stdout}")
print(f"STDERR: {result.stderr}")
2026-03-10 07:36:09 -05:00
2026-03-09 21:36:27 -05:00
# Imprimimos el codigo de salida
print(f"Código de salida: {result.returncode}")
2026-03-10 07:36:09 -05:00
2026-03-09 21:36:27 -05:00
# Verifica si el archivo log se creó (opcional, para mayor validación)
log_file = os.path.splitext(mql5_full_path)[0] + ".log"
if os.path.exists(log_file):
print(f"Log generado: {log_file}")
2026-03-10 07:36:09 -05:00
return result.returncode == 1, log_file # en mql5 es 1 por lo visto
2026-03-09 21:36:27 -05:00
except subprocess.TimeoutExpired:
print("Error: La compilación excedió el tiempo límite.")
return False, ""
except Exception as e:
print(f"Error al ejecutar MetaEditor: {str(e)}")
return False, ""
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--metaeditor_exe_path", type=str, required=True) # path al metaeditor.exe
parser.add_argument("--executor_mq5_full_path", type=str, required=True) # path al ea ejecutor
parser.add_argument("--timeout_sec", type=int, default=60) # timeout de espera
args = parser.parse_args()
res, log_file = CompileFileWithLogFile(args.metaeditor_exe_path, args.executor_mq5_full_path, args.timeout_sec)
if not res:
2026-03-09 21:44:49 -05:00
if os.path.exists(log_file):
2026-03-09 21:36:27 -05:00
# Abrir archivo e imprimir en consola su contenido
with open(log_file, "r", encoding="utf-16") as f:
print(f.read())
else:
print("Error no se genero un archivo log")
else:
2026-03-10 09:19:00 -05:00
print("Exito al compilar el ea ejecutor")
mt5_dir = os.path.dirname(args.metaeditor_exe_path)
mql5_root = os.path.join(mt5_dir, "MQL5")
dest = move_to_experts(args.executor_mq5_full_path, mql5_root)
print(f"Ex5 movido a en: {dest}")