Compare commits
2 Commits
d5b09db0c6
...
e7b3418932
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7b3418932 | ||
|
|
ab933e3c53 |
@@ -37,7 +37,7 @@ func newConfig(ctx context.Context) (Config, error) {
|
||||
|
||||
func newConfigFromEnv(ctx context.Context, getEnv func(string) string) (Config, error) {
|
||||
def := Config{
|
||||
Port: 8080,
|
||||
Port: 38080,
|
||||
OllamaModel: "gemma:2b",
|
||||
}
|
||||
|
||||
|
||||
58
main.go
58
main.go
@@ -64,6 +64,7 @@ func newHandler(cfg Config) http.HandlerFunc {
|
||||
mux := http.NewServeMux()
|
||||
|
||||
mux.Handle("POST /api/v1/events/slack", http.HandlerFunc(newHandlerPostAPIV1EventsSlack(cfg)))
|
||||
mux.Handle("GET /api/v1/messages", http.HandlerFunc(newHandlerGetAPIV1Messages(cfg)))
|
||||
mux.Handle("GET /api/v1/threads", http.HandlerFunc(newHandlerGetAPIV1Threads(cfg)))
|
||||
mux.Handle("GET /api/v1/threads/{thread}", http.HandlerFunc(newHandlerGetAPIV1ThreadsThread(cfg)))
|
||||
|
||||
@@ -78,19 +79,38 @@ func newHandler(cfg Config) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
func newHandlerGetAPIV1Messages(cfg Config) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if !basicAuth(cfg, w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
since, err := parseSince(r.URL.Query().Get("since"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
messages, err := cfg.storage.MessagesSince(r.Context(), since)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]any{"messages": messages})
|
||||
}
|
||||
}
|
||||
|
||||
func newHandlerGetAPIV1Threads(cfg Config) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if !basicAuth(cfg, w, r) {
|
||||
return
|
||||
}
|
||||
|
||||
since := time.Unix(0, 0)
|
||||
if sinceS := r.URL.Query().Get("since"); sinceS == "" {
|
||||
} else if n, err := strconv.ParseInt(sinceS, 10, 64); err != nil {
|
||||
since, err := parseSince(r.URL.Query().Get("since"))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
} else {
|
||||
since = time.Unix(n, 0)
|
||||
}
|
||||
|
||||
threads, err := cfg.storage.ThreadsSince(r.Context(), since)
|
||||
@@ -195,3 +215,31 @@ func _newHandlerPostAPIV1EventsSlack(cfg Config) http.HandlerFunc {
|
||||
log.Printf("ingested %v", m.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func parseSince(s string) (time.Time, error) {
|
||||
if s == "" {
|
||||
return time.Unix(0, 0), nil
|
||||
}
|
||||
|
||||
if n, err := strconv.ParseInt(s, 10, 64); err != nil {
|
||||
} else {
|
||||
return time.Unix(n, 0), nil
|
||||
}
|
||||
|
||||
if t, err := time.Parse(time.RFC3339, s); err != nil {
|
||||
} else {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
if t, err := time.Parse(time.RFC3339Nano, s); err != nil {
|
||||
} else {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
if t, err := time.ParseInLocation(time.DateOnly, s, time.Local); err != nil {
|
||||
} else {
|
||||
return t, nil
|
||||
}
|
||||
|
||||
return time.Time{}, fmt.Errorf("failed to parse since=%q", s)
|
||||
}
|
||||
|
||||
27
main_test.go
27
main_test.go
@@ -80,6 +80,29 @@ func TestRun(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("GET /api/v1/messages", func(t *testing.T) {
|
||||
resp, err := http.Get(fmt.Sprintf("%s/api/v1/messages", u))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
b, _ := io.ReadAll(resp.Body)
|
||||
t.Fatalf("(%d) %s", resp.StatusCode, b)
|
||||
}
|
||||
var result struct {
|
||||
Messages []Message
|
||||
}
|
||||
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
|
||||
t.Fatal(err)
|
||||
} else if len(result.Messages) != 1 {
|
||||
t.Fatal(result.Messages)
|
||||
} else {
|
||||
t.Logf("%+v", result)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("GET /api/v1/threads", func(t *testing.T) {
|
||||
resp, err := http.Get(fmt.Sprintf("%s/api/v1/threads", u))
|
||||
if err != nil {
|
||||
@@ -98,6 +121,8 @@ func TestRun(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
} else if result.Threads[0] != "1712911957.023359" {
|
||||
t.Fatal(result.Threads)
|
||||
} else {
|
||||
t.Logf("%+v", result)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -123,7 +148,7 @@ func TestRun(t *testing.T) {
|
||||
} else if len(result.Thread.Messages) != 1 {
|
||||
t.Fatal(result.Thread)
|
||||
} else {
|
||||
t.Logf("%+v", result.Thread.Messages[0])
|
||||
t.Logf("%+v", result)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
10
storage.go
10
storage.go
@@ -19,14 +19,18 @@ func NewStorage(driver Driver) Storage {
|
||||
return Storage{driver: driver}
|
||||
}
|
||||
|
||||
func (s Storage) MessagesSince(ctx context.Context, t time.Time) ([]Message, error) {
|
||||
return s.messagesWhere(ctx, func(m Message) bool {
|
||||
return !t.After(m.Time())
|
||||
})
|
||||
}
|
||||
|
||||
func (s Storage) Threads(ctx context.Context) ([]string, error) {
|
||||
return s.ThreadsSince(ctx, time.Unix(0, 0))
|
||||
}
|
||||
|
||||
func (s Storage) ThreadsSince(ctx context.Context, t time.Time) ([]string, error) {
|
||||
messages, err := s.messagesWhere(ctx, func(m Message) bool {
|
||||
return !t.After(m.Time())
|
||||
})
|
||||
messages, err := s.MessagesSince(ctx, t)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user