checkpoint: begin adding NO_COLOR support

This commit is contained in:
Dan Anglin 2024-05-31 09:25:31 +01:00
parent 88d6a8d498
commit 29d6ca600f
Signed by: dananglin
GPG key ID: 0C1D44CFBEE68638
11 changed files with 104 additions and 79 deletions

View file

@ -60,6 +60,7 @@ func run() error {
topLevelFlags := executor.TopLevelFlags{} topLevelFlags := executor.TopLevelFlags{}
flag.StringVar(&topLevelFlags.ConfigDir, "config-dir", "", "specify your config directory") flag.StringVar(&topLevelFlags.ConfigDir, "config-dir", "", "specify your config directory")
flag.BoolVar(&topLevelFlags.NoColor, "no-color", false, "disable ANSI colours when displaying text on screen")
flag.Usage = usageFunc(commandSummaries) flag.Usage = usageFunc(commandSummaries)

View file

@ -18,4 +18,5 @@ func (a *AccountNames) Set(value string) error {
type TopLevelFlags struct { type TopLevelFlags struct {
ConfigDir string ConfigDir string
NoColor bool
} }

View file

@ -116,7 +116,7 @@ func (c *ShowExecutor) showAccount(gtsClient *client.Client) error {
return nil return nil
} }
fmt.Println(account) utilities.Display(account, c.topLevelFlags.NoColor)
if !c.myAccount && !c.skipAccountRelationship { if !c.myAccount && !c.skipAccountRelationship {
relationship, err := gtsClient.GetAccountRelationship(account.ID) relationship, err := gtsClient.GetAccountRelationship(account.ID)
@ -124,7 +124,7 @@ func (c *ShowExecutor) showAccount(gtsClient *client.Client) error {
return fmt.Errorf("unable to retrieve the relationship to this account; %w", err) return fmt.Errorf("unable to retrieve the relationship to this account; %w", err)
} }
fmt.Println(relationship) utilities.Display(relationship, c.topLevelFlags.NoColor)
} }
if c.myAccount && c.showUserPreferences { if c.myAccount && c.showUserPreferences {
@ -133,7 +133,7 @@ func (c *ShowExecutor) showAccount(gtsClient *client.Client) error {
return fmt.Errorf("unable to retrieve the user preferences; %w", err) return fmt.Errorf("unable to retrieve the user preferences; %w", err)
} }
fmt.Println(preferences) utilities.Display(preferences, c.topLevelFlags.NoColor)
} }
return nil return nil
@ -197,7 +197,7 @@ func (c *ShowExecutor) showTimeline(gtsClient *client.Client) error {
return nil return nil
} }
fmt.Println(timeline) utilities.Display(timeline, c.topLevelFlags.NoColor)
return nil return nil
} }
@ -226,7 +226,7 @@ func (c *ShowExecutor) showList(gtsClient *client.Client) error {
list.Accounts = accountMap list.Accounts = accountMap
} }
fmt.Println(list) utilities.Display(list, c.topLevelFlags.NoColor)
return nil return nil
} }
@ -243,7 +243,7 @@ func (c *ShowExecutor) showLists(gtsClient *client.Client) error {
return nil return nil
} }
fmt.Println(utilities.HeaderFormat("LISTS")) fmt.Println(utilities.HeaderFormat(true, "LISTS"))
fmt.Println(lists) fmt.Println(lists)
return nil return nil
@ -261,7 +261,7 @@ func (c *ShowExecutor) showFollowers(gtsClient *client.Client) error {
} }
if len(followers.Accounts) > 0 { if len(followers.Accounts) > 0 {
fmt.Println(followers) utilities.Display(followers, c.topLevelFlags.NoColor)
} else { } else {
fmt.Println("There are no followers for this account or the list is hidden.") fmt.Println("There are no followers for this account or the list is hidden.")
} }
@ -281,7 +281,7 @@ func (c *ShowExecutor) showFollowing(gtsClient *client.Client) error {
} }
if len(following.Accounts) > 0 { if len(following.Accounts) > 0 {
fmt.Println(following) utilities.Display(following, c.topLevelFlags.NoColor)
} else { } else {
fmt.Println("This account is not following anyone or the list is hidden.") fmt.Println("This account is not following anyone or the list is hidden.")
} }
@ -296,7 +296,7 @@ func (c *ShowExecutor) showBlocked(gtsClient *client.Client) error {
} }
if len(blocked.Accounts) > 0 { if len(blocked.Accounts) > 0 {
fmt.Println(blocked) utilities.Display(blocked, c.topLevelFlags.NoColor)
} else { } else {
fmt.Println("You have no blocked accounts.") fmt.Println("You have no blocked accounts.")
} }

