Compare commits
2 commits
6e260266b1
...
3e47dea9ba
Author | SHA1 | Date | |
---|---|---|---|
3e47dea9ba | |||
c468d1fb62 |
5 changed files with 111 additions and 23 deletions
|
@ -13,9 +13,13 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
baseAccountsPath = "/api/v1/accounts"
|
||||||
|
baseFollowRequestsPath = "/api/v1/follow_requests"
|
||||||
|
)
|
||||||
|
|
||||||
func (g *Client) VerifyCredentials() (model.Account, error) {
|
func (g *Client) VerifyCredentials() (model.Account, error) {
|
||||||
path := "/api/v1/accounts/verify_credentials"
|
url := g.Authentication.Instance + baseAccountsPath + "/verify_credentials"
|
||||||
url := g.Authentication.Instance + path
|
|
||||||
|
|
||||||
var account model.Account
|
var account model.Account
|
||||||
|
|
||||||
|
@ -27,8 +31,7 @@ func (g *Client) VerifyCredentials() (model.Account, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) GetAccount(accountURI string) (model.Account, error) {
|
func (g *Client) GetAccount(accountURI string) (model.Account, error) {
|
||||||
path := "/api/v1/accounts/lookup?acct=" + accountURI
|
url := g.Authentication.Instance + baseAccountsPath + "/lookup?acct=" + accountURI
|
||||||
url := g.Authentication.Instance + path
|
|
||||||
|
|
||||||
var account model.Account
|
var account model.Account
|
||||||
|
|
||||||
|
@ -40,8 +43,7 @@ func (g *Client) GetAccount(accountURI string) (model.Account, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) GetAccountRelationship(accountID string) (*model.AccountRelationship, error) {
|
func (g *Client) GetAccountRelationship(accountID string) (*model.AccountRelationship, error) {
|
||||||
path := "/api/v1/accounts/relationships?id=" + accountID
|
url := g.Authentication.Instance + baseAccountsPath + "/relationships?id=" + accountID
|
||||||
url := g.Authentication.Instance + path
|
|
||||||
|
|
||||||
var relationships []model.AccountRelationship
|
var relationships []model.AccountRelationship
|
||||||
|
|
||||||
|
@ -75,7 +77,7 @@ func (g *Client) FollowAccount(form FollowAccountForm) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBody := bytes.NewBuffer(data)
|
requestBody := bytes.NewBuffer(data)
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/follow", form.AccountID)
|
url := g.Authentication.Instance + baseAccountsPath + "/" + form.AccountID + "/follow"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the follow request: %w", err)
|
return fmt.Errorf("received an error after sending the follow request: %w", err)
|
||||||
|
@ -85,7 +87,7 @@ func (g *Client) FollowAccount(form FollowAccountForm) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) UnfollowAccount(accountID string) error {
|
func (g *Client) UnfollowAccount(accountID string) error {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/unfollow", accountID)
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/unfollow"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to unfollow the account: %w", err)
|
return fmt.Errorf("received an error after sending the request to unfollow the account: %w", err)
|
||||||
|
@ -95,7 +97,7 @@ func (g *Client) UnfollowAccount(accountID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) GetFollowers(accountID string, limit int) (model.AccountList, error) {
|
func (g *Client) GetFollowers(accountID string, limit int) (model.AccountList, error) {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/followers?limit=%d", accountID, limit)
|
url := g.Authentication.Instance + fmt.Sprintf("%s/%s/followers?limit=%d", baseAccountsPath, accountID, limit)
|
||||||
|
|
||||||
accounts := make([]model.Account, limit)
|
accounts := make([]model.Account, limit)
|
||||||
|
|
||||||
|
@ -112,7 +114,7 @@ func (g *Client) GetFollowers(accountID string, limit int) (model.AccountList, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) GetFollowing(accountID string, limit int) (model.AccountList, error) {
|
func (g *Client) GetFollowing(accountID string, limit int) (model.AccountList, error) {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/following?limit=%d", accountID, limit)
|
url := g.Authentication.Instance + fmt.Sprintf("%s/%s/following?limit=%d", baseAccountsPath, accountID, limit)
|
||||||
|
|
||||||
accounts := make([]model.Account, limit)
|
accounts := make([]model.Account, limit)
|
||||||
|
|
||||||
|
@ -129,7 +131,7 @@ func (g *Client) GetFollowing(accountID string, limit int) (model.AccountList, e
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) BlockAccount(accountID string) error {
|
func (g *Client) BlockAccount(accountID string) error {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/block", accountID)
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/block"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to block the account: %w", err)
|
return fmt.Errorf("received an error after sending the request to block the account: %w", err)
|
||||||
|
@ -139,7 +141,7 @@ func (g *Client) BlockAccount(accountID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) UnblockAccount(accountID string) error {
|
func (g *Client) UnblockAccount(accountID string) error {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/unblock", accountID)
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/unblock"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to unblock the account: %w", err)
|
return fmt.Errorf("received an error after sending the request to unblock the account: %w", err)
|
||||||
|
@ -178,7 +180,7 @@ func (g *Client) SetPrivateNote(accountID, note string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBody := bytes.NewBuffer(data)
|
requestBody := bytes.NewBuffer(data)
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/accounts/%s/note", accountID)
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/note"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to set the private note: %w", err)
|
return fmt.Errorf("received an error after sending the request to set the private note: %w", err)
|
||||||
|
@ -188,7 +190,7 @@ func (g *Client) SetPrivateNote(accountID, note string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) GetFollowRequests(limit int) (model.AccountList, error) {
|
func (g *Client) GetFollowRequests(limit int) (model.AccountList, error) {
|
||||||
url := g.Authentication.Instance + fmt.Sprintf("/api/v1/follow_requests?limit=%d", limit)
|
url := g.Authentication.Instance + fmt.Sprintf("%s?limit=%d", baseFollowRequestsPath, limit)
|
||||||
|
|
||||||
var accounts []model.Account
|
var accounts []model.Account
|
||||||
|
|
||||||
|
@ -205,7 +207,7 @@ func (g *Client) GetFollowRequests(limit int) (model.AccountList, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) AcceptFollowRequest(accountID string) error {
|
func (g *Client) AcceptFollowRequest(accountID string) error {
|
||||||
url := g.Authentication.Instance + "/api/v1/follow_requests/" + accountID + "/authorize"
|
url := g.Authentication.Instance + baseFollowRequestsPath + "/" + accountID + "/authorize"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to accept the follow request: %w", err)
|
return fmt.Errorf("received an error after sending the request to accept the follow request: %w", err)
|
||||||
|
@ -215,7 +217,7 @@ func (g *Client) AcceptFollowRequest(accountID string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) RejectFollowRequest(accountID string) error {
|
func (g *Client) RejectFollowRequest(accountID string) error {
|
||||||
url := g.Authentication.Instance + "/api/v1/follow_requests/" + accountID + "/reject"
|
url := g.Authentication.Instance + baseFollowRequestsPath + "/" + accountID + "/reject"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to reject the follow request: %w", err)
|
return fmt.Errorf("received an error after sending the request to reject the follow request: %w", err)
|
||||||
|
@ -253,7 +255,7 @@ func (g *Client) MuteAccount(accountID string, form MuteAccountForm) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
requestBody := bytes.NewBuffer(data)
|
requestBody := bytes.NewBuffer(data)
|
||||||
url := g.Authentication.Instance + "/api/v1/accounts/" + accountID + "/mute"
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/mute"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, requestBody, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to mute the account: %w", err)
|
return fmt.Errorf("received an error after sending the request to mute the account: %w", err)
|
||||||
|
@ -263,7 +265,7 @@ func (g *Client) MuteAccount(accountID string, form MuteAccountForm) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *Client) UnmuteAccount(accountID string) error {
|
func (g *Client) UnmuteAccount(accountID string) error {
|
||||||
url := g.Authentication.Instance + "/api/v1/accounts/" + accountID + "/unmute"
|
url := g.Authentication.Instance + baseAccountsPath + "/" + accountID + "/unmute"
|
||||||
|
|
||||||
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
if err := g.sendRequest(http.MethodPost, url, nil, nil); err != nil {
|
||||||
return fmt.Errorf("received an error after sending the request to unmute the account: %w", err)
|
return fmt.Errorf("received an error after sending the request to unmute the account: %w", err)
|
||||||
|
@ -271,3 +273,40 @@ func (g *Client) UnmuteAccount(accountID string) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetAccountStatusesForm struct {
|
||||||
|
AccountID string
|
||||||
|
Limit int
|
||||||
|
ExcludeReplies bool
|
||||||
|
ExcludeReblogs bool
|
||||||
|
Pinned bool
|
||||||
|
OnlyMedia bool
|
||||||
|
OnlyPublic bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g *Client) GetAccountStatuses(form GetAccountStatusesForm) (*model.StatusList, error) {
|
||||||
|
path := baseAccountsPath + "/" + form.AccountID + "/statuses"
|
||||||
|
query := fmt.Sprintf(
|
||||||
|
"?limit=%d&exclude_replies=%t&exclude_reblogs=%t&pinned=%t&only_media=%t&only_public=%t",
|
||||||
|
form.Limit,
|
||||||
|
form.ExcludeReplies,
|
||||||
|
form.ExcludeReblogs,
|
||||||
|
form.Pinned,
|
||||||
|
form.OnlyMedia,
|
||||||
|
form.OnlyPublic,
|
||||||
|
)
|
||||||
|
url := g.Authentication.Instance + path + query
|
||||||
|
|
||||||
|
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 account's statuses: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
statusList := model.StatusList{
|
||||||
|
Name: "STATUSES:",
|
||||||
|
Statuses: statuses,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &statusList, nil
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ const (
|
||||||
flagEnableLikes = "enable-likes"
|
flagEnableLikes = "enable-likes"
|
||||||
flagEnableReplies = "enable-replies"
|
flagEnableReplies = "enable-replies"
|
||||||
flagEnableReposts = "enable-reposts"
|
flagEnableReposts = "enable-reposts"
|
||||||
|
flagExcludeBoosts = "exclude-boosts"
|
||||||
|
flagExcludeReplies = "exclude-replies"
|
||||||
flagFrom = "from"
|
flagFrom = "from"
|
||||||
flagFromFile = "from-file"
|
flagFromFile = "from-file"
|
||||||
flagFull = "full"
|
flagFull = "full"
|
||||||
|
@ -36,6 +38,9 @@ const (
|
||||||
flagMuteDuration = "mute-duration"
|
flagMuteDuration = "mute-duration"
|
||||||
flagMuteNotifications = "mute-notifications"
|
flagMuteNotifications = "mute-notifications"
|
||||||
flagNotify = "notify"
|
flagNotify = "notify"
|
||||||
|
flagOnlyMedia = "only-media"
|
||||||
|
flagOnlyPinned = "only-pinned"
|
||||||
|
flagOnlyPublic = "only-public"
|
||||||
flagPollAllowsMultipleChoices = "poll-allows-multiple-choices"
|
flagPollAllowsMultipleChoices = "poll-allows-multiple-choices"
|
||||||
flagPollExpiresIn = "poll-expires-in"
|
flagPollExpiresIn = "poll-expires-in"
|
||||||
flagPollHidesVoteCounts = "poll-hides-vote-counts"
|
flagPollHidesVoteCounts = "poll-hides-vote-counts"
|
||||||
|
@ -45,6 +50,7 @@ const (
|
||||||
flagSkipRelationship = "skip-relationship"
|
flagSkipRelationship = "skip-relationship"
|
||||||
flagShowPreferences = "show-preferences"
|
flagShowPreferences = "show-preferences"
|
||||||
flagShowReposts = "show-reposts"
|
flagShowReposts = "show-reposts"
|
||||||
|
flagShowStatuses = "show-statuses"
|
||||||
flagSpoilerText = "spoiler-text"
|
flagSpoilerText = "spoiler-text"
|
||||||
flagStatusID = "status-id"
|
flagStatusID = "status-id"
|
||||||
flagTag = "tag"
|
flagTag = "tag"
|
||||||
|
|
|
@ -23,9 +23,15 @@ type ShowExecutor struct {
|
||||||
printer *printer.Printer
|
printer *printer.Printer
|
||||||
config *config.Config
|
config *config.Config
|
||||||
myAccount bool
|
myAccount bool
|
||||||
skipAccountRelationship bool
|
excludeBoosts bool
|
||||||
showUserPreferences bool
|
excludeReplies bool
|
||||||
|
onlyMedia bool
|
||||||
|
onlyPinned bool
|
||||||
|
onlyPublic bool
|
||||||
showInBrowser bool
|
showInBrowser bool
|
||||||
|
showUserPreferences bool
|
||||||
|
showStatuses bool
|
||||||
|
skipAccountRelationship bool
|
||||||
resourceType string
|
resourceType string
|
||||||
accountName string
|
accountName string
|
||||||
statusID string
|
statusID string
|
||||||
|
@ -50,6 +56,12 @@ func NewShowExecutor(printer *printer.Printer, config *config.Config, name, summ
|
||||||
showExe.BoolVar(&showExe.skipAccountRelationship, flagSkipRelationship, false, "Set to true to skip showing your relationship to the specified account")
|
showExe.BoolVar(&showExe.skipAccountRelationship, flagSkipRelationship, false, "Set to true to skip showing your relationship to the specified account")
|
||||||
showExe.BoolVar(&showExe.showUserPreferences, flagShowPreferences, false, "Show your preferences")
|
showExe.BoolVar(&showExe.showUserPreferences, flagShowPreferences, false, "Show your preferences")
|
||||||
showExe.BoolVar(&showExe.showInBrowser, flagBrowser, false, "Set to true to view in the browser")
|
showExe.BoolVar(&showExe.showInBrowser, flagBrowser, false, "Set to true to view in the browser")
|
||||||
|
showExe.BoolVar(&showExe.showStatuses, flagShowStatuses, false, "Set to true to view the statuses created from the specified account")
|
||||||
|
showExe.BoolVar(&showExe.excludeReplies, flagExcludeReplies, false, "Set to true to exclude statuses that are a reply to another status")
|
||||||
|
showExe.BoolVar(&showExe.excludeBoosts, flagExcludeBoosts, false, "Set to true to exclude statuses that are boosts of another status")
|
||||||
|
showExe.BoolVar(&showExe.onlyPinned, flagOnlyPinned, false, "Set to true to show only the account's pinned statuses")
|
||||||
|
showExe.BoolVar(&showExe.onlyMedia, flagOnlyMedia, false, "Set to true to show only the statuses with media attachments")
|
||||||
|
showExe.BoolVar(&showExe.onlyPublic, flagOnlyPublic, false, "Set to true to show only the account's public posts")
|
||||||
showExe.StringVar(&showExe.resourceType, flagType, "", "Specify the type of resource to display")
|
showExe.StringVar(&showExe.resourceType, flagType, "", "Specify the type of resource to display")
|
||||||
showExe.StringVar(&showExe.accountName, flagAccountName, "", "Specify the account name in full (username@domain)")
|
showExe.StringVar(&showExe.accountName, flagAccountName, "", "Specify the account name in full (username@domain)")
|
||||||
showExe.StringVar(&showExe.statusID, flagStatusID, "", "Specify the ID of the status to display")
|
showExe.StringVar(&showExe.statusID, flagStatusID, "", "Specify the ID of the status to display")
|
||||||
|
@ -147,6 +159,7 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
var (
|
var (
|
||||||
relationship *model.AccountRelationship
|
relationship *model.AccountRelationship
|
||||||
preferences *model.Preferences
|
preferences *model.Preferences
|
||||||
|
statuses *model.StatusList
|
||||||
)
|
)
|
||||||
|
|
||||||
if !s.myAccount && !s.skipAccountRelationship {
|
if !s.myAccount && !s.skipAccountRelationship {
|
||||||
|
@ -163,7 +176,24 @@ func (s *ShowExecutor) showAccount(gtsClient *client.Client) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s.printer.PrintAccount(account, relationship, preferences)
|
if s.showStatuses {
|
||||||
|
form := client.GetAccountStatusesForm{
|
||||||
|
AccountID: account.ID,
|
||||||
|
Limit: s.limit,
|
||||||
|
ExcludeReplies: s.excludeReplies,
|
||||||
|
ExcludeReblogs: s.excludeBoosts,
|
||||||
|
Pinned: s.onlyPinned,
|
||||||
|
OnlyMedia: s.onlyMedia,
|
||||||
|
OnlyPublic: s.onlyPublic,
|
||||||
|
}
|
||||||
|
|
||||||
|
statuses, err = gtsClient.GetAccountStatuses(form)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to retrieve the account's statuses: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s.printer.PrintAccount(account, relationship, preferences, statuses)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,12 @@ import (
|
||||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
"codeflow.dananglin.me.uk/apollo/enbas/internal/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p Printer) PrintAccount(account model.Account, relationship *model.AccountRelationship, preferences *model.Preferences) {
|
func (p Printer) PrintAccount(
|
||||||
|
account model.Account,
|
||||||
|
relationship *model.AccountRelationship,
|
||||||
|
preferences *model.Preferences,
|
||||||
|
statuses *model.StatusList,
|
||||||
|
) {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
builder.WriteString("\n" + p.fullDisplayNameFormat(account.DisplayName, account.Acct))
|
builder.WriteString("\n" + p.fullDisplayNameFormat(account.DisplayName, account.Acct))
|
||||||
|
@ -45,6 +50,10 @@ func (p Printer) PrintAccount(account model.Account, relationship *model.Account
|
||||||
builder.WriteString(p.userPreferences(preferences))
|
builder.WriteString(p.userPreferences(preferences))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if statuses != nil {
|
||||||
|
builder.WriteString("\n\n" + p.statusList(*statuses))
|
||||||
|
}
|
||||||
|
|
||||||
builder.WriteString("\n\n")
|
builder.WriteString("\n\n")
|
||||||
|
|
||||||
p.print(builder.String())
|
p.print(builder.String())
|
||||||
|
|
|
@ -77,6 +77,10 @@ func (p Printer) PrintStatus(status model.Status) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Printer) PrintStatusList(list model.StatusList) {
|
func (p Printer) PrintStatusList(list model.StatusList) {
|
||||||
|
p.print(p.statusList(list))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Printer) statusList(list model.StatusList) string {
|
||||||
var builder strings.Builder
|
var builder strings.Builder
|
||||||
|
|
||||||
builder.WriteString(p.headerFormat(list.Name) + "\n")
|
builder.WriteString(p.headerFormat(list.Name) + "\n")
|
||||||
|
@ -170,5 +174,5 @@ func (p Printer) PrintStatusList(list model.StatusList) {
|
||||||
builder.WriteString("\n" + p.statusSeparator + "\n")
|
builder.WriteString("\n" + p.statusSeparator + "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
p.print(builder.String())
|
return builder.String()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue