cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm leaflet readability golang
at main 85 lines 2.1 kB view raw
1package handlers 2 3import ( 4 "context" 5 "database/sql" 6 "fmt" 7 8 "github.com/stormlightlabs/noteleaf/internal/repo" 9 "github.com/stormlightlabs/noteleaf/internal/store" 10) 11 12// DocumentHandler provides operations for document search 13type DocumentHandler struct { 14 db *sql.DB 15 repos *repo.Repositories 16 engine *repo.SearchEngine 17} 18 19// NewDocumentHandler creates a new document handler 20func NewDocumentHandler() (*DocumentHandler, error) { 21 db, err := store.NewDatabase() 22 if err != nil { 23 return nil, fmt.Errorf("failed to initialize database: %w", err) 24 } 25 26 repos := repo.NewRepositories(db.DB) 27 engine := repo.NewSearchEngine(repos.Documents) 28 29 return &DocumentHandler{ 30 db: db.DB, 31 repos: repos, 32 engine: engine, 33 }, nil 34} 35 36// RebuildIndex rebuilds the search index from notes 37func (h *DocumentHandler) RebuildIndex(ctx context.Context) error { 38 if err := h.repos.Documents.DeleteAll(ctx); err != nil { 39 return fmt.Errorf("failed to clear documents: %w", err) 40 } 41 42 if err := h.repos.Documents.RebuildFromNotes(ctx, h.repos.Notes); err != nil { 43 return fmt.Errorf("failed to rebuild from notes: %w", err) 44 } 45 46 if err := h.engine.Rebuild(ctx); err != nil { 47 return fmt.Errorf("failed to rebuild search index: %w", err) 48 } 49 50 fmt.Println("Search index rebuilt successfully") 51 return nil 52} 53 54// Search performs a TF-IDF search and displays results 55func (h *DocumentHandler) Search(ctx context.Context, query string, limit int) error { 56 if err := h.engine.Rebuild(ctx); err != nil { 57 return fmt.Errorf("failed to rebuild index: %w", err) 58 } 59 60 results, docs, err := h.engine.SearchWithScores(ctx, query, limit) 61 if err != nil { 62 return fmt.Errorf("search failed: %w", err) 63 } 64 65 if len(results) == 0 { 66 fmt.Println("No results found") 67 return nil 68 } 69 70 fmt.Printf("Found %d results:\n\n", len(results)) 71 for i, doc := range docs { 72 score := results[i].Score 73 fmt.Printf("%d. [Score: %.2f] %s\n", i+1, score, doc.Title) 74 fmt.Printf(" %s\n\n", truncate(doc.Body, 100)) 75 } 76 77 return nil 78} 79 80func truncate(s string, maxLen int) string { 81 if len(s) <= maxLen { 82 return s 83 } 84 return s[:maxLen] + "..." 85}