ms-tester/pkg/pandoc-client.go
2025-03-16 19:16:27 +05:00

153 lines
3.1 KiB
Go

package pkg
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
)
type Client struct {
client *http.Client
address string
}
type PandocClient interface {
ConvertLatexToHtml5(ctx context.Context, text string) (string, error)
BatchConvertLatexToHtml5(ctx context.Context, texts []string) ([]string, error)
}
func NewPandocClient(client *http.Client, address string) *Client {
return &Client{
client: client,
address: address,
}
}
type conversation struct {
Text string `json:"text"`
From string `json:"from"`
To string `json:"to"`
Math string `json:"html-math-method"`
}
type message struct {
Message string `json:"message"`
Verbosity string `json:"verbosity"`
}
type output struct {
Error string `json:"error"`
Output string `json:"output"`
Base64 bool `json:"base64"`
Messages []message `json:"messages"`
}
func (client *Client) sendRaw(ctx context.Context, path string, body []byte) ([]byte, error) {
path, err := url.JoinPath(client.address, path)
if err != nil {
return nil, err
}
buf := bytes.NewBuffer(body)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, path, buf)
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := client.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err = io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
}
func (client *Client) convert(ctx context.Context, text, from, to, math string) (string, error) {
body, err := json.Marshal(conversation{
Text: text,
From: from,
To: to,
Math: math,
})
if err != nil {
return "", err
}
resp, err := client.sendRaw(ctx, "/", body)
if err != nil {
return "", err
}
return string(resp), nil
}
func (client *Client) batchConvert(ctx context.Context, texts []string, from, to, math string) ([]string, error) {
list := make([]conversation, len(texts))
for i, text := range texts {
list[i] = conversation{
Text: text,
From: from,
To: to,
Math: math,
}
}
body, err := json.Marshal(list)
if err != nil {
return nil, err
}
resp, err := client.sendRaw(ctx, "/batch", body)
if err != nil {
return nil, err
}
var result []output
err = json.Unmarshal(resp, &result)
if err != nil {
return nil, err
}
if len(result) != len(texts) {
return nil, fmt.Errorf("wrong number of fieilds returned: %d", len(result))
}
err = nil
for _, o := range result {
if o.Error != "" {
err = errors.Join(err, errors.New(o.Error))
}
}
if err != nil {
return nil, Wrap(ErrBadInput, err, "BatchConvertLatexToHtml5", "invalid input")
}
res := make([]string, len(result))
for i, o := range result {
res[i] = o.Output
}
return res, nil
}
func (client *Client) ConvertLatexToHtml5(ctx context.Context, text string) (string, error) {
return client.convert(ctx, text, "latex", "html5", "katex")
}
func (client *Client) BatchConvertLatexToHtml5(ctx context.Context, texts []string) ([]string, error) {
return client.batchConvert(ctx, texts, "latex", "html5", "katex")
}