Skip to content

Commit

Permalink
chore: beautify structure
Browse files Browse the repository at this point in the history
  • Loading branch information
Gurkengewuerz committed Oct 25, 2024
1 parent 7846275 commit 7e0f8a9
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 163 deletions.
15 changes: 11 additions & 4 deletions internal/api/handlers/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/gurkengewuerz/GitCodeJudge/db"
"github.com/gurkengewuerz/GitCodeJudge/internal/api/handlers/templates"
"html/template"
"github.com/gurkengewuerz/GitCodeJudge/internal/markdown"
)

func HandleCommitResults() fiber.Handler {
Expand All @@ -21,7 +21,7 @@ func HandleCommitResults() fiber.Handler {
})
}

var htmlContent []byte
var mdContent []byte
err := db.DB.View(func(txn *badger.Txn) error {
item, err := txn.Get([]byte(commitHash))
if errors.Is(err, badger.ErrKeyNotFound) {
Expand All @@ -31,7 +31,7 @@ func HandleCommitResults() fiber.Handler {
return err
}

htmlContent, err = item.ValueCopy(nil)
mdContent, err = item.ValueCopy(nil)
return err
})

Expand All @@ -47,10 +47,17 @@ func HandleCommitResults() fiber.Handler {
})
}

content, err := markdown.FormatMarkdownToHTML(string(mdContent))
if err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to generate HTML content",
})
}

// Prepare template data
data := templates.TemplateDataResult{
Title: fmt.Sprintf("Commit Results - %s", commitHash),
Content: template.HTML(htmlContent), // Convert to template.HTML to prevent escaping
Content: content, // Convert to template.HTML to prevent escaping
}

var buf bytes.Buffer
Expand Down
120 changes: 5 additions & 115 deletions internal/api/handlers/scoreboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,10 @@ import (
"github.com/gofiber/fiber/v2"
"github.com/gurkengewuerz/GitCodeJudge/internal/api/handlers/templates"
"github.com/gurkengewuerz/GitCodeJudge/internal/judge/scoreboard"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"html/template"
"sort"
"strings"
"time"
"github.com/gurkengewuerz/GitCodeJudge/internal/markdown"
"github.com/gurkengewuerz/GitCodeJudge/internal/models"
)

var md = goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
html.WithXHTML(),
),
)

func formatMarkdownToHTML(markdown string) (template.HTML, error) {
var htmlBuf bytes.Buffer
if err := md.Convert([]byte(markdown), &htmlBuf); err != nil {
return "", err
}
return template.HTML(htmlBuf.String()), nil
}

func HandleUserProgress(scoreboardManager *scoreboard.ScoreboardManager) fiber.Handler {
return func(c *fiber.Ctx) error {
username := c.Params("username")
Expand All @@ -57,37 +32,7 @@ func HandleUserProgress(scoreboardManager *scoreboard.ScoreboardManager) fiber.H
})
}

var b strings.Builder
b.WriteString(fmt.Sprintf("# Progress for %s\n\n", username))

// Task count summary
b.WriteString(fmt.Sprintf("## Overview\n\n"))
b.WriteString(fmt.Sprintf("Total Completed Tasks: **%d**\n\n", len(progress.Submissions)))

// Sort submissions by timestamp (most recent first)
sort.Slice(progress.Submissions, func(i, j int) bool {
return progress.Submissions[i].Submission.Timestamp.After(progress.Submissions[j].Submission.Timestamp)
})

b.WriteString("## Completed Tasks\n\n")
b.WriteString("| Workshop | Task | Completion Date | Repository | Commit |\n")
b.WriteString("|----------|------|-----------------|------------|--------|\n")

for _, submission := range progress.Submissions {
b.WriteString(fmt.Sprintf("| %s | [%s](/workshop/%s/%s) | %s | [%s](%s) | [`%s`](%s/results/%s) |\n",
submission.Workshop,
submission.Task,
submission.Workshop,
submission.Task,
submission.Submission.Timestamp.Format(time.RFC850),
submission.Submission.RepoName,
submission.Submission.CloneURL,
submission.Submission.CommitID[:8],
c.BaseURL(),
submission.Submission.CommitID))
}

