Skip to content

Commit

Permalink
api v2 poc
Browse files Browse the repository at this point in the history
  • Loading branch information
mraron committed Sep 12, 2023
1 parent fb59c21 commit 19c5ab3
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 74 deletions.
152 changes: 81 additions & 71 deletions internal/web/handlers/taskarchive/taskarchive.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package taskarchive

import (
"net/http"

"github.com/volatiletech/null/v8"
"github.com/volatiletech/sqlboiler/v4/queries/qm"
"net/http"

"github.com/mraron/njudge/internal/web/domain/problem"
"github.com/mraron/njudge/internal/web/helpers"
Expand All @@ -16,107 +17,116 @@ import (
)

type TaskArchive struct {
Roots []TreeNode
Roots []TreeNode `json:"categories"`
}

type TreeNode struct {
ID int
Type string
Name string
Link string
SolvedStatus problem.SolvedStatus
Children []TreeNode
ID int `json:"-"`
Type string `json:"type"`
Name string `json:"title"`
Link string `json:"link"`
SolvedStatus problem.SolvedStatus `json:"solvedStatus"`
Children []TreeNode `json:"children"`
}

func Get(DB *sqlx.DB, problemStore problems.Store) echo.HandlerFunc {
return func(c echo.Context) error {
tr := c.Get(i18n.TranslatorContextKey).(i18n.Translator)
func MakeTaskArchive(c echo.Context, tr i18n.Translator, DB *sqlx.DB, problemStore problems.Store, u *models.User) (*TaskArchive, error) {
lst, err := models.ProblemCategories(models.ProblemCategoryWhere.ParentID.IsNull()).All(c.Request().Context(), DB)
if err != nil {
return nil, err
}

u := c.Get("user").(*models.User)
taskArchive := &TaskArchive{Roots: make([]TreeNode, 0)}

var dfs func(category *models.ProblemCategory, node *TreeNode) error
id := 1000

lst, err := models.ProblemCategories(models.ProblemCategoryWhere.ParentID.IsNull()).All(c.Request().Context(), DB)
dfs = func(root *models.ProblemCategory, tree *TreeNode) error {
problemList, err := models.ProblemRels(models.ProblemRelWhere.CategoryID.EQ(null.Int{
Int: root.ID,
Valid: true,
}), qm.OrderBy("problem")).All(c.Request().Context(), DB)
if err != nil {
return err
}

taskArchive := TaskArchive{Roots: make([]TreeNode, 0)}

var dfs func(category *models.ProblemCategory, node *TreeNode) error
id := 1000

dfs = func(root *models.ProblemCategory, tree *TreeNode) error {
problemList, err := models.ProblemRels(models.ProblemRelWhere.CategoryID.EQ(null.Int{
Int: root.ID,
Valid: true,
}), qm.OrderBy("problem")).All(c.Request().Context(), DB)
if err != nil {
return err
for _, p := range problemList {
elem := TreeNode{
ID: id,
Type: "problem",
Name: tr.TranslateContent(problemStore.MustGet(p.Problem).Titles()).String(),
Link: c.Echo().Reverse("getProblemMain", p.Problemset, p.Problem),
Children: make([]TreeNode, 0),
SolvedStatus: -1,
}

for _, p := range problemList {
elem := TreeNode{
ID: id,
Type: "problem",
Name: tr.TranslateContent(problemStore.MustGet(p.Problem).Titles()).String(),
Link: c.Echo().Reverse("getProblemMain", p.Problemset, p.Problem),
Children: make([]TreeNode, 0),
SolvedStatus: -1,
}

if u != nil {
elem.SolvedStatus, err = helpers.HasUserSolved(DB.DB, u.ID, p.Problemset, p.Problem)
if err != nil {
return err
}
if u != nil {
elem.SolvedStatus, err = helpers.HasUserSolved(DB.DB, u.ID, p.Problemset, p.Problem)
if err != nil {
return err
}

tree.Children = append(tree.Children, elem)

id++
}

subCategories, err := models.ProblemCategories(models.ProblemCategoryWhere.ParentID.EQ(null.Int{
Int: root.ID,
Valid: true,
}), qm.OrderBy("name")).All(c.Request().Context(), DB)
tree.Children = append(tree.Children, elem)

if err != nil {
return err
}
id++
}

for _, cat := range subCategories {
tree.Children = append(tree.Children, TreeNode{
ID: cat.ID,
Type: "category",
Name: cat.Name,
Link: "",
Children: make([]TreeNode, 0),
SolvedStatus: -1,
})

if err := dfs(cat, &tree.Children[len(tree.Children)-1]); err != nil {
return err
}
}
subCategories, err := models.ProblemCategories(models.ProblemCategoryWhere.ParentID.EQ(null.Int{
Int: root.ID,
Valid: true,
}), qm.OrderBy("name")).All(c.Request().Context(), DB)

return nil
if err != nil {
return err
}

for _, start := range lst {
taskArchive.Roots = append(taskArchive.Roots, TreeNode{
ID: start.ID,
for _, cat := range subCategories {
tree.Children = append(tree.Children, TreeNode{
ID: cat.ID,
Type: "category",
Name: start.Name,
Name: cat.Name,
Link: "",
Children: make([]TreeNode, 0),
SolvedStatus: -1,
})

if dfs(start, &taskArchive.Roots[len(taskArchive.Roots)-1]) != nil {
if err := dfs(cat, &tree.Children[len(tree.Children)-1]); err != nil {
return err
}
}

return nil
}

for _, start := range lst {
taskArchive.Roots = append(taskArchive.Roots, TreeNode{
ID: start.ID,
Type: "category",
Name: start.Name,
Link: "",
Children: make([]TreeNode, 0),
SolvedStatus: -1,
})

if dfs(start, &taskArchive.Roots[len(taskArchive.Roots)-1]) != nil {
return nil, err
}
}

return taskArchive, nil
}

func Get(DB *sqlx.DB, problemStore problems.Store) echo.HandlerFunc {
return func(c echo.Context) error {
tr := c.Get(i18n.TranslatorContextKey).(i18n.Translator)

u := c.Get("user").(*models.User)

taskArchive, err := MakeTaskArchive(c, tr, DB, problemStore, u)
if err != err {
return err
}

c.Set("title", tr.Translate("Archive"))
return c.Render(http.StatusOK, "task_archive.gohtml", taskArchive)
}
Expand Down
23 changes: 20 additions & 3 deletions internal/web/routes.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package web

import (
"github.com/labstack/echo/v4/middleware"
"github.com/mraron/njudge/internal/web/helpers/i18n"
"net/http"
"strings"
"time"

"github.com/labstack/echo/v4/middleware"
"github.com/mraron/njudge/internal/web/helpers/i18n"

"github.com/labstack/echo/v4"
"github.com/mraron/njudge/internal/web/extmodels"
"github.com/mraron/njudge/internal/web/handlers"
Expand Down Expand Up @@ -85,7 +87,22 @@ func (s *Server) prepareRoutes(e *echo.Echo) {
prs.POST("/change_password/", profile.PostSettingsChangePassword(s.DB))
prs.POST("/misc/", profile.PostSettingsMisc(s.DB))

v1 := e.Group("/api/v1")
apiGroup := e.Group("/api")

v2 := apiGroup.Group("/v2")
v2.GET("/archive", func(c echo.Context) error {
tr := c.Get(i18n.TranslatorContextKey).(i18n.Translator)

u := c.Get("user").(*models.User)

ta, err := taskarchive.MakeTaskArchive(c, tr, s.DB, s.ProblemStore, u)
if err != nil {
return err
}
return c.JSON(http.StatusOK, ta)
})

v1 := apiGroup.Group("/v1")

problemRelDataProvider := api.ProblemRelDataProvider{DB: s.DB.DB}
v1.GET("/problem_rels", api.GetList[models.ProblemRel](problemRelDataProvider))
Expand Down

0 comments on commit 19c5ab3

Please sign in to comment.