dictz 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dictz-0.0.2/CHANGELOG.md +36 -0
- dictz-0.0.2/LICENSE +55 -0
- dictz-0.0.2/MANIFEST.in +6 -0
- dictz-0.0.2/PKG-INFO +212 -0
- dictz-0.0.2/README.md +156 -0
- dictz-0.0.2/dictz/__init__.py +2 -0
- dictz-0.0.2/dictz/__main__.py +5 -0
- dictz-0.0.2/dictz/app.py +65 -0
- dictz-0.0.2/dictz/core/__init__.py +0 -0
- dictz-0.0.2/dictz/core/query_manager.py +126 -0
- dictz-0.0.2/dictz/parsers/__init__.py +0 -0
- dictz-0.0.2/dictz/parsers/babylon.py +16 -0
- dictz-0.0.2/dictz/parsers/base.py +104 -0
- dictz-0.0.2/dictz/parsers/dsl.py +20 -0
- dictz-0.0.2/dictz/parsers/pyglossary_base.py +171 -0
- dictz-0.0.2/dictz/parsers/stardict.py +190 -0
- dictz-0.0.2/dictz/services/__init__.py +0 -0
- dictz-0.0.2/dictz/storage/__init__.py +0 -0
- dictz-0.0.2/dictz/storage/indexer.py +183 -0
- dictz-0.0.2/dictz/ui/__init__.py +0 -0
- dictz-0.0.2/dictz/ui/main_window.py +306 -0
- dictz-0.0.2/dictz.egg-info/PKG-INFO +212 -0
- dictz-0.0.2/dictz.egg-info/SOURCES.txt +31 -0
- dictz-0.0.2/dictz.egg-info/dependency_links.txt +1 -0
- dictz-0.0.2/dictz.egg-info/entry_points.txt +2 -0
- dictz-0.0.2/dictz.egg-info/requires.txt +24 -0
- dictz-0.0.2/dictz.egg-info/top_level.txt +1 -0
- dictz-0.0.2/pyproject.toml +96 -0
- dictz-0.0.2/setup.cfg +4 -0
- dictz-0.0.2/tests/test_dsl.py +69 -0
- dictz-0.0.2/tests/test_indexer.py +100 -0
- dictz-0.0.2/tests/test_parser_registry.py +39 -0
- dictz-0.0.2/tests/test_stardict.py +125 -0
dictz-0.0.2/CHANGELOG.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to dictz are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.0.2] — 2026-11-13
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- **DSL (ABBYY Lingvo) format support** via PyGlossary — reads `.dsl` and `.dsl.dz` files
|
|
12
|
+
- **Babylon format support** via PyGlossary — reads `.bgl` binary dictionaries
|
|
13
|
+
- `PyGlossaryDictionary` generic base parser (shared code between PyGlossary-backed formats)
|
|
14
|
+
- Parser-registry dispatch handles `.dz`-compressed variants automatically
|
|
15
|
+
- `supported_extensions()` helper for UI file-dialog filters
|
|
16
|
+
- Test suite for the DSL parser and parser dispatcher
|
|
17
|
+
- `CHANGELOG.md` and `LICENSE` added to the repo
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
- `pyglossary` moved from optional to required dependency
|
|
21
|
+
- File-open dialog filter now lists StarDict, DSL and Babylon separately
|
|
22
|
+
- About-box version bumped to 0.0.2 and format list expanded
|
|
23
|
+
- README rewritten for multi-platform publication (PyPI, GitHub) with badges and install instructions
|
|
24
|
+
- PyPI classifiers expanded: Windows / Linux / macOS, Turkish and English natural languages
|
|
25
|
+
|
|
26
|
+
## [0.0.1] — 2026-11-12
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
- Project bootstrap (4-layer architecture: UI, core, parsers, storage)
|
|
30
|
+
- Native StarDict parser (no external dependency) — reads `.ifo`, `.idx`, `.dict` and `.dict.dz`
|
|
31
|
+
- SQLite FTS5 central index with `unicode61 remove_diacritics 2` tokenizer
|
|
32
|
+
- `QueryManager` orchestrates lookups across multiple loaded dictionaries
|
|
33
|
+
- PySide6 three-pane UI: search box, suggestion list, definition view
|
|
34
|
+
- Debounced incremental search (150 ms)
|
|
35
|
+
- Cross-platform per-user data directory (Windows / macOS / Linux)
|
|
36
|
+
- Test suite for the StarDict parser and index store (11 tests)
|
dictz-0.0.2/LICENSE
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 29 June 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
5
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
6
|
+
of this license document, but changing it is not allowed.
|
|
7
|
+
|
|
8
|
+
Preamble
|
|
9
|
+
|
|
10
|
+
The GNU General Public License is a free, copyleft license for
|
|
11
|
+
software and other kinds of works.
|
|
12
|
+
|
|
13
|
+
The licenses for most software and other practical works are designed
|
|
14
|
+
to take away your freedom to share and change the works. By contrast,
|
|
15
|
+
the GNU General Public License is intended to guarantee your freedom to
|
|
16
|
+
share and change all versions of a program--to make sure it remains free
|
|
17
|
+
software for all its users. We, the Free Software Foundation, use the
|
|
18
|
+
GNU General Public License for most of our software; it applies also to
|
|
19
|
+
any other work released this way by its authors. You can apply it to
|
|
20
|
+
your programs, too.
|
|
21
|
+
|
|
22
|
+
When we speak of free software, we are referring to freedom, not
|
|
23
|
+
price. Our General Public Licenses are designed to make sure that you
|
|
24
|
+
have the freedom to distribute copies of free software (and charge for
|
|
25
|
+
them if you wish), that you receive source code or can get it if you
|
|
26
|
+
want it, that you can change the software or use pieces of it in new
|
|
27
|
+
free programs, and that you know you can do these things.
|
|
28
|
+
|
|
29
|
+
To protect your rights, we need to prevent others from denying you
|
|
30
|
+
these rights or asking you to surrender the rights. Therefore, you have
|
|
31
|
+
certain responsibilities if you distribute copies of the software, or if
|
|
32
|
+
you modify it: responsibilities to respect the freedom of others.
|
|
33
|
+
|
|
34
|
+
The complete terms of the GNU General Public License version 3 are
|
|
35
|
+
available at <https://www.gnu.org/licenses/gpl-3.0.html>.
|
|
36
|
+
|
|
37
|
+
END OF TERMS AND CONDITIONS
|
|
38
|
+
|
|
39
|
+
How to Apply These Terms to Your New Programs
|
|
40
|
+
|
|
41
|
+
dictz — cross-platform multi-format offline dictionary application
|
|
42
|
+
Copyright (C) 2026 Bayram Kotan
|
|
43
|
+
|
|
44
|
+
This program is free software: you can redistribute it and/or modify
|
|
45
|
+
it under the terms of the GNU General Public License as published by
|
|
46
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
47
|
+
(at your option) any later version.
|
|
48
|
+
|
|
49
|
+
This program is distributed in the hope that it will be useful,
|
|
50
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
51
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
52
|
+
GNU General Public License for more details.
|
|
53
|
+
|
|
54
|
+
You should have received a copy of the GNU General Public License
|
|
55
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
dictz-0.0.2/MANIFEST.in
ADDED
dictz-0.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dictz
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: dictz — a cross-platform multi-format offline dictionary application (GoldenDict-style)
|
|
5
|
+
Author-email: Bayram Kotan <bayramkotan@gmail.com>
|
|
6
|
+
Maintainer-email: Bayram Kotan <bayramkotan@gmail.com>
|
|
7
|
+
License: GPL-3.0-or-later
|
|
8
|
+
Project-URL: Homepage, https://github.com/bayramkotan/dictz
|
|
9
|
+
Project-URL: Repository, https://github.com/bayramkotan/dictz
|
|
10
|
+
Project-URL: Issues, https://github.com/bayramkotan/dictz/issues
|
|
11
|
+
Project-URL: Documentation, https://github.com/bayramkotan/dictz#readme
|
|
12
|
+
Project-URL: Changelog, https://github.com/bayramkotan/dictz/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: dictionary,stardict,dsl,babylon,goldendict,offline,lexicography,translation,pyside6,qt
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Environment :: X11 Applications :: Qt
|
|
16
|
+
Classifier: Environment :: Win32 (MS Windows)
|
|
17
|
+
Classifier: Environment :: MacOS X
|
|
18
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
19
|
+
Classifier: Intended Audience :: Education
|
|
20
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
21
|
+
Classifier: Natural Language :: English
|
|
22
|
+
Classifier: Natural Language :: Turkish
|
|
23
|
+
Classifier: Operating System :: OS Independent
|
|
24
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
25
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
26
|
+
Classifier: Operating System :: MacOS
|
|
27
|
+
Classifier: Programming Language :: Python :: 3
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
29
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
30
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
31
|
+
Classifier: Topic :: Education
|
|
32
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
33
|
+
Requires-Python: >=3.10
|
|
34
|
+
Description-Content-Type: text/markdown
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Requires-Dist: PySide6>=6.6.0
|
|
37
|
+
Requires-Dist: rapidfuzz>=3.6.0
|
|
38
|
+
Requires-Dist: pyglossary>=4.7.0
|
|
39
|
+
Provides-Extra: tts
|
|
40
|
+
Requires-Dist: edge-tts>=6.1.0; extra == "tts"
|
|
41
|
+
Requires-Dist: pyttsx3>=2.90; extra == "tts"
|
|
42
|
+
Provides-Extra: ocr
|
|
43
|
+
Requires-Dist: mss>=9.0.0; extra == "ocr"
|
|
44
|
+
Requires-Dist: pytesseract>=0.3.10; extra == "ocr"
|
|
45
|
+
Requires-Dist: Pillow>=10.0.0; extra == "ocr"
|
|
46
|
+
Provides-Extra: anki
|
|
47
|
+
Requires-Dist: requests>=2.31.0; extra == "anki"
|
|
48
|
+
Provides-Extra: all
|
|
49
|
+
Requires-Dist: dictz[anki,ocr,tts]; extra == "all"
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: pytest>=7.4.0; extra == "dev"
|
|
52
|
+
Requires-Dist: pytest-qt>=4.3.0; extra == "dev"
|
|
53
|
+
Requires-Dist: ruff>=0.3.0; extra == "dev"
|
|
54
|
+
Requires-Dist: pyinstaller>=6.0.0; extra == "dev"
|
|
55
|
+
Dynamic: license-file
|
|
56
|
+
|
|
57
|
+
# dictz
|
|
58
|
+
|
|
59
|
+
[](https://pypi.org/project/dictz/)
|
|
60
|
+
[](https://pypi.org/project/dictz/)
|
|
61
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
62
|
+
[](https://github.com/bayramkotan/dictz)
|
|
63
|
+
[](https://pypi.org/project/dictz/)
|
|
64
|
+
|
|
65
|
+
Cross-platform, multi-format, offline dictionary application — a GoldenDict-style desktop tool built with Python and Qt.
|
|
66
|
+
|
|
67
|
+
> [Türkçe açıklama aşağıda](#türkçe)
|
|
68
|
+
|
|
69
|
+

|
|
70
|
+
|
|
71
|
+
## Highlights
|
|
72
|
+
|
|
73
|
+
- **Multi-format** — StarDict (`.ifo`), ABBYY Lingvo DSL (`.dsl`, `.dsl.dz`), Babylon (`.bgl`)
|
|
74
|
+
- **Multi-dictionary** — load any number of dictionaries at once; a single query hits them all
|
|
75
|
+
- **Fast** — SQLite FTS5 index with Unicode + diacritic-insensitive search
|
|
76
|
+
- **Offline** — no network calls, no telemetry
|
|
77
|
+
- **Cross-platform** — one codebase runs on Windows 11, Linux (CachyOS/Arch/Debian/Ubuntu/Fedora), and macOS
|
|
78
|
+
|
|
79
|
+
## Install
|
|
80
|
+
|
|
81
|
+
### From PyPI
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install dictz
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### From source
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git clone https://github.com/bayramkotan/dictz.git
|
|
91
|
+
cd dictz
|
|
92
|
+
pip install -e .
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Run
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
dictz
|
|
99
|
+
# or equivalently
|
|
100
|
+
python -m dictz
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Supported formats
|
|
104
|
+
|
|
105
|
+
| Format | Extension | Parser |
|
|
106
|
+
|--------|-----------|--------|
|
|
107
|
+
| StarDict | `.ifo` / `.idx` / `.dict(.dz)` | native |
|
|
108
|
+
| ABBYY Lingvo DSL | `.dsl` / `.dsl.dz` | [PyGlossary](https://github.com/ilius/pyglossary) |
|
|
109
|
+
| Babylon | `.bgl` | [PyGlossary](https://github.com/ilius/pyglossary) |
|
|
110
|
+
|
|
111
|
+
More formats (XDXF, Slob, DictD, MDict, …) are planned — see the [roadmap](#roadmap).
|
|
112
|
+
|
|
113
|
+
## Where to find dictionaries
|
|
114
|
+
|
|
115
|
+
- [FreeDict](https://freedict.org/) — StarDict dictionaries, many language pairs
|
|
116
|
+
- [StarDict.org](http://download.huzheng.org/) — large StarDict collection
|
|
117
|
+
- [Lingvo DSL packs](http://lingvo.helpmax.net/) — ABBYY Lingvo community dictionaries
|
|
118
|
+
|
|
119
|
+
## Roadmap
|
|
120
|
+
|
|
121
|
+
- [x] **v0.0.1** — StarDict, multi-dictionary search, SQLite FTS5 index
|
|
122
|
+
- [x] **v0.0.2** — DSL + Babylon format support via PyGlossary
|
|
123
|
+
- [ ] Fuzzy / approximate matching (RapidFuzz)
|
|
124
|
+
- [ ] Rich HTML rendering (QWebEngineView) with images and audio
|
|
125
|
+
- [ ] Text-to-speech (edge-tts neural voices)
|
|
126
|
+
- [ ] Clipboard monitoring + global hotkey
|
|
127
|
+
- [ ] Screen-area OCR (Tesseract)
|
|
128
|
+
- [ ] Anki integration (one-click flashcards)
|
|
129
|
+
- [ ] Dictionary manager UI + preferences
|
|
130
|
+
- [ ] Dark mode
|
|
131
|
+
- [ ] Standalone binaries for Windows / Linux / macOS (PyInstaller)
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Install with dev extras
|
|
137
|
+
pip install -e ".[dev]"
|
|
138
|
+
|
|
139
|
+
# Run the test suite
|
|
140
|
+
pytest -v
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Project layout:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
dictz/
|
|
147
|
+
├── dictz/
|
|
148
|
+
│ ├── core/ # query orchestration, parser dispatch
|
|
149
|
+
│ ├── parsers/ # one module per dictionary format
|
|
150
|
+
│ ├── storage/ # SQLite FTS5 indexer
|
|
151
|
+
│ ├── services/ # (planned) TTS, OCR, clipboard, Anki
|
|
152
|
+
│ ├── ui/ # PySide6 widgets
|
|
153
|
+
│ └── app.py # entry point
|
|
154
|
+
├── tests/
|
|
155
|
+
└── pyproject.toml
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Contributing
|
|
159
|
+
|
|
160
|
+
Issues and pull requests are welcome at [github.com/bayramkotan/dictz](https://github.com/bayramkotan/dictz).
|
|
161
|
+
|
|
162
|
+
## License
|
|
163
|
+
|
|
164
|
+
Licensed under the [GNU General Public License v3.0 or later](LICENSE).
|
|
165
|
+
|
|
166
|
+
## Author
|
|
167
|
+
|
|
168
|
+
[Bayram Kotan](https://bayramkotan.com) — [github.com/bayramkotan](https://github.com/bayramkotan)
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
## Türkçe
|
|
173
|
+
|
|
174
|
+
dictz, çoklu format destekli, çevrimdışı çalışan, çapraz platform bir sözlük uygulamasıdır. GoldenDict tarzı bir masaüstü aracıdır ve Python + Qt ile geliştirilmektedir.
|
|
175
|
+
|
|
176
|
+
### Öne çıkanlar
|
|
177
|
+
|
|
178
|
+
- **Çoklu format** — StarDict (`.ifo`), ABBYY Lingvo DSL (`.dsl`, `.dsl.dz`), Babylon (`.bgl`)
|
|
179
|
+
- **Çoklu sözlük** — istediğin kadar sözlük yükle; tek bir arama hepsinde çalışır
|
|
180
|
+
- **Hızlı** — SQLite FTS5 indeksi + Unicode + diakritik duyarsız arama
|
|
181
|
+
- **Çevrimdışı** — hiçbir ağ çağrısı yok, telemetri yok
|
|
182
|
+
- **Çapraz platform** — Windows 11, Linux (CachyOS/Arch/Debian/Ubuntu/Fedora) ve macOS üzerinde aynı kod
|
|
183
|
+
|
|
184
|
+
### Kurulum
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
pip install dictz
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Çalıştırma
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
dictz
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Yol haritası
|
|
197
|
+
|
|
198
|
+
- [x] **v0.0.1** — StarDict format desteği, çoklu sözlükte arama, SQLite FTS5 indeksi
|
|
199
|
+
- [x] **v0.0.2** — DSL + Babylon format desteği (PyGlossary ile)
|
|
200
|
+
- [ ] Fuzzy arama (RapidFuzz)
|
|
201
|
+
- [ ] Tanımlar için zengin HTML görüntüleme
|
|
202
|
+
- [ ] Metin okuma (TTS, neural sesler)
|
|
203
|
+
- [ ] Pano izleme + global kısayol
|
|
204
|
+
- [ ] Ekran OCR (Tesseract)
|
|
205
|
+
- [ ] Anki entegrasyonu
|
|
206
|
+
- [ ] Sözlük yöneticisi UI + tercihler
|
|
207
|
+
- [ ] Koyu tema
|
|
208
|
+
- [ ] Windows / Linux / macOS tek dosya binary (PyInstaller)
|
|
209
|
+
|
|
210
|
+
### Lisans
|
|
211
|
+
|
|
212
|
+
[GNU General Public License v3.0 veya sonrası](LICENSE).
|
dictz-0.0.2/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# dictz
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/dictz/)
|
|
4
|
+
[](https://pypi.org/project/dictz/)
|
|
5
|
+
[](https://www.gnu.org/licenses/gpl-3.0)
|
|
6
|
+
[](https://github.com/bayramkotan/dictz)
|
|
7
|
+
[](https://pypi.org/project/dictz/)
|
|
8
|
+
|
|
9
|
+
Cross-platform, multi-format, offline dictionary application — a GoldenDict-style desktop tool built with Python and Qt.
|
|
10
|
+
|
|
11
|
+
> [Türkçe açıklama aşağıda](#türkçe)
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
## Highlights
|
|
16
|
+
|
|
17
|
+
- **Multi-format** — StarDict (`.ifo`), ABBYY Lingvo DSL (`.dsl`, `.dsl.dz`), Babylon (`.bgl`)
|
|
18
|
+
- **Multi-dictionary** — load any number of dictionaries at once; a single query hits them all
|
|
19
|
+
- **Fast** — SQLite FTS5 index with Unicode + diacritic-insensitive search
|
|
20
|
+
- **Offline** — no network calls, no telemetry
|
|
21
|
+
- **Cross-platform** — one codebase runs on Windows 11, Linux (CachyOS/Arch/Debian/Ubuntu/Fedora), and macOS
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
### From PyPI
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install dictz
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### From source
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
git clone https://github.com/bayramkotan/dictz.git
|
|
35
|
+
cd dictz
|
|
36
|
+
pip install -e .
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Run
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
dictz
|
|
43
|
+
# or equivalently
|
|
44
|
+
python -m dictz
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Supported formats
|
|
48
|
+
|
|
49
|
+
| Format | Extension | Parser |
|
|
50
|
+
|--------|-----------|--------|
|
|
51
|
+
| StarDict | `.ifo` / `.idx` / `.dict(.dz)` | native |
|
|
52
|
+
| ABBYY Lingvo DSL | `.dsl` / `.dsl.dz` | [PyGlossary](https://github.com/ilius/pyglossary) |
|
|
53
|
+
| Babylon | `.bgl` | [PyGlossary](https://github.com/ilius/pyglossary) |
|
|
54
|
+
|
|
55
|
+
More formats (XDXF, Slob, DictD, MDict, …) are planned — see the [roadmap](#roadmap).
|
|
56
|
+
|
|
57
|
+
## Where to find dictionaries
|
|
58
|
+
|
|
59
|
+
- [FreeDict](https://freedict.org/) — StarDict dictionaries, many language pairs
|
|
60
|
+
- [StarDict.org](http://download.huzheng.org/) — large StarDict collection
|
|
61
|
+
- [Lingvo DSL packs](http://lingvo.helpmax.net/) — ABBYY Lingvo community dictionaries
|
|
62
|
+
|
|
63
|
+
## Roadmap
|
|
64
|
+
|
|
65
|
+
- [x] **v0.0.1** — StarDict, multi-dictionary search, SQLite FTS5 index
|
|
66
|
+
- [x] **v0.0.2** — DSL + Babylon format support via PyGlossary
|
|
67
|
+
- [ ] Fuzzy / approximate matching (RapidFuzz)
|
|
68
|
+
- [ ] Rich HTML rendering (QWebEngineView) with images and audio
|
|
69
|
+
- [ ] Text-to-speech (edge-tts neural voices)
|
|
70
|
+
- [ ] Clipboard monitoring + global hotkey
|
|
71
|
+
- [ ] Screen-area OCR (Tesseract)
|
|
72
|
+
- [ ] Anki integration (one-click flashcards)
|
|
73
|
+
- [ ] Dictionary manager UI + preferences
|
|
74
|
+
- [ ] Dark mode
|
|
75
|
+
- [ ] Standalone binaries for Windows / Linux / macOS (PyInstaller)
|
|
76
|
+
|
|
77
|
+
## Development
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Install with dev extras
|
|
81
|
+
pip install -e ".[dev]"
|
|
82
|
+
|
|
83
|
+
# Run the test suite
|
|
84
|
+
pytest -v
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Project layout:
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
dictz/
|
|
91
|
+
├── dictz/
|
|
92
|
+
│ ├── core/ # query orchestration, parser dispatch
|
|
93
|
+
│ ├── parsers/ # one module per dictionary format
|
|
94
|
+
│ ├── storage/ # SQLite FTS5 indexer
|
|
95
|
+
│ ├── services/ # (planned) TTS, OCR, clipboard, Anki
|
|
96
|
+
│ ├── ui/ # PySide6 widgets
|
|
97
|
+
│ └── app.py # entry point
|
|
98
|
+
├── tests/
|
|
99
|
+
└── pyproject.toml
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## Contributing
|
|
103
|
+
|
|
104
|
+
Issues and pull requests are welcome at [github.com/bayramkotan/dictz](https://github.com/bayramkotan/dictz).
|
|
105
|
+
|
|
106
|
+
## License
|
|
107
|
+
|
|
108
|
+
Licensed under the [GNU General Public License v3.0 or later](LICENSE).
|
|
109
|
+
|
|
110
|
+
## Author
|
|
111
|
+
|
|
112
|
+
[Bayram Kotan](https://bayramkotan.com) — [github.com/bayramkotan](https://github.com/bayramkotan)
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Türkçe
|
|
117
|
+
|
|
118
|
+
dictz, çoklu format destekli, çevrimdışı çalışan, çapraz platform bir sözlük uygulamasıdır. GoldenDict tarzı bir masaüstü aracıdır ve Python + Qt ile geliştirilmektedir.
|
|
119
|
+
|
|
120
|
+
### Öne çıkanlar
|
|
121
|
+
|
|
122
|
+
- **Çoklu format** — StarDict (`.ifo`), ABBYY Lingvo DSL (`.dsl`, `.dsl.dz`), Babylon (`.bgl`)
|
|
123
|
+
- **Çoklu sözlük** — istediğin kadar sözlük yükle; tek bir arama hepsinde çalışır
|
|
124
|
+
- **Hızlı** — SQLite FTS5 indeksi + Unicode + diakritik duyarsız arama
|
|
125
|
+
- **Çevrimdışı** — hiçbir ağ çağrısı yok, telemetri yok
|
|
126
|
+
- **Çapraz platform** — Windows 11, Linux (CachyOS/Arch/Debian/Ubuntu/Fedora) ve macOS üzerinde aynı kod
|
|
127
|
+
|
|
128
|
+
### Kurulum
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
pip install dictz
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Çalıştırma
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
dictz
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### Yol haritası
|
|
141
|
+
|
|
142
|
+
- [x] **v0.0.1** — StarDict format desteği, çoklu sözlükte arama, SQLite FTS5 indeksi
|
|
143
|
+
- [x] **v0.0.2** — DSL + Babylon format desteği (PyGlossary ile)
|
|
144
|
+
- [ ] Fuzzy arama (RapidFuzz)
|
|
145
|
+
- [ ] Tanımlar için zengin HTML görüntüleme
|
|
146
|
+
- [ ] Metin okuma (TTS, neural sesler)
|
|
147
|
+
- [ ] Pano izleme + global kısayol
|
|
148
|
+
- [ ] Ekran OCR (Tesseract)
|
|
149
|
+
- [ ] Anki entegrasyonu
|
|
150
|
+
- [ ] Sözlük yöneticisi UI + tercihler
|
|
151
|
+
- [ ] Koyu tema
|
|
152
|
+
- [ ] Windows / Linux / macOS tek dosya binary (PyInstaller)
|
|
153
|
+
|
|
154
|
+
### Lisans
|
|
155
|
+
|
|
156
|
+
[GNU General Public License v3.0 veya sonrası](LICENSE).
|
dictz-0.0.2/dictz/app.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""dictz application entry point.
|
|
2
|
+
|
|
3
|
+
Run with:
|
|
4
|
+
python -m dictz
|
|
5
|
+
# or after `pip install -e .`:
|
|
6
|
+
dictz
|
|
7
|
+
"""
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
from pathlib import Path
|
|
13
|
+
|
|
14
|
+
from PySide6.QtWidgets import QApplication
|
|
15
|
+
|
|
16
|
+
from .core.query_manager import QueryManager
|
|
17
|
+
from .storage.indexer import IndexStore
|
|
18
|
+
from .ui.main_window import MainWindow
|
|
19
|
+
|
|
20
|
+
__version__ = "0.0.2"
|
|
21
|
+
APP_NAME = "dictz"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def user_data_dir() -> Path:
|
|
25
|
+
"""Cross-platform per-user data directory.
|
|
26
|
+
|
|
27
|
+
- Windows: %APPDATA%\\dictz
|
|
28
|
+
- macOS: ~/Library/Application Support/dictz
|
|
29
|
+
- Linux: $XDG_DATA_HOME/dictz (fallback ~/.local/share/dictz)
|
|
30
|
+
"""
|
|
31
|
+
if sys.platform == "win32":
|
|
32
|
+
base = Path(os.environ.get("APPDATA", Path.home() / "AppData" / "Roaming"))
|
|
33
|
+
return base / APP_NAME
|
|
34
|
+
elif sys.platform == "darwin":
|
|
35
|
+
return Path.home() / "Library" / "Application Support" / APP_NAME
|
|
36
|
+
else:
|
|
37
|
+
xdg = os.environ.get("XDG_DATA_HOME")
|
|
38
|
+
base = Path(xdg) if xdg else Path.home() / ".local" / "share"
|
|
39
|
+
return base / APP_NAME.lower()
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def main() -> int:
|
|
43
|
+
app = QApplication(sys.argv)
|
|
44
|
+
app.setApplicationName(APP_NAME)
|
|
45
|
+
app.setApplicationVersion(__version__)
|
|
46
|
+
app.setOrganizationName("Bayram Kotan")
|
|
47
|
+
app.setOrganizationDomain("bayramkotan.com")
|
|
48
|
+
|
|
49
|
+
data_dir = user_data_dir()
|
|
50
|
+
data_dir.mkdir(parents=True, exist_ok=True)
|
|
51
|
+
index_path = data_dir / "dictz_index.db"
|
|
52
|
+
|
|
53
|
+
index_store = IndexStore(index_path)
|
|
54
|
+
index_store.open()
|
|
55
|
+
|
|
56
|
+
query_manager = QueryManager(index_store=index_store)
|
|
57
|
+
|
|
58
|
+
window = MainWindow(query_manager)
|
|
59
|
+
window.show()
|
|
60
|
+
|
|
61
|
+
return app.exec()
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
if __name__ == "__main__":
|
|
65
|
+
sys.exit(main())
|
|
File without changes
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""Query manager: orchestrates lookups across all loaded dictionaries.
|
|
2
|
+
|
|
3
|
+
The query manager keeps a list of loaded `Dictionary` instances and dispatches
|
|
4
|
+
a single user query to all of them, collecting and ranking the results.
|
|
5
|
+
|
|
6
|
+
For v0.0.2 we run lookups sequentially. Parallelization with QThreadPool comes
|
|
7
|
+
in a later version when big glossary loading becomes a bottleneck.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from ..parsers.babylon import BabylonDictionary
|
|
14
|
+
from ..parsers.base import Dictionary, DictionaryEntry
|
|
15
|
+
from ..parsers.dsl import DSLDictionary
|
|
16
|
+
from ..parsers.stardict import StarDictDictionary
|
|
17
|
+
from ..storage.indexer import IndexStore
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
# File-extension -> parser class. `.dsl.dz` is handled by peeling the .dz
|
|
21
|
+
# compression suffix before the lookup.
|
|
22
|
+
_PARSER_REGISTRY: dict[str, type[Dictionary]] = {
|
|
23
|
+
".ifo": StarDictDictionary,
|
|
24
|
+
".dsl": DSLDictionary,
|
|
25
|
+
".bgl": BabylonDictionary,
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def parser_for(path: Path | str) -> type[Dictionary]:
|
|
30
|
+
"""Pick a parser class based on file extension.
|
|
31
|
+
|
|
32
|
+
Handles compressed forms (.dsl.dz, .gls.dz) by peeling the .dz suffix.
|
|
33
|
+
"""
|
|
34
|
+
p = Path(path)
|
|
35
|
+
suffix = p.suffix.lower()
|
|
36
|
+
|
|
37
|
+
# Strip dictzip compression layer
|
|
38
|
+
if suffix == ".dz":
|
|
39
|
+
inner_suffix = p.with_suffix("").suffix.lower()
|
|
40
|
+
if inner_suffix in _PARSER_REGISTRY:
|
|
41
|
+
return _PARSER_REGISTRY[inner_suffix]
|
|
42
|
+
|
|
43
|
+
if suffix in _PARSER_REGISTRY:
|
|
44
|
+
return _PARSER_REGISTRY[suffix]
|
|
45
|
+
|
|
46
|
+
raise ValueError(f"No parser registered for file: {p}")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def supported_extensions() -> list[str]:
|
|
50
|
+
"""List of extensions the current build can open."""
|
|
51
|
+
return sorted(_PARSER_REGISTRY.keys())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class QueryManager:
|
|
55
|
+
"""Orchestrates dictionary loading and multi-dictionary lookups."""
|
|
56
|
+
|
|
57
|
+
def __init__(self, index_store: IndexStore | None = None):
|
|
58
|
+
self.dictionaries: dict[str, Dictionary] = {}
|
|
59
|
+
self.index_store = index_store
|
|
60
|
+
|
|
61
|
+
def add_dictionary(self, path: Path | str, reindex: bool = False) -> Dictionary:
|
|
62
|
+
parser_cls = parser_for(path)
|
|
63
|
+
dictionary = parser_cls(path)
|
|
64
|
+
dictionary.load()
|
|
65
|
+
self.dictionaries[dictionary.metadata.name] = dictionary
|
|
66
|
+
|
|
67
|
+
if self.index_store is not None:
|
|
68
|
+
already_indexed = self.index_store.is_indexed(dictionary.metadata.name)
|
|
69
|
+
if reindex or not already_indexed:
|
|
70
|
+
self.index_store.index_dictionary(dictionary)
|
|
71
|
+
|
|
72
|
+
return dictionary
|
|
73
|
+
|
|
74
|
+
def remove_dictionary(self, name: str) -> None:
|
|
75
|
+
if name in self.dictionaries:
|
|
76
|
+
self.dictionaries[name].close()
|
|
77
|
+
del self.dictionaries[name]
|
|
78
|
+
if self.index_store is not None:
|
|
79
|
+
self.index_store.remove_dictionary(name)
|
|
80
|
+
|
|
81
|
+
def loaded_names(self) -> list[str]:
|
|
82
|
+
return sorted(self.dictionaries.keys())
|
|
83
|
+
|
|
84
|
+
def search(self, word: str, exact: bool = True) -> list[DictionaryEntry]:
|
|
85
|
+
if not word.strip():
|
|
86
|
+
return []
|
|
87
|
+
|
|
88
|
+
results: list[DictionaryEntry] = []
|
|
89
|
+
for name, dictionary in self.dictionaries.items():
|
|
90
|
+
try:
|
|
91
|
+
entries = dictionary.lookup(word, exact=exact)
|
|
92
|
+
except Exception as e:
|
|
93
|
+
print(f"[dictz] lookup failed in {name}: {e}")
|
|
94
|
+
continue
|
|
95
|
+
results.extend(entries)
|
|
96
|
+
return results
|
|
97
|
+
|
|
98
|
+
def suggest(self, prefix: str, limit: int = 30) -> list[str]:
|
|
99
|
+
if not prefix.strip():
|
|
100
|
+
return []
|
|
101
|
+
|
|
102
|
+
if self.index_store is not None:
|
|
103
|
+
rows = self.index_store.search_headword(prefix, limit=limit)
|
|
104
|
+
seen: set[str] = set()
|
|
105
|
+
out: list[str] = []
|
|
106
|
+
for headword, _ in rows:
|
|
107
|
+
if headword not in seen:
|
|
108
|
+
seen.add(headword)
|
|
109
|
+
out.append(headword)
|
|
110
|
+
return out
|
|
111
|
+
|
|
112
|
+
seen = set()
|
|
113
|
+
out = []
|
|
114
|
+
for dictionary in self.dictionaries.values():
|
|
115
|
+
for entry in dictionary.lookup(prefix, exact=False):
|
|
116
|
+
if entry.headword not in seen:
|
|
117
|
+
seen.add(entry.headword)
|
|
118
|
+
out.append(entry.headword)
|
|
119
|
+
if len(out) >= limit:
|
|
120
|
+
return out
|
|
121
|
+
return out
|
|
122
|
+
|
|
123
|
+
def close_all(self) -> None:
|
|
124
|
+
for dictionary in self.dictionaries.values():
|
|
125
|
+
dictionary.close()
|
|
126
|
+
self.dictionaries.clear()
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Babylon (.bgl) dictionary parser.
|
|
2
|
+
|
|
3
|
+
Babylon is a proprietary binary format from the Babylon translator. The format
|
|
4
|
+
was reverse-engineered years ago; PyGlossary includes a mature parser that
|
|
5
|
+
handles the binary encoding, embedded images, and multi-byte character sets.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from .pyglossary_base import PyGlossaryDictionary
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class BabylonDictionary(PyGlossaryDictionary):
|
|
13
|
+
"""Babylon binary dictionary (.bgl)."""
|
|
14
|
+
|
|
15
|
+
_format = "BabylonBgl"
|
|
16
|
+
format_label = "babylon"
|