diff --git a/cmd/enbas/show.go b/cmd/enbas/show.go index e4e5658..5fb63ee 100644 --- a/cmd/enbas/show.go +++ b/cmd/enbas/show.go @@ -117,27 +117,27 @@ func (c *showCommand) showStatus(gts *client.Client) error { func (c *showCommand) showTimeline(gts *client.Client) error { var ( - statuses []model.Status + timeline model.Timeline err error ) switch c.timelineType { case "home": - statuses, err = gts.GetHomeTimeline(c.timelineLimit) + timeline, err = gts.GetHomeTimeline(c.timelineLimit) case "public": - statuses, err = gts.GetPublicTimeline(c.timelineLimit) + timeline, 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) + timeline, 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) + timeline, err = gts.GetTagTimeline(c.timelineTagName, c.timelineLimit) default: return fmt.Errorf("%q is not a valid type of timeline", c.timelineType) } @@ -146,21 +146,13 @@ func (c *showCommand) showTimeline(gts *client.Client) error { return fmt.Errorf("unable to retrieve the %s timeline; %w", c.timelineType, err) } - if len(statuses) == 0 { + if len(timeline.Statuses) == 0 { fmt.Println("There are no statuses in this timeline.") return nil } - - separator := "────────────────────────────────────────────────────────────────────────" - - fmt.Println(separator) - - for _, status := range statuses { - fmt.Println(status) - fmt.Println(separator) - } + fmt.Println(timeline) return nil } diff --git a/internal/client/client.go b/internal/client/client.go index 2792c7f..94d929f 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -34,14 +34,14 @@ func NewClientFromConfig() (*Client, error) { func NewClient(authentication config.Authentication) *Client { httpClient := http.Client{} - client := Client{ + gtsClient := Client{ Authentication: authentication, HTTPClient: httpClient, UserAgent: internal.UserAgent, Timeout: 5 * time.Second, } - return &client + return >sClient } func (g *Client) VerifyCredentials() (model.Account, error) { @@ -96,40 +96,62 @@ func (g *Client) GetStatus(statusID string) (model.Status, error) { return status, nil } -func (g *Client) GetHomeTimeline(limit int) ([]model.Status, error) { +func (g *Client) GetHomeTimeline(limit int) (model.Timeline, error) { path := fmt.Sprintf("/api/v1/timelines/home?limit=%d", limit) - return g.getTimeline(path) + timeline := model.Timeline{ + Name: "HOME TIMELINE", + Statuses: nil, + } + + return g.getTimeline(path, timeline) } -func (g *Client) GetPublicTimeline(limit int) ([]model.Status, error) { +func (g *Client) GetPublicTimeline(limit int) (model.Timeline, error) { path := fmt.Sprintf("/api/v1/timelines/public?limit=%d", limit) - return g.getTimeline(path) + timeline := model.Timeline{ + Name: "PUBLIC TIMELINE", + Statuses: nil, + } + + return g.getTimeline(path, timeline) } -func (g *Client) GetListTimeline(listID string, limit int) ([]model.Status, error) { +func (g *Client) GetListTimeline(listID string, limit int) (model.Timeline, error) { path := fmt.Sprintf("/api/v1/timelines/list/%s?limit=%d", listID, limit) - return g.getTimeline(path) + timeline := model.Timeline{ + Name: "LIST: " + listID, + Statuses: nil, + } + + return g.getTimeline(path, timeline) } -func (g *Client) GetTagTimeline(tag string, limit int) ([]model.Status, error) { +func (g *Client) GetTagTimeline(tag string, limit int) (model.Timeline, error) { path := fmt.Sprintf("/api/v1/timelines/tag/%s?limit=%d", tag, limit) - return g.getTimeline(path) + timeline := model.Timeline{ + Name: "TAG: " + tag, + Statuses: nil, + } + + return g.getTimeline(path, timeline) } -func (g *Client) getTimeline(path string) ([]model.Status, error) { +func (g *Client) getTimeline(path string, timeline model.Timeline) (model.Timeline, 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 timeline, fmt.Errorf("received an error after sending the request to get the timeline; %w", err) } - return statuses, nil + timeline.Statuses = statuses + + return timeline, nil } func (g *Client) sendRequest(method string, url string, requestBody io.Reader, object any) error { diff --git a/internal/model/timeline.go b/internal/model/timeline.go new file mode 100644 index 0000000..71e2314 --- /dev/null +++ b/internal/model/timeline.go @@ -0,0 +1,29 @@ +package model + +import ( + "strings" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" +) + +type Timeline struct { + Name string + Statuses []Status +} + +func (t Timeline) String() string { + var builder strings.Builder + + separator := "────────────────────────────────────────────────────────────────────────────────" + + builder.WriteString(t.Name + "\n" + separator + "\n") + + for _, status := range t.Statuses { + builder.WriteString(status.Account.DisplayName + " (@" + status.Account.Username + ")\n\n") + builder.WriteString(utilities.WrapLine(utilities.StripHTMLTags(status.Content), "\n", 80) + "\n\n") + builder.WriteString("ID: " + status.ID + "\tCreated at: " + utilities.FormatTime(status.CreatedAt) + "\n") + builder.WriteString(separator + "\n") + } + + return builder.String() +}