add subcommand for instance details
This commit is contained in:
parent
e354456c0e
commit
1361482dd4
5 changed files with 212 additions and 6 deletions
64
cmd/enbas/instance.go
Normal file
64
cmd/enbas/instance.go
Normal file
|
@ -0,0 +1,64 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"codeflow.dananglin.me.uk/apollo/enbas/internal/client"
|
||||
)
|
||||
|
||||
var instanceDetailsFormat = `INSTANCE:
|
||||
%s - %s
|
||||
|
||||
DOMAIN:
|
||||
%s
|
||||
|
||||
VERSION:
|
||||
Running GoToSocial %s
|
||||
|
||||
CONTACT:
|
||||
name: %s
|
||||
username: %s
|
||||
email: %s
|
||||
`
|
||||
|
||||
type instanceCommand struct {
|
||||
*flag.FlagSet
|
||||
summary string
|
||||
}
|
||||
|
||||
func newInstanceCommand(name, summary string) *instanceCommand {
|
||||
command := instanceCommand{
|
||||
FlagSet: flag.NewFlagSet(name, flag.ExitOnError),
|
||||
summary: summary,
|
||||
}
|
||||
|
||||
command.Usage = commandUsageFunc(command.Name(), command.summary, command.FlagSet)
|
||||
|
||||
return &command
|
||||
}
|
||||
|
||||
func (c *instanceCommand) Execute() error {
|
||||
gtsClient, err := client.NewClientFromConfig()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create the GoToSocial client; %w", err)
|
||||
}
|
||||
|
||||
instance, err := gtsClient.GetInstance()
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to retrieve the instance details; %w", err)
|
||||
}
|
||||
|
||||
fmt.Printf(
|
||||
instanceDetailsFormat,
|
||||
instance.Title,
|
||||
instance.Description,
|
||||
instance.Domain,
|
||||
instance.Version,
|
||||
instance.Contact.Account.DisplayName,
|
||||
instance.Contact.Account.Username,
|
||||
instance.Contact.Email,
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -9,8 +9,9 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
login string = "login"
|
||||
version string = "version"
|
||||
login string = "login"
|
||||
version string = "version"
|
||||
instance string = "instance"
|
||||
)
|
||||
|
||||
type Executor interface {
|
||||
|
@ -21,8 +22,9 @@ type Executor interface {
|
|||
|
||||
func main() {
|
||||
summaries := map[string]string{
|
||||
login: "login to an account on GoToSocial",
|
||||
version: "print the application's version and build information",
|
||||
login: "login to an account on GoToSocial",
|
||||
version: "print the application's version and build information",
|
||||
instance: "print the instance information",
|
||||
}
|
||||
|
||||
flag.Usage = enbasUsageFunc(summaries)
|
||||
|
@ -44,6 +46,8 @@ func main() {
|
|||
executor = newLoginCommand(login, summaries[login])
|
||||
case version:
|
||||
executor = newVersionCommand(version, summaries[version])
|
||||
case instance:
|
||||
executor = newInstanceCommand(instance, summaries[instance])
|
||||
default:
|
||||
fmt.Printf("ERROR: Unknown subcommand: %s\n", subcommand)
|
||||
flag.Usage()
|
||||
|
|
|
@ -19,6 +19,17 @@ type Client struct {
|
|||
Timeout time.Duration
|
||||
}
|
||||
|
||||
func NewClientFromConfig() (*Client, error) {
|
||||
config, err := config.NewAuthenticationConfigFromFile()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to get the authentication configuration; %w", err)
|
||||
}
|
||||
|
||||
currentAuthentication := config.Authentications[config.CurrentAccount]
|
||||
|
||||
return NewClient(currentAuthentication), nil
|
||||
}
|
||||
|
||||
func NewClient(authentication config.Authentication) *Client {
|
||||
httpClient := http.Client{}
|
||||
|
||||
|
@ -53,6 +64,27 @@ func (g *Client) VerifyCredentials() (model.Account, error) {
|
|||
return account, nil
|
||||
}
|
||||
|
||||
func (g *Client) GetInstance() (model.InstanceV2, error) {
|
||||
path := "/api/v2/instance"
|
||||
url := g.Authentication.Instance + path
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), g.Timeout)
|
||||
defer cancel()
|
||||
|
||||
request, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return model.InstanceV2{}, fmt.Errorf("unable to create the HTTP request, %w", err)
|
||||
}
|
||||
|
||||
var instance model.InstanceV2
|
||||
|
||||
if err := g.sendRequest(request, &instance); err != nil {
|
||||
return model.InstanceV2{}, fmt.Errorf("received an error after sending the request to get the instance details; %w", err)
|
||||
}
|
||||
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (g *Client) sendRequest(request *http.Request, object any) error {
|
||||
request.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||
request.Header.Set("Accept", "application/json; charset=utf-8")
|
||||
|
|
|
@ -39,7 +39,7 @@ func SaveAuthentication(username string, authentication Authentication) (string,
|
|||
|
||||
config.Authentications = make(map[string]Authentication)
|
||||
} else {
|
||||
config, err = newAuthenticationConfigFromFile()
|
||||
config, err = NewAuthenticationConfigFromFile()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to retrieve the existing authentication configuration; %w", err)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func SaveAuthentication(username string, authentication Authentication) (string,
|
|||
return authenticationName, nil
|
||||
}
|
||||
|
||||
func newAuthenticationConfigFromFile() (AuthenticationConfig, error) {
|
||||
func NewAuthenticationConfigFromFile() (AuthenticationConfig, error) {
|
||||
path := authenticationConfigFile()
|
||||
|
||||
file, err := os.Open(path)
|
||||
|
|
106
internal/model/instance_v2.go
Normal file
106
internal/model/instance_v2.go
Normal file
|
@ -0,0 +1,106 @@
|
|||
package model
|
||||
|
||||
type InstanceV2 struct {
|
||||
AccountDomain string `json:"account_domain"`
|
||||
Configuration InstanceConfiguration `json:"configuration"`
|
||||
Contact InstanceV2Contact `json:"contact"`
|
||||
Description string `json:"description"`
|
||||
Domain string `json:"domain"`
|
||||
Languages []string `json:"languages"`
|
||||
Registrations InstanceV2Registrations `json:"registrations"`
|
||||
Rules []InstanceRule `json:"rules"`
|
||||
SourceURL string `json:"source_url"`
|
||||
Terms string `json:"terms"`
|
||||
Thumbnail InstanceV2Thumbnail `json:"thumbnail"`
|
||||
Title string `json:"title"`
|
||||
Usage InstanceV2Usage `json:"usage"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
type InstanceConfiguration struct {
|
||||
Accounts InstanceConfigurationAccounts `json:"accounts"`
|
||||
Emojis InstanceConfigurationEmojis `json:"emojis"`
|
||||
MediaAttachments InstanceConfigurationMediaAttachments `json:"media_attachments"`
|
||||
Polls InstanceConfigurationPolls `json:"polls"`
|
||||
Statuses InstanceConfigurationStatuses `json:"statuses"`
|
||||
Translation InstanceV2ConfigurationTranslation `json:"translation"`
|
||||
URLs InstanceV2URLs `json:"urls"`
|
||||
}
|
||||
|
||||
type InstanceConfigurationAccounts struct {
|
||||
AllowCustomCSS bool `json:"allow_custom_css"`
|
||||
MaxFeaturedTags int `json:"max_featured_tags"`
|
||||
MaxProfileFields int `json:"max_profile_fields"`
|
||||
}
|
||||
|
||||
type InstanceConfigurationEmojis struct {
|
||||
EmojiSizeLimit int `json:"emoji_size_limit"`
|
||||
}
|
||||
|
||||
type InstanceConfigurationMediaAttachments struct {
|
||||
ImageMatrixLimit int `json:"image_matrix_limit"`
|
||||
ImageSizeLimit int `json:"image_size_limit"`
|
||||
SupportedMimeTypes []string `json:"supported_mime_types"`
|
||||
VideoFrameRateLimit int `json:"video_frame_rate_limit"`
|
||||
VideoMatrixLimit int `json:"video_matrix_limit"`
|
||||
VideoSizeLimit int `json:"video_size_limit"`
|
||||
}
|
||||
|
||||
type InstanceConfigurationPolls struct {
|
||||
MaxCharactersPerOption int `json:"max_characters_per_option"`
|
||||
MaxExpiration int `json:"max_expiration"`
|
||||
MaxOptions int `json:"max_options"`
|
||||
MinExpiration int `json:"min_expiration"`
|
||||
}
|
||||
|
||||
type InstanceConfigurationStatuses struct {
|
||||
CharactersReservedPerURL int `json:"characters_reserved_per_url"`
|
||||
MaxCharacters int `json:"max_characters"`
|
||||
MaxMediaAttachments int `json:"max_media_attachments"`
|
||||
SupportedMimeTypes []string `json:"supported_mime_types"`
|
||||
}
|
||||
|
||||
type InstanceV2ConfigurationTranslation struct {
|
||||
Enabled bool `json:"enabled"`
|
||||
}
|
||||
|
||||
type InstanceV2URLs struct {
|
||||
Streaming string `json:"streaming"`
|
||||
}
|
||||
|
||||
type InstanceV2Contact struct {
|
||||
Account Account `json:"account"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
type InstanceV2Registrations struct {
|
||||
ApprovalRequired bool `json:"approval_required"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
type InstanceRule struct {
|
||||
ID string `json:"id"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type InstanceV2Thumbnail struct {
|
||||
BlurHash string `json:"blurhash"`
|
||||
ThumbnailDescription string `json:"thumbnail_description"`
|
||||
ThumbnailType string `json:"thumbnail_type"`
|
||||
URL string `json:"url"`
|
||||
Version InstanceV2ThumbnailVersions `json:"versions"`
|
||||
}
|
||||
|
||||
type InstanceV2ThumbnailVersions struct {
|
||||
Size1URL string `json:"@1x"`
|
||||
Size2URL string `json:"@2x"`
|
||||
}
|
||||
|
||||
type InstanceV2Usage struct {
|
||||
Users InstanceV2Users `json:"users"`
|
||||
}
|
||||
|
||||
type InstanceV2Users struct {
|
||||
ActiveMonth int `json:"active_month"`
|
||||
}
|
Loading…
Reference in a new issue