You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
3.0 KiB
144 lines
3.0 KiB
package main |
|
|
|
import ( |
|
"fmt" |
|
"io/ioutil" |
|
"sort" |
|
|
|
"github.com/pkg/errors" |
|
"gopkg.in/yaml.v2" |
|
) |
|
|
|
const ( |
|
authorAccessRead = 0 |
|
authorAccessCheck = 1 |
|
authorAccessWrite = 2 |
|
) |
|
|
|
const defaultConfigPath = "~/.config/stick/stick.yml" |
|
|
|
type config struct { |
|
Salt string |
|
Serve string |
|
|
|
Authors []*authorConfig |
|
Notebooks []*notebookConfig |
|
|
|
Debug bool |
|
} |
|
|
|
type authorConfig struct { |
|
Email string |
|
Name string |
|
} |
|
|
|
type notebookConfig struct { |
|
Label string |
|
Repo string |
|
Serve map[string]int |
|
} |
|
|
|
func readConfigFile(path string) (*config, error) { |
|
var err error |
|
if path == "" { |
|
path = defaultConfigPath |
|
} |
|
path, err = expandPath(path) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
data, err := ioutil.ReadFile(path) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
c := &config{} |
|
err = c.load(data) |
|
return c, err |
|
} |
|
|
|
func readConfigData(data []byte) (*config, error) { |
|
c := &config{} |
|
err := c.load(data) |
|
return c, err |
|
} |
|
|
|
func (c *config) load(data []byte) error { |
|
var config map[string]interface{} |
|
err := yaml.Unmarshal(data, &config) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
if salt, ok := config["salt"]; ok { |
|
c.Salt = salt.(string) |
|
} |
|
|
|
if serve, ok := config["serve"]; ok { |
|
c.Serve = serve.(string) |
|
} |
|
|
|
if as, ok := config["authors"]; ok { |
|
auths := as.(map[interface{}]interface{}) |
|
for aemail, aname := range auths { |
|
c.Authors = append(c.Authors, &authorConfig{Email: aemail.(string), Name: aname.(string)}) |
|
} |
|
} |
|
|
|
if nbsv, ok := config["notebooks"]; ok { |
|
nbs := nbsv.(map[interface{}]interface{}) |
|
var labels []string |
|
for label := range nbs { |
|
labels = append(labels, label.(string)) |
|
} |
|
sort.Strings(labels) |
|
for _, label := range labels { |
|
nbconfig := ¬ebookConfig{Label: label, Serve: make(map[string]int)} |
|
|
|
nbo := nbs[label].(map[interface{}]interface{}) |
|
for option, v := range nbo { |
|
switch option.(string) { |
|
case "repo": |
|
nbconfig.Repo = v.(string) |
|
case "serve": |
|
nbsv := v.([]interface{}) |
|
for _, nbsvi := range nbsv { |
|
switch nbsvi.(type) { |
|
case string: |
|
nbconfig.Serve[nbsvi.(string)] = authorAccessRead |
|
case map[interface{}]interface{}: |
|
nbsvx := nbsvi.(map[interface{}]interface{}) |
|
for nbsvxi, nbsvxa := range nbsvx { |
|
access := -1 |
|
switch nbsvxa.(string) { |
|
case "read": |
|
access = authorAccessRead |
|
case "check": |
|
access = authorAccessCheck |
|
case "write": |
|
access = authorAccessWrite |
|
} |
|
if access == -1 { |
|
return errors.New(fmt.Sprintf("invalid serve configuration: invalid access level specified for %s (%s should be read/check/write)", nbsvxi, nbsvxa.(string))) |
|
} |
|
|
|
nbconfig.Serve[nbsvxi.(string)] = access |
|
} |
|
default: |
|
return errors.New(fmt.Sprintf("invalid serve configuration: %T", nbsvi)) |
|
} |
|
} |
|
} |
|
} |
|
|
|
if nbconfig.Repo == "" { |
|
return errors.New("invalid notebook configuration: no repo path supplied") |
|
} |
|
|
|
c.Notebooks = append(c.Notebooks, nbconfig) |
|
} |
|
} |
|
|
|
return nil |
|
}
|
|
|