package main import ( "flag" "os" "path/filepath" "time" ) var config Config func main() { // Command-line flags portFlag := flag.Int("port", 0, "Port number to run the application (overrides config)") domainFlag := flag.String("domain", "", "Domain address for the application (overrides config)") skipConfigFlag := flag.Bool("skip-config-check", false, "Skip interactive prompts and load config.ini") // Parse command-line flags flag.Parse() if *skipConfigFlag { // Skip interactive configuration if _, err := os.Stat(configFilePath); err == nil { // Load from config file if it exists config = loadConfig() } else { // Use defaults if config file does not exist config = defaultConfig saveConfig(config) // Save the defaults to config.ini printInfo("Configuration saved to %s", configFilePath) } } else { // Initialize configuration interactively or from config file err := initConfig() if err != nil { printErr("Error during initialization: %v", err) return } } // Override with command-line arguments if provided if *portFlag != 0 { config.Port = *portFlag } if *domainFlag != "" { config.Domain = *domainFlag } loadNodeConfig() if config.AuthCode == "" { config.AuthCode = generateStrongRandomString(64) printInfo("Generated connection code: %s\n", config.AuthCode) saveConfig(config) } // Generate Host ID hostID, nodeErr := generateHostID() if nodeErr != nil { printErr("Failed to generate host ID: %v", nodeErr) } config.PeerID = hostID InitializeLanguage("en") // Initialize language before generating OpenSearch generateOpenSearchXML(config) // Start the node client only if NodesEnabled is true if config.NodesEnabled { go startNodeClient() printInfo("Node client started.") } else { printInfo("Node client is disabled.") } // Check if the cache directory exists when caching is enabled if config.DriveCacheEnabled { if _, err := os.Stat(config.DriveCache.Path); os.IsNotExist(err) { printErr("Error: Drive cache is enabled, but cache directory '%s' does not exist.\n", config.DriveCache.Path) os.Exit(1) // Exit with a non-zero status to indicate an error } } // Start periodic cleanup of expired cache files if config.DriveCacheEnabled { go cleanExpiredCachedImages() printInfo("Drive cache started.") } else { printInfo("Drive cache is disabled.") } // Start periodic cleanup of expired cache files if config.RamCacheEnabled { resultsCache = NewResultsCache() geocodeCache = NewGeocodeCache() printInfo("RAM cache started.") } else { printInfo("RAM cache is disabled.") } // Init indexer if config.IndexerEnabled { if err := downloadAndSetupDomainsCSV(); err != nil { printErr("Failed to set up domains.csv: %v", err) return } webCrawlerInit() err := InitIndex() if err != nil { printErr("Failed to initialize index:", err) } // Start periodic indexing (every 2 minutes) dataFilePath := filepath.Join(config.DriveCache.Path, "data_to_index.txt") startPeriodicIndexing(dataFilePath, 2*time.Minute) printInfo("Indexer is enabled.") } else { printInfo("Indexer is disabled.") } runServer() }