This commit is contained in:
Matthieu Lamalle 2019-11-26 09:07:19 +01:00
parent a112fa589f
commit 0deab5858d
8 changed files with 181 additions and 33 deletions

View File

@ -1,27 +1,82 @@
package bdd
import (
"bytes"
"fmt"
"log"
"time"
bolt "go.etcd.io/bbolt"
"github.com/boltdb/bolt"
)
// BDD_VOTES est le nom de la base
var BDD_VOTES = "VotesBucket"
// InitBDD initialise la BDD
func InitBDD() {
// OpenDB a key-value store.
func OpenDB() (*bolt.DB, error) {
db, err := bolt.Open("foods.db", 0600, nil)
if err != nil {
log.Fatal(err)
return nil, fmt.Errorf("could not open db, %v", err)
}
db.Update(func(tx *bolt.Tx) error {
_, err := tx.CreateBucketIfNotExists([]byte(BDD_VOTES))
err = db.Update(func(tx *bolt.Tx) error {
root, err := tx.CreateBucketIfNotExists([]byte("DB"))
if err != nil {
return fmt.Errorf("create bucket: %s", err)
return fmt.Errorf("could not create root bucket: %v", err)
}
_, err = root.CreateBucketIfNotExists([]byte("VOTES"))
if err != nil {
return fmt.Errorf("could not create votes bucket: %v", err)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("could not set up buckets, %v", err)
}
return db, nil
}
// CloseDB closes the key-value store file.
func CloseDB(db *bolt.DB) error {
return db.Close()
}
// AddVote ajoute un vote à la bdd
func AddVote(db *bolt.DB, vote string, date time.Time) error {
err := db.Update(func(tx *bolt.Tx) error {
err := tx.Bucket([]byte("DB")).Bucket([]byte("VOTES")).Put([]byte(date.Format(time.RFC3339)), []byte(vote))
if err != nil {
return fmt.Errorf("could not insert vote: %v", err)
}
return nil
})
fmt.Println("Added vote")
return err
}
// GetAllVotes liste tous les votes
func GetAllVotes(db *bolt.DB) ([]string, error) {
res := []string{}
err := db.View(func(tx *bolt.Tx) error {
b := tx.Bucket([]byte("DB")).Bucket([]byte("VOTES"))
b.ForEach(func(k, v []byte) error {
res = append(res, string(v))
return nil
})
return nil
})
return res, err
}
// GetVotesOfTheDay liste tous les votes du jour
func GetVotesOfTheDay(db *bolt.DB, date time.Time) ([]string, error) {
res := []string{}
err := db.View(func(tx *bolt.Tx) error {
c := tx.Bucket([]byte("DB")).Bucket([]byte("VOTES")).Cursor()
min := []byte(time.Now().AddDate(0, 0, -1).Format(time.RFC3339))
max := []byte(time.Now().AddDate(0, 0, 0).Format(time.RFC3339))
for k, v := c.Seek(min); k != nil && bytes.Compare(k, max) <= 0; k, v = c.Next() {
res = append(res, string(v))
}
return nil
})
return res, err
}

View File

@ -6,6 +6,7 @@ import (
"io"
"log"
"os"
"time"
)
// FoodOfTheDay is the food list of the day
@ -21,7 +22,7 @@ type Food struct {
}
// GetFoodOfTheDay return the list of food of the day
func GetFoodOfTheDay(Today string) FoodOfTheDay {
func GetFoodOfTheDay() FoodOfTheDay {
foodcsv, _ := os.Open("foodlist/foods.csv")
foodreader := csv.NewReader(bufio.NewReader(foodcsv))
foods := FoodOfTheDay{}
@ -35,7 +36,7 @@ func GetFoodOfTheDay(Today string) FoodOfTheDay {
food := Food{line[0], line[1]}
foods.Foods = append(foods.Foods, food)
}
foods.Date = Today
foods.Date = time.Now().Format("02/01/2006")
return foods
}

BIN
foods.db

Binary file not shown.

BIN
my.db

Binary file not shown.

BIN
server

Binary file not shown.

View File

@ -3,42 +3,48 @@ package main
import (
"cadoles/foodoles/bdd"
"cadoles/foodoles/foodlist"
votefood "cadoles/foodoles/vote"
"cadoles/foodoles/vote"
"html/template"
"log"
"net/http"
"time"
)
// Today is today
var Today = time.Now().Format("02/01/2006")
func main() {
http.HandleFunc("/", base)
http.HandleFunc("/results", resultsPage)
bdd.InitBDD()
log.Print("ready: listening on localhost:8080\n")
http.HandleFunc("/", Base)
http.HandleFunc("/results", ResultsPage)
db, err := bdd.OpenDB()
if err != nil {
log.Printf("\nOpenDB error: %v", err)
return
}
bdd.CloseDB(db)
vote.GetVotesOfTheDay()
log.Print("\nready: listening on localhost:8080\n")
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
func base(w http.ResponseWriter, r *http.Request) {
// Base is the entry point to all requests
func Base(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
votePage(w, r)
VotePage(w, r)
} else if r.Method == http.MethodGet {
homePage(w, r)
HomePage(w, r)
} else {
w.WriteHeader(http.StatusBadRequest)
w.Write([]byte("400 - Unsupported Request Method!"))
}
}
func homePage(w http.ResponseWriter, r *http.Request) {
foods := foodlist.GetFoodOfTheDay(Today)
// HomePage is the homepage of the app
func HomePage(w http.ResponseWriter, r *http.Request) {
foods := foodlist.GetFoodOfTheDay()
paths := []string{
"./templates/index.tmpl",
}
@ -50,23 +56,33 @@ func homePage(w http.ResponseWriter, r *http.Request) {
}
}
func resultsPage(w http.ResponseWriter, r *http.Request) {
// ResultsPage is the page displaiyng the votes results
func ResultsPage(w http.ResponseWriter, r *http.Request) {
db, err := bdd.OpenDB()
if err != nil {
log.Printf("\nOpenDB error: %v", err)
return
}
//vote, _ := bdd.GetVotesOfTheDay(db, time.Now().AddDate(0, 0, -1))
bdd.CloseDB(db)
paths := []string{
"./templates/results.tmpl",
}
t := template.Must(template.New("results.tmpl").ParseFiles(paths...))
err := t.Execute(w, "")
err = t.Execute(w, "")
if err != nil {
log.Printf("\nExecute error: %v", err)
return
}
}
func votePage(w http.ResponseWriter, r *http.Request) {
// VotePage is the endpoint to add votes
func VotePage(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
option := r.Form.Get("option")
log.Print("vote for : ", option)
votefood.ForFood(Today, option)
vote.ForFood(option)
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")

View File

@ -9,6 +9,11 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.js"></script>
</head>
<body>
{{ range .Foods }}
<div>
<div class="ui massive label"> {{ .Icon }}</div>
</div>
{{ end }}
<div class="ui container">
<h2 class="ui header">TV Show - Poll Results</h2><br/>
<div class="ui one column grid link cards">
@ -17,6 +22,7 @@
</div>
</div>
</div>
<div style="color:#fff" id="key">{{.Key}}</div>
<div style="color:#fff" id="cluster">{{.Cluster}}</div>
</body>

View File

@ -1,5 +1,12 @@
package vote
import (
"cadoles/foodoles/bdd"
"fmt"
"log"
"time"
)
// VotesOfTheDay est le résultat des votes du jour
type VotesOfTheDay struct {
Date string
@ -13,6 +20,69 @@ type Vote struct {
}
// ForFood vote pour un choix du jour
func ForFood(Today string, Food string) {
func ForFood(Food string) {
db, err := bdd.OpenDB()
if err != nil {
log.Printf("\nOpenDB error: %v", err)
return
}
bdd.AddVote(db, Food, time.Now().AddDate(0, 0, 0))
bdd.CloseDB(db)
return
}
// GetVotesOfTheDay récupère les votes du jour
func GetVotesOfTheDay() VotesOfTheDay {
time.Now()
vo := VotesOfTheDay{time.Now().Format("02/01/2006"), nil}
duplicate := FoodList()
dupmap := dupcount(duplicate)
fmt.Println(dupmap)
for k, v := range dupmap {
vv := Vote{k, v}
vo.Votes = append(vo.Votes, vv)
}
fmt.Println(vo)
return vo
}
// FoodList return a list of food
func FoodList() []Vote {
f := []Vote{}
db, err := bdd.OpenDB()
if err != nil {
log.Fatal(err)
}
lvotes, _ := bdd.GetVotesOfTheDay(db, time.Now())
for _, fo := range lvotes {
vf := Vote{fo, 1}
f = append(f, vf)
}
bdd.CloseDB(db)
return f
}
func dupcount(list []Vote) map[string]int {
duplicatefrequency := make(map[string]int)
for _, item := range list {
// check if the item/element exist in the duplicate_frequency map
_, exist := duplicatefrequency[item.Food]
if exist {
duplicatefrequency[item.Food]++ // increase counter by 1 if already in the map
} else {
duplicatefrequency[item.Food] = 1 // else start counting from 1
}
}
return duplicatefrequency
}