Documentation and Guides(Please read at least the general notes before using. There are some important notices.)
This project is intended to be a modern, from-the-ground-up, maintainable alternative toGoldenDict(-ng), developed with Flask and React.
You can access the live demohere(library management and settings are disabled). It is hosted by Python Anywhere on a free plan, so it might be quite slow. Demo last updated on 16th August 2024.
The dark theme is not built in, but rendered with theDark Reader Firefox extension.
- Python-powered
- Deployable both locally and on a self-hosted server
- Fast enough
- Modern, clean and sleek web interface, with Material Design
- DSL, StarDict, MDict supported
- Anki mode
- Full-text search (available on Unix systems only)
- Cross-platform (Linux, Windows, MacOS, Android, limited iOS)
- Linux: RPM/Deb packaging, including various dependencies like
idzip
Add support for Babylon BGL glossary format1Transliteration for the Cyrillic, Greek, Arabic, Hebrew and Devanagari scripts(perhaps switching the keyboard layout is a far better solution, anyway Greek is already supported2)- Make concurrent code thread-safe to prepare forno-GIL Python
- Localisation
- A real mobile app
- Make the browser's back/forward buttons work (help needed.
useSearchParams()
doesn't work.) - (Ongoing) A C++/Qt (or QML) desktop client for better integration with the system (e.g. Ctrl+C+C to look up a word)
Note: If all you need is this key combination, then perhapsxbindkeys
suffices, which is quite huge though. Or you can use the following script:
importpyperclip
importwebbrowser
frompynputimportkeyboard
fromurllib.parseimporturlencode
server_address='http://localhost:2628/'
group='English'
classKeyListener:
def__init__(self):
self.ctrl_pressed=False
self.c_pressed_once=False
defon_press(self,key):
try:
ifkey==keyboard.Key.ctrl_lorkey==keyboard.Key.ctrl_r:
self.ctrl_pressed=True
elifkey.char=='c'andself.ctrl_pressed:
ifself.c_pressed_once:
selection=pyperclip.paste()
# Uncomment (and comment the line below) to use the full web UI
# params = urlencode({'group': group, 'key': selection})
# webbrowser.open_new_tab(server_address + '?' + params)
webbrowser.open_new_tab(f'{server_address}api/query/{group}/{selection}')
self.reset()
else:
self.c_pressed_once=True
else:
self.reset()
exceptAttributeError:
self.reset()
defon_release(self,key):
ifkey==keyboard.Key.esc:
returnFalse
defreset(self):
self.ctrl_pressed=False
self.c_pressed_once=False
if__name__=='__main__':
listener=KeyListener()
withkeyboard.Listener(
on_press=listener.on_press,
on_release=listener.on_release
)aslistener:
listener.join()
This project utilises some Python 3.10 features, such as thematchsyntax, and a minimal set of dependencies:
PyYAML # configuration files
Flask # the web framework
Flask-Cors
waitress # the WSGI server, note: other servers like Gunicorn and uWSGI work but you have to adjust the code
Python -idzip # for dictzip
Python -lzo # for v1/v2 MDict
xxhash # for v3 MDict
dsl2html # for DSL
xdxf2html # for XDXF-formatted StarDicts
requests # for auto-update
The packagesdsl2html
andxdxf2html
are mine, and could potentially be used by other projects.
In order to enable morphology analysis, you need to place the Hunspell dictionaries into~/.silverdict/hunspell
,and install the Python packagesibel
orhunspell
.I developedsibel
as a faster alternative to PyHunspell. But it might be difficult to install (see its Readme).
In order to enable Simplified/Traditional Chinese conversion, you need to install the Python packageopencc
.
To use full-text search, please installxapian
and the Python bindings, optionally alsolxml
.
Python -lzo
,xxhash
,dsl2html
,xdxf2html
all have pure Python alternatives, but they are either much slower or not very robust. If you are unable to installPython -lzo
ordsl2html
,no action is needed. Forxxhash
,please install the pure Python implementationppxxh
instead. Forxdxf2html
,installlxml
,which is not pure Python either, but its binary wheels are available for most platforms.
The simplest method to use this app is to run it locally.
cdclient
yarn install
yarn build
mv build../server/
And then:
cd../server
pip install -r requirements.txt
Python server.py#working-directory-agnostic
Then access it atlocalhost:2628.
Or, if you do not wish to build the web app yourself or clone the whole repository, you can download fromreleasea zip archive, which contains everything you need to run SilverDict.
For Windows users: A zip archive complete with a Python interpreter and all the dependencies (except for Xapian) is available inrelease.Download the archive, unzip it, and double-clicksetup.bat
to generate a shortcut. Then you can move it wherever you wish and click on it to run SilverDict. After launching the server, you can access it atlocalhost:2628.
For Termux users: run the bash scripttermux_setup.sh
in the top-level directory, which will install all the dependencies, including PyHunspell. The script assumes you have enabled external storage access and will create a default source directory at/sdcard/Documents/Dictionaries
.
Alternatively, you could use dedicated HTTP servers such as nginx to serve the static files and proxy API requests. Check out the sampleconfigfor more information.
I recommend nginx if you plan to deploy SilverDict to a server. Runyarn build
to generate the static files of the web app, or download a prebuilt one from release (insideserver/build
), and then place them into whatever directory where nginx looks for static files. Remember to reverse-proxy all API requests and permit methods other thanGET
andPOST
.
Assuming your distribution uses systemd, you can refer to the provided sample systemdconfigand run the script as a service.
docker build --tag silverdict https://github /Crissium/SilverDict.git
docker run --rm --publish 2628:2628 --volume${PATH_TO_DICTIONARIES}:/root/.silverdict/ --name silverdict silverdict
${PATH_TO_DICTIONARIES}
is the path where settings and dictionaries are stored. The default path to scan is${PATH_TO_DICTIONARIES}/source
for dictionaries and${PATH_TO_DICTIONARIES}/hunspell
for spellchecking libraries (if enabled).
When building the Docker image, optional features can be enabled by passing--build-arg
.For example, if you want to enable full text search:
docker build --tag silverdict --build-arg ENABLE_FULL_TEXT_SEARCH=true https://github /Crissium/SilverDict.git
Available arguments are:
Argument | value | default |
---|---|---|
ENABLE_FULL_TEXT_SEARCH | true or empty | empty |
ENABLE_MORPHOLOGY_ANALYSIS | true or empty | empty |
ENABLE_CHINESE_CONVERSION | true or empty | empty |
Or use Docker Compose: Editdocker-compose.yml
and
docker compose up -d
Note that if the paths to be mounted do not exist, Docker will create them with root ownership.
docker pull mathdodger/silverdict
Then run the container as above. This image is built with all three optional features enabled.
- Start with an item in the roadmap, or open an issue to discuss your ideas. Please notify me if you are working on something to avoid duplicated efforts. I myself dislike enforcing a coding style, but please use descriptive, verbose variable names and UTF-8 encoding, LF line endings, and indent with tabs.
- Translate the guides into your language. You could edit them directly on GitHub or translate on Crowdin.
- Translate the web UI onCrowdin.Please open an issue or send me a PM on Crowdin if your language's not there.
The favicon is the icon for 'Dictionary' from thePapirus icon theme,licensed under GPLv3.
The Dockerfile is contributed bysimonmysun.
This project uses or has adapted code from the following projects:
Name | Developer | Licence |
---|---|---|
GoldenDict | Konstantin Isakov | GPLv3 |
mdict-analysis | Xiaoqiang Wang | GPLv3 |
mdict-query | mmjang | No licence |
Python -stardict | Su Xing | GPLv3 |
dictionary-db (together with the n-gram method) | Jean-François Dockes | GPL 2.1 |
pyglossary | Saeed Rasooli | GPLv3 |
I would also express my gratitude to my long-time ' Alpha -tester' Jiang Qian, without whom this project could never become what it is today.
This project is licensed under GPLv3. But it's said that programs designed to run on a server should be licensed under AGPL instead. One thing I don't understand is that, for example, if you were to write a custom transformation script for a dictionary and run it on your server, then under AGPL you'd have to release the script's source code. That sounds unreasonable to me.
- flask-mdict
- GoldenDict-ng's proposed HTTP server(stuck at the moment)
- Lectus(DSL only, in Perl)
- django-mdict
- An ancient issue of GoldenDict
Footnotes
-
GoldenDict stores the decoded entries andfull-textdefinitions in its custom index. I see no reason why I should follow suit when one can always convert dictionaries in this obnoxious format into HTML-formatted StarDict with the excellentpyglossary.↩
-
The original use case is to support an ancient Greek lexicon that uses mixed Greek/Beta Code headwords. Normal dictionaries should not have this problem. Besides, implementing, say, a QWERTY-JCUKEN mapping is too trivial, whereas real transliteration is overcomplicated.↩