package drivebridge import ( "context" "errors" "io" "net/http" "path" "github.com/ultisuite/ulti-backend/internal/api/drive" "github.com/ultisuite/ulti-backend/internal/api/query" "github.com/ultisuite/ulti-backend/internal/auth" "github.com/ultisuite/ulti-backend/internal/nextcloud" ) // Bridge adapts drive.Service for mail attachment exports. type Bridge struct { Svc *drive.Service } func (b *Bridge) claims(email, sub, displayName string) *auth.Claims { return &auth.Claims{Email: email, Sub: sub, Name: displayName} } func (b *Bridge) ncUser(ctx context.Context, email, sub, displayName string) (string, error) { if b.Svc == nil { return "", errors.New("drive unavailable") } return b.Svc.EnsureNextcloudUser(ctx, b.claims(email, sub, displayName)) } func (b *Bridge) EnsureNextcloudFolder(ctx context.Context, email, sub, displayName, folderPath string) error { userID, err := b.ncUser(ctx, email, sub, displayName) if err != nil { return err } err = b.Svc.CreateFolder(ctx, userID, folderPath) if err == nil || errors.Is(err, drive.ErrConflict) { return nil } var statusErr *nextcloud.HTTPStatusError if errors.As(err, &statusErr) && statusErr.StatusCode == http.StatusMethodNotAllowed { return nil } return err } func (b *Bridge) UploadFile(ctx context.Context, email, sub, displayName, destPath string, body io.Reader, contentType string, size int64) error { userID, err := b.ncUser(ctx, email, sub, displayName) if err != nil { return err } return b.Svc.Upload(ctx, userID, destPath, body, contentType, size) } func (b *Bridge) NotifyFileChanged(platformUserID, filePath string) { if b.Svc == nil { return } b.Svc.PublishFileChanged(platformUserID, filePath) } func (b *Bridge) FileExists(ctx context.Context, email, sub, displayName, filePath string) (bool, error) { userID, err := b.ncUser(ctx, email, sub, displayName) if err != nil { return false, err } parent := path.Dir(filePath) name := path.Base(filePath) files, err := b.Svc.ListFiles(ctx, userID, parent, query.ListParams{Page: 1, PageSize: 10_000}) if err != nil { return false, err } for _, f := range files.Files { if f.Name == name { return true, nil } } return false, nil }