Actualización de logs y mejora en la gestión de excepciones en el script de exportación
- Se actualizaron los registros de ejecución en `log_x4.txt` para reflejar nuevas fechas y duraciones de los procesos. - Se implementó una nueva clase `PortalDisposedException` para manejar excepciones relacionadas con el cierre inesperado de TIA Portal. - Se mejoró la lógica de re-apertura del portal en `x4.py`, permitiendo múltiples intentos en caso de errores de acceso a bloques. - Se normalizaron los nombres de bloques para evitar omisiones en la exportación de referencias cruzadas. - Se actualizaron los logs de ejecución en `log_x0_main.txt` para reflejar el aumento en el número de archivos XML procesados.
This commit is contained in:
parent
734e6637bc
commit
bf30b2db52
|
@ -1,9 +1,9 @@
|
||||||
--- Log de Ejecución: x4.py ---
|
--- Log de Ejecución: x4.py ---
|
||||||
Grupo: ObtainIOFromProjectTia
|
Grupo: ObtainIOFromProjectTia
|
||||||
Directorio de Trabajo: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
Directorio de Trabajo: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||||
Inicio: 2025-06-13 11:14:30
|
Inicio: 2025-06-13 11:21:48
|
||||||
Fin: 2025-06-13 11:16:43
|
Fin: 2025-06-13 11:23:18
|
||||||
Duración: 0:02:13.165274
|
Duración: 0:01:29.910671
|
||||||
Estado: SUCCESS (Código de Salida: 0)
|
Estado: SUCCESS (Código de Salida: 0)
|
||||||
|
|
||||||
--- SALIDA ESTÁNDAR (STDOUT) ---
|
--- SALIDA ESTÁNDAR (STDOUT) ---
|
||||||
|
@ -14,16 +14,16 @@ Proyecto seleccionado: D:/Trabajo/VM/22 - 93841 - Sidel - Tilting/InLavoro/PLC/9
|
||||||
Usando directorio base de exportación: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
Usando directorio base de exportación: D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\Reporte\TiaExports
|
||||||
|
|
||||||
Conectando a TIA Portal V19.0...
|
Conectando a TIA Portal V19.0...
|
||||||
2025-06-13 11:14:34,713 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
2025-06-13 11:21:54,715 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - Start TIA Portal, please acknowledge the security dialog.
|
||||||
2025-06-13 11:14:34,731 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
|
2025-06-13 11:21:54,726 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Global OpenPortal - With user interface
|
||||||
Conectado a TIA Portal.
|
Conectado a TIA Portal.
|
||||||
2025-06-13 11:14:58,165 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal GetProcessId - Process id: 30140
|
2025-06-13 11:22:02,436 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal GetProcessId - Process id: 25644
|
||||||
ID del proceso del Portal: 30140
|
ID del proceso del Portal: 25644
|
||||||
Abriendo proyecto: 93841_PLC_28.ap19...
|
Abriendo proyecto: 93841_PLC_28.ap19...
|
||||||
2025-06-13 11:14:58,500 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\InLavoro\PLC\93841_PLC_28\93841_PLC_28.ap19
|
2025-06-13 11:22:02,613 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal OpenProject - Open project... D:\Trabajo\VM\22 - 93841 - Sidel - Tilting\InLavoro\PLC\93841_PLC_28\93841_PLC_28.ap19
|
||||||
Proyecto abierto exitosamente.
|
Proyecto abierto exitosamente.
|
||||||
2025-06-13 11:15:29,701 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc VM 1512 with parent name ET 200SP station_1
|
2025-06-13 11:22:12,777 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc VM 1512 with parent name ET 200SP station_1
|
||||||
2025-06-13 11:15:30,551 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc SIDEL Transport Example with parent name S71500/ET200MP station_1
|
2025-06-13 11:22:13,643 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Project GetPlcs - Found plc SIDEL Transport Example with parent name S71500/ET200MP station_1
|
||||||
Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzadas...
|
Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzadas...
|
||||||
|
|
||||||
--- Procesando PLC: VM 1512 ---
|
--- Procesando PLC: VM 1512 ---
|
||||||
|
@ -113,9 +113,9 @@ Se encontraron 2 PLC(s). Iniciando proceso de exportación de referencias cruzad
|
||||||
Exportando referencias cruzadas para FC Simple PID...
|
Exportando referencias cruzadas para FC Simple PID...
|
||||||
Procesando bloque: FC Scale Real...
|
Procesando bloque: FC Scale Real...
|
||||||
Exportando referencias cruzadas para FC Scale Real...
|
Exportando referencias cruzadas para FC Scale Real...
|
||||||
Procesando bloque: FB Correct Speed F/Pulses...
|
Procesando bloque: FB Correct Speed F_Pulses...
|
||||||
Exportando referencias cruzadas para FB Correct Speed F/Pulses...
|
Exportando referencias cruzadas para FB Correct Speed F_Pulses...
|
||||||
ERROR GENERAL al exportar referencias cruzadas para el bloque FB Correct Speed F/Pulses: OpennessAccessException: Unexpected exception - no exception message available.
|
ERROR GENERAL al exportar referencias cruzadas para el bloque FB Correct Speed F_Pulses: OpennessAccessException: Unexpected exception - no exception message available.
|
||||||
ERROR al acceder a los bloques de programa para exportar referencias cruzadas: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
ERROR al acceder a los bloques de programa para exportar referencias cruzadas: OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
||||||
|
|
||||||
TIA Portal has either been disposed or stopped running.
|
TIA Portal has either been disposed or stopped running.
|
||||||
|
@ -143,19 +143,19 @@ Ocurrió un error inesperado: OpennessAccessException: Access to a disposed obje
|
||||||
TIA Portal has either been disposed or stopped running.
|
TIA Portal has either been disposed or stopped running.
|
||||||
|
|
||||||
Cerrando TIA Portal...
|
Cerrando TIA Portal...
|
||||||
2025-06-13 11:16:43,486 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
|
2025-06-13 11:23:18,643 [1] INFO Siemens.TiaPortal.OpennessApi19.Implementations.Portal ClosePortal - Close TIA Portal
|
||||||
TIA Portal cerrado.
|
TIA Portal cerrado.
|
||||||
|
|
||||||
Script finalizado.
|
Script finalizado.
|
||||||
|
|
||||||
--- ERRORES (STDERR) ---
|
--- ERRORES (STDERR) ---
|
||||||
2025-06-13 11:16:43,458 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock ExportCrossReferences -
|
2025-06-13 11:23:18,616 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock ExportCrossReferences -
|
||||||
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Unexpected exception - no exception message available.
|
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Unexpected exception - no exception message available.
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 128, in export_plc_cross_references
|
File "D:\Proyectos\Scripts\ParamManagerScripts\backend\script_groups\ObtainIOFromProjectTia\x4.py", line 128, in export_plc_cross_references
|
||||||
block.export_cross_references(
|
block.export_cross_references(
|
||||||
ValueError: OpennessAccessException: Unexpected exception - no exception message available.
|
ValueError: OpennessAccessException: Unexpected exception - no exception message available.
|
||||||
2025-06-13 11:16:43,462 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock GetName -
|
2025-06-13 11:23:18,620 [1] ERROR Siemens.TiaPortal.OpennessApi19.Implementations.ProgramBlock GetName -
|
||||||
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
Siemens.TiaPortal.OpennessContracts.OpennessAccessException: Access to a disposed object of type 'Siemens.Engineering.SW.Blocks.FB' is not possible.
|
||||||
|
|
||||||
TIA Portal has either been disposed or stopped running.
|
TIA Portal has either been disposed or stopped running.
|
||||||
|
|
|
@ -29,6 +29,28 @@ SUPPORTED_TIA_VERSIONS = {
|
||||||
# Using 1 to export all. 0 might also work as a default in some API versions.
|
# Using 1 to export all. 0 might also work as a default in some API versions.
|
||||||
CROSS_REF_FILTER = 1
|
CROSS_REF_FILTER = 1
|
||||||
|
|
||||||
|
MAX_REOPEN_ATTEMPTS = 5 # Número máximo de re-aperturas permitidas para evitar bucles infinitos
|
||||||
|
|
||||||
|
class PortalDisposedException(Exception):
|
||||||
|
"""Excepción lanzada cuando TIA Portal se ha cerrado inesperadamente o un objeto ha sido descartado."""
|
||||||
|
|
||||||
|
def __init__(self, original_exception, failed_block: str | None = None):
|
||||||
|
super().__init__(str(original_exception))
|
||||||
|
self.failed_block = failed_block
|
||||||
|
|
||||||
|
|
||||||
|
def _is_disposed_exception(exc: Exception) -> bool:
|
||||||
|
"""Devuelve True si la excepción proviene de un objeto/portal ya cerrado o sin mensaje útil."""
|
||||||
|
msg = str(exc).lower()
|
||||||
|
return any(
|
||||||
|
indicator in msg
|
||||||
|
for indicator in (
|
||||||
|
"disposed object",
|
||||||
|
"tia portal has either been disposed",
|
||||||
|
"unexpected exception - no exception message available",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# --- TIA Scripting Import Handling ---
|
# --- TIA Scripting Import Handling ---
|
||||||
if os.getenv("TIA_SCRIPTING"):
|
if os.getenv("TIA_SCRIPTING"):
|
||||||
sys.path.append(os.getenv("TIA_SCRIPTING"))
|
sys.path.append(os.getenv("TIA_SCRIPTING"))
|
||||||
|
@ -100,8 +122,25 @@ def select_project_file():
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
return file_path
|
return file_path
|
||||||
|
|
||||||
def export_plc_cross_references(plc, export_base_dir):
|
# Normalizar nombres de bloque/tabla/udt para comparaciones consistentes
|
||||||
"""Exports cross-references for various elements from a given PLC."""
|
def _normalize_name(name: str) -> str:
|
||||||
|
"""Normaliza un nombre quitando espacios laterales y convirtiendo a minúsculas."""
|
||||||
|
return name.strip().lower()
|
||||||
|
|
||||||
|
def export_plc_cross_references(plc, export_base_dir, exported_blocks=None, problematic_blocks=None):
|
||||||
|
"""Exports cross-references for various elements from a given PLC.
|
||||||
|
Parámetros
|
||||||
|
----------
|
||||||
|
plc : objeto PLC actual
|
||||||
|
export_base_dir : pathlib.Path directorio base para exportar
|
||||||
|
exported_blocks : set[str] bloques que ya se han exportado
|
||||||
|
problematic_blocks : set[str] bloques que se deben omitir tras fallos previos
|
||||||
|
"""
|
||||||
|
if exported_blocks is None:
|
||||||
|
exported_blocks = set()
|
||||||
|
if problematic_blocks is None:
|
||||||
|
problematic_blocks = set()
|
||||||
|
|
||||||
plc_name = plc.get_name()
|
plc_name = plc.get_name()
|
||||||
print(f"\n--- Procesando PLC: {plc_name} ---")
|
print(f"\n--- Procesando PLC: {plc_name} ---")
|
||||||
|
|
||||||
|
@ -122,6 +161,14 @@ def export_plc_cross_references(plc, export_base_dir):
|
||||||
print(f" Se encontraron {len(program_blocks)} bloques de programa.")
|
print(f" Se encontraron {len(program_blocks)} bloques de programa.")
|
||||||
for block in program_blocks:
|
for block in program_blocks:
|
||||||
block_name = block.get_name()
|
block_name = block.get_name()
|
||||||
|
norm_block = _normalize_name(block_name)
|
||||||
|
if norm_block in problematic_blocks:
|
||||||
|
print(f" Omitiendo bloque problemático previamente detectado: {block_name}")
|
||||||
|
blocks_cr_skipped += 1
|
||||||
|
continue
|
||||||
|
if norm_block in exported_blocks:
|
||||||
|
# Ya exportado en un intento anterior, no repetir
|
||||||
|
continue
|
||||||
print(f" Procesando bloque: {block_name}...")
|
print(f" Procesando bloque: {block_name}...")
|
||||||
try:
|
try:
|
||||||
print(f" Exportando referencias cruzadas para {block_name}...")
|
print(f" Exportando referencias cruzadas para {block_name}...")
|
||||||
|
@ -130,10 +177,12 @@ def export_plc_cross_references(plc, export_base_dir):
|
||||||
filter=CROSS_REF_FILTER,
|
filter=CROSS_REF_FILTER,
|
||||||
)
|
)
|
||||||
blocks_cr_exported += 1
|
blocks_cr_exported += 1
|
||||||
|
exported_blocks.add(norm_block)
|
||||||
except RuntimeError as block_ex:
|
except RuntimeError as block_ex:
|
||||||
print(
|
print(
|
||||||
f" ERROR TIA al exportar referencias cruzadas para el bloque {block_name}: {block_ex}"
|
f" ERROR TIA al exportar referencias cruzadas para el bloque {block_name}: {block_ex}"
|
||||||
)
|
)
|
||||||
|
problematic_blocks.add(norm_block)
|
||||||
blocks_cr_skipped += 1
|
blocks_cr_skipped += 1
|
||||||
except Exception as block_ex:
|
except Exception as block_ex:
|
||||||
print(
|
print(
|
||||||
|
@ -141,6 +190,10 @@ def export_plc_cross_references(plc, export_base_dir):
|
||||||
)
|
)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
blocks_cr_skipped += 1
|
blocks_cr_skipped += 1
|
||||||
|
if _is_disposed_exception(block_ex):
|
||||||
|
# Escalamos para que el script pueda re-abrir el Portal y omitir el bloque
|
||||||
|
problematic_blocks.add(norm_block)
|
||||||
|
raise PortalDisposedException(block_ex, failed_block=block_name)
|
||||||
print(
|
print(
|
||||||
f" Resumen de exportación de referencias cruzadas de bloques: Exportados={blocks_cr_exported}, Omitidos/Errores={blocks_cr_skipped}"
|
f" Resumen de exportación de referencias cruzadas de bloques: Exportados={blocks_cr_exported}, Omitidos/Errores={blocks_cr_skipped}"
|
||||||
)
|
)
|
||||||
|
@ -151,6 +204,8 @@ def export_plc_cross_references(plc, export_base_dir):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f" ERROR al acceder a los bloques de programa para exportar referencias cruzadas: {e}")
|
print(f" ERROR al acceder a los bloques de programa para exportar referencias cruzadas: {e}")
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
problematic_blocks.add(_normalize_name(e.__str__()))
|
||||||
|
raise PortalDisposedException(e)
|
||||||
|
|
||||||
# --- Export PLC Tag Table Cross-References ---
|
# --- Export PLC Tag Table Cross-References ---
|
||||||
tags_cr_exported = 0
|
tags_cr_exported = 0
|
||||||
|
@ -345,6 +400,23 @@ def export_plc_cross_references(plc, export_base_dir):
|
||||||
|
|
||||||
print(f"\n--- Finalizado el procesamiento del PLC: {plc_name} ---")
|
print(f"\n--- Finalizado el procesamiento del PLC: {plc_name} ---")
|
||||||
|
|
||||||
|
def open_portal_and_project(tia_version: str, project_file_path: str):
|
||||||
|
"""Abre TIA Portal y el proyecto indicado, devolviendo el portal y el objeto proyecto."""
|
||||||
|
print(f"\nConectando a TIA Portal V{tia_version}...")
|
||||||
|
portal = ts.open_portal(
|
||||||
|
version=tia_version,
|
||||||
|
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
||||||
|
)
|
||||||
|
print("Conectado a TIA Portal.")
|
||||||
|
print(f"ID del proceso del Portal: {portal.get_process_id()}")
|
||||||
|
|
||||||
|
project_obj = portal.open_project(project_file_path=str(project_file_path))
|
||||||
|
if project_obj is None:
|
||||||
|
project_obj = portal.get_project()
|
||||||
|
if project_obj is None:
|
||||||
|
raise Exception("No se pudo abrir u obtener el proyecto especificado tras la reapertura.")
|
||||||
|
return portal, project_obj
|
||||||
|
|
||||||
# --- Main Script ---
|
# --- Main Script ---
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -380,28 +452,9 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 4. Connect to TIA Portal with detected version
|
# 4. Connect to TIA Portal with detected version
|
||||||
print(f"\nConectando a TIA Portal V{tia_version}...")
|
portal_instance, project_object = open_portal_and_project(tia_version, project_file)
|
||||||
portal_instance = ts.open_portal(
|
|
||||||
version=tia_version,
|
|
||||||
portal_mode=ts.Enums.PortalMode.WithGraphicalUserInterface,
|
|
||||||
)
|
|
||||||
print("Conectado a TIA Portal.")
|
|
||||||
print(f"ID del proceso del Portal: {portal_instance.get_process_id()}")
|
|
||||||
|
|
||||||
# 5. Open Project
|
# 5. Get PLCs
|
||||||
print(f"Abriendo proyecto: {os.path.basename(project_file)}...")
|
|
||||||
project_path_obj = Path(project_file)
|
|
||||||
project_object = portal_instance.open_project(
|
|
||||||
project_file_path=str(project_path_obj)
|
|
||||||
)
|
|
||||||
if project_object is None:
|
|
||||||
print("El proyecto podría estar ya abierto, intentando obtener el manejador...")
|
|
||||||
project_object = portal_instance.get_project()
|
|
||||||
if project_object is None:
|
|
||||||
raise Exception("No se pudo abrir u obtener el proyecto especificado.")
|
|
||||||
print("Proyecto abierto exitosamente.")
|
|
||||||
|
|
||||||
# 6. Get PLCs
|
|
||||||
plcs = project_object.get_plcs()
|
plcs = project_object.get_plcs()
|
||||||
if not plcs:
|
if not plcs:
|
||||||
print("No se encontraron dispositivos PLC en el proyecto.")
|
print("No se encontraron dispositivos PLC en el proyecto.")
|
||||||
|
@ -410,12 +463,63 @@ if __name__ == "__main__":
|
||||||
f"Se encontraron {len(plcs)} PLC(s). Iniciando proceso de exportación de referencias cruzadas..."
|
f"Se encontraron {len(plcs)} PLC(s). Iniciando proceso de exportación de referencias cruzadas..."
|
||||||
)
|
)
|
||||||
|
|
||||||
# 7. Iterate and Export Cross-References for each PLC
|
# 7. Iterate and Export Cross-References for each PLC con lógica de re-apertura
|
||||||
for plc_device in plcs:
|
for plc_device in plcs:
|
||||||
export_plc_cross_references(
|
plc_name = plc_device.get_name()
|
||||||
plc=plc_device,
|
exported_blocks = set()
|
||||||
export_base_dir=export_base_dir,
|
problematic_blocks = set()
|
||||||
)
|
skipped_blocks_report = []
|
||||||
|
reopen_attempts = 0
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
export_plc_cross_references(
|
||||||
|
plc=plc_device,
|
||||||
|
export_base_dir=export_base_dir,
|
||||||
|
exported_blocks=exported_blocks,
|
||||||
|
problematic_blocks=problematic_blocks,
|
||||||
|
)
|
||||||
|
break # Éxito
|
||||||
|
except PortalDisposedException as pd_ex:
|
||||||
|
reopen_attempts += 1
|
||||||
|
failed_block = pd_ex.failed_block
|
||||||
|
if failed_block:
|
||||||
|
problematic_blocks.add(_normalize_name(failed_block))
|
||||||
|
skipped_blocks_report.append(failed_block)
|
||||||
|
|
||||||
|
if reopen_attempts > MAX_REOPEN_ATTEMPTS:
|
||||||
|
print(
|
||||||
|
f"Se alcanzó el máximo de re-aperturas permitidas ({MAX_REOPEN_ATTEMPTS}) para el PLC '{plc_name}'. Abortando."
|
||||||
|
)
|
||||||
|
break
|
||||||
|
|
||||||
|
# Intentamos cerrar el portal actual (si existe)
|
||||||
|
try:
|
||||||
|
print("Cerrando instancia actual de TIA Portal...")
|
||||||
|
portal_instance.close_portal()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Re-abrir portal y proyecto
|
||||||
|
print(f"Re-abriendo TIA Portal (intento {reopen_attempts}/{MAX_REOPEN_ATTEMPTS})...")
|
||||||
|
portal_instance, project_object = open_portal_and_project(tia_version, project_file)
|
||||||
|
|
||||||
|
# Buscar de nuevo el PLC por nombre
|
||||||
|
plc_device = None
|
||||||
|
for _plc in project_object.get_plcs():
|
||||||
|
if _plc.get_name() == plc_name:
|
||||||
|
plc_device = _plc
|
||||||
|
break
|
||||||
|
if plc_device is None:
|
||||||
|
print(
|
||||||
|
f"No se encontró el PLC '{plc_name}' tras la re-apertura. Se aborta su procesamiento."
|
||||||
|
)
|
||||||
|
break
|
||||||
|
# Continuar con el while
|
||||||
|
continue
|
||||||
|
|
||||||
|
if skipped_blocks_report:
|
||||||
|
print(f"\nBloques problemáticos para el PLC '{plc_name}': {', '.join(set(skipped_blocks_report))}")
|
||||||
|
|
||||||
print("\nProceso de exportación de referencias cruzadas completado.")
|
print("\nProceso de exportación de referencias cruzadas completado.")
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
6002
data/log.txt
6002
data/log.txt
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue