package main import ( "database/sql" "embed" "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" ) //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 { panic(err) } driver, err := mysql.WithInstance(db, &mysql.Config{}) if err != nil { panic(err) } d, err := iofs.New(database, "database/migrations") if err != nil { panic(err) } m, err := migrate.NewWithInstance("iofs", d, "mysql", driver) if err != nil { panic(err) } 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") } s3 = minioClient log.Debug().Msg("Finish create s3 client") } func loadEnvConfig() { err := godotenv.Load() if err != nil { log.Fatal().Err(err).Msg("Error loading .env file") } } 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), }, )) f.Use(template.Templater( template.Options{ }, )) ro := redis.Options{ Addr: os.Getenv("REDIS_HORST"), DB: os.Getenv("REDIS_DB"), } 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", galleryEdit) 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() }