Files
gator/internal/command/helpers.go
T

108 lines
2.1 KiB
Go
Raw Normal View History

2026-08-04 18:00:54 -05:00
package command
import (
"context"
"fmt"
"net/url"
"os"
"strings"
"github.com/StevanFreeborn/gator/internal/database"
"github.com/StevanFreeborn/gator/internal/state"
"golang.org/x/term"
)
func normalizeFeedURL(raw string) (string, error) {
u, err := url.Parse(raw)
if err != nil {
return "", err
}
u.Scheme = strings.ToLower(u.Scheme)
u.Host = strings.ToLower(u.Host)
if (u.Scheme == "http" && u.Port() == "80") || (u.Scheme == "https" && u.Port() == "443") {
u.Host = u.Hostname()
}
if len(u.Path) > 1 {
u.Path = strings.TrimSuffix(u.Path, "/")
}
u.Fragment = ""
return u.String(), nil
}
func resolveFeedByNameOrURL(s *state.State, identifier string) (database.Feed, error) {
if strings.TrimSpace(identifier) == "" {
return database.Feed{}, fmt.Errorf("Feed identifier cannot be empty")
}
feeds, err := s.Database.GetAllFeeds(context.Background())
if err != nil {
return database.Feed{}, fmt.Errorf("Failed to load feeds")
}
var matches []database.Feed
for _, feed := range feeds {
if strings.EqualFold(feed.Name, identifier) {
matches = append(matches, feed)
}
}
if len(matches) == 1 {
return matches[0], nil
}
if len(matches) > 1 {
return database.Feed{}, fmt.Errorf("Multiple feeds match name '%s'; use a url instead", identifier)
}
normalizedURL, err := normalizeFeedURL(identifier)
if err != nil {
return database.Feed{}, fmt.Errorf("No feed found matching name or url '%s'", identifier)
}
feed, err := s.Database.GetFeedByUrl(context.Background(), normalizedURL)
if err != nil {
return database.Feed{}, fmt.Errorf("No feed found matching name or url '%s'", identifier)
}
return feed, nil
}
func enableKeypressExit(cancel context.CancelFunc) (func(), error) {
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
if err != nil {
return nil, fmt.Errorf("Failed to enable raw mode: %v", err)
}
go func() {
buf := make([]byte, 1)
for {
n, err := os.Stdin.Read(buf)
if err != nil || n == 0 {
return
}
if buf[0] == 'q' || buf[0] == 'Q' || buf[0] == 3 {
cancel()
return
}
}
}()
return func() {
term.Restore(int(os.Stdin.Fd()), oldState)
}, nil
}