Preparacion de PyInstaller

This commit is contained in:
Miguel 2025-08-17 23:53:58 +02:00
parent 00c021f496
commit 13e7a12b6d
4 changed files with 211 additions and 6 deletions

1
.gitignore vendored
View File

@ -46,7 +46,6 @@ MANIFEST
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt

189
main.spec Normal file
View File

@ -0,0 +1,189 @@
# -*- mode: python ; coding: utf-8 -*-
import os
import sys
block_cipher = None
a = Analysis(
['main.py'],
pathex=[],
binaries=[
# Include snap7.dll - now confirmed to be in project root
('snap7.dll', '.'),
],
datas=[
# Include the entire frontend build
('frontend/dist', 'frontend/dist'),
# Include configuration directories and schemas
('config', 'config'),
# Include core modules
('core', 'core'),
# Include utils
('utils', 'utils'),
# Include translation files
('translation.json', '.'),
('i18n.js', '.'),
# Create records directory structure
('records', 'records'),
],
hiddenimports=[
# Flask and web dependencies
'jinja2.ext',
'flask',
'flask_cors',
'flask_socketio',
'socketio',
'werkzeug',
# JSON Schema validation
'jsonschema',
'jsonschema.validators',
'jsonschema._format',
'jsonschema._types',
# PLC and system dependencies
'snap7',
'psutil._pswindows',
'psutil._psutil_windows',
# Data processing
'pandas',
'numpy',
# Threading and networking
'threading',
'socket',
'json',
'csv',
'datetime',
'pathlib',
# Core modules (explicit imports)
'core.config_manager',
'core.plc_client',
'core.plc_data_streamer',
'core.event_logger',
'core.instance_manager',
'core.schema_manager',
'core.streamer',
'core.plot_manager',
'core.historical_cache',
'core.performance_monitor',
'core.priority_manager',
'core.rotating_logger',
# Utils modules
'utils.csv_validator',
'utils.json_manager',
'utils.symbol_loader',
'utils.symbol_processor',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[
# Exclude unnecessary packages to reduce size
'matplotlib',
'scipy',
'IPython',
'notebook',
'jupyter',
'tests',
'unittest',
'pydoc',
'doctest',
],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
[],
exclude_binaries=True,
name='S7_Streamer_Logger',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True, # True para ver los logs del servidor en una consola.
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
coll = COLLECT(exe, a.binaries, a.zipfiles, a.datas, strip=False, upx=True, upx_exclude=[], name='main')
# Post-build: Copy config directory to the same level as the executable
import shutil
import os
def copy_config_external():
"""Copy config directory to external location for runtime access"""
try:
# Get absolute paths
current_dir = os.path.abspath('.')
source_config = os.path.join(current_dir, 'config')
dist_main_dir = os.path.join(current_dir, 'dist', 'main')
dest_config = os.path.join(dist_main_dir, 'config')
print(f"Current directory: {current_dir}")
print(f"Source config: {source_config}")
print(f"Destination config: {dest_config}")
# Ensure dist/main directory exists
os.makedirs(dist_main_dir, exist_ok=True)
# Remove existing config if present
if os.path.exists(dest_config):
shutil.rmtree(dest_config)
print(f"Removed existing config at: {dest_config}")
# Copy config directory to dist/main/config
if os.path.exists(source_config):
shutil.copytree(source_config, dest_config)
print(f" Config directory copied to: {dest_config}")
return True
else:
print(f" Source config directory not found: {source_config}")
return False
except Exception as e:
print(f" Error copying config directory: {e}")
return False
# Execute the copy operation
copy_config_external()
def config_path(relative_path):
"""Get path to config file, checking external location first when running as executable"""
if getattr(sys, 'frozen', False):
# Running as executable - config should be at same level as executable
executable_dir = os.path.dirname(sys.executable)
external_config = os.path.join(executable_dir, 'config', relative_path)
if os.path.exists(external_config):
return external_config
# Fallback to internal config within _internal
internal_config = os.path.join(executable_dir, '_internal', 'config', relative_path)
if os.path.exists(internal_config):
return internal_config
raise FileNotFoundError(f"Configuration file not found: {relative_path}")
else:
# Running as script - use standard path
base_dir = os.path.dirname(os.path.abspath(__file__))
project_root = os.path.dirname(base_dir)
return os.path.join(project_root, 'config', relative_path)

View File

@ -1,7 +1,24 @@
# Core Web Framework
Flask==2.3.3
python-snap7==1.3
psutil==5.9.5
flask-socketio==5.3.6
jsonschema==4.22.0
Flask-Cors==4.0.0
pandas
# PLC Communication
python-snap7==1.3
# System Monitoring & Process Management
psutil==5.9.5
# Data Processing & Analysis
pandas==2.3.1
numpy==2.2.6
# JSON Schema Validation
jsonschema==4.22.0
# Note: The following dependencies are automatically installed with Flask:
# - Werkzeug==3.1.3 (WSGI toolkit)
# - Jinja2==3.1.6 (templating engine)
# - click (CLI utilities)
# - itsdangerous (security utilities)
# - blinker (signals)
# - MarkupSafe (safe string handling)

BIN
snap7.dll Normal file

Binary file not shown.