367 lines
17 KiB
Python
367 lines
17 KiB
Python
import sys, os
|
|
from cx_Freeze import setup, Executable
|
|
# from PySide6 import QtCore
|
|
# import ssl
|
|
from setuptools import find_packages
|
|
from updateManager.__version__ import (
|
|
__title__, __version__, __description__, __author__,
|
|
__author_email__, __license__, __install_requires__,
|
|
__exe_name__, __icon_file__, __main_script__,
|
|
__file_log_level__, __gui_log_level__
|
|
)
|
|
import subprocess
|
|
from setuptools.command.build_ext import build_ext
|
|
from setuptools.command.install import install
|
|
from cx_Freeze.command.build_exe import build_exe as _build_exe
|
|
import importlib.util
|
|
import logging
|
|
import shutil
|
|
|
|
# 필요한 파일 경로 설정
|
|
base_dir = os.path.dirname(__file__)
|
|
browsers_dir = os.path.join(base_dir, 'src', 'browsers')
|
|
chromium_dir = os.path.join(browsers_dir, 'src', 'browsers', 'chromium-1200')
|
|
extensions_dir = os.path.join(browsers_dir, 'src', 'browsers', 'extensions')
|
|
|
|
updater_file = os.path.join(base_dir, 'updateManager', 'updater.exe')
|
|
|
|
dll_files = [
|
|
# "LIBPQ.dll",
|
|
# "MIMAPI64.dll",
|
|
# "Qt63DQuickScene3D.dll",
|
|
"api-ms-win-core-com-l1-1-0.dll",
|
|
"api-ms-win-core-debug-l1-1-0.dll",
|
|
"api-ms-win-core-errorhandling-l1-1-0.dll",
|
|
"api-ms-win-core-handle-l1-1-0.dll",
|
|
"api-ms-win-core-heap-l1-1-0.dll",
|
|
# "api-ms-win-core-heap-l2-1-0.dll",
|
|
"api-ms-win-core-interlocked-l1-1-0.dll",
|
|
# "api-ms-win-core-libraryloader-l1-2-0.dll",
|
|
# "api-ms-win-core-libraryloader-l1-2-1.dll",
|
|
"api-ms-win-core-localization-l1-2-0.dll",
|
|
# "api-ms-win-core-path-l1-1-0.dll",
|
|
"api-ms-win-core-processthreads-l1-1-0.dll",
|
|
"api-ms-win-core-processthreads-l1-1-1.dll",
|
|
"api-ms-win-core-profile-l1-1-0.dll",
|
|
# "api-ms-win-core-realtime-l1-1-1.dll",
|
|
"api-ms-win-core-rtlsupport-l1-1-0.dll",
|
|
"api-ms-win-core-synch-l1-1-0.dll",
|
|
"api-ms-win-core-synch-l1-2-0.dll",
|
|
"api-ms-win-core-sysinfo-l1-1-0.dll",
|
|
# "api-ms-win-core-winrt-error-l1-1-0.dll",
|
|
# "api-ms-win-core-winrt-l1-1-0.dll",
|
|
# "api-ms-win-core-winrt-string-l1-1-0.dll",
|
|
"api-ms-win-crt-conio-l1-1-0.dll",
|
|
"api-ms-win-crt-environment-l1-1-0.dll",
|
|
"api-ms-win-crt-filesystem-l1-1-0.dll",
|
|
"api-ms-win-crt-multibyte-l1-1-0.dll",
|
|
"api-ms-win-crt-private-l1-1-0.dll",
|
|
"api-ms-win-crt-process-l1-1-0.dll",
|
|
"api-ms-win-crt-time-l1-1-0.dll",
|
|
"api-ms-win-crt-utility-l1-1-0.dll",
|
|
# "api-ms-win-power-base-l1-1-0.dll",
|
|
# "api-ms-win-power-setting-l1-1-0.dll",
|
|
# "api-ms-win-shcore-scaling-l1-1-1.dll",
|
|
]
|
|
|
|
# ✅ DLL 경로 설정 (Windows 10의 System32에서 가져오기)
|
|
system32_path = "C:/Windows/System32/downlevel"
|
|
dll_include_files = [(os.path.join(system32_path, dll), dll) for dll in dll_files]
|
|
|
|
dll_include_files = [] # 충돌 가능성으로 인해 빈 리스트로 초기화
|
|
|
|
vc_runtime_files = [
|
|
('C:/Windows/System32/vcruntime140.dll', 'vcruntime140.dll'),
|
|
('C:/Windows/System32/vcruntime140_1.dll', 'vcruntime140_1.dll'),
|
|
('C:/Windows/System32/msvcp140.dll', 'msvcp140.dll'),
|
|
('C:/Windows/System32/msvcp140_1.dll', 'msvcp140_1.dll'),
|
|
('C:/Windows/System32/msvcp140_2.dll', 'msvcp140_2.dll'),
|
|
('C:/Windows/System32/concrt140.dll', 'concrt140.dll'),
|
|
('C:/Windows/System32/vcomp140.dll', 'vcomp140.dll'),
|
|
]
|
|
|
|
# DirectML 사용: Windows GPU 가속을 위해 DirectML 기반 ONNXRuntime 사용
|
|
|
|
# ✅ 기존 포함 파일 + DLL 추가
|
|
include_files = dll_include_files + vc_runtime_files + [
|
|
# 나머지 파일들
|
|
('src/Edit_PartTimer3.ico', 'lib/src/Edit_PartTimer3.ico'), # 아이콘 파일 경로 수정
|
|
# ('win.exe.manifest', 'win.exe.manifest'),
|
|
# ('libssl-3-x64.dll', 'libssl-3-x64.dll'),
|
|
# ('libcrypto-3-x64.dll', 'libcrypto-3-x64.dll'),
|
|
('kiprisCategories.json', 'kiprisCategories.json'),
|
|
('src/keyword/kiprisCategories.json', 'lib/src/keyword/kiprisCategories.json'),
|
|
('src/modules/fonts', 'lib/src/modules/fonts'),
|
|
# ('src/modules/fonts/Cafe24Ohsquare-v2.0.ttf', 'lib/src/fonts/Cafe24Ohsquare-v2.0.ttf'),
|
|
# ('src/modules/fonts/gamtanload.ttf', 'lib/src/fonts/gamtanload.ttf'),
|
|
# ('src/modules/fonts/NanumBarunGothic.ttf', 'lib/src/fonts/NanumBarunGothic.ttf'),
|
|
# ('src/modules/fonts/NanumSquareRoundR.ttf', 'lib/src/fonts/NanumSquareRoundR.ttf'),
|
|
# ('src/modules/fonts/HakgyoansimDunggeunmisoTTFB.ttf', 'lib/src/fonts/HakgyoansimDunggeunmisoTTFB.ttf'),
|
|
|
|
# ('src/modules/fonts/Cafe24Ohsquare-v2.0.ttf', 'lib/src/modules/fonts/Cafe24Ohsquare-v2.0.ttf'),
|
|
# ('src/modules/fonts/gamtanload.ttf', 'lib/src/modules/fonts/gamtanload.ttf'),
|
|
# ('src/modules/fonts/NanumBarunGothic.ttf', 'lib/src/modules/fonts/NanumBarunGothic.ttf'),
|
|
# ('src/modules/fonts/NanumSquareRoundR.ttf', 'lib/src/modules/fonts/NanumSquareRoundR.ttf'),
|
|
# ('src/modules/fonts/HakgyoansimDunggeunmisoTTFB.ttf', 'lib/src/modules/fonts/HakgyoansimDunggeunmisoTTFB.ttf'),
|
|
|
|
(updater_file, 'updater.exe'),
|
|
|
|
('퍼센티 다양한 카테고리 엑셀 수집(스스 기준).xlsx', '퍼센티 다양한 카테고리 엑셀 수집(스스 기준).xlsx'),
|
|
('src/Percenty_SS_Code.json', 'lib/src/Percenty_SS_Code.json'),
|
|
('src/browsers/chromium-1200', 'lib/src/browsers/chromium-1200'),
|
|
('src/browsers/extensions', 'lib/src/browsers/extensions'),
|
|
('C:/Windows/System32/vcomp140.dll', 'vcomp140.dll'),
|
|
]
|
|
for src, dest in include_files:
|
|
if not os.path.exists(src):
|
|
print(f"경로가 존재하지 않습니다: {src}")
|
|
|
|
# 사용된 패키지 정의
|
|
build_exe_options = {
|
|
'include_msvcr': True, # VC++ 런타임 자동 포함
|
|
'packages': [
|
|
'ctypes', 'asyncio',
|
|
'subprocess', 'pyperclip', 'numpy',
|
|
'requests', 'openai',
|
|
'PIL', 'bs4', 'PySide6', 'psutil',
|
|
'pandas', 'supabase', 'translatepy', 'markdown',
|
|
'supabase', 'gotrue', 'storage3', 'postgrest',
|
|
# json 모듈 순환 import 문제 해결
|
|
'json', 'json.encoder', 'json.decoder', 'json.scanner',
|
|
],
|
|
'includes': [
|
|
'shiboken6','playwright','comtypes.stream', 'win32com.client', 'win32com.server', 'pythoncom',
|
|
'loggerModule', 'toggleSwitch',
|
|
'browser_control', 'locatorManager_by_SP',
|
|
'src.cmdDiag', 'src.inputDiag', 'src.keyword', 'src.priceSetDiag',
|
|
'src.contents', 'src.contents.option', 'src.contents.price', 'src.contents.details',
|
|
'src.contents.titleGenerator', 'src.contents.thumb', 'src.contents.tags',
|
|
'src.titleManager', 'src.titleManager.sp_ForbiddenM', 'src.titleManager.gpt_client',
|
|
'src.translator', 'src.translator.papago_translator',
|
|
'src.discord_manager', 'src.unwantedDiag', 'src.unwantedDiag.unwanted_words_dialog',
|
|
'src.logDialog', 'src.logDialog.log_dialog', 'src.logDialog.log_filter',
|
|
'src.translator.chinese_dict_manager','src.translator.papago_translator',
|
|
'src.modules.settings_manager',
|
|
'src.modules.gpu_status_checker', 'src.modules.gpu_utils', 'src.gpuDiag',
|
|
'src.modules.image_worker_client', # 이미지 워커 클라이언트만 포함
|
|
'src.img_module', 'src.img_module.image_processor_manager', 'src.img_module.image_processor_dialog',
|
|
'src.modules.fonts.fontSelectDialog',
|
|
'src.lens', 'src.lens.naver_lens_client', 'src.lens.naver_lens_parser', 'src.lens.naver_lens_adapter', 'src.lens.aliprice_lens_client',
|
|
'translatepy', 'translatepy.translators', 'translatepy.translators.google',
|
|
# 썸네일 이미지 처리용 (thumb.py에서 사용)
|
|
'PIL', 'PIL.Image', 'PIL.ImageOps', 'PIL.ImageEnhance', 'PIL.ImageFilter', 'PIL.features',
|
|
'numpy', 'numpy.core', 'numpy.random',
|
|
# supabase 전체 생태계
|
|
'supabase', 'gotrue', 'storage3', 'postgrest', 'supafunc', 'realtime',
|
|
# pydantic 생태계
|
|
'pydantic', 'pydantic_core',
|
|
# json 순환 import 문제 해결
|
|
'json', 'json.encoder', 'json.decoder', 'json.scanner',
|
|
# httpx 의존성 모듈들
|
|
'httpx', 'httpx.__version__', 'httpx._models', 'httpx._client', 'httpx._config',
|
|
'curl_cffi', 'curl_cffi.requests',
|
|
# pathlib 명시적 포함 (PySide6에서 필요)
|
|
'pathlib',
|
|
],
|
|
'include_files': include_files,
|
|
'excludes': [
|
|
'tkinter', 'PyQt4', 'PyQt5', 'AppKit', 'Foundation', 'IPython',
|
|
'OpenSSL', 'curses', 'test', 'matplotlib', 'asyncpg',
|
|
# importlib 관련 - metadata는 pydantic에서 필요하므로 제외하지 않음
|
|
'importlib._bootstrap', 'importlib.machinery',
|
|
# 개발/테스트 도구들 제외
|
|
'pytest', 'hypothesis', 'mypy', 'coverage', 'tox',
|
|
# 수학 라이브러리 (사용하지 않음)
|
|
'sympy', 'sympy.core', 'sympy.ntheory', 'sympy.external', 'sympy.polys', 'sympy.*',
|
|
'mpmath', 'gmpy2',
|
|
# ImageProcessor3 관련 제외 (별도 프로젝트로 분리됨)
|
|
'paddle', 'paddleocr', 'paddlehub',
|
|
'onnxruntime', 'onnx',
|
|
'skimage', 'scikit-image',
|
|
'pyclipper', 'shapely',
|
|
'scipy', 'scipy.special', 'scipy.sparse', 'scipy.linalg', 'scipy.ndimage',
|
|
'imgaug', 'albumentations',
|
|
'torch', 'tensorflow', 'keras',
|
|
# OCR 및 이미지 처리 관련 모듈 (별도 프로젝트로 분리됨)
|
|
'src.modules.image_processor3',
|
|
'src.modules.image_processor4',
|
|
'src.modules.image_worker',
|
|
'src.modules.image_worker_manager',
|
|
'src.modules.ocr_module',
|
|
'src.modules.mask_module_for_paddle',
|
|
'src.modules.text_rendering_module',
|
|
'src.modules.postImageManager',
|
|
'src.modules.request_inpaint',
|
|
'src.modules.migan_module',
|
|
'src.modules.background_removal_module',
|
|
'src.modules.bria_background_removal_module',
|
|
'src.modules.gemma_client',
|
|
'src.modules.onnx_ocr_module',
|
|
],
|
|
'zip_include_packages': [], # 아무 패키지도 압축하지 않음 (numpy 관련 문제 해결)
|
|
'optimize': 0, # 바이트 코드 최적화 비활성화 (numpy/scipy 호환성 보장)
|
|
'silent': True, # 디버그 메시지 활성화
|
|
# numpy 바이너리 파일 강제 포함
|
|
'include_msvcr': True, # VC++ 런타임 포함
|
|
}
|
|
|
|
# 애플리케이션 메인 파일 및 설정
|
|
base = None
|
|
if sys.platform == 'win32':
|
|
base = 'Win32GUI'
|
|
|
|
# ✅ 아이콘 지정: icon='파일경로.ico'
|
|
executables = [
|
|
Executable(
|
|
'main.py',
|
|
base=base,
|
|
target_name='Edit_PartTimer3.exe',
|
|
icon="Edit_PartTimer3.ico"
|
|
)
|
|
]
|
|
|
|
|
|
# build_exe 클래스를 확장하여 빌드 전 의존성 체크 및 빌드 후 iss 파일 생성
|
|
class build_exe(_build_exe):
|
|
def run(self):
|
|
|
|
# 원래 빌드 프로세스 실행
|
|
_build_exe.run(self)
|
|
|
|
# 빌드 후 불필요한 ImageProcessor3 관련 파일 정리
|
|
print("\n불필요한 ImageProcessor3 관련 파일 정리 중...\n")
|
|
self._cleanup_unnecessary_files()
|
|
|
|
print("\n빌드가 완료되었습니다. 이제 Inno Setup 스크립트 생성을 시작합니다...\n")
|
|
|
|
try:
|
|
# generate_iss.py 스크립트 실행
|
|
result = subprocess.run([sys.executable, "generate_iss.py"], capture_output=True, text=True)
|
|
if result.returncode == 0:
|
|
print(result.stdout)
|
|
print("\nInno Setup 스크립트 생성이 완료되었습니다!")
|
|
else:
|
|
print(f"Inno Setup 스크립트 생성 중 오류 발생: {result.stderr}")
|
|
except Exception as e:
|
|
print(f"Inno Setup 스크립트 생성 중 예외 발생: {e}")
|
|
|
|
def _cleanup_unnecessary_files(self):
|
|
"""빌드 결과물에서 ImageProcessor3 관련 불필요한 파일/디렉토리 제거"""
|
|
# 빌드 디렉토리 경로
|
|
build_dir = os.path.join(os.path.dirname(__file__), "build")
|
|
|
|
# 제거할 디렉토리/파일 목록
|
|
unnecessary_items = [
|
|
# 디렉토리
|
|
"lib/src/modules/briaaiModel",
|
|
"lib/src/modules/migan_onnx",
|
|
"lib/src/modules/modules",
|
|
"lib/src/modules/ocr_backends",
|
|
"lib/src/modules/onnx_ocr_module",
|
|
"lib/src/modules/output",
|
|
"lib/src/modules/outputs",
|
|
"lib/src/modules/PP_Models",
|
|
"lib/src/modules/rembg_models",
|
|
"lib/src/PP_Models", # 상위 디렉토리의 PP_Models도 제거
|
|
# 대용량 패키지 (만약 포함되었다면)
|
|
"lib/paddle",
|
|
"lib/paddleocr",
|
|
"lib/onnxruntime",
|
|
"lib/skimage",
|
|
"lib/scipy",
|
|
# 모델 파일
|
|
"lib/src/modules/migan_traced.pt",
|
|
# Python 소스 파일
|
|
"lib/src/modules/image_processor3.py",
|
|
"lib/src/modules/image_processor4.py",
|
|
"lib/src/modules/image_worker.py",
|
|
"lib/src/modules/image_worker_manager.py",
|
|
"lib/src/modules/ocr_module.py",
|
|
"lib/src/modules/mask_module_for_paddle.py",
|
|
"lib/src/modules/text_rendering_module.py",
|
|
"lib/src/modules/postImageManager.py",
|
|
"lib/src/modules/request_inpaint.py",
|
|
"lib/src/modules/migan_module.py",
|
|
"lib/src/modules/background_removal_module.py",
|
|
"lib/src/modules/bria_background_removal_module.py",
|
|
"lib/src/modules/gemma_client.py",
|
|
# 컴파일된 파일
|
|
"lib/src/modules/image_processor3.pyc",
|
|
"lib/src/modules/image_processor4.pyc",
|
|
"lib/src/modules/image_worker.pyc",
|
|
"lib/src/modules/image_worker_manager.pyc",
|
|
"lib/src/modules/ocr_module.pyc",
|
|
"lib/src/modules/mask_module_for_paddle.pyc",
|
|
"lib/src/modules/text_rendering_module.pyc",
|
|
"lib/src/modules/postImageManager.pyc",
|
|
"lib/src/modules/request_inpaint.pyc",
|
|
"lib/src/modules/migan_module.pyc",
|
|
"lib/src/modules/background_removal_module.pyc",
|
|
"lib/src/modules/bria_background_removal_module.pyc",
|
|
"lib/src/modules/gemma_client.pyc",
|
|
]
|
|
|
|
removed_count = 0
|
|
total_size_saved = 0
|
|
|
|
# build 디렉토리 내의 모든 exe.* 디렉토리를 찾아서 정리
|
|
if os.path.exists(build_dir):
|
|
for item in os.listdir(build_dir):
|
|
if item.startswith("exe."):
|
|
exe_dir = os.path.join(build_dir, item)
|
|
|
|
for unnecessary_item in unnecessary_items:
|
|
target_path = os.path.join(exe_dir, unnecessary_item)
|
|
|
|
try:
|
|
if os.path.exists(target_path):
|
|
# 디렉토리인 경우
|
|
if os.path.isdir(target_path):
|
|
# 크기 계산
|
|
dir_size = sum(
|
|
os.path.getsize(os.path.join(dirpath, filename))
|
|
for dirpath, dirnames, filenames in os.walk(target_path)
|
|
for filename in filenames
|
|
)
|
|
total_size_saved += dir_size
|
|
|
|
shutil.rmtree(target_path)
|
|
print(f" ✓ 디렉토리 삭제: {unnecessary_item} ({dir_size / (1024*1024):.1f} MB)")
|
|
# 파일인 경우
|
|
else:
|
|
file_size = os.path.getsize(target_path)
|
|
total_size_saved += file_size
|
|
|
|
os.remove(target_path)
|
|
print(f" ✓ 파일 삭제: {unnecessary_item} ({file_size / (1024*1024):.2f} MB)")
|
|
|
|
removed_count += 1
|
|
except Exception as e:
|
|
print(f" ✗ 삭제 실패: {unnecessary_item} - {e}")
|
|
|
|
if removed_count > 0:
|
|
print(f"\n정리 완료: {removed_count}개 항목 삭제, 약 {total_size_saved / (1024*1024):.1f} MB 절약\n")
|
|
else:
|
|
print("정리할 항목이 없습니다.\n")
|
|
|
|
if __name__ == '__main__':
|
|
# Setup 설정 (cmdclass에 build_exe 추가)
|
|
setup(
|
|
name=__title__,
|
|
version=__version__,
|
|
description=__description__,
|
|
author=__author__,
|
|
author_email=__author_email__,
|
|
license=__license__,
|
|
packages=find_packages(),
|
|
install_requires=__install_requires__,
|
|
python_requires='>=3.11',
|
|
include_package_data=True,
|
|
zip_safe=False,
|
|
options={'build_exe': build_exe_options},
|
|
executables=executables,
|
|
cmdclass={
|
|
"build_exe": build_exe,
|
|
},
|
|
)
|