hmn/src/website/urls.go

136 lines
3.4 KiB
Go

package website
import (
"context"
"fmt"
"strings"
"git.handmade.network/hmn/hmn/src/db"
"git.handmade.network/hmn/hmn/src/hmnurl"
"git.handmade.network/hmn/hmn/src/models"
"github.com/jackc/pgx/v4/pgxpool"
)
type categoryUrlQueryResult struct {
Cat models.Category `db:"cat"`
Project models.Project `db:"project"`
}
func GetAllCategoryUrls(ctx context.Context, conn *pgxpool.Pool) map[int]string {
it, err := db.Query(ctx, conn, categoryUrlQueryResult{},
`
SELECT $columns
FROM
handmade_category AS cat
JOIN handmade_project AS project ON project.id = cat.project_id
WHERE
cat.kind != 6
`, // TODO(asaf): Clean up the db and remove the cat.kind != 6 check
)
if err != nil {
panic(err)
}
defer it.Close()
return makeCategoryUrls(it.ToSlice())
}
func GetProjectCategoryUrls(ctx context.Context, conn *pgxpool.Pool, projectId ...int) map[int]string {
it, err := db.Query(ctx, conn, categoryUrlQueryResult{},
`
SELECT $columns
FROM
handmade_category AS cat
JOIN handmade_project AS project ON project.id = cat.project_id
WHERE
project.id = ANY ($1)
AND cat.kind != 6
`, // TODO(asaf): Clean up the db and remove the cat.kind != 6 check
projectId,
)
if err != nil {
panic(err)
}
defer it.Close()
return makeCategoryUrls(it.ToSlice())
}
func makeCategoryUrls(rows []interface{}) map[int]string {
categories := make(map[int]*models.Category)
for _, irow := range rows {
cat := irow.(*categoryUrlQueryResult).Cat
categories[cat.ID] = &cat
}
result := make(map[int]string)
for _, irow := range rows {
row := irow.(*categoryUrlQueryResult)
// get hierarchy (backwards, so current -> parent -> root)
var hierarchyReverse []*models.Category
currentCatID := row.Cat.ID
for {
cat := categories[currentCatID]
hierarchyReverse = append(hierarchyReverse, cat)
if cat.ParentID == nil {
break
} else {
currentCatID = *cat.ParentID
}
}
// reverse to get root -> parent -> current
hierarchy := make([]*models.Category, len(hierarchyReverse))
for i := len(hierarchyReverse) - 1; i >= 0; i-- {
hierarchy[len(hierarchyReverse)-1-i] = hierarchyReverse[i]
}
result[row.Cat.ID] = CategoryUrl(row.Project.Slug, hierarchy...)
}
return result
}
func CategoryUrl(projectSlug string, cats ...*models.Category) string {
catNames := make([]string, 0, len(cats))
for _, cat := range cats {
catNames = append(catNames, *cat.Name)
}
switch cats[0].Kind {
case models.CatKindForum:
return hmnurl.BuildForumCategory(projectSlug, catNames[1:], 1)
default:
return ""
}
}
func PostUrl(post models.Post, catKind models.CategoryKind, categoryUrl string) string {
categoryUrl = strings.TrimRight(categoryUrl, "/")
switch catKind {
// TODO: All the relevant post types. Maybe it doesn't make sense to lump them all together here.
case models.CatKindBlog:
return fmt.Sprintf("%s/p/%d/e/%d", categoryUrl, post.ThreadID, post.ID)
case models.CatKindForum:
return fmt.Sprintf("%s/t/%d/p/%d", categoryUrl, post.ThreadID, post.ID)
}
return ""
}
func ThreadUrl(thread models.Thread, catKind models.CategoryKind, categoryUrl string) string {
categoryUrl = strings.TrimRight(categoryUrl, "/")
switch catKind {
// TODO: All the relevant post types. Maybe it doesn't make sense to lump them all together here.
case models.CatKindBlog:
return fmt.Sprintf("%s/p/%d", categoryUrl, thread.ID)
case models.CatKindForum:
return fmt.Sprintf("%s/t/%d", categoryUrl, thread.ID)
}
return ""
}