diff --git a/core/channel.go b/core/channel.go index 1fc0310..61169c8 100644 --- a/core/channel.go +++ b/core/channel.go @@ -39,3 +39,29 @@ func GetSourcesInChannel(db DB) (map[string][]string, error) { } return channelSources, nil } + +func GetChannelsAndActiveCounts(db DB) (map[string]int, error) { + rows, err := db.Query(` + select c.name, count(i.id) as count + from channels c + left outer join items i on c.source = i.source and i.active = 1 + group by c.name + `) + if err != nil { + return nil, err + } + defer rows.Close() + channelCounts := make(map[string]int) + for rows.Next() { + var name string + var count int + if err := rows.Scan(&name, &count); err != nil { + return nil, err + } + channelCounts[name] = count + } + if err := rows.Err(); err != nil { + return nil, err + } + return channelCounts, nil +} diff --git a/core/channel_test.go b/core/channel_test.go index c9bc309..bcea9a1 100644 --- a/core/channel_test.go +++ b/core/channel_test.go @@ -50,9 +50,17 @@ func TestChannel(t *testing.T) { }); err != nil { t.Fatalf("failed to add items to one: %v", err) } + if counts, err := GetChannelsAndActiveCounts(db); counts["channel"] != 2 || err != nil { + t.Fatalf("expected 2 active items in channel, got %d: %v", counts["channel"], err) + } + if _, err := DeactivateItem(db, "one", "a"); err != nil { t.Fatalf("failed to deactivate item: %v", err) } + if counts, err := GetChannelsAndActiveCounts(db); counts["channel"] != 1 || err != nil { + t.Fatalf("expected 1 active items in channel, got %d: %v", counts["channel"], err) + } + items, err := GetAllItemsForChannel(db, "channel") if err != nil { t.Fatalf("failed to get all items in channel: %v", err) diff --git a/web/channel.go b/web/channel.go new file mode 100644 index 0000000..fa7a615 --- /dev/null +++ b/web/channel.go @@ -0,0 +1,30 @@ +package web + +import ( + "net/http" + + "github.com/Jaculabilis/intake/core" + "github.com/Jaculabilis/intake/web/html" +) + +func (env *Env) getChannel(writer http.ResponseWriter, req *http.Request) { + channel := req.PathValue("channel") + + var items []core.Item + var err error + inactive := req.URL.Query().Get("inactive") == "1" + if inactive { + items, err = core.GetAllItemsForChannel(env.db, channel) + } else { + items, err = core.GetActiveItemsForChannel(env.db, channel) + } + if err != nil { + http.Error(writer, err.Error(), 500) + return + } + + data := html.FeedData{ + Items: items, + } + html.Feed(writer, data) +} diff --git a/web/html/home.html b/web/html/home.html index 9fb03b8..68180ae 100644 --- a/web/html/home.html +++ b/web/html/home.html @@ -1,6 +1,25 @@ {{ define "title" }}Intake{{ end }} {{ define "content" -}} +
+
+Channels +{{ if .Channels }} +{{ range .Channels }} +

+{{ if .Active }} +{{ .Name }} ({{ .Active }}) +{{ else }} +{{ .Name }} +{{ end }} +

+{{ end }} +{{ else }} +

No channels found.

+{{ end }} +
+
+
Sources diff --git a/web/html/html.go b/web/html/html.go index c4fda1d..a39835b 100644 --- a/web/html/html.go +++ b/web/html/html.go @@ -57,12 +57,18 @@ func load(files ...string) *template.Template { var home = load("home.html") +type ChannelData struct { + Name string + Active int +} + type SourceData struct { Name string } type HomeData struct { - Sources []SourceData + Channels []ChannelData + Sources []SourceData } func Home(writer io.Writer, data HomeData) error { diff --git a/web/main.go b/web/main.go index b02a9c0..f245a27 100644 --- a/web/main.go +++ b/web/main.go @@ -31,6 +31,7 @@ func RunServer(db core.DB, addr string, port string) { handleFunc("GET /style.css", env.getStyle) handleFunc("GET /htmx.org@2.0.4.js", env.getScript) handleFunc("GET /source/{source}", env.getSource) + handleFunc("GET /channel/{channel}", env.getChannel) handleFunc("GET /item/{source}/{id}", env.getItem) handleFunc("DELETE /item/{source}/{id}", env.deleteItem) handleFunc("POST /item/{source}/{id}/action/{action}", env.doAction) diff --git a/web/root.go b/web/root.go index 487cc7c..a462a7a 100644 --- a/web/root.go +++ b/web/root.go @@ -13,17 +13,27 @@ func (env *Env) getRoot(writer http.ResponseWriter, req *http.Request) { return } - names, err := core.GetSources(env.db) + sources, err := core.GetSources(env.db) if err != nil { http.Error(writer, err.Error(), 500) } - - var sources []html.SourceData - for _, name := range names { - sources = append(sources, html.SourceData{Name: name}) + var sourceData []html.SourceData + for _, name := range sources { + sourceData = append(sourceData, html.SourceData{Name: name}) } + + channels, err := core.GetChannelsAndActiveCounts(env.db) + if err != nil { + http.Error(writer, err.Error(), 500) + } + var channelData []html.ChannelData + for name, active := range channels { + channelData = append(channelData, html.ChannelData{Name: name, Active: active}) + } + data := html.HomeData{ - Sources: sources, + Channels: channelData, + Sources: sourceData, } html.Home(writer, data) } diff --git a/web/source.go b/web/source.go index fb09106..f35e0b2 100644 --- a/web/source.go +++ b/web/source.go @@ -1,7 +1,6 @@ package web import ( - "log" "net/http" "github.com/Jaculabilis/intake/core" @@ -18,7 +17,6 @@ func (env *Env) getSource(writer http.ResponseWriter, req *http.Request) { var items []core.Item var err error inactive := req.URL.Query().Get("inactive") == "1" - log.Printf("inactive = %t", inactive) if inactive { items, err = core.GetAllItemsForSource(env.db, source) } else {