Files
ares/scripts/seed.go
Beyhan Oğur 4d92991817 first commit
2026-04-26 21:30:42 +03:00

236 lines
5.7 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
crand "crypto/rand"
"encoding/hex"
"fmt"
"io"
"math/rand"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"time"
configs "ares/config"
database "ares/database/config"
"ares/database/models"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
var nonSlugChars = regexp.MustCompile(`[^a-z0-9\-]+`)
var multiDash = regexp.MustCompile(`-+`)
func randHex(n int) string {
b := make([]byte, n)
_, _ = crand.Read(b)
return hex.EncodeToString(b)[:n]
}
func ensureUploadsDir() error {
p := "./uploads/posts"
return os.MkdirAll(p, 0755)
}
func slugify(s string) string {
repl := strings.NewReplacer(
"ç", "c", "Ç", "c",
"ğ", "g", "Ğ", "g",
"ı", "i", "İ", "i",
"ö", "o", "Ö", "o",
"ş", "s", "Ş", "s",
"ü", "u", "Ü", "u",
)
s = repl.Replace(strings.TrimSpace(strings.ToLower(s)))
s = strings.ReplaceAll(s, " ", "-")
s = nonSlugChars.ReplaceAllString(s, "-")
s = multiDash.ReplaceAllString(s, "-")
s = strings.Trim(s, "-")
if s == "" {
return "item"
}
return s
}
func ensureUniqueCategorySlug(db *gorm.DB, base string) string {
slug := base
i := 1
for {
var count int64
_ = db.Model(&models.Category{}).Where("slug = ?", slug).Count(&count).Error
if count == 0 {
return slug
}
i++
slug = fmt.Sprintf("%s-%d", base, i)
}
}
func ensureUniquePostSlug(db *gorm.DB, base string) string {
slug := base
i := 1
for {
var count int64
_ = db.Model(&models.Post{}).Where("slug = ?", slug).Count(&count).Error
if count == 0 {
return slug
}
i++
slug = fmt.Sprintf("%s-%d", base, i)
}
}
func downloadImage(destDir string, idx int) (string, error) {
url := fmt.Sprintf("https://picsum.photos/1200/800?random=%d", idx)
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
filename := fmt.Sprintf("post_%d_%s.jpg", idx, randHex(6))
outPath := filepath.Join(destDir, filename)
out, err := os.Create(outPath)
if err != nil {
return "", err
}
defer out.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
return "", err
}
return "/uploads/posts/" + filename, nil
}
func main() {
fmt.Println("Seeder starting...")
// load config to get DB_URL
configs.LoadConfig()
// ensure uploads dir
if err := ensureUploadsDir(); err != nil {
fmt.Println("failed to create uploads dir:", err)
os.Exit(1)
}
// Require DB_URL / configured DB. Do not fallback to sqlite.
database.ConnectDB()
if database.DB == nil {
fmt.Println("Database not configured or connection failed. Please set DB_URL in .env and ensure database is reachable.")
os.Exit(1)
}
// set GORM logger to Silent for seeding to reduce noise
var db *gorm.DB = database.DB.Session(&gorm.Session{Logger: logger.Default.LogMode(logger.Silent)})
fmt.Println("Using configured DB")
// auto-migrate minimal models used
err := db.AutoMigrate(&models.Category{}, &models.Tag{}, &models.Post{}, &models.Comment{})
if err != nil {
fmt.Println("AutoMigrate failed:", err)
os.Exit(1)
}
rand.Seed(time.Now().UnixNano())
// create categories
cats := []models.Category{}
catNames := []string{"Teknoloji", "Yazilim", "Guncel", "Yasam", "Egitim", "Spor", "Saglik", "Finans"}
for _, n := range catNames {
baseSlug := slugify(n)
var c models.Category
if err := db.Where("title = ?", n).First(&c).Error; err == nil {
// Ensure old records have a valid unique slug.
if strings.TrimSpace(c.Slug) == "" {
c.Slug = ensureUniqueCategorySlug(db, baseSlug)
_ = db.Save(&c).Error
}
cats = append(cats, c)
continue
}
c = models.Category{
Title: n,
Slug: ensureUniqueCategorySlug(db, baseSlug),
Description: fmt.Sprintf("%s kategorisi seed verisi", n),
}
res := db.Create(&c)
if res.Error != nil {
fmt.Println("Failed to create category", n, ":", res.Error)
continue
}
cats = append(cats, c)
fmt.Println("Created category:", c.Title, "slug:", c.Slug)
}
// create tags
tags := []models.Tag{}
tagNames := []string{"go", "fiber", "backend", "mysql", "redis", "jwt", "api", "docker", "cloud", "devops", "security", "testing"}
for _, n := range tagNames {
var t models.Tag
if err := db.Where("name = ?", n).First(&t).Error; err == nil {
tags = append(tags, t)
continue
}
t = models.Tag{Name: n}
res := db.Create(&t)
if res.Error != nil {
fmt.Println("Failed to create tag", n, ":", res.Error)
continue
}
tags = append(tags, t)
fmt.Println("Created tag:", t.Name)
}
// create posts
dest := "./uploads/posts"
targetPosts := 39
for i := 1; i <= targetPosts; i++ {
imgPath, err := downloadImage(dest, i)
if err != nil {
fmt.Println("image download failed for", i, "— using fallback path. err:", err)
imgPath = fmt.Sprintf("/uploads/posts/fallback_%d.jpg", i)
}
title := fmt.Sprintf("Seed Post %d", i)
baseSlug := slugify(title)
uniqueSlug := ensureUniquePostSlug(db, baseSlug)
p := models.Post{
Title: title,
Slug: uniqueSlug,
Content: fmt.Sprintf("Bu bir test icerigidir. Gonderi numarasi %d.", i),
}
// randomly attach 1-2 categories
nc := rand.Intn(2) + 1
permCats := rand.Perm(len(cats))[:nc]
for _, idx := range permCats {
p.Categories = append(p.Categories, cats[idx])
}
// attach 1-3 tags
nx := rand.Intn(3) + 1
permTags := rand.Perm(len(tags))[:nx]
for _, idx := range permTags {
p.Tags = append(p.Tags, tags[idx])
}
// assign image paths (seed: same path for all sizes)
p.Images = imgPath
p.ImagesMid = imgPath
p.ImagesMin = imgPath
res := db.Create(&p)
if res.Error != nil {
fmt.Println("Failed to create post", title, ":", res.Error)
} else {
fmt.Println("Created post", p.Title, "slug:", p.Slug)
}
}
fmt.Printf("Seeding done — %d posts targeted.\n", targetPosts)
// print reminder where images are
fmt.Println("Images saved to ./uploads/posts — check files.")
}