152 lines
4.0 KiB
Go
152 lines
4.0 KiB
Go
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)
|
||
|
|
}
|
||
|
|
}
|