-
Notifications
You must be signed in to change notification settings - Fork 93
.RM V6 Support #392
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
.RM V6 Support #392
Conversation
|
Awesome work @joagonca 🥳 |
|
Thanks! The "randomness", I intend to fix that, and support all pages in a subsequent PR. The rmc-go library already exports the multipage PDF using the .content files from reMarkable, in the correct order. |
|
It should now support multipage rendering in the correct order. |
|
@joagonca I actually came up with a solution myself, too. I looks quite similar to yours, but it stitches the single pages together with baflo@15de3ca#diff-fc741d1c044272840de20d525e88fb8068c4737e42703b589317c2f981502d12 |
|
@baflo Nice one. For the sake of this PR, it might make more sense to go with yours, as it provides best functionality out of the box. For the final one, I might ditch Thoughts? |
|
Sound good to me ;) @ddvk what do you think? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds native support for reMarkable v6 file format (introduced in software 3.0+) to rmfakecloud. The implementation integrates the rmc-go library with Cairo renderer to enable in-process rendering of v6 files without external dependencies.
Key changes:
- Added version detection logic to differentiate between v3/v5/v6 .rm file formats
- Integrated rmc-go library for native v6 file rendering using Cairo
- Updated document export paths to route v5 files to rmapi and v6 files to rmc-go
Reviewed Changes
Copilot reviewed 12 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/storage/models/archive.go | Modified to detect and store v6 page data separately in V6PageData map instead of attempting to parse with rmapi |
| internal/storage/fs/documents.go | Added version detection and routing logic to use rmc-go for v6 files and rmapi for v5 files |
| internal/storage/fs/blobstore.go | Implemented v6 blob export path with direct .rm file extraction and rmc-go rendering |
| internal/storage/exporter/version.go | New file with version detection logic for .rm files |
| internal/storage/exporter/version_test.go | Comprehensive tests for version detection functionality |
| internal/storage/exporter/rmc_go.go | New file with wrapper functions for rmc-go library PDF/SVG export |
| internal/storage/exporter/myarchive.go | Added V6PageData field to store raw v6 page bytes |
| internal/config/config.go | Updated help text to document v6 support and formatting fix |
| go.mod | Added rmc-go dependency and upgraded Go version to 1.25.1 |
| go.sum | Updated with new dependencies (rmc-go and go-cairo) |
| README.md | Added comprehensive v6 support documentation |
| Makefile | Added build-cairo targets for building with Cairo support |
| Dockerfile | Updated to include Cairo dependencies for v6 rendering |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
internal/storage/fs/blobstore.go
Outdated
| if len(arch.Pages) == 0 { | ||
| return exporter.VersionUnknown, fmt.Errorf("no pages in archive") | ||
| } | ||
|
|
||
| // Try to marshal first page and detect from header | ||
| if arch.Pages[0].Data != nil { | ||
| data, err := arch.Pages[0].Data.MarshalBinary() | ||
| if err != nil { | ||
| return exporter.VersionUnknown, fmt.Errorf("failed to marshal page data: %w", err) | ||
| } | ||
| return exporter.DetectRmVersion(bytes.NewReader(data)) | ||
| } | ||
|
|
||
| return exporter.VersionUnknown, fmt.Errorf("no page data available") |
Copilot
AI
Nov 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function 'detectBlobArchiveVersion' is identical to 'detectArchiveVersion' in documents.go (lines 227-243). This is duplicated code. Consider extracting this to a shared utility function or moving it to the exporter package to avoid duplication.
| if len(arch.Pages) == 0 { | |
| return exporter.VersionUnknown, fmt.Errorf("no pages in archive") | |
| } | |
| // Try to marshal first page and detect from header | |
| if arch.Pages[0].Data != nil { | |
| data, err := arch.Pages[0].Data.MarshalBinary() | |
| if err != nil { | |
| return exporter.VersionUnknown, fmt.Errorf("failed to marshal page data: %w", err) | |
| } | |
| return exporter.DetectRmVersion(bytes.NewReader(data)) | |
| } | |
| return exporter.VersionUnknown, fmt.Errorf("no page data available") | |
| return exporter.DetectArchiveVersionFromMyArchive(arch) |
README.md
Outdated
|
|
||
| ### Known Limitations | ||
|
|
||
| - Multi-page v6 documents: Currently exports first page only |
Copilot
AI
Nov 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation states 'Multi-page v6 documents: Currently exports first page only' in Known Limitations, but the code in documents.go (lines 122-127) and blobstore.go (lines 194-212) clearly iterates through all pages and uses ExportV6MultiPageToPdfNative to export all pages. This limitation appears to be incorrect or outdated.
| - Multi-page v6 documents: Currently exports first page only | |
| - Multi-page v6 documents: Fully supported |
internal/storage/fs/documents.go
Outdated
| for i := 0; i < len(arch.V6PageData); i++ { | ||
| if data, ok := arch.V6PageData[i]; ok { | ||
| pages = append(pages, data) | ||
| } | ||
| } |
Copilot
AI
Nov 3, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loop assumes that V6PageData keys are sequential from 0 to len(V6PageData)-1, but if there are gaps in the page indices (e.g., missing page 2 in a 5-page document), the loop will still iterate 5 times but may skip entries. This could result in pages being collected out of order or missing pages. Consider using a sorted iteration over the map keys instead.
|
nice work! unipdf is no longer agpl and has to be removed |
|
Hmm, if that's the case, we might be better off trying to fix it using current Moreover, I'll address the comments made by co-pilot. |
|
I've bumped the |
|
A quick look seems to indicate that this also will support CRDT IDs needed for the handwriting search branch I'm working on 👍 |
|
Do we have an estimate on how long is left on this PR before it gets merged? I am so thrilled for this ticket I check several times a week. |
|
@ddvk I would like to help rectify any problems that still exist with this PR. Would you give me a hint what's missing so this can be merged? |
|
just the merge conflicts i guess |
|
This is held back by the unipdf PR. It breaks some stuff.
…-------- Original Message --------
On Tuesday, 01/06/26 at 09:56 ddvk ***@***.***> wrote:
ddvk left a comment [(ddvk/rmfakecloud#392)](#392 (comment))
just the merge conflicts i guess
—
Reply to this email directly, [view it on GitHub](#392 (comment)), or [unsubscribe](https://github.com/notifications/unsubscribe-auth/AB35UWQ6S4M4HPSY2GEER7T4FOBDLAVCNFSM6AAAAACKR2C6VGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTOMJUGAYTANJTHA).
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
Trying to address issue #255 .