Repository navigation
Home
A Persian-first, fully right-to-left desktop studio that turns PDF and EPUB books into academic Persian — and back into English — one page or an entire book, with a quality pipeline built for long documents. Windows desktop app · PyQt6 · MIT licensed · current release v3.0.0
Kaman AI Translator is a Windows desktop application for translating whole books with a large language model. You open a PDF or EPUB, and the app translates it page by page into academic Persian (or English), handling the parts of the job that a chat window cannot: chunking long text without losing sentences, keeping terminology consistent across hundreds of pages, stripping running headers and page numbers before the model sees them, and saving every finished page so a crash or a quota stop never costs you the work.
It serves two audiences at once:
- The translator — a Persian-language, RTL interface where a person can translate a 300-page book in the background, watch the page being translated live, pause, resume, cancel, correct a page by hand, and mark it reviewed.
-
The developer — a deliberately Qt-free core (
kaman_core.py) that holds every hard part of the pipeline, so the whole thing can be tested headlessly with fake engines and no API key.
The part worth understanding before reading further: the "AI" is not a hosted service inside the app. It is a thin, replaceable engine layer — the official Google Gemini SDK, or any OpenAI-compatible endpoint (Ollama, LM Studio, llama.cpp, or a cloud aggregator). The translation strategy — chunking, context rolling, structure templates, quality control — is local, deterministic code that you can read in about 1,400 lines.
| Page | What you will find there |
|---|---|
| Architecture | The two-layer split (Qt-free core + PyQt6 UI), the single-page translation lifecycle, and why the core imports no Qt. |
| Translation Pipeline | Paragraph- and sentence-aware chunking, the rolling context tail, the JSON contract with the model, and the completeness-enforcing prompts. |
| Book Structure Templates | How the app detects each book's headings and recurring labels locally, merges an optional AI pass, and injects them into every prompt. |
| Engines and Providers | Gemini and OpenAI-compatible transports, retry and backoff, quota handling, and the structured-output fallbacks. |
| Scanned Pages and Image Translation | What happens when a page has no text layer — the 2× render, the vision prompt, and the limits of that path. |
| Job Store and Resume | The per-book JSON state file, the atomic write, the "continue or restart" decision, and the reviewed-page marks. |
| Exports and Output | The three export formats — single page as TXT, the whole book as Markdown, and a print-ready RTL HTML edition with page images. |
| User Interface | Every screen, button, and interaction, including the live page-following behaviour and the RTL conventions. |
| Settings Reference | Every configuration field, its default, where it is stored, and what changing it actually does. |
| Security and Privacy | How the API key is protected with Windows DPAPI, what the fallback means, and the app's complete network surface. |
| Testing | The offline test suite — 302 checks, no network, no API key — and what each group of them covers. |
| Build and Release | The PyInstaller command, the icon packaging detail that breaks builds, and what ships in each release. |
| Development | Repository layout, coding conventions, the RTL rules, and how to contribute a change. |
| Capability | Implementation | What it actually does |
|---|---|---|
| Bidirectional translation |
DIRECTIONS in kaman_core.py
|
Two full system prompts — English → Persian and Persian → English — with the output labels and text direction switched to match. |
| Whole-book automation |
BatchWorker in translator_app_v3.py
|
A QThread translates a page range in the background, saving each page the moment it finishes. |
| Resume vs. restart |
JobStore.missing_pages, BatchDialog
|
When saved pages exist, the dialog asks whether to continue from the first unfinished page or clear the store and start over. |
| Pause / resume / cancel | BatchWorker.pause/resume/cancel |
Pause blocks between chunks; cancel raises CancelledError and unwinds cleanly. Settings stay editable while paused, and the new key or model applies from the next page. |
| Smart chunking | split_into_chunks |
Splits on paragraph boundaries, then sentence boundaries, then words — never mid-sentence — and repacks units under a character budget. |
| Rolling context | rolling_context |
Each chunk carries the tail of the previous translation (default 700 characters) so terminology and prose flow stay consistent. |
| Book structure template |
analyze_structure, structure_prompt_block
|
Detects headings and recurring labels per book, locally and for free, and injects them into every prompt so a label is always translated the same way. |
| Running-header removal |
detect_repeated_lines, clean_page_text
|
Lines that repeat on at least a quarter of sampled pages near the top or bottom edge are dropped before the model sees them. |
| Hyphen rejoining | _page_text_flags |
MuPDF's TEXT_DEHYPHENATE flag repairs words broken across a line end. |
| Image-based translation | translate_page |
A page with no text layer is rendered at 2× and sent to the model as an image, with a prompt that asks it to read and translate. |
| Quality-control loop | review_translation |
An optional second pass compares the translation to its source and can return a corrected version. |
| JSON safety |
parse_json_response, response_to_output
|
Raw model replies are unwrapped, repaired, or accepted as plain text — the user never sees JSON in the output box. |
| Encrypted key storage |
encrypt_secret / decrypt_secret
|
The API key is encrypted with Windows DPAPI, tied to the Windows account, and never written in plain text. |
| Per-page review marks | JobStore.set_reviewed |
A "✓ بازبینی شد" checkbox records human approval per page, and the counts are shown in the status bar. |
| Three export formats |
export_page_text, export_markdown, export_html
|
One page as TXT, the whole book as Markdown, or a complete RTL HTML edition with a page image per section. |
| Fact | Value | Source |
|---|---|---|
| Current version | 3.0.0 |
APP_VERSION in kaman_core.py
|
| Core library | ~1,400 lines, Qt-free | kaman_core.py |
| UI application | ~1,800 lines | translator_app_v3.py |
| Test suite | 302 checks, all passing, fully offline | tests/test_v3.py |
| Runtime dependencies | 4 | requirements.txt |
| Repository history | 10 commits, oldest b1c004a (2026-10-10) |
git log |
| Repository created | 2026-07-04, for the v2.0.0 release | GitHub API |
| Releases |
v3.0.0 (Windows executable + source zip), v2.0.0
|
GitHub Releases |
| License | MIT | LICENSE |
kaman-ai-translator/
├── translator_app_v3.py # PyQt6 UI and QThread workers — the entry point
├── kaman_core.py # Qt-free core: config, DPAPI, prompts, chunking,
│ # structure analysis, engines, job store, exporters
├── tests/test_v3.py # 302-check offline test suite
├── icon.png / icon.ico # application icons
├── requirements.txt
├── CONTRIBUTING.md
├── README.md
└── LICENSE
- As an end user — download the Windows executable from the latest release. No Python needed.
-
As a developer — clone,
pip install -r requirements.txt, thenpython translator_app_v3.py. See Development.
Wiki pages describe the code as it stands in main. Every claim here was checked
against the source — see Testing and Development.