commit f018f5a676cd8a415a426d8302bc1950a9dd20b4 from: Matt Streatfield via: Oliver Lowe date: Mon Apr 21 05:04:28 2025 UTC Rename "Feeds" to Channels as that's what they are Make button link styles reuseable Add button that will link to the channel commit - 425992826e66e30d6e3cd737f117fc9f1703f820 commit + f018f5a676cd8a415a426d8302bc1950a9dd20b4 blob - 242b02fed7d0b62a37f7f060050ed7d4a8ecb14b blob + 5d314c8b567c2310869f36ded050c4d482681ab5 --- internal/db/db.go +++ internal/db/db.go @@ -17,7 +17,7 @@ func New(path string, mode os.FileMode, options *bolt. } err = db.Update(func(tx *bolt.Tx) error { - tx.CreateBucketIfNotExists(feedsBucket) + tx.CreateBucketIfNotExists(channelsBucket) return nil }) blob - /dev/null blob + e13d3e5bec8d3e544e132b865037605b3202a231 (mode 644) --- /dev/null +++ internal/db/channels.go @@ -0,0 +1,46 @@ +package db + +import ( + "encoding/json" + + "github.com/streatCodes/rss/rss" + bolt "go.etcd.io/bbolt" +) + +var channelsBucket = []byte("channels") + +func (db *DB) SaveChannel(url string, channel *rss.Channel) error { + value, err := json.Marshal(channel) + if err != nil { + return err + } + + err = db.raw.Update(func(tx *bolt.Tx) error { + bucket := tx.Bucket(channelsBucket) + if err := bucket.Put([]byte(url), value); err != nil { + return err + } + + return nil + }) + + return err +} + +func (db *DB) GetChannel(url string) (*rss.Channel, error) { + var channelBytes []byte + err := db.raw.View(func(tx *bolt.Tx) error { + if bucket := tx.Bucket(channelsBucket); bucket != nil { + channelBytes = bucket.Get([]byte(url)) + } + return nil + }) + + if err != nil { + return nil, err + } + + var channel rss.Channel + err = json.Unmarshal(channelBytes, &channel) + return &channel, err +} blob - 773e9b46e59c135b9444cd9365bd7193d0b39b57 blob + 5294b93022c95404764e9266c17bf43c83c69b4a --- internal/db/db_test.go +++ internal/db/db_test.go @@ -30,13 +30,13 @@ func TestSaveFeed(t *testing.T) { t.Error(err) } - feedKey := []byte("test") - err = db.SaveFeed(feedKey, &feed.Channel) + feedUrl := "http://example.com" + err = db.SaveChannel(feedUrl, &feed.Channel) if err != nil { t.Error(err) } - retrievedFeed, err := db.GetFeed(feedKey) + retrievedFeed, err := db.GetChannel(feedUrl) if err != nil { t.Error(err) } blob - 1a8dad7d542e277fcd1d8762b09fcbddaa378b5e (mode 644) blob + /dev/null --- internal/db/feeds.go +++ /dev/null @@ -1,46 +0,0 @@ -package db - -import ( - "encoding/json" - - "github.com/streatCodes/rss/rss" - bolt "go.etcd.io/bbolt" -) - -var feedsBucket = []byte("feeds") - -func (db *DB) SaveFeed(key []byte, feed *rss.Channel) error { - value, err := json.Marshal(feed) - if err != nil { - return err - } - - err = db.raw.Update(func(tx *bolt.Tx) error { - bucket := tx.Bucket(feedsBucket) - if err := bucket.Put(key, value); err != nil { - return err - } - - return nil - }) - - return err -} - -func (db *DB) GetFeed(key []byte) (*rss.Channel, error) { - var channelBytes []byte - err := db.raw.View(func(tx *bolt.Tx) error { - if bucket := tx.Bucket(feedsBucket); bucket != nil { - channelBytes = bucket.Get(key) - } - return nil - }) - - if err != nil { - return nil, err - } - - var channel rss.Channel - err = json.Unmarshal(channelBytes, &channel) - return &channel, err -} blob - 3a6e23323fb3edd9d1ef72cfec4be4c458b63e9e blob + fc7a36095e3546d9ad62f9fc8ff9dc680428be92 --- internal/service/search.go +++ internal/service/search.go @@ -11,7 +11,7 @@ func (service *Service) findChannel(query string) ([]r //If the search query is a URL then ingest the feed if parsedURL, err := url.ParseRequestURI(query); err == nil { //Check to see if we have the feed in the database - if channel, err := service.db.GetFeed([]byte(query)); channel != nil && err == nil { + if channel, err := service.db.GetChannel(parsedURL.String()); channel != nil && err == nil { return []rss.Channel{*channel}, nil } @@ -26,8 +26,7 @@ func (service *Service) findChannel(query string) ([]r return nil, err } - key := []byte(parsedURL.String()) - err = service.db.SaveFeed(key, &feed.Channel) + err = service.db.SaveChannel(parsedURL.String(), &feed.Channel) if err != nil { return nil, err } blob - 5f73e7d290bddfea32f754b8902b26ee2e5bae8f blob + ad391e469a4acfeefce544eb74dfd6a64c09bab2 --- internal/templates/base.tmpl +++ internal/templates/base.tmpl @@ -20,8 +20,8 @@ d="M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2zm1.5 2.5c5.523 0 10 4.477 10 10a1 1 0 1 1-2 0 8 8 0 0 0-8-8 1 1 0 0 1 0-2m0 4a6 6 0 0 1 6 6 1 1 0 1 1-2 0 4 4 0 0 0-4-4 1 1 0 0 1 0-2m.5 7a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3" /> - Sign up - Login + Sign up + Login {{ end }} blob - 19559976b5fedec3fdbb7b5a905a98abe09800a9 blob + 9d3a73da08d07995b9a751c618d6103d58855e78 --- internal/templates/results.tmpl +++ internal/templates/results.tmpl @@ -5,7 +5,10 @@
-

{{ .Title }}

+
+

{{ .Title }}

+ Episodes +
blob - f49b78523709356d5ea4991e57b1a5c47965d94c blob + 273cadda4dc38e2b12ef22db0e9ce52b16cc787d --- web/style.css +++ web/style.css @@ -36,26 +36,8 @@ a { text-decoration: none; cursor: pointer; color: var(--peach); -} -header { - padding: 1rem; - display: flex; - justify-content: end; - align-items: center; - border-bottom: solid 1px var(--gray); - - a.logo { - color: white; - line-height: 0; - margin-right: auto; - - &:focus, &:hover { - color: var(--blue); - } - } - - a.link { + &.button { background-color: white; color: var(--dark-gray); padding: .3rem .8rem; @@ -80,6 +62,25 @@ header { } } + +header { + padding: 1rem; + display: flex; + justify-content: end; + align-items: center; + border-bottom: solid 1px var(--gray); + + a.logo { + color: white; + line-height: 0; + margin-right: auto; + + &:focus, &:hover { + color: var(--blue); + } + } +} + main { flex: 1; padding: 1rem; @@ -238,6 +239,12 @@ main:has(.result)>hgroup.search-animation { hgroup { margin-bottom: 0.5rem; + .flex { + display: flex; + align-items: start; + justify-content: space-between; + } + h2 { margin-bottom: 0; }