Skip to content

Commit

Permalink
Fix cloning a note with images (#4327)
Browse files Browse the repository at this point in the history
  • Loading branch information
nono committed Feb 13, 2024
2 parents e0c4bc2 + 0e88c80 commit 0c19202
Show file tree
Hide file tree
Showing 4 changed files with 291 additions and 109 deletions.
90 changes: 90 additions & 0 deletions model/note/copy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package note

import (
"github.com/cozy/cozy-stack/model/instance"
"github.com/cozy/cozy-stack/model/vfs"
"github.com/cozy/prosemirror-go/model"
"github.com/gofrs/uuid/v5"
)

// CopyFile is an overloaded version of Fs.CopyFile that take care of also
// copying the images in the note.
func CopyFile(inst *instance.Instance, olddoc, newdoc *vfs.FileDoc) error {
// Check available disk space
_, _, _, err := vfs.CheckAvailableDiskSpace(inst.VFS(), newdoc)
if err != nil {
return err
}

// Load data from the source note
noteDoc, err := get(inst, olddoc)
if err != nil {
return err
}
content, err := noteDoc.Content()
if err != nil {
return err
}
srcImages, err := getImages(inst, olddoc.ID())
if err != nil {
return err
}

// We need a fileID for saving images
uuidv7, _ := uuid.NewV7()
newdoc.SetID(uuidv7.String())

// id of the image in the source doc -> image in the destination doc
mapping := make(map[string]*Image)
var dstImages []*Image
for _, img := range srcImages {
if img.ToRemove {
continue
}
copied, err := CopyImageToAnotherNote(inst, img.ID(), newdoc)
if err != nil {
return err
}
mapping[img.ID()] = copied
dstImages = append(dstImages, copied)
}

updateProsemirrorImageURLs(content, mapping)

md := markdownSerializer(dstImages).Serialize(content)
if err != nil {
return err
}
body := []byte(md)
if hasImages(dstImages) {
body, _ = buildArchive(inst, []byte(md), dstImages)
}
newdoc.ByteSize = int64(len(body))
newdoc.MD5Sum = nil
newdoc.Metadata["content"] = content.ToJSON()

file, err := inst.VFS().CreateFile(newdoc, nil)
if err != nil {
return err
}
_, err = file.Write(body)
if cerr := file.Close(); cerr != nil && err == nil {
err = cerr
}
return err
}

func updateProsemirrorImageURLs(node *model.Node, mapping map[string]*Image) {
if node.Type.Name == "media" {
nodeURL, _ := node.Attrs["url"].(string)
for id, img := range mapping {
if nodeURL == id {
node.Attrs["url"] = img.ID()
}
}
}

node.ForEach(func(child *model.Node, _ int, _ int) {
updateProsemirrorImageURLs(child, mapping)
})
}
Binary file added tests/fixtures/note-with-an-image.cozy-note
Binary file not shown.
7 changes: 6 additions & 1 deletion web/files/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,12 @@ func FileCopyHandler(c echo.Context) error {
newdoc.ResetFullpath()
updateFileCozyMetadata(c, newdoc, true)

err = fs.CopyFile(olddoc, newdoc)
if olddoc.Mime == consts.NoteMimeType {
// We need a special copy for notes because of their images
err = note.CopyFile(inst, olddoc, newdoc)
} else {
err = fs.CopyFile(olddoc, newdoc)
}
if err != nil {
return WrapVfsError(err)
}
Expand Down
Loading

0 comments on commit 0c19202

Please sign in to comment.