Files

152 lines
4.0 KiB
Go
Raw Permalink Normal View History

2026-03-11 09:01:45 +00:00
package exporter
import (
"encoding/csv"
"encoding/json"
"fmt"
"os"
"strings"
"time"
"bargain-scraper/internal/models"
)
type Exporter struct{}
func New() *Exporter {
return &Exporter{}
}
func (e *Exporter) ExportToJSON(products []models.StorageProduct, filename string) error {
if filename == "" {
filename = fmt.Sprintf("storage_products_%s.json", time.Now().Format("2006-01-02_150405"))
}
data, err := json.MarshalIndent(products, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal JSON: %w", err)
}
err = os.WriteFile(filename, data, 0644)
if err != nil {
return fmt.Errorf("failed to write JSON file: %w", err)
}
return nil
}
func (e *Exporter) ExportToCSV(products []models.StorageProduct, filename string) error {
if filename == "" {
filename = fmt.Sprintf("storage_products_%s.csv", time.Now().Format("2006-01-02_150405"))
}
file, err := os.Create(filename)
if err != nil {
return fmt.Errorf("failed to create CSV file: %w", err)
}
defer file.Close()
writer := csv.NewWriter(file)
defer writer.Flush()
headers := []string{"ID", "Name", "Price", "Capacity", "Interface", "FormFactor", "Brand", "PartNumber", "StockStatus", "URL", "ScrapedAt"}
if err := writer.Write(headers); err != nil {
return fmt.Errorf("failed to write CSV headers: %w", err)
}
for _, p := range products {
row := []string{
p.ID,
p.Name,
p.Price,
p.Capacity,
p.Interface,
p.FormFactor,
p.Brand,
p.PartNumber,
p.StockStatus,
p.URL,
p.ScrapedAt.Format(time.RFC3339),
}
if err := writer.Write(row); err != nil {
return fmt.Errorf("failed to write CSV row: %w", err)
}
}
return nil
}
func (e *Exporter) PrintToConsole(products []models.StorageProduct) string {
var b strings.Builder
b.WriteString("\n")
b.WriteString("═══════════════════════════════════════════════════════════════════════════════\n")
b.WriteString(fmt.Sprintf(" STORAGE PRODUCTS (%d items) \n", len(products)))
b.WriteString("═══════════════════════════════════════════════════════════════════════════════\n")
b.WriteString("\n")
headerFmt := " %-4s | %-40s | %-10s | %-8s | %-6s | %-10s | %-12s\n"
separator := "──────┼──────────────────────────────────────────┬────────────┬──────────┼────────┼────────────┼──────────────\n"
b.WriteString(fmt.Sprintf(headerFmt, "#", "Name", "Capacity", "Interface", "Factor", "Stock", "Price"))
b.WriteString(separator)
for i, p := range products {
name := p.Name
if len(name) > 40 {
name = name[:37] + "..."
}
capacity := p.Capacity
if capacity == "" {
capacity = "-"
}
interface_ := p.Interface
if interface_ == "" {
interface_ = "-"
}
formFactor := p.FormFactor
if formFactor == "" {
formFactor = "-"
}
stock := p.StockStatus
if stock == "" {
stock = "-"
}
price := p.Price
if price == "" {
price = "-"
}
b.WriteString(fmt.Sprintf(headerFmt,
fmt.Sprintf("%d", i+1),
name,
capacity,
interface_,
formFactor,
stock,
price,
))
}
b.WriteString("\n")
b.WriteString(fmt.Sprintf("Total: %d products\n", len(products)))
return b.String()
}
func (e *Exporter) Export(products []models.StorageProduct, format string, filename string) error {
switch strings.ToLower(format) {
case "json":
return e.ExportToJSON(products, filename)
case "csv":
return e.ExportToCSV(products, filename)
default:
return fmt.Errorf("unsupported format: %s (use 'json' or 'csv')", format)
}
}