summaryrefslogtreecommitdiff
path: root/blavote.go
blob: 48e1ae2b00921d77cd914b61109da6dd18013dc7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main

// import "blavote"
import "fmt"
import "github.com/mxk/go-sqlite/sqlite3"
import "github.com/jessevdk/go-flags"
import "os"
import "io/ioutil"
import "strings"
import "strconv"

var version string

func main() {

    version = "0.2"

    //Command line arguments
    var opts struct {
        Version bool `short:"v" long:"version" description:"Show program version"`
        Add string `short:"a" long:"add" description:"Title for a new poll"`
        New string `short:"n" long:"new" description:"Title for a new poll"`
        Username string `short:"u" long:"username" description:"Username of user adding poll"`
        Remove int `short:"r" long:"remove" description:"ID of a poll to delete"`
        Args struct {
            
            Rest []string

        }   `positional-args:"yes"`
    }

    var args []string

    //If there are no command line arguments, read them from stdin
    if (len(os.Args) > 1) {
       flags.Parse(&opts)
    } else {
        bytes, err := ioutil.ReadAll(os.Stdin)
        if (err == nil) {
            args = strings.Split(strings.Split(string(bytes),"\n")[0], " ")
            flags.ParseArgs(&opts, args)
        } else {
            fmt.Println(err)
            //No args given, deal with it
        }

    }

    db, err := connectDb("blavote.db")

    if (err != nil) {
        fmt.Print("Could not connect to vote database: ")
        fmt.Println(err)
        return
    }

    if (opts.Version) {
        fmt.Println("v" + version)
    } else if (opts.Add != "") {
        fmt.Println(opts.Args.Rest)

        pollId, err := addPoll(db, opts.Add, opts.Args.Rest, opts.Username)
        if (err == nil) {
            fmt.Print("Poll added with ID ")
            fmt.Println(pollId)
        } else {
            fmt.Println(err)
        }
    } else if (opts.New != "") {
        pollId, err := addPoll(db, opts.New, opts.Args.Rest, opts.Username)
        if (err == nil) {
            fmt.Print("Poll added with ID ")
            fmt.Println(pollId)
        } else {
            fmt.Println(err)
        }
    } else if (opts.Remove > 0) {
        deletePoll(db, opts.Remove)

        if (err == nil) {
            fmt.Print("Poll removed with ID ")
            fmt.Println(opts.Remove)
        } else {
            fmt.Println(err)
        }

    } else {
        fmt.Println(opts.Args.Rest)
        vote(db, opts.Username, opts.Args.Rest)
    }


}

func connectDb(name string) (*sqlite3.Conn, error) {
    db, err := sqlite3.Open(name)

    if (err != nil) {
        return nil, err
    }

    //Check the version in the DB, if it doesn't exist we'll create it
    //Can use this later to update the DB if needed
    sql := "select * from info where key = 'version'"
    _, err = db.Query(sql)

    if (err != nil) {
        fmt.Println("info table does not exist, creating database")
        initTables(db)
        return nil, err
    }

    return db, err
}

func initTables(db *sqlite3.Conn) {

   db.Exec("create table info(id int, key text, value text)")
   db.Exec("insert into info (key, value) values('version', '0.01')")

   db.Exec("create table users(id integer primary key autoincrement, name text, admin boolean)")
   db.Exec("create table polls(id integer primary key autoincrement, title text, user_id int)")
   db.Exec("create table options(id integer primary key autoincrement, text text, poll_id int)")
   db.Exec("create table votes(id integer primary key autoincrement, user_id int, poll_id int, option_id int)")

}

func vote(db *sqlite3.Conn, nick string, options []string) {

    if pollId, err := strconv.Atoi(options[0]); err == nil {
        option := getOptionFromText(db, options[1])
        user := getUserForName(db, nick)
        args := sqlite3.NamedArgs{"$a": user.id, "$b": pollId, "$c": option.id}
        sql := "INSERT INTO votes (user_id, poll_id, option_id) VALUES ($a, $b, $c)"

        err := db.Exec(sql, args)

        if (err != nil ) {
            fmt.Print("Failed to vote: ")
            fmt.Print(err)
        } else {
            fmt.Println("Vote added")
        }
    }
}