retold-remote 0.0.23 → 0.0.26
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 +343 -20
- package/docs/.nojekyll +0 -0
- package/docs/README.md +64 -12
- package/docs/_cover.md +6 -6
- package/docs/_sidebar.md +2 -0
- package/docs/_topbar.md +1 -1
- package/docs/_version.json +7 -0
- package/docs/collections.md +30 -0
- package/docs/css/docuserve.css +327 -0
- package/docs/ebook-reader.md +75 -1
- package/docs/image-explorer.md +62 -2
- package/docs/index.html +39 -0
- package/docs/retold-catalog.json +254 -0
- package/docs/retold-keyword-index.json +31216 -0
- package/docs/server-setup.md +122 -91
- package/docs/stack-launcher.md +218 -0
- package/docs/synology.md +585 -0
- package/docs/ultravisor-configuration.md +5 -5
- package/docs/ultravisor-integration.md +4 -2
- package/package.json +20 -14
- package/source/Pict-Application-RetoldRemote.js +22 -0
- package/source/RetoldRemote-ExtensionMaps.js +1 -1
- package/source/cli/RetoldRemote-Server-Setup.js +460 -7
- package/source/cli/RetoldRemote-Stack-Launcher.js +563 -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 +55 -0
- package/source/providers/Pict-Provider-OperationStatus.js +597 -0
- package/source/providers/keyboard-handlers/KeyHandler-ImageExplorer.js +20 -1
- package/source/providers/keyboard-handlers/KeyHandler-Viewer.js +23 -0
- package/source/server/RetoldRemote-AudioWaveformService.js +49 -3
- package/source/server/RetoldRemote-CollectionExportService.js +763 -0
- package/source/server/RetoldRemote-CollectionService.js +5 -0
- package/source/server/RetoldRemote-EbookService.js +218 -3
- package/source/server/RetoldRemote-ImageService.js +221 -46
- package/source/server/RetoldRemote-MediaService.js +63 -4
- package/source/server/RetoldRemote-MetadataCache.js +25 -5
- package/source/server/RetoldRemote-OperationBroadcaster.js +363 -0
- package/source/server/RetoldRemote-SubimageService.js +680 -0
- package/source/server/RetoldRemote-ToolDetector.js +50 -0
- package/source/server/RetoldRemote-UltravisorBeacon.js +18 -3
- package/source/server/RetoldRemote-UltravisorDispatcher.js +65 -491
- package/source/server/RetoldRemote-UltravisorOperations.js +133 -20
- package/source/server/RetoldRemote-VideoFrameService.js +302 -9
- package/source/views/MediaViewer-EbookViewer.js +419 -1
- package/source/views/MediaViewer-PdfViewer.js +1050 -0
- package/source/views/PictView-Remote-AudioExplorer.js +77 -1
- package/source/views/PictView-Remote-CollectionsPanel.js +213 -0
- package/source/views/PictView-Remote-Gallery.js +365 -64
- package/source/views/PictView-Remote-ImageExplorer.js +1529 -44
- package/source/views/PictView-Remote-ImageViewer.js +2 -2
- package/source/views/PictView-Remote-Layout.js +58 -0
- package/source/views/PictView-Remote-MediaViewer.js +100 -25
- package/source/views/PictView-Remote-RegionsBrowser.js +554 -0
- package/source/views/PictView-Remote-SubimagesPanel.js +353 -0
- package/source/views/PictView-Remote-TopBar.js +1 -0
- package/source/views/PictView-Remote-VideoExplorer.js +77 -1
- package/web-application/css/docuserve.css +277 -23
- package/web-application/css/retold-remote.css +343 -20
- package/web-application/docs/README.md +64 -12
- package/web-application/docs/_cover.md +6 -6
- package/web-application/docs/_sidebar.md +2 -0
- package/web-application/docs/_topbar.md +1 -1
- package/web-application/docs/collections.md +30 -0
- package/web-application/docs/ebook-reader.md +75 -1
- package/web-application/docs/image-explorer.md +62 -2
- package/web-application/docs/server-setup.md +122 -91
- package/web-application/docs/stack-launcher.md +218 -0
- package/web-application/docs/synology.md +585 -0
- package/web-application/docs/ultravisor-configuration.md +5 -5
- package/web-application/docs/ultravisor-integration.md +4 -2
- package/web-application/js/pict-docuserve.min.js +12 -12
- package/web-application/js/pict.min.js +2 -2
- package/web-application/js/pict.min.js.map +1 -1
- package/web-application/retold-remote.js +6596 -1784
- package/web-application/retold-remote.js.map +1 -1
- package/web-application/retold-remote.min.js +75 -23
- package/web-application/retold-remote.min.js.map +1 -1
|
@@ -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
|
|
@@ -51,10 +51,70 @@ 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
|
-
| `Esc` |
|
|
58
|
+
| `Esc` | Unwind one layer: exit edit mode -> exit selection mode -> back to viewer |
|
|
59
|
+
|
|
60
|
+
`Esc` is layered: if you are editing a saved region, the first `Esc` exits edit mode; if you are drawing a new region, it cancels the draw; otherwise it closes the explorer.
|
|
61
|
+
|
|
62
|
+
## Subimage Regions
|
|
63
|
+
|
|
64
|
+
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.
|
|
65
|
+
|
|
66
|
+
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:
|
|
67
|
+
|
|
68
|
+
- **X, Y** -- top-left corner in original image pixels
|
|
69
|
+
- **Width, Height** -- dimensions in original image pixels
|
|
70
|
+
|
|
71
|
+
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. Overlays are restored automatically whenever you reopen the image, including after the tile-viewer swap for DZI-mode images.
|
|
72
|
+
|
|
73
|
+
### Editing Existing Regions
|
|
74
|
+
|
|
75
|
+
Double-click any saved region overlay to enter **edit mode**. The selected region is highlighted, the other regions dim to 35% opacity, and eight drag handles appear (four corners + four edges). Each handle has a larger invisible hit area around a small visible dot so it's easy to grab on both mouse and touch.
|
|
76
|
+
|
|
77
|
+
In edit mode you can:
|
|
78
|
+
|
|
79
|
+
- **Resize** -- drag a corner or edge handle. Dragging past the opposite edge flips the rectangle (so you can go from tl-drag to br-drag without re-entering edit mode).
|
|
80
|
+
- **Move** -- drag the body of the region.
|
|
81
|
+
- **Edit label** -- the inline label input in the controls bar is pre-filled with the current label. Change it and press `Enter` (or click Save).
|
|
82
|
+
- **Cancel** -- click the Cancel button, press `Esc`, or double-click a different region.
|
|
83
|
+
|
|
84
|
+
Geometry and label changes are **optimistic**: they apply locally the instant you release the drag or press Enter, then fire a `PUT /api/media/subimage-regions/:id` in the background. If the server request fails (e.g., because the file's mtime changed since the region was loaded), the change reverts and a toast explains the failure.
|
|
85
|
+
|
|
86
|
+
While in edit mode OpenSeadragon's mouse navigation (pan/zoom/click-to-zoom) is suspended inside the region rectangle so drags on the handles or body don't also pan the viewer. Clicks outside any region still pan normally.
|
|
87
|
+
|
|
88
|
+
Edit mode is mutually exclusive with new-region draw mode: entering one automatically exits the other.
|
|
89
|
+
|
|
90
|
+
### Region Actions
|
|
91
|
+
|
|
92
|
+
From the **Regions** sidebar tab you can:
|
|
93
|
+
|
|
94
|
+
- **Navigate** -- zoom the explorer to the saved region (`viewport.fitBounds(imageRect)`)
|
|
95
|
+
- **Add to Collection** -- saves as an `image-crop` collection item with the original-pixel `CropRegion`
|
|
96
|
+
- **Delete** -- removes the region
|
|
97
|
+
|
|
98
|
+
The Regions sidebar auto-refreshes when you navigate between files -- you no longer have to click the Regions tab after switching images.
|
|
99
|
+
|
|
100
|
+
### Multiple Regions
|
|
101
|
+
|
|
102
|
+
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()`.
|
|
103
|
+
|
|
104
|
+
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.
|
|
105
|
+
|
|
106
|
+
### Regions Browser
|
|
107
|
+
|
|
108
|
+
The topbar **▣ Regions Browser** button opens a full-screen folder-scoped view of every saved region across every file. This scales cleanly to thousands of regions because the server maintains an in-memory cache keyed on the Bibliograph enumeration, invalidated only on mutations.
|
|
109
|
+
|
|
110
|
+
Layout:
|
|
111
|
+
|
|
112
|
+
- **Left** -- folder tree with per-folder region counts. Click a folder to filter the right pane. "All folders" shows every region across the content root.
|
|
113
|
+
- **Right** -- files in the selected folder, each with a header showing the filename and region count, followed by the regions as clickable chips (label + dimensions).
|
|
114
|
+
|
|
115
|
+
Click a region chip to close the browser, open the file in the appropriate viewer (image explorer for images, media viewer for PDFs/EPUBs), and jump to the region's coordinates.
|
|
116
|
+
|
|
117
|
+
The initial folder selection is seeded from the gallery's current browsing location, so opening the browser from a folder you're browsing shows just that folder's regions by default. Press `Esc` or the ** Close** button to dismiss.
|
|
58
118
|
|
|
59
119
|
## Coordinate Display
|
|
60
120
|
|
|
@@ -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
|
|
@@ -131,111 +141,132 @@ When enabled (`-H` flag or `RETOLD_HASHED_FILENAMES=true`), real file paths are
|
|
|
131
141
|
|
|
132
142
|
## Docker
|
|
133
143
|
|
|
134
|
-
|
|
144
|
+
Retold Remote ships with two Dockerfiles, a `docker-compose.yml`, and a `docker-build-and-save.sh` helper. All images run the full stack (Ultravisor + Retold Remote + embedded Orator-Conversion) as a single container.
|
|
145
|
+
|
|
146
|
+
> **Running on Synology?** See the dedicated [Synology Container Manager](synology.md) guide for a step-by-step walkthrough including how to build the image on a dev machine and transfer it to the NAS.
|
|
135
147
|
|
|
136
|
-
|
|
148
|
+
### Quick Start (any Docker host with the source tree)
|
|
149
|
+
|
|
150
|
+
The compose file defaults to `image: retold-stack:latest` so it works on hosts that already have the image loaded. To build and run from the source tree in one go:
|
|
137
151
|
|
|
138
152
|
```bash
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
cd retold-remote
|
|
154
|
+
|
|
155
|
+
# Build the image and tag it as retold-stack:latest
|
|
156
|
+
docker build -t retold-stack:latest .
|
|
157
|
+
|
|
158
|
+
# Start the stack
|
|
159
|
+
MEDIA_PATH=/path/to/your/media docker compose up -d
|
|
141
160
|
```
|
|
142
161
|
|
|
143
|
-
|
|
162
|
+
Then browse to `http://localhost:7777/`. The Ultravisor coordinator web interface is at `http://localhost:54321/`.
|
|
144
163
|
|
|
145
|
-
If you
|
|
164
|
+
If you'd rather have Compose build the image directly, edit `docker-compose.yml`:
|
|
165
|
+
|
|
166
|
+
```yaml
|
|
167
|
+
services:
|
|
168
|
+
retold-stack:
|
|
169
|
+
# image: retold-stack:latest # <- comment this out
|
|
170
|
+
build: # <- uncomment this block
|
|
171
|
+
context: .
|
|
172
|
+
dockerfile: Dockerfile
|
|
173
|
+
```
|
|
146
174
|
|
|
147
|
-
|
|
148
|
-
FROM node:20-slim
|
|
175
|
+
Then `docker compose up -d --build` will build and start in one step.
|
|
149
176
|
|
|
150
|
-
|
|
151
|
-
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
152
|
-
ffmpeg \
|
|
153
|
-
imagemagick \
|
|
154
|
-
p7zip-full \
|
|
155
|
-
calibre \
|
|
156
|
-
&& rm -rf /var/lib/apt/lists/*
|
|
177
|
+
### Dockerfile Variants
|
|
157
178
|
|
|
158
|
-
|
|
179
|
+
Both images have been verified to build and run the full stack on ARM64 (Apple Silicon) and should build identically on AMD64.
|
|
159
180
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
181
|
+
| File | Measured Size | Includes | Use for |
|
|
182
|
+
|------|---------------|----------|---------|
|
|
183
|
+
| `Dockerfile` | **3.0 GB** | Everything: ffmpeg, ImageMagick, 7z, poppler, pdftk, LibreOffice, Calibre, exiftool, dcraw | Full document conversion (DOC, DOCX, RTF, ODT, WPD, MOBI, PPT, XLS, etc.) |
|
|
184
|
+
| `Dockerfile.slim` | **1.81 GB** | Same but without LibreOffice and Calibre | Image/video/audio/PDF/EPUB only -- no doc/docx/mobi conversion |
|
|
163
185
|
|
|
164
|
-
|
|
165
|
-
RUN npm install sharp || true
|
|
186
|
+
> **Note on audiowaveform:** Neither image installs `audiowaveform` because it is not in the default Debian repositories. Retold Remote automatically falls back to ffprobe + ffmpeg for waveform generation, which is slower but works identically. If you need the BBC `audiowaveform` tool for faster generation, add it via a custom Dockerfile step (build from source or a PPA).
|
|
166
187
|
|
|
167
|
-
|
|
168
|
-
COPY source/ source/
|
|
169
|
-
COPY web-application/ web-application/
|
|
170
|
-
COPY css/ css/
|
|
171
|
-
COPY html/ html/
|
|
172
|
-
COPY server.js ./
|
|
188
|
+
### Building and Saving for Transfer
|
|
173
189
|
|
|
174
|
-
|
|
175
|
-
RUN mkdir -p /cache
|
|
190
|
+
For deploying to a NAS or any host that doesn't have the source tree, use the `docker-build-and-save.sh` helper:
|
|
176
191
|
|
|
177
|
-
|
|
178
|
-
|
|
192
|
+
```bash
|
|
193
|
+
./docker-build-and-save.sh # full image, host architecture
|
|
194
|
+
./docker-build-and-save.sh slim # slim variant
|
|
195
|
+
./docker-build-and-save.sh --amd64 # cross-build for x86_64
|
|
196
|
+
./docker-build-and-save.sh slim --arm64 # slim + arm64
|
|
197
|
+
```
|
|
179
198
|
|
|
180
|
-
|
|
199
|
+
This produces a compressed tar file (`retold-stack-image.tar.gz` or `retold-stack-image-slim.tar.gz`) that you can copy to the target host and load with:
|
|
181
200
|
|
|
182
|
-
|
|
183
|
-
|
|
201
|
+
```bash
|
|
202
|
+
docker load -i retold-stack-image.tar.gz
|
|
184
203
|
```
|
|
185
204
|
|
|
186
|
-
|
|
205
|
+
Then start the stack with the included `docker-compose.yml` (which references `retold-stack:latest` by default). No source tree needed on the target host.
|
|
187
206
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
### Manual Docker Run
|
|
208
|
+
|
|
209
|
+
If you prefer `docker run` over Compose:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
docker build -t retold-stack .
|
|
213
|
+
|
|
214
|
+
docker run -d \
|
|
215
|
+
--name retold-stack \
|
|
216
|
+
-p 7777:7777 \
|
|
217
|
+
-p 54321:54321 \
|
|
218
|
+
-v /path/to/media:/media:ro \
|
|
219
|
+
-v retold-cache:/cache \
|
|
220
|
+
-v ultravisor-data:/data \
|
|
221
|
+
-v retold-config:/config \
|
|
222
|
+
--restart unless-stopped \
|
|
223
|
+
retold-stack
|
|
204
224
|
```
|
|
205
225
|
|
|
206
|
-
|
|
226
|
+
Then browse to `http://localhost:7777/`.
|
|
227
|
+
|
|
228
|
+
### Volume Mounts
|
|
207
229
|
|
|
208
|
-
|
|
209
|
-
- Mount a volume to `/cache` for persistent thumbnail and frame caches
|
|
210
|
-
- The `node:20-slim` base keeps the image small while the `apt-get` packages add full media processing
|
|
211
|
-
- `calibre` is the largest optional package; omit it if you do not need MOBI/AZW ebook conversion
|
|
212
|
-
- `sharp` is installed separately because it has native bindings that may fail on some architectures; the `|| true` ensures the build continues without it
|
|
230
|
+
The stack uses four volume mount points. The first is your media; the other three are for persistent state:
|
|
213
231
|
|
|
214
|
-
|
|
232
|
+
| Container path | Purpose | Typical host mapping |
|
|
233
|
+
|----------------|---------|---------------------|
|
|
234
|
+
| `/media` | Media folder to browse (read-only) | `/path/to/media:/media:ro` |
|
|
235
|
+
| `/cache` | Thumbnails, frames, waveforms, conversions | Named volume `retold-cache` |
|
|
236
|
+
| `/data` | Ultravisor datastore + staging | Named volume `ultravisor-data` |
|
|
237
|
+
| `/config` | Stack config files | Named volume `retold-config` |
|
|
215
238
|
|
|
216
|
-
|
|
239
|
+
Inside the container, `XDG_CACHE_HOME`, `XDG_DATA_HOME`, and `XDG_CONFIG_HOME` are set to these paths so the stack launcher uses them automatically.
|
|
217
240
|
|
|
218
|
-
|
|
219
|
-
FROM node:20-slim
|
|
241
|
+
### Published Ports
|
|
220
242
|
|
|
221
|
-
|
|
243
|
+
| Port | Purpose |
|
|
244
|
+
|------|---------|
|
|
245
|
+
| **7777** | Retold Remote web UI (the main thing you browse to) |
|
|
246
|
+
| **54321** | Ultravisor coordinator API + web interface (optional -- useful for monitoring) |
|
|
222
247
|
|
|
223
|
-
|
|
224
|
-
RUN npm ci --omit=dev && npm cache clean --force
|
|
248
|
+
Both are pinned to fixed ports via the `-p 7777` flag in the default CMD, overriding the usual random 7000-7999 behavior.
|
|
225
249
|
|
|
226
|
-
|
|
227
|
-
COPY web-application/ web-application/
|
|
228
|
-
COPY css/ css/
|
|
229
|
-
COPY html/ html/
|
|
230
|
-
COPY server.js ./
|
|
250
|
+
### Customizing the CMD
|
|
231
251
|
|
|
232
|
-
|
|
233
|
-
EXPOSE 8086
|
|
252
|
+
The default command launches `retold-stack` against `/media` on port 7777 with hashed filenames disabled. To override (e.g., to enable hashed filenames or change the port):
|
|
234
253
|
|
|
235
|
-
|
|
254
|
+
```yaml
|
|
255
|
+
command: ["node", "source/cli/RetoldRemote-Stack-Run.js", "/media", "-p", "7777"]
|
|
236
256
|
```
|
|
237
257
|
|
|
238
|
-
|
|
258
|
+
Remove the `--no-hash` flag to re-enable hashed filenames, or change `/media` if you mounted your media to a different path.
|
|
259
|
+
|
|
260
|
+
### Image Size Notes
|
|
261
|
+
|
|
262
|
+
- `node:20-slim` base: ~180 MB
|
|
263
|
+
- Full `Dockerfile` (with LibreOffice + Calibre): ~2.5 GB -- Calibre alone is ~1 GB, LibreOffice is ~600 MB
|
|
264
|
+
- `Dockerfile.slim`: ~1.8 GB -- drops both big dependencies
|
|
265
|
+
- Omit `ffmpeg` and `audiowaveform` too if you don't need video/audio processing, for a ~1 GB image
|
|
266
|
+
|
|
267
|
+
### Child Process Note
|
|
268
|
+
|
|
269
|
+
The stack launcher spawns Ultravisor as a child process using `node` and the resolved `ultravisor` bin path. This works inside Docker without any special configuration -- the child runs in the same container PID namespace and its logs are streamed through the main process's stdout with `[ultravisor]` prefixes.
|
|
239
270
|
|
|
240
271
|
## Archive Browsing
|
|
241
272
|
|