多用户系统 + Admin 角色权限 + Web/TUI 同步 + 构建集成

本轮实现功能:
1. 多用户隔离:每个用户独立 config.json + graph.db
2. TUI 登录页 + 旧版自动迁移(core/migrate.py)
3. Admin/User 角色体系(core/embedded_db.py)
4. Web 后台管理 API(userinfo + admin CRUD)
5. Web 设置页用户管理区(仅 admin 可见)
6. TUI 侧栏配置区权限同步(非 admin 隐藏 Web 服务设置)
7. Web 服务打包为独立二进制(trulymem-web)
8. 双入口 PyInstaller 构建脚本(TUI + Web)
9. 活动记录器(core/activity_recorder.py)
10. 静态页面模板(登录/设置/首次引导)
This commit is contained in:
root
2026-04-28 10:37:57 +08:00
parent 46008c14c5
commit b4456a9c5b
22 changed files with 5488 additions and 183 deletions

View File

@ -12,7 +12,9 @@ APPDIR="$PROJECT_ROOT/TrulyMEM.AppDir"
rm -rf "$APPDIR"
mkdir -p "$APPDIR/usr/bin"
mkdir -p "$APPDIR/usr/share/trulymem"
echo "===== Step 1: Build binary with PyInstaller ====="
mkdir -p "$APPDIR/usr/share/trulymem-web"
echo "===== Step 1: Build binaries with PyInstaller ====="
VENV_DIR="$PROJECT_ROOT/.venv_appimage"
rm -rf "$VENV_DIR"
python3 -m venv "$VENV_DIR"
@ -21,16 +23,33 @@ pip install --upgrade pip
pip install -r requirements.txt
pip install pyinstaller
rm -rf "$PROJECT_ROOT/build/pyinstaller_build" "$PROJECT_ROOT/dist"
echo "Running PyInstaller..."
CORE_HIDDEN=(
--hidden-import core
--hidden-import core.embedded_db
--hidden-import core.graph_client
--hidden-import core.tool_executor
--hidden-import core.tool_limiter
--hidden-import core.tools
--hidden-import core.tools.memory_tools
--hidden-import core.prompts
--hidden-import core.prompts.prompt_manager
--hidden-import core.server
--hidden-import core.client
--hidden-import core.migrate
--hidden-import core.activity_recorder
)
echo "Running PyInstaller for TUI..."
pyinstaller trulymem_entry.py \
--clean \
--onefile \
--console \
--name TrulyMEM \
--clean --onefile --console --name TrulyMEM \
--distpath "$PROJECT_ROOT/dist" \
--workpath "$PROJECT_ROOT/build/pyinstaller_build" \
--workpath "$PROJECT_ROOT/build/pyinstaller_build/tui" \
--add-data "ui/styles:ui/styles" \
--add-data "core/prompts/templates:core/prompts/templates" \
--add-data "static:static" \
--add-data "templates:templates" \
--add-data "web_api.py:." \
--hidden-import textual \
--hidden-import textual.app \
--hidden-import textual.widgets \
@ -39,17 +58,10 @@ pyinstaller trulymem_entry.py \
--hidden-import openai._client \
--hidden-import neo4j \
--hidden-import sqlite3 \
--hidden-import core \
--hidden-import core.embedded_db \
--hidden-import core.graph_client \
--hidden-import core.tool_executor \
--hidden-import core.tool_limiter \
--hidden-import core.tools \
--hidden-import core.tools.memory_tools \
--hidden-import core.prompts \
--hidden-import core.prompts.prompt_manager \
"${CORE_HIDDEN[@]}" \
--hidden-import ui \
--hidden-import ui.app \
--hidden-import ui.login_screen \
--hidden-import ui.models \
--hidden-import ui.models.message \
--hidden-import ui.models.config \
@ -59,10 +71,28 @@ pyinstaller trulymem_entry.py \
--hidden-import ui.services \
--hidden-import ui.services.config_manager \
--hidden-import ui.services.config_service \
--hidden-import web_api \
--hidden-import flask \
--hidden-import flask_cors \
--collect-all textual \
--noconfirm
echo "Running PyInstaller for Web..."
pyinstaller web_api.py \
--clean --onefile --console --name trulymem-web \
--distpath "$PROJECT_ROOT/dist" \
--workpath "$PROJECT_ROOT/build/pyinstaller_build/web" \
--add-data "templates:templates" \
--add-data "static:static" \
--hidden-import flask \
--hidden-import flask_cors \
"${CORE_HIDDEN[@]}" \
--noconfirm
cp "$PROJECT_ROOT/dist/TrulyMEM" "$APPDIR/usr/bin/"
cp "$PROJECT_ROOT/dist/trulymem-web" "$APPDIR/usr/bin/"
cp "$PROJECT_ROOT/trulymem_entry.py" "$APPDIR/usr/share/trulymem/"
echo "===== Step 2: Create AppImage structure ====="
cat > "$APPDIR/AppRun" << 'EOF'
#!/bin/bash
@ -73,6 +103,7 @@ export PATH="$APPDIR/usr/bin:$PATH"
exec "$APPDIR/usr/bin/TrulyMEM" "$@"
EOF
chmod +x "$APPDIR/AppRun"
cat > "$APPDIR/trulymem.desktop" << 'EOF'
[Desktop Entry]
Name=TrulyMEM
@ -83,7 +114,8 @@ Terminal=true
Type=Application
Categories=Utility;X-AI;
EOF
# Copy icon file (try multiple possible locations)
# Copy icon
if [ -f "$PROJECT_ROOT/pic/TrulyMEM.png" ]; then
cp "$PROJECT_ROOT/pic/TrulyMEM.png" "$APPDIR/trulymem.png"
elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_256x256.png" ]; then
@ -91,13 +123,12 @@ elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_256x256.png" ]; then
elif [ -f "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_128x128.png" ]; then
cp "$PROJECT_ROOT/pic/TrulyMEM.iconset/icon_128x128.png" "$APPDIR/trulymem.png"
else
echo "Warning: No icon file found, creating placeholder"
# Create a simple placeholder icon
convert -size 256x256 xc:blue "$APPDIR/trulymem.png" 2>/dev/null || \
echo "Note: Install ImageMagick to generate placeholder icon"
echo "Warning: No icon file found"
fi
APPIMAGE="$PROJECT_ROOT/TrulyMEM.AppImage"
rm -f "$APPIMAGE"
echo "===== Step 3: Package as AppImage ====="
cd /tmp
if ! command -v appimagetool &> /dev/null; then
@ -108,30 +139,23 @@ if ! command -v appimagetool &> /dev/null; then
fi
cd "$PROJECT_ROOT"
if [ -x /tmp/appimagetool ]; then
/tmp/appimagetool "$APPDIR" "$APPIMAGE" || {
echo "appimagetool failed, keeping AppDir for manual packaging"
}
/tmp/appimagetool "$APPDIR" "$APPIMAGE" || echo "appimagetool failed, keeping AppDir"
elif command -v appimagetool &> /dev/null; then
appimagetool "$APPDIR" "$APPIMAGE"
else
echo "Warning: appimagetool not available"
echo "AppDir created at: $APPDIR"
echo "You can manually run: appimagetool $APPDIR $APPIMAGE"
echo "Warning: appimagetool not available, AppDir at: $APPDIR"
fi
echo "===== Build Complete ====="
[ -f "$APPIMAGE" ] && echo "AppImage: $APPIMAGE" && ls -la "$APPIMAGE"
[ -d "$APPDIR" ] && echo "AppDir: $APPDIR (can be packaged manually with appimagetool)"
echo "===== Cleaning up build artifacts ====="
[ -d "$APPDIR" ] && echo "AppDir: $APPDIR"
echo "===== Cleanup ====="
deactivate
rm -rf "$VENV_DIR"
rm -rf "$PROJECT_ROOT/build/pyinstaller_build"
rm -rf "$PROJECT_ROOT/build/pyinstaller_build"
rm -f /tmp/appimagetool
# Only remove AppDir if AppImage was successfully created
if [ -f "$APPIMAGE" ]; then
echo "Removing AppDir since AppImage was created successfully"
rm -rf "$APPDIR"
else
echo "Keeping AppDir for manual packaging"
fi
echo "Done!"
echo "Done!"

