// scholscan command-line tool // this is the main entry point, commands are implemented in cmds/ // and basic logic in core/ package main import ( "errors" "flag" "fmt" "os" "scholscan/cmds" "scholscan/core" ) func main() { if len(os.Args) < 2 { printHelp() os.Exit(1) } cmdName := os.Args[1] args := os.Args[2:] // handle the help stuff if cmdName == "help" || cmdName == "--help" || cmdName == "-h" { printHelp() return } // flag -> command var cmd core.Command switch cmdName { case "train": cmd = &cmds.TrainCommand{} case "scan": cmd = &cmds.ScanCommand{} case "serve": cmd = &cmds.ServeCommand{} default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n\n", cmdName) printHelp() os.Exit(1) } // init the command, then run it if err := cmd.Init(args); err != nil { if errors.Is(err, flag.ErrHelp) { os.Exit(0) } fmt.Fprintf(os.Stderr, "Error initializing %s command: %v\n", cmdName, err) os.Exit(1) } if err := cmd.Run(os.Stdin, os.Stdout); err != nil { fmt.Fprintf(os.Stderr, "Error running %s command: %v\n", cmdName, err) os.Exit(1) } } func printHelp() { fmt.Printf(`scholscan [arguments] A command-line tool for filtering articles based on learned user preferences. Commands: train Train a model from positives and RSS feeds scan Filter articles using a trained model serve Start HTTP server with filtered RSS and scoring API Usage: scholscan train POSITIVES_FILE --rss-feeds RSS_FEEDS_FILE > model.json scholscan scan --url RSS_URL --model MODEL > results.jsonl scholscan serve --model MODEL --rss-world RSS_FEEDS_FILE # Start server scholscan serve --title "My Custom ScholScan" # Custom title for web interface scholscan help # Show this help message Examples: scholscan train positives.jsonl --rss-feeds rss_world.txt > model.json scholscan scan --url "https://feeds.reuters.com/reuters/topNews" --model model.json scholscan serve --port 8080 --model model.json --rss-world rss_world.txt `) }