204 lines
5.1 KiB
Go
204 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()
|
|
}
|
|
|