plumbed through child add/delete subcommands
This commit is contained in:
parent
8e5f559567
commit
5957437ded
43
children/db.go
Normal file
43
children/db.go
Normal file
@ -0,0 +1,43 @@
|
||||
package children
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"mcquay.me/fs"
|
||||
)
|
||||
|
||||
var mut sync.Mutex
|
||||
|
||||
type DB map[string]int
|
||||
|
||||
func Load(filename string) (children DB, err error) {
|
||||
db := DB{}
|
||||
if !fs.Exists(filename) {
|
||||
return db, errors.New("db file doesn't exist")
|
||||
}
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := json.NewDecoder(f).Decode(&db); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func (db DB) Save(filename string) error {
|
||||
mut.Lock()
|
||||
defer mut.Unlock()
|
||||
f, err := os.Create(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
if err := json.NewEncoder(f).Encode(db); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
@ -10,12 +9,14 @@ import (
|
||||
"github.com/bgentry/speakeasy"
|
||||
|
||||
"mcquay.me/allowances"
|
||||
"mcquay.me/allowances/children"
|
||||
)
|
||||
|
||||
const usage = `allowances app
|
||||
|
||||
subcommands:
|
||||
pw -- manage password file
|
||||
child -- manage children
|
||||
serve -- serve webapp
|
||||
`
|
||||
|
||||
@ -26,6 +27,13 @@ subcommands:
|
||||
test <passes.json>
|
||||
`
|
||||
|
||||
const childUsage = `allowances child
|
||||
|
||||
subcommands:
|
||||
add <children.json> <child name> <child name> ...
|
||||
delete <children.json> <child name> <child name> ...
|
||||
`
|
||||
|
||||
func main() {
|
||||
if len(os.Args) < 2 {
|
||||
fmt.Fprintf(os.Stderr, usage)
|
||||
@ -74,6 +82,41 @@ func main() {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", pwUsage)
|
||||
os.Exit(1)
|
||||
}
|
||||
case "child":
|
||||
childCmd := os.Args[2:]
|
||||
if len(childCmd) < 3 {
|
||||
fmt.Fprintf(os.Stderr, "%s\n", childUsage)
|
||||
os.Exit(1)
|
||||
}
|
||||
switch childCmd[0] {
|
||||
case "add":
|
||||
dbfile := os.Args[3]
|
||||
names := os.Args[4:]
|
||||
db, err := children.Load(dbfile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "problem loading children db: %s\n", pwUsage)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, name := range names {
|
||||
db[name] = 0
|
||||
}
|
||||
db.Save(dbfile)
|
||||
case "delete", "del":
|
||||
dbfile := os.Args[3]
|
||||
names := os.Args[4:]
|
||||
db, err := children.Load(dbfile)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "problem loading children db: %s\n", pwUsage)
|
||||
os.Exit(1)
|
||||
}
|
||||
for _, name := range names {
|
||||
delete(db, name)
|
||||
}
|
||||
db.Save(dbfile)
|
||||
default:
|
||||
fmt.Fprintf(os.Stderr, "%s\n", pwUsage)
|
||||
os.Exit(1)
|
||||
}
|
||||
case "serve":
|
||||
sm := http.NewServeMux()
|
||||
dbfile := os.Getenv("DB")
|
||||
@ -93,7 +136,6 @@ func main() {
|
||||
port = p
|
||||
}
|
||||
addr := fmt.Sprintf(":%d", port)
|
||||
log.Printf("%+v", addr)
|
||||
err = http.ListenAndServe(addr, sm)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
35
db.go
35
db.go
@ -2,18 +2,20 @@ package allowances
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
|
||||
"mcquay.me/fs"
|
||||
)
|
||||
|
||||
var dbMutex sync.RWMutex
|
||||
|
||||
func GetHashes(filename string) (Passes, bool, error) {
|
||||
r := []string{}
|
||||
exists := false
|
||||
if !Exists(filename) {
|
||||
if !fs.Exists(filename) {
|
||||
return r, exists, nil
|
||||
}
|
||||
exists = true
|
||||
@ -59,30 +61,3 @@ func (p Passes) Check(attempt string) (bool, error) {
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
var dbMutex = sync.RWMutex{}
|
||||
|
||||
func loadChildren(filename string) (children map[string]int) {
|
||||
dbMutex.RLock()
|
||||
defer dbMutex.RUnlock()
|
||||
b, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = json.Unmarshal(b, &children)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func dumpChildren(filename string, children map[string]int) {
|
||||
dbMutex.Lock()
|
||||
defer dbMutex.Unlock()
|
||||
b, err := json.Marshal(children)
|
||||
err = ioutil.WriteFile(filename, b, 0644)
|
||||
if err != nil {
|
||||
log.Fatal("serious issue writing children db file", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
12
fs.go
12
fs.go
@ -1,12 +0,0 @@
|
||||
package allowances
|
||||
|
||||
import "os"
|
||||
|
||||
func Exists(path string) bool {
|
||||
if _, err := os.Stat(path); err != nil {
|
||||
return false
|
||||
} else if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
24
handlers.go
24
handlers.go
@ -9,6 +9,8 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/sessions"
|
||||
"mcquay.me/allowances/children"
|
||||
"mcquay.me/fs"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -28,7 +30,8 @@ func NewFailure(msg string) *failure {
|
||||
}
|
||||
|
||||
type Allowances struct {
|
||||
db string
|
||||
db children.DB
|
||||
dbfile string
|
||||
hashes Passes
|
||||
store *sessions.CookieStore
|
||||
}
|
||||
@ -47,11 +50,16 @@ func NewAllowances(sm *http.ServeMux, dbfile, passfile, staticFiles string) (*Al
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !Exists(dbfile) {
|
||||
if !fs.Exists(dbfile) {
|
||||
return nil, fmt.Errorf("child db file doesn't exist: %q", dbfile)
|
||||
}
|
||||
db, err := children.Load(dbfile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
r := &Allowances{
|
||||
db: dbfile,
|
||||
db: db,
|
||||
dbfile: dbfile,
|
||||
hashes: hashes,
|
||||
store: sessions.NewCookieStore([]byte("hello world")),
|
||||
}
|
||||
@ -60,8 +68,7 @@ func NewAllowances(sm *http.ServeMux, dbfile, passfile, staticFiles string) (*Al
|
||||
}
|
||||
|
||||
func (a *Allowances) home(w http.ResponseWriter, req *http.Request, uid string) error {
|
||||
children := loadChildren(a.db)
|
||||
tmpls["home"].Execute(w, map[string]interface{}{"children": children})
|
||||
tmpls["home"].Execute(w, map[string]interface{}{"children": a.db})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -102,12 +109,11 @@ func (a *Allowances) add(w http.ResponseWriter, req *http.Request, uid string) e
|
||||
if err != nil {
|
||||
return fmt.Errorf("couldn't parse a dollar amount: %v", err)
|
||||
}
|
||||
children := loadChildren(a.db)
|
||||
children[child] += amount
|
||||
defer dumpChildren(a.db, children)
|
||||
a.db[child] += amount
|
||||
a.db.Save(a.dbfile)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
b, err := json.Marshal(map[string]interface{}{
|
||||
"amount": dollarize(children[child]),
|
||||
"amount": dollarize(a.db[child]),
|
||||
"name": child,
|
||||
})
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user