feat(tester): integrate pandoc
This commit is contained in:
parent
ffacc9e3ac
commit
94fc50e272
9 changed files with 315 additions and 105 deletions
|
@ -1,8 +1,8 @@
|
|||
package config
|
||||
|
||||
type Config struct {
|
||||
Env string `env:"ENV" env-default:"prod"`
|
||||
//Pandoc string `env:"PANDOC" required:"true"`
|
||||
Env string `env:"ENV" env-default:"prod"`
|
||||
Pandoc string `env:"PANDOC" required:"true"`
|
||||
Address string `env:"ADDRESS" required:"true"`
|
||||
PostgresDSN string `env:"POSTGRES_DSN" required:"true"`
|
||||
JWTSecret string `env:"JWT_SECRET" required:"true"`
|
||||
|
|
|
@ -3,18 +3,26 @@ package models
|
|||
import "time"
|
||||
|
||||
type Problem struct {
|
||||
Id int32 `db:"id"`
|
||||
Title string `db:"title"`
|
||||
Legend string `db:"legend"`
|
||||
InputFormat string `db:"input_format"`
|
||||
OutputFormat string `db:"output_format"`
|
||||
Notes string `db:"notes"`
|
||||
Tutorial string `db:"tutorial"`
|
||||
LatexSummary string `db:"latex_summary"`
|
||||
TimeLimit int32 `db:"time_limit"`
|
||||
MemoryLimit int32 `db:"memory_limit"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
Id int32 `db:"id"`
|
||||
Title string `db:"title"`
|
||||
TimeLimit int32 `db:"time_limit"`
|
||||
MemoryLimit int32 `db:"memory_limit"`
|
||||
|
||||
Legend string `db:"legend"`
|
||||
InputFormat string `db:"input_format"`
|
||||
OutputFormat string `db:"output_format"`
|
||||
Notes string `db:"notes"`
|
||||
Scoring string `db:"scoring"`
|
||||
LatexSummary string `db:"latex_summary"`
|
||||
|
||||
LegendHtml string `db:"legend_html"`
|
||||
InputFormatHtml string `db:"input_format_html"`
|
||||
OutputFormatHtml string `db:"output_format_html"`
|
||||
NotesHtml string `db:"notes_html"`
|
||||
ScoringHtml string `db:"scoring_html"`
|
||||
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
|
||||
type ProblemListItem struct {
|
||||
|
@ -27,24 +35,35 @@ type ProblemListItem struct {
|
|||
}
|
||||
|
||||
type ProblemUpdate struct {
|
||||
Title *string `db:"title"`
|
||||
Title *string `db:"title"`
|
||||
MemoryLimit *int32 `db:"memory_limit"`
|
||||
TimeLimit *int32 `db:"time_limit"`
|
||||
|
||||
Legend *string `db:"legend"`
|
||||
InputFormat *string `db:"input_format"`
|
||||
OutputFormat *string `db:"output_format"`
|
||||
Notes *string `db:"notes"`
|
||||
Tutorial *string `db:"tutorial"`
|
||||
LatexSummary *string `db:"latex_summary"`
|
||||
MemoryLimit *int32 `db:"memory_limit"`
|
||||
TimeLimit *int32 `db:"time_limit"`
|
||||
Scoring *string `db:"scoring"`
|
||||
|
||||
LegendHtml *string `db:"legend_html"`
|
||||
InputFormatHtml *string `db:"input_format_html"`
|
||||
OutputFormatHtml *string `db:"output_format_html"`
|
||||
NotesHtml *string `db:"notes_html"`
|
||||
ScoringHtml *string `db:"scoring_html"`
|
||||
}
|
||||
|
||||
type ProblemStatement struct {
|
||||
Title string `db:"title"`
|
||||
Legend string `db:"legend"`
|
||||
InputFormat string `db:"input_format"`
|
||||
OutputFormat string `db:"output_format"`
|
||||
Notes string `db:"notes"`
|
||||
Tutorial string `db:"tutorial"`
|
||||
TimeLimit int32 `db:"time_limit"`
|
||||
MemoryLimit int32 `db:"memory_limit"`
|
||||
Scoring string `db:"scoring"`
|
||||
}
|
||||
|
||||
type Html5ProblemStatement struct {
|
||||
LegendHtml string `db:"legend_html"`
|
||||
InputFormatHtml string `db:"input_format_html"`
|
||||
OutputFormatHtml string `db:"output_format_html"`
|
||||
NotesHtml string `db:"notes_html"`
|
||||
ScoringHtml string `db:"scoring_html"`
|
||||
}
|
||||
|
|
|
@ -220,18 +220,25 @@ func (h *TesterHandlers) GetProblem(c *fiber.Ctx, id int32) error {
|
|||
|
||||
return c.JSON(
|
||||
testerv1.GetProblemResponse{Problem: testerv1.Problem{
|
||||
Id: problem.Id,
|
||||
Title: problem.Title,
|
||||
Id: problem.Id,
|
||||
Title: problem.Title,
|
||||
TimeLimit: problem.TimeLimit,
|
||||
MemoryLimit: problem.MemoryLimit,
|
||||
|
||||
Legend: problem.Legend,
|
||||
InputFormat: problem.InputFormat,
|
||||
OutputFormat: problem.OutputFormat,
|
||||
Notes: problem.Notes,
|
||||
Tutorial: problem.Tutorial,
|
||||
LatexSummary: problem.LatexSummary,
|
||||
TimeLimit: problem.TimeLimit,
|
||||
MemoryLimit: problem.MemoryLimit,
|
||||
CreatedAt: problem.CreatedAt,
|
||||
UpdatedAt: problem.UpdatedAt,
|
||||
Scoring: problem.Scoring,
|
||||
|
||||
LegendHtml: problem.LegendHtml,
|
||||
InputFormatHtml: problem.InputFormatHtml,
|
||||
OutputFormatHtml: problem.OutputFormatHtml,
|
||||
NotesHtml: problem.NotesHtml,
|
||||
ScoringHtml: problem.ScoringHtml,
|
||||
|
||||
CreatedAt: problem.CreatedAt,
|
||||
UpdatedAt: problem.UpdatedAt,
|
||||
}},
|
||||
)
|
||||
}
|
||||
|
@ -274,14 +281,15 @@ func (h *TesterHandlers) UpdateProblem(c *fiber.Ctx, id int32) error {
|
|||
}
|
||||
|
||||
err = h.problemsUC.UpdateProblem(c.Context(), id, models.ProblemUpdate{
|
||||
Title: req.Title,
|
||||
Title: req.Title,
|
||||
MemoryLimit: req.MemoryLimit,
|
||||
TimeLimit: req.TimeLimit,
|
||||
|
||||
Legend: req.Legend,
|
||||
InputFormat: req.InputFormat,
|
||||
OutputFormat: req.OutputFormat,
|
||||
Notes: req.Notes,
|
||||
Tutorial: req.Tutorial,
|
||||
MemoryLimit: req.MemoryLimit,
|
||||
TimeLimit: req.TimeLimit,
|
||||
Scoring: req.Scoring,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
|
|
|
@ -114,15 +114,22 @@ func (r *ProblemRepository) ListProblems(ctx context.Context, q tester.Querier,
|
|||
|
||||
const (
|
||||
UpdateProblemQuery = `UPDATE problems
|
||||
SET title = COALESCE(?, title),
|
||||
legend = COALESCE(?, legend),
|
||||
input_format = COALESCE(?, input_format),
|
||||
output_format = COALESCE(?, output_format),
|
||||
notes = COALESCE(?, notes),
|
||||
tutorial = COALESCE(?, tutorial),
|
||||
latex_summary = COALESCE(?, latex_summary),
|
||||
time_limit = COALESCE(?, time_limit),
|
||||
memory_limit = COALESCE(?, memory_limit)
|
||||
SET title = COALESCE(?, title),
|
||||
time_limit = COALESCE(?, time_limit),
|
||||
memory_limit = COALESCE(?, memory_limit),
|
||||
|
||||
legend = COALESCE(?, legend),
|
||||
input_format = COALESCE(?, input_format),
|
||||
output_format = COALESCE(?, output_format),
|
||||
notes = COALESCE(?, notes),
|
||||
scoring = COALESCE(?, scoring),
|
||||
|
||||
legend_html = COALESCE(?, legend_html),
|
||||
input_format_html = COALESCE(?, input_format_html),
|
||||
output_format_html = COALESCE(?, output_format_html),
|
||||
notes_html = COALESCE(?, notes_html),
|
||||
scoring_html = COALESCE(?, scoring_html)
|
||||
|
||||
WHERE id=?`
|
||||
)
|
||||
|
||||
|
@ -132,14 +139,21 @@ func (r *ProblemRepository) UpdateProblem(ctx context.Context, q tester.Querier,
|
|||
query := q.Rebind(UpdateProblemQuery)
|
||||
_, err := q.ExecContext(ctx, query,
|
||||
problem.Title,
|
||||
problem.TimeLimit,
|
||||
problem.MemoryLimit,
|
||||
|
||||
problem.Legend,
|
||||
problem.InputFormat,
|
||||
problem.OutputFormat,
|
||||
problem.Notes,
|
||||
problem.Tutorial,
|
||||
problem.LatexSummary,
|
||||
problem.TimeLimit,
|
||||
problem.MemoryLimit,
|
||||
problem.Scoring,
|
||||
|
||||
problem.LegendHtml,
|
||||
problem.InputFormatHtml,
|
||||
problem.OutputFormatHtml,
|
||||
problem.NotesHtml,
|
||||
problem.ScoringHtml,
|
||||
|
||||
id,
|
||||
)
|
||||
if err != nil {
|
||||
|
|
|
@ -3,23 +3,25 @@ package usecase
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"git.sch9.ru/new_gate/ms-tester/internal/models"
|
||||
"git.sch9.ru/new_gate/ms-tester/internal/tester"
|
||||
"git.sch9.ru/new_gate/ms-tester/pkg"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ProblemUseCase struct {
|
||||
problemRepo tester.ProblemPostgresRepository
|
||||
//pandocClient pkg.PandocClient
|
||||
problemRepo tester.ProblemPostgresRepository
|
||||
pandocClient pkg.PandocClient
|
||||
}
|
||||
|
||||
func NewProblemUseCase(
|
||||
problemRepo tester.ProblemPostgresRepository,
|
||||
// pandocClient pkg.PandocClient,
|
||||
pandocClient pkg.PandocClient,
|
||||
) *ProblemUseCase {
|
||||
return &ProblemUseCase{
|
||||
problemRepo: problemRepo,
|
||||
//pandocClient: pandocClient,
|
||||
problemRepo: problemRepo,
|
||||
pandocClient: pandocClient,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,14 +47,82 @@ func isEmpty(p models.ProblemUpdate) bool {
|
|||
p.InputFormat == nil &&
|
||||
p.OutputFormat == nil &&
|
||||
p.Notes == nil &&
|
||||
p.Tutorial == nil &&
|
||||
p.LatexSummary == nil &&
|
||||
p.Scoring == nil &&
|
||||
p.MemoryLimit == nil &&
|
||||
p.TimeLimit == nil
|
||||
}
|
||||
|
||||
func build(p models.ProblemStatement) string {
|
||||
return ""
|
||||
const heading = `
|
||||
\newcommand{\InputFile}{\subsection*{Входные данные}}
|
||||
\newcommand{\OutputFile}{\subsection*{Выходные данные}}
|
||||
\newcommand{\Scoring}{\subsection*{Система оценки}}
|
||||
\newcommand{\Note}{\subsection*{Примечание}}
|
||||
\newcommand{\Examples}{\subsection*{Примеры}}
|
||||
`
|
||||
|
||||
func wrap(s string) string {
|
||||
return fmt.Sprintf("%s\n\\begin{document}\n%s\n\\end{document}\n", heading, s)
|
||||
}
|
||||
|
||||
func trimSpaces(statement models.ProblemStatement) models.ProblemStatement {
|
||||
return models.ProblemStatement{
|
||||
Legend: strings.TrimSpace(statement.Legend),
|
||||
InputFormat: strings.TrimSpace(statement.InputFormat),
|
||||
OutputFormat: strings.TrimSpace(statement.OutputFormat),
|
||||
Notes: strings.TrimSpace(statement.Notes),
|
||||
Scoring: strings.TrimSpace(statement.Scoring),
|
||||
}
|
||||
}
|
||||
|
||||
func build(ctx context.Context, pandocClient pkg.PandocClient, p models.ProblemStatement) (models.Html5ProblemStatement, error) {
|
||||
p = trimSpaces(p)
|
||||
|
||||
latex := models.ProblemStatement{}
|
||||
|
||||
if p.Legend != "" {
|
||||
latex.Legend = wrap(fmt.Sprintf("\\InputFile\n%s\n", p.Legend))
|
||||
}
|
||||
|
||||
if p.InputFormat != "" {
|
||||
latex.InputFormat = wrap(fmt.Sprintf("\\InputFile\n%s\n", p.InputFormat))
|
||||
}
|
||||
|
||||
if p.OutputFormat != "" {
|
||||
latex.OutputFormat = wrap(fmt.Sprintf("\\OutputFile\n%s\n", p.OutputFormat))
|
||||
}
|
||||
|
||||
if p.Notes != "" {
|
||||
latex.Notes = wrap(fmt.Sprintf("\\Note\n%s\n", p.Notes))
|
||||
}
|
||||
|
||||
if p.Scoring != "" {
|
||||
latex.Scoring = wrap(fmt.Sprintf("\\Scoring\n%s\n", p.Scoring))
|
||||
}
|
||||
|
||||
req := []string{
|
||||
latex.Legend,
|
||||
latex.InputFormat,
|
||||
latex.OutputFormat,
|
||||
latex.Notes,
|
||||
latex.Scoring,
|
||||
}
|
||||
|
||||
res, err := pandocClient.BatchConvertLatexToHtml5(ctx, req)
|
||||
if err != nil {
|
||||
return models.Html5ProblemStatement{}, err
|
||||
}
|
||||
|
||||
if len(res) != len(req) {
|
||||
return models.Html5ProblemStatement{}, fmt.Errorf("wrong number of fieilds returned: %d", len(res))
|
||||
}
|
||||
|
||||
return models.Html5ProblemStatement{
|
||||
LegendHtml: res[0],
|
||||
InputFormatHtml: res[1],
|
||||
OutputFormatHtml: res[2],
|
||||
NotesHtml: res[3],
|
||||
ScoringHtml: res[4],
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *ProblemUseCase) UpdateProblem(ctx context.Context, id int32, problemUpdate models.ProblemUpdate) error {
|
||||
|
@ -71,19 +141,13 @@ func (u *ProblemUseCase) UpdateProblem(ctx context.Context, id int32, problemUpd
|
|||
}
|
||||
|
||||
statement := models.ProblemStatement{
|
||||
Title: problem.Title,
|
||||
Legend: problem.Legend,
|
||||
InputFormat: problem.InputFormat,
|
||||
OutputFormat: problem.OutputFormat,
|
||||
Notes: problem.Notes,
|
||||
Tutorial: problem.Tutorial,
|
||||
TimeLimit: problem.TimeLimit,
|
||||
MemoryLimit: problem.MemoryLimit,
|
||||
Scoring: problem.Scoring,
|
||||
}
|
||||
|
||||
if problemUpdate.Title != nil {
|
||||
statement.Title = *problemUpdate.Title
|
||||
}
|
||||
if problemUpdate.Legend != nil {
|
||||
statement.Legend = *problemUpdate.Legend
|
||||
}
|
||||
|
@ -96,19 +160,29 @@ func (u *ProblemUseCase) UpdateProblem(ctx context.Context, id int32, problemUpd
|
|||
if problemUpdate.Notes != nil {
|
||||
statement.Notes = *problemUpdate.Notes
|
||||
}
|
||||
if problemUpdate.Tutorial != nil {
|
||||
statement.Tutorial = *problemUpdate.Tutorial
|
||||
}
|
||||
if problemUpdate.TimeLimit != nil {
|
||||
statement.TimeLimit = *problemUpdate.TimeLimit
|
||||
}
|
||||
if problemUpdate.MemoryLimit != nil {
|
||||
statement.MemoryLimit = *problemUpdate.MemoryLimit
|
||||
if problemUpdate.Scoring != nil {
|
||||
statement.Scoring = *problemUpdate.Scoring
|
||||
}
|
||||
|
||||
builtStatement := build(statement)
|
||||
if builtStatement != problem.LatexSummary {
|
||||
problemUpdate.LatexSummary = &builtStatement
|
||||
builtStatement, err := build(ctx, u.pandocClient, trimSpaces(statement))
|
||||
if err != nil {
|
||||
return errors.Join(err, tx.Rollback())
|
||||
}
|
||||
|
||||
if builtStatement.LegendHtml != problem.LegendHtml {
|
||||
problemUpdate.LegendHtml = &builtStatement.LegendHtml
|
||||
}
|
||||
if builtStatement.InputFormatHtml != problem.InputFormatHtml {
|
||||
problemUpdate.InputFormatHtml = &builtStatement.InputFormatHtml
|
||||
}
|
||||
if builtStatement.OutputFormatHtml != problem.OutputFormatHtml {
|
||||
problemUpdate.OutputFormatHtml = &builtStatement.OutputFormatHtml
|
||||
}
|
||||
if builtStatement.NotesHtml != problem.NotesHtml {
|
||||
problemUpdate.NotesHtml = &builtStatement.NotesHtml
|
||||
}
|
||||
if builtStatement.ScoringHtml != problem.ScoringHtml {
|
||||
problemUpdate.ScoringHtml = &builtStatement.ScoringHtml
|
||||
}
|
||||
|
||||
err = u.problemRepo.UpdateProblem(ctx, tx, id, problemUpdate)
|
||||
|
|
5
main.go
5
main.go
|
@ -12,6 +12,7 @@ import (
|
|||
fiberlogger "github.com/gofiber/fiber/v2/middleware/logger"
|
||||
"github.com/ilyakaznacheev/cleanenv"
|
||||
"go.uber.org/zap"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
@ -41,10 +42,10 @@ func main() {
|
|||
defer db.Close()
|
||||
logger.Info("successfully connected to postgres")
|
||||
|
||||
//pandocClient := pkg.NewPandocClient(&http.Client{}, cfg.Pandoc)
|
||||
pandocClient := pkg.NewPandocClient(&http.Client{}, cfg.Pandoc)
|
||||
|
||||
problemRepo := problemsRepository.NewProblemRepository(db)
|
||||
problemUC := testerUseCase.NewProblemUseCase(problemRepo)
|
||||
problemUC := testerUseCase.NewProblemUseCase(problemRepo, pandocClient)
|
||||
|
||||
contestRepo := problemsRepository.NewContestRepository(db)
|
||||
contestUC := testerUseCase.NewContestUseCase(contestRepo)
|
||||
|
|
|
@ -11,22 +11,30 @@ $$;
|
|||
|
||||
CREATE TABLE IF NOT EXISTS problems
|
||||
(
|
||||
id serial NOT NULL,
|
||||
title varchar(64) NOT NULL,
|
||||
legend varchar(10240) NOT NULL DEFAULT '',
|
||||
input_format varchar(10240) NOT NULL DEFAULT '',
|
||||
output_format varchar(10240) NOT NULL DEFAULT '',
|
||||
notes varchar(10240) NOT NULL DEFAULT '',
|
||||
tutorial varchar(10240) NOT NULL DEFAULT '',
|
||||
latex_summary varchar(10240) NOT NULL DEFAULT '',
|
||||
time_limit integer NOT NULL DEFAULT 1000,
|
||||
memory_limit integer NOT NULL DEFAULT 64,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
id serial NOT NULL,
|
||||
title varchar(64) NOT NULL,
|
||||
time_limit integer NOT NULL DEFAULT 1000,
|
||||
memory_limit integer NOT NULL DEFAULT 64,
|
||||
|
||||
legend varchar(10240) NOT NULL DEFAULT '',
|
||||
input_format varchar(10240) NOT NULL DEFAULT '',
|
||||
output_format varchar(10240) NOT NULL DEFAULT '',
|
||||
notes varchar(10240) NOT NULL DEFAULT '',
|
||||
scoring varchar(10240) NOT NULL DEFAULT '',
|
||||
|
||||
legend_html varchar(10240) NOT NULL DEFAULT '',
|
||||
input_format_html varchar(10240) NOT NULL DEFAULT '',
|
||||
output_format_html varchar(10240) NOT NULL DEFAULT '',
|
||||
notes_html varchar(10240) NOT NULL DEFAULT '',
|
||||
scoring_html varchar(10240) NOT NULL DEFAULT '',
|
||||
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
|
||||
PRIMARY KEY (id),
|
||||
CHECK (length(title) != 0),
|
||||
CHECK (memory_limit BETWEEN 4 and 1024),
|
||||
CHECK (time_limit BETWEEN 250 and 15000)
|
||||
CHECK (time_limit BETWEEN 250 and 5000)
|
||||
);
|
||||
|
||||
CREATE TRIGGER on_problems_update
|
||||
|
|
|
@ -4,8 +4,11 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
|
@ -15,6 +18,7 @@ type Client struct {
|
|||
|
||||
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 {
|
||||
|
@ -24,44 +28,126 @@ func NewPandocClient(client *http.Client, address string) *Client {
|
|||
}
|
||||
}
|
||||
|
||||
type convertRequest struct {
|
||||
type conversation struct {
|
||||
Text string `json:"text"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Math string `json:"html-math-method"`
|
||||
}
|
||||
|
||||
func (client *Client) convert(ctx context.Context, text, from, to string) (string, error) {
|
||||
body, err := json.Marshal(convertRequest{
|
||||
Text: text,
|
||||
From: from,
|
||||
To: to,
|
||||
})
|
||||
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 "", err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(body)
|
||||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, client.address, buf)
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, path, buf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
|
||||
resp, err := client.client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
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
|
||||
}
|
||||
|
||||
return string(body), nil
|
||||
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")
|
||||
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")
|
||||
}
|
||||
|
|
2
proto
2
proto
|
@ -1 +1 @@
|
|||
Subproject commit d021cf202fde8ba13409b9031d01e8b068b82ca9
|
||||
Subproject commit fb65ba8ce2220e7e47990f0f52214126839b3d78
|
Loading…
Add table
Reference in a new issue