happyDeliver/internal/app/cli_analyzer.go

103 lines
3.1 KiB
Go

// This file is part of the happyDeliver (R) project.
// Copyright (c) 2025 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package app
import (
"encoding/json"
"flag"
"fmt"
"io"
"log"
"strings"
"github.com/google/uuid"
"git.happydns.org/happyDeliver/internal/config"
"git.happydns.org/happyDeliver/pkg/analyzer"
)
// RunAnalyzer runs the standalone email analyzer (from stdin)
func RunAnalyzer(cfg *config.Config, args []string, reader io.Reader, writer io.Writer) error {
// Parse command-line flags
fs := flag.NewFlagSet("analyze", flag.ExitOnError)
jsonOutput := fs.Bool("json", false, "Output results as JSON")
if err := fs.Parse(args); err != nil {
return err
}
if err := cfg.Validate(); err != nil {
return err
}
log.Printf("Email analyzer ready, reading from stdin...")
// Read email from stdin
emailData, err := io.ReadAll(reader)
if err != nil {
return fmt.Errorf("failed to read email from stdin: %w", err)
}
// Create analyzer with configuration
emailAnalyzer := analyzer.NewEmailAnalyzer(cfg)
// Analyze the email (using a dummy test ID for standalone mode)
result, err := emailAnalyzer.AnalyzeEmailBytes(emailData, uuid.New())
if err != nil {
return fmt.Errorf("failed to analyze email: %w", err)
}
log.Printf("Analyzing email from: %s", result.Email.From)
// Output results
if *jsonOutput {
return outputJSON(result, writer)
}
return outputHumanReadable(result, emailAnalyzer, writer)
}
// outputJSON outputs the report as JSON
func outputJSON(result *analyzer.AnalysisResult, writer io.Writer) error {
reportJSON, err := json.MarshalIndent(result.Report, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal report: %w", err)
}
fmt.Fprintln(writer, string(reportJSON))
return nil
}
// outputHumanReadable outputs a human-readable summary
func outputHumanReadable(result *analyzer.AnalysisResult, emailAnalyzer *analyzer.EmailAnalyzer, writer io.Writer) error {
// Header
fmt.Fprintln(writer, "\n"+strings.Repeat("=", 70))
fmt.Fprintln(writer, "EMAIL DELIVERABILITY ANALYSIS REPORT")
fmt.Fprintln(writer, strings.Repeat("=", 70))
// Detailed checks
fmt.Fprintln(writer, "\n"+strings.Repeat("-", 70))
fmt.Fprintln(writer, "DETAILED CHECK RESULTS")
fmt.Fprintln(writer, strings.Repeat("-", 70))
// TODO
fmt.Fprintln(writer, "\n"+strings.Repeat("=", 70))
return nil
}