2018-01-10 01:18:19 +01:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2018-01-10 03:24:50 +01:00
|
|
|
"fmt"
|
2018-01-10 01:18:19 +01:00
|
|
|
"path"
|
2018-01-10 03:24:50 +01:00
|
|
|
"strings"
|
2018-01-10 01:18:19 +01:00
|
|
|
"unicode"
|
2018-01-10 17:19:45 +01:00
|
|
|
|
|
|
|
"github.com/go-ini/ini"
|
|
|
|
"github.com/kyoh86/xdg"
|
2018-01-10 01:18:19 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
type UIConfig struct {
|
|
|
|
IndexFormat string
|
|
|
|
TimestampFormat string
|
|
|
|
ShowHeaders []string `delim:","`
|
|
|
|
LoadingFrames []string `delim:","`
|
|
|
|
RenderAccountTabs string
|
|
|
|
SidebarWidth int
|
|
|
|
PreviewHeight int
|
|
|
|
EmptyMessage string
|
|
|
|
}
|
|
|
|
|
|
|
|
type AccountConfig struct {
|
2018-01-10 02:39:00 +01:00
|
|
|
Name string
|
|
|
|
Source string
|
|
|
|
Folders []string
|
|
|
|
Params map[string]string
|
2018-01-10 01:18:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type AercConfig struct {
|
|
|
|
Ini *ini.File `ini:"-"`
|
|
|
|
Accounts []AccountConfig `ini:"-"`
|
|
|
|
Ui UIConfig
|
|
|
|
}
|
|
|
|
|
|
|
|
// Input: TimestampFormat
|
|
|
|
// Output: timestamp-format
|
|
|
|
func mapName(raw string) string {
|
|
|
|
newstr := make([]rune, 0, len(raw))
|
|
|
|
for i, chr := range raw {
|
|
|
|
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
|
|
|
|
if i > 0 {
|
|
|
|
newstr = append(newstr, '-')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newstr = append(newstr, unicode.ToLower(chr))
|
|
|
|
}
|
|
|
|
return string(newstr)
|
|
|
|
}
|
|
|
|
|
2018-01-10 03:24:50 +01:00
|
|
|
func loadAccountConfig(path string) ([]AccountConfig, error) {
|
2018-01-10 17:19:45 +01:00
|
|
|
file, err := ini.Load(path)
|
|
|
|
if err != nil {
|
2018-01-10 03:24:50 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
file.NameMapper = mapName
|
2018-01-10 17:19:45 +01:00
|
|
|
|
|
|
|
var accounts []AccountConfig
|
2018-01-10 03:24:50 +01:00
|
|
|
for _, _sec := range file.SectionStrings() {
|
|
|
|
if _sec == "DEFAULT" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
sec := file.Section(_sec)
|
|
|
|
account := AccountConfig{Name: _sec}
|
|
|
|
if err = sec.MapTo(&account); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
for key, val := range sec.KeysHash() {
|
|
|
|
if key == "source" {
|
|
|
|
account.Source = val
|
|
|
|
} else if key == "folders" {
|
|
|
|
account.Folders = strings.Split(val, ",")
|
|
|
|
} else if key != "name" {
|
|
|
|
account.Params[key] = val
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if account.Source == "" {
|
|
|
|
return nil, fmt.Errorf("Expected source for account %s", _sec)
|
|
|
|
}
|
|
|
|
accounts = append(accounts, account)
|
|
|
|
}
|
|
|
|
return accounts, nil
|
|
|
|
}
|
|
|
|
|
2018-01-10 01:18:19 +01:00
|
|
|
func LoadConfig(root *string) (*AercConfig, error) {
|
|
|
|
if root == nil {
|
|
|
|
_root := path.Join(xdg.ConfigHome(), "aerc")
|
|
|
|
root = &_root
|
|
|
|
}
|
2018-01-10 17:19:45 +01:00
|
|
|
file, err := ini.Load(path.Join(*root, "aerc.conf"))
|
|
|
|
if err != nil {
|
2018-01-10 01:18:19 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
file.NameMapper = mapName
|
|
|
|
config := &AercConfig{
|
|
|
|
Ini: file,
|
|
|
|
Ui: UIConfig{
|
|
|
|
IndexFormat: "%4C %Z %D %-17.17n %s",
|
|
|
|
TimestampFormat: "%F %l:%M %p",
|
|
|
|
ShowHeaders: []string{
|
|
|
|
"From", "To", "Cc", "Bcc", "Subject", "Date",
|
|
|
|
},
|
|
|
|
LoadingFrames: []string{
|
|
|
|
"[..] ", " [..] ", " [..]", " [..] ",
|
|
|
|
},
|
|
|
|
RenderAccountTabs: "auto",
|
|
|
|
SidebarWidth: 20,
|
|
|
|
PreviewHeight: 12,
|
|
|
|
EmptyMessage: "(no messages)",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
if ui, err := file.GetSection("ui"); err != nil {
|
|
|
|
ui.MapTo(config.Ui)
|
|
|
|
}
|
2018-01-10 03:24:50 +01:00
|
|
|
accountsPath := path.Join(*root, "accounts.conf")
|
|
|
|
if accounts, err := loadAccountConfig(accountsPath); err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else {
|
|
|
|
config.Accounts = accounts
|
|
|
|
}
|
2018-01-10 01:18:19 +01:00
|
|
|
return config, nil
|
|
|
|
}
|