View File

@ -6,40 +6,49 @@ echo "===== Building TrulyMEM for Linux ====="
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"
echo "Project root: $PROJECT_ROOT"
if ! command -v python3 &> /dev/null; then
echo "Error: python3 not found"
exit 1
echo "Error: python3 not found"; exit 1
fi
# 创建并激活虚拟环境
VENV_DIR="$PROJECT_ROOT/.venv_build"
echo "Creating virtual environment: $VENV_DIR"
python3 -m venv "$VENV_DIR"
echo "Activating virtual environment..."
source "$VENV_DIR/bin/activate"
echo "Upgrading pip in virtual environment..."
pip install --upgrade pip
echo "Installing dependencies in virtual environment..."
pip install -r requirements.txt
echo "Cleaning previous builds..."
rm -rf build/dist build/__pycache__ 2>/dev/null || true
echo "Running PyInstaller..."
# 共用 hidden imports(TUI + Web 都需要的核心库)
CORE_HIDDEN=(
--hidden-import core
--hidden-import core.embedded_db
--hidden-import core.graph_client
--hidden-import core.tool_executor
--hidden-import core.tool_limiter
--hidden-import core.tools
--hidden-import core.tools.memory_tools
--hidden-import core.prompts
--hidden-import core.prompts.prompt_manager
--hidden-import core.server
--hidden-import core.client
--hidden-import core.migrate
--hidden-import core.activity_recorder
)
echo "================================"
echo "1️⃣ Build TUI: TrulyMEM"
echo "================================"
python -m PyInstaller trulymem_entry.py \
--clean \
--onefile \
--console \
--name TrulyMEM \
--clean --onefile --console --name TrulyMEM \
--add-data "ui/styles:ui/styles" \
--add-data "core/prompts/templates:core/prompts/templates" \
--add-data "static:static" \
--add-data "templates:templates" \
--add-data "web_api.py:." \
--hidden-import textual \
--hidden-import textual.app \
--hidden-import textual.widgets \
@ -48,17 +57,10 @@ python -m PyInstaller trulymem_entry.py \
--hidden-import openai._client \
--hidden-import neo4j \
--hidden-import sqlite3 \
--hidden-import core \
--hidden-import core.embedded_db \
--hidden-import core.graph_client \
--hidden-import core.tool_executor \
--hidden-import core.tool_limiter \
--hidden-import core.tools \
--hidden-import core.tools.memory_tools \
--hidden-import core.prompts \
--hidden-import core.prompts.prompt_manager \
"${CORE_HIDDEN[@]}" \
--hidden-import ui \
--hidden-import ui.app \
--hidden-import ui.login_screen \
--hidden-import ui.models \
--hidden-import ui.models.message \
--hidden-import ui.models.config \
@ -68,16 +70,30 @@ python -m PyInstaller trulymem_entry.py \
--hidden-import ui.services \
--hidden-import ui.services.config_manager \
--hidden-import ui.services.config_service \
--hidden-import web_api \
--hidden-import flask \
--hidden-import flask_cors \
--collect-all textual \
--noconfirm
echo "================================"
echo "2️⃣ Build Web: trulymem-web"
echo "================================"
python -m PyInstaller web_api.py \
--clean --onefile --console --name trulymem-web \
--add-data "templates:templates" \
--add-data "static:static" \
--hidden-import flask \
--hidden-import flask_cors \
"${CORE_HIDDEN[@]}" \
--noconfirm
echo "================================"
echo "===== Build Complete ====="
echo "Binary: dist/TrulyMEM"
echo "Binary: dist/trulymem-web"
ls -la dist/
# 清理虚拟环境
echo "Cleaning up virtual environment..."
deactivate
rm -rf "$VENV_DIR"
echo "Build finished successfully!"
echo "Build finished successfully!"

