diff options
| -rw-r--r-- | api/handlers/html.go | 42 | ||||
| -rw-r--r-- | api/router.go | 4 | ||||
| -rw-r--r-- | main.go | 3 | ||||
| -rw-r--r-- | pkg/database/migrations/0005_rename_read_kind.sql | 5 | ||||
| -rw-r--r-- | pkg/database/query/entries.sql | 6 | ||||
| -rw-r--r-- | pkg/database/query/kinds.sql | 2 | ||||
| -rw-r--r-- | pkg/database/sqlc/entries.sql.go | 46 | ||||
| -rw-r--r-- | pkg/database/sqlc/kinds.sql.go | 37 | ||||
| -rw-r--r-- | pkg/entries/entries.go | 30 | ||||
| -rw-r--r-- | pkg/entries/model.go | 30 | ||||
| -rw-r--r-- | pkg/html/service.go | 6 | ||||
| -rw-r--r-- | pkg/kinds/kinds.go | 34 |
12 files changed, 231 insertions, 14 deletions
diff --git a/api/handlers/html.go b/api/handlers/html.go index 88407bf..57adb12 100644 --- a/api/handlers/html.go +++ b/api/handlers/html.go @@ -5,6 +5,7 @@ import ( "git.leonardobishop.net/stash/pkg/entries" "git.leonardobishop.net/stash/pkg/html" + "git.leonardobishop.net/stash/pkg/kinds" ) const style = `<style> @@ -49,32 +50,61 @@ body { } </style>` -func GetEntriesHtml(entriesService entries.Service, htmlService html.Service) http.HandlerFunc { +func GetEntriesHtml(entriesService entries.Service, kindsService kinds.Service, htmlService html.Service) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - entries, err := entriesService.GetEntries() + var entries []entries.EntryRow + kinds, err := kindsService.GetKinds() + + kind := r.URL.Query().Get("kind") + if kind != "" { + entries, err = entriesService.GetEntriesByKind(kind) + } else { + entries, err = entriesService.GetEntries() + } if err != nil { w.WriteHeader(http.StatusInternalServerError) return } - html, err := htmlService.GenerateHtml(entries) + var html string + page, err := htmlService.GenerateHtml(entries) if err != nil { w.WriteHeader(http.StatusInternalServerError) return } if r.URL.Query().Get("css") == "no" { + html = page goto send } html = `<!DOCTYPE html> <html> <head> -<title>stash</title> +<title>Stash</title> ` + style + ` </head> -<body>` + html + `</body> -</html>` +<body>` + + // gross + html += "<p>Show: " + if kind == "" { + html += `<b>` + } + html += `<a href="/html">all</a> ` + if kind == "" { + html += `</b>` + } + for _, k := range kinds { + if kind == k.Name { + html += `<b>` + } + html += `<a href="/html?kind=` + k.Name + `">` + k.Emoji + " " + k.Name + "</a> " + if kind == k.Name { + html += `</b>` + } + } + html += "</p>" + page + "</body></html>" send: w.Header().Set("Content-Type", "text/html;charset=UTF-8") diff --git a/api/router.go b/api/router.go index 89abbc0..94ec88d 100644 --- a/api/router.go +++ b/api/router.go @@ -8,10 +8,12 @@ import ( "git.leonardobishop.net/stash/internal/config" "git.leonardobishop.net/stash/pkg/entries" "git.leonardobishop.net/stash/pkg/html" + "git.leonardobishop.net/stash/pkg/kinds" ) type ApiServices struct { EntiresService entries.Service + KindsService kinds.Service HtmlService html.Service Config *config.Config @@ -28,7 +30,7 @@ func NewServer(api ApiServices) *http.ServeMux { mux.HandleFunc("DELETE /record", cors(auth(handlers.DeleteEntry(api.EntiresService)))) mux.HandleFunc("GET /entry", cors(auth(handlers.GetEntryURLs(api.EntiresService)))) mux.HandleFunc("POST /entry", cors(auth(handlers.GetEntry(api.EntiresService)))) - mux.HandleFunc("GET /html", handlers.GetEntriesHtml(api.EntiresService, api.HtmlService)) + mux.HandleFunc("GET /html", handlers.GetEntriesHtml(api.EntiresService, api.KindsService, api.HtmlService)) mux.HandleFunc("GET /", handlers.Pong()) return mux @@ -12,6 +12,7 @@ import ( "git.leonardobishop.net/stash/pkg/database" "git.leonardobishop.net/stash/pkg/entries" "git.leonardobishop.net/stash/pkg/html" + "git.leonardobishop.net/stash/pkg/kinds" ) func main() { @@ -38,10 +39,12 @@ func run() error { } entriesService := entries.NewService(db) + kindsService := kinds.NewService(db) htmlService := html.NewService() api := api.NewServer(api.ApiServices{ EntiresService: entriesService, + KindsService: kindsService, HtmlService: htmlService, Config: c, diff --git a/pkg/database/migrations/0005_rename_read_kind.sql b/pkg/database/migrations/0005_rename_read_kind.sql new file mode 100644 index 0000000..ec8b2c0 --- /dev/null +++ b/pkg/database/migrations/0005_rename_read_kind.sql @@ -0,0 +1,5 @@ +-- +goose Up + +UPDATE kinds +SET name = "seen" +WHERE name = "read"; diff --git a/pkg/database/query/entries.sql b/pkg/database/query/entries.sql index 9584adf..37d11ce 100644 --- a/pkg/database/query/entries.sql +++ b/pkg/database/query/entries.sql @@ -20,6 +20,12 @@ SELECT title, url, description, timestamp, kinds.name as kind_name, kinds.emoji JOIN kinds ON entries.kind == kinds.id ORDER BY timestamp DESC; +-- name: GetEntriesByKind :many +SELECT title, url, description, timestamp, kinds.name as kind_name, kinds.emoji as kind_emoji FROM entries +JOIN kinds ON entries.kind == kinds.id +WHERE kinds.name = ? +ORDER BY timestamp DESC; + -- name: GetEntryURLs :many SELECT url FROM entries ORDER BY timestamp DESC; diff --git a/pkg/database/query/kinds.sql b/pkg/database/query/kinds.sql new file mode 100644 index 0000000..91917f3 --- /dev/null +++ b/pkg/database/query/kinds.sql @@ -0,0 +1,2 @@ +-- name: GetKinds :many +SELECT * FROM kinds; diff --git a/pkg/database/sqlc/entries.sql.go b/pkg/database/sqlc/entries.sql.go index 846076d..eadc25c 100644 --- a/pkg/database/sqlc/entries.sql.go +++ b/pkg/database/sqlc/entries.sql.go @@ -101,6 +101,52 @@ func (q *Queries) GetEntries(ctx context.Context) ([]GetEntriesRow, error) { return items, nil } +const getEntriesByKind = `-- name: GetEntriesByKind :many +SELECT title, url, description, timestamp, kinds.name as kind_name, kinds.emoji as kind_emoji FROM entries +JOIN kinds ON entries.kind == kinds.id +WHERE kinds.name = ? +ORDER BY timestamp DESC +` + +type GetEntriesByKindRow struct { + Title string `json:"title"` + Url string `json:"url"` + Description string `json:"description"` + Timestamp string `json:"timestamp"` + KindName string `json:"kind_name"` + KindEmoji string `json:"kind_emoji"` +} + +func (q *Queries) GetEntriesByKind(ctx context.Context, name string) ([]GetEntriesByKindRow, error) { + rows, err := q.db.QueryContext(ctx, getEntriesByKind, name) + if err != nil { + return nil, err + } + defer rows.Close() + var items []GetEntriesByKindRow + for rows.Next() { + var i GetEntriesByKindRow + if err := rows.Scan( + &i.Title, + &i.Url, + &i.Description, + &i.Timestamp, + &i.KindName, + &i.KindEmoji, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getEntryByUrl = `-- name: GetEntryByUrl :one SELECT entries.id, title, url, description, timestamp, kinds.name as kind_name, kinds.emoji as kind_emoji FROM entries JOIN kinds ON entries.kind == kinds.id diff --git a/pkg/database/sqlc/kinds.sql.go b/pkg/database/sqlc/kinds.sql.go new file mode 100644 index 0000000..a9efd90 --- /dev/null +++ b/pkg/database/sqlc/kinds.sql.go @@ -0,0 +1,37 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.29.0 +// source: kinds.sql + +package sqlc + +import ( + "context" +) + +const getKinds = `-- name: GetKinds :many +SELECT id, name, emoji FROM kinds +` + +func (q *Queries) GetKinds(ctx context.Context) ([]Kind, error) { + rows, err := q.db.QueryContext(ctx, getKinds) + if err != nil { + return nil, err + } + defer rows.Close() + var items []Kind + for rows.Next() { + var i Kind + if err := rows.Scan(&i.ID, &i.Name, &i.Emoji); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/pkg/entries/entries.go b/pkg/entries/entries.go index 92f28d9..466f340 100644 --- a/pkg/entries/entries.go +++ b/pkg/entries/entries.go @@ -13,7 +13,8 @@ type Service interface { CreateEntry(title, kind, url, description string) (*sqlc.Entry, error) UpdateEntryKind(id int64, kind string) (*sqlc.Entry, error) DeleteEntry(id int64) error - GetEntries() ([]sqlc.GetEntriesRow, error) + GetEntries() ([]EntryRow, error) + GetEntriesByKind(kind string) ([]EntryRow, error) GetEntryURLs() ([]string, error) GetEntryByUrl(url string) (*sqlc.GetEntryByUrlRow, error) } @@ -73,12 +74,33 @@ func (s *service) DeleteEntry(id int64) error { return err } -func (s *service) GetEntries() ([]sqlc.GetEntriesRow, error) { +func (s *service) GetEntries() ([]EntryRow, error) { queries := sqlc.New(s.db) - entries, err := queries.GetEntries(context.Background()) + response, err := queries.GetEntries(context.Background()) + entries := make([]EntryRow, len(response)) if err != nil { - return make([]sqlc.GetEntriesRow, 0), fmt.Errorf("could not get entries: %w", err) + return entries, fmt.Errorf("could not get entries: %w", err) + } + + for i := range response { + entries[i].ScanGetEntriesRow(response[i]) + } + + return entries, nil +} + +func (s *service) GetEntriesByKind(kind string) ([]EntryRow, error) { + queries := sqlc.New(s.db) + + response, err := queries.GetEntriesByKind(context.Background(), kind) + entries := make([]EntryRow, len(response)) + if err != nil { + return entries, fmt.Errorf("could not get entries: %w", err) + } + + for i := range response { + entries[i].ScanGetEntriesByKindRow(response[i]) } return entries, nil diff --git a/pkg/entries/model.go b/pkg/entries/model.go new file mode 100644 index 0000000..9ddcd20 --- /dev/null +++ b/pkg/entries/model.go @@ -0,0 +1,30 @@ +package entries + +import "git.leonardobishop.net/stash/pkg/database/sqlc" + +type EntryRow struct { + Title string `json:"title"` + Url string `json:"url"` + Description string `json:"description"` + Timestamp string `json:"timestamp"` + KindName string `json:"kind_name"` + KindEmoji string `json:"kind_emoji"` +} + +func (dst *EntryRow) ScanGetEntriesByKindRow(src sqlc.GetEntriesByKindRow) { + dst.Title = src.Title + dst.Url = src.Url + dst.Description = src.Description + dst.Timestamp = src.Timestamp + dst.KindName = src.KindName + dst.KindEmoji = src.KindEmoji +} + +func (dst *EntryRow) ScanGetEntriesRow(src sqlc.GetEntriesRow) { + dst.Title = src.Title + dst.Url = src.Url + dst.Description = src.Description + dst.Timestamp = src.Timestamp + dst.KindName = src.KindName + dst.KindEmoji = src.KindEmoji +} diff --git a/pkg/html/service.go b/pkg/html/service.go index e078136..bead902 100644 --- a/pkg/html/service.go +++ b/pkg/html/service.go @@ -3,11 +3,11 @@ package html import ( "time" - "git.leonardobishop.net/stash/pkg/database/sqlc" + "git.leonardobishop.net/stash/pkg/entries" ) type Service interface { - GenerateHtml([]sqlc.GetEntriesRow) (string, error) + GenerateHtml([]entries.EntryRow) (string, error) } type service struct{} @@ -16,7 +16,7 @@ func NewService() Service { return &service{} } -func (s *service) GenerateHtml(entries []sqlc.GetEntriesRow) (string, error) { +func (s *service) GenerateHtml(entries []entries.EntryRow) (string, error) { var str string var currentDate time.Time diff --git a/pkg/kinds/kinds.go b/pkg/kinds/kinds.go new file mode 100644 index 0000000..401bc7e --- /dev/null +++ b/pkg/kinds/kinds.go @@ -0,0 +1,34 @@ +package kinds + +import ( + "context" + "database/sql" + "fmt" + + "git.leonardobishop.net/stash/pkg/database/sqlc" +) + +type Service interface { + GetKinds() ([]sqlc.Kind, error) +} + +type service struct { + db *sql.DB +} + +func NewService(db *sql.DB) Service { + return &service{ + db: db, + } +} + +func (s *service) GetKinds() ([]sqlc.Kind, error) { + queries := sqlc.New(s.db) + + kinds, err := queries.GetKinds(context.Background()) + if err != nil { + return nil, fmt.Errorf("could not get kinds: %w", err) + } + + return kinds, nil +} |
