all repos — privychka @ 781f26ac38324da74a9fe59c0d37f603b7f8eca8

habit tracking service

main.go (view raw)

 1package main
 2
 3import (
 4	"encoding/csv"
 5	"encoding/json"
 6	"errors"
 7	"flag"
 8	"fmt"
 9	"log"
10	"net/http"
11	"os"
12	"strings"
13	"time"
14)
15
16type Habit struct {
17	Time     time.Time `json:"time"`
18	Activity string    `json:"activity"`
19	Notes    string    `json:"notes,omitempty"`
20}
21
22func (h Habit) String() string {
23	t := h.Time.Format(time.RFC1123Z)
24	return fmt.Sprintf(
25		"time: %s  activity: %s  notes:  %s",
26		t,
27		h.Activity,
28		h.Notes,
29	)
30}
31
32func (h Habit) WriteTSV(fname string) error {
33	record := []string{}
34
35	f, err := os.OpenFile(fname, os.O_APPEND|os.O_WRONLY, 0644)
36	if err != nil {
37		return err
38	}
39
40	w := csv.NewWriter(f)
41	w.Comma = '\t'
42	t := h.Time.Format(time.RFC1123)
43
44	record = append(record, t, h.Activity, h.Notes)
45	if err := w.Write(record); err != nil {
46		return err
47	}
48
49	w.Flush()
50	if err := w.Error(); err != nil {
51		return err
52	}
53
54	defer f.Close()
55
56	return nil
57}
58
59func getKey(r *http.Request) string {
60	var key string
61	header := r.Header.Get("Authorization")
62	key = strings.Split(header, " ")[1]
63	return key
64}
65
66func main() {
67	hFile := *flag.String("f", "./habits.tsv", "csv file to store habit data")
68	secretKey := *flag.String("key", "secret", "auth key to be passed as bearer token")
69	flag.Parse()
70
71	if _, err := os.Stat(hFile); errors.Is(err, os.ErrNotExist) {
72		_, err := os.Create(hFile)
73		if err != nil {
74			log.Fatalf(err.Error())
75		}
76	}
77
78	http.HandleFunc("/submit", func(w http.ResponseWriter, r *http.Request) {
79		h := Habit{}
80		key := getKey(r)
81		if secretKey != key {
82			log.Printf("incorrect key: %v\n", key)
83			w.WriteHeader(401)
84		}
85		json.NewDecoder(r.Body).Decode(&h)
86		log.Printf(h.String())
87
88		if err := h.WriteTSV(hFile); err != nil {
89			log.Printf("error: %v\n", err)
90			w.WriteHeader(500)
91		}
92		w.WriteHeader(204)
93	})
94
95	http.ListenAndServe(":8585", nil)
96}