cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm
leaflet
readability
golang
1package store
2
3import (
4 "os"
5 "path/filepath"
6
7 "github.com/BurntSushi/toml"
8 "github.com/stormlightlabs/noteleaf/internal/shared"
9)
10
11// Config holds application configuration
12type Config struct {
13 DatabasePath string `toml:"database_path,omitempty"`
14 DataDir string `toml:"data_dir,omitempty"`
15 DateFormat string `toml:"date_format"`
16 ColorScheme string `toml:"color_scheme"`
17 DefaultView string `toml:"default_view"`
18 DefaultPriority string `toml:"default_priority,omitempty"`
19 Editor string `toml:"editor,omitempty"`
20 ArticlesDir string `toml:"articles_dir,omitempty"`
21 NotesDir string `toml:"notes_dir,omitempty"`
22 AutoArchive bool `toml:"auto_archive"`
23 SyncEnabled bool `toml:"sync_enabled"`
24 SyncEndpoint string `toml:"sync_endpoint,omitempty"`
25 SyncToken string `toml:"sync_token,omitempty"`
26 ExportFormat string `toml:"export_format"`
27 MovieAPIKey string `toml:"movie_api_key,omitempty"`
28 BookAPIKey string `toml:"book_api_key,omitempty"`
29
30 ATProtoDID string `toml:"atproto_did,omitempty"`
31 ATProtoHandle string `toml:"atproto_handle,omitempty"`
32 ATProtoAccessJWT string `toml:"atproto_access_jwt,omitempty"`
33 ATProtoRefreshJWT string `toml:"atproto_refresh_jwt,omitempty"`
34 ATProtoPDSURL string `toml:"atproto_pds_url,omitempty"`
35 ATProtoExpiresAt string `toml:"atproto_expires_at,omitempty"` // ISO8601 timestamp
36}
37
38// DefaultConfig returns a configuration with sensible defaults
39func DefaultConfig() *Config {
40 return &Config{
41 DateFormat: "2006-01-02",
42 ColorScheme: "default",
43 DefaultView: "list",
44 AutoArchive: false,
45 SyncEnabled: false,
46 ExportFormat: "json",
47 }
48}
49
50// LoadConfig loads configuration from the config directory or NOTELEAF_CONFIG path
51var LoadConfig = func() (*Config, error) {
52 var configPath string
53
54 if envConfigPath := os.Getenv("NOTELEAF_CONFIG"); envConfigPath != "" {
55 configPath = envConfigPath
56 } else {
57 configDir, err := GetConfigDir()
58 if err != nil {
59 return nil, shared.ConfigError("failed to get config directory", err)
60 }
61 configPath = filepath.Join(configDir, ".noteleaf.conf.toml")
62 }
63
64 if _, err := os.Stat(configPath); os.IsNotExist(err) {
65 config := DefaultConfig()
66 if err := SaveConfig(config); err != nil {
67 return nil, shared.ConfigError("failed to create default config", err)
68 }
69 return config, nil
70 }
71
72 data, err := os.ReadFile(configPath)
73 if err != nil {
74 return nil, shared.ConfigError("failed to read config file", err)
75 }
76
77 config := DefaultConfig()
78 if err := toml.Unmarshal(data, config); err != nil {
79 return nil, shared.ConfigError("failed to parse config file", err)
80 }
81
82 return config, nil
83}
84
85// SaveConfig saves the configuration to the config directory or NOTELEAF_CONFIG path
86func SaveConfig(config *Config) error {
87 var configPath string
88
89 if envConfigPath := os.Getenv("NOTELEAF_CONFIG"); envConfigPath != "" {
90 configPath = envConfigPath
91 configDir := filepath.Dir(configPath)
92 if err := os.MkdirAll(configDir, 0755); err != nil {
93 return shared.ConfigError("failed to create config directory", err)
94 }
95 } else {
96 configDir, err := GetConfigDir()
97 if err != nil {
98 return shared.ConfigError("failed to get config directory", err)
99 }
100 configPath = filepath.Join(configDir, ".noteleaf.conf.toml")
101 }
102
103 data, err := toml.Marshal(config)
104 if err != nil {
105 return shared.ConfigError("failed to marshal config", err)
106 }
107
108 if err := os.WriteFile(configPath, data, 0644); err != nil {
109 return shared.ConfigError("failed to write config file", err)
110 }
111
112 return nil
113}
114
115// GetConfigPath returns the path to the configuration file
116func GetConfigPath() (string, error) {
117 if envConfigPath := os.Getenv("NOTELEAF_CONFIG"); envConfigPath != "" {
118 return envConfigPath, nil
119 }
120
121 configDir, err := GetConfigDir()
122 if err != nil {
123 return "", err
124 }
125 return filepath.Join(configDir, ".noteleaf.conf.toml"), nil
126}