docs: fix spec issues from review
This commit is contained in:
parent
ebfd751e8d
commit
82ef96ea09
|
|
@ -52,7 +52,8 @@ def _app_dir() -> str:
|
|||
return os.path.dirname(sys.executable)
|
||||
else:
|
||||
# Dev mode: use script directory (git repo root)
|
||||
return os.path.dirname(os.path.abspath(__file__ + "/../../"))
|
||||
# config.py lives at whisper_app/config.py → two levels up = repo root
|
||||
return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
```
|
||||
|
||||
Machine-local config (`config_local.json`) continues to use `%LOCALAPPDATA%\WhisperDictation` (Windows) or `~/.local/share/WhisperDictation` (Linux) — unchanged.
|
||||
|
|
@ -62,21 +63,25 @@ Machine-local config (`config_local.json`) continues to use `%LOCALAPPDATA%\Whis
|
|||
`app.py` owns a `queue.Queue[str]` and a pre-queue buffer list.
|
||||
|
||||
```python
|
||||
_log_buffer: list[str] = [] # before queue is ready
|
||||
_log_buffer: list[str] = [] # before queue is ready, capped at 500 entries
|
||||
_log_queue: queue.Queue | None = None
|
||||
_log_lock = threading.Lock()
|
||||
|
||||
def log(msg: str) -> None:
|
||||
if _log_queue is not None:
|
||||
_log_queue.put(msg)
|
||||
else:
|
||||
_log_buffer.append(msg)
|
||||
with _log_lock:
|
||||
if _log_queue is not None:
|
||||
_log_queue.put(msg)
|
||||
else:
|
||||
_log_buffer.append(msg)
|
||||
|
||||
def set_log_queue(q: queue.Queue) -> None:
|
||||
global _log_queue
|
||||
_log_queue = q
|
||||
for msg in _log_buffer:
|
||||
q.put(msg)
|
||||
_log_buffer.clear()
|
||||
with _log_lock:
|
||||
_log_queue = q
|
||||
buffered = list(_log_buffer)
|
||||
_log_buffer.clear()
|
||||
for msg in buffered: # flush outside the lock to avoid deadlock
|
||||
q.put_nowait(msg)
|
||||
```
|
||||
|
||||
All `print()` calls in all modules are replaced with `app.log()`.
|
||||
|
|
@ -106,6 +111,7 @@ Opened via tray icon left-click or "Anzeigen" menu item. Implemented in `log_win
|
|||
- Close button → `withdraw()` (does not quit the app)
|
||||
- 🗑 button → clears the text widget
|
||||
- Queue polled via `root.after(100, _poll_log_queue)`
|
||||
- The tkinter `root` (hidden) is always alive as long as the tray runs — `withdraw()` on the log window does not trigger mainloop exit. The app exits only via the tray "Beenden" menu item.
|
||||
|
||||
## Settings Window — Installation Section
|
||||
|
||||
|
|
@ -117,9 +123,10 @@ Each integration shows status ("eingerichtet" / "nicht eingerichtet") and two bu
|
|||
|---|---|---|
|
||||
| Autostart beim Login | `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` | `~/.config/autostart/whisper-dictation.desktop` |
|
||||
| Startmenü-Eintrag | `%APPDATA%\Microsoft\Windows\Start Menu\Programs\Whisper Dictation.lnk` | `~/.local/share/applications/whisper-dictation.desktop` |
|
||||
| Desktop-Verknüpfung | `%USERPROFILE%\Desktop\Whisper Dictation.lnk` | `~/Desktop/whisper-dictation.desktop` |
|
||||
| Desktop-Verknüpfung | `%USERPROFILE%\Desktop\Whisper Dictation.lnk` | XDG: `xdg-user-dir DESKTOP` (fallback: `~/Desktop`) |
|
||||
|
||||
Windows `.lnk` files are created via `pywin32` (`win32com.client.Dispatch("WScript.Shell")`).
|
||||
`import win32com` must be guarded: `if sys.platform == "win32"` — top-level import is forbidden to avoid import errors on Linux.
|
||||
|
||||
**Only available when running as a frozen binary.** In dev mode, the buttons are disabled with a tooltip "Nur im gebauten Binary verfügbar".
|
||||
|
||||
|
|
@ -141,22 +148,25 @@ a = Analysis(
|
|||
'ctranslate2',
|
||||
'faster_whisper',
|
||||
'sounddevice',
|
||||
'pynput.keyboard._win32', # Windows
|
||||
'pynput.keyboard._xorg', # Linux
|
||||
],
|
||||
datas=[
|
||||
('config.json', '.'),
|
||||
('vocabulary.json', '.'),
|
||||
'pynput.keyboard._win32', # Windows
|
||||
'pynput.keyboard._xorg', # Linux X11
|
||||
'pynput.keyboard._uinput', # Linux Wayland
|
||||
],
|
||||
datas=[], # config.json / vocabulary.json NOT bundled — see below
|
||||
)
|
||||
exe = EXE(a.pure, ..., console=False, icon='icon.ico')
|
||||
pyz = PYZ(a.pure)
|
||||
exe = EXE(pyz, a.scripts, ..., console=False, icon='icon.ico')
|
||||
coll = COLLECT(exe, a.binaries, a.datas, name='whisper-dictation')
|
||||
```
|
||||
|
||||
**config.json / vocabulary.json are NOT bundled via `datas`.**
|
||||
They are user-editable files that live next to the binary. `build.py` copies them from the repo root into `dist/whisper-dictation/` after the PyInstaller run. This is the single authoritative location in frozen mode (`os.path.dirname(sys.executable)`).
|
||||
|
||||
### `build.py`
|
||||
|
||||
1. Generates `icon.ico` from PIL
|
||||
1. Generates `icon.ico` from PIL (must run before PyInstaller — `.spec` references it)
|
||||
2. Runs PyInstaller with the `.spec` file
|
||||
3. Copies `config.json` and `vocabulary.json` into `dist/whisper-dictation/`
|
||||
3. Copies `config.json` and `vocabulary.json` into `dist/whisper-dictation/` **only if they don't already exist there** (to avoid overwriting user edits)
|
||||
|
||||
### Platform requirement
|
||||
|
||||
|
|
@ -172,6 +182,16 @@ PyInstaller cannot cross-compile. **Build must be run separately on each platfor
|
|||
|
||||
Added to `requirements-windows.txt`. Not required on Linux.
|
||||
|
||||
## UI Language
|
||||
|
||||
All UI labels are in German. "WHISPER DICTATION" in the log panel header is the product name and stays as-is. All other UI text (buttons, section headers, tooltips) is German.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- **Startup crash visibility:** With `console=False`, crashes before the tray appears produce no visible output. Implementer should wrap `main()` in a try/except that writes to a logfile (e.g., `%LOCALAPPDATA%\WhisperDictation\error.log`) as a last resort.
|
||||
- **pynput hidden imports:** Only keyboard backends are needed (`_win32`, `_xorg`, `_uinput`). No mouse backends required — hotkeys are keyboard-only.
|
||||
- **`_log_buffer` cap:** Enforce max 500 entries; if buffer exceeds cap, drop oldest entry before appending.
|
||||
|
||||
## Out of Scope
|
||||
|
||||
- Code signing / notarization
|
||||
|
|
|
|||
Loading…
Reference in New Issue