retold-remote 0.0.22 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/css/retold-remote.css +87 -20
- package/docs/README.md +59 -11
- package/docs/_sidebar.md +1 -0
- package/docs/collections.md +30 -0
- package/docs/ebook-reader.md +75 -1
- package/docs/image-explorer.md +27 -1
- package/docs/server-setup.md +28 -18
- package/docs/stack-launcher.md +218 -0
- package/docs/ultravisor-integration.md +2 -0
- package/package.json +10 -7
- package/source/Pict-Application-RetoldRemote.js +2 -0
- package/source/RetoldRemote-ExtensionMaps.js +1 -1
- package/source/cli/RetoldRemote-Server-Setup.js +240 -2
- package/source/cli/RetoldRemote-Stack-Launcher.js +387 -0
- package/source/cli/RetoldRemote-Stack-Run.js +41 -0
- package/source/cli/commands/RetoldRemote-Command-Serve.js +129 -54
- package/source/providers/CollectionManager-AddItems.js +166 -0
- package/source/providers/Pict-Provider-GalleryNavigation.js +46 -0
- package/source/providers/keyboard-handlers/KeyHandler-ImageExplorer.js +5 -0
- package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +23 -0
- package/source/server/RetoldRemote-CollectionExportService.js +696 -0
- package/source/server/RetoldRemote-CollectionService.js +5 -0
- package/source/server/RetoldRemote-EbookService.js +194 -3
- package/source/server/RetoldRemote-SubimageService.js +530 -0
- package/source/server/RetoldRemote-ToolDetector.js +50 -0
- package/source/server/RetoldRemote-UltravisorOperations.js +6 -6
- package/source/views/MediaViewer-EbookViewer.js +419 -1
- package/source/views/MediaViewer-PdfViewer.js +963 -0
- package/source/views/PictView-Remote-CollectionsPanel.js +166 -0
- package/source/views/PictView-Remote-ImageExplorer.js +606 -1
- package/source/views/PictView-Remote-ImageViewer.js +2 -2
- package/source/views/PictView-Remote-Layout.js +12 -0
- package/source/views/PictView-Remote-MediaViewer.js +83 -25
- package/source/views/PictView-Remote-SubimagesPanel.js +353 -0
- package/web-application/css/retold-remote.css +87 -20
- package/web-application/docs/README.md +59 -11
- package/web-application/docs/_sidebar.md +1 -0
- package/web-application/docs/collections.md +30 -0
- package/web-application/docs/ebook-reader.md +75 -1
- package/web-application/docs/image-explorer.md +27 -1
- package/web-application/docs/server-setup.md +28 -18
- package/web-application/docs/stack-launcher.md +218 -0
- package/web-application/docs/ultravisor-integration.md +2 -0
- package/web-application/retold-remote.js +399 -45
- package/web-application/retold-remote.js.map +1 -1
- package/web-application/retold-remote.min.js +13 -12
- package/web-application/retold-remote.min.js.map +1 -1
package/css/retold-remote.css
CHANGED
|
@@ -2263,26 +2263,7 @@ html, body
|
|
|
2263
2263
|
{
|
|
2264
2264
|
opacity: 1;
|
|
2265
2265
|
}
|
|
2266
|
-
|
|
2267
|
-
{
|
|
2268
|
-
position: absolute;
|
|
2269
|
-
bottom: 16px;
|
|
2270
|
-
right: 16px;
|
|
2271
|
-
background: rgba(40, 44, 52, 0.85);
|
|
2272
|
-
color: #abb2bf;
|
|
2273
|
-
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
2274
|
-
padding: 6px 14px;
|
|
2275
|
-
border-radius: 6px;
|
|
2276
|
-
font-size: 0.82rem;
|
|
2277
|
-
cursor: pointer;
|
|
2278
|
-
z-index: 20;
|
|
2279
|
-
transition: background 0.2s, color 0.2s;
|
|
2280
|
-
}
|
|
2281
|
-
.retold-remote-image-explore-btn:hover
|
|
2282
|
-
{
|
|
2283
|
-
background: rgba(97, 175, 239, 0.3);
|
|
2284
|
-
color: #fff;
|
|
2285
|
-
}
|
|
2266
|
+
/* Explore button overlay styles removed — button moved to nav bar */
|
|
2286
2267
|
.retold-remote-image-large-badge
|
|
2287
2268
|
{
|
|
2288
2269
|
position: absolute;
|
|
@@ -2480,6 +2461,75 @@ html, body
|
|
|
2480
2461
|
text-align: center;
|
|
2481
2462
|
color: var(--retold-text-secondary);
|
|
2482
2463
|
}
|
|
2464
|
+
/* Subimage region overlays */
|
|
2465
|
+
.retold-remote-iex-region-overlay
|
|
2466
|
+
{
|
|
2467
|
+
border: 2px solid rgba(229, 192, 123, 0.85);
|
|
2468
|
+
background: rgba(229, 192, 123, 0.08);
|
|
2469
|
+
pointer-events: none;
|
|
2470
|
+
position: relative;
|
|
2471
|
+
}
|
|
2472
|
+
/* Subimages sidebar panel */
|
|
2473
|
+
.retold-remote-subimages-panel
|
|
2474
|
+
{
|
|
2475
|
+
overflow-y: auto;
|
|
2476
|
+
height: 100%;
|
|
2477
|
+
}
|
|
2478
|
+
.retold-remote-subimages-item
|
|
2479
|
+
{
|
|
2480
|
+
display: flex;
|
|
2481
|
+
align-items: center;
|
|
2482
|
+
justify-content: space-between;
|
|
2483
|
+
padding: 6px 10px;
|
|
2484
|
+
border-bottom: 1px solid var(--retold-border);
|
|
2485
|
+
cursor: default;
|
|
2486
|
+
transition: background 0.15s;
|
|
2487
|
+
}
|
|
2488
|
+
.retold-remote-subimages-item:hover
|
|
2489
|
+
{
|
|
2490
|
+
background: rgba(255, 255, 255, 0.04);
|
|
2491
|
+
}
|
|
2492
|
+
.retold-remote-subimages-item-info
|
|
2493
|
+
{
|
|
2494
|
+
flex: 1;
|
|
2495
|
+
min-width: 0;
|
|
2496
|
+
overflow: hidden;
|
|
2497
|
+
}
|
|
2498
|
+
.retold-remote-subimages-item-label
|
|
2499
|
+
{
|
|
2500
|
+
font-size: 0.82rem;
|
|
2501
|
+
color: var(--retold-text);
|
|
2502
|
+
white-space: nowrap;
|
|
2503
|
+
overflow: hidden;
|
|
2504
|
+
text-overflow: ellipsis;
|
|
2505
|
+
}
|
|
2506
|
+
.retold-remote-subimages-item-dims
|
|
2507
|
+
{
|
|
2508
|
+
font-size: 0.7rem;
|
|
2509
|
+
color: var(--retold-text-dim);
|
|
2510
|
+
margin-top: 1px;
|
|
2511
|
+
}
|
|
2512
|
+
.retold-remote-subimages-item-actions
|
|
2513
|
+
{
|
|
2514
|
+
display: flex;
|
|
2515
|
+
gap: 2px;
|
|
2516
|
+
margin-left: 6px;
|
|
2517
|
+
flex-shrink: 0;
|
|
2518
|
+
}
|
|
2519
|
+
.retold-remote-subimages-item-actions button
|
|
2520
|
+
{
|
|
2521
|
+
background: transparent;
|
|
2522
|
+
border: 1px solid var(--retold-border);
|
|
2523
|
+
border-radius: 3px;
|
|
2524
|
+
color: var(--retold-text-dim);
|
|
2525
|
+
cursor: pointer;
|
|
2526
|
+
transition: color 0.15s, border-color 0.15s;
|
|
2527
|
+
}
|
|
2528
|
+
.retold-remote-subimages-item-actions button:hover
|
|
2529
|
+
{
|
|
2530
|
+
color: var(--retold-text);
|
|
2531
|
+
border-color: var(--retold-accent);
|
|
2532
|
+
}
|
|
2483
2533
|
|
|
2484
2534
|
/* ============================================================
|
|
2485
2535
|
AudioExplorer
|
|
@@ -3515,6 +3565,23 @@ html, body
|
|
|
3515
3565
|
border-color: var(--retold-accent);
|
|
3516
3566
|
color: var(--retold-text-primary);
|
|
3517
3567
|
}
|
|
3568
|
+
.retold-remote-collections-export-btn
|
|
3569
|
+
{
|
|
3570
|
+
padding: 3px 8px;
|
|
3571
|
+
border: 1px solid var(--retold-border);
|
|
3572
|
+
border-radius: 3px;
|
|
3573
|
+
background: transparent;
|
|
3574
|
+
color: var(--retold-text-muted);
|
|
3575
|
+
font-size: 0.72rem;
|
|
3576
|
+
cursor: pointer;
|
|
3577
|
+
font-family: inherit;
|
|
3578
|
+
margin-left: auto;
|
|
3579
|
+
}
|
|
3580
|
+
.retold-remote-collections-export-btn:hover
|
|
3581
|
+
{
|
|
3582
|
+
border-color: var(--retold-accent);
|
|
3583
|
+
color: var(--retold-text-primary);
|
|
3584
|
+
}
|
|
3518
3585
|
/* ---- Item rows ---- */
|
|
3519
3586
|
.retold-remote-collection-item
|
|
3520
3587
|
{
|
package/docs/README.md
CHANGED
|
@@ -4,10 +4,18 @@ A browser-based media server and NAS file explorer. Point it at a folder and bro
|
|
|
4
4
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
|
+
Just the media browser:
|
|
8
|
+
|
|
7
9
|
```bash
|
|
8
10
|
npx retold-remote serve /path/to/media
|
|
9
11
|
```
|
|
10
12
|
|
|
13
|
+
The full stack (Retold Remote + embedded Orator-Conversion + child Ultravisor):
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
retold-stack /path/to/media
|
|
17
|
+
```
|
|
18
|
+
|
|
11
19
|
Or with Docker:
|
|
12
20
|
|
|
13
21
|
```bash
|
|
@@ -17,17 +25,24 @@ docker run -p 8086:8086 -v /path/to/media:/media retold-remote
|
|
|
17
25
|
|
|
18
26
|
Then open `http://localhost:8086` in a browser.
|
|
19
27
|
|
|
28
|
+
See [Stack Launcher](stack-launcher.md) for what `retold-stack` does and how the XDG-style data paths work.
|
|
29
|
+
|
|
20
30
|
## Features
|
|
21
31
|
|
|
22
32
|
- **Gallery browser** with grid and list views, thumbnail generation, and lazy loading
|
|
23
33
|
- **Image viewer** with three fit modes, 0.25x-8x zoom, and EXIF orientation support
|
|
24
34
|
- **Video viewer** with action menu, in-browser playback, VLC streaming, and frame explorer
|
|
25
35
|
- **Audio viewer** with waveform visualization, selection-based playback, and segment extraction
|
|
26
|
-
- **eBook reader** for EPUB and MOBI with table of contents and
|
|
36
|
+
- **eBook reader** for EPUB and MOBI with table of contents, page navigation, text selection capture, and visual region selection
|
|
37
|
+
- **PDF viewer** with full pdf.js rendering, page navigation, text layer selection, and visual region selection
|
|
38
|
+
- **Document conversion** for DOC, DOCX, RTF, ODT, WPD, ODP, PPT(X), ODS, XLS(X) — converted to PDF on the fly via Orator-Conversion + LibreOffice
|
|
27
39
|
- **Code/text viewer** with syntax highlighting for 30+ languages
|
|
28
|
-
- **PDF viewer** via native browser rendering
|
|
29
40
|
- **Archive browsing** into zip, 7z, rar, tar.gz, cbz, and cbr files as virtual folders
|
|
30
41
|
- **Filtering and sorting** by media type, extension, file size, date, and text search (with regex)
|
|
42
|
+
- **Subimage regions** — draw labeled rectangles on images, ebook pages, and PDF pages; persisted per file
|
|
43
|
+
- **Collections & Export** — bookmark files, image crops, video clips, audio clips, and document regions; export the whole collection to a folder with proper file cutting
|
|
44
|
+
- **Stack mode** — single command launches Ultravisor coordinator + Retold Remote + embedded Orator-Conversion with sane XDG data paths
|
|
45
|
+
- **Ultravisor offload** — heavy work (frame extraction, waveforms, conversions) dispatched to a beacon worker on a faster machine
|
|
31
46
|
- **15 themes** from greyscale to retro and cyberpunk
|
|
32
47
|
- **Full keyboard navigation** across every mode
|
|
33
48
|
- **Media type override** to force any file open as image, video, audio, or text (keys 1-4)
|
|
@@ -40,14 +55,16 @@ Then open `http://localhost:8086` in a browser.
|
|
|
40
55
|
| Document | Contents |
|
|
41
56
|
|----------|----------|
|
|
42
57
|
| [Server Setup and Docker](server-setup.md) | Installation, CLI options, environment variables, configuration, Docker |
|
|
58
|
+
| [Stack Launcher](stack-launcher.md) | `retold-stack` and `--stack` flag, XDG paths, child process orchestration |
|
|
59
|
+
| [Ultravisor Integration](ultravisor-integration.md) | Offloading heavy media processing to a beacon worker |
|
|
43
60
|
| [Image Viewer](image-viewer.md) | Fit modes, zoom, keyboard shortcuts, mouse interactions |
|
|
44
61
|
| [Video Viewer](video-viewer.md) | Action menu, in-browser playback, VLC streaming |
|
|
45
62
|
| [Audio Viewer](audio-viewer.md) | HTML5 playback, autoplay, VLC streaming |
|
|
46
|
-
| [eBook Reader](ebook-reader.md) | EPUB/MOBI support,
|
|
47
|
-
| [Image Explorer](image-explorer.md) | Deep-zoom with OpenSeadragon, DZI tiling,
|
|
63
|
+
| [eBook Reader](ebook-reader.md) | EPUB/MOBI support, TOC, page nav, text/region selection |
|
|
64
|
+
| [Image Explorer](image-explorer.md) | Deep-zoom with OpenSeadragon, DZI tiling, region selection |
|
|
48
65
|
| [Video Explorer](video-explorer.md) | Frame grid, timeline, range selection, clip extraction |
|
|
49
66
|
| [Audio Explorer](audio-explorer.md) | Waveform visualization, selection, zoom, segment playback |
|
|
50
|
-
| [Collections](collections.md) | Bookmarks, favorites, quick-add, item types, operation plans |
|
|
67
|
+
| [Collections](collections.md) | Bookmarks, favorites, quick-add, item types, operation plans, export |
|
|
51
68
|
| [File Metadata](metadata.md) | Info overlay, sidebar metadata, EXIF/GPS, ffprobe, explorer info bars |
|
|
52
69
|
|
|
53
70
|
## Keyboard Shortcuts (All Modes)
|
|
@@ -158,11 +175,24 @@ In the frame preview overlay:
|
|
|
158
175
|
| `+` / `=` | Zoom in |
|
|
159
176
|
| `-` | Zoom out |
|
|
160
177
|
| `0` | Reset zoom |
|
|
161
|
-
| `
|
|
178
|
+
| `s` | Toggle region selection mode (draw rectangles) |
|
|
179
|
+
| `a` | Quick-add to collection (current region if selected) |
|
|
162
180
|
| `b` | Toggle collection panel |
|
|
163
181
|
| `h` | Toggle favorite |
|
|
164
182
|
| `Esc` | Back to viewer |
|
|
165
183
|
|
|
184
|
+
### Document Viewer (PDF / EPUB)
|
|
185
|
+
|
|
186
|
+
| Key | Action |
|
|
187
|
+
|-----|--------|
|
|
188
|
+
| `s` | Toggle visual region selection mode |
|
|
189
|
+
| `a` | Quick-add document region to collection |
|
|
190
|
+
| `Esc` | Back to gallery |
|
|
191
|
+
|
|
192
|
+
In the PDF viewer, page navigation buttons and a page input are in the controls bar. The text layer supports native browser text selection — use the **Save Selection** button to capture selected text as a labeled region.
|
|
193
|
+
|
|
194
|
+
In the EPUB reader, the controls bar exposes **Save Selection** (captures the selected text + CFI) and **Select Region** (draws a rectangle over the rendered page).
|
|
195
|
+
|
|
166
196
|
### Sidebar (F9)
|
|
167
197
|
|
|
168
198
|
| Key | Action |
|
|
@@ -184,7 +214,9 @@ mp4, webm, mov, mkv, avi, wmv, flv, m4v, ogv, mpg, mpeg, mpe, mpv, m2v, ts, mts,
|
|
|
184
214
|
mp3, wav, ogg, flac, aac, m4a, wma, oga
|
|
185
215
|
|
|
186
216
|
### Documents
|
|
187
|
-
pdf, epub, mobi
|
|
217
|
+
pdf, epub, mobi, doc, docx, rtf, odt, wpd, wps, pages, odp, ppt, pptx, ods, xls, xlsx
|
|
218
|
+
|
|
219
|
+
Documents beyond pdf/epub/mobi are converted to PDF on the fly via the embedded Orator-Conversion service (requires LibreOffice or Calibre on the server).
|
|
188
220
|
|
|
189
221
|
### Archives
|
|
190
222
|
zip, 7z, rar, tar, tar.gz, tar.bz2, tar.xz, tgz, cbz, cbr
|
|
@@ -204,13 +236,16 @@ These external tools enhance functionality when available on the server:
|
|
|
204
236
|
|
|
205
237
|
| Tool | Feature |
|
|
206
238
|
|------|---------|
|
|
207
|
-
| **sharp** (npm) | Fast image thumbnail generation |
|
|
239
|
+
| **sharp** (npm) | Fast image thumbnail generation, region cropping |
|
|
208
240
|
| **ImageMagick** | Fallback image thumbnails |
|
|
209
|
-
| **ffmpeg** | Video thumbnails, frame extraction, audio waveforms |
|
|
241
|
+
| **ffmpeg** | Video thumbnails, frame extraction, audio waveforms, clip cutting |
|
|
210
242
|
| **ffprobe** | Media metadata (duration, resolution, codec) |
|
|
211
243
|
| **7-Zip** (7z) | Archive browsing for rar, 7z, tar.* formats |
|
|
212
244
|
| **VLC** | External video streaming |
|
|
213
|
-
| **
|
|
245
|
+
| **audiowaveform** (BBC) | Faster audio waveform peak generation |
|
|
246
|
+
| **ebook-convert** (Calibre) | MOBI/AZW to EPUB conversion (and PDF fallback for documents) |
|
|
247
|
+
| **LibreOffice** (`soffice`) | DOC/DOCX/RTF/ODT/WPD/PPT(X)/XLS(X) to PDF conversion |
|
|
248
|
+
| **pdftk** + **pdftoppm** (poppler) | PDF page extraction and rendering (used by Orator-Conversion) |
|
|
214
249
|
|
|
215
250
|
Without these tools the application still works -- images serve directly, videos play in-browser, and zip/cbz archives use native extraction.
|
|
216
251
|
|
|
@@ -231,7 +266,20 @@ Without these tools the application still works -- images serve directly, videos
|
|
|
231
266
|
| GET | `/api/media/audio-waveform?path=&peaks=` | Audio waveform peak data |
|
|
232
267
|
| GET | `/api/media/audio-segment?path=&start=&end=` | Extract audio segment |
|
|
233
268
|
| GET | `/api/media/ebook-convert?path=` | Convert MOBI to EPUB |
|
|
234
|
-
| GET | `/api/media/
|
|
269
|
+
| GET | `/api/media/doc-convert?path=` | Convert DOC/DOCX/RTF/ODT/WPD/etc. to PDF |
|
|
270
|
+
| GET | `/api/media/ebook/:cacheKey/:filename` | Serve converted ebook or PDF |
|
|
271
|
+
| GET | `/api/media/pdf-text?path=&page=` | Extract text from a PDF page |
|
|
272
|
+
| GET | `/api/media/subimage-regions?path=` | List labeled regions for an image, ebook, or PDF |
|
|
273
|
+
| POST | `/api/media/subimage-regions` | Add a labeled region (visual or text-selection) |
|
|
274
|
+
| PUT | `/api/media/subimage-regions/:id` | Update a region's label or coordinates |
|
|
275
|
+
| DELETE | `/api/media/subimage-regions/:id?path=` | Remove a labeled region |
|
|
276
|
+
| GET | `/api/collections` | List all collections |
|
|
277
|
+
| POST | `/api/collections/:guid/items` | Add items to a collection |
|
|
278
|
+
| POST | `/api/collections/:guid/export` | Export collection to a folder (cuts clips, crops images) |
|
|
279
|
+
| POST | `/api/conversion/1.0/doc-to-pdf` | Convert any document buffer to PDF (via Orator-Conversion) |
|
|
280
|
+
| POST | `/api/conversion/1.0/pdf-to-page-png/:Page` | Render a PDF page as PNG |
|
|
281
|
+
| POST | `/api/conversion/1.0/pdf-to-page-jpg/:Page/:LongSidePixels` | Render and resize a PDF page as JPEG |
|
|
282
|
+
| POST | `/api/conversion/1.0/image/resize` | Resize an image |
|
|
235
283
|
| POST | `/api/media/open` | Open file in external player (VLC) |
|
|
236
284
|
|
|
237
285
|
## License
|
package/docs/_sidebar.md
CHANGED
package/docs/collections.md
CHANGED
|
@@ -16,6 +16,11 @@ Press `a` in any mode to add the current item to a collection. If a collection i
|
|
|
16
16
|
| Video explorer | Video frame | Path, timestamp, cached frame image |
|
|
17
17
|
| Video explorer (with selection) | Video clip | Path, start time, end time |
|
|
18
18
|
| Audio explorer (with selection) | Audio clip | Path, start time, end time |
|
|
19
|
+
| Image explorer (with active region) | Image crop | Path, X, Y, Width, Height in original pixels |
|
|
20
|
+
| PDF viewer (with text selection) | Document region (text) | Path, page number, selected text |
|
|
21
|
+
| PDF viewer (with visual region) | Document region (visual) | Path, page number, X/Y/Width/Height in PDF units |
|
|
22
|
+
| EPUB reader (with text selection) | Document region (text) | Path, CFI, spine index, chapter title, selected text |
|
|
23
|
+
| EPUB reader (with visual region) | Document region (visual) | Path, X/Y/Width/Height in container coordinates |
|
|
19
24
|
|
|
20
25
|
### Folder Choice
|
|
21
26
|
|
|
@@ -136,11 +141,35 @@ Pending item destinations can be edited inline by clicking the destination path.
|
|
|
136
141
|
| `a` | Gallery, viewer, all explorers | Quick-add current item to collection |
|
|
137
142
|
| `s` | Video explorer | Add selected range as video clip |
|
|
138
143
|
| `s` | Audio explorer | Save audio snippet to collection |
|
|
144
|
+
| `s` | Image explorer | Toggle region selection mode |
|
|
145
|
+
| `s` | Document viewer (PDF/EPUB) | Toggle visual region selection mode |
|
|
139
146
|
| `[` | Video explorer | Set selection start at current frame |
|
|
140
147
|
| `]` | Video explorer | Set selection end at current frame |
|
|
141
148
|
| `b` | All modes | Toggle collection panel |
|
|
142
149
|
| `h` | All modes | Toggle favorite |
|
|
143
150
|
|
|
151
|
+
## Export
|
|
152
|
+
|
|
153
|
+
Collections can be exported to a folder within the content root. Each item is processed according to its type:
|
|
154
|
+
|
|
155
|
+
| Item Type | Export Behavior |
|
|
156
|
+
|-----------|----------------|
|
|
157
|
+
| `file` / `subfile` | Copied directly to the destination |
|
|
158
|
+
| `image-crop` | Cropped via sharp at the original resolution |
|
|
159
|
+
| `video-clip` | Extracted via `ffmpeg -ss -t -c copy` |
|
|
160
|
+
| `video-frame` | Extracted via `ffmpeg -ss -vframes 1` |
|
|
161
|
+
| `audio-clip` | Extracted via `ffmpeg -ss -t -vn` |
|
|
162
|
+
| `document-region` (text) | Written as a `.txt` file with the captured text and source metadata |
|
|
163
|
+
| `document-region` (visual) | Metadata file describing the page and region |
|
|
164
|
+
| `folder` | Copied recursively |
|
|
165
|
+
| `folder-contents` | Files copied flat into the destination |
|
|
166
|
+
|
|
167
|
+
Exported files are named `{sortOrder}_{label}.{ext}` so the order is preserved on disk.
|
|
168
|
+
|
|
169
|
+
To export, click the **⇩ Export** button in the collection detail header. You will be prompted for a destination path (relative to the content root).
|
|
170
|
+
|
|
171
|
+
The export endpoint is restricted to paths within the content root for safety — paths containing `..` or absolute paths are rejected.
|
|
172
|
+
|
|
144
173
|
## Data Storage
|
|
145
174
|
|
|
146
175
|
Collections are stored server-side as Bibliograph records. Each collection is a JSON document containing the collection metadata and its items array. The favorites collection uses a well-known GUID and is created automatically.
|
|
@@ -160,3 +189,4 @@ Client-side state (which collection is open, panel width, last-used collection)
|
|
|
160
189
|
| PUT | `/api/collections/:guid/reorder` | Reorder items (manual sort) |
|
|
161
190
|
| POST | `/api/collections/copy-items` | Copy items between collections |
|
|
162
191
|
| POST | `/api/collections/:guid/execute` | Execute pending operations (operation plans) |
|
|
192
|
+
| POST | `/api/collections/:guid/export` | Export the collection to a folder within the content root |
|
package/docs/ebook-reader.md
CHANGED
|
@@ -79,12 +79,86 @@ RUN apt-get update && apt-get install -y calibre && rm -rf /var/lib/apt/lists/*
|
|
|
79
79
|
|
|
80
80
|
## PDF Files
|
|
81
81
|
|
|
82
|
-
PDF files are rendered using
|
|
82
|
+
PDF files are rendered using a full **pdf.js** canvas pipeline. The library is loaded from CDN on first use; no server-side dependencies are required for basic display.
|
|
83
|
+
|
|
84
|
+
### Page Navigation
|
|
85
|
+
|
|
86
|
+
The controls bar exposes:
|
|
87
|
+
|
|
88
|
+
- **← Prev** / **Next →** — page navigation
|
|
89
|
+
- **Page input** — type a page number and press Enter to jump
|
|
90
|
+
- **Zoom In / Out / Fit** — adjust scale (0.25x – 5x)
|
|
91
|
+
|
|
92
|
+
### Text Selection
|
|
93
|
+
|
|
94
|
+
PDF.js renders an invisible text layer over the canvas, so native browser text selection works. Drag to select text, then click **💾 Save Selection** to capture it as a labeled region.
|
|
95
|
+
|
|
96
|
+
The capture stores: page number, selected text, optional label.
|
|
97
|
+
|
|
98
|
+
### Visual Region Selection
|
|
99
|
+
|
|
100
|
+
Click **✂ Select Region** to enter visual selection mode. A crosshair cursor appears over the page canvas. Drag a rectangle, release, and a label input appears in the controls bar.
|
|
101
|
+
|
|
102
|
+
The capture stores: page number, X/Y/Width/Height in PDF units (so the region remaps correctly at any zoom level), optional label.
|
|
103
|
+
|
|
104
|
+
### Server-Side Text Extraction
|
|
105
|
+
|
|
106
|
+
`GET /api/media/pdf-text?path=<file>&page=<num>` returns the extracted text for a specific page (via pdf-parse). This is useful for search indexing or for when you want the full text without selecting it manually.
|
|
107
|
+
|
|
108
|
+
## Convertible Document Formats
|
|
109
|
+
|
|
110
|
+
Beyond PDF/EPUB/MOBI, the viewer also handles `.doc`, `.docx`, `.rtf`, `.odt`, `.wpd`, `.wps`, `.pages`, `.odp`, `.ppt`, `.pptx`, `.ods`, `.xls`, and `.xlsx` files. These are converted to PDF on the fly via the embedded **Orator-Conversion** service, then displayed in the same pdf.js viewer.
|
|
111
|
+
|
|
112
|
+
### Conversion Pipeline
|
|
113
|
+
|
|
114
|
+
1. The browser opens a convertible document
|
|
115
|
+
2. Retold Remote shows a "Converting document to PDF..." spinner
|
|
116
|
+
3. The server calls `GET /api/media/doc-convert?path=<file>` which delegates to `orator-conversion`'s `doc-to-pdf` custom converter
|
|
117
|
+
4. The converter pipes the file through LibreOffice headless (`soffice --headless --convert-to pdf`)
|
|
118
|
+
5. Falls back to Calibre's `ebook-convert` if LibreOffice is unavailable
|
|
119
|
+
6. The resulting PDF is cached in the same Parime cache as ebooks (separate `manifest-pdf.json`)
|
|
120
|
+
7. The browser loads the PDF in the standard pdf.js viewer with full text and region selection
|
|
121
|
+
|
|
122
|
+
Conversion results are cached per file (keyed by path + mtime), so reopening the same document is instant after the first conversion.
|
|
123
|
+
|
|
124
|
+
### Required Tools
|
|
125
|
+
|
|
126
|
+
| Tool | Use |
|
|
127
|
+
|------|-----|
|
|
128
|
+
| **LibreOffice** (`soffice`) | Best fidelity for Word, RTF, ODT, WordPerfect, PowerPoint, Excel |
|
|
129
|
+
| **Calibre** (`ebook-convert`) | Fallback for documents LibreOffice can't handle |
|
|
130
|
+
|
|
131
|
+
Install at least one of them on the server. On macOS: `brew install --cask libreoffice` or `brew install calibre`.
|
|
132
|
+
|
|
133
|
+
## eBook Selection Features
|
|
134
|
+
|
|
135
|
+
The EPUB reader supports the same labeled-region capture pattern as PDF and image viewers.
|
|
136
|
+
|
|
137
|
+
### Save Text Selection
|
|
138
|
+
|
|
139
|
+
1. Select text in the rendered EPUB content (works through the epub.js iframe via `getContents()`)
|
|
140
|
+
2. Click **💾 Save Selection** in the controls bar
|
|
141
|
+
3. Enter a label and save
|
|
142
|
+
|
|
143
|
+
The capture stores:
|
|
144
|
+
|
|
145
|
+
- **CFI** (Canonical Fragment Identifier) — exact location for re-navigating later
|
|
146
|
+
- **Spine index** — which section of the book
|
|
147
|
+
- **Chapter title** — best-effort lookup from the TOC
|
|
148
|
+
- **Selected text** — the actual highlighted prose
|
|
149
|
+
|
|
150
|
+
Click a saved text selection in the **Regions** sidebar tab to navigate back to its exact location via `rendition.display(cfi)`.
|
|
151
|
+
|
|
152
|
+
### Visual Region Selection
|
|
153
|
+
|
|
154
|
+
Click **✂ Select Region** to overlay a transparent crosshair on the rendered page. Drag a rectangle to capture a visual area. The capture stores X/Y/Width/Height plus the viewport dimensions at capture time (so coordinates can be remapped if the window is resized later).
|
|
83
155
|
|
|
84
156
|
## Limitations
|
|
85
157
|
|
|
86
158
|
- MOBI conversion requires Calibre's `ebook-convert` on the server
|
|
159
|
+
- Document conversion (DOC, DOCX, RTF, etc.) requires LibreOffice or Calibre on the server
|
|
87
160
|
- DRM-protected ebooks cannot be read
|
|
88
161
|
- Complex EPUB layouts (fixed-layout EPUBs, heavy CSS) may not render perfectly
|
|
89
162
|
- The reader uses single-page mode only (no two-page spreads)
|
|
90
163
|
- Page numbers shown in the UI correspond to the reflowed content, not the original book pagination
|
|
164
|
+
- EPUB visual region coordinates are container-relative; they remap reasonably at different window sizes but are not perfectly stable across major layout reflows
|
package/docs/image-explorer.md
CHANGED
|
@@ -51,11 +51,37 @@ If Sharp is not available on the server, the image loads directly regardless of
|
|
|
51
51
|
| `+` / `=` | Zoom in (1.5x) |
|
|
52
52
|
| `-` | Zoom out (1.5x) |
|
|
53
53
|
| `0` | Reset to home zoom (fit to view) |
|
|
54
|
-
| `
|
|
54
|
+
| `s` | Toggle region selection mode |
|
|
55
|
+
| `a` | Quick-add to active collection (current region if one is selected) |
|
|
55
56
|
| `b` | Toggle collection panel |
|
|
56
57
|
| `h` | Toggle favorite |
|
|
57
58
|
| `Esc` | Back to image viewer |
|
|
58
59
|
|
|
60
|
+
## Subimage Regions
|
|
61
|
+
|
|
62
|
+
Press `s` (or click the **✂ Select** button in the header) to enter region selection mode. The cursor changes to a crosshair and OpenSeadragon's drag-to-pan is temporarily disabled.
|
|
63
|
+
|
|
64
|
+
Drag a rectangle on the image. On release, an inline label input appears in the controls bar — type a name and hit Enter. The region is saved with these coordinates:
|
|
65
|
+
|
|
66
|
+
- **X, Y** — top-left corner in original image pixels
|
|
67
|
+
- **Width, Height** — dimensions in original image pixels
|
|
68
|
+
|
|
69
|
+
Saved regions render as gold-bordered overlays with floating label badges. They persist per file via the SubimageService and appear in the **Regions** sidebar tab.
|
|
70
|
+
|
|
71
|
+
### Region Actions
|
|
72
|
+
|
|
73
|
+
From the **Regions** sidebar tab you can:
|
|
74
|
+
|
|
75
|
+
- 🔍 **Navigate** — zoom the explorer to the saved region (`viewport.fitBounds(imageRect)`)
|
|
76
|
+
- ➕ **Add to Collection** — saves as an `image-crop` collection item with the original-pixel `CropRegion`
|
|
77
|
+
- 🗑️ **Delete** — removes the region
|
|
78
|
+
|
|
79
|
+
### Multiple Regions
|
|
80
|
+
|
|
81
|
+
You can save unlimited labeled regions per image. They never lose resolution because the coordinates are stored in the original image pixel space, not in viewport pixels. When the collection is exported, each region is cropped at full resolution via `sharp.extract()`.
|
|
82
|
+
|
|
83
|
+
This same labeling pattern works on CBZ/CBR comic pages (each page is a regular image inside an archive — no special handling needed) and is the foundation for the document region system in the EPUB and PDF viewers.
|
|
84
|
+
|
|
59
85
|
## Coordinate Display
|
|
60
86
|
|
|
61
87
|
In DZI tile mode, the info bar shows the pixel coordinates of the point under the cursor in real time (e.g., "(4096, 3072)"). This updates as the mouse moves across the canvas and reflects the actual pixel position in the original full-resolution image.
|
package/docs/server-setup.md
CHANGED
|
@@ -21,31 +21,31 @@ The build step bundles the client-side JavaScript with Quackage and copies asset
|
|
|
21
21
|
|
|
22
22
|
## Running the Server
|
|
23
23
|
|
|
24
|
-
### CLI
|
|
24
|
+
### CLI Commands
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
retold-remote serve [content-path] [options]
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Or using the short alias:
|
|
26
|
+
There are three bin entries provided by the `retold-remote` package:
|
|
31
27
|
|
|
32
28
|
```bash
|
|
33
|
-
|
|
29
|
+
retold-remote serve [content-path] [options] # full form
|
|
30
|
+
rr serve [content-path] [options] # short alias
|
|
31
|
+
retold-stack [content-path] [options] # convenience: serve --stack
|
|
34
32
|
```
|
|
35
33
|
|
|
36
34
|
If `content-path` is omitted, the current directory is served.
|
|
37
35
|
|
|
36
|
+
The `retold-stack` shortcut auto-injects `serve --stack`, which spawns Ultravisor as a child process and uses XDG-style data paths. See [Stack Launcher](stack-launcher.md) for the full story.
|
|
37
|
+
|
|
38
38
|
### Options
|
|
39
39
|
|
|
40
40
|
| Flag | Description | Default |
|
|
41
41
|
|------|-------------|---------|
|
|
42
42
|
| `-p, --port [port]` | Port to listen on | Random 7000-7999 |
|
|
43
|
-
|
|
|
44
|
-
| `-c, --cache-path [path]` | Root cache directory | `./dist/retold-cache/` |
|
|
45
|
-
| `--cache-
|
|
46
|
-
|
|
|
47
|
-
| `--
|
|
48
|
-
|
|
|
43
|
+
| `--no-hash` | Disable hashed filename mode (use plain paths in URLs) | Hashing on |
|
|
44
|
+
| `-c, --cache-path [path]` | Root cache directory | `./dist/retold-cache/` (or `~/.cache/retold-remote/` in stack mode) |
|
|
45
|
+
| `--cache-server [url]` | URL of a remote Parime cache server | None |
|
|
46
|
+
| `-u, --ultravisor [url]` | Connect to an Ultravisor mesh; URL defaults to `http://localhost:54321` if omitted | None |
|
|
47
|
+
| `--stack` | Spawn Ultravisor as a child process and connect to it. Uses XDG-style data paths under `~/.local/share` and `~/.cache`. See [Stack Launcher](stack-launcher.md) | Off |
|
|
48
|
+
| `-l, --logfile [path]` | Write logs to a file (auto-generates timestamped name if path omitted) | Console only |
|
|
49
49
|
|
|
50
50
|
### Direct Node.js
|
|
51
51
|
|
|
@@ -65,20 +65,30 @@ Default port is `8086` when using `server.js` directly.
|
|
|
65
65
|
### Examples
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
# Serve current directory on port
|
|
69
|
-
|
|
68
|
+
# Serve current directory on a random port
|
|
69
|
+
retold-remote serve
|
|
70
70
|
|
|
71
71
|
# Serve a specific folder
|
|
72
|
-
|
|
72
|
+
retold-remote serve /mnt/nas/media
|
|
73
73
|
|
|
74
74
|
# CLI with custom port
|
|
75
75
|
retold-remote serve /mnt/nas/media -p 3000
|
|
76
76
|
|
|
77
|
-
#
|
|
78
|
-
retold-remote serve /mnt/nas/media -
|
|
77
|
+
# Plain paths in URLs (disable hashing)
|
|
78
|
+
retold-remote serve /mnt/nas/media --no-hash
|
|
79
79
|
|
|
80
80
|
# Custom cache location (useful for Docker volumes)
|
|
81
81
|
retold-remote serve /media -c /cache
|
|
82
|
+
|
|
83
|
+
# Connect to an existing Ultravisor mesh
|
|
84
|
+
retold-remote serve /media -u http://192.168.1.100:54321
|
|
85
|
+
|
|
86
|
+
# Full stack: spawn Ultravisor as a child process, embed Orator-Conversion,
|
|
87
|
+
# use XDG paths (~/.local/share/ultravisor, ~/.cache/retold-remote)
|
|
88
|
+
retold-stack /mnt/nas/media
|
|
89
|
+
|
|
90
|
+
# Same thing via the explicit flag
|
|
91
|
+
retold-remote serve --stack /mnt/nas/media
|
|
82
92
|
```
|
|
83
93
|
|
|
84
94
|
## Configuration
|