hugo-medialog/internal/books/controller.go
2024-10-14 16:52:23 +02:00

116 lines
3.0 KiB
Go

package books
import (
"fmt"
"hugo-medialog/utils"
"os"
"path/filepath"
"gopkg.in/yaml.v2"
)
func LoadBooks() ([]Book, error) {
booksFile := os.Getenv("OBSIDIAN_BOOKS_FILE")
fileData, err := os.ReadFile(booksFile)
if err != nil {
return nil, err
}
var books []Book
err = yaml.Unmarshal(fileData, &books)
if err != nil {
return nil, err
}
return books, nil
}
func ProcessBooks(books []Book, update bool) error {
fmt.Printf(" B O O K S\n")
utils.Sep()
for _, book := range books {
fmt.Printf("Title: %s\n", book.Title)
// If we're updating, the process is a bit different
if update || !book.New {
outputDir := os.Getenv("MARKDOWN_OUTPUT_BOOKS_DIR")
mdFilePath := filepath.Join(outputDir, fmt.Sprintf("%s.md", utils.Sluggify(book.Title)))
frontmatter, content, err := utils.LoadMarkdown(mdFilePath)
if err != nil {
fmt.Printf(" ! Error loading markdown frontmatter for book %s: %v\n", book.Title, err)
continue
}
updatedFrontmatter := updateFrontmatterWithYAML(frontmatter, book)
err = utils.SaveUpdatedMarkdown(mdFilePath, updatedFrontmatter, content)
if err != nil {
fmt.Printf(" ! Error saving updated markdown for book %s: %v\n", book.Title, err)
continue
}
// We want to continue the loop here, in update's cases we don't
// want to do any api calls for info nor for images
continue
}
// If we dont have ID, search movie by Title and get the ID
if book.ID == "" {
err := SearchBookByTitle(book.Title, &book)
if err != nil {
fmt.Printf(" ! Error searching book by title %s: %s\n", book.Title, err)
continue
}
}
book.Slug = utils.Sluggify(book.Title)
// Now we need to get the image
imageURL := getBookCoverByTitle(book.Title)
if imageURL != "" {
err := DownloadImage(imageURL, book.Slug)
if err != nil {
fmt.Printf(" ! Error downloading %s: %s\n", imageURL, err)
}
}
book.Image = fmt.Sprintf("%s.jpg", book.Slug)
err := generateBookMarkdown(book)
if err != nil {
return err
}
utils.Sep()
}
return nil
}
func generateBookMarkdown(book Book) error {
templatePath := filepath.Join(os.Getenv("TEMPLATES_DIR"), "book.md.tpl")
outputDir := os.Getenv("MARKDOWN_OUTPUT_BOOKS_DIR")
if err := utils.CreateDirIfNotExists(outputDir); err != nil {
return err
}
outputPath := filepath.Join(outputDir, fmt.Sprintf("%s.md", book.Slug))
data := map[string]interface{}{
"Title": book.Title,
"Author": book.Author,
"Link": book.Link,
"Subtitle": book.Year,
"Year": book.Year,
"Rate": book.Rate,
"Pages": book.Pages,
"Progress": book.Progress,
"Image": book.Image,
"Date": book.Date,
"Tags": "reading",
}
return utils.GenerateMarkdown(templatePath, outputPath, data)
}
// Helper function to update only YAML fields that exist in both the frontmatter and YAML data
func updateFrontmatterWithYAML(frontmatter utils.FrontMatter, book Book) utils.FrontMatter {
frontmatter.Progress = book.Progress
frontmatter.Date = book.Date
frontmatter.Rate = book.Rate
return frontmatter
}