118 lines
2.7 KiB
Go
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
|
|
}
|