Десктопное приложение на PySide6. Вся база — один JSON-документ, зашифрованный AES-256-GCM под паролем (ключ через scrypt), лежит в data/vault.fmdb и раз в час уезжает в этот репозиторий. Основное: - партии с дедлайном возврата себестоимости пекарне, FIFO-разнос продаж по партиям и прогресс покрытия к сроку; - типы выбытия: розница, другу по себестоимости, съел сам, подарок, списание — съеденное вычитается из прибыли, за него платить всё равно; - долги контрагентов с частичными оплатами; - номенклатура с историей изменения цен; - журнал изменений внутри базы: git хранит непрозрачные снимки, поэтому настоящая история ведётся здесь. Синхронизация коммитит только путь базы и схлопывает часовые пуши в один коммит на день через amend + force-with-lease. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
# -*- mode: python ; coding: utf-8 -*-
|
||
"""Сборка одного exe: pyinstaller food-market.spec
|
||
|
||
Готовый food-market.exe кладётся в корень клона репозитория — рядом с папкой
|
||
data, где лежит зашифрованная база. Приложение ищет data/vault.fmdb
|
||
относительно самого exe (см. app/paths.py).
|
||
"""
|
||
|
||
# Qt тянет за собой много того, что этому приложению не нужно. Без чистки
|
||
# onefile раздувается до ~150 МБ, с ней укладывается примерно вдвое меньше.
|
||
EXCLUDES = [
|
||
"PySide6.QtWebEngineCore",
|
||
"PySide6.QtWebEngineWidgets",
|
||
"PySide6.QtWebEngineQuick",
|
||
"PySide6.QtQuick",
|
||
"PySide6.QtQuick3D",
|
||
"PySide6.QtQuickWidgets",
|
||
"PySide6.QtQml",
|
||
"PySide6.Qt3DCore",
|
||
"PySide6.Qt3DRender",
|
||
"PySide6.Qt3DInput",
|
||
"PySide6.Qt3DLogic",
|
||
"PySide6.Qt3DAnimation",
|
||
"PySide6.Qt3DExtras",
|
||
"PySide6.QtMultimedia",
|
||
"PySide6.QtMultimediaWidgets",
|
||
"PySide6.QtCharts",
|
||
"PySide6.QtDataVisualization",
|
||
"PySide6.QtBluetooth",
|
||
"PySide6.QtNfc",
|
||
"PySide6.QtPositioning",
|
||
"PySide6.QtSerialPort",
|
||
"PySide6.QtSensors",
|
||
"PySide6.QtTest",
|
||
"PySide6.QtSql",
|
||
"PySide6.QtDesigner",
|
||
"PySide6.QtHelp",
|
||
"PySide6.QtUiTools",
|
||
"PySide6.QtPdf",
|
||
"PySide6.QtPdfWidgets",
|
||
"PySide6.QtSpatialAudio",
|
||
"PySide6.QtTextToSpeech",
|
||
"PySide6.QtWebChannel",
|
||
"PySide6.QtWebSockets",
|
||
# Не наши зависимости — если утащатся транзитом, только раздуют файл.
|
||
"tkinter",
|
||
"unittest",
|
||
"pydoc",
|
||
"pytest",
|
||
"numpy",
|
||
"matplotlib",
|
||
"PIL",
|
||
]
|
||
|
||
a = Analysis(
|
||
["run.py"],
|
||
pathex=[],
|
||
binaries=[],
|
||
datas=[],
|
||
hiddenimports=[],
|
||
hookspath=[],
|
||
runtime_hooks=[],
|
||
excludes=EXCLUDES,
|
||
noarchive=False,
|
||
)
|
||
|
||
pyz = PYZ(a.pure)
|
||
|
||
exe = EXE(
|
||
pyz,
|
||
a.scripts,
|
||
a.binaries,
|
||
a.datas,
|
||
[],
|
||
name="food-market",
|
||
debug=False,
|
||
bootloader_ignore_signals=False,
|
||
strip=False,
|
||
# UPX выключен намеренно: сжатые им exe регулярно ловят ложные
|
||
# срабатывания антивирусов, а выигрыш в размере того не стоит.
|
||
upx=False,
|
||
runtime_tmpdir=None,
|
||
console=False,
|
||
disable_windowed_traceback=False,
|
||
argv_emulation=False,
|
||
target_arch=None,
|
||
codesign_identity=None,
|
||
entitlements_file=None,
|
||
)
|