View File

@ -6,30 +6,20 @@ echo "===== Building TrulyMEM for macOS ====="
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"
echo "Project root: $PROJECT_ROOT"
if ! command -v python3 &> /dev/null; then
echo "Error: python3 not found"
exit 1
echo "Error: python3 not found"; exit 1
fi
# 创建并激活虚拟环境
VENV_DIR="$PROJECT_ROOT/.venv_build"
echo "Creating virtual environment: $VENV_DIR"
python3 -m venv "$VENV_DIR"
echo "Activating virtual environment..."
source "$VENV_DIR/bin/activate"
echo "Upgrading pip in virtual environment..."
pip install --upgrade pip
echo "Installing dependencies in virtual environment..."
pip install -r requirements.txt
echo "Generating ICNS icon..."
# 生成图标
if [ -d "pic/TrulyMEM.iconset" ]; then
iconutil -c icns pic/TrulyMEM.iconset -o pic/TrulyMEM.icns
echo "ICNS icon generated: pic/TrulyMEM.icns"
@ -38,15 +28,33 @@ fi
echo "Cleaning previous builds..."
rm -rf build/dist build/__pycache__ 2>/dev/null || true
echo "Running PyInstaller..."
CORE_HIDDEN=(
--hidden-import core
--hidden-import core.embedded_db
--hidden-import core.graph_client
--hidden-import core.tool_executor
--hidden-import core.tool_limiter
--hidden-import core.tools
--hidden-import core.tools.memory_tools
--hidden-import core.prompts
--hidden-import core.prompts.prompt_manager
--hidden-import core.server
--hidden-import core.client
--hidden-import core.migrate
--hidden-import core.activity_recorder
)
echo "================================"
echo "1️⃣ Build TUI: TrulyMEM"
echo "================================"
python -m PyInstaller trulymem_entry.py \
--clean \
--onefile \
--console \
--name TrulyMEM \
--clean --onefile --console --name TrulyMEM \
--icon "pic/TrulyMEM.icns" \
--add-data "ui/styles:ui/styles" \
--add-data "core/prompts/templates:core/prompts/templates" \
--add-data "static:static" \
--add-data "templates:templates" \
--add-data "web_api.py:." \
--hidden-import textual \
--hidden-import textual.app \
--hidden-import textual.widgets \
@ -55,17 +63,10 @@ python -m PyInstaller trulymem_entry.py \
--hidden-import openai._client \
--hidden-import neo4j \
--hidden-import sqlite3 \
--hidden-import core \
--hidden-import core.embedded_db \
--hidden-import core.graph_client \
--hidden-import core.tool_executor \
--hidden-import core.tool_limiter \
--hidden-import core.tools \
--hidden-import core.tools.memory_tools \
--hidden-import core.prompts \
--hidden-import core.prompts.prompt_manager \
"${CORE_HIDDEN[@]}" \
--hidden-import ui \
--hidden-import ui.app \
--hidden-import ui.login_screen \
--hidden-import ui.models \
--hidden-import ui.models.message \
--hidden-import ui.models.config \
@ -75,16 +76,30 @@ python -m PyInstaller trulymem_entry.py \
--hidden-import ui.services \
--hidden-import ui.services.config_manager \
--hidden-import ui.services.config_service \
--hidden-import web_api \
--hidden-import flask \
--hidden-import flask_cors \
--collect-all textual \
--noconfirm
echo "================================"
echo "2️⃣ Build Web: trulymem-web"
echo "================================"
python -m PyInstaller web_api.py \
--clean --onefile --console --name trulymem-web \
--add-data "templates:templates" \
--add-data "static:static" \
--hidden-import flask \
--hidden-import flask_cors \
"${CORE_HIDDEN[@]}" \
--noconfirm
echo "================================"
echo "===== Build Complete ====="
echo "Binary: dist/TrulyMEM"
echo "Binary: dist/trulymem-web"
ls -la dist/
# 清理虚拟环境
echo "Cleaning up virtual environment..."
deactivate
rm -rf "$VENV_DIR"
echo "Build finished successfully!"
echo "Build finished successfully!"

