package main import ( "context" "fmt" "net/http" "slices" "sort" "strings" "time" ) func httpServer(c console, app *appState) { c.Log("start http server") db, err := app.DB() if err != nil { c.Log("missing db", err) c.abort() return } http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write([]byte("ok")) }) http.HandleFunc("/conv/{hash}", func(w http.ResponseWriter, r *http.Request) { hash := r.PathValue("hash") if (len(hash) < 6 || len(hash) > 8) && !notAny(hash, "abcdefghijklmnopqrstuvwxyz234567") { w.WriteHeader(http.StatusBadRequest) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write([]byte(hash)) rows, err := db.QueryContext(r.Context(), "SELECT feed_id, hash, conv, dt, text FROM twt WHERE hash = $1 or conv = $1", hash) if err != nil { c.Log(err) return } defer rows.Close() for rows.Next() { var twt struct { FeedID string Hash string Conv string Dt time.Time Text string } err = rows.Scan(&twt.FeedID, &twt.Hash, &twt.Conv, &twt.Dt, &twt.Text) if err != nil { c.Log(err) return } } }) http.HandleFunc("/feeds", func(w http.ResponseWriter, r *http.Request) { lis := slices.Collect(app.queue.Iter()) sort.Slice(lis, func(i, j int) bool { return lis[i].LastScanOn.Time.Before(lis[j].LastScanOn.Time) }) for _, feed := range lis { fmt.Fprintln(w, feed.State, feed.LastScanOn.Time.Format(time.RFC3339), feed.Nick, feed.URI) } }) srv := &http.Server{ Addr: app.args.Listen, Handler: http.DefaultServeMux, } go func() { <-c.Done() c.Log("stop http server") srv.Shutdown(context.Background()) }() err = srv.ListenAndServe() if err != nil { c.Log(err) c.abort() return } } func notAny(s string, chars string) bool { for _, c := range s { if !strings.ContainsRune(chars, c) { return false } } return true }