Skip to content

Commit d46edca

Browse files
hydropixclaude
andcommitted
Add macOS build support (Intel + Apple Silicon)
- Add PyInstaller spec file for macOS - Add build script for local macOS builds - Add GitHub Actions workflow for automated macOS releases - Builds for both Intel (x86_64) and Apple Silicon (arm64) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent b888a10 commit d46edca

File tree

3 files changed

+369
-0
lines changed

3 files changed

+369
-0
lines changed

.github/workflows/build-macos.yml

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
name: Build macOS Executable
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: write
11+
12+
jobs:
13+
build-macos:
14+
strategy:
15+
matrix:
16+
include:
17+
- os: macos-13
18+
arch: x86_64
19+
artifact_suffix: Intel
20+
- os: macos-14
21+
arch: arm64
22+
artifact_suffix: AppleSilicon
23+
24+
runs-on: ${{ matrix.os }}
25+
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v4
29+
30+
- name: Set up Python 3.11
31+
uses: actions/setup-python@v5
32+
with:
33+
python-version: '3.11'
34+
cache: 'pip'
35+
36+
- name: Install dependencies
37+
run: |
38+
python -m pip install --upgrade pip
39+
pip install -r requirements.txt
40+
pip install pyinstaller
41+
42+
- name: Build executable
43+
run: |
44+
pyinstaller --clean TranslateBook-macOS.spec
45+
46+
- name: Get executable info
47+
id: exe_info
48+
run: |
49+
SIZE_BYTES=$(stat -f%z dist/TranslateBook)
50+
SIZE_MB=$(echo "scale=2; $SIZE_BYTES / 1048576" | bc)
51+
echo "size_bytes=$SIZE_BYTES" >> $GITHUB_OUTPUT
52+
echo "size_mb=$SIZE_MB" >> $GITHUB_OUTPUT
53+
ARCH=$(file dist/TranslateBook | grep -o 'arm64\|x86_64')
54+
echo "arch=$ARCH" >> $GITHUB_OUTPUT
55+
56+
- name: Create release archive
57+
run: |
58+
# Create a release folder with the executable and readme
59+
mkdir -p release
60+
61+
# Copy executable
62+
cp dist/TranslateBook release/
63+
64+
# Make sure it's executable
65+
chmod +x release/TranslateBook
66+
67+
# Create a README for the release
68+
cat > release/README.txt << 'EOF'
69+
# TranslateBook macOS Executable
70+
71+
## Quick Start
72+
73+
1. Extract TranslateBook to a folder of your choice
74+
2. Install Ollama from https://ollama.ai (required for local LLM)
75+
3. Download a translation model: ollama pull qwen3:14b
76+
4. Open Terminal and run: ./TranslateBook
77+
5. Open your browser to http://localhost:5000
78+
79+
## First Launch - Security Authorization
80+
81+
macOS will block the app on first launch. To authorize it:
82+
83+
1. Double-click TranslateBook - macOS will show a warning
84+
2. Open System Settings > Privacy & Security
85+
3. Scroll down and click "Open Anyway" next to the TranslateBook message
86+
4. Click "Open" in the confirmation dialog
87+
88+
This only needs to be done once.
89+
90+
## Choosing the Best Model for Your Language
91+
92+
Different models perform better for different target languages!
93+
94+
See our comprehensive benchmarks to find the best model for your target language:
95+
https://github.com/hydropix/TranslateBookWithLLM/wiki
96+
97+
Benchmarks include 11 models tested across 19 languages with accuracy, fluency, and style scores.
98+
99+
## First Run
100+
101+
On first run, the application will:
102+
- Create a TranslateBook_Data folder next to the executable
103+
- Generate a default .env configuration file
104+
- Create necessary subdirectories (translated_files, checkpoints)
105+
106+
## Configuration
107+
108+
Edit TranslateBook_Data/.env to customize:
109+
- LLM provider (Ollama, OpenAI, Gemini, OpenRouter)
110+
- Model selection
111+
- API keys for cloud providers
112+
- Server port and host
113+
114+
## Usage
115+
116+
- Web UI: http://localhost:5000
117+
- Supported formats: .txt, .epub, .srt
118+
- Output files: TranslateBook_Data/translated_files/
119+
120+
## Links
121+
122+
- Full Documentation: https://github.com/hydropix/TranslateBookWithLLM
123+
- Model Benchmarks: https://github.com/hydropix/TranslateBookWithLLM/wiki
124+
- Report Issues: https://github.com/hydropix/TranslateBookWithLLM/issues
125+
- OpenRouter Models: https://openrouter.ai/models (200+ cloud models)
126+
EOF
127+
128+
# Create zip archive
129+
cd release
130+
zip -r ../TranslateBook-macOS-${{ matrix.artifact_suffix }}.zip .
131+
cd ..
132+
133+
- name: Upload artifact
134+
uses: actions/upload-artifact@v4
135+
with:
136+
name: TranslateBook-macOS-${{ matrix.artifact_suffix }}
137+
path: TranslateBook-macOS-${{ matrix.artifact_suffix }}.zip
138+
retention-days: 90
139+
140+
- name: Upload executable only
141+
uses: actions/upload-artifact@v4
142+
with:
143+
name: TranslateBook-${{ matrix.artifact_suffix }}
144+
path: dist/TranslateBook
145+
retention-days: 90
146+
147+
- name: Build summary
148+
run: |
149+
echo "### Build Complete! :rocket:" >> $GITHUB_STEP_SUMMARY
150+
echo "" >> $GITHUB_STEP_SUMMARY
151+
echo "**Platform:** macOS ${{ matrix.artifact_suffix }} (${{ matrix.arch }})" >> $GITHUB_STEP_SUMMARY
152+
echo "**Executable Size:** ${{ steps.exe_info.outputs.size_mb }} MB" >> $GITHUB_STEP_SUMMARY
153+
echo "" >> $GITHUB_STEP_SUMMARY
154+
echo "**Artifacts:**" >> $GITHUB_STEP_SUMMARY
155+
echo "- TranslateBook-macOS-${{ matrix.artifact_suffix }}.zip (executable + README)" >> $GITHUB_STEP_SUMMARY
156+
echo "- TranslateBook (standalone)" >> $GITHUB_STEP_SUMMARY
157+
158+
create-release:
159+
needs: build-macos
160+
runs-on: ubuntu-latest
161+
if: startsWith(github.ref, 'refs/tags/v')
162+
163+
steps:
164+
- name: Download all artifacts
165+
uses: actions/download-artifact@v4
166+
with:
167+
pattern: TranslateBook-macOS-*
168+
merge-multiple: false
169+
170+
- name: List downloaded files
171+
run: |
172+
ls -la
173+
find . -name "*.zip" -type f
174+
175+
- name: Create Release
176+
uses: softprops/action-gh-release@v1
177+
with:
178+
files: |
179+
TranslateBook-macOS-Intel/TranslateBook-macOS-Intel.zip
180+
TranslateBook-macOS-AppleSilicon/TranslateBook-macOS-AppleSilicon.zip
181+
body: |
182+
## macOS Executable Release
183+
184+
### Downloads
185+
- **TranslateBook-macOS-AppleSilicon.zip** - For Apple Silicon Macs (M1/M2/M3/M4)
186+
- **TranslateBook-macOS-Intel.zip** - For Intel-based Macs
187+
188+
### Installation
189+
1. Download the appropriate version for your Mac
190+
2. Extract the zip file
191+
3. Install [Ollama](https://ollama.ai) (required for local LLM)
192+
4. Open Terminal and run `./TranslateBook`
193+
5. Open http://localhost:5000 in your browser
194+
195+
### First Launch - Security Authorization
196+
macOS will block the app on first launch:
197+
1. Double-click TranslateBook - macOS shows a warning
198+
2. Open **System Settings > Privacy & Security**
199+
3. Click **"Open Anyway"** next to the TranslateBook message
200+
201+
This only needs to be done once.
202+
203+
### What's Included
204+
- Single-file macOS executable (no Python installation required)
205+
- Auto-generated configuration on first run
206+
- Support for .txt, .epub, .srt translation
207+
208+
### System Requirements
209+
- macOS 11+ (Big Sur or later)
210+
- Ollama installed for local LLM support
211+
- Or API keys for cloud providers (OpenAI, Gemini, OpenRouter)
212+
draft: false
213+
prerelease: false
214+
env:
215+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

TranslateBook-macOS.spec

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# -*- mode: python ; coding: utf-8 -*-
2+
import os
3+
import tiktoken_ext.openai_public
4+
5+
block_cipher = None
6+
7+
# Get tiktoken_ext data directory (contains pre-bundled encodings)
8+
tiktoken_ext_dir = os.path.dirname(tiktoken_ext.openai_public.__file__)
9+
10+
# Prepare datas list
11+
datas_list = [
12+
('src/web/static', 'src/web/static'),
13+
('src/web/templates', 'src/web/templates'),
14+
('src', 'src'),
15+
('.env.example', '.'),
16+
]
17+
18+
# Add tiktoken_ext if directory exists
19+
if os.path.exists(tiktoken_ext_dir):
20+
datas_list.append((tiktoken_ext_dir, 'tiktoken_ext/openai_public'))
21+
22+
a = Analysis(
23+
['launcher.py'],
24+
pathex=[],
25+
binaries=[],
26+
datas=datas_list,
27+
hiddenimports=[
28+
'flask',
29+
'flask_cors',
30+
'flask_socketio',
31+
'python_socketio',
32+
'socketio',
33+
'engineio',
34+
'engineio.async_drivers.threading',
35+
'requests',
36+
'tqdm',
37+
'httpx',
38+
'lxml',
39+
'lxml.etree',
40+
'lxml._elementpath',
41+
'dotenv',
42+
'aiofiles',
43+
'tiktoken',
44+
'tiktoken_ext',
45+
'tiktoken_ext.openai_public',
46+
'pyyaml',
47+
'jinja2',
48+
'langdetect',
49+
'PIL',
50+
'dns',
51+
'dns.resolver',
52+
],
53+
hookspath=[],
54+
hooksconfig={},
55+
runtime_hooks=[],
56+
excludes=[],
57+
cipher=block_cipher,
58+
noarchive=False,
59+
)
60+
61+
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
62+
63+
exe = EXE(
64+
pyz,
65+
a.scripts,
66+
a.binaries,
67+
a.zipfiles,
68+
a.datas,
69+
[],
70+
name='TranslateBook',
71+
debug=False,
72+
bootloader_ignore_signals=False,
73+
strip=False,
74+
upx=True,
75+
upx_exclude=[],
76+
runtime_tmpdir=None,
77+
console=True,
78+
disable_windowed_traceback=False,
79+
argv_emulation=True, # Enable for macOS compatibility
80+
target_arch=None, # Will build for current architecture (arm64 or x86_64)
81+
codesign_identity=None,
82+
entitlements_file=None,
83+
icon=None,
84+
)

build_macos.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
# ============================================
3+
# TranslateBook - Build macOS Executable
4+
# ============================================
5+
6+
echo ""
7+
echo "============================================"
8+
echo "TranslateBook - Building macOS Executable"
9+
echo "============================================"
10+
echo ""
11+
12+
# Check if virtual environment exists
13+
if [ ! -d "venv" ]; then
14+
echo "[ERROR] Virtual environment not found"
15+
echo "Please create one first:"
16+
echo " python3 -m venv venv"
17+
echo " source venv/bin/activate"
18+
echo " pip install -r requirements.txt"
19+
exit 1
20+
fi
21+
22+
# Activate virtual environment
23+
echo "[1/4] Activating virtual environment..."
24+
source venv/bin/activate
25+
26+
# Install PyInstaller if not already installed
27+
echo "[2/4] Checking PyInstaller installation..."
28+
if ! pip show pyinstaller > /dev/null 2>&1; then
29+
echo "[INFO] Installing PyInstaller..."
30+
pip install pyinstaller
31+
fi
32+
echo "[OK] PyInstaller ready"
33+
34+
# Clean previous builds
35+
echo "[3/4] Cleaning previous builds..."
36+
rm -rf dist build
37+
echo "[OK] Cleaned"
38+
39+
# Build executable
40+
echo "[4/4] Building TranslateBook..."
41+
echo "This may take 5-10 minutes..."
42+
echo ""
43+
pyinstaller --clean TranslateBook-macOS.spec
44+
45+
if [ $? -ne 0 ]; then
46+
echo ""
47+
echo "[ERROR] Build failed"
48+
exit 1
49+
fi
50+
51+
echo ""
52+
echo "============================================"
53+
echo "Build Complete!"
54+
echo "============================================"
55+
echo ""
56+
echo "Executable location: dist/TranslateBook"
57+
58+
# Get file size
59+
if [ -f "dist/TranslateBook" ]; then
60+
SIZE=$(ls -lh dist/TranslateBook | awk '{print $5}')
61+
echo "File size: $SIZE"
62+
fi
63+
64+
echo ""
65+
echo "You can now distribute this executable"
66+
echo "Users need to have Ollama installed separately"
67+
echo ""
68+
echo "To make it executable on another Mac:"
69+
echo " chmod +x TranslateBook"
70+
echo ""

0 commit comments

Comments
 (0)