obs2hugo/main.go

273 lines
6.7 KiB
Go
Raw Normal View History

2024-04-09 20:06:34 +02:00
package main
import (
"bufio"
2024-04-09 20:06:34 +02:00
"bytes"
"fmt"
"io"
"io/ioutil"
2024-04-09 20:06:34 +02:00
"log"
"os"
"path/filepath"
"regexp"
"strings"
"time"
2024-04-09 20:06:34 +02:00
"github.com/fsnotify/fsnotify"
"github.com/gosimple/slug"
"gopkg.in/ini.v1"
)
func main() {
// Read the config file
home, err := os.UserHomeDir()
if err != nil {
log.Fatalln(err)
}
config, err := ini.Load(home + "/.config/obs2hugo/obs2hugo.ini")
if err != nil {
config, err = ini.Load(home + "/.config/obs2hugo.ini")
if err != nil {
log.Fatalln(err)
}
}
// Watcher directory
directory := config.Section("").Key("watcher_dir").String()
// Hugo content directory
destDir := config.Section("").Key("hugo_dir").String()
2024-04-09 20:21:52 +02:00
// Creating watcher
2024-04-09 20:06:34 +02:00
watcher, err := fsnotify.NewWatcher()
if err != nil {
fmt.Println("Error creating the watcher:", err)
return
}
defer watcher.Close()
// Add directory to the watcher
err = filepath.Walk(directory, func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Println("Error accessing to the directory:", err)
return err
}
if info.IsDir() {
return watcher.Add(path)
}
return nil
})
if err != nil {
fmt.Println("Error adding directory to the watcher:", err)
return
}
// Watcher event loop
for {
select {
case event := <-watcher.Events:
switch {
case event.Op&fsnotify.Create == fsnotify.Create:
fmt.Println("New file:", event.Name)
// TBD
case event.Op&fsnotify.Write == fsnotify.Write:
fmt.Println("File modified:", event.Name)
processModifiedFile(event.Name, directory, destDir)
case event.Op&fsnotify.Remove == fsnotify.Remove:
fmt.Println("File deleted:", event.Name)
// TBD
case event.Op&fsnotify.Rename == fsnotify.Rename:
fmt.Println("File renamed:", event.Name)
// TBD
}
case err := <-watcher.Errors:
fmt.Println("Watcher error:", err)
}
}
}
func processModifiedFile(filePath, directory, destDir string) {
// Slugified file name without extension
fileName := strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))
slug := slug.Make(fileName)
2024-04-09 20:59:11 +02:00
// Creating destination directory
2024-04-09 20:06:34 +02:00
newDir := filepath.Join(destDir, slug)
err := os.MkdirAll(newDir, os.ModePerm)
if err != nil {
fmt.Println("Error creating directory:", err)
return
}
2024-04-09 20:59:11 +02:00
// Copy modified file to the new destination
2024-04-09 20:06:34 +02:00
newFilePath := filepath.Join(newDir, "index.md")
// Check if the file already has frontmatter
hasFrontmatter, err := checkFrontmatter(filePath)
if err != nil {
fmt.Println("Error checking frontmatter:", err)
return
}
// If the file doesn't have frontmatter, add it
if !hasFrontmatter {
err = addFrontmatter(filePath, fileName)
if err != nil {
fmt.Println("Error adding frontmatter:", err)
return
}
}
2024-04-09 20:06:34 +02:00
err = copyFile(filePath, newFilePath)
if err != nil {
fmt.Println("Error copying file:", err)
return
}
// Move images to the gallery directory
err = moveImagesToGallery(filePath, newDir, directory)
if err != nil {
fmt.Println("Error moving images to the gallery:", err)
return
}
}
// Function to check if the file already has frontmatter
func checkFrontmatter(filePath string) (bool, error) {
file, err := os.Open(filePath)
if err != nil {
return false, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
if line == "---" {
return true, nil
}
}
return false, nil
}
// Function to add frontmatter to the file
func addFrontmatter(filePath, title string) error {
// Read the content of the original file
content, err := ioutil.ReadFile(filePath)
if err != nil {
return err
}
// Create a new temporary file with the frontmatter added
tempFilePath := filePath + ".tmp"
frontmatter := fmt.Sprintf("---\ntitle: %s\ndate: %s\ndraft: false\ntags: micropost\n---\n\n", title, time.Now().Format("2006-01-02 15:04:05 -0700"))
err = ioutil.WriteFile(tempFilePath, []byte(frontmatter+string(content)), os.ModePerm)
if err != nil {
return err
}
// Replace the original file with the temporary file
fmt.Println("Rename:", tempFilePath, filePath)
err = os.Rename(tempFilePath, filePath)
if err != nil {
return err
}
return nil
}
2024-04-09 20:06:34 +02:00
func copyFile(src, dst string) error {
sourceFile, err := os.Open(src)
if err != nil {
return err
}
defer sourceFile.Close()
newFile, err := os.Create(dst)
if err != nil {
return err
}
defer newFile.Close()
_, err = io.Copy(newFile, sourceFile)
if err != nil {
return err
}
return nil
}
func moveImagesToGallery(filePath, destDir, directory string) error {
// Routes
destFilePath := filepath.Join(destDir, "index.md")
slugDir := slug.Make(strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath)))
galleryDir := filepath.Join(destDir, "gallery")
// Read file content
content, err := os.ReadFile(filePath)
if err != nil {
return err
}
// Regexp to find the markdown images
re := regexp.MustCompile(`!\[\[([^]]+)\]\]`)
matches := re.FindAllStringSubmatch(string(content), -1)
// Create gallery dir if it doesn't exist
if _, err := os.Stat(galleryDir); os.IsNotExist(err) {
err := os.Mkdir(galleryDir, os.ModePerm)
if err != nil {
return err
}
}
// Move every image found
for _, match := range matches {
imagePath := match[1]
imageName := filepath.Base(imagePath)
ext := filepath.Ext(imageName)
slugName := slug.Make(strings.TrimSuffix(imageName, ext))
imageSrc := filepath.Join(directory, imagePath)
imageDest := filepath.Join(galleryDir, slugName+ext)
// Open source file
srcFile, err := os.Open(imageSrc)
if err != nil {
fmt.Printf("Error opening source file %s: %s\n", imageSrc, err)
continue
}
defer srcFile.Close()
// Create destination file
destFile, err := os.Create(imageDest)
if err != nil {
fmt.Printf("Error creating destination file %s: %s\n", imageDest, err)
continue
}
defer destFile.Close()
// Copy source to destination
_, err = io.Copy(destFile, srcFile)
if err != nil {
fmt.Printf("Error copying file %s to %s: %s\n", imageSrc, imageDest, err)
continue
}
// Modify link text
newImageMarkdown := fmt.Sprintf("![%s](%s/gallery/%s)", strings.TrimSuffix(slugName, ext), slugDir, slugName+ext)
content = bytes.Replace(content, []byte(match[0]), []byte(newImageMarkdown), -1)
fmt.Printf("Image %s was copied to %s\n", imageSrc, imageDest)
}
// Replace [gallery] pattern
content = bytes.Replace(content, []byte("[gallery]"), []byte("{{< gallery match=\"gallery/*\" sortOrder=\"asc\" rowHeight=\"150\" margins=\"5\" thumbnailResizeOptions=\"600x600 q90 Lanczos\" previewType=\"blur\" embedPreview=\"true\" >}}"), -1)
// Write markdown file new content
err = os.WriteFile(destFilePath, content, os.ModePerm)
if err != nil {
fmt.Printf("Error writing file content to the file: %s: %s\n", filePath, err)
}
return nil
}