ultisuite-backend/internal/nextcloud/groupfolder_dav.go
R3D347HR4Y 1d063237b9
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
feat(transcription): integrate Faster Whisper for Jitsi transcriptions
- Added support for Faster Whisper transcription via Jigasi and Skynet.
- Updated .env.example to include new environment variables for transcription settings.
- Enhanced Jitsi Docker Compose configuration to include Skynet and Jigasi services.
- Introduced new API endpoints for managing organizational folders in the drive service.
- Updated Nextcloud initialization script to enable external file mounting.
- Improved error handling and response structures in the drive API.
- Added new properties for organization settings related to transcription and agenda management.
2026-06-12 19:10:18 +02:00

151 lines
4.4 KiB
Go

package nextcloud
import (
"context"
"io"
"net/http"
"strings"
)
func (c *Client) ListFilesAtDAV(ctx context.Context, userID, davPath, logicalPath string) ([]FileInfo, error) {
body := propfindBody
resp, err := c.DoAsUser(ctx, "PROPFIND", davPath, strings.NewReader(body), userID, map[string]string{
"Depth": "1",
"Content-Type": "application/xml",
})
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != 207 {
return nil, &HTTPStatusError{Operation: "propfind", StatusCode: resp.StatusCode}
}
return parsePropfindResponse(resp.Body, logicalPath)
}
func (c *Client) StatFileAtDAV(ctx context.Context, userID, davPath, logicalPath string) (FileInfo, error) {
body := propfindBody
resp, err := c.DoAsUser(ctx, "PROPFIND", davPath, strings.NewReader(body), userID, map[string]string{
"Depth": "0",
"Content-Type": "application/xml",
})
if err != nil {
return FileInfo{}, err
}
defer resp.Body.Close()
if resp.StatusCode != 207 {
return FileInfo{}, &HTTPStatusError{Operation: "propfind", StatusCode: resp.StatusCode}
}
files, err := parsePropfindResponse(resp.Body, logicalPath)
if err != nil {
return FileInfo{}, err
}
if len(files) == 0 {
return FileInfo{}, &HTTPStatusError{Operation: "stat", StatusCode: http.StatusNotFound}
}
return files[0], nil
}
func (c *Client) UploadAtDAV(ctx context.Context, userID, davPath, contentType string, content io.Reader) error {
if contentType == "" {
contentType = "application/octet-stream"
}
resp, err := c.DoAsUser(ctx, "PUT", davPath, content, userID, map[string]string{
"Content-Type": contentType,
})
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent {
return &HTTPStatusError{Operation: "upload", StatusCode: resp.StatusCode}
}
return nil
}
func (c *Client) CreateFolderAtDAV(ctx context.Context, userID, davPath string) error {
resp, err := c.DoAsUser(ctx, "MKCOL", davPath, nil, userID, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated {
return &HTTPStatusError{Operation: "mkcol", StatusCode: resp.StatusCode}
}
return nil
}
func (c *Client) DeleteAtDAV(ctx context.Context, userID, davPath string) error {
resp, err := c.DoAsUser(ctx, "DELETE", davPath, nil, userID, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusNoContent && resp.StatusCode != http.StatusOK {
return &HTTPStatusError{Operation: "delete", StatusCode: resp.StatusCode}
}
return nil
}
func (c *Client) MoveAtDAV(ctx context.Context, userID, srcDAV, destDAV string) error {
resp, err := c.DoAsUser(ctx, "MOVE", srcDAV, nil, userID, map[string]string{
"Destination": c.webDAVDestination(destDAV),
"Overwrite": "T",
})
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent {
return &HTTPStatusError{Operation: "move", StatusCode: resp.StatusCode}
}
return nil
}
func (c *Client) CopyAtDAV(ctx context.Context, userID, srcDAV, destDAV string) error {
resp, err := c.DoAsUser(ctx, "COPY", srcDAV, nil, userID, map[string]string{
"Destination": c.webDAVDestination(destDAV),
"Overwrite": "T",
})
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusNoContent {
return &HTTPStatusError{Operation: "copy", StatusCode: resp.StatusCode}
}
return nil
}
func (c *Client) DownloadAtDAV(ctx context.Context, userID, davPath string) (io.ReadCloser, string, error) {
resp, err := c.DoAsUser(ctx, "GET", davPath, nil, userID, nil)
if err != nil {
return nil, "", err
}
if resp.StatusCode != http.StatusOK {
resp.Body.Close()
return nil, "", &HTTPStatusError{Operation: "download", StatusCode: resp.StatusCode}
}
contentType := resp.Header.Get("Content-Type")
if contentType == "" {
contentType = "application/octet-stream"
}
return resp.Body, contentType, nil
}
const propfindBody = `<?xml version="1.0" encoding="UTF-8"?>
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns" xmlns:nc="http://nextcloud.org/ns">
<d:prop>
<d:getlastmodified/>
<d:getetag/>
<d:getcontenttype/>
<d:getcontentlength/>
<d:resourcetype/>
<oc:fileid/>
<oc:size/>
<oc:favorite/>
<oc:share-types/>
<d:displayname/>
</d:prop>
</d:propfind>`