party/cmd/party/api/parlvotes.go
2026-05-10 10:49:20 +02:00

118 lines
2.7 KiB
Go

package api
import (
"encoding/json"
"net/http"
"sort"
"time"
"party.at/party/cmd/party/parlament"
)
type apiPartyStat struct {
Code string `json:"code"`
For int `json:"for"`
Against int `json:"against"`
}
type apiParlDocument struct {
Date string `json:"date"`
Title string `json:"title"`
Number string `json:"number"`
Type string `json:"type"`
Topics []string `json:"topics"`
VotesFor []string `json:"votes_for"`
VotesAgainst []string `json:"votes_against"`
RouteID string `json:"route_id"`
}
func (api *Api) ListParlVotes(w http.ResponseWriter, r *http.Request) {
all, _, err := api.App.Parlament.ListDocuments(parlament.DocumentFilter{
Chamber: []string{"NR"},
Period: []string{parlament.CurrentPeriod},
})
if err != nil {
api.ServerErrorResponse(w, r, err)
return
}
docs := make([]apiParlDocument, 0, len(all))
for _, d := range all {
docs = append(docs, apiParlDocument{
Date: d.Date,
Title: d.Title,
Number: d.Number,
Type: d.Type,
Topics: parseStringArray(d.Topics),
VotesFor: parseStringArray(d.VotesFor),
VotesAgainst: parseStringArray(d.VotesAgainst),
RouteID: d.RouteID,
})
}
sort.Slice(docs, func(i, j int) bool {
di, _ := time.Parse("02.01.2006", docs[i].Date)
dj, _ := time.Parse("02.01.2006", docs[j].Date)
return di.After(dj)
})
forCount := make(map[string]int)
againstCount := make(map[string]int)
totalWithVotes := 0
for _, d := range docs {
if len(d.VotesFor) == 0 && len(d.VotesAgainst) == 0 {
continue
}
totalWithVotes++
for _, p := range d.VotesFor {
forCount[p]++
}
for _, p := range d.VotesAgainst {
againstCount[p]++
}
}
seen := make(map[string]bool)
for p := range forCount {
seen[p] = true
}
for p := range againstCount {
seen[p] = true
}
partyStats := make([]apiPartyStat, 0, len(seen))
for code := range seen {
partyStats = append(partyStats, apiPartyStat{
Code: code,
For: forCount[code],
Against: againstCount[code],
})
}
sort.Slice(partyStats, func(i, j int) bool {
ti := partyStats[i].For + partyStats[i].Against
tj := partyStats[j].For + partyStats[j].Against
if ti != tj {
return ti > tj
}
return partyStats[i].Code < partyStats[j].Code
})
if err := api.writeJSON(w, http.StatusOK, envelope{
"documents": docs,
"total": len(docs),
"total_with_votes": totalWithVotes,
"party_stats": partyStats,
}, nil); err != nil {
api.ServerErrorResponse(w, r, err)
}
}
func parseStringArray(s string) []string {
if s == "" {
return nil
}
var out []string
if err := json.Unmarshal([]byte(s), &out); err != nil {
return nil
}
return out
}