107 lines
2.7 KiB
Go
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
|
|
}
|