97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
package nextcloud
|
|
|
|
import (
|
|
"context"
|
|
"encoding/xml"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
func (c *Client) FileID(ctx context.Context, userID, filePath string) (int64, error) {
|
|
filePath = NormalizeClientFilePath(userID, filePath)
|
|
davPath := c.WebDAVPath(userID, filePath)
|
|
body := `<?xml version="1.0" encoding="UTF-8"?>
|
|
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns">
|
|
<d:prop>
|
|
<oc:fileid/>
|
|
</d:prop>
|
|
</d:propfind>`
|
|
|
|
resp, err := c.DoAsUser(ctx, "PROPFIND", davPath, strings.NewReader(body), userID, map[string]string{
|
|
"Depth": "0",
|
|
"Content-Type": "application/xml",
|
|
})
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
if resp.StatusCode != http.StatusMultiStatus && resp.StatusCode != http.StatusOK {
|
|
return 0, &HTTPStatusError{Operation: "propfind fileid", StatusCode: resp.StatusCode}
|
|
}
|
|
|
|
var ms struct {
|
|
Responses []struct {
|
|
Propstat struct {
|
|
Prop struct {
|
|
FileID string `xml:"http://owncloud.org/ns fileid"`
|
|
} `xml:"prop"`
|
|
} `xml:"propstat"`
|
|
} `xml:"response"`
|
|
}
|
|
if err := xml.NewDecoder(resp.Body).Decode(&ms); err != nil {
|
|
return 0, err
|
|
}
|
|
if len(ms.Responses) == 0 {
|
|
return 0, fmt.Errorf("fileid propfind: empty response")
|
|
}
|
|
|
|
raw := strings.TrimSpace(ms.Responses[0].Propstat.Prop.FileID)
|
|
if raw == "" {
|
|
return 0, fmt.Errorf("fileid propfind: missing fileid")
|
|
}
|
|
// Nextcloud may return "00001234" — keep numeric part.
|
|
id, err := strconv.ParseInt(raw, 10, 64)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("fileid propfind: invalid fileid %q", raw)
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func (c *Client) Preview(ctx context.Context, userID string, fileID int64, width, height int) (io.ReadCloser, string, error) {
|
|
if width <= 0 {
|
|
width = 400
|
|
}
|
|
if height <= 0 {
|
|
height = 300
|
|
}
|
|
if width > 2048 {
|
|
width = 2048
|
|
}
|
|
if height > 2048 {
|
|
height = 2048
|
|
}
|
|
|
|
path := fmt.Sprintf(
|
|
"/index.php/core/preview?fileId=%d&x=%d&y=%d&a=1&mode=cover&mimeFallback=true",
|
|
fileID, width, height,
|
|
)
|
|
resp, err := c.DoAsUser(ctx, "GET", path, nil, userID, nil)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
if resp.StatusCode != http.StatusOK {
|
|
resp.Body.Close()
|
|
return nil, "", &HTTPStatusError{Operation: "preview", StatusCode: resp.StatusCode}
|
|
}
|
|
|
|
contentType := resp.Header.Get("Content-Type")
|
|
if contentType == "" {
|
|
contentType = "image/jpeg"
|
|
}
|
|
return resp.Body, contentType, nil
|
|
}
|