package main import ( "bufio" "fmt" "log" "os" "strings" "time" "gopkg.in/yaml.v2" ) type ( DB interface { HistoryOf(string) map[string][]History Next(string, string) time.Time Question(string) Question LastAnswer(string, string) (string, Answer) Answer(string) Answer PushAnswer(string, string, string, bool) error Close() } Question struct { Q string Clues []string Tags []string } Answer struct { Q string A string TS int64 Author string } History struct { A string TS int64 Pass bool } ) func main() { if err := Main(); err != nil { panic(err) } } func Main() error { db, err := NewDB() if err != nil { return err } defer db.Close() user := os.Getenv("USER") for q, _ := range db.HistoryOf(user) { if time.Until(db.Next(user, q)) > 0 { continue } question := db.Question(q) fmt.Printf("> Q: ") if strings.HasPrefix(question.Q, "img:") { } else { fmt.Printf("%s", question.Q) } fmt.Printf("\n") fmt.Printf("> %+v\n", question.Tags) var response string for i := range question.Clues { if i == 0 { fmt.Printf("> /clue for a clue\n") } response = readline() if response != "/clue" { break } fmt.Printf("> %s", question.Clues[i]) if i+1 < len(question.Clues) { fmt.Printf(" | /clue for another clue") } fmt.Printf("\n") } if len(question.Clues) == 0 || response == "/clue" { response = readline() } if id, _ := db.LastAnswer(user, q); id == "" { } else if lastAnswer := db.Answer(id); lastAnswer.A != "" { fmt.Printf("> Last time, you responded:\n\t%s\n", lastAnswer.A) } fmt.Printf("> Did you pass this time? [Yns]\n") switch readline() { case "s": case "n": if err := db.PushAnswer(user, q, response, false); err != nil { return err } default: if err := db.PushAnswer(user, q, response, true); err != nil { return err } } fmt.Println() } if b, _ := yaml.Marshal(db); len(b) > 0 { log.Printf("%s\n", b) } return nil } func readline() string { fmt.Printf("\t") reader := bufio.NewReader(os.Stdin) text, _ := reader.ReadString('\n') return strings.TrimSpace(text) } func NewDB() (DB, error) { return newYamlDB(os.Getenv("DB")) } func (q Question) Tagged(tag string) bool { for i := range q.Tags { if q.Tags[i] == tag { return true } } return false }