package main import ( "encoding/json" "math/rand" "os" "time" "github.com/aquilax/go-perlin" "github.com/charmbracelet/log" ) const ( bannersDir = "./banners" // mountable fontPath = "./fonts/PixelOperator-Bold.ttf" configFile = "./config.json" // mountable ) var ( config Config perlinNoise perlin.Perlin ) type Config struct { ClearwebURL string `json:"clearweb_url"` OnionURL string `json:"onion_url"` ColorThemes []string `json:"color_themes"` MaxBanners uint `json:"max_banners"` BannerWidth int `json:"banner_width"` BannerHeight int `json:"banner_height"` LogLevel log.Level `json:"log_level"` // -4=DBG, 0=INFO, 4=WARN, 8=ERR, 12=FATAL } type BannerInfo struct { Filename string CreatedAt time.Time } func init() { config = Config{ ClearwebURL: "https://example.com", OnionURL: "http://example.onion", ColorThemes: []string{ "vibrant", "sunset", "ocean", "neon", "cosmic", "midnight", "fire", "pastel", "earth", "ice", "autumn", "cyberpunk", "retro", "monochrome", "tropical", "volcanic", "aurora", "desert", "matrix", }, MaxBanners: 50, BannerWidth: 600, BannerHeight: 120, LogLevel: log.InfoLevel, } if data, err := os.ReadFile(configFile); err == nil { if err := json.Unmarshal(data, &config); err != nil { log.Fatalf("Error parsing config: %s", err) os.Exit(1) } } else { data, _ := json.MarshalIndent(config, "", " ") os.WriteFile(configFile, data, 0644) log.Info("Created default config - please update your URLs into it") os.Exit(0) } log.SetLevel(config.LogLevel) if err := os.MkdirAll(bannersDir, 0755); err != nil { log.Fatalf("Error creating banner output directory: %s", err) os.Exit(1) } if err := initFontManager(); err != nil { log.Fatalf("Error initializing font manager: %s", err) os.Exit(1) } // perlin input params: alpha, beta, octaves, seed perlinNoise = *perlin.NewPerlin(2.0, 2.0, 3, rand.Int63()) } func main() { // TODO: cli param `--portable ` for instant generation of n banners // TODO: ticker setup for banner rotation // NOTE: makes the life a lot easier to draw the bigger element first, // then find a place for the smaller one textData := []*TextData{ NewTextData(config.OnionURL, defaultFontSize, true), NewTextData(config.ClearwebURL, defaultFontSize+4.0, false), } for range 25 { if err := genBanner(textData); err != nil { log.Errorf("Error generating banner: %s", err) } } }