move media models
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 10s
Gitea Actions Demo / build-and-test (push) Failing after 1m3s

This commit is contained in:
2026-11-05 22:18:13 +01:00
committed by Thomas Peetz
parent f75dd3a9fb
commit 20e141b73e
9 changed files with 456 additions and 0 deletions
+162
View File
@@ -0,0 +1,162 @@
package config
import (
"errors"
"fmt"
"log/slog"
"strings"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
var (
CfgFile string
Verbose int
Overwrite bool
ServerName string
Mediatype MediaType
Config CliConfig
ServerConfig ServerConfiguration
DryRun bool
FileName string
)
const (
mediaTypeMedia MediaType = "media"
mediaTypeVideo MediaType = "video"
mediaTypeLofi MediaType = "lofi"
)
type MediaType string
func (e *MediaType) String() string {
return string(*e)
}
func (e *MediaType) Set(v string) error {
switch v {
case "media", "video", "lofi":
*e = MediaType(v)
return nil
default:
return errors.New(`must be one of "media", "video", "lofi"`)
}
}
func (e *MediaType) Type() string {
return "MediaType"
}
func myEnumCompletion(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{
"media\thelp text for media",
"video\thelp text for video",
"lofi\thelp text for lofi",
}, cobra.ShellCompDirectiveDefault
}
type Server struct {
Url string `mapstructure:"url"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
}
type Database struct {
Type string `mapstructure:"type" validate:"required"`
Path string `mapstructure:"path" validate:"required"`
Host string `mapstructure:"host" validate:"required"`
Name string `mapstructure:"name" validate:"required"`
Port int `mapstructure:"port" validate:"required"`
Password string `mapstructure:"password" validate:"required"`
User string `mapstructure:"user" validate:"required"`
}
type CliConfig struct {
ApiVersion string
Server map[string]Server `mapstructure:"server"`
DB Database `mapstructure:"db"`
}
type ServerConfiguration struct {
Server struct {
Port int `mapstructure:"port" validate:"required"`
Host string `mapstructure:"host"`
} `mapstructure:"server"`
DB Database `mapstructure:"db"`
Gin struct {
Mode string `mapstructure:"mode" validate:"required"`
} `mapstructure:"gin"`
}
func InitCliConfig() {
slog.Info("InitCliConfig")
if CfgFile != "" {
viper.SetConfigFile(CfgFile)
} else {
viper.SetConfigName("kli") // without extension
viper.SetConfigType("yaml")
viper.AddConfigPath(".") // look for config in working directory
viper.AddConfigPath("/home/tpeetz/.config")
}
Mediatype = mediaTypeMedia
// Read the configuration file
if err := viper.ReadInConfig(); err != nil {
// Handle the case where config file is not found
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
slog.Info("No config file found, using defaults")
if err := viper.SafeWriteConfig(); err != nil {
slog.Info("error writing config file", "error", err.Error())
}
} else {
slog.Info("error reading config file", "error", err.Error())
}
} else {
slog.Info("InitCliConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&Config); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
}
}
func InitConfig() error {
viper.SetConfigName("kontor-gin")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("/home/tpeetz/.config")
viper.AddConfigPath("/etc/kontor")
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
viper.SetDefault("db.type", "postgres")
viper.SetDefault("db.host", "localhost")
viper.SetDefault("db.port", 5432)
viper.SetDefault("db.name", "kontor")
viper.SetDefault("db.user", "kontor")
viper.SetDefault("db.password", "kontor")
viper.SetDefault("db.path", "data/kontor.db")
viper.SetDefault("server.port", 8550)
viper.SetDefault("gin.mode", "release")
// Read the config file
if err := viper.ReadInConfig(); err != nil {
// Handle the case where config file is not found
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
slog.Info("No config file found, using defaults")
if err := viper.SafeWriteConfig(); err != nil {
slog.Info("error writing config file", "error", err.Error())
return fmt.Errorf("error writing config file: %w", err)
}
} else {
return fmt.Errorf("error reading config file: %w", err)
}
} else {
slog.Info("InitConfig", "Using config file: ", viper.ConfigFileUsed())
if err := viper.Unmarshal(&ServerConfig); err != nil {
slog.Info("parsing of config file failed", "error", err.Error())
}
}
return nil
}
+60
View File
@@ -0,0 +1,60 @@
package config
import (
"fmt"
"log/slog"
"gorm.io/driver/postgres"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func NewDB(db Database) (*gorm.DB, error) {
db_type := db.Type
slog.Info("using database", "type", db_type)
switch db_type {
case "postgres":
dsn := fmt.Sprintf(
"host=%s user=%s password=%s dbname=%s port=%d sslmode=disable",
db.Host,
db.User,
db.Password,
db.Name,
db.Port,
)
return gorm.Open(postgres.Open(dsn), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
case "sqlite":
return gorm.Open(sqlite.Open(db.Path), &gorm.Config{
Logger: logger.Default.LogMode(logger.Info),
})
default:
return nil, fmt.Errorf("unknown db.type=%s", db_type)
}
// Configure GORM with custom settings
// The logger helps with debugging SQL queries during development
// if err != nil {
// log.Fatal("Failed to connect to database:", err)
// }
// // Get the underlying SQL database connection for pool configuration
// sqlDB, err := db.DB()
// if err != nil {
// log.Fatal("Failed to get database instance:", err)
// }
// // Configure connection pool settings
// // MaxIdleConns: number of connections kept open when idle
// sqlDB.SetMaxIdleConns(10)
// // MaxOpenConns: maximum total connections to the database
// sqlDB.SetMaxOpenConns(100)
// // ConnMaxLifetime: how long a connection can be reused
// sqlDB.SetConnMaxLifetime(time.Hour)
// slog.Info("Database connected successfully")
}