mail2couch/go/config/config.go
Ole-Morten Duesund 2ed5ce7ad2 docs: add keyword filtering feature request and implementation notes
- Add TODO comments in config structure for future keyword filtering
- Document planned subjectKeywords, senderKeywords, and recipientKeywords support
- Create TODO.md with detailed feature specification and use cases
- Update CLAUDE.md with keyword filtering in next steps

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 17:19:19 +02:00

115 lines
3.2 KiB
Go

package config
import (
"encoding/json"
"flag"
"fmt"
"os"
"path/filepath"
)
type Config struct {
CouchDb CouchDbConfig `json:"couchDb"`
MailSources []MailSource `json:"mailSources"`
}
type CouchDbConfig struct {
URL string `json:"url"`
User string `json:"user"`
Password string `json:"password"`
Database string `json:"database"`
}
type MailSource struct {
Name string `json:"name"`
Enabled bool `json:"enabled"`
Protocol string `json:"protocol"`
Host string `json:"host"`
Port int `json:"port"`
User string `json:"user"`
Password string `json:"password"`
Sync bool `json:"sync"`
FolderFilter FolderFilter `json:"folderFilter"`
MessageFilter MessageFilter `json:"messageFilter"`
}
type FolderFilter struct {
Include []string `json:"include"`
Exclude []string `json:"exclude"`
}
type MessageFilter struct {
Since string `json:"since,omitempty"`
// TODO: Add keyword filtering support
// SubjectKeywords []string `json:"subjectKeywords,omitempty"` // Filter by keywords in subject
// SenderKeywords []string `json:"senderKeywords,omitempty"` // Filter by keywords in sender addresses
// RecipientKeywords []string `json:"recipientKeywords,omitempty"` // Filter by keywords in recipient addresses
}
func LoadConfig(path string) (*Config, error) {
configFile, err := os.Open(path)
if err != nil {
return nil, err
}
defer configFile.Close()
var config Config
jsonParser := json.NewDecoder(configFile)
if err = jsonParser.Decode(&config); err != nil {
return nil, err
}
return &config, nil
}
// FindConfigFile searches for config.json in the following order:
// 1. Path specified by -config flag
// 2. ./config.json (current directory)
// 3. ~/.config/mail2couch/config.json (user config directory)
// 4. ~/.mail2couch.json (user home directory)
func FindConfigFile() (string, error) {
// Check for command line flag
configFlag := flag.String("config", "", "Path to configuration file")
flag.Parse()
if *configFlag != "" {
if _, err := os.Stat(*configFlag); err == nil {
return *configFlag, nil
}
return "", fmt.Errorf("specified config file not found: %s", *configFlag)
}
// List of possible config file locations in order of preference
candidates := []string{
"config.json", // Current directory
"config/config.json", // Config subdirectory
}
// Add user directory paths
if homeDir, err := os.UserHomeDir(); err == nil {
candidates = append(candidates,
filepath.Join(homeDir, ".config", "mail2couch", "config.json"),
filepath.Join(homeDir, ".mail2couch.json"),
)
}
// Try each candidate location
for _, candidate := range candidates {
if _, err := os.Stat(candidate); err == nil {
return candidate, nil
}
}
return "", fmt.Errorf("no configuration file found. Searched locations: %v", candidates)
}
// LoadConfigWithDiscovery loads configuration using automatic file discovery
func LoadConfigWithDiscovery() (*Config, error) {
configPath, err := FindConfigFile()
if err != nil {
return nil, err
}
fmt.Printf("Using configuration file: %s\n", configPath)
return LoadConfig(configPath)
}