updated 'config.ini'
This commit is contained in:
parent
28f71271d7
commit
be4f86580e
13 changed files with 635 additions and 208 deletions
418
config.go
418
config.go
|
@ -2,20 +2,74 @@ package main
|
|||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/shirou/gopsutil/mem"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
var configFilePath = "./config.ini"
|
||||
|
||||
type CacheConfig struct {
|
||||
Duration time.Duration
|
||||
MaxUsageBytes uint64 // Store as bytes for uniformity
|
||||
Path string
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Port int // Added
|
||||
AuthCode string // Added
|
||||
PeerID string // Added
|
||||
Peers []string
|
||||
Domain string // Added
|
||||
NodesEnabled bool // Added
|
||||
CrawlerEnabled bool // Added
|
||||
WebsiteEnabled bool // Added
|
||||
RamCacheEnabled bool
|
||||
DriveCacheEnabled bool // Added
|
||||
LogLevel int // Added
|
||||
|
||||
DriveCache CacheConfig
|
||||
RamCache CacheConfig
|
||||
}
|
||||
|
||||
var defaultConfig = Config{
|
||||
Port: 5000,
|
||||
Domain: "localhost",
|
||||
Peers: []string{},
|
||||
AuthCode: generateStrongRandomString(64),
|
||||
NodesEnabled: false,
|
||||
CrawlerEnabled: true,
|
||||
WebsiteEnabled: true,
|
||||
RamCacheEnabled: true,
|
||||
DriveCacheEnabled: false,
|
||||
LogLevel: 1,
|
||||
DriveCache: CacheConfig{
|
||||
Duration: 48 * time.Hour, // Added
|
||||
Path: "./cache", // Added
|
||||
MaxUsageBytes: parseMaxUsageDrive("90 %", config.DriveCache.Path), // Added
|
||||
},
|
||||
RamCache: CacheConfig{
|
||||
Duration: 6 * time.Hour, // Added
|
||||
MaxUsageBytes: parseMaxUsageRam("90%"), // Added
|
||||
},
|
||||
}
|
||||
|
||||
func initConfig() error {
|
||||
// Check if the configuration file exists
|
||||
if _, err := os.Stat(configFilePath); os.IsNotExist(err) {
|
||||
// If not, create a new configuration
|
||||
return createConfig()
|
||||
}
|
||||
|
||||
printInfo("Configuration file already exists.")
|
||||
printInfo("Configuration file already exists. Loading configuration.")
|
||||
// Load existing configuration
|
||||
config = loadConfig()
|
||||
return nil
|
||||
}
|
||||
|
@ -23,60 +77,180 @@ func initConfig() error {
|
|||
func createConfig() error {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
|
||||
printMessage("Configuration file not found.")
|
||||
printMessage("Do you want to use default values? (yes/no): ")
|
||||
printMessage("Configuration file not found. Let's set it up.")
|
||||
printMessage("Do you want to use default values? (yes/NO): ")
|
||||
useDefaults, _ := reader.ReadString('\n')
|
||||
|
||||
if strings.TrimSpace(useDefaults) != "yes" {
|
||||
if strings.TrimSpace(strings.ToLower(useDefaults)) != "yes" {
|
||||
// Server settings
|
||||
printMessage("Enter port (default 5000): ")
|
||||
portStr, _ := reader.ReadString('\n')
|
||||
if portStr != "\n" {
|
||||
port, err := strconv.Atoi(strings.TrimSpace(portStr))
|
||||
if err != nil {
|
||||
config.Port = 5000
|
||||
} else {
|
||||
portStr = strings.TrimSpace(portStr)
|
||||
if portStr != "" {
|
||||
port, err := strconv.Atoi(portStr)
|
||||
if err == nil {
|
||||
config.Port = port
|
||||
} else {
|
||||
printWarn("Invalid port, using default (5000).")
|
||||
config.Port = defaultConfig.Port
|
||||
}
|
||||
} else {
|
||||
config.Port = defaultConfig.Port
|
||||
}
|
||||
|
||||
printMessage("Enter your domain address (default localhost): ")
|
||||
domain, _ := reader.ReadString('\n')
|
||||
if domain != "\n" {
|
||||
config.Domain = strings.TrimSpace(domain)
|
||||
config.Domain = strings.TrimSpace(domain)
|
||||
if config.Domain == "" {
|
||||
config.Domain = defaultConfig.Domain
|
||||
}
|
||||
|
||||
// Cache settings
|
||||
printMessage("Would you like to configure Cache settings (yes/NO): ")
|
||||
configureCache, _ := reader.ReadString('\n')
|
||||
if strings.TrimSpace(strings.ToLower(configureCache)) == "yes" {
|
||||
// RamCache settings
|
||||
printMessage("Enter duration to store results in Ram (default 6h): ")
|
||||
ramDurationStr, _ := reader.ReadString('\n')
|
||||
ramDurationStr = strings.TrimSpace(ramDurationStr)
|
||||
if ramDurationStr == "" {
|
||||
config.RamCache.Duration = defaultConfig.RamCache.Duration
|
||||
config.RamCacheEnabled = true
|
||||
} else if ramDurationStr == "0h" {
|
||||
config.RamCacheEnabled = false
|
||||
} else {
|
||||
ramDuration, err := time.ParseDuration(ramDurationStr)
|
||||
if err != nil {
|
||||
printWarn("Invalid duration, using default (6h).")
|
||||
config.RamCache.Duration = defaultConfig.RamCache.Duration
|
||||
config.RamCacheEnabled = true
|
||||
} else {
|
||||
config.RamCache.Duration = ramDuration
|
||||
config.RamCacheEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
printMessage("Enter RamCache max usage, e.g., 2 GiB or 80%% (default 90%%): ")
|
||||
ramMaxUsage, _ := reader.ReadString('\n')
|
||||
ramMaxUsage = strings.TrimSpace(ramMaxUsage)
|
||||
if ramMaxUsage == "" {
|
||||
config.RamCache.MaxUsageBytes = defaultConfig.RamCache.MaxUsageBytes
|
||||
} else if ramMaxUsage == "0" || parseMaxUsageRam(ramMaxUsage) == 0 {
|
||||
config.RamCacheEnabled = false
|
||||
} else {
|
||||
config.RamCache.MaxUsageBytes = parseMaxUsageRam(ramMaxUsage)
|
||||
if config.RamCache.MaxUsageBytes == 0 {
|
||||
printWarn("Invalid RamCache max usage, using default (90%%).")
|
||||
config.RamCache.MaxUsageBytes = defaultConfig.RamCache.MaxUsageBytes
|
||||
}
|
||||
}
|
||||
|
||||
// DriveCache settings
|
||||
printMessage("Enter duration to store results in DriveCache (default 0h): ")
|
||||
driveDurationStr, _ := reader.ReadString('\n')
|
||||
driveDurationStr = strings.TrimSpace(driveDurationStr)
|
||||
if driveDurationStr == "" {
|
||||
config.DriveCache.Duration = defaultConfig.DriveCache.Duration
|
||||
config.DriveCacheEnabled = config.DriveCache.Duration > 0
|
||||
} else if driveDurationStr == "0h" {
|
||||
config.DriveCacheEnabled = false
|
||||
} else {
|
||||
driveDuration, err := time.ParseDuration(driveDurationStr)
|
||||
if err != nil {
|
||||
printWarn("Invalid duration, using default (48h).")
|
||||
config.DriveCache.Duration = defaultConfig.DriveCache.Duration
|
||||
config.DriveCacheEnabled = config.DriveCache.Duration > 0
|
||||
} else {
|
||||
config.DriveCache.Duration = driveDuration
|
||||
config.DriveCacheEnabled = config.DriveCache.Duration > 0
|
||||
}
|
||||
}
|
||||
|
||||
printMessage("Enter DriveCache path (default ./cache): ")
|
||||
drivePath, _ := reader.ReadString('\n')
|
||||
drivePath = strings.TrimSpace(drivePath)
|
||||
if drivePath == "" {
|
||||
config.DriveCache.Path = defaultConfig.DriveCache.Path
|
||||
} else {
|
||||
config.DriveCache.Path = drivePath
|
||||
}
|
||||
|
||||
printMessage("Enter DriveCache max usage, e.g., 2 GiB or 90%% (default 90%%): ")
|
||||
driveMaxUsage, _ := reader.ReadString('\n')
|
||||
driveMaxUsage = strings.TrimSpace(driveMaxUsage)
|
||||
if driveMaxUsage == "" {
|
||||
config.DriveCache.MaxUsageBytes = defaultConfig.DriveCache.MaxUsageBytes
|
||||
} else if driveMaxUsage == "0" || parseMaxUsageDrive(driveMaxUsage, drivePath) == 0 {
|
||||
config.DriveCacheEnabled = false
|
||||
} else {
|
||||
config.DriveCache.MaxUsageBytes = parseMaxUsageDrive(driveMaxUsage, drivePath)
|
||||
if config.DriveCache.MaxUsageBytes == 0 {
|
||||
printWarn("Invalid DriveCache max usage, using default (1 TiB).")
|
||||
config.DriveCache.MaxUsageBytes = defaultConfig.DriveCache.MaxUsageBytes
|
||||
}
|
||||
}
|
||||
} else {
|
||||
printInfo("Cache settings skipped. Using default values.")
|
||||
config.RamCache = defaultConfig.RamCache
|
||||
config.DriveCache = defaultConfig.DriveCache
|
||||
}
|
||||
} else {
|
||||
// Use default configuration
|
||||
config = defaultConfig
|
||||
}
|
||||
|
||||
// Generate AuthCode if missing
|
||||
if config.AuthCode == "" {
|
||||
config.AuthCode = generateStrongRandomString(64)
|
||||
printMessage("Generated connection code: %s\n", config.AuthCode)
|
||||
}
|
||||
|
||||
config.NodesEnabled = len(config.Peers) > 0
|
||||
config.CrawlerEnabled = true
|
||||
config.WebsiteEnabled = true
|
||||
config.LogLevel = 1
|
||||
// Set other default values
|
||||
config.NodesEnabled = defaultConfig.NodesEnabled
|
||||
config.CrawlerEnabled = defaultConfig.CrawlerEnabled
|
||||
config.WebsiteEnabled = defaultConfig.WebsiteEnabled
|
||||
config.LogLevel = defaultConfig.LogLevel
|
||||
|
||||
// Save configuration to file
|
||||
saveConfig(config)
|
||||
printInfo("Configuration saved successfully.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveConfig(config Config) {
|
||||
cfg := ini.Empty()
|
||||
sec := cfg.Section("")
|
||||
sec.Key("Port").SetValue(strconv.Itoa(config.Port))
|
||||
sec.Key("AuthCode").SetValue(config.AuthCode)
|
||||
sec.Key("PeerID").SetValue(config.PeerID)
|
||||
|
||||
peers := strings.Join(config.Peers, ",")
|
||||
sec.Key("Peers").SetValue(peers)
|
||||
// Server section
|
||||
sec := cfg.Section("Server")
|
||||
sec.Key("Port").SetValue(strconv.Itoa(config.Port))
|
||||
sec.Key("Domain").SetValue(config.Domain)
|
||||
sec.Key("NodesEnabled").SetValue(strconv.FormatBool(config.NodesEnabled))
|
||||
sec.Key("CrawlerEnabled").SetValue(strconv.FormatBool(config.CrawlerEnabled))
|
||||
sec.Key("WebsiteEnabled").SetValue(strconv.FormatBool(config.WebsiteEnabled))
|
||||
sec.Key("LogLevel").SetValue(strconv.Itoa(config.LogLevel))
|
||||
sec.Key("HardCacheDuration").SetValue(config.HardCacheDuration.String())
|
||||
|
||||
// Peers section
|
||||
peersSec := cfg.Section("Peers")
|
||||
peersSec.Key("AuthCode").SetValue(config.AuthCode)
|
||||
peersSec.Key("PeerID").SetValue(config.PeerID)
|
||||
peersSec.Key("Peers").SetValue(strings.Join(config.Peers, ","))
|
||||
|
||||
// Features section
|
||||
featuresSec := cfg.Section("Features")
|
||||
featuresSec.Key("Nodes").SetValue(strconv.FormatBool(config.NodesEnabled))
|
||||
featuresSec.Key("Crawler").SetValue(strconv.FormatBool(config.CrawlerEnabled))
|
||||
featuresSec.Key("Website").SetValue(strconv.FormatBool(config.WebsiteEnabled))
|
||||
featuresSec.Key("RamCache").SetValue(strconv.FormatBool(config.RamCacheEnabled))
|
||||
featuresSec.Key("DriveCache").SetValue(strconv.FormatBool(config.DriveCacheEnabled))
|
||||
|
||||
// DriveCache section
|
||||
driveSec := cfg.Section("DriveCache")
|
||||
driveSec.Key("Duration").SetValue(config.DriveCache.Duration.String())
|
||||
driveSec.Key("MaxUsage").SetValue(formatMaxUsage(config.DriveCache.MaxUsageBytes))
|
||||
driveSec.Key("Path").SetValue(config.DriveCache.Path)
|
||||
// driveSec.Key("MaxConcurrentDownloads.Thumbnail").SetValue(strconv.Itoa(config.DriveCache.MaxConcurrentThumbnailDownloads))
|
||||
|
||||
// RamCache section
|
||||
ramSec := cfg.Section("RamCache")
|
||||
ramSec.Key("Duration").SetValue(config.RamCache.Duration.String())
|
||||
ramSec.Key("MaxUsage").SetValue(formatMaxUsage(config.RamCache.MaxUsageBytes))
|
||||
|
||||
err := cfg.SaveTo(configFilePath)
|
||||
if err != nil {
|
||||
|
@ -90,73 +264,153 @@ func loadConfig() Config {
|
|||
printErr("Error opening config file: %v", err)
|
||||
}
|
||||
|
||||
port, err := cfg.Section("").Key("Port").Int()
|
||||
if err != nil || port == 0 {
|
||||
port = 5000 // Default to 5000 if not set or error
|
||||
}
|
||||
// Server
|
||||
port, _ := cfg.Section("Server").Key("Port").Int()
|
||||
domain := cfg.Section("Server").Key("Domain").String()
|
||||
logLevel, _ := cfg.Section("Server").Key("LogLevel").Int()
|
||||
|
||||
peersStr := cfg.Section("").Key("Peers").String()
|
||||
var peers []string
|
||||
if peersStr != "" {
|
||||
peers = strings.Split(peersStr, ",")
|
||||
for i, peer := range peers {
|
||||
peers[i] = addProtocol(peer)
|
||||
}
|
||||
}
|
||||
// Peers
|
||||
authCode := cfg.Section("Peers").Key("AuthCode").String()
|
||||
peersStr := cfg.Section("Peers").Key("Peers").String()
|
||||
peers := strings.Split(peersStr, ",")
|
||||
|
||||
domain := cfg.Section("").Key("Domain").String()
|
||||
if domain == "" {
|
||||
domain = "localhost" // Default to localhost if not set
|
||||
}
|
||||
// Features
|
||||
nodesEnabled, _ := cfg.Section("Features").Key("Nodes").Bool()
|
||||
crawlerEnabled, _ := cfg.Section("Features").Key("Crawler").Bool()
|
||||
websiteEnabled, _ := cfg.Section("Features").Key("Website").Bool()
|
||||
ramCacheEnabled, _ := cfg.Section("Features").Key("RamCache").Bool()
|
||||
driveCacheEnabled, _ := cfg.Section("Features").Key("DriveCache").Bool()
|
||||
|
||||
nodesEnabled, err := cfg.Section("").Key("NodesEnabled").Bool()
|
||||
if err != nil { // If NodesEnabled is not found in config
|
||||
nodesEnabled = len(peers) > 0 // Enable nodes if peers are configured
|
||||
}
|
||||
// DriveCache
|
||||
driveDuration, _ := time.ParseDuration(cfg.Section("DriveCache").Key("Duration").String())
|
||||
drivePath := cfg.Section("DriveCache").Key("Path").String()
|
||||
driveMaxUsage := parseMaxUsageDrive(cfg.Section("DriveCache").Key("MaxUsage").String(), drivePath)
|
||||
// maxConcurrentDownloads, _ := cfg.Section("DriveCache").Key("MaxConcurrentDownloads.Thumbnail").Int()
|
||||
// if maxConcurrentDownloads == 0 {
|
||||
// maxConcurrentDownloads = defaultConfig.DriveCache.MaxConcurrentThumbnailDownloads
|
||||
// }
|
||||
|
||||
crawlerEnabled, err := cfg.Section("").Key("CrawlerEnabled").Bool()
|
||||
if err != nil { // Default to true if not found
|
||||
crawlerEnabled = true
|
||||
}
|
||||
// RamCache
|
||||
ramDuration, _ := time.ParseDuration(cfg.Section("RamCache").Key("Duration").String())
|
||||
ramMaxUsage := parseMaxUsageRam(cfg.Section("RamCache").Key("MaxUsage").String())
|
||||
|
||||
websiteEnabled, err := cfg.Section("").Key("WebsiteEnabled").Bool()
|
||||
if err != nil { // Default to true if not found
|
||||
websiteEnabled = true
|
||||
}
|
||||
|
||||
logLevel, err := cfg.Section("").Key("LogLevel").Int()
|
||||
if err != nil || logLevel < 0 || logLevel > 4 { // Default to 1 if not found or out of range
|
||||
logLevel = 1
|
||||
}
|
||||
|
||||
// Read HardCacheDuration
|
||||
hardCacheStr := cfg.Section("").Key("HardCacheDuration").String()
|
||||
var hardCacheDuration time.Duration
|
||||
if hardCacheStr != "" {
|
||||
duration, err := time.ParseDuration(hardCacheStr)
|
||||
if err != nil {
|
||||
printWarn("Invalid HardCacheDuration format, defaulting to 0: %v", err)
|
||||
hardCacheDuration = 0
|
||||
} else {
|
||||
hardCacheDuration = duration
|
||||
}
|
||||
} else {
|
||||
hardCacheDuration = 0 // Default to 0 if not set
|
||||
}
|
||||
|
||||
config = Config{
|
||||
return Config{
|
||||
Port: port,
|
||||
AuthCode: cfg.Section("").Key("AuthCode").String(),
|
||||
PeerID: cfg.Section("").Key("PeerID").String(),
|
||||
Peers: peers,
|
||||
Domain: domain,
|
||||
LogLevel: logLevel,
|
||||
AuthCode: authCode, // Assign AuthCode here
|
||||
Peers: peers,
|
||||
NodesEnabled: nodesEnabled,
|
||||
CrawlerEnabled: crawlerEnabled,
|
||||
WebsiteEnabled: websiteEnabled,
|
||||
LogLevel: logLevel,
|
||||
HardCacheDuration: hardCacheDuration,
|
||||
HardCacheEnabled: hardCacheDuration != 0,
|
||||
RamCacheEnabled: ramCacheEnabled,
|
||||
DriveCacheEnabled: driveCacheEnabled,
|
||||
DriveCache: CacheConfig{
|
||||
Duration: driveDuration,
|
||||
MaxUsageBytes: driveMaxUsage,
|
||||
Path: drivePath,
|
||||
// MaxConcurrentThumbnailDownloads: maxConcurrentDownloads,
|
||||
},
|
||||
RamCache: CacheConfig{
|
||||
Duration: ramDuration,
|
||||
MaxUsageBytes: ramMaxUsage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to parse MaxUsage string into bytes
|
||||
func parseMaxUsageRam(value string) uint64 {
|
||||
const GiB = 1024 * 1024 * 1024
|
||||
value = strings.TrimSpace(value)
|
||||
valueNoSpaces := strings.ReplaceAll(value, " ", "")
|
||||
|
||||
if strings.HasSuffix(valueNoSpaces, "%") {
|
||||
percentStr := strings.TrimSuffix(valueNoSpaces, "%")
|
||||
percent, err := strconv.ParseFloat(percentStr, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
totalMem := getTotalMemory()
|
||||
return uint64(float64(totalMem) * (percent / 100))
|
||||
} else if strings.HasSuffix(valueNoSpaces, "GiB") {
|
||||
sizeStr := strings.TrimSuffix(valueNoSpaces, "GiB")
|
||||
size, err := strconv.ParseFloat(sizeStr, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint64(size * GiB)
|
||||
}
|
||||
|
||||
return config
|
||||
return 0
|
||||
}
|
||||
|
||||
// Helper to parse MaxUsage string into bytes based on drive space
|
||||
func parseMaxUsageDrive(value string, cachePath string) uint64 {
|
||||
const GiB = 1024 * 1024 * 1024
|
||||
value = strings.TrimSpace(value)
|
||||
valueNoSpaces := strings.ReplaceAll(value, " ", "")
|
||||
|
||||
totalDiskSpace := getTotalDiskSpace(cachePath)
|
||||
if totalDiskSpace == 0 {
|
||||
printErr("Failed to retrieve disk space for path: %s", cachePath)
|
||||
return 0
|
||||
}
|
||||
|
||||
if strings.HasSuffix(valueNoSpaces, "%") {
|
||||
percentStr := strings.TrimSuffix(valueNoSpaces, "%")
|
||||
percent, err := strconv.ParseFloat(percentStr, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint64(float64(totalDiskSpace) * (percent / 100))
|
||||
} else if strings.HasSuffix(valueNoSpaces, "GiB") {
|
||||
sizeStr := strings.TrimSuffix(valueNoSpaces, "GiB")
|
||||
size, err := strconv.ParseFloat(sizeStr, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return uint64(size * GiB)
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Get total disk space of the system where cachePath resides
|
||||
func getTotalDiskSpace(cachePath string) uint64 {
|
||||
var stat syscall.Statfs_t
|
||||
|
||||
// Get filesystem stats for the cache path
|
||||
absPath, err := filepath.Abs(cachePath)
|
||||
if err != nil {
|
||||
printErr("Failed to resolve absolute path for: %s", cachePath)
|
||||
return 0
|
||||
}
|
||||
|
||||
err = syscall.Statfs(absPath, &stat)
|
||||
if err != nil {
|
||||
printErr("Failed to retrieve filesystem stats for: %s", absPath)
|
||||
return 0
|
||||
}
|
||||
|
||||
// Total disk space in bytes
|
||||
return stat.Blocks * uint64(stat.Bsize)
|
||||
}
|
||||
|
||||
// Helper to format bytes back to human-readable string
|
||||
func formatMaxUsage(bytes uint64) string {
|
||||
const GiB = 1024 * 1024 * 1024
|
||||
if bytes >= GiB {
|
||||
return fmt.Sprintf("%.2fGiB", float64(bytes)/GiB)
|
||||
}
|
||||
return fmt.Sprintf("%dbytes", bytes)
|
||||
}
|
||||
|
||||
// Get total memory of the system
|
||||
func getTotalMemory() uint64 {
|
||||
v, err := mem.VirtualMemory()
|
||||
if err != nil {
|
||||
printErr("Failed to retrieve system memory: %v", err)
|
||||
return 0
|
||||
}
|
||||
return v.Total
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue