mirror of
https://github.com/lukaszraczylo/gohoarder.git
synced 2026-06-05 22:53:53 +00:00
6b037a92b4
- [x] Reorder struct fields across codebase for consistency - [x] Add analytics event handlers and tests - [x] Add authentication API key management handlers and tests - [x] Add pre-warming control handlers and tests - [x] Implement S3 storage backend with tests - [x] Implement SMB/CIFS storage backend with tests - [x] Add CDN middleware tests - [x] Integrate analytics tracking into cache manager - [x] Add S3 and SMB storage initialization in app setup - [x] Add CDN caching to proxy handlers - [x] Remove distributed locking (Redis lock manager) - [x] Remove proxy common package and utilities - [x] Remove standalone HTTP server package - [x] Remove logger middleware - [x] Simplify error handling utilities - [x] Update config with S3 and SMB options - [x] Update cache manager signature to include analytics
150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
package app
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/gofiber/fiber/v2"
|
|
"github.com/rs/zerolog/log"
|
|
)
|
|
|
|
// handleAnalyticsTopPackages returns the most downloaded packages
|
|
func (a *App) handleAnalyticsTopPackages(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
// Get limit from query params (default: 10)
|
|
limit := 10
|
|
if limitStr := c.Query("limit"); limitStr != "" {
|
|
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
packages := a.analyticsEngine.GetTopPackages(limit)
|
|
|
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
|
"packages": packages,
|
|
"total": len(packages),
|
|
})
|
|
}
|
|
|
|
// handleAnalyticsTrendingPackages returns trending packages
|
|
func (a *App) handleAnalyticsTrendingPackages(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
// Get limit from query params (default: 10)
|
|
limit := 10
|
|
if limitStr := c.Query("limit"); limitStr != "" {
|
|
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
packages := a.analyticsEngine.GetTrendingPackages(limit)
|
|
|
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
|
"packages": packages,
|
|
"total": len(packages),
|
|
})
|
|
}
|
|
|
|
// handleAnalyticsTrends returns download trends over time
|
|
func (a *App) handleAnalyticsTrends(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
trends := a.analyticsEngine.GetTrends()
|
|
|
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
|
"trends": trends,
|
|
})
|
|
}
|
|
|
|
// handleAnalyticsTotalStats returns overall statistics
|
|
func (a *App) handleAnalyticsTotalStats(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
stats := a.analyticsEngine.GetTotalStats()
|
|
|
|
return c.Status(fiber.StatusOK).JSON(stats)
|
|
}
|
|
|
|
// handleAnalyticsRegistryStats returns per-registry statistics
|
|
func (a *App) handleAnalyticsRegistryStats(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
registry := c.Params("registry")
|
|
if registry == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
|
"error": "registry parameter is required",
|
|
})
|
|
}
|
|
|
|
stats := a.analyticsEngine.GetRegistryStats(registry)
|
|
|
|
return c.Status(fiber.StatusOK).JSON(stats)
|
|
}
|
|
|
|
// handleAnalyticsPackageStats returns statistics for a specific package
|
|
func (a *App) handleAnalyticsPackageStats(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
registry := c.Params("registry")
|
|
name := c.Params("name")
|
|
|
|
if registry == "" || name == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
|
"error": "registry and name parameters are required",
|
|
})
|
|
}
|
|
|
|
stats, exists := a.analyticsEngine.GetPackageStats(registry, name)
|
|
if !exists {
|
|
return c.Status(fiber.StatusNotFound).JSON(fiber.Map{
|
|
"error": "package not found in analytics",
|
|
})
|
|
}
|
|
|
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
|
"package": stats,
|
|
})
|
|
}
|
|
|
|
// handleAnalyticsSearch searches for packages matching a query
|
|
func (a *App) handleAnalyticsSearch(c *fiber.Ctx) error {
|
|
c.Set("Content-Type", "application/json")
|
|
c.Set("Access-Control-Allow-Origin", "*")
|
|
|
|
query := c.Query("q")
|
|
if query == "" {
|
|
return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{
|
|
"error": "query parameter 'q' is required",
|
|
})
|
|
}
|
|
|
|
// Get limit from query params (default: 20)
|
|
limit := 20
|
|
if limitStr := c.Query("limit"); limitStr != "" {
|
|
if parsedLimit, err := strconv.Atoi(limitStr); err == nil && parsedLimit > 0 {
|
|
limit = parsedLimit
|
|
}
|
|
}
|
|
|
|
results := a.analyticsEngine.SearchPackages(query, limit)
|
|
|
|
log.Debug().
|
|
Str("query", query).
|
|
Int("results", len(results)).
|
|
Msg("Analytics search completed")
|
|
|
|
return c.Status(fiber.StatusOK).JSON(fiber.Map{
|
|
"results": results,
|
|
"total": len(results),
|
|
"query": query,
|
|
})
|
|
}
|