aboutsummaryrefslogtreecommitdiff
path: root/config
diff options
context:
space:
mode:
authorBobby <[email protected]>2025-06-15 00:05:43 +0530
committerBobby <[email protected]>2025-06-15 00:05:43 +0530
commit9f6aac08a8e9a0685a21fbe4ee292cb514485f22 (patch)
tree165b210ffd080c47d775596322868996d51413dc /config
parente79dcba2565c10f9a967a97e863fedb727a3a041 (diff)
downloadimageboard-9f6aac08a8e9a0685a21fbe4ee292cb514485f22.tar.xz
imageboard-9f6aac08a8e9a0685a21fbe4ee292cb514485f22.zip
setting up the imageboard
Diffstat (limited to 'config')
-rw-r--r--config/config.go47
-rw-r--r--config/functions.go115
-rw-r--r--config/types.go43
3 files changed, 205 insertions, 0 deletions
diff --git a/config/config.go b/config/config.go
new file mode 100644
index 0000000..14c0bf2
--- /dev/null
+++ b/config/config.go
@@ -0,0 +1,47 @@
+package config
+
+import (
+ "log"
+
+ "github.com/joho/godotenv"
+)
+
+var (
+ AppSecret string = "default_secret"
+ Database DatabaseConfig
+ IsDevelopmentMode bool = true
+ Image ImageConfig
+ S3 S3Config
+ Server ServerConfig
+ Session SessionConfig
+)
+
+func init() {
+ if err := godotenv.Load(); err != nil {
+ log.Println("no .env file found, using environment variables")
+ }
+
+ AppSecret = getEnv("APP_SECRET", AppSecret)
+
+ if err := Parse(&Database); err != nil {
+ log.Fatalf("failed to parse configuration: %v", err)
+ }
+
+ IsDevelopmentMode = getEnvBool("DEV_MODE", IsDevelopmentMode)
+
+ if err := Parse(&Image); err != nil {
+ log.Fatalf("failed to parse configuration: %v", err)
+ }
+
+ if err := Parse(&S3); err != nil {
+ log.Fatalf("failed to parse configuration: %v", err)
+ }
+
+ if err := Parse(&Server); err != nil {
+ log.Fatalf("failed to parse configuration: %v", err)
+ }
+
+ if err := Parse(&Session); err != nil {
+ log.Fatalf("failed to parse configuration: %v", err)
+ }
+}
diff --git a/config/functions.go b/config/functions.go
new file mode 100644
index 0000000..0ec2d8e
--- /dev/null
+++ b/config/functions.go
@@ -0,0 +1,115 @@
+package config
+
+import (
+ "fmt"
+ "os"
+ "reflect"
+ "strconv"
+ "time"
+)
+
+func getEnv(key, defaultVal string) string {
+ if value := os.Getenv(key); value != "" {
+ return value
+ }
+ return defaultVal
+}
+
+func getEnvBool(key string, defaultVal bool) bool {
+ if value := os.Getenv(key); value != "" {
+ if parsed, err := strconv.ParseBool(value); err == nil {
+ return parsed
+ }
+ }
+ return defaultVal
+}
+
+func getEnvDuration(key string, defaultVal time.Duration) time.Duration {
+ if value := os.Getenv(key); value != "" {
+ if parsed, err := time.ParseDuration(value); err == nil {
+ return parsed
+ }
+ }
+ return defaultVal
+}
+
+func getEnvInt64(key string, defaultVal int64) int64 {
+ if value := os.Getenv(key); value != "" {
+ if parsed, err := strconv.ParseInt(value, 10, 64); err == nil {
+ return parsed
+ }
+ }
+ return defaultVal
+}
+
+func getEnvFloat64(key string, defaultVal float64) float64 {
+ if value := os.Getenv(key); value != "" {
+ if parsed, err := strconv.ParseFloat(value, 64); err == nil {
+ return parsed
+ }
+ }
+ return defaultVal
+}
+
+func Parse(config interface{}) error {
+ v := reflect.ValueOf(config)
+ if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
+ return fmt.Errorf("config must be a pointer to struct")
+ }
+
+ v = v.Elem()
+ t := v.Type()
+
+ for i := range v.NumField() {
+ field := v.Field(i)
+ fieldType := t.Field(i)
+
+ if !field.CanSet() {
+ continue
+ }
+
+ envKey := fieldType.Tag.Get("env")
+ defaultVal := fieldType.Tag.Get("default")
+
+ if envKey == "" {
+ continue
+ }
+
+ switch field.Kind() {
+ case reflect.String:
+ field.SetString(getEnv(envKey, defaultVal))
+
+ case reflect.Bool:
+ defaultBool, _ := strconv.ParseBool(defaultVal)
+ field.SetBool(getEnvBool(envKey, defaultBool))
+
+ case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
+ defaultInt, _ := strconv.ParseInt(defaultVal, 10, 64)
+ field.SetInt(getEnvInt64(envKey, defaultInt))
+
+ case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+ defaultUint, _ := strconv.ParseUint(defaultVal, 10, 64)
+ if value := os.Getenv(envKey); value != "" {
+ if parsed, err := strconv.ParseUint(value, 10, 64); err == nil {
+ field.SetUint(parsed)
+ continue
+ }
+ }
+ field.SetUint(defaultUint)
+
+ case reflect.Float32, reflect.Float64:
+ defaultFloat, _ := strconv.ParseFloat(defaultVal, 64)
+ field.SetFloat(getEnvFloat64(envKey, defaultFloat))
+
+ default:
+ if field.Type() == reflect.TypeOf(time.Duration(0)) {
+ defaultDuration, _ := time.ParseDuration(defaultVal)
+ field.Set(reflect.ValueOf(getEnvDuration(envKey, defaultDuration)))
+ } else {
+ return fmt.Errorf("unsupported field type: %s", field.Kind())
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/config/types.go b/config/types.go
new file mode 100644
index 0000000..994b93e
--- /dev/null
+++ b/config/types.go
@@ -0,0 +1,43 @@
+package config
+
+import "time"
+
+type ServerConfig struct {
+ Host string `env:"SERVER_HOST" default:"localhost"`
+ Port string `env:"SERVER_PORT" default:"8080"`
+ AppName string `env:"APP_NAME" default:"ImageBoard"`
+}
+
+type DatabaseConfig struct {
+ Host string `env:"DB_HOST" default:"localhost"`
+ Port int `env:"DB_PORT" default:"5432"`
+ Username string `env:"DB_USERNAME" default:"postgres"`
+ Password string `env:"DB_PASSWORD" default:""`
+ DatabaseName string `env:"DB_NAME" default:"imageboard"`
+ SSLMode string `env:"DB_SSLMODE" default:"disable"`
+}
+
+type SessionConfig struct {
+ Expiration time.Duration `env:"SESSION_EXPIRATION" default:"24h"`
+ CookieName string `env:"SESSION_COOKIE_NAME" default:"session_id"`
+ CookieDomain string `env:"SESSION_COOKIE_DOMAIN" default:""`
+ CookiePath string `env:"SESSION_COOKIE_PATH" default:"/"`
+ CookieSecure bool `env:"SESSION_COOKIE_SECURE" default:"false"`
+ CookieSameSite string `env:"SESSION_COOKIE_SAMESITE" default:"Lax"`
+}
+
+type ImageConfig struct {
+ MaxSize int `env:"IMAGE_MAX_SIZE" default:"10485760"`
+ AllowedTypes string `env:"IMAGE_ALLOWED_TYPES" default:"image/jpeg,image/png,image/gif,image/webp"`
+}
+
+type S3Config struct {
+ Endpoint string `env:"S3_ENDPOINT" default:"localhost:9000"`
+ AccessKey string `env:"S3_ACCESS_KEY" default:"minioadmin"`
+ SecretAccessKey string `env:"S3_SECRET_KEY" default:"minioadmin"`
+ BucketName string `env:"S3_BUCKET_NAME" default:"shifoo"`
+ FolderPath string `env:"S3_FOLDER_PATH" default:"imageboard"`
+ Region string `env:"S3_REGION" default:"us-east-1"`
+ UseSSL bool `env:"S3_USE_SSL" default:"false"`
+ PublicURL string `env:"S3_PUBLIC_URL" default:""`
+}