Skip to content
This repository was archived by the owner on Jul 16, 2024. It is now read-only.

Commit 957330e

Browse files
committed
feat: POST /domains/{domain}/problems/{problem}/configs
1 parent c587c9a commit 957330e

File tree

6 files changed

+96
-33
lines changed

6 files changed

+96
-33
lines changed

Diff for: app/handler/v1/problem.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,6 @@ func (s *Api) SubmitSolutionToProblem(
7272
request schema.SubmitSolutionToProblemRequestObject,
7373
) (any, error) {
7474
return convert.WithErr[schema.Record](
75-
service.Record(c).Submit(request.Body),
75+
service.Record(c).Submit(),
7676
)
7777
}

Diff for: app/handler/v1/problem_config.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package v1
33
import (
44
"github.com/gofiber/fiber/v2"
55
"github.com/joint-online-judge/go-horse/app/schema"
6+
"github.com/joint-online-judge/go-horse/app/service"
7+
"github.com/joint-online-judge/go-horse/pkg/convert"
68
)
79

810
// List Problem Config Commits
@@ -20,7 +22,9 @@ func (s *Api) UpdateProblemConfigByArchive(
2022
c *fiber.Ctx,
2123
request schema.UpdateProblemConfigByArchiveRequestObject,
2224
) (any, error) {
23-
return nil, schema.NewBizError(schema.APINotImplementedError)
25+
return convert.WithErr[schema.ProblemConfigDetail](
26+
service.ProblemConfig(c).UpdateProblemConfigByArchive(),
27+
)
2428
}
2529

2630
// Update Problem Config Json

Diff for: app/handler/v1/problem_set.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,6 @@ func (s *Api) SubmitSolutionToProblemInProblemSet(
114114
request schema.SubmitSolutionToProblemInProblemSetRequestObject,
115115
) (any, error) {
116116
return convert.WithErr[schema.Record](
117-
service.Record(c).SubmitInProblemSet(request.Body),
117+
service.Record(c).SubmitInProblemSet(),
118118
)
119119
}

Diff for: app/service/problem_config.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
package service
22

33
import (
4+
"mime/multipart"
5+
46
"github.com/gofiber/fiber/v2"
57
"github.com/joint-online-judge/go-horse/app/model"
8+
"github.com/joint-online-judge/go-horse/platform/storage"
69
"gorm.io/gorm"
710
)
811

