Replace dsc import calls with Docspell API

This commit is contained in:
Jan Bader
2026-07-20 20:48:08 +02:00
parent 608dc99c45
commit c4a2e9d085
4 changed files with 229 additions and 46 deletions
+102
View File
@@ -3,12 +3,17 @@ package main
import (
"bytes"
"context"
"crypto/sha256"
"encoding/json"
"fmt"
"io"
"mime/multipart"
"net/http"
"net/textproto"
"net/url"
"os"
"path"
"path/filepath"
"strings"
"time"
)
@@ -60,6 +65,23 @@ type ItemAttachment struct {
Position int `json:"position"`
}
type BasicResult struct {
Success bool `json:"success"`
Message string `json:"message"`
}
type UploadMeta struct {
Multiple bool `json:"multiple"`
Direction string `json:"direction,omitempty"`
Folder string `json:"folder,omitempty"`
SkipDuplicates bool `json:"skipDuplicates,omitempty"`
Tags []string `json:"tags,omitempty"`
FileFilter string `json:"fileFilter,omitempty"`
Language string `json:"language,omitempty"`
AttachmentsOnly bool `json:"attachmentsOnly,omitempty"`
FlattenArchives bool `json:"flattenArchives,omitempty"`
}
type DocspellTag struct {
ID string `json:"id"`
Name string `json:"name"`
@@ -137,6 +159,86 @@ func (c *DocspellClient) GetItem(ctx context.Context, id string) (*SearchItem, e
return &out, nil
}
func (c *DocspellClient) FileExists(ctx context.Context, filePath string) (FileExistsResult, error) {
var result FileExistsResult
hash, err := fileSHA256(filePath)
if err != nil {
return result, err
}
if err := c.doJSON(ctx, http.MethodGet, "/api/v1/sec/checkfile/"+url.PathEscape(hash), nil, &result); err != nil {
return result, err
}
if abs, err := filepath.Abs(filePath); err == nil {
result.File = abs
} else {
result.File = filePath
}
return result, nil
}
func (c *DocspellClient) UploadFile(ctx context.Context, filePath string, meta UploadMeta) (BasicResult, error) {
file, err := os.Open(filePath)
if err != nil {
return BasicResult{}, err
}
defer file.Close()
var body bytes.Buffer
writer := multipart.NewWriter(&body)
metaPart, err := writer.CreatePart(textPartHeader("meta", "application/json"))
if err != nil {
return BasicResult{}, err
}
if err := json.NewEncoder(metaPart).Encode(meta); err != nil {
return BasicResult{}, err
}
filePart, err := writer.CreateFormFile("file", filepath.Base(filePath))
if err != nil {
return BasicResult{}, err
}
if _, err := io.Copy(filePart, file); err != nil {
return BasicResult{}, err
}
if err := writer.Close(); err != nil {
return BasicResult{}, err
}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, c.url("/api/v1/sec/upload/item"), &body)
if err != nil {
return BasicResult{}, err
}
req.Header.Set("Content-Type", writer.FormDataContentType())
data, err := c.do(req)
if err != nil {
return BasicResult{}, err
}
var out BasicResult
if err := json.Unmarshal(data, &out); err != nil {
return BasicResult{}, err
}
return out, nil
}
func fileSHA256(filePath string) (string, error) {
file, err := os.Open(filePath)
if err != nil {
return "", err
}
defer file.Close()
hash := sha256.New()
if _, err := io.Copy(hash, file); err != nil {
return "", err
}
return fmt.Sprintf("%x", hash.Sum(nil)), nil
}
func textPartHeader(name, contentType string) textproto.MIMEHeader {
header := make(textproto.MIMEHeader)
header.Set("Content-Disposition", fmt.Sprintf(`form-data; name="%s"`, name))
header.Set("Content-Type", contentType)
return header
}
func (c *DocspellClient) AttachmentSize(ctx context.Context, id string) (int64, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodHead, c.url("/api/v1/sec/attachment/"+url.PathEscape(id)), nil)
if err != nil {