initial commit
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user