@@ -18,13 +21,46 @@ func ProblemConfig(c *fiber.Ctx) *problemConfigImpl {
1821

1922
func (s *problemConfigImpl) GetLatestproblemConfig(
2023
problem *model.Problem,
21-
) (problemConfigModel model.ProblemConfig, err error) {
22-
problemConfigModel.ProblemId = &problem.Id
23-
result := db.Limit(1).Order("updated_at desc").Find(&problemConfigModel)
24+
) (problemConfig model.ProblemConfig, err error) {
25+
problemConfig.ProblemId = &problem.Id
26+
result := db.Limit(1).Order("updated_at desc").Find(&problemConfig)
2427
if result.Error != nil {
2528
err = result.Error
2629
} else if result.RowsAffected == 0 {
2730
err = gorm.ErrRecordNotFound
2831
}
2932
return
3033
}
34+
35+
func (s *problemConfigImpl) UpdateProblemConfigByArchive() (
36+
problemConfig model.ProblemConfig, err error,
37+
) {
38+
problem, err := Problem(s.c).GetCurrentProblem()
39+
if err != nil {
40+
return
41+
}
42+
user, err := User(s.c).GetCurrentUser()
43+
if err != nil {
44+
return
45+
}
46+
var form *multipart.Form
47+
if form, err = s.c.MultipartForm(); err != nil {
48+
return
49+
}
50+
formFiles, ok := form.File["file"]
51+
if !ok || len(formFiles) != 1 {
52+
err = fiber.ErrUnprocessableEntity
53+
return
54+
}
55+
problemConfig = model.ProblemConfig{
56+
ProblemId: &problem.Id,
57+
CommitterId: &user.Id,
58+
}
59+
err = db.Transaction(func(tx *gorm.DB) error {
60+
if err := tx.Create(&problemConfig).Error; err != nil {
61+
return err
62+
}
63+
return storage.PutProblemConfig("", formFiles[0])
64+
})
65+
return
66+
}

Diff for: app/service/record.go

+12-16
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,7 @@ func (s *recordImpl) GetCurrentRecord() (*model.Record, error) {
6262
return record.(*model.Record), nil
6363
}
6464

65-
func (s *recordImpl) prepareSubmit(
66-
body *multipart.Reader, form *multipart.Form, inProblemSet bool,
67-
) (
65+
func (s *recordImpl) prepareSubmit(form *multipart.Form, inProblemSet bool) (
6866
problemSet *model.ProblemSet, problem *model.Problem, record model.Record,
6967
userLatestRecord model.UserLatestRecord, err error,
7068
) {
@@ -107,7 +105,7 @@ func (s *recordImpl) prepareSubmit(
107105
return
108106
}
109107

110-
func (s *recordImpl) submitImpl(body *multipart.Reader, inProblemSet bool) (
108+
func (s *recordImpl) submitImpl(inProblemSet bool) (
111109
record model.Record, err error,
112110
) {
113111
var form *multipart.Form
@@ -116,32 +114,32 @@ func (s *recordImpl) submitImpl(body *multipart.Reader, inProblemSet bool) (
116114
}
117115
logrus.Debugf("form: %+v", form)
118116
problemSet, problem, record, userLatestRecord, err := s.prepareSubmit(
119-
body, form, inProblemSet,
117+
form, inProblemSet,
120118
)
121119
if err != nil {
122120
return
123121
}
124122
err = db.Transaction(func(tx *gorm.DB) error {
125-
if err := db.Save(&record).Error; err != nil {
123+
if err := tx.Save(&record).Error; err != nil {
126124
return err
127125
}
128126
if inProblemSet {
129-
if err := db.Save(problemSet).Error; err != nil {
127+
if err := tx.Save(problemSet).Error; err != nil {
130128
return err
131129
}
132130
}
133-
if err := db.Save(problem).Error; err != nil {
131+
if err := tx.Save(problem).Error; err != nil {
134132
return err
135133
}
136134
// TODO: save latest record in cache
137-
result := db.Limit(1).Find(&userLatestRecord)
135+
result := tx.Limit(1).Find(&userLatestRecord)
138136
if result.RowsAffected == 1 {
139137
if err := result.Update("record_id", record.Id).Error; err != nil {
140138
return err
141139
}
142140
} else {
143141
userLatestRecord.RecordId = record.Id
144-
if err := db.Save(&userLatestRecord).Error; err != nil {
142+
if err := tx.Save(&userLatestRecord).Error; err != nil {
145143
return err
146144
}
147145
}
@@ -154,12 +152,10 @@ func (s *recordImpl) submitImpl(body *multipart.Reader, inProblemSet bool) (
154152
return
155153
}
156154

157-
func (s *recordImpl) SubmitInProblemSet(
158-
body *multipart.Reader,
159-
) (model.Record, error) {
160-
return s.submitImpl(body, true)
155+
func (s *recordImpl) SubmitInProblemSet() (model.Record, error) {
156+
return s.submitImpl(true)
161157
}
162158

163-
func (s *recordImpl) Submit(body *multipart.Reader) (model.Record, error) {
164-
return s.submitImpl(body, false)
159+
func (s *recordImpl) Submit() (model.Record, error) {
160+
return s.submitImpl(false)
165161
}

Diff for: platform/storage/minio.go

+38-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package storage
22

33
import (
4+
"archive/zip"
45
"context"
56
"fmt"
67
"mime/multipart"
@@ -53,24 +54,15 @@ func EnsureBucket(bucketName string) {
5354
}
5455

5556
func PutSubmission(prefix string, files []*multipart.FileHeader) error {
56-
return putObjects(SubmissionBucketName, prefix, files)
57-
}
58-
59-
func PutConfig(prefix string, files []*multipart.FileHeader) error {
60-
return putObjects(ProblemConfigBucketName, prefix, files)
61-
}
62-
63-
func putObjects(
64-
bucketName, prefix string, files []*multipart.FileHeader,
65-
) error {
6657
for _, file := range files {
6758
reader, err := file.Open()
6859
if err != nil {
6960
return err
7061
}
62+
defer reader.Close()
7163
uploadInfo, err := Minio.PutObject(
7264
context.Background(),
73-
bucketName,
65+
SubmissionBucketName,
7466
file.Filename,
7567
reader,
7668
file.Size,
@@ -83,3 +75,38 @@ func putObjects(
8375
}
8476
return nil
8577
}
78+
79+
func PutProblemConfig(prefix string, file *multipart.FileHeader) error {
80+
fileReader, err := file.Open()
81+
if err != nil {
82+
return err
83+
}
84+
defer fileReader.Close()
85+
zipFile, err := zip.NewReader(fileReader, file.Size)
86+
if err != nil {
87+
return err
88+
}
89+
for _, file := range zipFile.File {
90+
reader, err := file.Open()
91+
if err != nil {
92+
return err
93+
}
94+
defer reader.Close()
95+
if file.FileInfo().IsDir() {
96+
continue
97+
}
98+
uploadInfo, err := Minio.PutObject(
99+
context.Background(),
100+
SubmissionBucketName,
101+
file.FileInfo().Name(),
102+
reader,
103+
file.FileInfo().Size(),
104+
minio.PutObjectOptions{ContentType: "application/octet-stream"},
105+
)
106+
if err != nil {
107+
return err
108+
}
109+
logrus.Debugf("Successfully uploaded bytes: %+v", uploadInfo)
110+
}
111+
return nil
112+
}

0 commit comments

Comments
 (0)