feat: implement feed agg and browse
This commit is contained in:
+90
-18
@@ -5,14 +5,19 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/StevanFreeborn/gator/internal/database"
|
||||
"github.com/StevanFreeborn/gator/internal/rss"
|
||||
"github.com/StevanFreeborn/gator/internal/state"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
type Command struct {
|
||||
@@ -54,6 +59,7 @@ func NewRegistry() *CommandRegistry {
|
||||
followCommand(),
|
||||
followingCommand(),
|
||||
unfollowCommand(),
|
||||
browseCommand(),
|
||||
}
|
||||
|
||||
for _, cmd := range commands {
|
||||
@@ -172,25 +178,60 @@ func usersCommand() *Command {
|
||||
|
||||
func aggCommand() *Command {
|
||||
return newCommand("agg", func(s *state.State) error {
|
||||
// if len(s.Arguments) == 0 {
|
||||
// return fmt.Errorf("Did not receive expected feed argument")
|
||||
// }
|
||||
|
||||
// feed := s.Arguments[0]
|
||||
//
|
||||
// validUrl, err := url.Parse(feed)
|
||||
//
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("Feed '%s' is not a valid url", feed)
|
||||
// }
|
||||
|
||||
rssFeed, err := rss.FetchFeed(context.Background(), "https://www.wagslane.dev/index.xml")
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
if len(s.Arguments) == 0 {
|
||||
return fmt.Errorf("Did not receive expected time between requests argument")
|
||||
}
|
||||
|
||||
fmt.Printf("%v\n", rssFeed)
|
||||
timeBetweenRequests := s.Arguments[0]
|
||||
validDuration, err := time.ParseDuration(timeBetweenRequests)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Time between requests argument '%s' not valid duration string", timeBetweenRequests)
|
||||
}
|
||||
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
defer cancel()
|
||||
|
||||
oldState, err := term.MakeRaw(int(os.Stdin.Fd()))
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to enable raw mode: %v", err)
|
||||
}
|
||||
|
||||
defer term.Restore(int(os.Stdin.Fd()), oldState)
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
ticker := time.NewTicker(validDuration)
|
||||
defer ticker.Stop()
|
||||
|
||||
rss.ScrapeNextFeed(ctx, s)
|
||||
|
||||
fetchFeeds:
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
fmt.Print("Stopping feed agg command\r\n")
|
||||
break fetchFeeds
|
||||
case <-ticker.C:
|
||||
rss.ScrapeNextFeed(ctx, s)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
@@ -321,7 +362,7 @@ func followingCommand() *Command {
|
||||
}
|
||||
|
||||
for _, follow := range follows {
|
||||
fmt.Printf("* %s", follow.FeedName)
|
||||
fmt.Printf("* %s\n", follow.FeedName)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -358,3 +399,34 @@ func unfollowCommand() *Command {
|
||||
return nil
|
||||
}))
|
||||
}
|
||||
|
||||
func browseCommand() *Command {
|
||||
return newCommand("browse", requiresLoggedInUser(func(s *state.State, currentUser database.User) error {
|
||||
limit := int32(2)
|
||||
|
||||
if len(s.Arguments) > 0 {
|
||||
parsedLimit, err := strconv.ParseInt(s.Arguments[0], 10, 32)
|
||||
|
||||
if err == nil {
|
||||
limit = int32(parsedLimit)
|
||||
}
|
||||
}
|
||||
|
||||
getUserPostsParams := database.GetPostsForUserParams{
|
||||
UserID: currentUser.ID,
|
||||
Limit: limit,
|
||||
}
|
||||
|
||||
posts, err := s.Database.GetPostsForUser(context.Background(), getUserPostsParams)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, post := range posts {
|
||||
fmt.Printf("* %s - %s\n", post.FeedName, post.Title)
|
||||
}
|
||||
|
||||
return nil
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user