diff options
| author | Paul Buetow <paul@buetow.org> | 2024-09-21 15:54:11 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2024-09-21 15:54:11 +0300 |
| commit | d38f93fc4fdb54687c425b8866bc99cbd9ad7935 (patch) | |
| tree | ca5e5b3c582ea373aa6b9193d2e047e2fb06c2f5 | |
| parent | dff4d455e07d639b82a0bed814f41d0656e9b6d0 (diff) | |
initial revamp
| -rw-r--r-- | cmd/gos/main.go | 42 | ||||
| -rw-r--r-- | internal/config/args.go | 7 | ||||
| -rw-r--r-- | internal/oi/oi.go | 87 | ||||
| -rw-r--r-- | internal/queue/queue.go | 91 | ||||
| -rw-r--r-- | internal/run.go | 12 |
5 files changed, 239 insertions, 0 deletions
diff --git a/cmd/gos/main.go b/cmd/gos/main.go new file mode 100644 index 0000000..67f3351 --- /dev/null +++ b/cmd/gos/main.go @@ -0,0 +1,42 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "strings" + "time" + + "codeberg.org/snonux/gos/internal" + "codeberg.org/snonux/gos/internal/config" +) + +const versionStr = "v0.0.0" + +func main() { + dry := flag.Bool("dry", false, "Dry run") + version := flag.Bool("version", false, "Display version") + gosDir := flag.String("gosDir", "./gosdir", "Gos' directory") + platforms := flag.String("platforms", "Mastodon,LinkedIn", "Platforms enabled") + flag.Parse() + + args := config.Args{ + DryRun: *dry, + GosDir: *gosDir, + Platforms: strings.Split(*platforms, ","), + } + + if *version { + fmt.Printf("This is Gos version %s; (C) by Paul Buetow\n", versionStr) + fmt.Println("https://codeberg.org/snonux/gos") + return + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(1*time.Minute)) + defer cancel() + + if err := internal.Run(ctx, args); err != nil { + log.Fatal(err) + } +} diff --git a/internal/config/args.go b/internal/config/args.go new file mode 100644 index 0000000..5b16912 --- /dev/null +++ b/internal/config/args.go @@ -0,0 +1,7 @@ +package config + +type Args struct { + GosDir string + DryRun bool + Platforms []string +} diff --git a/internal/oi/oi.go b/internal/oi/oi.go new file mode 100644 index 0000000..00b4dd5 --- /dev/null +++ b/internal/oi/oi.go @@ -0,0 +1,87 @@ +package oi + +import ( + "fmt" + "io" + "os" + "path/filepath" +) + +func EnsureDirExists(dir string) error { + if _, err := os.Stat(dir); os.IsNotExist(err) { + return os.MkdirAll(dir, os.ModePerm) + } + return nil +} + +func ReadDirFilter(dir string, filter func(file os.DirEntry) bool) (chan string, error) { + ch := make(chan string) + + if err := EnsureDirExists(dir); err != nil { + return ch, err + } + + files, err := os.ReadDir(dir) + if err != nil { + return ch, err + } + + go func() { + defer close(ch) + for _, file := range files { + if filter(file) { + ch <- filepath.Join(dir, file.Name()) + } + } + }() + + return ch, nil +} + +func ReadDirSlurp(dir string, filter func(file os.DirEntry) bool) ([]string, error) { + var files []string + + ch, err := ReadDirFilter(dir, filter) + if err != err { + return files, err + } + + for file := range ch { + files = append(files, file) + } + + return files, nil +} + +func IsRegular(path string) bool { + stat, err := os.Stat(path) + if err != nil { + return false + } + return stat.Mode().IsRegular() +} + +func CopyFile(srcPath, dstPath string) error { + if !IsRegular(srcPath) { + return fmt.Errorf("%s is not a regular file", srcPath) + } + + source, err := os.Open(srcPath) + if err != nil { + return err + } + defer source.Close() + + if err := EnsureDirExists(dstPath); err != nil { + return err + } + + destination, err := os.Create(dstPath) + if err != nil { + return err + } + defer destination.Close() + + _, err = io.Copy(destination, source) + return err +} diff --git a/internal/queue/queue.go b/internal/queue/queue.go new file mode 100644 index 0000000..71dde71 --- /dev/null +++ b/internal/queue/queue.go @@ -0,0 +1,91 @@ +package queue + +import ( + "fmt" + "log" + "os" + "path/filepath" + "slices" + "strings" + "time" + + "codeberg.org/snonux/gos/internal/config" + "codeberg.org/snonux/gos/internal/oi" +) + +func Run(args config.Args) error { + if err := queueEntries(args); err != nil { + return err + } + if err := queuePlatforms(args); err != nil { + return err + } + return nil +} + +// Queue all *.txt into ./db/*.txt.STAMP.queued +func queueEntries(args config.Args) error { + // Strictly, we only operate on .txt files, but we also accept .md as Obsidian creates only .md files. + var validExtensions = []string{".txt", ".md"} + + ch, err := oi.ReadDirFilter(args.GosDir, func(entry os.DirEntry) bool { + return slices.Contains(validExtensions, filepath.Ext(entry.Name())) && + entry.Type().IsRegular() + }) + if err != err { + return err + } + + now := time.Now() + for filePath := range ch { + destPath := fmt.Sprintf("%s/db/%s.%s.queued", args.GosDir, + now.Format("20060102-150405"), filepath.Base(filePath)) + if err := os.Rename(filePath, destPath); err != nil { + return err + } + } + + return nil +} + +// Queue all ./db/queued/*.txt.STAMP.queued into ./db/platforms/PLATFORM/*.txt.STAMP.queued +// for each PLATFORM +func queuePlatforms(args config.Args) error { + dbDir := fmt.Sprintf("%s/db", args.GosDir) + ch, err := oi.ReadDirFilter(dbDir, func(entry os.DirEntry) bool { + return strings.HasSuffix(entry.Name(), ".queued") + }) + if err != err { + return err + } + + for filePath := range ch { + for _, platform := range args.Platforms { + if err := queuePlatform(filePath, args.GosDir, platform); err != nil { + return err + } + } + log.Println("Removing", filePath) + if err := os.Remove(filePath); err != nil { + return err + } + } + + return nil +} + +// Queue ./db/queued/*.txt.STAMP.queued to ./db/platforms/PLATFORM/*.txt.STAMP.queued +func queuePlatform(entryPath, gosDir, platform string) error { + destDir := fmt.Sprintf("%s/db/platforms/%s/", gosDir, strings.ToLower(platform)) + destPath := fmt.Sprintf("%s/%s", destDir, filepath.Base(entryPath)) + postedFile := fmt.Sprintf("%s.posted", strings.TrimSuffix(destPath, ".queued")) + + // Entry already posted platform? + if oi.IsRegular(postedFile) { + log.Println("Not re-queueing", destPath, "as", postedFile, "already exists") + return nil + } + + log.Println("Queuing", entryPath, "->", destPath) + return oi.CopyFile(entryPath, destPath) +} diff --git a/internal/run.go b/internal/run.go new file mode 100644 index 0000000..feb69f8 --- /dev/null +++ b/internal/run.go @@ -0,0 +1,12 @@ +package internal + +import ( + "context" + + "codeberg.org/snonux/gos/internal/config" + "codeberg.org/snonux/gos/internal/queue" +) + +func Run(ctx context.Context, args config.Args) error { + return queue.Run(args) +} |
