api | ||
assets | ||
client/syncninja.koplugin | ||
cmd | ||
config | ||
database | ||
graph | ||
metadata | ||
server | ||
templates | ||
utils | ||
.envrc | ||
.gitignore | ||
.sqlfluff | ||
API.md | ||
docker-compose.yml | ||
Dockerfile | ||
go.mod | ||
go.sum | ||
Makefile | ||
README.md | ||
shell.nix | ||
sqlc.yaml |
Book PWA
Development
SQLC Generation:
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
~/go/bin/sqlc generate
Run Development:
CONFIG_PATH=./config_data go run cmd/main.go serve
Notes
- Books can potentially be updated, deleted, added
- Read activity is static, but can be added and deleted
- Icons: https://www.svgrepo.com/collection/solar-bold-icons
Data
-
./settings/bookinfo_cache.sqlite3
- Contains Deleted Books
SELECT directory, filename, title, authors FROM bookinfo;
-
./settings/statistics.sqlite3
- Contains Deleted Books
SELECT * from book;
Client New Plugin Logic
Background Processes: https://github.com/koreader/koreader/blob/master/plugins/coverbrowser.koplugin/bookinfomanager.lua#L682C11-L701 Check if Files Exist: https://github.com/koreader/koreader/blob/master/plugins/coverbrowser.koplugin/bookinfomanager.lua#L582 API Client: https://github.com/koreader/koreader/blob/master/plugins/kosync.koplugin/KOSyncClient.lua Spore Upload File: https://fperrad.frama.io/lua-Spore/spore/#global-functions
-
POST /sync/documents/check
DATA: { "have": [id1, id2] } RESP: { "want": [id1], "give": [{...doc_data}], "delete": [id2] }
-
PUT /sync/documents/file/ (IF WANT, FOR EACH)
DATA: ID FILE RESP: {status:ok}
-
POST /sync/documents (IF WANT)
DATA: [{...doc_data}] RESP: {status:ok}
-
GET /sync/documents/file/ (FOR EACH IF GIVE & FILE DOESNT EXIST)
DATA: ID FILE
Schema
Books Schema (User Agnostic):
- Hash Identifier (X BYTES MD5)
- MD5 (Actual MD5)
- Filepath
- Title
- Author
- Series
- Series Index
- Language
- Description
- LastUpdated
- WantMetadata Flag (Default TRUE)
- IsDeleted Flag (Default FALSE)
Device Schema:
- ID
- UserID
- DeviceName
BookDeviceSync Schema:
- UserID
- BookID
- DeviceID
- LastSynced
- Sync (DEFAULT TRUE)
BookProgress Schema:
- UserID
- BookID
- DeviceID
- Percentage
- Progress
- CreateAt
BookReadActivity Schema:
- UserID
- BookID
- DeviceID
- StartTime
- Duration (Seconds)
- CurrentPage
- TotalPages
- CreatedAt
Notes
- If user has book on device, set BookDeviceSync.Sync = TRUE
Other
POST /sync/all/check
DATA: {
books: [{ md5, percentage }, ...]
last_activity: <TS>
}
POST /sync/all/check
DATA: {
books: [{ md5: <MD5>, last_open: <TS> }],
last_activity: <TS>
}
RESP: {
add: {
books: [],
activity: []
},
want: {
books: [],
activity_after: <TS>
}
books: ["<MD51>", "MD52"],
activity_since: <TS>
}
POST /sync/all
// Get server books
GET /sync/books
RESP: ["id1"]
// Send missing books
POST /sync/books
DATA: [{...book1 }, {...book2}, ...]
RESP: {status: ok}
// Get server activity
GET /sync/activity
RESP: [
{ device_id: <DEV_ID>, last_activity: <TIMSTAMP> },
{ device_id: <DEV_ID>, last_activity: <TIMSTAMP> },
...
]
// Send missing activity
POST /sync/activity
DATA: [{..activity}, {...activity}, ...]
TODO - Server
-
Build Sync API
-
Add Statistics Endpoint
-
Separate App?
-
Modified Sync Lua Plugin?
-
PUT /syncs/progress
{ // Original Parameters document: <MD5> progress: percentage: device: device_id: }
-
POST /syncs/statistics
{ book_id: <MD5>, page: 123, start_time: 1693403388, duration: 8, }
-
Goals
- Logins
- Plugins
- PWA
- Store Books in IndexDB (Limit: 500MB or half of available storage)
- Dark Mode
- Service Worker Resource Cache (i.e. Offline capable)
- Sync State API - Compatible with KOReader Sync API
- User Support
- Library Genesis Integration
- OPDS Integration
Pages
- Settings
- Reader
- Downloader