brunel/handlers/packages/packages.go

91 lines
2.2 KiB
Go
Raw Normal View History

2024-07-28 20:59:50 +02:00
package handlers_packages
import (
"brunel/domain"
"brunel/fastmap"
2024-07-29 17:39:11 +02:00
"brunel/helpers"
2024-07-28 20:59:50 +02:00
"brunel/packages"
2024-07-29 17:39:11 +02:00
"fmt"
2024-07-29 01:46:05 +02:00
"sort"
2024-07-28 20:59:50 +02:00
"strings"
"github.com/gofiber/fiber/v2"
)
2024-07-29 17:39:11 +02:00
type PackagesResponse struct {
Total int `json:"total"`
Packages *fastmap.Fastmap[string, domain.SourcePackage] `json:"packages"`
}
2024-07-28 20:59:50 +02:00
func Packages(c *fiber.Ctx) error {
2024-07-29 17:39:11 +02:00
pageNum := c.QueryInt("page", 1)
pageSize := c.QueryInt("pageSize", 250)
2024-07-29 01:46:05 +02:00
search := strings.ToLower(c.Query("search"))
2024-07-28 20:59:50 +02:00
filter := c.Query("filter")
2024-07-29 01:46:05 +02:00
2024-07-29 17:39:11 +02:00
cacheKey := fmt.Sprintf("packages:%d:%d:%s:%s", pageNum, pageSize, search, filter)
if cachedResponse, ok := helpers.Cache.Get(cacheKey); ok {
return c.Status(fiber.StatusOK).JSON(cachedResponse)
}
2024-07-29 01:46:05 +02:00
// Adjust pageNum to be 0-based for GetPage
adjustedPageNum := pageNum - 1
if adjustedPageNum < 0 {
adjustedPageNum = 0
2024-07-28 20:59:50 +02:00
}
2024-07-29 01:46:05 +02:00
2024-07-28 20:59:50 +02:00
packs := packages.GetPackages()
2024-07-29 01:46:05 +02:00
// Convert map to slice for sorting
packSlice := make([]struct {
Key string
Value domain.SourcePackage
}, 0, packs.Len())
packs.Iter(func(k string, v domain.SourcePackage) bool {
packSlice = append(packSlice, struct {
Key string
Value domain.SourcePackage
}{k, v})
return true
})
// Stable sort the slice
sort.SliceStable(packSlice, func(i, j int) bool {
return packSlice[i].Key < packSlice[j].Key
})
finalReturn := fastmap.New[string, domain.SourcePackage]()
for _, item := range packSlice {
k, source := item.Key, item.Value
matchesFilter := filter == ""
matchesSearch := search == "" || strings.Contains(strings.ToLower(k), search)
source.Packages.Iter(func(key string, value domain.PackageInfo) bool {
if !matchesFilter && value.Status == domain.PackageStatus(filter) {
matchesFilter = true
}
if !matchesSearch && strings.Contains(strings.ToLower(key), search) {
matchesSearch = true
}
return !(matchesFilter && matchesSearch) // stop iterating if we've found matches for both
2024-07-28 20:59:50 +02:00
})
2024-07-29 01:46:05 +02:00
if matchesFilter && matchesSearch {
finalReturn.Set(k, source)
2024-07-28 20:59:50 +02:00
}
}
2024-07-29 01:46:05 +02:00
result := finalReturn.GetPage(adjustedPageNum, pageSize)
2024-07-29 17:39:11 +02:00
response := PackagesResponse{
Total: finalReturn.Len(),
Packages: result,
}
helpers.Cache.Set(cacheKey, response)
return c.Status(fiber.StatusOK).JSON(response)
2024-07-28 20:59:50 +02:00
}