A calibre plugin to synchronize metadata from KOReader to calibre.
KOReader creates sidecar files that hold read progress and annotations. This plugin reads the data from those sidecar files and updates calibre's metadata based on them. It is inspired by the Kobo Utilities plugin, that synchronizes reading progress between the original Kobo firmware ("Nickel") and custom columns in calibre.
Note that at the moment the sync is primarily one-way—from the KOReader device to calibre, and only works for USB and wireless devices. For best experience please use the latest KOReader release
Releases will also be uploaded to plugin thread on the MobileRead Forums. If you are on there as well, please let me know what you think of the plugin in that thread.
- Go to your calibre's Preferences > Plugins > Get new plugins and search for KOReader Sync
- Click Install
- Restart calibre
- Download the latest release from here.
- Go to your calibre's Preferences > Plugins > Load plugin from file and point it to the downloaded ZIP file
- Restart calibre
-
Pick and choose the metadata you would like to sync and create the appropriate columns in calibre. The plugin makes this easy, simply select the create new columns option in the config dropdowns.
These are your options:
- A Floating point numbers column to store the current percent read,
with Format for numbers set to
{:.0%}. - An Integers column to store the current percent read.
- A regular Text column to store the location you last stopped reading at
- A Rating column to store your rating of the book, as entered on the book's status page.
- A Long text column to store your review of the book, as entered on the book's status page.
- A regular Text column to store the reading status of the book, as entered on the book status page (Finished, Reading, On hold). Translates to complete, reading, and abandoned respectively in calibre.
- A Yes/No column to store the reading status of the book, as a boolean (Yes = Finished, No = everything else).
- A Long text column to store your bookmarks and highlights of the book, with Interpret this column as set to Plain text formatted using markdown. (Highlights are an unordered list with their metadata in an HTML comment.)
- A regular Text column to store the MD5 hash KOReader uses to sync progress to a KOReader Sync Server (Progress sync in the KOReader app). This allows for syncing progress and location to calibre without having to connect your KOReader device.
- A Date column to store when the last sync was performed.
- A Date column to store when the sidecar file was last modified. Works for wired connection only, wireless will be always empty.
- A Date column to store when the book status was first marked reading.
- A Date column to store when the book status was first marked finished.
- A Long text column to store the contents of the metadata sidecar as HTML, with Interpret this column as set to HTML.
There are additional settings for:
- Sync only if changes are more recent: Checks retrieved Last Sync Date against date on file.
- No sync if book has already been finished: If percent read is 100 or if reading status is finished don't update data.
- Automatic Sync on device connection: Silently sync's from KOReader when device is connected
- A Floating point numbers column to store the current percent read,
with Format for numbers set to
-
Add KOReader Sync to main toolbar when a device is connected, if it isn't there already.
-
Right-click the KOReader Sync icon and Configure.
-
Map the metadata you want to sync to the newly created calibre columns.
-
Click OK to save your mapping.
-
From now on just click the KOReader Sync icon to sync all mapped metadata for all books on the connected device to calibre.
Note: Some field are depreciated and removed from plugin since they are
changed/removed from sidecar_contents data structure:
first_bookmarkremovedlast_bookmarkremovedbookmarksrenamed toannotationsratingKOreader uses 5-point but calibre 10-point scale (whole starts, not half stars)date_sidecar_modifiedseems to be present incalculatedonly if connected via cable (not wireless)
This plugin supports use of a KOReader Sync
Server
(Progress sync in the KOReader app) in order to update current percent read
(both float and int) and location you last stopped reading at wirelessly.
You must also have the MD5 hash column enabled.
Add the server and user credentials in the plugin config to use this function.
The user password is stored as a hash, not plain text.
You can have calibre fetch updated data on a daily schedule.
- The plugin overwrites existing metadata in Calibre without asking. That usually isn’t a problem, because you will probably only add to KOReader’s metadata. But be aware that you might lose data in calibre if you’re not careful.
- Pushing sidecars back to KOReader currently only happens for sidecars which
are missing. For now, manually delete the
<bookname>.sdrfolder from the device before attempting to push the sidecars back to KOReader for any books you would like to overwrite the current metadata with Calibre's metadata. - When pushing missing sidecars to the device, no attempt is made to convert Calibre's metadata to account for changes in KOReader's sidecar format. Old metadata may work unpredictably if it's from a different version of KOReader.
This plugin has been tested successfully with:
- Kobo Clara BW/Colour connected over USB or KOreader wireless driver
- Kobo Aura/Touch connected over USB (
KOBOandKOBOTOUCHdrivers) - Kobo Aura H2O over USB (
KOBOTOUCHEXTENDEDdriver) - All devices connected wirelessly via the
SMART_DEVICE_APPdriver (e.g., KOReader wireless connection) - PocketBook devices using
POCKETBOOK_IMPROVED,POCKETBOOK632,POCKETBOOK626, orPOCKETBOOK622drivers - Kindle Keyboard (
KINDLE2) - Tolino Vision 4 HD (
TOLINO) - A connected folder (
FOLDER_DEVICE) - Manually defined devices using the
USER_DEFINEDdriver
This plugin is not compatible with:
MTP_DEVICE(Android devices connected via MTP)
If you encounter any issues with the plugin, please submit them here.
- Multiple tweaks and bug fixes by Glen Sawyer
- Additional functionality by Charles Taylor
- Contains SirAnthony's SLPP to parse Lua in Python.
- Some code borrowed from--and heavily inspired by--the great Kobo Utilities calibre plugin.
- Some code borrowed from--and heavily inspired by--the great Goodreads Sync calibre plugin.
- My first attempt was actually to sync calibre with KOReader's read progress through the progress sync plugin and a sync server. Read here why that did not work. This plugin might actually make that possible now by allowing you to store KOReader's MD5 hash in calibre...
- calibre allows you to auto-connect to a folder device on boot, which greatly
speeds up your workflow when testing. You can find this under "
Preferences" > "Tweaks", search for
auto_connect_to_folder. Point that to thedummy_devicefolder in this repository. (I have included royalty free EPUBs for your and my convenience.) - If you're testing and don't actually want to update any metadata,
set
DRY_RUNtoTruein__init__.py. - I work in PyCharm, which offers a remote debugging server. To enable that in
this plugin, set
PYDEVDtoTruein__init__.py.You might need to changesys.path.appendinaction.py. - The supported device drivers can be found
in the
SUPPORTED_DEVICESlist inconfig.py. Adding a new type here is the first step to adding support, but make sure all features are tested thoroughly before releasing a version with an added device
Use make to load the plugin into calibre and launch it:
make devFor Linux users with a Flatpak installation of Calibre, use the FLATPAK=1
flag. This is necessary because Flatpak runs Calibre in a
sandboxed environment,
requiring specific commands to interact with it:
make dev FLATPAK=1Note:
FLATPAK=1is only supported on Linux. On Windows and macOS, please install Calibre natively and runmakewithout this flag.
| Target | Description |
|---|---|
test |
Run unit and integration tests using pytest (includes Calibre environment mocks) |
lint |
Run static analysis using pylint (enforces 9.5/10 score and zero Errors) |
dev |
Load plugin source directly into Calibre and launch in debug mode |
pre |
Patch internal version with -pre and build a community pre-release ZIP |
bump-patch |
Increment the patch version in .version (e.g., 0.8.0 -> 0.8.1) |
bump-minor |
Increment the minor version in .version (e.g., 0.8.0 -> 0.9.0) |
bump-major |
Increment the major version in .version (e.g., 0.8.0 -> 1.0.0) |
prep-release |
Create a release-prep-<version> branch, update files, and commit |
release |
Tag the current version and push to trigger GitHub Release, do this after updated version already pushed to main |
md_to_bb |
Convert input.md to output.forumbb (BBCode) for MobileRead forum posts |
| Target | Description |
|---|---|
install |
Install ZIP into Calibre without launching the GUI |
zip |
Create plugin ZIP file in dist/ directory |
load |
Install ZIP from dist/ and launch Calibre in debug mode |
build |
Full build workflow: update versions from .version and create ZIP |
dev_version |
Update all code files with the current version from .version |
clean |
Remove all build artifacts and temporary files |
clean_dev |
Clean up development-specific temporary files |
tag |
Create and push git tag for current version |
The project uses a structured workflow to ensure both rapid updates and stable releases:
- Develop Branch (
develop): This is the primary work-in-progress branch.- Experimental fixes and new features are merged here first.
- Every push to this branch triggers an automated Pre-release build.
- Users can download the latest community pre-release from the Upcoming Release page.
- Main Branch (
main): This branch contains the stable, production-ready code.- Only merge
developintomainwhen a milestone is reached. - Running
make releaseon this branch automatically cleans the version string, tags the commit, and triggers the official GitHub Release.
- Only merge
The project enforces high code quality standards through automated checks:
- Unit Testing: Run
make test. We usepytestalong with a mocking layer (tests/conftest.py) that simulates the Calibre environment. This allows you to test plugin logic without having Calibre installed. - Linting: Run
make lint. We usepylintwith a custom configuration (.pylintrc).- Threshold: The project requires a minimum score of 9.5/10.
- Strictness: The build will instantly fail if any Fatal (F) or Error (E) messages are found, regardless of the total score.
These checks run automatically on every Pull Request via GitHub Actions.
The project uses GitHub Actions to automate releases. When a tag v* is pushed, a GitHub Release is created automatically with the built plugin ZIP.
- Prepare the version:
- Manually edit
.versionOR runmake bump-patch/make bump-minor.
- Manually edit
- Run preparation:
- Run
make prep-release. This creates a new branch (e.g.,release-prep-x.x.x), updates all version strings in the code, and commits them.
- Run
- Review and Merge:
- Review the changes in the new branch, then merge it into
main.
- Review the changes in the new branch, then merge it into
- Publish:
- On the
mainbranch, runmake release. This will tag the commit and push it. - The GitHub Action will pick up the tag, build the plugin, and create a GitHub Release with the ZIP attached.
- On the
- Download the required release from here
- Add it to calibre by running this in your
terminal:
calibre-customize -a "KOReader_Sync_vX.X.X.zip", whereX.X.Xrefers to the version you downloaded - Start calibre in debug mode with
calibre-debug -g - Configure the KOReader plugin as described here
- Connect your device
- Run the sync by clicking the KOReader icon in your toolbar
- Check the details of the message when it's done if any/all books have been synced correctly
- Check your (custom) columns for one of those books to see if their contents are what they should be
- Check the output in your terminal for lines containing
koreaderto see what it did