Óscar M. Lage
ad9b786f45
If frontmatter doesn't exist in the sourfe file, add it automatically so you don't have to remember it.
273 lines
6.7 KiB
Go
273 lines
6.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"time"
|
|
|
|
"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()
|
|
|
|
// Creating watcher
|
|
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)
|
|
|
|
// Creating destination directory
|
|
newDir := filepath.Join(destDir, slug)
|
|
err := os.MkdirAll(newDir, os.ModePerm)
|
|
if err != nil {
|
|
fmt.Println("Error creating directory:", err)
|
|
return
|
|
}
|
|
|
|
// Copy modified file to the new destination
|
|
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
|
|
}
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
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
|
|
}
|