Skip to content
Snippets Groups Projects
Commit e79d7a20 authored by Antoine Kryus's avatar Antoine Kryus
Browse files

add server functions, response and request types, utils function ranking to give ballot result

parent fc8b29fc
No related branches found
No related tags found
No related merge requests found
......@@ -11,34 +11,68 @@ import (
"log"
)
type Request struct {
Vote []comsoc.Alternative `json:"vote"` // je comprends pas le json:""
ID int `json:"id"`
Meth string
type RequestVote struct {
voteID string `json:"vote-id"`
prefs []Alternative `json:"prefs"`
agentID int `json:"agent-id"`
options []Alternative `json:"options"`
}
type Response struct {
Result int `json:"res"`
type RequestNewBallot struct {
rule string `json:"rule"`
deadline string `json:"deadline"`
voterIDs []string `json:"voter-ids"`
alts int `json:"#alts"`
}
type RequestResult struct {
ballotID string `json:"ballot-id"`
}
type ResponseNewBallot struct {
ballotID string `json:"ballot-id"`
// code int
}
// type ResponseVote struct {
// code int
// }
type ResponseResult struct {
winner int `json:"winner"`
ranking []Alternative `json:"ranking"`
// code int
}
type BallotID int
type RestBallotAgent struct {
sync.Mutex
ID BallotID
addr string
pfl comsoc.Profile
addr string // the only non-varying value in one
// server instance, the rest is change
// every RequestNewBallot
pfl Profile
rule string
isOpen bool // open: 1 / closed: 0
voterIDs []string
alts []Alternative
}
type Alternative comsoc.Alternative
type Profile comsoc.Profile
type RestBallotI interface {
checkMethod(method string, w http.ResponseWriter, r *http.Request) bool
decodeRequest(r *http.Request) (req Request, err error)
decodeRequestNewBallot(r *http.Request) (req RequestNewBallot, err error)
decodeRequestVote(r *http.Request) (req RequestVote, err error)
decodeRequestResult(r *http.Request) (req RequestResult, err error)
} // je ne sais pas trop comment utiliser l'interface je te laisse si tu préfères
func NewRestBallotAgent(addr string, emptyProfile comsoc.Profile) *RestBallotAgent {
return &RestBallotAgent{ID: BallotID(1), addr: addr, pfl: emptyProfile}
func NewRestBallotAgent(addr string, emptyProfile Profile) *RestBallotAgent {
return &RestBallotAgent{ID: BallotID(0), addr: addr, isOpen: true}
}
// Test de la méthode
......@@ -51,14 +85,29 @@ func (rsa *RestBallotAgent) checkMethod(method string, w http.ResponseWriter, r
return true
}
func (*RestBallotAgent) decodeRequest(r *http.Request) (req Request, err error) {
func (*RestBallotAgent) decodeRequestNewBallot(r *http.Request) (req RequestNewBallot, err error) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
err = json.Unmarshal(buf.Bytes(), &req)
return
}
func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
func (*RestBallotAgent) decodeRequestVote(r *http.Request) (req RequestVote, err error) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
err = json.Unmarshal(buf.Bytes(), &req)
return
}
func (*RestBallotAgent) decodeRequestResult(r *http.Request) (req RequestResult, err error) {
buf := new(bytes.Buffer)
buf.ReadFrom(r.Body)
err = json.Unmarshal(buf.Bytes(), &req)
return
}
func (rba *RestBallotAgent) doNewBallot(w http.ResponseWriter, r *http.Request) {
// mise à jour du nombre de requêtes
rba.Lock()
defer rba.Unlock()
......@@ -70,7 +119,7 @@ func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
}
// décodage de la requête
req, err := rba.decodeRequest(r)
req, err := rba.decodeRequestNewBallot(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err.Error())
......@@ -78,23 +127,44 @@ func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
}
// traitement de la requête
var resp Response
var resp ResponseNewBallot
rba.pfl = append(rba.pfl, req.Vote) // req should have vote (list of int) and ID (int)
if rba.ID != 0 { // zero Value
rba.ID = rba.ID + 1
} else {
rba.ID = 1
}
if comsoc.CheckProfileAlternative(rba.pfl, req.Vote) != nil {
rba.rule = req.rule
rba.voterIDs = req.voterIDs
for i := 1; i<=req.alts; i++ {
rba.alts[i] = Alternative(i)
}
deadline, err := time.Parse("Mon Jan _2 15:04:05 MST 2006", req.deadline)
if err != nil {
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("Vote of voter '%s' is not correct", req.ID)
msg := fmt.Sprintf("Deadline \"'%s'\" is not in a correct format", req.deadline)
r.Write([]byte(msg))
return
}
time.AfterFunc(time.Until(deadline), closeVote(rba))
// treat deadline
w.WriteHeader(http.StatusOK)
serial, _ := json.Marshal(resp)
w.Write(serial)
}
func (rba *RestBallotAgent) doClose_vote(w http.ResponseWriter, r *http.Request) {
func (rba *RestBallotAgent) doVote(w http.ResponseWriter, r *http.Request) {
// mise à jour du nombre de requêtes
rba.Lock()
defer rba.Unlock()
......@@ -106,7 +176,7 @@ func (rba *RestBallotAgent) doClose_vote(w http.ResponseWriter, r *http.Request)
}
// décodage de la requête
req, err := rba.decodeRequest(r)
req, err := rba.decodeRequestVote(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err.Error())
......@@ -114,25 +184,67 @@ func (rba *RestBallotAgent) doClose_vote(w http.ResponseWriter, r *http.Request)
}
// traitement de la requête
var resp Response
switch rba.Meth {
rba.pfl = append(rba.pfl, req.prefs) // wtf the error
if comsoc.CheckProfileAlternative(rba.pfl, req.Vote) != nil {
w.WriteHeader(http.StatusNotImplemented)
msg := fmt.Sprintf("Vote of voter '%s' is not correct", req.ID)
r.Write([]byte(msg))
return
}
switch rba.rule {
case "borda":
//call borda SCF and SWF and store results
}
// another way to do this would be to call method directly from router (mux)
// code here
w.WriteHeader(http.StatusOK)
// serial, _ := json.Marshal(resp)
// w.Write(serial)
}
func (rba *RestBallotAgent) doResult(w http.ResponseWriter, r *http.Request) {
// mise à jour du nombre de requêtes
rba.Lock()
defer rba.Unlock()
// rba.reqCount++
// vérification de la méthode de la requête
if !rba.checkMethod("POST", w, r) {
return
}
// décodage de la requête
req, err := rba.decodeRequestResult(r)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprint(w, err.Error())
return
}
// traitement de la requête
var resp ResponseResult
// code here
w.WriteHeader(http.StatusOK)
serial, _ := json.Marshal(resp)
w.Write(serial)
}
func closeVote (rba *RestBallotAgent) {
rba.status = 0
}
func (rba *RestBallotAgent) Start() {
// création du routeur
mux := http.NewServeMux()
mux.HandleFunc("/new_ballot")
mux.HandleFunc("/vote")
mux.HandleFunc("/close_vote")
mux.HandleFunc("/get_results")
mux.HandleFunc("/result")
// création du serveur http
s := &http.Server{
......
......@@ -38,6 +38,15 @@ func maxCount(count Count) (bestAlts []Alternative) {
return
}
func ranking(count Count) (ranking []Alternative) {
for len(count) > 0 {
best := maxCount(count)[0] // comment gérer le tie break
ranking = append(ranking, )
delete(count, best)
}
return
}
// vérifie le profil donné, par ex. qu'ils sont tous complets et que chaque alternative n'apparaît qu'une seule fois par préférences
// func checkProfile(prefs Profile) error
......
......@@ -2,6 +2,4 @@ module ia04
go 1.19
require (
gitlab.utc.fr/lagruesy/ia04 v0.2.0
)
require gitlab.utc.fr/lagruesy/ia04 v0.2.0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment