refactor: migrate env-var reads to config package
This commit is contained in:
@@ -11,12 +11,18 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/database"
|
"mal/internal/database"
|
||||||
"mal/internal/db"
|
"mal/internal/db"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
dbConn, err := db.Open(db.GetDBFile())
|
cfg, err := config.Load()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("load config: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
dbConn, err := db.Open(cfg.DatabaseFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("failed to open db: %v", err)
|
log.Fatalf("failed to open db: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,19 +7,21 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/db"
|
"mal/internal/db"
|
||||||
"mal/internal/observability"
|
"mal/internal/observability"
|
||||||
|
|
||||||
"golang.org/x/sync/singleflight"
|
"golang.org/x/sync/singleflight"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var traceEnabled bool
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
baseURL string
|
baseURL string
|
||||||
@@ -39,7 +41,8 @@ type Client struct {
|
|||||||
|
|
||||||
const jikanSlowLogThreshold = 750 * time.Millisecond
|
const jikanSlowLogThreshold = 750 * time.Millisecond
|
||||||
|
|
||||||
func NewClient(queries *db.Queries, metrics *observability.Metrics) *Client {
|
func NewClient(cfg config.Config, queries *db.Queries, metrics *observability.Metrics) *Client {
|
||||||
|
traceEnabled = cfg.JikanTrace
|
||||||
return &Client{
|
return &Client{
|
||||||
httpClient: &http.Client{
|
httpClient: &http.Client{
|
||||||
Timeout: 10 * time.Second,
|
Timeout: 10 * time.Second,
|
||||||
@@ -142,8 +145,7 @@ func waitForRetry(ctx context.Context, delay time.Duration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func jikanTraceEnabled() bool {
|
func jikanTraceEnabled() bool {
|
||||||
value := strings.ToLower(strings.TrimSpace(os.Getenv("MAL_JIKAN_TRACE")))
|
return traceEnabled
|
||||||
return value == "1" || value == "true" || value == "yes"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func logJikanCache(cacheKey string, source string, startedAt time.Time, err error) {
|
func logJikanCache(cacheKey string, source string, startedAt time.Time, err error) {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"mal/integrations/playback/allanime"
|
"mal/integrations/playback/allanime"
|
||||||
"mal/internal/anime"
|
"mal/internal/anime"
|
||||||
"mal/internal/auth"
|
"mal/internal/auth"
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/database"
|
"mal/internal/database"
|
||||||
"mal/internal/episodes"
|
"mal/internal/episodes"
|
||||||
"mal/internal/playback"
|
"mal/internal/playback"
|
||||||
@@ -19,6 +20,7 @@ import (
|
|||||||
|
|
||||||
func NewApp() *fx.App {
|
func NewApp() *fx.App {
|
||||||
return fx.New(
|
return fx.New(
|
||||||
|
config.Module,
|
||||||
database.Module,
|
database.Module,
|
||||||
jikan.Module,
|
jikan.Module,
|
||||||
allanime.Module,
|
allanime.Module,
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package db
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
|
|
||||||
// sqlite3 driver.
|
// sqlite3 driver.
|
||||||
_ "github.com/mattn/go-sqlite3"
|
_ "github.com/mattn/go-sqlite3"
|
||||||
@@ -17,11 +16,3 @@ func Open(dbFile string) (*sql.DB, error) {
|
|||||||
}
|
}
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetDBFile returns the database file path, checking DATABASE_FILE env var first
|
|
||||||
func GetDBFile() string {
|
|
||||||
if f := os.Getenv("DATABASE_FILE"); f != "" {
|
|
||||||
return f
|
|
||||||
}
|
|
||||||
return "mal.db"
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
package episodes
|
package episodes
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"mal/integrations/jikan"
|
"mal/integrations/jikan"
|
||||||
"mal/integrations/playback/allanime"
|
"mal/integrations/playback/allanime"
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/db"
|
"mal/internal/db"
|
||||||
"mal/internal/domain"
|
"mal/internal/domain"
|
||||||
episodeService "mal/internal/episodes/service"
|
episodeService "mal/internal/episodes/service"
|
||||||
@@ -14,9 +12,8 @@ import (
|
|||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
func episodeAvailabilityEnabled() bool {
|
func episodeAvailabilityEnabled(cfg config.Config) bool {
|
||||||
value := strings.ToLower(strings.TrimSpace(os.Getenv("EPISODE_AVAILABILITY_MODE")))
|
return cfg.EpisodeAvailabilityMode != config.EpisodeAvailabilityModeLegacy && cfg.EpisodeAvailabilityMode != config.EpisodeAvailabilityModeJikan
|
||||||
return value != "legacy" && value != "jikan"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var Module = fx.Options(
|
var Module = fx.Options(
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
package playback
|
package playback
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
|
|
||||||
"mal/integrations/jikan"
|
"mal/integrations/jikan"
|
||||||
"mal/integrations/playback/allanime"
|
"mal/integrations/playback/allanime"
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/domain"
|
"mal/internal/domain"
|
||||||
"mal/internal/playback/handler"
|
"mal/internal/playback/handler"
|
||||||
"mal/internal/playback/repository"
|
"mal/internal/playback/repository"
|
||||||
@@ -14,8 +13,8 @@ import (
|
|||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
)
|
)
|
||||||
|
|
||||||
func provideProxyTokenKey() string {
|
func provideProxyTokenKey(cfg config.Config) string {
|
||||||
return os.Getenv("PLAYBACK_PROXY_SECRET")
|
return cfg.PlaybackProxySecret
|
||||||
}
|
}
|
||||||
|
|
||||||
var Module = fx.Options(
|
var Module = fx.Options(
|
||||||
|
|||||||
@@ -1,16 +1,19 @@
|
|||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"mal/internal/config"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CORSMiddleware() gin.HandlerFunc {
|
func CORSMiddleware() gin.HandlerFunc {
|
||||||
allowAll := os.Getenv("MAL_CORS_ALLOW_ALL") == "1"
|
return CORSMiddlewareWithConfig(config.Config{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func CORSMiddlewareWithConfig(cfg config.Config) gin.HandlerFunc {
|
||||||
|
allowAll := cfg.CORSAllowAll
|
||||||
return func(c *gin.Context) {
|
return func(c *gin.Context) {
|
||||||
origin := c.GetHeader("Origin")
|
origin := c.GetHeader("Origin")
|
||||||
if origin != "" && (allowAll || isAllowedOrigin(origin)) {
|
if origin != "" && (allowAll || isAllowedOrigin(origin)) {
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package server
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"log"
|
"log"
|
||||||
|
"mal/internal/config"
|
||||||
"mal/internal/observability"
|
"mal/internal/observability"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@@ -19,12 +19,14 @@ var Module = fx.Options(
|
|||||||
fx.Invoke(RunServer),
|
fx.Invoke(RunServer),
|
||||||
)
|
)
|
||||||
|
|
||||||
func ProvideRouter(htmlRender render.HTMLRender, metrics *observability.Metrics) *gin.Engine {
|
func ProvideRouter(cfg config.Config, htmlRender render.HTMLRender, metrics *observability.Metrics) *gin.Engine {
|
||||||
if os.Getenv("GIN_MODE") == "" {
|
if cfg.GinMode == "" {
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
} else {
|
||||||
|
gin.SetMode(cfg.GinMode)
|
||||||
}
|
}
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
r.Use(CORSMiddleware(), RequestLogger(metrics), gin.Recovery())
|
r.Use(CORSMiddlewareWithConfig(cfg), RequestLogger(metrics), gin.Recovery())
|
||||||
r.Static("/static", "./static")
|
r.Static("/static", "./static")
|
||||||
r.Static("/dist", "./dist")
|
r.Static("/dist", "./dist")
|
||||||
r.GET("/metrics", gin.WrapH(metrics.Handler()))
|
r.GET("/metrics", gin.WrapH(metrics.Handler()))
|
||||||
@@ -32,11 +34,8 @@ func ProvideRouter(htmlRender render.HTMLRender, metrics *observability.Metrics)
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunServer(lifecycle fx.Lifecycle, r *gin.Engine) {
|
func RunServer(cfg config.Config, lifecycle fx.Lifecycle, r *gin.Engine) {
|
||||||
port := os.Getenv("PORT")
|
port := cfg.Port
|
||||||
if port == "" {
|
|
||||||
port = "3000"
|
|
||||||
}
|
|
||||||
|
|
||||||
srv := newHTTPServer(":"+port, r)
|
srv := newHTTPServer(":"+port, r)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user