Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Add MustPutInputFile function #143

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions app/controller/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -397,12 +397,11 @@ func CreateTestCase(c echo.Context) error {
InputFileName: inputFile.Filename,
OutputFileName: outputFile.Filename,
}

if err := base.DB.Model(&problem).Association("TestCases").Append(&testCase); err != nil {
panic(errors.Wrap(err, "could not create test case"))
}

utils.MustPutObject(inputFile, c.Request().Context(), "problems", fmt.Sprintf("%d/input/%d.in", problem.ID, testCase.ID))
// upload to minio
utils.MustPutInputFile(*req.Sanitize, inputFile, c.Request().Context(), "problems", fmt.Sprintf("%d/input/%d.in", problem.ID, testCase.ID))
utils.MustPutObject(outputFile, c.Request().Context(), "problems", fmt.Sprintf("%d/output/%d.out", problem.ID, testCase.ID))

return c.JSON(http.StatusCreated, response.CreateTestCaseResponse{
Expand Down Expand Up @@ -478,7 +477,6 @@ func UpdateTestCase(c echo.Context) error {
if err, ok := utils.BindAndValidate(&req, c); !ok {
return err
}

inputFile, err := c.FormFile("input_file")
if err != nil && err != http.ErrMissingFile && err.Error() != "request Content-Type isn't multipart/form-data" {
panic(errors.Wrap(err, "could not read input file"))
Expand All @@ -489,7 +487,7 @@ func UpdateTestCase(c echo.Context) error {
}

if inputFile != nil {
utils.MustPutObject(inputFile, c.Request().Context(), "problems", fmt.Sprintf("%d/input/%d.in", problem.ID, testCase.ID))
utils.MustPutInputFile(*req.Sanitize, inputFile, c.Request().Context(), "problems", fmt.Sprintf("%d/input/%d.in", problem.ID, testCase.ID))
testCase.InputFileName = inputFile.Filename
}
if outputFile != nil {
Expand Down
12 changes: 8 additions & 4 deletions app/request/problem.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ type CreateProblemRequest struct {
Public *bool `json:"public" form:"public" query:"public" validate:"required"`
Privacy *bool `json:"privacy" form:"privacy" query:"privacy" validate:"required"`

Sanitize *bool `json:"sanitize" form:"sanitize" query:"sanitize" validate:"required"`

MemoryLimit uint64 `json:"memory_limit" form:"memory_limit" query:"memory_limit" validate:"required"` // Byte
TimeLimit uint `json:"time_limit" form:"time_limit" query:"time_limit" validate:"required"` // ms
LanguageAllowed string `json:"language_allowed" form:"language_allowed" query:"language_allowed" validate:"required,max=255"` // E.g. cpp,c,java,python
Expand Down Expand Up @@ -36,8 +38,9 @@ type DeleteProblemRequest struct {
}

type CreateTestCaseRequest struct {
Score uint `json:"score" form:"score" query:"score"` // 0 for 平均分配
Sample *bool `json:"sample" form:"sample" query:"sample" validate:"required"`
Score uint `json:"score" form:"score" query:"score"`
Sample *bool `json:"sample" form:"sample" query:"sample" validate:"required"`
Sanitize *bool `json:"sanitize" form:"sanitize" query:"sanitize" validate:"required"`
// input_file(required)
// output_file(required)
}
Expand All @@ -49,8 +52,9 @@ type GetTestCaseOutputFileRequest struct {
}

type UpdateTestCaseRequest struct {
Score uint `json:"score" form:"score" query:"score"` // 0 for 平均分配
Sample *bool `json:"sample" form:"sample" query:"sample" validate:"required"`
Score uint `json:"score" form:"score" query:"score"`
Sample *bool `json:"sample" form:"sample" query:"sample" validate:"required"`
Sanitize *bool `json:"sanitize" form:"sanitize" query:"sanitize" validate:"required"`
// input_file(optional)
// output_file(optional)
}
Expand Down
59 changes: 59 additions & 0 deletions base/utils/helpers.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package utils

import (
"bufio"
"context"
"fmt"
"mime/multipart"
"net/http"
"os"
"strings"

"github.com/EduOJ/backend/app/response"
"github.com/EduOJ/backend/base"
Expand Down Expand Up @@ -58,6 +62,61 @@ func MustPutObject(object *multipart.FileHeader, ctx context.Context, bucket str
}
}

func MustPutInputFile(sanitize bool, object *multipart.FileHeader, ctx context.Context, bucket string, path string) {
src, err := object.Open()
if err != nil {
panic(err)
}
defer src.Close()

var fileSize int64

if sanitize {
scanner := bufio.NewScanner(src)
tempFile, err := os.CreateTemp("", "tempFile*.txt")
if err != nil {
panic(err)
}
writer := bufio.NewWriter(tempFile)
for scanner.Scan() {
line := strings.ReplaceAll(scanner.Text(), "\r\n", "\n") // replace '\r\n' to '\n'

if !strings.HasSuffix(line, "\n") {
line += "\n"
}
_, err := fmt.Fprint(writer, line)
if err != nil {
panic(err)
}
}
if err := scanner.Err(); err != nil {
panic(err)
}
if err := writer.Flush(); err != nil {
panic(err)
}

fileInfo, err := tempFile.Stat()
if err != nil {
panic(err)
}
fileSize = fileInfo.Size()

src, err = os.Open(tempFile.Name())
if err != nil {
panic(err)
}
defer src.Close()
} else {
fileSize = object.Size
}

_, err = base.Storage.PutObject(ctx, bucket, path, src, fileSize, minio.PutObjectOptions{})
if err != nil {
panic(errors.Wrap(err, "could write file to s3 storage."))
}
}

func MustGetObject(c echo.Context, bucket string, path string) *minio.Object {
object, err := base.Storage.GetObject(c.Request().Context(), bucket, path, minio.GetObjectOptions{})
if err != nil {
Expand Down
Loading