feat(tester): add bluemonday
This commit is contained in:
parent
94fc50e272
commit
af6e0b89f6
3 changed files with 117 additions and 84 deletions
|
@ -7,6 +7,7 @@ import (
|
|||
"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"
|
||||
"github.com/microcosm-cc/bluemonday"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -41,90 +42,6 @@ func (u *ProblemUseCase) ListProblems(ctx context.Context, page int32, pageSize
|
|||
return u.problemRepo.ListProblems(ctx, u.problemRepo.DB(), page, pageSize)
|
||||
}
|
||||
|
||||
func isEmpty(p models.ProblemUpdate) bool {
|
||||
return p.Title == nil &&
|
||||
p.Legend == nil &&
|
||||
p.InputFormat == nil &&
|
||||
p.OutputFormat == nil &&
|
||||
p.Notes == nil &&
|
||||
p.Scoring == nil &&
|
||||
p.MemoryLimit == nil &&
|
||||
p.TimeLimit == nil
|
||||
}
|
||||
|
||||
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 {
|
||||
if isEmpty(problemUpdate) {
|
||||
return pkg.Wrap(pkg.ErrBadInput, nil, "UpdateProblem", "empty problem update")
|
||||
|
@ -197,3 +114,109 @@ func (u *ProblemUseCase) UpdateProblem(ctx context.Context, id int32, problemUpd
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isEmpty(p models.ProblemUpdate) bool {
|
||||
return p.Title == nil &&
|
||||
p.Legend == nil &&
|
||||
p.InputFormat == nil &&
|
||||
p.OutputFormat == nil &&
|
||||
p.Notes == nil &&
|
||||
p.Scoring == nil &&
|
||||
p.MemoryLimit == nil &&
|
||||
p.TimeLimit == nil
|
||||
}
|
||||
|
||||
func wrap(s string) string {
|
||||
return fmt.Sprintf("\\begin{document}\n%s\n\\end{document}\n", 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 sanitize(statement models.Html5ProblemStatement) models.Html5ProblemStatement {
|
||||
p := bluemonday.UGCPolicy()
|
||||
|
||||
p.AllowAttrs("class").Globally()
|
||||
p.AllowAttrs("style").Globally()
|
||||
p.AllowStyles("text-align").MatchingEnum("center", "left", "right").Globally()
|
||||
p.AllowStyles("display").MatchingEnum("block", "inline", "inline-block").Globally()
|
||||
|
||||
p.AllowStandardURLs()
|
||||
p.AllowAttrs("cite").OnElements("blockquote", "q")
|
||||
p.AllowAttrs("href").OnElements("a", "area")
|
||||
p.AllowAttrs("src").OnElements("img")
|
||||
|
||||
if statement.LegendHtml != "" {
|
||||
statement.LegendHtml = p.Sanitize(statement.LegendHtml)
|
||||
}
|
||||
if statement.InputFormatHtml != "" {
|
||||
statement.InputFormatHtml = p.Sanitize(statement.InputFormatHtml)
|
||||
}
|
||||
if statement.OutputFormatHtml != "" {
|
||||
statement.OutputFormatHtml = p.Sanitize(statement.OutputFormatHtml)
|
||||
}
|
||||
if statement.NotesHtml != "" {
|
||||
statement.NotesHtml = p.Sanitize(statement.NotesHtml)
|
||||
}
|
||||
if statement.ScoringHtml != "" {
|
||||
statement.ScoringHtml = p.Sanitize(statement.ScoringHtml)
|
||||
}
|
||||
|
||||
return statement
|
||||
}
|
||||
|
||||
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(p.Legend)
|
||||
}
|
||||
if p.InputFormat != "" {
|
||||
latex.InputFormat = wrap(p.InputFormat)
|
||||
}
|
||||
if p.OutputFormat != "" {
|
||||
latex.OutputFormat = wrap(p.OutputFormat)
|
||||
}
|
||||
if p.Notes != "" {
|
||||
latex.Notes = wrap(p.Notes)
|
||||
}
|
||||
if p.Scoring != "" {
|
||||
latex.Scoring = wrap(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))
|
||||
}
|
||||
|
||||
sanitizedStatement := sanitize(models.Html5ProblemStatement{
|
||||
LegendHtml: res[0],
|
||||
InputFormatHtml: res[1],
|
||||
OutputFormatHtml: res[2],
|
||||
NotesHtml: res[3],
|
||||
ScoringHtml: res[4],
|
||||
})
|
||||
|
||||
return sanitizedStatement, nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue