- 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.
151 lines
4.4 KiB
Go
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>`
|