Detect Kobo reader databases on Windows

This commit is contained in:
Ken 2026-05-18 20:05:53 +08:00
parent a8d802e5a7
commit 4dd411cbd8
3 changed files with 27 additions and 15 deletions

View file

@ -39,7 +39,7 @@ The plugin can read the local `Kobo.sqlite` database created by the Kobo Desktop
## Usage
1. In plugin settings, choose a sync source: **Kobo Desktop App** or **Custom SQLite file**
2. Confirm the database path for that source. In **Custom SQLite file** mode on macOS, you can use **Detect Kobo reader** to fill the path automatically.
2. Confirm the database path for that source. In **Custom SQLite file** mode on macOS or Windows, you can use **Detect Kobo reader** to fill the path automatically.
3. Open Command Palette (`Cmd/Ctrl + P`) and run **Kobo Note Sync**
4. Or click the book icon in the left sidebar
@ -60,7 +60,7 @@ This plugin includes `sql.js`, which is licensed under the MIT License. See [THI
| **Sync source** | Choose Kobo Desktop App or a custom SQLite file |
| **Kobo Desktop database path** | Path to `Kobo.sqlite`. Auto-detected based on your OS. |
| **Custom database file path** | Path to a copied Kobo SQLite database, such as `.kobo/KoboReader.sqlite` |
| **Detect Kobo reader** | Finds `/Volumes/*/.kobo/KoboReader.sqlite` on macOS and fills the custom database path |
| **Detect Kobo reader** | Finds `/Volumes/*/.kobo/KoboReader.sqlite` on macOS or `?:\.kobo\KoboReader.sqlite` on Windows and fills the custom database path |
| **Output folder** | Folder in your vault for highlight notes |
| **Note template** | Eta.js template for each book note |
| **Highlight template** | Eta.js template for each highlight |

View file

@ -39,7 +39,7 @@ Kobo 閱讀器 → 複製出的 KoboReader.sqlite → 本插件 → Obsidian 筆
## 使用方式
1. 在插件設定中選擇同步來源:**Kobo Desktop App** 或 **自訂 SQLite 檔案**
2. 確認該來源的資料庫路徑。在 macOS 的 **自訂 SQLite 檔案** 模式下,可以使用 **偵測 Kobo 閱讀器** 自動填入路徑。
2. 確認該來源的資料庫路徑。在 macOS 或 Windows **自訂 SQLite 檔案** 模式下,可以使用 **偵測 Kobo 閱讀器** 自動填入路徑。
3. 開啟命令面板(`Cmd/Ctrl + P`)執行 **Kobo Note Sync**
4. 或點擊左側工具列的書本圖示
@ -60,7 +60,7 @@ Kobo 閱讀器 → 複製出的 KoboReader.sqlite → 本插件 → Obsidian 筆
| **同步來源** | 選擇 Kobo Desktop App 或自訂 SQLite 檔案 |
| **Kobo Desktop 資料庫路徑** | `Kobo.sqlite` 的路徑,會根據作業系統自動偵測 |
| **自訂資料庫檔案路徑** | 自行複製出的 Kobo SQLite 資料庫,例如 `.kobo/KoboReader.sqlite` |
| **偵測 Kobo 閱讀器** | 在 macOS 尋找 `/Volumes/*/.kobo/KoboReader.sqlite` 並填入自訂資料庫路徑 |
| **偵測 Kobo 閱讀器** | 在 macOS 尋找 `/Volumes/*/.kobo/KoboReader.sqlite`,或在 Windows 尋找 `?:\.kobo\KoboReader.sqlite`並填入自訂資料庫路徑 |
| **輸出資料夾** | Vault 中儲存畫線筆記的資料夾 |
| **筆記模板** | 每本書的 Eta.js 模板 |
| **畫線模板** | 每條畫線的 Eta.js 模板 |

View file

@ -145,7 +145,7 @@ const locales: Record<string, LocaleStrings> = {
customDbPath: "Custom database file path",
customDbPathDesc: "Path to a copied Kobo SQLite database, such as .kobo/KoboReader.sqlite from your device",
detectKoboReader: "Detect Kobo reader",
detectKoboReaderDesc: "Find a connected Kobo reader on this Mac and fill the custom database path.",
detectKoboReaderDesc: "Find a connected Kobo reader on this computer and fill the custom database path.",
detectFound: (path) => `Kobo Note Sync: Found Kobo database at ${path}`,
detectNotFound: "Kobo Note Sync: No connected Kobo reader database found.",
outputFolder: "Output folder",
@ -172,7 +172,7 @@ const locales: Record<string, LocaleStrings> = {
customDbPath: "自訂資料庫檔案路徑",
customDbPathDesc: "自行複製出的 Kobo SQLite 資料庫,例如閱讀器中的 .kobo/KoboReader.sqlite",
detectKoboReader: "偵測 Kobo 閱讀器",
detectKoboReaderDesc: "尋找已連接到這台 Mac 的 Kobo 閱讀器,並填入自訂資料庫路徑。",
detectKoboReaderDesc: "尋找已連接到這台電腦的 Kobo 閱讀器,並填入自訂資料庫路徑。",
detectFound: (path) => `Kobo Note Sync找到 Kobo 資料庫:${path}`,
detectNotFound: "Kobo Note Sync找不到已連接的 Kobo 閱讀器資料庫。",
outputFolder: "輸出資料夾",
@ -283,21 +283,33 @@ function getActiveDbPath(settings: KoboHighlighterSettings): string {
}
function detectKoboReaderDbPath(): string | null {
if (os.platform() !== "darwin") return null;
const platform = os.platform();
const volumesDir = "/Volumes";
if (!fs.existsSync(volumesDir)) return null;
if (platform === "darwin") {
const volumesDir = "/Volumes";
if (!fs.existsSync(volumesDir)) return null;
try {
const volumes = fs.readdirSync(volumesDir).sort((a, b) => a.localeCompare(b));
for (const volume of volumes) {
const candidate = path.join(volumesDir, volume, ".kobo", "KoboReader.sqlite");
try {
const volumes = fs.readdirSync(volumesDir).sort((a, b) => a.localeCompare(b));
for (const volume of volumes) {
const candidate = path.join(volumesDir, volume, ".kobo", "KoboReader.sqlite");
if (fs.existsSync(candidate)) {
return candidate;
}
}
} catch {
return null;
}
}
if (platform === "win32") {
for (let code = 65; code <= 90; code++) {
const drive = `${String.fromCharCode(code)}:\\`;
const candidate = path.join(drive, ".kobo", "KoboReader.sqlite");
if (fs.existsSync(candidate)) {
return candidate;
}
}
} catch {
return null;
}
return null;