feat(export): Obsidian-compatible Markdown vault as streamed ZIP
- GET /export/markdown streams the workspace as ZIP (no temp files): notes as .md with YAML front matter in the user's folder structure (shared notes and mounted folders included, empty folders kept) - Clean Markdown: top-level headings/dividers/callouts/code as real blocks (their children move up a level), lists with tabs, todos as - [ ] - Aufgaben/<list>.md in Obsidian Tasks format (due date, priority, subtasks, notes), Listen/<list>.md for shopping and other lists - Safe, unique file names; download button in settings (mobile-safe) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d6c70d7a8e
commit
e509f685c1
7 files changed
+531
-6
No files matched your search
@@ -109,6 +109,7 @@ func (s *Server) Router() http.Handler {
|
||||
r.Get("/api/v1/stats", s.handleStats)
|
||||
r.Get("/api/v1/search", s.handleSearch)
|
||||
r.Get("/api/v1/export", s.handleExport)
|
||||
r.Get("/api/v1/export/markdown", s.handleExportMarkdown)
|
||||
r.Get("/api/v1/themes", s.handleGetThemes)
|
||||
r.Post("/api/v1/themes", s.handleSaveTheme)
|
||||
r.Delete("/api/v1/themes/{id}", s.handleDeleteTheme)
|
||||
@@ -2117,6 +2118,17 @@ func (s *Server) handleDeleteTheme(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusOK, map[string]bool{"deleted": true})
|
||||
}
|
||||
|
||||
// handleExportMarkdown streams an Obsidian-compatible ZIP of the user's workspace (no temp files).
|
||||
func (s *Server) handleExportMarkdown(w http.ResponseWriter, r *http.Request) {
|
||||
userID := auth.GetUserID(r.Context())
|
||||
w.Header().Set("Content-Type", "application/zip")
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="mindsift-vault-%s.zip"`, time.Now().Format("2006-01-02")))
|
||||
if err := s.store.WriteMarkdownVault(userID, w); err != nil {
|
||||
// Headers are already sent; the client gets a truncated archive
|
||||
slog.Error("Markdown-Export fehlgeschlagen", "user_id", userID, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleExport(w http.ResponseWriter, r *http.Request) {
|
||||
userID := auth.GetUserID(r.Context())
|
||||
exportData, err := s.store.ExportUserData(userID)
|
||||
|
||||
Reference in new issue
Block a user