219 lines
6.3 KiB
Go
219 lines
6.3 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"gopkg.in/yaml.v2"
|
|
"log"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
BlogUrl string
|
|
MediaEndpointUrl string
|
|
IgnoredWebmentionUrls []string
|
|
SyndicationTargets []SyndicationTarget
|
|
SelectedStorage Storage
|
|
SelectedMediaStorage MediaStorage
|
|
SelectedCdn Cdn
|
|
SelectedNotificationServices NotificationServices
|
|
SelectedImageCompression ImageCompression
|
|
DefaultLanguage string
|
|
Languages map[string]Language
|
|
)
|
|
|
|
type SyndicationTarget struct {
|
|
Uid string `json:"uid"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type YamlConfig struct {
|
|
BlogUrl string `yaml:"blogUrl"`
|
|
BaseUrl string `yaml:"baseUrl"`
|
|
MediaUrl string `yaml:"mediaUrl"`
|
|
DefaultLanguage string `yaml:"defaultLang"`
|
|
Languages map[string]Language `yaml:"languages"`
|
|
Git GitConfig `yaml:"git"`
|
|
BunnyCdn BunnyCdnConfig `yaml:"bunnyCdn"`
|
|
Telegram TelegramConfig `yaml:"telegram"`
|
|
Tinify TinifyConfig `yaml:"tinify"`
|
|
IgnoredWebmentionUrls []string `yaml:"ignoreWebmention"`
|
|
SyndicationTargets []string `yaml:"syndication"`
|
|
}
|
|
|
|
type BunnyCdnConfig struct {
|
|
Key string `yaml:"key"`
|
|
StorageKey string `yaml:"storageKey"`
|
|
StorageName string `yaml:"storageName"`
|
|
}
|
|
|
|
type TelegramConfig struct {
|
|
UserId int `yaml:"userId"`
|
|
BotToken string `yaml:"botToken"`
|
|
}
|
|
|
|
type TinifyConfig struct {
|
|
Key string `yaml:"key"`
|
|
}
|
|
|
|
type GitConfig struct {
|
|
Filepath string `yaml:"filepath"`
|
|
Url string `yaml:"url"`
|
|
Username string `yaml:"username"`
|
|
Password string `yaml:"password"`
|
|
AuthorName string `yaml:"authorName"`
|
|
AuthorEmail string `yaml:"authorEmail"`
|
|
}
|
|
|
|
type Language struct {
|
|
BlogUrl string `yaml:"blogUrl"`
|
|
ContentDir string `yaml:"contentDir"`
|
|
DefaultSection string `yaml:"defaultSection"`
|
|
Sections map[string]Section `yaml:"sections"`
|
|
}
|
|
|
|
type Section struct {
|
|
FilenameTemplate string `yaml:"file"`
|
|
LocationTemplate string `yaml:"location"`
|
|
}
|
|
|
|
func initConfig() (err error) {
|
|
configFileName, configSet := os.LookupEnv("CONFIG")
|
|
if !configSet {
|
|
configFileName = "config.yml"
|
|
}
|
|
configFile, err := os.Open(configFileName)
|
|
if err != nil {
|
|
return errors.New("failed to open config file")
|
|
}
|
|
cfg := YamlConfig{}
|
|
err = yaml.NewDecoder(configFile).Decode(&cfg)
|
|
if err != nil {
|
|
return errors.New("failed to parse yaml")
|
|
}
|
|
// Blog URL (required)
|
|
if len(cfg.BlogUrl) < 1 {
|
|
return errors.New("blogUrl not configured")
|
|
}
|
|
if !strings.HasSuffix(cfg.BlogUrl, "/") {
|
|
return errors.New("missing trailing slash in configured blogUrl")
|
|
}
|
|
BlogUrl = cfg.BlogUrl
|
|
// Media endpoint (required)
|
|
if len(cfg.BaseUrl) < 1 {
|
|
return errors.New("baseUrl not configured")
|
|
}
|
|
if len(cfg.MediaUrl) < 1 {
|
|
return errors.New("mediaUrl not configured")
|
|
}
|
|
if !strings.HasSuffix(cfg.BaseUrl, "/") {
|
|
return errors.New("missing trailing slash in configured baseUrl")
|
|
}
|
|
MediaEndpointUrl = cfg.BaseUrl + "media"
|
|
// Languages (required)
|
|
if len(cfg.DefaultLanguage) < 1 {
|
|
return errors.New("no default language configured")
|
|
}
|
|
DefaultLanguage = cfg.DefaultLanguage
|
|
if len(cfg.Languages) > 0 {
|
|
for _, lang := range cfg.Languages {
|
|
if len(lang.ContentDir) < 1 || len(lang.DefaultSection) < 1 || len(lang.Sections) < 1 {
|
|
return errors.New("language not completely configured")
|
|
}
|
|
for _, section := range lang.Sections {
|
|
if len(section.FilenameTemplate) < 1 || len(section.LocationTemplate) < 1 {
|
|
return errors.New("section not completely configured")
|
|
}
|
|
}
|
|
}
|
|
Languages = cfg.Languages
|
|
} else {
|
|
return errors.New("no languages configured")
|
|
}
|
|
// Ignored Webmention URLs (optional)
|
|
IgnoredWebmentionUrls = cfg.IgnoredWebmentionUrls
|
|
// Syndication Targets (optional)
|
|
targets := make([]SyndicationTarget, 0)
|
|
for _, url := range cfg.SyndicationTargets {
|
|
targets = append(targets, SyndicationTarget{
|
|
Uid: url,
|
|
Name: url,
|
|
})
|
|
}
|
|
SyndicationTargets = targets
|
|
// Find selected storage
|
|
SelectedStorage = func() Storage {
|
|
// Git
|
|
if len(cfg.Git.Filepath) > 0 && len(cfg.Git.Url) > 0 && len(cfg.Git.Username) > 0 && len(cfg.Git.Password) > 0 && len(cfg.Git.AuthorName) > 0 && len(cfg.Git.AuthorEmail) > 0 {
|
|
return &Git{
|
|
filepath: cfg.Git.Filepath,
|
|
url: cfg.Git.Url,
|
|
username: cfg.Git.Username,
|
|
password: cfg.Git.Password,
|
|
name: cfg.Git.AuthorName,
|
|
email: cfg.Git.AuthorEmail,
|
|
}
|
|
}
|
|
return nil
|
|
}()
|
|
if SelectedStorage == nil {
|
|
return errors.New("no storage configured")
|
|
}
|
|
// Find selected media storage (Optional)
|
|
SelectedMediaStorage = func() MediaStorage {
|
|
// BunnyCDN
|
|
// MEDIA_URL needs trailing slash too
|
|
if len(cfg.BunnyCdn.StorageKey) > 0 && len(cfg.BunnyCdn.StorageName) > 0 && len(cfg.MediaUrl) > 0 && strings.HasSuffix(cfg.MediaUrl, "/") {
|
|
return &BunnyCdnStorage{
|
|
key: cfg.BunnyCdn.StorageKey,
|
|
storageZoneName: cfg.BunnyCdn.StorageName,
|
|
baseLocation: cfg.MediaUrl,
|
|
}
|
|
}
|
|
return nil
|
|
}()
|
|
if SelectedMediaStorage == nil {
|
|
log.Println("no media storage configured")
|
|
}
|
|
// Find selected CDN (optional)
|
|
SelectedCdn = func() Cdn {
|
|
// BunnyCDN
|
|
if len(cfg.BunnyCdn.Key) > 0 {
|
|
return &BunnyCdn{key: cfg.BunnyCdn.Key}
|
|
}
|
|
return nil
|
|
}()
|
|
if SelectedCdn == nil {
|
|
log.Println("no CDN configured")
|
|
}
|
|
// Find configured notification services (optional)
|
|
SelectedNotificationServices = func() NotificationServices {
|
|
var notificationServices []NotificationService = nil
|
|
// Telegram
|
|
if cfg.Telegram.UserId > 0 && len(cfg.Telegram.BotToken) > 0 {
|
|
notificationServices = append(notificationServices, &Telegram{
|
|
userId: cfg.Telegram.UserId,
|
|
botToken: cfg.Telegram.BotToken,
|
|
})
|
|
}
|
|
return notificationServices
|
|
}()
|
|
if SelectedNotificationServices == nil {
|
|
log.Println("No notification services configured")
|
|
}
|
|
// Find configured image compression service (optional)
|
|
SelectedImageCompression = func() ImageCompression {
|
|
// Tinify
|
|
if len(cfg.Tinify.Key) > 0 {
|
|
return &Tinify{
|
|
key: cfg.Tinify.Key,
|
|
}
|
|
}
|
|
return nil
|
|
}()
|
|
if SelectedImageCompression == nil {
|
|
log.Println("no image compression configured")
|
|
}
|
|
return nil
|
|
}
|