Make it work with non-defaut instances
authorMikael Berthe <mikael@lilotux.net>
Wed, 12 Apr 2017 16:40:02 +0200
changeset 83 adc39ae774c0
parent 81 ba90955d2d56
child 84 519be52bfced
Make it work with non-defaut instances
app.go
cmd/gondole-cli/main.go
cmd/gondole-cli/utils.go
gondole.go
types.go
--- a/app.go	Wed Apr 12 14:27:09 2017 +0200
+++ b/app.go	Wed Apr 12 16:40:02 2017 +0200
@@ -2,30 +2,38 @@
 
 import (
 	"encoding/json"
+	"log"
+	"net/url"
+	"strings"
+
 	"github.com/sendgrid/rest"
-	"log"
-	"strings"
 )
 
-var ()
-
 type registerApp struct {
-	ID           string `json:"id"`
+	ID           int    `json:"id"`
 	ClientID     string `json:"client_id"`
 	ClientSecret string `json:"client_secret"`
 }
 
 // NewApp registers a new instance
-func NewApp(name string, scopes []string, redirectURI, baseURL string) (g *Client, err error) {
-	var endpoint string
+func NewApp(name string, scopes []string, redirectURI, instanceURL string) (g *Client, err error) {
+	if instanceURL == "" {
+		instanceURL = defaultInstanceURL
+	}
 
-	if baseURL != "" {
-		endpoint = baseURL
+	if !strings.Contains(instanceURL, "://") {
+		instanceURL = "https://" + instanceURL
+	}
+
+	apiPath := instanceURL + defaultAPIPath
+
+	if _, err := url.ParseRequestURI(apiPath); err != nil {
+		return nil, err
 	}
 
 	g = &Client{
-		Name: name,
-		APIBase: endpoint,
+		Name:    name,
+		APIBase: apiPath,
 	}
 
 	req := g.prepareRequest("apps")
@@ -54,12 +62,8 @@
 		log.Fatalf("error: can not write token for %s", name)
 	}
 
-	g = &Client{
-		Name:    name,
-		ID:      resp.ClientID,
-		Secret:  resp.ClientSecret,
-		APIBase: endpoint,
-	}
+	g.ID = resp.ClientID
+	g.Secret = resp.ClientSecret
 
 	return
 }
--- a/cmd/gondole-cli/main.go	Wed Apr 12 14:27:09 2017 +0200
+++ b/cmd/gondole-cli/main.go	Wed Apr 12 16:40:02 2017 +0200
@@ -16,19 +16,14 @@
 	instance *gondole.Client
 	cnf      *Server
 
-	// For bootstrapping, override the API endpoint w/o any possible /api/vN, that is
-	// supplied by the library
-	APIEndpoint string
-
-	// Deduced though the full instance URL when registering
-	InstanceName string
-
 	// Default scopes
 	ourScopes = []string{
 		"read",
 		"write",
 		"follow",
 	}
+
+	defaultInstanceURL = "https://mastodon.social"
 )
 
 // Config holds our parameters
@@ -36,7 +31,8 @@
 	ID          string `json:"id"`
 	Name        string `json:"name"`
 	BearerToken string `json:"bearer_token"`
