cmd/gondole-cli/config.go
changeset 69 3474d0f36259
parent 68 6252b7eea308
child 73 d601c957d789
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmd/gondole-cli/config.go	Wed Apr 12 09:38:20 2017 +0200
@@ -0,0 +1,152 @@
+// config.go
+//
+// This file implements the configuration part for when you need the API
+// key to modify things in the Mastodon configuration and manage measurements.
+
+package gondole
+
+import (
+	"fmt"
+	"io/ioutil"
+	"log"
+	"os"
+	"path/filepath"
+
+	"github.com/naoina/toml"
+)
+
+/*
+Assume the application is registered if $HOME/.config/<gondole>/config.toml already exist
+We will store the per-instance token into $HOME/.config/<gondole>/<site>.token
+*/
+
+const (
+	DefaultName = "config.toml"
+)
+
+var (
+	baseDir = filepath.Join(os.Getenv("HOME"),
+		".config",
+		"gondole",
+	)
+)
+
+// Config holds our parameters
+type Server struct {
+	ID          string `json:"id"`
+	Name        string `json:"name"`
+	BearerToken string `json:"bearer_token"`
+	BaseURL     string `json:"base_url"`	// Allow for overriding APIEndpoint on registration
+}
+
+type Config struct {
+	Default string
+}
+
+func loadGlobal(file string) (c *Config, err error) {
+	log.Printf("file=%s", file)
+	// Check if there is any config file
+	_, err = os.Stat(file)
+	if err != nil {
+		return
+	}
+
+	log.Printf("file=%s, found it", file)
+	// Read it
+	buf, err := ioutil.ReadFile(file)
+	if err != nil {
+		return c, fmt.Errorf("Can not read %s", file)
+	}
+
+	cnf := Config{}
+	err = toml.Unmarshal(buf, &cnf)
+	if err != nil {
+		return c, fmt.Errorf("Error parsing toml %s: %v", file, err)
+	}
+	c = &cnf
+	return
+}
+
+func loadInstance(name string) (s *Server, err error) {
+	// Load instance-specific file
+	file := filepath.Join(baseDir, name+".token")
+
+	log.Printf("instance is %s", file)
+
+	// Check if there is any config file
+	if _, err = os.Stat(file); err == nil {
+		// Read it
+		buf, err := ioutil.ReadFile(file)
+		if err != nil {
+			return s, fmt.Errorf("Can not read %s", file)
+		}
+
+		sc := Server{}
+		err = toml.Unmarshal(buf, &sc)
+		if err != nil {
+			return s, fmt.Errorf("Error parsing toml %s: %v", file, err)
+		}
+		s = &sc
+	}
+	return
+}
+
+func GetInstanceList() (list []string) {
+	list, err := filepath.Glob(filepath.Join(baseDir, "*.token"))
+	log.Printf("basedir=%s", filepath.Join(baseDir, "*.token"))
+	if err != nil {
+		log.Printf("warning, no *.token files in %s", baseDir)
+		list = nil
+	}
+	log.Printf("list=%v", list)
+	return
+}
+
+// LoadConfig reads a file as a TOML document and return the structure
+func LoadConfig(name string) (s *Server, err error) {
+	// Load global file
+	gFile := filepath.Join(baseDir, DefaultName)
+
+	log.Printf("global is %s", gFile)
+	c, err := loadGlobal(gFile)
+	if err != nil {
+		return
+	}
+	if name == "" {
+		s, err = loadInstance(c.Default)
+	} else {
+		s, err = loadInstance(name)
+	}
+
+	return s, err
+}
+
+func (c *Config) Write() (err error) {
+	if err = os.MkdirAll(baseDir, 0700); err != nil {
+		log.Fatalf("error creating configuration directory: %s", baseDir)
+	}
+
+	var sc []byte
+
+	if sc, err = toml.Marshal(*c); err != nil {
+		log.Fatalf("error saving configuration")
+	}
+	err = ioutil.WriteFile(filepath.Join(baseDir, DefaultName), sc, 0600)
+	return
+}
+
+func (s *Server) WriteToken(instance string) (err error) {
+	if err = os.MkdirAll(baseDir, 0700); err != nil {
+		log.Fatalf("error creating configuration directory: %s", baseDir)
+	}
+
+	var sc []byte
+
+	if sc, err = toml.Marshal(s); err != nil {
+		log.Fatalf("error saving configuration")
+	}
+
+	full := instance + ".token"
+	err = ioutil.WriteFile(filepath.Join(baseDir, full), sc, 0600)
+	return
+}