summaryrefslogtreecommitdiff
path: root/main.go
diff refs
from: back
to: back
| flip
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/main.go b/main.go
new file mode 100644
index 0000000..6648aeb
--- /dev/null
+++ b/main.go
@@ -0,0 +1,112 @@
+package main
+
+import (
+ "flag"
+ "io/fs"
+ "log/slog"
+ "os"
+ "path/filepath"
+ "strings"
+ "sync"
+
+ "github.com/SayaAndy/saya-today-article-metadata-add/config"
+ "github.com/SayaAndy/saya-today-article-metadata-add/internal/draft"
+ "github.com/SayaAndy/saya-today-article-metadata-add/internal/transcoder"
+)
+
+var configPath = flag.String("c", "config.json", "Path to the configuration file")
+
+func main() {
+ flag.Parse()
+
+ cfg, err := config.InitConfig(*configPath)
+ if err != nil {
+ slog.Error("fail to load configuration", slog.String("error", err.Error()))
+ os.Exit(1)
+ }
+
+ slog.SetLogLoggerLevel(cfg.LogLevel)
+ slog.Info("starting metadata extractor...")
+
+ transcoders := make([]transcoder.Transcoder, 0, len(cfg.Transcoders))
+ for _, tcCfg := range cfg.Transcoders {
+ newTranscoder, ok := transcoder.NewTranscoderMap[tcCfg.Type]
+ if !ok {
+ slog.Error("unsupported transcoder type", slog.String("type", tcCfg.Type))
+ os.Exit(1)
+ }
+ t, err := newTranscoder(tcCfg.Config)
+ if err != nil {
+ slog.Error("fail to initialize transcoder", slog.String("type", tcCfg.Type), slog.String("error", err.Error()))
+ os.Exit(1)
+ }
+ transcoders = append(transcoders, t)
+ slog.Info("initialized transcoder", slog.String("type", tcCfg.Type))
+ }
+
+ var drafts []string
+ err = filepath.WalkDir(cfg.DraftDir, func(path string, d fs.DirEntry, err error) error {
+ if err != nil {
+ return err
+ }
+ if d.IsDir() {
+ return nil
+ }
+ if strings.HasSuffix(path, cfg.DraftSuffix) {
+ drafts = append(drafts, path)
+ }
+ return nil
+ })
+ if err != nil {
+ slog.Error("fail to scan draft directory", slog.String("dir", cfg.DraftDir), slog.String("error", err.Error()))
+ os.Exit(1)
+ }
+ slog.Info("scanned drafts", slog.Int("draft_count", len(drafts)))
+
+ semaphore := make(chan struct{}, cfg.MaxConcurrentJobs)
+ var wg sync.WaitGroup
+ wg.Add(len(drafts))
+
+ for _, draftPath := range drafts {
+ semaphore <- struct{}{}
+ go func(path string) {
+ defer wg.Done()
+ defer func() { <-semaphore }()
+
+ codename := strings.TrimSuffix(filepath.Base(path), cfg.DraftSuffix)
+ fileLogger := slog.With(slog.String("draft", path), slog.String("codename", codename))
+
+ content, err := os.ReadFile(path)
+ if err != nil {
+ fileLogger.Warn("fail to read draft", slog.String("error", err.Error()))
+ return
+ }
+
+ doc, err := draft.ParseDraft(path, codename, content)
+ if err != nil {
+ fileLogger.Warn("fail to parse draft", slog.String("error", err.Error()))
+ return
+ }
+ if doc.Metadata == nil {
+ fileLogger.Info("skip draft without frontmatter metadata")
+ return
+ }
+
+ for _, t := range transcoders {
+ if err := t.Transcode(doc); err != nil {
+ fileLogger.Warn("transcoder failed", slog.String("transcoder", t.Name()), slog.String("error", err.Error()))
+ }
+ }
+ }(draftPath)
+ }
+
+ wg.Wait()
+
+ for _, t := range transcoders {
+ if err := t.Finalize(); err != nil {
+ slog.Error("fail to finalize transcoder", slog.String("transcoder", t.Name()), slog.String("error", err.Error()))
+ os.Exit(1)
+ }
+ slog.Info("finalized transcoder", slog.String("transcoder", t.Name()))
+ }
+}