-	BaseURL     string `json:"base_url"` // Allow for overriding APIEndpoint on registration
+	APIBase     string `json:"base_url"`
+	InstanceURL string `json:"base_url"`
 }
 
 type Config struct {
@@ -46,21 +42,27 @@
 func setupEnvironment(c *cli.Context) (err error) {
 	var scopes []string
 
+	instanceURL := defaultInstanceURL
 	if fInstance != "" {
-		InstanceName = basename(fInstance)
-		APIEndpoint = filterURL(fInstance)
+		if strings.Contains(fInstance, "://") {
+			instanceURL = fInstance
+		} else {
+			instanceURL = "https://" + fInstance
+		}
 	}
 
+	instanceName := basename(instanceURL)
+
 	// Load configuration, will register if none is found
-	cnf, err = LoadConfig(InstanceName)
+	cnf, err = LoadConfig(instanceName)
 	if err != nil {
 		// Nothing exist yet
 		defName := Config{
-			Default: InstanceName,
+			Default: instanceName,
 		}
 		err = defName.Write()
 		if err != nil {
-			log.Fatalf("error: can not write config for %s", InstanceName)
+			log.Fatalf("error: can not write config for %s", instanceName)
 		}
 
 		// Now register this through OAuth
@@ -70,15 +72,16 @@
 			scopes = ourScopes
 		}
 
-		instance, err = gondole.NewApp("gondole-cli", scopes, gondole.NoRedirect, fInstance)
+		instance, err = gondole.NewApp("gondole-cli", scopes, gondole.NoRedirect, instanceURL)
 
 		server := &Server{
 			ID:          instance.ID,
 			Name:        instance.Name,
 			BearerToken: instance.Secret,
-			BaseURL:     instance.APIBase,
+			APIBase:     instance.APIBase,
+			InstanceURL: instance.InstanceURL,
 		}
-		err = server.WriteToken(InstanceName)
+		err = server.WriteToken(instanceName)
 		if err != nil {
 			log.Fatalf("error: can not write token for %s", instance.Name)
 		}
@@ -101,7 +104,7 @@
 	cli.VersionFlag = cli.BoolFlag{Name: "version, V"}
 
 	cli.VersionPrinter = func(c *cli.Context) {
-		log.Printf("API wrapper: %s Mastodon CLI: %s\n", c.App.Version, gondole.APIVersion)
+		log.Printf("API wrapper: %s Mastodon CLI: %s\n", c.App.Version, gondole.GondoleVersion)
 	}
 }
 
@@ -111,7 +114,7 @@
 	app.Name = "gondole"
 	app.Usage = "Mastodon CLI interface"
 	app.Author = "Ollivier Robert <roberto@keltia.net>"
-	app.Version = gondole.APIVersion
+	app.Version = gondole.GondoleVersion
 	//app.HideVersion = true
 
 	app.Before = setupEnvironment
--- a/cmd/gondole-cli/utils.go	Wed Apr 12 14:27:09 2017 +0200
+++ b/cmd/gondole-cli/utils.go	Wed Apr 12 16:40:02 2017 +0200
@@ -1,9 +1,9 @@
 package main
 
 import (
-    "github.com/urfave/cli"
-    "net/url"
-    "strings"
+	"github.com/urfave/cli"
+	"net/url"
+	"strings"
 )
 
 // ByAlphabet is for sorting
@@ -14,23 +14,23 @@
 func (a ByAlphabet) Less(i, j int) bool { return a[i].Name < a[j].Name }
 
 func filterURL(in string) (out string) {
-    uri, err := url.Parse(in)
-    if err != nil {
-        out = ""
-    } else {
-        uri := url.URL{Scheme: uri.Scheme, Host: uri.Host}
-        out = uri.String()
-    }
-    return
+	uri, err := url.Parse(in)
+	if err != nil {
+		out = ""
+	} else {
+		uri := url.URL{Scheme: uri.Scheme, Host: uri.Host}
+		out = uri.String()
+	}
+	return
 }
 
 func basename(in string) (out string) {
-    uri, err := url.Parse(in)
-    if err != nil {
-        out = ""
-    } else {
-        // Remove the :NN part of present
-        out = strings.Split(uri.Host, ":")[0]
-    }
-    return
+	uri, err := url.Parse(in)
+	if err != nil {
+		out = ""
+	} else {
+		// Remove the :NN part of present
+		out = strings.Split(uri.Host, ":")[0]
+	}
+	return
 }
--- a/gondole.go	Wed Apr 12 14:27:09 2017 +0200
+++ b/gondole.go	Wed Apr 12 16:40:02 2017 +0200
@@ -1,51 +1,43 @@
 package gondole
 
 import (
-	"github.com/sendgrid/rest"
+	"errors"
 	"fmt"
-	"errors"
+
+	"github.com/sendgrid/rest"
 )
 
 const (
-	APIVersion = "0.0"
+	// GondoleVersion contains the version of the Gondole implementation
+	GondoleVersion = "0.0"
 
-	// That is not overridable
-	apiURL = "/api/v1"
+	defaultInstanceURL = "https://mastodon.social"
+	apiVersion         = "v1" // That is not overridable
+	defaultAPIPath     = "/api/" + apiVersion
 
-	// Fallback instance
-	FallBackURL = "https://mastodon.social"
-
+	// NoRedirect is the URI for no redirection in the App registration
 	NoRedirect = "urn:ietf:wg:oauth:2.0:oob"
 )
 
 var (
-	APIEndpoint string
 	ErrAlreadyRegistered = errors.New("App already registered")
 )
 
 // prepareRequest insert all pre-defined stuff
 func (g *Client) prepareRequest(what string) (req rest.Request) {
-	var APIBase string
+	var endPoint string
 
-	// Allow for overriding for registration
-	if g.APIBase == "" {
-		APIBase = FallBackURL
-	} else {
-		APIBase = g.APIBase
-	}
-
-	APIEndpoint = fmt.Sprintf("%s%s/%", APIBase, apiURL, what)
-
+	endPoint = g.APIBase + "/" + what
 	// Add at least one option, the APIkey if present
 	hdrs := make(map[string]string)
 	opts := make(map[string]string)
 
 	// Insert our sig
-	hdrs["User-Agent"] = fmt.Sprintf("Client/%s", APIVersion)
+	hdrs["User-Agent"] = fmt.Sprintf("Gondole/%s", GondoleVersion)
 	hdrs["Authorization"] = fmt.Sprintf("Bearer %s", g.Secret)
 
 	req = rest.Request{
-		BaseURL:     APIEndpoint,
+		BaseURL:     endPoint,
 		Headers:     hdrs,
 		QueryParams: opts,
 	}
--- a/types.go	Wed Apr 12 14:27:09 2017 +0200
+++ b/types.go	Wed Apr 12 16:40:02 2017 +0200
@@ -4,11 +4,13 @@
 	"time"
 )
 
+// Client contains data for a gondole client application
 type Client struct {
-	Name    string
-	ID      string
-	Secret  string
-	APIBase string
+	Name        string
+	ID          string
+	Secret      string
+	APIBase     string
+	InstanceURL string
 }
 
 /*