fix up git
This commit is contained in:
@@ -231,6 +231,10 @@ func bundleSubmissionZips(rows []submissionRow, destZipPath string) (warnings []
|
||||
}
|
||||
|
||||
func collectSubmissionZipFiles(rows []submissionRow) (files []gitPathFile, warnings []string) {
|
||||
return collectSubmissionZipFilesWithPrefix(rows, true)
|
||||
}
|
||||
|
||||
func collectSubmissionZipFilesWithPrefix(rows []submissionRow, useStudentFolder bool) (files []gitPathFile, warnings []string) {
|
||||
byPath := map[string]gitPathFile{}
|
||||
usedFolders := map[string]int{}
|
||||
for _, row := range rows {
|
||||
@@ -238,13 +242,17 @@ func collectSubmissionZipFiles(rows []submissionRow) (files []gitPathFile, warni
|
||||
warnings = append(warnings, fmt.Sprintf("bài SV %d: không tìm thấy file", row.StudentRkID))
|
||||
continue
|
||||
}
|
||||
folder := studentSubmissionFolder(row.StudentCode, row.FullName)
|
||||
if n := usedFolders[folder]; n > 0 {
|
||||
folder = fmt.Sprintf("%s_%d", folder, n+1)
|
||||
prefix := ""
|
||||
if useStudentFolder {
|
||||
folder := studentSubmissionFolder(row.StudentCode, row.FullName)
|
||||
if n := usedFolders[folder]; n > 0 {
|
||||
folder = fmt.Sprintf("%s_%d", folder, n+1)
|
||||
}
|
||||
usedFolders[folder]++
|
||||
prefix = folder
|
||||
}
|
||||
usedFolders[folder]++
|
||||
|
||||
skipped, err := copySubmissionZipEntries(row.FilePath, folder, func(destPath string, open func() (io.ReadCloser, error), size int64) error {
|
||||
skipped, err := copySubmissionZipEntries(row.FilePath, prefix, func(destPath string, open func() (io.ReadCloser, error), size int64) error {
|
||||
if size > githubBlobMaxBytes {
|
||||
warnings = append(warnings, destPath+": file quá lớn (>100MB), bỏ qua")
|
||||
return nil
|
||||
@@ -262,11 +270,11 @@ func collectSubmissionZipFiles(rows []submissionRow) (files []gitPathFile, warni
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
warnings = append(warnings, folder+": "+err.Error())
|
||||
warnings = append(warnings, prefix+": "+err.Error())
|
||||
continue
|
||||
}
|
||||
for _, s := range skipped {
|
||||
warnings = append(warnings, folder+"/"+s)
|
||||
warnings = append(warnings, prefix+"/"+s)
|
||||
}
|
||||
}
|
||||
files = make([]gitPathFile, 0, len(byPath))
|
||||
@@ -453,6 +461,8 @@ func PublishExamSubmissionsGitHandler(db *gorm.DB) fiber.Handler {
|
||||
|
||||
room.GitPublishURL = viewURL
|
||||
_ = db.Save(&room).Error
|
||||
roomIDCopy := roomID
|
||||
recordStaffGitHubRepo(db, staffID, owner, repo, repoHTML, models.GitPublishModeRoom, room.Name, &roomIDCopy, nil)
|
||||
|
||||
msg := fmt.Sprintf("Đã đẩy %d bài lên GitHub — mỗi sinh viên một folder.", len(rows))
|
||||
if len(allWarn) > 0 {
|
||||
@@ -471,3 +481,112 @@ func PublishExamSubmissionsGitHandler(db *gorm.DB) fiber.Handler {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/exam-rooms/:id/submissions/publish-git-students — mỗi sinh viên một repo GitHub riêng
|
||||
func PublishExamSubmissionsGitPerStudentHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
staffID := middleware.StaffIDFromCtx(c)
|
||||
if staffID == 0 {
|
||||
return c.Status(401).JSON(fiber.Map{"error": "Unauthorized"})
|
||||
}
|
||||
token, ghLogin, err := loadStaffGitHubToken(db, staffID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return c.Status(401).JSON(fiber.Map{
|
||||
"error": "Chưa kết nối GitHub. Vào Tài khoản của tôi → Kết nối GitHub.",
|
||||
"needsGitHubOAuth": true,
|
||||
})
|
||||
}
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Không đọc được token GitHub"})
|
||||
}
|
||||
|
||||
roomID, err := parseUintParam(c, "id")
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid id"})
|
||||
}
|
||||
var room models.ExamRoom
|
||||
if err := db.First(&room, roomID).Error; err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "Không tìm thấy phòng thi"})
|
||||
}
|
||||
|
||||
rows, err := loadExamSubmissionRows(db, roomID)
|
||||
if err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": err.Error()})
|
||||
}
|
||||
if len(rows) == 0 {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Chưa có bài nộp"})
|
||||
}
|
||||
|
||||
branch := "main"
|
||||
published := 0
|
||||
var allWarn []string
|
||||
var repoURLs []string
|
||||
type studentRepo struct {
|
||||
StudentRkID int64 `json:"studentRkId"`
|
||||
StudentCode string `json:"studentCode"`
|
||||
FullName string `json:"fullName"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
studentRepos := make([]studentRepo, 0, len(rows))
|
||||
|
||||
for _, row := range rows {
|
||||
files, unpackWarn := collectSubmissionZipFilesWithPrefix([]submissionRow{row}, false)
|
||||
allWarn = append(allWarn, unpackWarn...)
|
||||
if len(files) == 0 {
|
||||
allWarn = append(allWarn, fmt.Sprintf("%s: không có file để đẩy", studentSubmissionFolder(row.StudentCode, row.FullName)))
|
||||
continue
|
||||
}
|
||||
repoName, repoHTML, err := githubEnsureRepoForStudent(token, ghLogin, &room, &row)
|
||||
if err != nil {
|
||||
allWarn = append(allWarn, row.StudentCode+": "+err.Error())
|
||||
continue
|
||||
}
|
||||
label := studentSubmissionFolder(row.StudentCode, row.FullName)
|
||||
commitMsg := fmt.Sprintf("Simple Care: bài nộp %s — %s", label, room.Name)
|
||||
viewURL, pushWarn, err := githubPushFiles(token, ghLogin, repoName, branch, files, commitMsg)
|
||||
allWarn = append(allWarn, pushWarn...)
|
||||
if err != nil {
|
||||
allWarn = append(allWarn, label+": "+err.Error())
|
||||
continue
|
||||
}
|
||||
_ = db.Model(&models.ExamSubmission{}).Where("id = ?", row.ID).
|
||||
Updates(map[string]any{"git_repo_url": repoHTML, "git_publish_url": viewURL}).Error
|
||||
subID := row.ID
|
||||
roomIDCopy := roomID
|
||||
recordStaffGitHubRepo(db, staffID, ghLogin, repoName, repoHTML, models.GitPublishModeStudent, label, &roomIDCopy, &subID)
|
||||
published++
|
||||
repoURLs = append(repoURLs, viewURL)
|
||||
studentRepos = append(studentRepos, studentRepo{
|
||||
StudentRkID: row.StudentRkID,
|
||||
StudentCode: row.StudentCode,
|
||||
FullName: row.FullName,
|
||||
URL: viewURL,
|
||||
})
|
||||
}
|
||||
|
||||
if published == 0 {
|
||||
return c.Status(502).JSON(fiber.Map{
|
||||
"error": "Không đẩy được repo nào",
|
||||
"warnings": allWarn,
|
||||
})
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("Đã tạo %d repo GitHub — mỗi sinh viên một repo.", published)
|
||||
if len(allWarn) > 0 {
|
||||
msg += fmt.Sprintf(" (%d cảnh báo)", len(allWarn))
|
||||
}
|
||||
openURL := ""
|
||||
if len(repoURLs) > 0 {
|
||||
openURL = repoURLs[0]
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{
|
||||
"ok": true,
|
||||
"published": published,
|
||||
"studentRepos": studentRepos,
|
||||
"openUrl": openURL,
|
||||
"warnings": allWarn,
|
||||
"message": msg,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user