content, err := formatMarkdownToHTML(b.String())
content, err := markdown.FormatMarkdownToHTML(models.FormatUserStats(c.BaseURL(), progress))
if err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to generate HTML content",
Expand Down Expand Up @@ -134,41 +79,7 @@ func HandleWorkshopStats(scoreboardManager *scoreboard.ScoreboardManager) fiber.
})
}

var b strings.Builder
b.WriteString(fmt.Sprintf("# Statistics for [%s/%s](/pdf?task=%s/%s)\n\n", workshop, task, workshop, task))

// Overview section
b.WriteString("## Overview\n\n")
b.WriteString(fmt.Sprintf("- Total Completions: **%d**\n", stats.TotalUsers))
if stats.LatestSubmit.Year() > 1 {
b.WriteString(fmt.Sprintf("- Latest Completion: **%s**\n", stats.LatestSubmit.Format(time.RFC850)))
}
b.WriteString("\n")

// Sort submissions by timestamp (most recent first)
sort.Slice(stats.Submissions, func(i, j int) bool {
return stats.Submissions[i].Timestamp.After(stats.Submissions[j].Timestamp)
})

b.WriteString("## Submissions\n\n")
b.WriteString("| User | Completion Date | Repository | Commit |\n")
b.WriteString("|------|-----------------|------------|--------|\n")

for _, submission := range stats.Submissions {
parts := strings.Split(submission.RepoName, "/")
username := parts[1]
b.WriteString(fmt.Sprintf("| [%s](/user/%s) | %s | [%s](%s) | [`%s`](%s/results/%s) |\n",
username,
username,
submission.Timestamp.Format(time.RFC850),
submission.RepoName,
submission.CloneURL,
submission.CommitID[:8],
c.BaseURL(),
submission.CommitID))
}

content, err := formatMarkdownToHTML(b.String())
content, err := markdown.FormatMarkdownToHTML(models.FormatWorkshopStats(c.BaseURL(), workshop, task, stats))
if err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to generate HTML content",
Expand Down Expand Up @@ -203,28 +114,7 @@ func HandleLeaderboard(scoreboardManager *scoreboard.ScoreboardManager) fiber.Ha
})
}

var b strings.Builder
b.WriteString("# 🏆 Leaderboard\n\n")

// Add total participants info if available
if len(leaderboard) > 0 {
b.WriteString(fmt.Sprintf("Showing top %d participants\n\n", len(leaderboard)))
}

b.WriteString("| Rank | User | Completed Tasks | Latest Submission | Latest Repository |\n")
b.WriteString("|------|------|-----------------|-------------------|------------------|\n")

for i, entry := range leaderboard {
b.WriteString(fmt.Sprintf("| %d | [%s](/user/%s) | %d | %s | %s |\n",
i+1,
entry.Username,
entry.Username,
entry.CompletedTasks,
entry.LastSubmission.Format(time.RFC850),
entry.LatestRepoName))
}

