65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package app
|
|
|
|
import (
|
|
"net/http"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func handleTrafficAppMarksItems(w http.ResponseWriter, r *http.Request) {
|
|
if r.Method != http.MethodGet {
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
|
return
|
|
}
|
|
_ = pruneExpiredAppMarks()
|
|
|
|
appMarksMu.Lock()
|
|
st := loadAppMarksState()
|
|
appMarksMu.Unlock()
|
|
|
|
now := time.Now().UTC()
|
|
items := make([]TrafficAppMarkItemView, 0, len(st.Items))
|
|
for _, it := range st.Items {
|
|
rem := -1 // persistent by default
|
|
expRaw := strings.TrimSpace(it.ExpiresAt)
|
|
if expRaw != "" {
|
|
exp, err := time.Parse(time.RFC3339, expRaw)
|
|
if err == nil {
|
|
rem = int(exp.Sub(now).Seconds())
|
|
if rem < 0 {
|
|
rem = 0
|
|
}
|
|
} else {
|
|
rem = 0
|
|
}
|
|
}
|
|
items = append(items, TrafficAppMarkItemView{
|
|
ID: it.ID,
|
|
Target: it.Target,
|
|
Cgroup: it.Cgroup,
|
|
CgroupRel: it.CgroupRel,
|
|
Level: it.Level,
|
|
Unit: it.Unit,
|
|
Command: it.Command,
|
|
AppKey: it.AppKey,
|
|
AddedAt: it.AddedAt,
|
|
ExpiresAt: it.ExpiresAt,
|
|
RemainingSec: rem,
|
|
})
|
|
}
|
|
|
|
// Sort: target -> app_key -> remaining desc.
|
|
sort.Slice(items, func(i, j int) bool {
|
|
if items[i].Target != items[j].Target {
|
|
return items[i].Target < items[j].Target
|
|
}
|
|
if items[i].AppKey != items[j].AppKey {
|
|
return items[i].AppKey < items[j].AppKey
|
|
}
|
|
return items[i].RemainingSec > items[j].RemainingSec
|
|
})
|
|
|
|
writeJSON(w, http.StatusOK, TrafficAppMarksItemsResponse{Items: items, Message: "ok"})
|
|
}
|