View File

@ -1,28 +1,56 @@
@echo off
echo ===== Building TrulyMEM for Windows =====
#!/bin/bash
set -e
REM 切换到脚本所在目录的上一级目录(项目根目录)
cd /d "%~dp0.."
echo Project root: %CD%
echo "===== Building TrulyMEM for Windows ====="
python --version >nul 2>&1
if errorlevel 1 (
echo Error: python not found
exit /b 1
)
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
cd "$PROJECT_ROOT"
echo "Project root: $PROJECT_ROOT"
echo Installing dependencies...
if ! command -v python &> /dev/null; then
echo "Error: python not found"
exit 1
fi
VENV_DIR="$PROJECT_ROOT\.venv_build"
echo "Creating virtual environment: %VENV_DIR%"
python -m venv "%VENV_DIR%"
call "%VENV_DIR%\Scripts\activate.bat"
pip install --upgrade pip
pip install -r requirements.txt
echo Running PyInstaller...
echo "Cleaning previous builds..."
rmdir /s /q "build\dist" 2>nul
rmdir /s /q "build\__pycache__" 2>nul
del /f /q "TrulyMEM.spec" 2>nul
CORE_HIDDEN=(
--hidden-import core
--hidden-import core.embedded_db
--hidden-import core.graph_client
--hidden-import core.tool_executor
--hidden-import core.tool_limiter
--hidden-import core.tools
--hidden-import core.tools.memory_tools
--hidden-import core.prompts
--hidden-import core.prompts.prompt_manager
--hidden-import core.server
--hidden-import core.client
--hidden-import core.migrate
--hidden-import core.activity_recorder
)
echo "================================"
echo "1. Build TUI: TrulyMEM.exe"
echo "================================"
python -m PyInstaller trulymem_entry.py ^
--clean ^
--onefile ^
--console ^
--name TrulyMEM ^
--icon "pic/TrulyMEM.ico" ^
--clean --onefile --console --name TrulyMEM ^
--add-data "ui/styles;ui/styles" ^
--add-data "core/prompts/templates;core/prompts/templates" ^
--add-data "static;static" ^
--add-data "templates;templates" ^
--add-data "web_api.py;." ^
--hidden-import textual ^
--hidden-import textual.app ^
--hidden-import textual.widgets ^
@ -31,17 +59,10 @@ python -m PyInstaller trulymem_entry.py ^
--hidden-import openai._client ^
--hidden-import neo4j ^
--hidden-import sqlite3 ^
--hidden-import core ^
--hidden-import core.embedded_db ^
--hidden-import core.graph_client ^
--hidden-import core.tool_executor ^
--hidden-import core.tool_limiter ^
--hidden-import core.tools ^
--hidden-import core.tools.memory_tools ^
--hidden-import core.prompts ^
--hidden-import core.prompts.prompt_manager ^
%CORE_HIDDEN% ^
--hidden-import ui ^
--hidden-import ui.app ^
--hidden-import ui.login_screen ^
--hidden-import ui.models ^
--hidden-import ui.models.message ^
--hidden-import ui.models.config ^
@ -51,10 +72,27 @@ python -m PyInstaller trulymem_entry.py ^
--hidden-import ui.services ^
--hidden-import ui.services.config_manager ^
--hidden-import ui.services.config_service ^
--hidden-import web_api ^
--hidden-import flask ^
--hidden-import flask_cors ^
--collect-all textual ^
--noconfirm
echo ===== Build Complete =====
echo Binary: dist\TrulyMEM.exe
dir dist\TrulyMEM.exe
pause
echo "================================"
echo "2. Build Web: trulymem-web.exe"
echo "================================"
python -m PyInstaller web_api.py ^
--clean --onefile --console --name trulymem-web ^
--add-data "templates;templates" ^
--add-data "static;static" ^
--hidden-import flask ^
--hidden-import flask_cors ^
%CORE_HIDDEN% ^
--noconfirm
echo "===== Build Complete ====="
echo "Output: dist/TrulyMEM.exe, dist/trulymem-web.exe"
deactivate
rmdir /s /q "%VENV_DIR%"
echo "Build finished successfully!"

