kuvia2/main.go

205 lines
5.1 KiB
Go

package main
import (
"context"
"database/sql"
"embed"
"errors"
"github.com/flamego/captcha"
"github.com/flamego/cors"
"github.com/flamego/flamego"
"github.com/flamego/session"
sredis "github.com/flamego/session/redis"
"github.com/flamego/template"
"github.com/go-redis/redis/v8"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/mysql"
"github.com/golang-migrate/migrate/v4/source/iofs"
"github.com/jmoiron/sqlx"
"github.com/joho/godotenv"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"kuvia/pkg/globaleuserdata"
"net/http"
"os"
"strconv"
)
//go:embed public
var public embed.FS
//go:embed templates
var templates embed.FS
//go:embed database/migrations/*.sql
var database embed.FS
var sqlConnection *sqlx.DB
var s3 *minio.Client
func migrateDB() {
log.Info().Msg("Run Migration if exists")
db, err := sql.Open("mysql", os.Getenv("DB_MIGRATION"))
if err != nil {
log.Fatal().Err(err).Str("Connection String", os.Getenv("DB_MIGRATION")).Msg("Cant Open SQL Connection")
}
driver, err := mysql.WithInstance(db, &mysql.Config{})
if err != nil {
log.Fatal().Err(err).Str("Connection String", os.Getenv("DB_MIGRATION")).Msg("Cant create drive")
}
d, err := iofs.New(database, "database/migrations")
if err != nil {
log.Fatal().Err(err).Msg("Cant creat iofs to get migrations from")
}
m, err := migrate.NewWithInstance("iofs", d, "mysql", driver)
if err != nil {
log.Fatal().Err(err).Msg("Cant create migrate instante")
}
err = m.Up()
if err != nil {
if err.Error() == "no change" {
log.Debug().Msg("No Changes at Migration")
} else {
panic(err)
}
}
log.Info().Msg("Run Migration done")
}
func sqlConnect() {
log.Info().Msg("Connect to MYSQL Server")
db, err := sqlx.Open("mysql", os.Getenv("DB_CONNECTION"))
if err != nil {
panic(err)
}
sqlConnection = db
log.Debug().Msg("Connection to MYSQL Done")
}
func s3Connect() {
log.Debug().Msg("Connect to s3")
minioClient, err := minio.New( os.Getenv("S3_HOST"), &minio.Options{
Creds: credentials.NewStaticV4(os.Getenv("S3_ID"), os.Getenv("S3_SECRET"), os.Getenv("S3_TOKEN")),
Secure: false,
})
if err != nil {
log.Fatal().Err(err).Msg("Cant create s3 client")
}
ctx := context.Background()
bucketexists, err := minioClient.BucketExists(ctx, os.Getenv("S3_BUCKET"))
if err != nil {
log.Fatal().Err(err).Msg("Cant check S3 Bucket exists")
}
if bucketexists == false {
log.Info().Msg("Create S3 Bucket")
err = minioClient.MakeBucket(ctx, os.Getenv("S3_BUCKET"), minio.MakeBucketOptions{})
if err != nil {
log.Fatal().Str("Bucket-Name", os.Getenv("S3_BUCKET")).Err(err).Msg("Cant Create S3 Bucklet")
}
} else {
log.Debug().Msg("Bucket already exists")
}
s3 = minioClient
log.Debug().Msg("Finish create s3 client")
}
func loadEnvConfig() {
if _, err := os.Stat(".env"); err == nil {
err := godotenv.Load()
if err != nil {
log.Fatal().Err(err).Msg("Error loading .env file")
}
} else if errors.Is(err, os.ErrNotExist) {
log.Info().Msg("No .env file found")
} else {
log.Fatal().Err(err).Msg("Error load config from env")
}
}
func main() {
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
loadEnvConfig()
migrateDB()
sqlConnect()
s3Connect()
f := flamego.Classic()
f.Use(flamego.Static(
flamego.StaticOptions{
FileSystem: http.FS(public),
},
))
templateFS, err := template.EmbedFS(templates, "templates", []string{".tmpl"})
if err != nil {
log.Fatal().Err(err).Msg("Cant creat EmbedFS for templates")
}
f.Use(template.Templater(
template.Options{
FileSystem: templateFS,
},
))
redisDB, err := strconv.Atoi(os.Getenv("REDIS_DB"))
if err != nil {
log.Fatal().Err(err).Str("Redis DB String", os.Getenv("REDIS_DB")).Msg("Cant convertz Redis DB to int")
}
ro := redis.Options{
Addr: os.Getenv("REDIS_HORST"),
DB: redisDB,
}
f.Use(session.Sessioner(session.Options{
Initer: sredis.Initer(),
Config: sredis.Config{
Options: &ro,
},
}))
f.Use(globaleuserdata.GlobalUserData(sqlConnection))
f.Use(captcha.Captchaer(captcha.Options{
TextLength: 4,
}))
f.Use(cors.CORS())
f.Any("/", func(s session.Session, t template.Template, data template.Data) {
t.HTML(http.StatusOK, "home")
})
f.Get("/login", loginForm)
f.Post("/login", login)
f.Get("/register", registerForm)
f.Post("/register", register)
f.Get("/logout", logout)
f.Get("/gallery/new", galleryNewForm)
f.Post("/gallery/new", galleryNew)
f.Get("/gallery/edit", galleryEditList)
f.Get("/gallery/edit/{id}", galleryEdit)
f.Post("/gallery/edit/{id}", galleryEditSave)
f.Get("/gallery/edit/{id}/image", galleryEditMainImage)
f.Post("/gallery/edit/{id}/image", galleryEditMainImageChange)
f.Get("/file/upload", uploadImageForm)
f.Post("/file/upload", uploadImage)
f.Get("/u/{name}", userProfile)
f.Get("/u/{name}/{id}", userGallery)
f.Get("/image", getImage)
f.Get("/settings/profile", profile)
f.Post("/settings/profile", profileUpdate)
f.Get("/settings/profile/image", profileImage)
f.Post("/settings/profile/image", profileImageChange)
f.Run()
}