Zeedif 590e43c827 feat(sync/koreader): Add KOReader reading progress synchronization (#1560)
* feat(sync/koreader): implement reading progress synchronization

This commit introduces a comprehensive integration with KOReader Sync Server to enable two-way synchronization of reading progress.

The core logic is encapsulated in a new `KoreaderSyncService`, which handles authentication, registration, and progress pushing/pulling based on user-defined strategies (LATEST, KOSYNC, SUWAYOMI).

Key changes include:

- A new GraphQL API is added to manage the KOReader Sync connection:
  - `connectKoSyncAccount` mutation provides a simplified flow that attempts to log in and, if the user doesn't exist, automatically registers them.
  - `logoutKoSyncAccount` mutation to clear credentials.
  - `koSyncStatus` query to check the current connection status.

- Reading progress is now synchronized at key points:
  - The `fetchChapterPages` mutation pulls the latest progress from the sync server before loading the reader. It respects the configured sync strategy and updates the local database if necessary.
  - The `updateChapters` and other progress-updating methods now push changes to the sync server automatically.
- OPDS chapter entries also pull the latest progress, ensuring clients receive up-to-date reading status.

- Supporting backend changes have been made:
  - The `Chapter` table is extended with a `koreader_hash` column to uniquely identify documents. A database migration is included.
  - New configuration options are added to `server.conf` to manage the feature (enable, server URL, credentials, strategy, etc.).

* perf(opds): defer KOReader sync to improve chapter feed performance

Removes the KOReader Sync progress-pulling logic from the `createChapterListEntry` function.

The previous implementation triggered a network request to the sync server for every single chapter when generating a list, leading to severe performance issues and slow load times on feeds with many entries.

This change reverts to the more performant approach of always linking to the chapter's metadata feed. The expensive sync operation will be handled within the metadata entry generation instead, ensuring it's only triggered on-demand for a single chapter. This restores the responsiveness of browsing chapter feeds.

* refactor(koreader): Use enums for sync settings and correct OPDS logic

Refactor Koreader Sync settings to use enums instead of raw strings for `checksumMethod` and `strategy`. This improves type safety, prevents typos, and makes the configuration handling more robust.

The changes include:
- Introducing `KoreaderSyncChecksumMethod` and `KoreaderSyncStrategy` enums.
- Updating `ServerConfig`, GraphQL types, and backup models to use these new enums.
- Refactoring `KoreaderSyncService` to work with the enum types.

Additionally, this commit fixes an issue in `OpdsEntryBuilder` where the logic for determining which sync progress to use (local vs. remote) was duplicated. The builder now correctly delegates this decision to `KoreaderSyncService.pullProgress`, which already contains the necessary strategy logic. This centralizes the logic and ensures consistent behavior.

* refactor(koreader): Improve config handling and remove redundant update

This commit combines several refactoring and cleanup tasks:

- **Koreader Sync:** The sync service is updated to use the modern `serverConfig` provider instead of the legacy `GlobalConfigManager`. This aligns it with the current configuration management approach in the project.

- **Download Provider:** A redundant `pageCount` database update is removed from `ChaptersFilesProvider`. This operation was unnecessary because the `getChapterDownloadReady` function, which is called earlier in the download process, already verifies and corrects the page count. This change eliminates a superfluous database write and fixes a related import issue.

* feat(sync/koreader)!: enhance sync strategy and add progress tolerance

This commit overhauls the KOReader synchronization feature to provide more granular control and robustness. The simple on/off toggle has been replaced with a more flexible strategy-based system.

Key changes include:
- Replaced `koreaderSyncEnabled` with a more powerful `koreaderSyncStrategy` enum.
- Introduced new sync strategies: `PROMPT`, `SILENT`, `SEND`, `RECEIVE`, and `DISABLE`, allowing for fine-grained control over the sync direction and conflict resolution.
- Added a `koreaderSyncPercentageTolerance` setting. This prevents unnecessary sync updates for minor progress differences between Suwayomi and KOReader.
- Refactored the `KoreaderSyncService` to implement the new strategies and use the configurable tolerance.
- Updated GraphQL schemas, mutations, and server configuration to remove the old setting and incorporate the new ones.
- Adjusted the backup and restore process to correctly handle the new configuration parameters.
- Modified API endpoints and internal logic to check and apply remote progress based on the selected strategy.

BREAKING CHANGE: The `koreaderSyncEnabled` setting is removed and replaced by a more granular `koreaderSyncStrategy`. The enum values for the strategy have been completely changed, making previous configurations incompatible.

* fix: remove unused imports

* feat(opds, sync): enhance Koreader sync and OPDS conflict handling

This commit introduces significant improvements to the Koreader synchronization feature, focusing on providing a better user experience for handling progress conflicts in both OPDS and GraphQL clients.

Key changes include:

- **OPDS Conflict Resolution:** When a reading progress conflict is detected, the OPDS feed for a chapter now provides two distinct "Read Online" links: one to continue from the local progress and another to continue from the synced progress from the remote device (e.g., "Continue Reading Online (Synced from KOReader)"). This empowers users to choose which progress to follow.

- **GraphQL Sync Conflict Information:** The `fetchChapterPages` GraphQL mutation now includes a `syncConflict` field in its payload. This field provides the remote device name and page number, allowing GraphQL clients to implement a user-facing prompt to resolve sync conflicts.

- **Improved Sync Strategy Handling:**
  - The `connectKoSyncAccount` mutation no longer unconditionally sets the sync strategy to `PROMPT`. It now respects the user's existing setting, preventing accidental configuration changes upon re-login.
  - The default `koreaderSyncStrategy` in the configuration is changed to `DISABLED`, providing a safer and more intuitive default for new users.

- **Refinements & Fixes:**
  - The fallback for the remote device name is now centralized within the KoreaderSyncService, defaulting to "KOReader" if not provided.
  - Renamed `KoreaderSyncStrategy.DISABLE` to `DISABLED` for consistency.
  - Updated i18n strings for OPDS links to be more descriptive and user-friendly.

* refactor(kosync): rename stream page link titles for consistency

* refactor(kosync): return SettingsType in auth mutation payloads

The `connectKoSyncAccount` and `logoutKoSyncAccount` mutations modify server settings (username and userkey) but did not previously return the updated configuration. This forced client applications to manually refetch settings to avoid a stale cache.

This change modifies the payloads for both mutations to include the full `SettingsType`.

By returning the updated settings directly, GraphQL clients like Apollo Client can automatically update their cache, simplifying client-side state management and ensuring the UI always reflects the current server configuration.

Additionally, `clientMutationId` has been added to `KoSyncConnectPayload` for consistency with GraphQL practices, aligning it with the logout mutation.

Refs: #1560

* refactor(kosync): replace KoSyncConnectPayload with ConnectResult in connect method

* fix(kosync): add koreaderSyncPercentageTolerance default setting
2025-08-19 15:00:19 -04:00
2025-07-31 13:56:03 -04:00
2025-07-31 13:56:03 -04:00
2025-08-19 15:00:09 -04:00
2025-07-31 12:01:33 -04:00
2023-10-04 22:02:20 -04:00
2025-07-31 13:56:03 -04:00
2021-05-07 19:41:34 +04:30
2025-06-12 11:59:41 -04:00

Build Stable Preview Support Server
CI stable release preview Discord

Table of Content

What is Suwayomi?

drawing

A free and open source manga reader server that runs extensions built for Mihon (Tachiyomi).

Suwayomi is an independent Mihon (Tachiyomi) compatible software and is not a Fork of Mihon (Tachiyomi).

Suwayomi-Server is as multi-platform as you can get. Any platform that runs java and/or has a modern browser can run it. This includes Windows, Linux, macOS, chrome OS, etc. Follow Downloading and Running the app for installation instructions.

You can use Mihon (Tachiyomi) to access your Suwayomi-Server. For more info look here.

Features

Note

These are capabilities of Suwayomi-Server, the actual working support is provided by each front-end app, checkout their respective readme for more info.

  • Installing and executing Mihon (Tachiyomi)'s Extensions, So you'll get the same sources
  • Searching and browsing installed sources
  • A library to save your mangas and categories to put them into
  • Automated library updates to check for new chapters
  • Automated download of new chapters
  • Viewing latest updated chapters
  • Ability to download Manga for offline read
  • Backup and restore support powered by Mihon (Tachiyomi)-compatible Backups
  • Automated backup creations
  • Tracking via MyAnimeList, AniList, MangaUpdates, etc.
  • FlareSolverr support to bypass Cloudflare protection
  • Automated WebUI updates (supports the default WebUI and VUI)
  • OPDS and OPDS-PSE support (endpoint: /api/opds/v1.2)

Suwayomi client projects

You need a client/user interface app as a front-end for Suwayomi-Server, if you Directly Download Suwayomi-Server you'll get a bundled version of Suwayomi-WebUI with it.

Here's a list of known clients/user interfaces for Suwayomi-Server (checkout the respective GitHub repository for their features):

Actively Developed Clients
  • Suwayomi-WebUI: The web front-end that Suwayomi-Server ships with by default.
  • Suwayomi-VUI: A Suwayomi-Server preview focused web frontend built with svelte
  • Tachidesk-VaadinUI: A Web front-end for Suwayomi-Server built with Vaadin.
Inactive Clients (functional but outdated)
  • Tachidesk-JUI: The native desktop front-end for Suwayomi-Server.
  • Tachidesk-Sorayomi: A Flutter front-end for Desktop(Linux, windows, etc.), Web and Android with a User Interface inspired by Mihon (Tachiyomi).
Abandoned Clients (functionality unknown)
  • Tachidesk-qtui: A C++/Qt front-end for mobile devices(Android/linux), feature support is basic.
  • Tachidesk-GTK: A native Rust/GTK desktop client.
  • Equinox: A web user interface made with Vue.js.

Downloading and Running the app

Using Operating System Specific Bundles

To facilitate the use of Suwayomi we provide bundle releases that include The Java Runtime Environment, ElectronJS and the Suwayomi-Launcher.

If a bundle for your operating system or cpu architecture is not provided then refer to Advanced Methods

Windows

Download the latest win64(Windows 64-bit) release from the releases section or a preview one from the preview repository.

Unzip the downloaded file and double-click on one of the launcher scripts.

macOS

Download the latest macOS-x64(older macOS systems) or macOS-arm64(Apple M1 and newer) release from the releases section or a preview one from the preview repository.

Unzip the downloaded file and double-click on one of the launcher scripts.

GNU/Linux

Download the latest linux-x64(x86_64) release from the releases section or a preview one from the preview repository.

tar xvf the downloaded file and double-click on one of the launcher scripts or run them using the terminal.

WebView support (GNU/Linux)

WebView support is implemented via KCEF. This is optional, and is only necessary to support some extensions.

To have a functional WebView, several dependencies are required; aside from X11 libraries necessary for rendering Chromium, some JNI bindings are necessary: gluegen and jogl (found in Ubuntu as libgluegen2-jni and libjogl2-jni). Note that on some systems (e.g. Ubuntu), the JNI libraries are not automatically found, see below.

A KCEF server is launched on startup, which loads the X11 libraries. If those are missing, you should see "Could not load 'jcef' library". If so, use ldd ~/.local/share/Tachidesk/bin/kcef/libjcef.so | grep not to figure out which libraries are not found on your system.

The JNI bindings are only loaded when a browser is actually launched. This is done by extensions that rely on WebView, not by Suwayomi itself. If there is a problem loading the JNI libraries, you should see a message indicating the library and the search path. This search path includes the current working directory, if you do not want to modify system directories.

Refer to the Dockerfile for more details.

Other methods of getting Suwayomi

Docker

Check our Official Docker release Suwayomi Container for running Suwayomi Server in a docker container. Source code for our container is available at docker-tachidesk, an example compose file can also be found there. By default, the server will be running on http://localhost:4567 open this url in your browser.

Arch Linux

You can install Suwayomi from the AUR:

yay -S tachidesk

Debian/Ubuntu

Download the latest deb package from the release section.

Caution

These options are outdated and unmaintained (relevant issue)

MPR

git clone https://mpr.makedeb.org/tachidesk-server.git
cd tachidesk-server
makedeb -si

Ubuntu

sudo add-apt-repository ppa:suwayomi/tachidesk-server
sudo apt update
sudo apt install tachidesk-server

NixOS

You can deploy Suwayomi on NixOS using the module services.suwayomi-server in your configuration:

{
  services.suwayomi-server = {
    enable = true;
  };
}

For more information, see the NixOS manual.

You can also directly use the package from nixpkgs.

Advanced Methods

Running the jar release directly

In order to run the app you need the following:

  • The jar release of Suwayomi-Server
  • The Java Runtime Environment(JRE) 21 or newer
  • A Browser like Google Chrome, Firefox, Edge, etc.
  • ElectronJS (optional)

Download the latest .jar release from the releases section or a preview jar build from the preview repository.

Make sure you have The Java Runtime Environment installed on your system, Double-click on the jar file or run java -jar Suwayomi-Server-vX.Y.Z-rxxxx.jar from a Terminal/Command Prompt window to run the app which will open a new browser window automatically.

Using Suwayomi Remotely

You can run Suwayomi on your computer or a server and connect to it remotely through one of our clients or the bundled web interface with a web browser. This method of using Suwayomi is requiring a bit of networking/firewall/port forwarding/server configuration/etc. knowledge on your side, if you can run a Minecraft server and configure it, then you are good to go.

Check out this wiki page for a guide on configuring Suwayomi-Server.

If you face issues with your setup then we are happy to provide help, just join our discord server(a discord badge is on the top of the page, you are just a click-clack away!).

Syncing With Mihon (Tachiyomi) and Neko

The Suwayomi extension and tracker

  • You can install and configure the Suwayomi extension inside Mihon (Tachiyomi) and forks.
  • The extension will load your Suwayomi library.
  • By manipulating extension search filters you can browse your categories.
  • You can enable the Suwayomi tracker to track reading progress with your Suwayomi server.
    • Note: to sync from
      • Mihon (Tachiyomi) to Suwayomi: Mihon (Tachiyomi) automatically updates the chapters read status when it's updating the tracker (e.g. while reading)
      • Suwayomi to Mihon (Tachiyomi): To sync Mihon (Tachiyomi) with Suwayomi, you have to open the manga's track information, then, Mihon (Tachiyomi) will automatically update its chapter list with the state from Suwayomi

The Suwayomi merge source in Neko

  • You can enable the Suwayomi source in the Merge Source settings
  • You can merge titles in Neko with titles from your Suwayomi library.
  • You can enable 2-way automatic sync to track reading progress with your Suwayomi server.
    • Note: only applies to merged titles
      • Neko automatically updates the chapters read status in Suwayomi
      • During updates, Neko will automatically update its chapter list with the read state from Suwayomi
      • This only pulls if the status is read, to prevent marking read chapters as unread in Neko

Other methods

Checkout this issue for tracking progress.

Troubleshooting and Support

See this troubleshooting wiki page.

Contributing and Technical info

See CONTRIBUTING.md.

Translation

Feel free to translate the project on Weblate

Translation Progress Translation status

Credit

This project is a spiritual successor of TachiWeb-Server, Many of the ideas and the groundwork adopted in this project comes from TachiWeb.

The AndroidCompat module was originally developed by @null-dev for TachiWeb-Server and is licensed under Apache License Version 2.0 and Copyright 2019 Andy Bao and contributors.

Parts of Mihon (Tachiyomi) is adopted into this codebase, also licensed under Apache License Version 2.0 and Copyright 2015 Javier Tomás.

You can obtain a copy of Apache License Version 2.0 from http://www.apache.org/licenses/LICENSE-2.0

Changes to both codebases is licensed under MPL v. 2.0 as the rest of this project.

License

Copyright (C) Contributors to the Suwayomi project

This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.

Disclaimer

The developer of this application does not have any affiliation with the content providers available.

Description
No description provided
Readme MPL-2.0 92 MiB
Languages
Java 64.5%
Kotlin 35%
Shell 0.3%
HTML 0.1%