View File

@ -8,6 +8,7 @@ project_root = os.path.dirname(os.path.abspath(SPEC))
sys.path.insert(0, project_root)
datas = []
# UI 样式
if os.path.exists(os.path.join(project_root, 'ui', 'styles')):
for root, dirs, files in os.walk(os.path.join(project_root, 'ui', 'styles')):
for f in files:
@ -15,6 +16,7 @@ if os.path.exists(os.path.join(project_root, 'ui', 'styles')):
dst = os.path.join('ui', 'styles', os.path.relpath(src, os.path.join(project_root, 'ui', 'styles')))
datas.append((src, dst))
# Prompt 模板
if os.path.exists(os.path.join(project_root, 'core', 'prompts', 'templates')):
for root, dirs, files in os.walk(os.path.join(project_root, 'core', 'prompts', 'templates')):
for f in files:
@ -22,45 +24,52 @@ if os.path.exists(os.path.join(project_root, 'core', 'prompts', 'templates')):
dst = os.path.join('core', 'prompts', 'templates', os.path.relpath(src, os.path.join(project_root, 'core', 'prompts', 'templates')))
datas.append((src, dst))
# Web 静态文件
if os.path.exists(os.path.join(project_root, 'static')):
for root, dirs, files in os.walk(os.path.join(project_root, 'static')):
for f in files:
src = os.path.join(root, f)
dst = os.path.join('static', os.path.relpath(src, os.path.join(project_root, 'static')))
datas.append((src, dst))
# Web 模板
if os.path.exists(os.path.join(project_root, 'templates')):
for root, dirs, files in os.walk(os.path.join(project_root, 'templates')):
for f in files:
src = os.path.join(root, f)
dst = os.path.join('templates', os.path.relpath(src, os.path.join(project_root, 'templates')))
datas.append((src, dst))
# Web API 脚本(以便子进程模式回退使用)
web_api_src = os.path.join(project_root, 'web_api.py')
if os.path.exists(web_api_src):
datas.append((web_api_src, '.'))
# ——— TUI 主二进制 ———
a = Analysis(
['trulymem_entry.py'],
pathex=[],
pathex=[project_root],
binaries=[],
datas=datas,
hiddenimports=[
'textual',
'textual.app',
'textual.widgets',
'textual.css',
'openai',
'openai._client',
'textual', 'textual.app', 'textual.widgets', 'textual.css',
'openai', 'openai._client',
'neo4j',
'sqlite3',
'graph_memory_tui',
'core',
'core.embedded_db',
'core.graph_client',
'core.tool_executor',
'core.tool_limiter',
'core.tools',
'core.tools.memory_tools',
'core.prompts',
'core.prompts.prompt_manager',
'ui',
'ui.app',
'ui.models',
'ui.models.message',
'ui.models.config',
'ui.models.log_entry',
'ui.widgets',
'ui.widgets.left_panel',
'ui.widgets.right_panel',
'ui.widgets.input_box',
'ui.widgets.message_history',
'ui.widgets.status_bar',
'core', 'core.embedded_db', 'core.graph_client',
'core.tool_executor', 'core.tool_limiter',
'core.tools', 'core.tools.memory_tools',
'core.prompts', 'core.prompts.prompt_manager',
'core.server', 'core.client',
'core.migrate',
'ui', 'ui.app', 'ui.login_screen',
'ui.models', 'ui.models.message', 'ui.models.config', 'ui.models.log_entry',
'ui.widgets', 'ui.widgets.left_panel', 'ui.widgets.right_panel',
'ui.widgets.input_box', 'ui.widgets.message_history', 'ui.widgets.status_bar',
'ui.handlers',
'ui.services',
'ui.services.config_manager',
'ui.services', 'ui.services.config_manager', 'ui.services.config_service',
'web_api',
'flask', 'flask_cors',
],
hookspath=[],
hooksconfig={},
@ -89,4 +98,48 @@ exe = EXE(
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)
)
# ——— Web 服务二进制(trulymem-web)———
web_a = Analysis(
['web_api.py'],
pathex=[project_root],
binaries=[],
datas=[
(os.path.join(project_root, 'templates'), 'templates'),
(os.path.join(project_root, 'static'), 'static'),
],
hiddenimports=[
'flask', 'flask_cors',
'core', 'core.server', 'core.client',
'core.embedded_db', 'core.activity_recorder',
'core.migrate',
],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
noarchive=False,
optimize=0,
)
web_pyz = PYZ(web_a.pure, block_cipher)
web_exe = EXE(
web_pyz,
web_a.scripts,
web_a.binaries,
web_a.datas,
[],
name='trulymem-web',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
)