# HG changeset patch # User Mikael Berthe # Date 1493564836 -7200 # Node ID 9bc03db114c36c557f5130414d1a04a734e1c99c # Parent c601c0d7b3b4a18b8508e21aaaf6da50460b711e Add server statistics with gomif (using instances.mastodon.xyz API) diff -r c601c0d7b3b4 -r 9bc03db114c3 .travis.yml --- a/.travis.yml Sun Apr 30 16:12:55 2017 +0200 +++ b/.travis.yml Sun Apr 30 17:07:16 2017 +0200 @@ -16,3 +16,4 @@ - go get github.com/McKael/madon - go get github.com/ghodss/yaml - go get github.com/jaytaylor/html2text +- go get github.com/m0t0k1ch1/gomif diff -r c601c0d7b3b4 -r 9bc03db114c3 README.md --- a/README.md Sun Apr 30 16:12:55 2017 +0200 +++ b/README.md Sun Apr 30 17:07:16 2017 +0200 @@ -13,7 +13,7 @@ ### From source -To install the application from source (you need to have Go >= 1.5), just type: +To install the application from source (you need to have Go >= 1.7), just type: go get github.com/McKael/madonctl @@ -165,6 +165,11 @@ % madonctl accounts --account-id 1 followers --template '{{.acct}}{{"\n"}}' ``` +Number of users on current instance (madonctl 1.5+) (statistics from instances.mastodon.xyz API): +``` +madonctl instance --stats --template '{{printf "%v\n" .users}}' +``` + There are many more commands, you can find them in the online help or the manpage. diff -r c601c0d7b3b4 -r 9bc03db114c3 cmd/instance.go --- a/cmd/instance.go Sun Apr 30 16:12:55 2017 +0200 +++ b/cmd/instance.go Sun Apr 30 17:07:16 2017 +0200 @@ -6,34 +6,94 @@ package cmd import ( + "context" + "errors" + "os" + "strings" + + "github.com/m0t0k1ch1/gomif" "github.com/spf13/cobra" + + "github.com/McKael/madonctl/printer" ) +var instanceOpts struct { + stats bool + server string +} + // timelinesCmd represents the timelines command var instanceCmd = &cobra.Command{ Use: "instance", Short: "Display current instance information", RunE: instanceRunE, + Example: ` madonctl instance + madonctl instance -i mastodon.social + madonctl instance --stats + madonctl instance --stats --server mastodon.social --template '{{.Users}}'`, } func init() { RootCmd.AddCommand(instanceCmd) + + instanceCmd.Flags().BoolVar(&instanceOpts.stats, "stats", false, "Display server statistics (from instances.mastodon.xyz)") + instanceCmd.Flags().StringVar(&instanceOpts.server, "server", "", "Display statistics for a specific server (for --stats)") } func instanceRunE(cmd *cobra.Command, args []string) error { + opt := instanceOpts + + p, err := getPrinter() + if err != nil { + return err + } + + if opt.stats { + // Get instance statistics using gomif + if opt.server == "" { + if err := madonInit(false); err != nil { + return err + } + opt.server = strings.TrimLeft(gClient.InstanceURL, "https://") + } + is, err := instanceFetchStatus(opt.server) + if err != nil { + errPrint("Error: %s", err.Error()) + os.Exit(1) + } + if is == nil { + return nil + } + istats := &printer.InstanceStatistics{ + InstanceName: opt.server, + InstanceStatus: *is, + } + return p.PrintObj(istats, nil, "") + } + + // Get current instance data through the API if err := madonInit(false); err != nil { return err } - i, err := gClient.GetCurrentInstance() if err != nil { errPrint("Error: %s", err.Error()) return nil } - p, err := getPrinter() - if err != nil { - return err - } return p.PrintObj(i, nil, "") } + +func instanceFetchStatus(server string) (*gomif.InstanceStatus, error) { + if server == "" { + return nil, errors.New("no instance server name") + } + + client := gomif.NewClient() + + return client.FetchLastInstanceStatus( + context.Background(), + server, + 3600, // span (sec) + ) +} diff -r c601c0d7b3b4 -r 9bc03db114c3 printer/plain.go --- a/printer/plain.go Sun Apr 30 16:12:55 2017 +0200 +++ b/printer/plain.go Sun Apr 30 17:07:16 2017 +0200 @@ -13,6 +13,7 @@ "time" "github.com/jaytaylor/html2text" + "github.com/m0t0k1ch1/gomif" "github.com/McKael/madon" ) @@ -33,6 +34,12 @@ return &PlainPrinter{Indent: indentInc}, nil } +// InstanceStatistics embeds a gomif.InstanceStatus with an ID in a new type +type InstanceStatistics struct { + InstanceName string `json:"instance_name"` + gomif.InstanceStatus +} + // PrintObj sends the object as text to the writer // If the writer w is nil, standard output will be used. // For PlainPrinter, the option parameter contains the initial indent. @@ -90,6 +97,10 @@ return p.plainPrintUserToken(o, w, initialIndent) case madon.UserToken: return p.plainPrintUserToken(&o, w, initialIndent) + case *InstanceStatistics: + return p.plainPrintInstanceStatistics(o, w, initialIndent) + case InstanceStatistics: + return p.plainPrintInstanceStatistics(&o, w, initialIndent) } // TODO: Mention // TODO: StreamEvent @@ -271,3 +282,13 @@ indentedPrint(w, indent, false, true, "Scope", "%s", s.Scope) return nil } + +func (p *PlainPrinter) plainPrintInstanceStatistics(is *InstanceStatistics, w io.Writer, indent string) error { + indentedPrint(w, indent, true, false, "Instance", "%s", is.InstanceName) + indentedPrint(w, indent, false, false, "Users", "%d", is.Users) + indentedPrint(w, indent, false, false, "Statuses", "%d", is.Statuses) + indentedPrint(w, indent, false, false, "Open Registrations", "%v", is.OpenRegistrations) + indentedPrint(w, indent, false, false, "Up", "%v", is.Up) + indentedPrint(w, indent, false, false, "Date", "%s", time.Unix(is.Date, 0)) + return nil +}