-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.go
150 lines (130 loc) · 6.15 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Generator is a static site generator for my site.
package main
import (
"fmt"
"reflect"
"time"
"github.com/BurntSushi/toml"
"github.com/charmbracelet/log"
flags "github.com/jessevdk/go-flags"
"github.com/meilisearch/meilisearch-go"
i "github.com/nicksnyder/go-i18n/v2/i18n"
"golang.org/x/text/language"
)
// Config is a struct that holds all configuration options
type Config struct {
ContentDirectory string `env:"CONTENT_DIR" long:"content" description:"content directory" default:"content"`
TemplatesDirectory string `env:"TEMPLATES_DIR" long:"templates" description:"templates directory" default:"templates"`
OutputDirectory string `env:"OUTPUT_DIR" long:"output" description:"output directory" default:"output"`
TempDirectory string `env:"TEMP_DIR" long:"temp" description:"temp directory" default:""`
DefaultLanguage string `env:"DEFAULT_LANG" long:"default-lang" description:"default language" default:"en"`
RootURL string `env:"ROOT_URL" long:"root-url" description:"root url" default:"https://local.chuhlomin.com"`
CommentsSiteID string `env:"COMMENTS_SITE_ID" long:"comments-site-id" description:"comments site id"`
CacheDirectory string `env:"CACHE_DIR" long:"cache-dir" description:"cache directory" default:"cache"`
I18NDirectory string `env:"I18N_DIR" long:"i18n-dir" description:"i18n directory" default:"i18n"`
SearchHost string `env:"SEARCH_HOST" long:"search-host" description:"search host" default:"https://local.chuhlomin.com/blog/search"`
SearchMasterKey string `env:"SEARCH_MASTER_KEY" long:"search-master-key" description:"search master key, used to create index"`
SearchAPIKey string `env:"SEARCH_API_KEY" long:"search-api-key" description:"search api key, used on frontend to search"`
ThumbPath string `env:"THUMB_PATH" long:"thumb-path" description:"path to thumbnails" default:"/img/thumbs/"`
OpenGraphCacheFile string `env:"OPENGRAPH_CACHE_FILE" long:"opengraph-cache-file" description:"opengraph cache file" default:"cache.yml"`
PhotosDomain string `env:"PHOTOS_DOMAIN" long:"photos-domain" description:"photos domain" default:"https://photos.chuhlomin.com/"`
FilesChannelSize int `env:"FILES_CHANNEL_SIZE" long:"files-channel-size" description:"size of file channel" default:"100"`
ImagesChannelSize int `env:"IMAGES_CHANNEL_SIZE" long:"images-channel-size" description:"size of images channel" default:"100"`
SearchTimeout time.Duration `env:"SEARCH_TIMEOUT" long:"search-timeout" description:"search timeout" default:"5s"`
NumWorkers int `env:"NUM_WORKERS" long:"workers" description:"number of workers" default:"4"`
ThumbMaxWidth int `env:"THUMB_MAX_WIDTH" long:"thumb-max-width" description:"max width of thumbnails" default:"140"`
ThumbMaxHeight int `env:"THUMB_MAX_HEIGHT" long:"thumb-max-height" description:"max height of thumbnails" default:"140"`
OpenGraphTimeout time.Duration `env:"OPENGRAPH_TIMEOUT" long:"opengraph-timeout" description:"opengraph timeout" default:"5s"`
Debug bool `env:"DEBUG" long:"debug" description:"debug mode"`
RemoveHTMLExtension bool `env:"REMOVE_HTML_EXT" long:"remove-html-ext" description:"remove .html extension from urls"`
CommentsEnabled bool `env:"COMMENTS_ENABLED" long:"comments-enabled" description:"enable comments"`
ShowDrafts bool `env:"SHOW_DRAFTS" long:"show-drafts" description:"show drafts"`
SearchEnabled bool `env:"SEARCH_ENABLED" long:"search-enabled" description:"enable search"`
}
// GetString returns the value of the environment variable named by the key.
// If the variable is not present, GetString returns empty string.
// Used in `config` template function to access config values.
func (c Config) GetString(key string) string {
// use reflect to get the value of the key
v := reflect.ValueOf(c)
for i := 0; i < v.NumField(); i++ {
if v.Field(i).Kind() != reflect.String {
continue
}
if v.Type().Field(i).Name == key {
return v.Field(i).String()
}
}
return ""
}
// GetBool returns the value of the environment variable named by the key.
// If the variable is not present, GetBool returns `false`.
// Used in `enabled` template function to access config values.
func (c Config) GetBool(key string) bool {
// use reflect to get the value of the key
v := reflect.ValueOf(c)
for i := 0; i < v.NumField(); i++ {
if v.Field(i).Kind() != reflect.Bool {
continue
}
if v.Type().Field(i).Name == key {
return v.Field(i).Bool()
}
}
return false
}
var (
ts time.Time // timestamp used to measure execution time
cfg Config // global config
bundle *i.Bundle // used in templates/i18n to get translated strings
)
func main() {
log.Info("Starting")
ts = time.Now()
if err := run(ts); err != nil {
log.Fatal(err)
}
log.Infof("Finished in %v", time.Now().Sub(ts))
}
func run(ts time.Time) error {
_, err := flags.Parse(&cfg)
if err != nil {
return fmt.Errorf("Error parsing flags: %v", err)
}
if cfg.Debug {
log.SetLevel(log.DebugLevel)
}
if err := initBundle(); err != nil {
return fmt.Errorf("Error initializing i18n bundle: %v", err)
}
og, err := newOpenGraphClient(cfg.OpenGraphTimeout, cfg.OpenGraphCacheFile)
if err != nil {
return fmt.Errorf("Error creating opengraph client: %v", err)
}
defer og.Save(cfg.OpenGraphCacheFile)
var searchClient *meilisearch.Client
if cfg.SearchEnabled {
searchClient = meilisearch.NewClient(meilisearch.ClientConfig{
Host: cfg.SearchHost,
APIKey: cfg.SearchMasterKey,
Timeout: cfg.SearchTimeout,
})
}
generator, err := NewGenerator(og, searchClient)
if err != nil {
return fmt.Errorf("Error creating generator: %v", err)
}
return generator.Run(ts)
}
func initBundle() error {
if cfg.DefaultLanguage == "" {
cfg.DefaultLanguage = "en"
}
lang, err := language.Parse(cfg.DefaultLanguage)
if err != nil {
return fmt.Errorf("parse language %q", cfg.DefaultLanguage)
}
bundle = i.NewBundle(lang)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
return nil
}