content, err := formatMarkdownToHTML(b.String())
content, err := markdown.FormatMarkdownToHTML(models.FormatLeaderboard(leaderboard))
if err != nil {
return c.Status(500).JSON(fiber.Map{
"error": "Failed to generate HTML content",
Expand Down
9 changes: 8 additions & 1 deletion internal/api/handlers/templates/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,17 @@ const htmlTemplate = `
</html>
`

var ResultTemplate *template.Template

func GetResultTemplate() *template.Template {
if ResultTemplate != nil {
return ResultTemplate
}

tmpl, err := template.New("results").Parse(htmlTemplate)
if err != nil {
panic(fmt.Sprintf("Failed to parse HTML template: %v", err))
}
return tmpl
ResultTemplate = tmpl
return ResultTemplate
}
27 changes: 2 additions & 25 deletions internal/judge/pool.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
package judge

import (
"bytes"
"fmt"
"github.com/dgraph-io/badger/v4"
appConfig "github.com/gurkengewuerz/GitCodeJudge/config"
"github.com/gurkengewuerz/GitCodeJudge/db"
"github.com/gurkengewuerz/GitCodeJudge/internal/judge/scoreboard"
"github.com/gurkengewuerz/GitCodeJudge/internal/models"
"github.com/gurkengewuerz/GitCodeJudge/internal/models/status"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"log"
"strings"
"sync"
Expand All @@ -25,28 +20,15 @@ type Pool struct {
workers chan struct{}
submissions chan models.Submission
wg sync.WaitGroup
mdParser goldmark.Markdown
scoreboardManager *scoreboard.ScoreboardManager
}

func NewPool(executor *Executor, scoreboardManager *scoreboard.ScoreboardManager, maxWorkers int) *Pool {
md := goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
html.WithXHTML(),
),
)

p := &Pool{
executor: executor,
maxWorkers: maxWorkers,
workers: make(chan struct{}, maxWorkers),
submissions: make(chan models.Submission, 1000), // Buffer for pending submissions
mdParser: md,
scoreboardManager: scoreboardManager,
}

Expand Down Expand Up @@ -95,15 +77,10 @@ func (p *Pool) worker() {
continue
}

var markdownBuf bytes.Buffer
markdown := models.FormatTestResult(result)
if err := p.mdParser.Convert([]byte(markdown), &markdownBuf); err != nil {
log.Printf("Failed to generate markdown results by %s @ %s: %v", submission.RepoName, submission.CommitID, err)
}
result.Markdown = markdownBuf.String()
result.Markdown = models.FormatTestResult(result)

err = db.DB.Update(func(txn *badger.Txn) error {
e := badger.NewEntry([]byte(submission.CommitID), markdownBuf.Bytes())
e := badger.NewEntry([]byte(submission.CommitID), []byte(result.Markdown))
if appConfig.CFG.DatabaseTTL != 0 {
e = e.WithTTL(time.Hour * time.Duration(appConfig.CFG.DatabaseTTL))
}
Expand Down
21 changes: 3 additions & 18 deletions internal/judge/scoreboard/scoreboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,12 +217,7 @@ func (sm *ScoreboardManager) GetWorkshopStats(workshop, task string) (*models.Wo
return &stats, nil
}

func (sm *ScoreboardManager) GetLeaderboard(limit int) ([]struct {
Username string
CompletedTasks int
LastSubmission time.Time
LatestRepoName string
}, error) {
func (sm *ScoreboardManager) GetLeaderboard(limit int) ([]models.Leaderboard, error) {
type userScore struct {
username string
completedTasks int
Expand Down Expand Up @@ -286,20 +281,10 @@ func (sm *ScoreboardManager) GetLeaderboard(limit int) ([]struct {
limit = len(scores)
}

result := make([]struct {
Username string
CompletedTasks int
LastSubmission time.Time
LatestRepoName string
}, limit)
result := make([]models.Leaderboard, limit)

for i := 0; i < limit; i++ {
result[i] = struct {
Username string
CompletedTasks int
LastSubmission time.Time
LatestRepoName string
}{
result[i] = models.Leaderboard{
Username: scores[i].username,
CompletedTasks: scores[i].completedTasks,
LastSubmission: scores[i].lastSubmission,
Expand Down
29 changes: 29 additions & 0 deletions internal/markdown/Markdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package markdown

import (
"bytes"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer/html"
"html/template"
)

var MD = goldmark.New(
goldmark.WithExtensions(extension.GFM),
goldmark.WithParserOptions(
parser.WithAutoHeadingID(),
),
goldmark.WithRendererOptions(
html.WithHardWraps(),
html.WithXHTML(),
),
)

func FormatMarkdownToHTML(md string) (template.HTML, error) {
var htmlBuf bytes.Buffer
if err := MD.Convert([]byte(md), &htmlBuf); err != nil {
return "", err
}
return template.HTML(htmlBuf.String()), nil
}
Loading

0 comments on commit 7e0f8a9

Please sign in to comment.