Files
goGin/cmd/seeder/main.go
Beyhan Oğur 2a5b661443 first commit
2026-04-26 21:46:42 +03:00

251 lines
7.4 KiB
Go
Raw 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 (
"fmt"
"io"
"log"
"math/rand"
"net/http"
"os"
"path/filepath"
"strings"
"time"
database "goGin/app/database/config"
"goGin/app/database/models"
configs "goGin/config"
"gorm.io/gorm"
)
func main() {
// Config ve DB yükle
configs.LoadConfig()
database.ConnectDB()
db := database.DB
if db == nil {
log.Fatal("Veritabanı bağlantısı kurulamadı!")
}
log.Println("Seeder başladı...")
// create a local random generator to avoid deprecated rand.Seed usage
r := rand.New(rand.NewSource(time.Now().UnixNano()))
// 1. Kullanıcıyı Kontrol Et / Oluştur (ID: 2)
var user models.User
result := db.First(&user, 2)
if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound {
log.Println("Kullanıcı (ID: 2) bulunamadı, oluşturuluyor...")
user = models.User{
ID: 2,
UserName: "fakeuser",
Email: "fakeuser@example.com",
Password: "password123", // Hashlenmemiş, sadece test için
}
isAdmin := false
emailVerified := true
user.IsAdmin = &isAdmin
user.EmailVerified = &emailVerified
if err := db.Create(&user).Error; err != nil {
log.Printf("Kullanıcı oluşturulurken hata: %v", err)
user.ID = 0
if err2 := db.Create(&user).Error; err2 != nil {
log.Fatal("Kullanıcı oluşturulamadı:", err2)
}
}
} else {
log.Fatal("Veritabanı hatası:", result.Error)
}
} else {
log.Println("Kullanıcı (ID: 2) mevcut.")
}
// 2. Kategorileri Oluştur
categories := []struct {
Title string
Subs []string
}{
{"Teknoloji", []string{"Yazılım", "Donanım", "Yapay Zeka", "Mobil"}},
{"Yaşam", []string{"Sağlık", "Spor", "Gezi", "Dekorasyon"}},
{"Yemek", []string{"Tatlılar", "Ana Yemekler", "İçecekler"}},
{"Sanat", []string{"Sinema", "Müzik", "Edebiyat"}},
}
var createdCategories []models.Category
for _, catData := range categories {
parent := models.Category{
Title: catData.Title,
Slug: slugify(catData.Title),
}
if err := db.Where("slug = ?", parent.Slug).FirstOrCreate(&parent).Error; err != nil {
log.Printf("Kategori hatası (%s): %v", parent.Title, err)
continue
}
createdCategories = append(createdCategories, parent)
for _, subTitle := range catData.Subs {
sub := models.Category{
Title: subTitle,
Slug: slugify(subTitle),
ParentID: &parent.ID,
}
if err := db.Where("slug = ?", sub.Slug).FirstOrCreate(&sub).Error; err != nil {
log.Printf("Alt kategori hatası (%s): %v", subTitle, err)
continue
}
createdCategories = append(createdCategories, sub)
}
}
// 3. Etiketleri Oluştur
tagNames := []string{"Go", "Gin", "Web", "Api", "Tutorial", "Coding", "Life", "Nature", "Food", "Travel"}
var createdTags []models.Tag
for _, name := range tagNames {
tag := models.Tag{Name: name}
if err := db.Where("name = ?", name).FirstOrCreate(&tag).Error; err != nil {
log.Printf("Etiket hatası (%s): %v", name, err)
continue
}
createdTags = append(createdTags, tag)
}
// 4. Postları Oluştur (40 adet)
postCount := 40
titles := []string{
"Go ile Web Geliştirme", "Gin Framework İpuçları", "Veritabanı Optimizasyonu",
"Modern Web Tasarımı", "Yapay Zeka Geleceği", "sağlıklı Yaşam Sırları",
"Dünya Turu Rehberi", "Lezzetli Pizza Tarifi", "Film İncelemesi: Joker",
"Müzik ve Ruh Hali", "Kodlama Pratikleri", "Cloud Computing Temelleri",
}
images := []string{
"https://images.unsplash.com/photo-1518770660439-4636190af475?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1498050108023-c5249f4df085?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1461749280684-dccba630e2f6?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1504674900247-0877df9cc836?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1472214103451-9374bd1c798e?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1493770348161-369560ae357d?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1470225620780-dba8ba36b745?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1542291026-7eec264c27ff?auto=format&fit=crop&w=1000&q=80",
"https://images.unsplash.com/photo-1515378791036-0648a3ef77b2?auto=format&fit=crop&w=1000&q=80",
}
// Resimlerin indirileceği hedef klasör
uploadDir := "uploads/posts"
if err := os.MkdirAll(uploadDir, os.ModePerm); err != nil {
log.Fatalf("Klasör oluşturulamadı: %v", err)
}
log.Println("Postlar oluşturuluyor ve resimler indiriliyor...")
for i := 0; i < postCount; i++ {
// use local rand generator
title := fmt.Sprintf("%s %d", titles[r.Intn(len(titles))], i+1)
// Resim İndirme İşlemi
remoteURL := images[r.Intn(len(images))]
fileName := fmt.Sprintf("seed-post-%d-%d.jpg", i+1, time.Now().Unix())
filePath := filepath.Join(uploadDir, fileName)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
if err := downloadFile(filePath, remoteURL); err != nil {
log.Printf("Resim indirilemedi (%s): %v", remoteURL, err)
}
}
dbImagePath := fmt.Sprintf("/uploads/posts/%s", fileName)
post := models.Post{
Title: title,
Slug: slugify(title),
Content: fmt.Sprintf("<p>Bu otomatik oluşturulmuş bir içeriktir: %s. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>", title),
Images: dbImagePath,
}
if err := db.Create(&post).Error; err != nil {
log.Printf("Post oluşturma hatası: %v", err)
continue
}
// İlişkiler
numCats := r.Intn(3) + 1
for j := 0; j < numCats; j++ {
cat := createdCategories[r.Intn(len(createdCategories))]
if err := db.Model(&post).Association("Categories").Append(&cat); err != nil {
log.Printf("Kategori ilişkilendirme hatası (post %d, cat %d): %v", post.ID, cat.ID, err)
}
}
numTags := r.Intn(4) + 1
for j := 0; j < numTags; j++ {
tag := createdTags[r.Intn(len(createdTags))]
if err := db.Model(&post).Association("Tags").Append(&tag); err != nil {
log.Printf("Tag ilişkilendirme hatası (post %d, tag %d): %v", post.ID, tag.ID, err)
}
}
numComments := r.Intn(6)
for c := 0; c < numComments; c++ {
comment := models.Comment{
PostID: post.ID,
UserID: user.ID,
Body: fmt.Sprintf("Bu harika bir yazı! Yorum #%d", c+1),
}
if err := db.Create(&comment).Error; err != nil {
log.Printf("Yorum oluşturma hatası: %v", err)
}
}
time.Sleep(50 * time.Millisecond)
}
log.Println("Tüm işlemler başarıyla tamamlandı!")
}
func downloadFile(filepath string, url string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer func() {
if cerr := resp.Body.Close(); cerr != nil {
log.Printf("error closing response body: %v", cerr)
}
}()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("bad status: %s", resp.Status)
}
out, err := os.Create(filepath)
if err != nil {
return err
}
defer func() {
if cerr := out.Close(); cerr != nil {
log.Printf("error closing file: %v", cerr)
}
}()
_, err = io.Copy(out, resp.Body)
return err
}
func slugify(s string) string {
s = strings.ToLower(s)
s = strings.ReplaceAll(s, " ", "-")
s = strings.ReplaceAll(s, "ı", "i")
s = strings.ReplaceAll(s, "ğ", "g")
s = strings.ReplaceAll(s, "ü", "u")
s = strings.ReplaceAll(s, "ş", "s")
s = strings.ReplaceAll(s, "ö", "o")
s = strings.ReplaceAll(s, "ç", "c")
timestamp := time.Now().UnixNano()
return fmt.Sprintf("%s-%d", s, timestamp)
}