360 lines
9.2 KiB
RPMSpec
360 lines
9.2 KiB
RPMSpec
# -*- mode: python ; coding: utf-8 -*-
|
|
import os
|
|
from PyInstaller.utils.hooks import collect_data_files, collect_submodules
|
|
import glob
|
|
|
|
block_cipher = None
|
|
|
|
# Get the base path
|
|
base_path = '.'
|
|
|
|
# Collect all Odoo submodules dynamically
|
|
try:
|
|
odoo_submodules = collect_submodules('odoo')
|
|
addon_submodules = collect_submodules('odoo.addons')
|
|
except Exception:
|
|
odoo_submodules = []
|
|
addon_submodules = []
|
|
|
|
# Collect data files from various sources
|
|
try:
|
|
babel_data = collect_data_files('babel')
|
|
reportlab_data = collect_data_files('reportlab')
|
|
except Exception:
|
|
babel_data = []
|
|
reportlab_data = []
|
|
|
|
# Function to safely add data files that exist
|
|
def safe_add_data(source_pattern, dest_folder):
|
|
data_files = []
|
|
try:
|
|
if '*' in source_pattern:
|
|
# Handle glob patterns
|
|
matches = glob.glob(os.path.join(base_path, source_pattern))
|
|
for match in matches:
|
|
if os.path.exists(match):
|
|
rel_path = os.path.relpath(match, base_path)
|
|
data_files.append((rel_path, dest_folder))
|
|
else:
|
|
# Handle single files/folders
|
|
full_path = os.path.join(base_path, source_pattern)
|
|
if os.path.exists(full_path):
|
|
data_files.append((source_pattern, dest_folder))
|
|
except Exception as e:
|
|
print(f"Warning: Could not add {source_pattern}: {e}")
|
|
return data_files
|
|
|
|
a = Analysis(
|
|
['odoo-bin'],
|
|
pathex=[base_path],
|
|
binaries=[],
|
|
datas=[
|
|
# Core Odoo files (only if they exist)
|
|
('addons', 'addons'),
|
|
('odoo', 'odoo'),
|
|
('extra-addons', 'extra-addons'),
|
|
|
|
# Configuration files
|
|
('odoo.conf', '.'),
|
|
|
|
# Add other config files if they exist
|
|
] + safe_add_data('odoo-*.conf', '.') + [
|
|
|
|
# GeoIP databases (if they exist)
|
|
] + safe_add_data('/root/dev/NextERP/dev/odoo18/resource/GeoLite2-City_20250708/GeoLite2-City.mmdb', 'geoip/') + \
|
|
safe_add_data('/root/dev/NextERP/dev/odoo18/resource/GeoLite2-Country_20250708/GeoLite2-Country.mmdb', 'geoip/') + \
|
|
babel_data + reportlab_data,
|
|
|
|
hiddenimports=[
|
|
# Core Python modules
|
|
'pkg_resources.py2_warn',
|
|
'pkg_resources',
|
|
|
|
# Database drivers
|
|
'psycopg2',
|
|
'psycopg2.extensions',
|
|
'psycopg2.extras',
|
|
|
|
# Core Odoo dependencies
|
|
'lxml',
|
|
'lxml.etree',
|
|
'lxml.html',
|
|
'lxml.html.clean',
|
|
'werkzeug',
|
|
'werkzeug.serving',
|
|
'werkzeug.security',
|
|
'babel',
|
|
'babel.dates',
|
|
'babel.numbers',
|
|
'passlib',
|
|
'passlib.hash',
|
|
'dateutil',
|
|
'python_dateutil',
|
|
'pytz',
|
|
'PIL',
|
|
'PIL.Image',
|
|
'reportlab',
|
|
'openpyxl',
|
|
'xlrd',
|
|
'xlwt',
|
|
'requests',
|
|
'urllib3',
|
|
'jinja2',
|
|
'markupsafe',
|
|
|
|
# Odoo core modules
|
|
'odoo',
|
|
'odoo.addons',
|
|
'odoo.tools',
|
|
'odoo.tools.pdf',
|
|
|
|
# Only include PDF modules that actually exist
|
|
'odoo.tools.pdf._pypdf',
|
|
'odoo.tools.pdf._pypdf2_1',
|
|
'odoo.tools.pdf._pypdf2_2',
|
|
|
|
'odoo.service',
|
|
'odoo.service.server',
|
|
'odoo.http',
|
|
'odoo.cli',
|
|
'odoo.cli.server',
|
|
'odoo.cli.command',
|
|
'odoo.cli.deploy',
|
|
'odoo.cli.scaffold',
|
|
'odoo.cli.shell',
|
|
'odoo.cli.start',
|
|
|
|
# Web framework
|
|
'odoo.addons.web',
|
|
'odoo.addons.base',
|
|
|
|
# Additional dependencies from your requirements
|
|
'gevent',
|
|
'greenlet',
|
|
'psutil',
|
|
'qrcode',
|
|
'num2words',
|
|
'python_stdnum',
|
|
'vobject',
|
|
'zeep',
|
|
'cryptography',
|
|
'cryptography.hazmat',
|
|
'cryptography.hazmat.primitives',
|
|
'cryptography.hazmat.primitives.kdf',
|
|
'cryptography.hazmat.primitives.kdf.hkdf',
|
|
'cryptography.hazmat.primitives.hashes',
|
|
'cryptography.hazmat.primitives.ciphers',
|
|
'cryptography.hazmat.primitives.serialization',
|
|
'cryptography.hazmat.backends',
|
|
'cryptography.hazmat.backends.openssl',
|
|
'cryptography.fernet',
|
|
'docutils',
|
|
'freezegun',
|
|
'geoip2',
|
|
'libsass',
|
|
'polib',
|
|
'pyopenssl',
|
|
'pyserial',
|
|
'pyusb',
|
|
'rjsmin',
|
|
'unidecode',
|
|
'beautifulsoup4',
|
|
'html2text',
|
|
'python_docx',
|
|
'boto3',
|
|
'paramiko',
|
|
'openai',
|
|
'weasyprint',
|
|
'pdfkit',
|
|
'pdfminer',
|
|
'pdfminer.six',
|
|
|
|
# Reportlab barcode modules - needed for Odoo reports
|
|
'reportlab.graphics.barcode',
|
|
'reportlab.graphics.barcode.code128',
|
|
'reportlab.graphics.barcode.code39',
|
|
'reportlab.graphics.barcode.code93',
|
|
'reportlab.graphics.barcode.common',
|
|
'reportlab.graphics.barcode.eanbc',
|
|
'reportlab.graphics.barcode.qr',
|
|
'reportlab.graphics.barcode.usps',
|
|
'reportlab.graphics.barcode.usps4s',
|
|
'reportlab.graphics.barcode.widgets',
|
|
'reportlab.graphics.barcode.lto',
|
|
'reportlab.graphics.barcode.dmtx',
|
|
'reportlab.graphics.barcode.ecc200datamatrix',
|
|
'reportlab.graphics.barcode.fourstate',
|
|
|
|
# Babel message modules - needed for translations
|
|
'babel.messages',
|
|
'babel.messages.pofile',
|
|
'babel.messages.catalog',
|
|
'babel.messages.extract',
|
|
'babel.messages.frontend',
|
|
'babel.messages.jslexer',
|
|
'babel.messages.mofile',
|
|
'babel.messages.plurals',
|
|
|
|
# PyPDF modules (the ones that actually exist)
|
|
'PyPDF2',
|
|
'PyPDF2.errors',
|
|
'PyPDF2.filters',
|
|
'PyPDF2.generic',
|
|
'pypdf',
|
|
'pypdf.errors',
|
|
'pypdf.filters',
|
|
'pypdf.generic',
|
|
|
|
# Dynamic imports
|
|
'email.mime.multipart',
|
|
'email.mime.text',
|
|
'email.mime.base',
|
|
'email.encoders',
|
|
|
|
# Additional modules that might be imported dynamically
|
|
'unicodedata',
|
|
'locale',
|
|
'threading',
|
|
'multiprocessing',
|
|
'subprocess',
|
|
'socket',
|
|
'ssl',
|
|
'json',
|
|
'base64',
|
|
'hashlib',
|
|
'hmac',
|
|
'uuid',
|
|
'datetime',
|
|
'time',
|
|
'timeit', # Add timeit as it's needed by passlib
|
|
'calendar',
|
|
'math',
|
|
'random',
|
|
'os',
|
|
'sys',
|
|
'io',
|
|
'tempfile',
|
|
'shutil',
|
|
're',
|
|
'collections',
|
|
'itertools',
|
|
'functools',
|
|
'operator',
|
|
'copy',
|
|
'pickle',
|
|
'csv',
|
|
'xml',
|
|
'xml.etree',
|
|
'xml.etree.ElementTree',
|
|
'xml.sax',
|
|
'html',
|
|
'urllib',
|
|
'urllib.parse',
|
|
'urllib.request',
|
|
'http',
|
|
'http.client',
|
|
|
|
# Additional Odoo modules that might be needed
|
|
'odoo.modules',
|
|
'odoo.modules.registry',
|
|
'odoo.modules.loading',
|
|
'odoo.modules.migration',
|
|
'odoo.modules.module',
|
|
'odoo.modules.graph',
|
|
'odoo.modules.db',
|
|
'odoo.sql_db',
|
|
'odoo.pooler',
|
|
'odoo.fields',
|
|
'odoo.models',
|
|
'odoo.api',
|
|
'odoo.exceptions',
|
|
'odoo.release',
|
|
'odoo.netsvc',
|
|
'odoo.loglevels',
|
|
|
|
# Passlib specific modules
|
|
'passlib.context',
|
|
'passlib.registry',
|
|
'passlib.ifc',
|
|
'passlib.utils',
|
|
'passlib.utils.compat',
|
|
'passlib.crypto',
|
|
'passlib.crypto.digest',
|
|
'passlib.handlers',
|
|
'passlib.handlers.pbkdf2',
|
|
'passlib.handlers.sha2_crypt',
|
|
'passlib.handlers.bcrypt',
|
|
'passlib.handlers.argon2',
|
|
# Mail module dependencies
|
|
'email.utils',
|
|
'email.header',
|
|
'email.charset',
|
|
'smtplib',
|
|
'poplib',
|
|
'imaplib',
|
|
] + odoo_submodules + addon_submodules,
|
|
|
|
hookspath=[],
|
|
runtime_hooks=[],
|
|
excludes=[
|
|
# Exclude unnecessary modules to reduce size
|
|
'tkinter',
|
|
'matplotlib',
|
|
'scipy',
|
|
'pandas',
|
|
'jupyter',
|
|
'notebook',
|
|
'ipython',
|
|
'django',
|
|
'flask',
|
|
'tornado',
|
|
'twisted',
|
|
'test',
|
|
'tests',
|
|
'unittest',
|
|
'doctest',
|
|
'pdb',
|
|
'profile',
|
|
'cProfile',
|
|
'pstats',
|
|
'trace',
|
|
# 'timeit', # DON'T exclude - needed by passlib
|
|
|
|
# Exclude non-existent PDF modules
|
|
'odoo.tools.pdf._pypdf2_3',
|
|
'odoo.tools.pdf._pypdf4',
|
|
],
|
|
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='odoo18',
|
|
debug=False,
|
|
bootloader_ignore_signals=False,
|
|
strip=False,
|
|
upx=True,
|
|
console=True,
|
|
disable_windowed_traceback=False,
|
|
target_arch=None,
|
|
codesign_identity=None,
|
|
entitlements_file=None,
|
|
)
|
|
|
|
coll = COLLECT(
|
|
exe,
|
|
a.binaries,
|
|
a.datas,
|
|
strip=False,
|
|
upx=True,
|
|
upx_exclude=[],
|
|
name='odoo18',
|
|
) |