View file

@ -59,7 +59,7 @@ type Field struct {
VerifiedAt string `json:"verified_at"` VerifiedAt string `json:"verified_at"`
} }
func (a Account) String() string { func (a Account) Display(noColor bool) string {
format := ` format := `
%s (@%s) %s (@%s)
@ -87,28 +87,28 @@ func (a Account) String() string {
for _, field := range a.Fields { for _, field := range a.Fields {
metadata += fmt.Sprintf( metadata += fmt.Sprintf(
"\n %s: %s", "\n %s: %s",
utilities.FieldFormat(field.Name), utilities.FieldFormat(noColor, field.Name),
utilities.StripHTMLTags(field.Value), utilities.StripHTMLTags(field.Value),
) )
} }
return fmt.Sprintf( return fmt.Sprintf(
format, format,
utilities.DisplayNameFormat(a.DisplayName), utilities.DisplayNameFormat(noColor, a.DisplayName),
a.Username, a.Username,
utilities.HeaderFormat("ACCOUNT ID:"), utilities.HeaderFormat(noColor, "ACCOUNT ID:"),
a.ID, a.ID,
utilities.HeaderFormat("JOINED ON:"), utilities.HeaderFormat(noColor, "JOINED ON:"),
utilities.FormatDate(a.CreatedAt), utilities.FormatDate(a.CreatedAt),
utilities.HeaderFormat("STATS:"), utilities.HeaderFormat(noColor, "STATS:"),
utilities.FieldFormat("Followers:"), a.FollowersCount, utilities.FieldFormat(noColor, "Followers:"), a.FollowersCount,
utilities.FieldFormat("Following:"), a.FollowingCount, utilities.FieldFormat(noColor, "Following:"), a.FollowingCount,
utilities.FieldFormat("Statuses:"), a.StatusCount, utilities.FieldFormat(noColor, "Statuses:"), a.StatusCount,
utilities.HeaderFormat("BIOGRAPHY:"), utilities.HeaderFormat(noColor, "BIOGRAPHY:"),
utilities.WrapLines(utilities.StripHTMLTags(a.Note), "\n ", 80), utilities.WrapLines(utilities.StripHTMLTags(a.Note), "\n ", 80),
utilities.HeaderFormat("METADATA:"), utilities.HeaderFormat(noColor, "METADATA:"),
metadata, metadata,
utilities.HeaderFormat("ACCOUNT URL:"), utilities.HeaderFormat(noColor, "ACCOUNT URL:"),
a.URL, a.URL,
) )
} }
@ -130,7 +130,7 @@ type AccountRelationship struct {
ShowingReblogs bool `json:"showing_reblogs"` ShowingReblogs bool `json:"showing_reblogs"`
} }
func (a AccountRelationship) String() string { func (a AccountRelationship) Display(noColor bool) string {
format := ` format := `
%s %s
%s: %t %s: %t
@ -151,25 +151,25 @@ func (a AccountRelationship) String() string {
output := fmt.Sprintf( output := fmt.Sprintf(
format, format,
utilities.HeaderFormat("YOUR RELATIONSHIP WITH THIS ACCOUNT:"), utilities.HeaderFormat(noColor, "YOUR RELATIONSHIP WITH THIS ACCOUNT:"),
utilities.FieldFormat("Following"), a.Following, utilities.FieldFormat(noColor, "Following"), a.Following,
utilities.FieldFormat("Is following you"), a.FollowedBy, utilities.FieldFormat(noColor, "Is following you"), a.FollowedBy,
utilities.FieldFormat("A follow request was sent and is pending"), a.FollowRequested, utilities.FieldFormat(noColor, "A follow request was sent and is pending"), a.FollowRequested,
utilities.FieldFormat("Received a pending follow request"), a.FollowRequestedBy, utilities.FieldFormat(noColor, "Received a pending follow request"), a.FollowRequestedBy,
utilities.FieldFormat("Endorsed"), a.Endorsed, utilities.FieldFormat(noColor, "Endorsed"), a.Endorsed,
utilities.FieldFormat("Showing Reposts (boosts)"), a.ShowingReblogs, utilities.FieldFormat(noColor, "Showing Reposts (boosts)"), a.ShowingReblogs,
utilities.FieldFormat("Muted"), a.Muting, utilities.FieldFormat(noColor, "Muted"), a.Muting,
utilities.FieldFormat("Notifications muted"), a.MutingNotifications, utilities.FieldFormat(noColor, "Notifications muted"), a.MutingNotifications,
utilities.FieldFormat("Blocking"), a.Blocking, utilities.FieldFormat(noColor, "Blocking"), a.Blocking,
utilities.FieldFormat("Is blocking you"), a.BlockedBy, utilities.FieldFormat(noColor, "Is blocking you"), a.BlockedBy,
utilities.FieldFormat("Blocking account's domain"), a.DomainBlocking, utilities.FieldFormat(noColor, "Blocking account's domain"), a.DomainBlocking,
) )
if a.PrivateNote != "" { if a.PrivateNote != "" {
output += "\n" output += "\n"
output += fmt.Sprintf( output += fmt.Sprintf(
privateNoteFormat, privateNoteFormat,
utilities.HeaderFormat("YOUR PRIVATE NOTE ABOUT THIS ACCOUNT:"), utilities.HeaderFormat(noColor, "YOUR PRIVATE NOTE ABOUT THIS ACCOUNT:"),
utilities.WrapLines(a.PrivateNote, "\n ", 80), utilities.WrapLines(a.PrivateNote, "\n ", 80),
) )
} }
@ -190,18 +190,18 @@ type AccountList struct {
Accounts []Account Accounts []Account
} }
func (a AccountList) String() string { func (a AccountList) Display(noColor bool) string {
output := "\n" output := "\n"
switch a.Type { switch a.Type {
case AccountListFollowers: case AccountListFollowers:
output += utilities.HeaderFormat("FOLLOWED BY:") output += utilities.HeaderFormat(noColor, "FOLLOWED BY:")
case AccountListFollowing: case AccountListFollowing:
output += utilities.HeaderFormat("FOLLOWING:") output += utilities.HeaderFormat(noColor, "FOLLOWING:")
case AccountListBlockedAccount: case AccountListBlockedAccount:
output += utilities.HeaderFormat("BLOCKED ACCOUNTS:") output += utilities.HeaderFormat(noColor, "BLOCKED ACCOUNTS:")
default: default:
output += utilities.HeaderFormat("ACCOUNTS:") output += utilities.HeaderFormat(noColor, "ACCOUNTS:")
} }
if a.Type == AccountListBlockedAccount { if a.Type == AccountListBlockedAccount {
@ -216,7 +216,7 @@ func (a AccountList) String() string {
for i := range a.Accounts { for i := range a.Accounts {
output += fmt.Sprintf( output += fmt.Sprintf(
"\n • %s (%s)", "\n • %s (%s)",
utilities.DisplayNameFormat(a.Accounts[i].DisplayName), utilities.DisplayNameFormat(noColor, a.Accounts[i].DisplayName),
a.Accounts[i].Acct, a.Accounts[i].Acct,
) )
} }

View file

@ -113,7 +113,7 @@ type InstanceV2Users struct {
ActiveMonth int `json:"active_month"` ActiveMonth int `json:"active_month"`
} }
func (i InstanceV2) String() string { func (i InstanceV2) Display(noColor bool) string {
format := ` format := `
%s %s
%s %s
@ -138,22 +138,22 @@ func (i InstanceV2) String() string {
return fmt.Sprintf( return fmt.Sprintf(
format, format,
utilities.HeaderFormat("INSTANCE TITLE:"), utilities.HeaderFormat(noColor, "INSTANCE TITLE:"),
i.Title, i.Title,
utilities.HeaderFormat("INSTANCE DESCRIPTION:"), utilities.HeaderFormat(noColor, "INSTANCE DESCRIPTION:"),
utilities.WrapLines(i.DescriptionText, "\n ", 80), utilities.WrapLines(i.DescriptionText, "\n ", 80),
utilities.HeaderFormat("DOMAIN:"), utilities.HeaderFormat(noColor, "DOMAIN:"),
i.Domain, i.Domain,
utilities.HeaderFormat("TERMS AND CONDITIONS:"), utilities.HeaderFormat(noColor, "TERMS AND CONDITIONS:"),
utilities.WrapLines(i.TermsText, "\n ", 80), utilities.WrapLines(i.TermsText, "\n ", 80),
utilities.HeaderFormat("VERSION:"), utilities.HeaderFormat(noColor, "VERSION:"),
i.Version, i.Version,
utilities.HeaderFormat("CONTACT:"), utilities.HeaderFormat(noColor, "CONTACT:"),
utilities.FieldFormat("Name:"), utilities.FieldFormat(noColor, "Name:"),
utilities.DisplayNameFormat(i.Contact.Account.DisplayName), utilities.DisplayNameFormat(noColor, i.Contact.Account.DisplayName),
utilities.FieldFormat("Username:"), utilities.FieldFormat(noColor, "Username:"),
i.Contact.Account.Username, i.Contact.Account.Username,
utilities.FieldFormat("Email:"), utilities.FieldFormat(noColor, "Email:"),
i.Contact.Email, i.Contact.Email,
) )
} }

View file

@ -83,7 +83,7 @@ type List struct {
Accounts map[string]string Accounts map[string]string
} }
func (l List) String() string { func (l List) Display(noColor bool) string {
format := ` format := `
%s %s
%s %s
@ -98,17 +98,17 @@ func (l List) String() string {
output := fmt.Sprintf( output := fmt.Sprintf(
format, format,
utilities.HeaderFormat("LIST TITLE:"), l.Title, utilities.HeaderFormat(noColor, "LIST TITLE:"), l.Title,
utilities.HeaderFormat("LIST ID:"), l.ID, utilities.HeaderFormat(noColor, "LIST ID:"), l.ID,
utilities.HeaderFormat("REPLIES POLICY:"), l.RepliesPolicy, utilities.HeaderFormat(noColor, "REPLIES POLICY:"), l.RepliesPolicy,
utilities.HeaderFormat("ADDED ACCOUNTS:"), utilities.HeaderFormat(noColor, "ADDED ACCOUNTS:"),
) )
if len(l.Accounts) > 0 { if len(l.Accounts) > 0 {
for id, name := range l.Accounts { for id, name := range l.Accounts {
output += fmt.Sprintf( output += fmt.Sprintf(
"\n • %s (%s)", "\n • %s (%s)",
utilities.DisplayNameFormat(name), utilities.DisplayNameFormat(noColor, name),
id, id,
) )
} }

View file

@ -15,7 +15,7 @@ type Preferences struct {
ReadingAutoplayGifs bool `json:"reading:autoplay:gifs"` ReadingAutoplayGifs bool `json:"reading:autoplay:gifs"`
} }
func (p Preferences) String() string { func (p Preferences) Display(noColor bool) string {
format := ` format := `
%s %s
%s: %s %s: %s
@ -24,9 +24,9 @@ func (p Preferences) String() string {
return fmt.Sprintf( return fmt.Sprintf(
format, format,
utilities.HeaderFormat("YOUR PREFERENCES:"), utilities.HeaderFormat(noColor, "YOUR PREFERENCES:"),
utilities.FieldFormat("Default post language"), p.PostingDefaultLanguage, utilities.FieldFormat(noColor, "Default post language"), p.PostingDefaultLanguage,
utilities.FieldFormat("Default post visibility"), p.PostingDefaultVisibility, utilities.FieldFormat(noColor, "Default post visibility"), p.PostingDefaultVisibility,
utilities.FieldFormat("Mark posts as sensitive by default"), p.PostingDefaultSensitive, utilities.FieldFormat(noColor, "Mark posts as sensitive by default"), p.PostingDefaultSensitive,
) )
} }

View file

@ -152,7 +152,7 @@ type MediaDimensions struct {
Width int `json:"width"` Width int `json:"width"`
} }
func (s Status) String() string { func (s Status) Display(noColor bool) string {
format := ` format := `
%s (@%s) %s (@%s)
@ -178,20 +178,20 @@ func (s Status) String() string {
return fmt.Sprintf( return fmt.Sprintf(
format, format,
utilities.DisplayNameFormat(s.Account.DisplayName), s.Account.Username, utilities.DisplayNameFormat(noColor, s.Account.DisplayName), s.Account.Username,
utilities.HeaderFormat("CONTENT:"), utilities.HeaderFormat(noColor, "CONTENT:"),
utilities.WrapLines(utilities.StripHTMLTags(s.Content), "\n ", 80), utilities.WrapLines(utilities.StripHTMLTags(s.Content), "\n ", 80),
utilities.HeaderFormat("STATUS ID:"), utilities.HeaderFormat(noColor, "STATUS ID:"),
s.ID, s.ID,
utilities.HeaderFormat("CREATED AT:"), utilities.HeaderFormat(noColor, "CREATED AT:"),
utilities.FormatTime(s.CreatedAt), utilities.FormatTime(s.CreatedAt),
utilities.HeaderFormat("STATS:"), utilities.HeaderFormat(noColor, "STATS:"),
s.ReblogsCount, s.ReblogsCount,
s.FavouritesCount, s.FavouritesCount,
s.RepliesCount, s.RepliesCount,
utilities.HeaderFormat("VISIBILITY:"), utilities.HeaderFormat(noColor, "VISIBILITY:"),
s.Visibility, s.Visibility,
utilities.HeaderFormat("URL:"), utilities.HeaderFormat(noColor, "URL:"),
s.URL, s.URL,
) )
} }

View file

@ -11,27 +11,27 @@ type Timeline struct {
Statuses []Status Statuses []Status
} }
func (t Timeline) String() string { func (t Timeline) Display(noColor bool) string {
var builder strings.Builder var builder strings.Builder
separator := "────────────────────────────────────────────────────────────────────────────────" separator := "────────────────────────────────────────────────────────────────────────────────"
builder.WriteString(utilities.HeaderFormat(t.Name) + "\n\n") builder.WriteString(utilities.HeaderFormat(noColor, t.Name) + "\n")
for _, status := range t.Statuses { for _, status := range t.Statuses {
builder.WriteString(utilities.DisplayNameFormat(status.Account.DisplayName) + " (@" + status.Account.Acct + ")\n") builder.WriteString("\n" + utilities.DisplayNameFormat(noColor, status.Account.DisplayName) + " (@" + status.Account.Acct + ")\n")
statusID := status.ID statusID := status.ID
createdAt := status.CreatedAt createdAt := status.CreatedAt
if status.Reblog != nil { if status.Reblog != nil {
builder.WriteString("reposted this status from " + utilities.DisplayNameFormat(status.Reblog.Account.DisplayName) + " (@" + status.Reblog.Account.Acct + ")\n") builder.WriteString("reposted this status from " + utilities.DisplayNameFormat(noColor, status.Reblog.Account.DisplayName) + " (@" + status.Reblog.Account.Acct + ")\n")
statusID = status.Reblog.ID statusID = status.Reblog.ID
createdAt = status.Reblog.CreatedAt createdAt = status.Reblog.CreatedAt
} }
builder.WriteString(utilities.WrapLines(utilities.StripHTMLTags(status.Content), "\n", 80) + "\n\n") builder.WriteString(utilities.WrapLines(utilities.StripHTMLTags(status.Content), "\n", 80) + "\n\n")
builder.WriteString(utilities.FieldFormat("ID:") + " " + statusID + "\t" + utilities.FieldFormat("Created at:") + " " + utilities.FormatTime(createdAt) + "\n") builder.WriteString(utilities.FieldFormat(noColor, "ID:") + " " + statusID + "\t" + utilities.FieldFormat(noColor, "Created at:") + " " + utilities.FormatTime(createdAt) + "\n")
builder.WriteString(separator + "\n") builder.WriteString(separator + "\n")
} }

View file

@ -12,18 +12,30 @@ const (
green = "\033[32m" green = "\033[32m"
) )
func HeaderFormat(text string) string { func HeaderFormat(noColor bool, text string) string {
if noColor {
return text
}
return boldblue + text + reset return boldblue + text + reset
} }
func FieldFormat(text string) string { func FieldFormat(noColor bool, text string) string {
if noColor {
return text
}
return green + text + reset return green + text + reset
} }
func DisplayNameFormat(text string) string { func DisplayNameFormat(noColor bool, text string) string {
// use this pattern to remove all emoji strings // use this pattern to remove all emoji strings
pattern := regexp.MustCompile(`\s:[A-Za-z0-9]*:`) pattern := regexp.MustCompile(`\s:[A-Za-z0-9]*:`)
if noColor {
return pattern.ReplaceAllString(text, "")
}
return boldmagenta + pattern.ReplaceAllString(text, "") + reset return boldmagenta + pattern.ReplaceAllString(text, "") + reset
} }

View file

@ -0,0 +1,11 @@
package utilities
import "os"
type Displayer interface {
Display(noColor bool) string
}
func Display(d Displayer, noColor bool) {
os.Stdout.WriteString(d.Display(noColor) + "\n")
}