Files
jellybit/cmd/jellybit/add.go
T

68 lines
2.1 KiB
Go

package main
import (
"bytes"
"context"
"encoding/json"
"flag"
"fmt"
"io"
"net/http"
"strings"
"time"
)
// runAdd — тонкий CLI-клиент REST API запущенного сервиса (для отладки):
//
// jellybit add <magnet> --context "..." --server http://localhost:8080
func runAdd(args []string) error {
fs := flag.NewFlagSet("add", flag.ContinueOnError)
server := fs.String("server", "http://localhost:8080", "адрес запущенного jellybit")
contextStr := fs.String("context", "", "контекст для распознавания")
// stdlib flag прекращает разбор на первом позиционном аргументе, поэтому
// magnet (если он идёт первым) вынимаем до Parse — так работают оба
// порядка: `add <magnet> --context ...` и `add --context ... <magnet>`.
var source string
if len(args) > 0 && !strings.HasPrefix(args[0], "-") {
source, args = args[0], args[1:]
}
if err := fs.Parse(args); err != nil {
return err
}
if source == "" {
if fs.NArg() < 1 {
return fmt.Errorf("usage: jellybit add <magnet> [--context ...] [--server ...]")
}
source = fs.Arg(0)
}
body, err := json.Marshal(map[string]string{"source": source, "context": *contextStr})
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
endpoint := strings.TrimRight(*server, "/") + "/api/downloads"
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint, bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return fmt.Errorf("call %s: %w", endpoint, err)
}
defer func() { _ = resp.Body.Close() }()
respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<16))
if resp.StatusCode >= 400 {
return fmt.Errorf("server returned %d: %s", resp.StatusCode, strings.TrimSpace(string(respBody)))
}
fmt.Println(strings.TrimSpace(string(respBody)))
return nil
}