# 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: } POST /sync/all/check DATA: { books: [{ md5: , last_open: }], last_activity: } RESP: { add: { books: [], activity: [] }, want: { books: [], activity_after: } books: ["", "MD52"], activity_since: } 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: , last_activity: }, { device_id: , last_activity: }, ... ] // 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: progress: percentage: device: device_id: } ``` - POST /syncs/statistics ``` { book_id: , 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 -