package main import ( "bufio" "context" "log/slog" "os" "strings" "shared-album/internal/config" "shared-album/internal/db" "shared-album/internal/photos" "shared-album/internal/storage" ) func main() { loadDotEnv(".env") loadDotEnv("../.env") logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo})) slog.SetDefault(logger) cfg, err := config.Load() if err != nil { slog.Error("config error", "error", err) os.Exit(1) } ctx := context.Background() pool, err := db.Connect(ctx, cfg.Postgres.DSN()) if err != nil { slog.Error("database connect failed", "error", err) os.Exit(1) } defer pool.Close() store, err := storage.Open(ctx, cfg) if err != nil { slog.Error("storage init failed", "error", err) os.Exit(1) } photoStore := photos.NewStore(pool) updated, err := photoStore.BackfillEXIF(ctx, store.Get) if err != nil { slog.Error("backfill failed", "error", err) os.Exit(1) } slog.Info("exif backfill complete", "updated", updated) } func loadDotEnv(path string) { f, err := os.Open(path) if err != nil { return } defer f.Close() scanner := bufio.NewScanner(f) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if line == "" || strings.HasPrefix(line, "#") { continue } key, value, ok := strings.Cut(line, "=") if !ok { continue } key = strings.TrimSpace(key) value = strings.TrimSpace(value) if _, exists := os.LookupEnv(key); !exists { _ = os.Setenv(key, value) } } }