98 lines
1.9 KiB
Go
98 lines
1.9 KiB
Go
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
|
|
}
|