174 lines
4.8 KiB
Go
174 lines
4.8 KiB
Go
package server
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/sirrobot01/decypharr/internal/request"
|
|
debridTypes "github.com/sirrobot01/decypharr/pkg/debrid/types"
|
|
"github.com/sirrobot01/decypharr/pkg/wire"
|
|
"net/http"
|
|
"runtime"
|
|
)
|
|
|
|
func (s *Server) handleIngests(w http.ResponseWriter, r *http.Request) {
|
|
ingests := make([]debridTypes.IngestData, 0)
|
|
_store := wire.Get()
|
|
debrids := _store.Debrid()
|
|
if debrids == nil {
|
|
http.Error(w, "Debrid service is not enabled", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
for _, cache := range debrids.Caches() {
|
|
if cache == nil {
|
|
s.logger.Error().Msg("Debrid cache is nil, skipping")
|
|
continue
|
|
}
|
|
data, err := cache.GetIngests()
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("Failed to get ingests from debrid cache")
|
|
http.Error(w, "Failed to get ingests: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
ingests = append(ingests, data...)
|
|
}
|
|
|
|
request.JSONResponse(w, ingests, 200)
|
|
}
|
|
|
|
func (s *Server) handleIngestsByDebrid(w http.ResponseWriter, r *http.Request) {
|
|
debridName := chi.URLParam(r, "debrid")
|
|
if debridName == "" {
|
|
http.Error(w, "Debrid name is required", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
_store := wire.Get()
|
|
debrids := _store.Debrid()
|
|
|
|
if debrids == nil {
|
|
http.Error(w, "Debrid service is not enabled", http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
caches := debrids.Caches()
|
|
|
|
cache, exists := caches[debridName]
|
|
if !exists {
|
|
http.Error(w, "Debrid cache not found: "+debridName, http.StatusNotFound)
|
|
return
|
|
}
|
|
|
|
data, err := cache.GetIngests()
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("Failed to get ingests from debrid cache")
|
|
http.Error(w, "Failed to get ingests: "+err.Error(), http.StatusInternalServerError)
|
|
return
|
|
}
|
|
|
|
request.JSONResponse(w, data, 200)
|
|
}
|
|
|
|
func (s *Server) handleStats(w http.ResponseWriter, r *http.Request) {
|
|
var memStats runtime.MemStats
|
|
runtime.ReadMemStats(&memStats)
|
|
|
|
stats := map[string]any{
|
|
// Memory stats
|
|
"heap_alloc_mb": fmt.Sprintf("%.2fMB", float64(memStats.HeapAlloc)/1024/1024),
|
|
"total_alloc_mb": fmt.Sprintf("%.2fMB", float64(memStats.TotalAlloc)/1024/1024),
|
|
"memory_used": fmt.Sprintf("%.2fMB", float64(memStats.Sys)/1024/1024),
|
|
|
|
// GC stats
|
|
"gc_cycles": memStats.NumGC,
|
|
// Goroutine stats
|
|
"goroutines": runtime.NumGoroutine(),
|
|
|
|
// System info
|
|
"num_cpu": runtime.NumCPU(),
|
|
|
|
// OS info
|
|
"os": runtime.GOOS,
|
|
"arch": runtime.GOARCH,
|
|
"go_version": runtime.Version(),
|
|
}
|
|
|
|
debrids := wire.Get().Debrid()
|
|
if debrids != nil {
|
|
clients := debrids.Clients()
|
|
caches := debrids.Caches()
|
|
debridStats := make([]debridTypes.Stats, 0)
|
|
for debridName, client := range clients {
|
|
debridStat := debridTypes.Stats{}
|
|
libraryStat := debridTypes.LibraryStats{}
|
|
profile, err := client.GetProfile()
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Str("debrid", debridName).Msg("Failed to get debrid profile")
|
|
profile = &debridTypes.Profile{
|
|
Name: debridName,
|
|
}
|
|
}
|
|
profile.Name = debridName
|
|
debridStat.Profile = profile
|
|
cache, ok := caches[debridName]
|
|
if ok {
|
|
// Get torrent data
|
|
libraryStat.Total = cache.TotalTorrents()
|
|
libraryStat.Bad = len(cache.GetListing("__bad__"))
|
|
libraryStat.ActiveLinks = cache.GetTotalActiveDownloadLinks()
|
|
|
|
}
|
|
debridStat.Library = libraryStat
|
|
|
|
// Get detailed account information
|
|
accounts := client.Accounts().All()
|
|
accountDetails := make([]map[string]any, 0)
|
|
for _, account := range accounts {
|
|
// Mask token - show first 8 characters and last 4 characters
|
|
maskedToken := ""
|
|
if len(account.Token) > 12 {
|
|
maskedToken = account.Token[:8] + "****" + account.Token[len(account.Token)-4:]
|
|
} else if len(account.Token) > 8 {
|
|
maskedToken = account.Token[:4] + "****" + account.Token[len(account.Token)-2:]
|
|
} else {
|
|
maskedToken = "****"
|
|
}
|
|
|
|
accountDetail := map[string]any{
|
|
"order": account.Order,
|
|
"disabled": account.Disabled,
|
|
"token_masked": maskedToken,
|
|
"username": account.Username,
|
|
"traffic_used": account.TrafficUsed,
|
|
"links_count": account.LinksCount(),
|
|
"debrid": account.Debrid,
|
|
}
|
|
accountDetails = append(accountDetails, accountDetail)
|
|
}
|
|
debridStat.Accounts = accountDetails
|
|
debridStats = append(debridStats, debridStat)
|
|
}
|
|
stats["debrids"] = debridStats
|
|
}
|
|
|
|
// Add rclone stats if available
|
|
if rcManager := wire.Get().RcloneManager(); rcManager != nil && rcManager.IsReady() {
|
|
rcStats, err := rcManager.GetStats()
|
|
if err != nil {
|
|
s.logger.Error().Err(err).Msg("Failed to get rclone stats")
|
|
stats["rclone"] = map[string]interface{}{
|
|
"enabled": true,
|
|
"server_ready": false,
|
|
}
|
|
} else {
|
|
stats["rclone"] = rcStats
|
|
}
|
|
} else {
|
|
stats["rclone"] = map[string]interface{}{
|
|
"enabled": false,
|
|
"server_ready": false,
|
|
}
|
|
}
|
|
|
|
request.JSONResponse(w, stats, http.StatusOK)
|
|
}
|