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
|
||||||
|
}
|
|
@ -11,6 +11,7 @@ import (
|
||||||
const (
|
const (
|
||||||
login string = "login"
|
login string = "login"
|
||||||
version string = "version"
|
version string = "version"
|
||||||
|
instance string = "instance"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Executor interface {
|
type Executor interface {
|
||||||
|
@ -23,6 +24,7 @@ func main() {
|
||||||
summaries := map[string]string{
|
summaries := map[string]string{
|
||||||
login: "login to an account on GoToSocial",
|
login: "login to an account on GoToSocial",
|
||||||
version: "print the application's version and build information",
|
version: "print the application's version and build information",
|
||||||
|
instance: "print the instance information",
|
||||||
}
|
}
|
||||||
|
|
||||||
flag.Usage = enbasUsageFunc(summaries)
|
flag.Usage = enbasUsageFunc(summaries)
|
||||||
|
@ -44,6 +46,8 @@ func main() {
|
||||||
executor = newLoginCommand(login, summaries[login])
|
executor = newLoginCommand(login, summaries[login])
|
||||||
case version:
|
case version:
|
||||||
executor = newVersionCommand(version, summaries[version])
|
executor = newVersionCommand(version, summaries[version])
|
||||||
|
case instance:
|
||||||
|
executor = newInstanceCommand(instance, summaries[instance])
|
||||||
default:
|
default:
|
||||||
fmt.Printf("ERROR: Unknown subcommand: %s\n", subcommand)
|
fmt.Printf("ERROR: Unknown subcommand: %s\n", subcommand)
|
||||||
flag.Usage()
|
flag.Usage()
|
||||||
|
|
|
@ -19,6 +19,17 @@ type Client struct {
|
||||||
Timeout time.Duration
|
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 {
|
func NewClient(authentication config.Authentication) *Client {
|
||||||
httpClient := http.Client{}
|
httpClient := http.Client{}
|
||||||
|
|
||||||
|
@ -53,6 +64,27 @@ func (g *Client) VerifyCredentials() (model.Account, error) {
|
||||||
return account, nil
|
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 {
|
func (g *Client) sendRequest(request *http.Request, object any) error {
|
||||||
request.Header.Set("Content-Type", "application/json; charset=utf-8")
|
request.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||||
request.Header.Set("Accept", "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)
|
config.Authentications = make(map[string]Authentication)
|
||||||
} else {
|
} else {
|
||||||
config, err = newAuthenticationConfigFromFile()
|
config, err = NewAuthenticationConfigFromFile()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("unable to retrieve the existing authentication configuration; %w", err)
|
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
|
return authenticationName, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAuthenticationConfigFromFile() (AuthenticationConfig, error) {
|
func NewAuthenticationConfigFromFile() (AuthenticationConfig, error) {
|
||||||
path := authenticationConfigFile()
|
path := authenticationConfigFile()
|
||||||
|
|
||||||
file, err := os.Open(path)
|
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