Add server statistics with gomif (using instances.mastodon.xyz API)
authorMikael Berthe <mikael@lilotux.net>
Sun, 30 Apr 2017 17:07:16 +0200
changeset 37 9bc03db114c3
parent 36 c601c0d7b3b4
child 38 891a3c46a62a
Add server statistics with gomif (using instances.mastodon.xyz API)
.travis.yml
README.md
cmd/instance.go
printer/plain.go
--- 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
--- 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.
 
 
--- 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)
+	)
+}
--- 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
+}