first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:45:19 +03:00
commit 60db80892b
101 changed files with 16757 additions and 0 deletions

233
scripts/seed.go Normal file
View File

@@ -0,0 +1,233 @@
package main
import (
crand "crypto/rand"
"encoding/hex"
"fmt"
"io"
"math/rand"
"net/http"
"os"
"path/filepath"
"regexp"
"strings"
"time"
configs "goFiber/config"
database "goFiber/database/config"
"goFiber/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 a single relative image path (NOT JSON array)
p.Images = 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.")
}