update pyCreateTh.py

This commit is contained in:
Alex38Lyon
2025-06-20 00:02:06 +02:00
parent 7fb026c131
commit 19d516997d
14 changed files with 1012 additions and 834 deletions
+38
View File
@@ -89,3 +89,41 @@
2025-06-18 21:39:26,691 - INFO - ******************************************************************************************************************************************** 2025-06-18 21:39:26,691 - INFO - ********************************************************************************************************************************************
2025-06-18 21:39:26,692 - ERROR - !!! file not yet supported 2025-06-18 21:39:26,692 - ERROR - !!! file not yet supported
2025-06-18 21:39:26,692 - ERROR - !!! There were 1 errors during 32.63 secondes, check the log file ~\..\pyCreateTh.log 2025-06-18 21:39:26,692 - ERROR - !!! There were 1 errors during 32.63 secondes, check the log file ~\..\pyCreateTh.log
2025-06-19 08:27:09,067 - INFO - ********************************************************************************************************************************************
2025-06-19 08:27:09,068 - INFO - * Conversion Th, Dat, Mak files to Therion files and folders
2025-06-19 08:27:09,068 - INFO - * Script pyCreateTh by : alexandre.pont@yahoo.fr
2025-06-19 08:27:09,068 - INFO - * Version : 2025.06.18
2025-06-19 08:27:09,068 - INFO - * Input file :
2025-06-19 08:27:09,068 - INFO - * Output file : ~\.
2025-06-19 08:27:09,069 - INFO - * Log file : ~\..\pyCreateTh.log
2025-06-19 08:27:09,069 - INFO - *
2025-06-19 08:27:09,069 - INFO - *
2025-06-19 08:27:09,070 - INFO - *
2025-06-19 08:27:09,070 - INFO - ********************************************************************************************************************************************
2025-06-19 08:27:09,071 - ERROR - !!! file not yet supported
2025-06-19 08:27:09,071 - ERROR - !!! There were 1 errors during 3.02 secondes, check the log file ~\..\pyCreateTh.log
2025-06-19 15:01:03,588 - INFO - ********************************************************************************************************************************************
2025-06-19 15:01:03,592 - INFO - * Conversion Th, Dat, Mak files to Therion files and folders
2025-06-19 15:01:03,592 - INFO - * Script pyCreateTh by : alexandre.pont@yahoo.fr
2025-06-19 15:01:03,592 - INFO - * Version : 2025.06.18
2025-06-19 15:01:03,593 - INFO - * Input file :
2025-06-19 15:01:03,593 - INFO - * Output file : ~\.
2025-06-19 15:01:03,593 - INFO - * Log file : ~\..\pyCreateTh.log
2025-06-19 15:01:03,593 - INFO - *
2025-06-19 15:01:03,594 - INFO - *
2025-06-19 15:01:03,594 - INFO - *
2025-06-19 15:01:03,594 - INFO - ********************************************************************************************************************************************
2025-06-19 15:01:03,595 - ERROR - !!! file not yet supported
2025-06-19 15:01:03,595 - ERROR - !!! There were 1 errors during 3.53 secondes, check the log file ~\..\pyCreateTh.log
2025-06-19 23:34:59,337 - INFO - ********************************************************************************************************************************************
2025-06-19 23:34:59,341 - INFO - * Conversion Th, Dat, Mak files to Therion files and folders
2025-06-19 23:34:59,341 - INFO - * Script pyCreateTh by : alexandre.pont@yahoo.fr
2025-06-19 23:34:59,341 - INFO - * Version : 2025.06.18
2025-06-19 23:34:59,341 - INFO - * Input file :
2025-06-19 23:34:59,342 - INFO - * Output file : ~\.
2025-06-19 23:34:59,342 - INFO - * Log file : ~\..\pyCreateTh.log
2025-06-19 23:34:59,342 - INFO - *
2025-06-19 23:34:59,342 - INFO - *
2025-06-19 23:34:59,342 - INFO - *
2025-06-19 23:34:59,342 - INFO - ********************************************************************************************************************************************
2025-06-19 23:34:59,343 - ERROR - !!! file not yet supported
+6
View File
@@ -7,6 +7,7 @@
"australiangeodeticdatum", "australiangeodeticdatum",
"backclino", "backclino",
"backcompass", "backcompass",
"Backsights",
"beijing", "beijing",
"cavename", "cavename",
"clarke", "clarke",
@@ -23,6 +24,7 @@
"drawnexemptre", "drawnexemptre",
"drawnre", "drawnre",
"ecart", "ecart",
"ecarts",
"ENDC", "ENDC",
"endlayout", "endlayout",
"endscrap", "endscrap",
@@ -43,6 +45,7 @@
"lenmatch", "lenmatch",
"levelname", "levelname",
"levelno", "levelno",
"LRUD",
"migovec", "migovec",
"NODRAW", "NODRAW",
"northamerican", "northamerican",
@@ -59,6 +62,9 @@
"thconfig", "thconfig",
"therion", "therion",
"totdata", "totdata",
"UUUUDDDDSSSB",
"UUUUDDDDSSSBL",
"UUUUDDDDSSSSSBL",
"wpage", "wpage",
"XTHERION" "XTHERION"
] ]
+285
View File
@@ -0,0 +1,285 @@
"""
#############################################################################################
general_fonctions.py for pyCreateTh.py
#############################################################################################
"""
import os, logging, sys, re, configparser
import Lib.global_data as global_data
import tkinter as tk
from tkinter import filedialog
#################################################################################################
# Couleurs ANSI par niveau de log
#################################################################################################
COLOR_CODES = {
logging.DEBUG: "\033[94m", # Bleu
logging.INFO: "\033[92m", # Vert
logging.WARNING: "\033[95m", # MAGENTA
logging.ERROR: "\033[91m", # Rouge
logging.CRITICAL: "\033[1;91m", # Rouge vif
}
RESET = "\033[0m"
#################################################################################################
# Codes de couleur ANSI
class Colors:
BLACK = '\033[90m'
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
ERROR = '\033[91m'
WARNING = '\033[95m'
HEADER = '\033[96m'
DEBUG = '\033[94m' # Bleu
INFO = '\033[92m' # Vert
CRITICAL = '\033[1;91m', # Rouge vif
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
#################################################################################################
def safe_relpath(path):
"""
Renvoie un chemin relatif si possible, sinon un chemin partiel à partir du dossier de référence.
"""
abs_path = os.path.abspath(path)
ref_path = os.path.abspath(os.getcwd())
try:
valeur = "~\\" + os.path.relpath(path, ref_path)
return valeur
except ValueError:
max_depth = 4 # Profondeur maximale pour tronquer le chemin
# Disques différents, afficher le chemin relatif partiel depuis la racine commune
path_parts = abs_path.split(os.sep)
ref_parts = ref_path.split(os.sep)
while path_parts and ref_parts and path_parts[0] == ref_parts[0]:
path_parts.pop(0)
ref_parts.pop(0)
result = os.path.join(*path_parts) if path_parts else os.path.basename(path)
# Si max_depth est défini, tronque le chemin
if max_depth is not None:
parts = result.split(os.sep)
if len(parts) > max_depth:
result = os.path.join("~\\" , *parts[-max_depth:])
return result
#################################################################################################
# Coloration des messages d'aide d'arg #
#################################################################################################
def colored_help(parser):
"""
Affiche l'aide colorée pour les arguments de la ligne de commande.
Args:
parser (argparse.ArgumentParser): Le parseur d'arguments.
Returns:
None
"""
# Captures the help output
help_text = parser.format_help()
# Coloration des différentes parties
colored_help_text = help_text.replace(
'usage:', f'{Colors.ERROR}usage:{Colors.ENDC}'
).replace(
'options:', f'{Colors.GREEN}options:{Colors.ENDC}'
).replace('positional arguments:', f'{Colors.BLUE}positional arguments:{Colors.ENDC}'
).replace(', --help', f'{Colors.BLUE}, --help:{Colors.ENDC}'
).replace('elp:', f'{Colors.BLUE}elp{Colors.ENDC}')
# Surligner les arguments
for action in parser._actions:
if action.option_strings:
# Colorer les options (--xyz)
for opt in action.option_strings:
colored_help_text = colored_help_text.replace(opt, f'{Colors.BLUE}{opt}{Colors.ENDC}').replace('--help', f'{Colors.BLUE}--help:{Colors.ENDC}')
# Imprimer le texte coloré
print(colored_help_text)
sys.exit(1)
#################################################################################################
def select_file_tk_window():
"""
Ouvre une boite de dialogue tkinter pour sélectionner un fichier.
Returns:
str: Le chemin complet du fichier sélectionné.
"""
# Créer une instance de la fenêtre tkinter
root = tk.Tk()
# Cacher la fenêtre principale
root.withdraw()
# Afficher la boite de dialogue de sélection de fichier
file_path = filedialog.askopenfilename(
title="Select your file",
filetypes=[("MAK files", "*.mak"), ("Compatibles files", "*.th *.mak *.dat"), ("TH files", "*.th"), ("DAT files", "*.dat"), ("All files", "*.*")]
)
return file_path # Retourner le chemin complet du fichier sélectionné
#################################################################################################
def read_config(config_file):
"""
Lit le fichier de configuration et initialise les variables globales.
Args:
config_file (str): Le chemin vers le fichier de configuration.
Returns:
None
"""
# Initialize the configparser to read .ini files
config = configparser.ConfigParser()
config.read(config_file, encoding="utf-8")
if 'Survey_Data' in config and 'Author' in config['Survey_Data']:
global_data.Author = config['Survey_Data']['Author']
if 'Survey_Data' in config and 'Copyright1' in config['Survey_Data']:
global_data.Copyright = config['Survey_Data']['Copyright1'] + "\n" + config['Survey_Data']['Copyright2'] + "\n" + config['Survey_Data']['Copyright3'] + "\n"
if 'Survey_Data' in config and 'Copyright_Short' in config['Survey_Data']:
global_data.CopyrightShort = config['Survey_Data']['Copyright_Short']
if 'Survey_Data' in config and 'map_comment' in config['Survey_Data']:
global_data.mapComment = config['Survey_Data']['map_comment']
if 'Survey_Data' in config and 'club' in config['Survey_Data']:
global_data.club = config['Survey_Data']['club']
if 'Survey_Data' in config and 'thanksto' in config['Survey_Data']:
global_data.thanksto = config['Survey_Data']['thanksto']
if 'Survey_Data' in config and 'datat' in config['Survey_Data']:
global_data.datat = config['Survey_Data']['datat']
if 'Survey_Data' in config and 'wpage' in config['Survey_Data']:
global_data.wpage = config['Survey_Data']['wpage']
if 'Survey_Data' in config and 'cs' in config['Survey_Data']:
global_data.cs = config['Survey_Data']['cs']
if 'Application_Data' in config and 'template_path' in config['Application_Data']:
global_data.templatePath = config['Application_Data']['template_path']
if 'Application_Data' in config and 'station_by_scrap' in config['Application_Data']:
global_data.stationByScrap = int(config['Application_Data']['station_by_scrap'])
if 'Application_Data' in config and 'final_therion_exe' in config['Application_Data']:
global_data.finalTherionExe = bool(config['Application_Data']['final_therion_exe'])
if 'Application_Data' in config and 'therion_path' in config['Application_Data']:
global_data.therionPath = config['Application_Data']['therion_path']
if 'Application_Data' in config and 'therion_path' in config['Application_Data']:
global_data.SurveyPrefixName = config['Application_Data']['survey_prefix_name']
if global_data.linesInTh2 == -1 :
if 'Application_Data' in config and 'shot_lines_in_th2_files' in config['Application_Data']:
linesInTh2 = 0 if config['Application_Data']['shot_lines_in_th2_files'] == "False" else 1
if global_data.stationNamesInTh2 == -1 :
if 'Application_Data' in config and 'station_name_in_th2_files' in config['Application_Data']:
global_data.stationNamesInTh2 = 0 if config['Application_Data']['station_name_in_th2_files'] == "False" else 1
#################################################################################################
# Supprime les codes ANSI (pour l'écriture dans les fichiers)
#################################################################################################
def strip_ansi_codes(text):
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
return ansi_escape.sub('', text)
#################################################################################################
# Formatter pour la console avec couleurs
#################################################################################################
class ConsoleFormatter(logging.Formatter):
def format(self, record):
color = COLOR_CODES.get(record.levelno, "")
message = super().format(record)
return f"{color}{message}{RESET}"
#################################################################################################
# Formatter pour le fichier avec "!!!" sur les erreurs
#################################################################################################
class FileFormatter(logging.Formatter):
def format(self, record):
clean_msg = strip_ansi_codes(record.getMessage())
prefix = "!!! " if record.levelno >= logging.ERROR else ""
record_copy = logging.LogRecord(
name=record.name,
level=record.levelno,
pathname=record.pathname,
lineno=record.lineno,
msg=f"{prefix}{clean_msg}",
args=(),
exc_info=record.exc_info,
func=record.funcName,
sinfo=record.stack_info
)
return super().format(record_copy)
#################################################################################################
# Fonction de configuration du logger
#################################################################################################
def setup_logger(logfile="app.log", debug_log=False):
logger = logging.getLogger("Logger")
logger.setLevel(logging.DEBUG)
logger.handlers.clear()
min_level = logging.DEBUG if debug_log else logging.INFO
# Console stderr handler — affichage à l'écran avec couleurs
stderr_handler = logging.StreamHandler(sys.stderr)
stderr_handler.setLevel(min_level)
stderr_formatter = ConsoleFormatter("%(levelname)s: %(message)s") # <-- Ta classe personnalisée
stderr_handler.setFormatter(stderr_formatter)
logger.addHandler(stderr_handler)
# File handler — fichier de log
file_handler = logging.FileHandler(logfile, encoding="utf-8")
file_handler.setLevel(min_level)
file_formatter = FileFormatter("%(asctime)s - %(levelname)s - %(message)s") # <-- Ta classe personnalisée
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
return logger
#################################################################################################
def release_log_file(logger):
handlers = logger.handlers[:]
for handler in handlers:
if isinstance(handler, logging.FileHandler):
handler.close()
logger.removeHandler(handler)
+22 -1
View File
@@ -7,9 +7,30 @@ global_data.py for pyCreateTh.py
################################################################################################# #################################################################################################
error_count = 0 # Compteur d'erreurs error_count = 0 # Compteur d'erreurs
## [Survey_Data] default values
Author = "Created by pyCreateTh.py"
Copyright = "# global_data.Copyright (C) pyCreateTh.py"
CopyrightShort = "Licence (C) pyCreateTh.py"
mapComment = "Created by pyCreateTh.py"
cs = "UTM30"
club = "Therion"
thanksto = "Therion"
datat = "https://therion.speleo.sk/"
wpage = "https://therion.speleo.sk/"
## [Application_data] default values
templatePath = "./Template"
stationByScrap = 20
finalTherion_exe = True
therionPath = "C:/Therion/therion.exe"
SurveyPrefixName = f"Survey_"
linesInTh2 = -1
stationNamesInTh2 = -1
################################################################################################# #################################################################################################
thFileDat = """ thFileDat = """
encoding utf-8 encoding utf-8
-83
View File
@@ -1,83 +0,0 @@
"""
#############################################################################################
logger_config.py for pyCreateTh.py
#############################################################################################
"""
import logging
import sys
import re
#################################################################################################
# Couleurs ANSI par niveau de log
#################################################################################################
COLOR_CODES = {
logging.DEBUG: "\033[94m", # Bleu
logging.INFO: "\033[92m", # Vert
logging.WARNING: "\033[95m",
logging.ERROR: "\033[91m", # Rouge
logging.CRITICAL: "\033[1;91m", # Rouge vif
}
RESET = "\033[0m"
#################################################################################################
# Supprime les codes ANSI (pour l'écriture dans les fichiers)
#################################################################################################
def strip_ansi_codes(text):
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
return ansi_escape.sub('', text)
#################################################################################################
# Formatter pour la console avec couleurs
#################################################################################################
class ConsoleFormatter(logging.Formatter):
def format(self, record):
color = COLOR_CODES.get(record.levelno, "")
message = super().format(record)
return f"{color}{message}{RESET}"
#################################################################################################
# Formatter pour le fichier avec "!!!" sur les erreurs
#################################################################################################
class FileFormatter(logging.Formatter):
def format(self, record):
clean_msg = strip_ansi_codes(record.getMessage())
prefix = "!!! " if record.levelno >= logging.ERROR else ""
record_copy = logging.LogRecord(
name=record.name,
level=record.levelno,
pathname=record.pathname,
lineno=record.lineno,
msg=f"{prefix}{clean_msg}",
args=(),
exc_info=record.exc_info,
func=record.funcName,
sinfo=record.stack_info
)
return super().format(record_copy)
#################################################################################################
# Fonction de configuration du logger
#################################################################################################
def setup_logger(logfile="app.log", debug_log=False):
logger = logging.getLogger("Logger")
logger.setLevel(logging.DEBUG)
logger.handlers.clear()
min_level = logging.DEBUG if debug_log else logging.INFO
# Console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(min_level)
console_formatter = ConsoleFormatter("%(levelname)s: %(message)s")
console_handler.setFormatter(console_formatter)
logger.addHandler(console_handler)
# File handler
file_handler = logging.FileHandler(logfile, encoding="utf-8")
file_handler.setLevel(min_level)
file_formatter = FileFormatter("%(asctime)s - %(levelname)s - %(message)s")
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
return logger
+80 -102
View File
@@ -4,111 +4,20 @@ therion.py for pyCreateTh.py
############################################################################################# #############################################################################################
""" """
import tempfile import tempfile, shutil, os, re, logging, threading, subprocess
import shutil
import os
from os.path import join from os.path import join
import subprocess
import re
import logging
import threading
import Lib.global_data as global_data import Lib.global_data as global_data
from Lib.general_fonctions import Colors, safe_relpath
log = logging.getLogger("Logger") log = logging.getLogger("Logger")
#################################################################################################
# Codes de couleur ANSI
class Colors:
BLACK = '\033[90m'
RED = '\033[91m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
BLUE = '\033[94m'
MAGENTA = '\033[95m'
CYAN = '\033[96m'
WHITE = '\033[97m'
ERROR = '\033[91m'
WARNING = '\033[95m'
HEADER = '\033[96m'
DEBUG = '\033[94m' # Bleu
INFO = '\033[92m' # Vert
CRITICAL = '\033[1;91m', # Rouge vif
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
#################################################################################################
def safe_relpath(path):
"""
Renvoie un chemin relatif si possible, sinon un chemin partiel à partir du dossier de référence.
"""
abs_path = os.path.abspath(path)
ref_path = os.path.abspath(os.getcwd())
try:
valeur = "~\\" + os.path.relpath(path, ref_path)
return valeur
except ValueError:
max_depth = 4 # Profondeur maximale pour tronquer le chemin
# Disques différents, afficher le chemin relatif partiel depuis la racine commune
path_parts = abs_path.split(os.sep)
ref_parts = ref_path.split(os.sep)
while path_parts and ref_parts and path_parts[0] == ref_parts[0]:
path_parts.pop(0)
ref_parts.pop(0)
result = os.path.join(*path_parts) if path_parts else os.path.basename(path)
# Si max_depth est défini, tronque le chemin
if max_depth is not None:
parts = result.split(os.sep)
if len(parts) > max_depth:
result = os.path.join("~\\" , *parts[-max_depth:])
return result
#################################################################################################
# Compilation Therion 'Template' (version avec blocage) #
#################################################################################################
def compile_templateOld(template, template_args, **kwargs):
try :
logfile = ""
tmpdir = tempfile.mkdtemp()
config = template.format(**template_args, tmpdir=tmpdir.replace("\\", "/"))
log.debug(f"{config}\n")
config_file = join(tmpdir, "config.thconfig")
log_file = join(tmpdir, "log.log")
therion_path = kwargs["therion_path"] if "therion_path" in kwargs else "therion"
with open(config_file, mode="w+", encoding="utf-8") as tmp:
with open(log_file, mode="w+") as tmp2:
tmp.write(config)
tmp.flush()
subprocess.check_output('''"{}" "{}" -l "{}"'''.format(therion_path, config_file, log_file), shell=True, )
tmp2.flush()
logfile = tmp2.read()
if kwargs["cleanup"]:
shutil.rmtree(tmpdir)
log.debug("\n" )
return logfile, tmpdir
except Exception as e:
log.error(f"Therion template compilation error: {Colors.ENDC}{e}")
global_data.error_count += 1
################################################################################################# #################################################################################################
# Compilation Therion 'Template' (version sans blocage) # # Compilation Therion 'Template' (version sans blocage) #
# Compiler une configuration générée dynamiquement à partir d'un template texte. # # Compiler une configuration générée dynamiquement à partir d'un template texte. #
################################################################################################# #################################################################################################
def compile_template(template, template_args, **kwargs): def compile_template(template, template_args, totReadMeError = "", **kwargs ):
logfile = "" logfile = ""
tmpdir = None tmpdir = None
try: try:
@@ -147,23 +56,26 @@ def compile_template(template, template_args, **kwargs):
# Analyse du code retour # Analyse du code retour
if result.returncode != 0 or "press any key" in result.stdout.lower(): if result.returncode != 0 or "press any key" in result.stdout.lower():
log.error(f"Therion compilation failed with return code: {Colors.ENDC}{result.returncode}\n{Colors.WHITE}{result.stdout}") log.error(f"Therion compilation failed with return code: {Colors.ENDC}{result.returncode}\n{Colors.WHITE}{result.stdout}")
totReadMeError += f"\tTherion compilation failed with return code: {result.returncode}\n"
global_data.error_count += 1 global_data.error_count += 1
return "Therion error", tmpdir return "Therion error", tmpdir, totReadMeError
stat = get_stats_from_log(logfile) stat = get_stats_from_log(logfile)
log.info(f"Therion compilation successful, length: {Colors.ENDC}{stat["length"]}m{Colors.INFO}, depth: {Colors.ENDC}{stat["depth"]}m") log.info(f"Therion compilation successful, length: {Colors.ENDC}{stat["length"]}m{Colors.INFO}, depth: {Colors.ENDC}{stat["depth"]}m")
return logfile, tmpdir return logfile, tmpdir, totReadMeError
except subprocess.TimeoutExpired: except subprocess.TimeoutExpired:
log.error(f"Therion process timed out and was terminated: {Colors.ENDC}{logfile}") log.error(f"Therion process timed out and was terminated: {Colors.ENDC}{logfile}")
totReadMeError += f"\tTherion process timed out and was terminated\n"
global_data.error_count += 1 global_data.error_count += 1
return "Therion error", tmpdir return "Therion error", tmpdir, totReadMeError
except Exception as e: except Exception as e:
log.error(f"Therion template compilation error: {Colors.ENDC}{e}") log.error(f"Therion template compilation error: {Colors.ENDC}{e}")
totReadMeError += f"\tTherion template compilation error: {e}\n"
global_data.error_count += 1 global_data.error_count += 1
return "Therion error", tmpdir return "Therion error", tmpdir, totReadMeError
finally: finally:
if kwargs.get("cleanup", True) and tmpdir: if kwargs.get("cleanup", True) and tmpdir:
@@ -176,8 +88,7 @@ def compile_template(template, template_args, **kwargs):
################################################################################################# #################################################################################################
# Compilation Therion (version sans blocage) # # Compilation Therion (version sans blocage) #
################################################################################################# #################################################################################################
def compile_file(filename, **kwargs): def compile_fileOLd(filename, **kwargs):
tmpdir = os.path.dirname(filename) tmpdir = os.path.dirname(filename)
log_file = join(tmpdir, "therion.log").replace("\\", "/") log_file = join(tmpdir, "therion.log").replace("\\", "/")
therion_path = kwargs.get("therion_path", "therion") therion_path = kwargs.get("therion_path", "therion")
@@ -240,6 +151,70 @@ def compile_file(filename, **kwargs):
global_data.error_count += 1 global_data.error_count += 1
def compile_file(filename, **kwargs):
tmpdir = os.path.dirname(filename)
log_file = join(tmpdir, "therion.log").replace("\\", "/")
therion_path = kwargs.get("therion_path", "therion")
timeout = kwargs.get("timeout", 60)
log.info(f"Start therion compilation file: {Colors.ENDC}{safe_relpath(filename)}")
def run():
try:
process = subprocess.Popen(
[therion_path, filename, "-l", log_file],
cwd=tmpdir,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
bufsize=1
)
def read_output(proc):
try:
for line in proc.stdout:
line = line.rstrip()
lower_line = line.lower()
if "average loop error" in lower_line:
log.warning(f"[Therion_Compile] {Colors.ENDC}{line}")
elif "error" in lower_line:
log.error(f"[Therion_Compile] {Colors.ENDC}{line}")
elif "warning" in lower_line:
log.warning(f"[Therion_Compile] {Colors.ENDC}{line}")
else:
log.debug(f"[Therion_Compile] {Colors.ENDC}{line}")
except Exception as e:
log.warning(f"Reading Therion output: {Colors.ENDC}{e}")
output_thread = threading.Thread(target=read_output, args=(process,))
output_thread.start()
output_thread.join(timeout)
if output_thread.is_alive():
log.error(f"Therion compilation timed out after {Colors.ENDC}{timeout}{Colors.ERROR} seconds. Killing process...")
global_data.error_count += 1
process.kill()
output_thread.join() # Toujours attendre proprement
process.wait()
if process.returncode != 0:
log.error(f"Therion returned error code {Colors.ENDC}{process.returncode}")
global_data.error_count += 1
else:
log.info(f"Therion file: {Colors.ENDC}{safe_relpath(filename)}{Colors.GREEN} compilation succeeded")
except Exception as e:
log.error(f"Therion file: {Colors.ENDC}{safe_relpath(filename)}{Colors.ERROR} compilation error: {Colors.ENDC}{e}")
global_data.error_count += 1
# Lancer le thread principal pour cette compilation et le retourner
thread = threading.Thread(target=run)
thread.start()
return thread
################################################################################################# #################################################################################################
def compile_file_th(filepath, **kwargs): def compile_file_th(filepath, **kwargs):
template = """source {filepath} template = """source {filepath}
@@ -248,15 +223,18 @@ def compile_file_th(filepath, **kwargs):
endlayout endlayout
""" """
template_args = {"filepath": filepath} template_args = {"filepath": filepath}
logs, _ = compile_template(template, template_args, cleanup=True, **kwargs) logs, _, = compile_template(template, template_args, cleanup=True, **kwargs)
return logs return logs
################################################################################################# #################################################################################################
# Attention fonctionne pour la version therion en français ! à voir pour les autres langues # Attention fonctionne pour la version therion en français ! à voir pour les autres langues
lengthre = re.compile(r".*Longueur totale de la topographie = \s*(\S+)m") lengthre = re.compile(r".*Longueur totale de la topographie = \s*(\S+)m")
depthre = re.compile(r".*Longueur totale verticale =\s*(\S+)m") depthre = re.compile(r".*Longueur totale verticale =\s*(\S+)m")
def get_stats_from_log(log): def get_stats_from_log(log):
lenmatch = lengthre.findall(log) lenmatch = lengthre.findall(log)
depmatch = depthre.findall(log) depmatch = depthre.findall(log)
if len(lenmatch) == 1 and len(depmatch) == 1: if len(lenmatch) == 1 and len(depmatch) == 1:
@@ -6,7 +6,7 @@
# Fix point list # Fix point list
{fixPointList} {fixPointList}
# Survey list : # Survey / file list :
{readMeList} {readMeList}
@@ -385,7 +385,7 @@ endlayout
# export model -fmt kml -o Outputs/{fileName}-model.kml -enable all # export model -fmt kml -o Outputs/{fileName}-model.kml -enable all
# export model -enable all -o Outputs/{fileName}-3D.kml # export model -enable all -o Outputs/{fileName}-3D.kml
# export cave-list -location on -o Outputs/{fileName}-Cave-list.html # export cave-list -location on -o Outputs/{fileName}-Cave-list.html
# export survey-list -location on -o Outputs/{fileName}-Surveys.html export survey-list -location on -o Outputs/{fileName}-Surveys.html
# export database -fmt sql -o Outputs/{fileName}-database.sql # export database -fmt sql -o Outputs/{fileName}-database.sql
# export continuation-list -o Outputs/{fileName}-Continuations.html # export continuation-list -o Outputs/{fileName}-Continuations.html
View File
+2 -1
View File
@@ -18,5 +18,6 @@ template_path = ./template
station_by_scrap = 30 station_by_scrap = 30
final_therion_exe = True final_therion_exe = True
therion_path = C:\Program Files\Therion\therion.exe therion_path = C:\Program Files\Therion\therion.exe
shot_lines_in_th2_files = False survey_prefix_name = Explo_
shot_lines_in_th2_files = True
station_name_in_th2_files = True station_name_in_th2_files = True
File diff suppressed because it is too large Load Diff