ultisuite-backend/internal/api/drive/ultidoc_sidecar.go
R3D347HR4Y 0466a1c169
Some checks are pending
CI / Go tests (push) Waiting to run
CI / Integration tests (push) Waiting to run
CI / DB migrations (push) Waiting to run
wow
2026-06-11 01:22:52 +02:00

107 lines
2.7 KiB
Go

package drive
import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"github.com/ultisuite/ulti-backend/internal/nextcloud"
)
func shouldSyncUltidocSidecar(path string) bool {
return !nextcloud.IsUltidocSidecarPath(path)
}
func sidecarPathsForSourceMove(sourcePath, destinationPath string) (sidecarSource, sidecarDestination string, ok bool) {
if !shouldSyncUltidocSidecar(sourcePath) {
return "", "", false
}
return nextcloud.SidecarPathForSource(sourcePath), nextcloud.SidecarPathForSource(destinationPath), true
}
func (s *Service) sidecarExists(ctx context.Context, userID, path string) bool {
_, err := s.nc.FileRevision(ctx, userID, path)
return err == nil
}
func (s *Service) syncUltidocSidecarCopy(
ctx context.Context,
userID, sourcePath, destinationPath string,
) error {
sidecarSource, sidecarDestination, ok := sidecarPathsForSourceMove(sourcePath, destinationPath)
if !ok || !s.sidecarExists(ctx, userID, sidecarSource) {
return nil
}
if err := mapDriveError(s.nc.Copy(ctx, userID, sidecarSource, sidecarDestination)); err != nil {
return err
}
return s.patchUltidocSidecarSourcePath(ctx, userID, sidecarDestination, destinationPath)
}
func (s *Service) patchUltidocSidecarSourcePath(
ctx context.Context,
userID, sidecarPath, newSourcePath string,
) error {
body, _, err := s.nc.Download(ctx, userID, sidecarPath)
if err != nil {
return mapDriveError(err)
}
defer body.Close()
raw, err := io.ReadAll(body)
if err != nil {
return err
}
var doc map[string]any
if err := json.Unmarshal(raw, &doc); err != nil {
return err
}
source, _ := doc["source"].(map[string]any)
if source == nil {
source = map[string]any{}
doc["source"] = source
}
source["path"] = newSourcePath
encoded, err := json.Marshal(doc)
if err != nil {
return err
}
if err := mapDriveError(s.nc.Upload(ctx, userID, sidecarPath, bytes.NewReader(encoded), "application/json")); err != nil {
return err
}
return nil
}
func (s *Service) moveWithUltidocSidecar(ctx context.Context, userID, source, destination string) error {
sidecarSource, sidecarDestination, ok := sidecarPathsForSourceMove(source, destination)
hasSidecar := ok && s.sidecarExists(ctx, userID, sidecarSource)
if hasSidecar {
if err := mapDriveError(s.nc.Move(ctx, userID, sidecarSource, sidecarDestination)); err != nil {
return err
}
}
if err := mapDriveError(s.nc.Move(ctx, userID, source, destination)); err != nil {
if hasSidecar {
_ = s.nc.Move(ctx, userID, sidecarDestination, sidecarSource)
}
return err
}
if hasSidecar {
if err := s.patchUltidocSidecarSourcePath(ctx, userID, sidecarDestination, destination); err != nil {
return errors.Join(err, mapDriveError(s.nc.Move(ctx, userID, destination, source)))
}
}
return nil
}