weiro/handlers/obsimport.go
exe.dev user 6bab58f1af Add Obsidian vault import feature
- New 'Import Obsidian' action on site settings page
- Upload a zip file of an Obsidian vault to import all notes as posts
- Markdown notes imported with title from filename, published date from
  file timestamp, and body with front-matter stripped
- Images and other attachments saved as Upload records
- New obsimport service handles zip traversal and import logic
- Unit tests for front-matter stripping

Co-authored-by: Shelley <shelley@exe.dev>
2026-04-09 11:37:11 +00:00

51 lines
1.1 KiB
Go

package handlers
import (
"fmt"
"os"
"path/filepath"
"github.com/gofiber/fiber/v3"
"lmika.dev/lmika/weiro/models"
"lmika.dev/lmika/weiro/services/obsimport"
)
type ObsImportHandler struct {
ObsImportService *obsimport.Service
ScratchDir string
}
func (h ObsImportHandler) Form(c fiber.Ctx) error {
return c.Render("obsimport/form", fiber.Map{})
}
func (h ObsImportHandler) Upload(c fiber.Ctx) error {
site := c.Locals("site").(models.Site)
fileHeader, err := c.FormFile("zipfile")
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "no file provided")
}
// Save uploaded file to scratch dir
if err := os.MkdirAll(h.ScratchDir, 0755); err != nil {
return err
}
dstPath := filepath.Join(h.ScratchDir, models.NewNanoID()+".zip")
if err := c.SaveFile(fileHeader, dstPath); err != nil {
return err
}
defer os.Remove(dstPath)
result, err := h.ObsImportService.ImportZip(c.Context(), dstPath)
if err != nil {
return err
}
return c.Render("obsimport/result", fiber.Map{
"result": result,
"siteURL": fmt.Sprintf("/sites/%v/posts", site.ID),
})
}