From ce76793510bc77e9f0fe19fa507aae83c82525ed Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Fri, 23 Feb 2024 17:46:55 +0000 Subject: [PATCH] timelines: implemented but not yet tested --- cmd/enbas/show.go | 68 +++++++++++++++++++++++++++++++++------ cmd/enbas/usage.go | 7 ++-- internal/client/client.go | 38 +++++++++++++++++++++- 3 files changed, 99 insertions(+), 14 deletions(-) diff --git a/cmd/enbas/show.go b/cmd/enbas/show.go index 4aa90d1..5a4f9ea 100644 --- a/cmd/enbas/show.go +++ b/cmd/enbas/show.go @@ -7,29 +7,34 @@ import ( "codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/config" + "codeflow.dananglin.me.uk/apollo/enbas/internal/model" ) type showCommand struct { *flag.FlagSet - myAccount bool - targetType string - account string - statusID string + myAccount bool + targetType string + account string + statusID string + timelineType string + timelineListID string + timelineTagName string + timelineLimit int } func newShowCommand(name, summary string) *showCommand { command := showCommand{ - FlagSet: flag.NewFlagSet(name, flag.ExitOnError), - myAccount: false, - targetType: "", - account: "", - statusID: "", + FlagSet: flag.NewFlagSet(name, flag.ExitOnError), } command.BoolVar(&command.myAccount, "my-account", false, "set to true to lookup your account") command.StringVar(&command.targetType, "type", "", "specify the type of resource to display") command.StringVar(&command.account, "account", "", "specify the account URI to lookup") command.StringVar(&command.statusID, "status-id", "", "specify the ID of the status to display") + command.StringVar(&command.timelineType, "timeline-type", "home", "specify the type of timeline to display (valid values are home, public, list and tag)") + command.StringVar(&command.timelineListID, "timeline-list-id", "", "specify the ID of the list timeline to display") + command.StringVar(&command.timelineTagName, "timeline-tag-name", "", "specify the name of the tag timeline to display") + command.IntVar(&command.timelineLimit, "timeline-limit", 5, "specify the number of statuses to display") command.Usage = commandUsageFunc(name, summary, command.FlagSet) return &command @@ -45,6 +50,7 @@ func (c *showCommand) Execute() error { "instance": c.showInstance, "account": c.showAccount, "status": c.showStatus, + "timeline": c.showTimeline, } doFunc, ok := funcMap[c.targetType] @@ -108,3 +114,47 @@ func (c *showCommand) showStatus(gts *client.Client) error { return nil } + +func (c *showCommand) showTimeline(gts *client.Client) error { + var ( + statuses []model.Status + err error + ) + + switch c.timelineType { + case "home": + statuses, err = gts.GetHomeTimeline(c.timelineLimit) + case "public": + statuses, err = gts.GetPublicTimeline(c.timelineLimit) + case "list": + if c.timelineListID == "" { + return errors.New("the timeline-list-id flag is not set") + } + + statuses, err = gts.GetListTimeline(c.timelineListID, c.timelineLimit) + case "tag": + if c.timelineTagName == "" { + return errors.New("the timeline-tag-name flag is not set") + } + + statuses, err = gts.GetTagTimeline(c.timelineTagName, c.timelineLimit) + default: + return fmt.Errorf("%q is not a valid type of timeline", c.timelineType) + } + + if err != nil { + return fmt.Errorf("unable to retrieve the %s timeline; %w", c.timelineType, err) + } + + if len(statuses) == 0 { + fmt.Println("There are no statuses in this timeline.") + + return nil + } + + for status := range statuses { + fmt.Println(status) + } + + return nil +} diff --git a/cmd/enbas/usage.go b/cmd/enbas/usage.go index 660139b..4536ed3 100644 --- a/cmd/enbas/usage.go +++ b/cmd/enbas/usage.go @@ -22,8 +22,7 @@ func commandUsageFunc(name, summary string, flagset *flag.FlagSet) func() { flagset.VisitAll(func(f *flag.Flag) { fmt.Fprintf( &builder, - "\n -%s, --%s\n %s", - f.Name, + "\n --%s\n %s", f.Name, f.Usage, ) @@ -63,9 +62,9 @@ func enbasUsageFunc(summaries map[string]string) func() { fmt.Fprintf(&builder, "\n %s\t%s", cmd, summaries[cmd]) } - builder.WriteString("\n\nFLAGS:\n -help, --help\n print the help message\n") + builder.WriteString("\n\nFLAGS:\n --help\n print the help message\n") flag.VisitAll(func(f *flag.Flag) { - fmt.Fprintf(&builder, "\n -%s, --%s\n %s\n", f.Name, f.Name, f.Usage) + fmt.Fprintf(&builder, "\n --%s\n %s\n", f.Name, f.Usage) }) builder.WriteString("\nUse \"enbas [command] --help\" for more information about a command.\n") diff --git a/internal/client/client.go b/internal/client/client.go index 6113653..2792c7f 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -71,7 +71,7 @@ func (g *Client) GetInstance() (model.InstanceV2, error) { } func (g *Client) GetAccount(accountURI string) (model.Account, error) { - path := "/api/v1/accounts/lookup" + "?acct=" + accountURI + path := "/api/v1/accounts/lookup?acct=" + accountURI url := g.Authentication.Instance + path var account model.Account @@ -96,6 +96,42 @@ func (g *Client) GetStatus(statusID string) (model.Status, error) { return status, nil } +func (g *Client) GetHomeTimeline(limit int) ([]model.Status, error) { + path := fmt.Sprintf("/api/v1/timelines/home?limit=%d", limit) + + return g.getTimeline(path) +} + +func (g *Client) GetPublicTimeline(limit int) ([]model.Status, error) { + path := fmt.Sprintf("/api/v1/timelines/public?limit=%d", limit) + + return g.getTimeline(path) +} + +func (g *Client) GetListTimeline(listID string, limit int) ([]model.Status, error) { + path := fmt.Sprintf("/api/v1/timelines/list/%s?limit=%d", listID, limit) + + return g.getTimeline(path) +} + +func (g *Client) GetTagTimeline(tag string, limit int) ([]model.Status, error) { + path := fmt.Sprintf("/api/v1/timelines/tag/%s?limit=%d", tag, limit) + + return g.getTimeline(path) +} + +func (g *Client) getTimeline(path string) ([]model.Status, error) { + url := g.Authentication.Instance + path + + var statuses []model.Status + + if err := g.sendRequest(http.MethodGet, url, nil, &statuses); err != nil { + return nil, fmt.Errorf("received an error after sending the request to get the timeline; %w", err) + } + + return statuses, nil +} + func (g *Client) sendRequest(method string, url string, requestBody io.Reader, object any) error { ctx, cancel := context.WithTimeout(context.Background(), g.Timeout) defer cancel()