cli + tui to publish to leaflet (wip) & manage tasks, notes & watch/read lists 馃崈
charm
leaflet
readability
golang
1package handlers
2
3import (
4 "context"
5 "fmt"
6 "math/rand"
7 "time"
8
9 "github.com/stormlightlabs/noteleaf/internal/repo"
10 "github.com/stormlightlabs/noteleaf/internal/store"
11 "github.com/stormlightlabs/noteleaf/internal/ui"
12 "github.com/stormlightlabs/noteleaf/internal/utils"
13)
14
15// SeedHandler handles database seeding operations
16type SeedHandler struct {
17 db *store.Database
18 config *store.Config
19 repos *repo.Repositories
20}
21
22// NewSeedHandler creates a new seed handler
23func NewSeedHandler() (*SeedHandler, error) {
24 db, err := store.NewDatabase()
25 if err != nil {
26 return nil, fmt.Errorf("failed to initialize database: %w", err)
27 }
28
29 config, err := store.LoadConfig()
30 if err != nil {
31 return nil, fmt.Errorf("failed to load configuration: %w", err)
32 }
33
34 repos := repo.NewRepositories(db.DB)
35
36 return &SeedHandler{
37 db: db,
38 config: config,
39 repos: repos,
40 }, nil
41}
42
43// Close cleans up resources
44func (h *SeedHandler) Close() error {
45 if h.db != nil {
46 return h.db.Close()
47 }
48 return nil
49}
50
51// Seed populates the database with test data for demonstration and testing
52func (h *SeedHandler) Seed(ctx context.Context, force bool) error {
53 logger := utils.GetLogger()
54 logger.Info("Seeding database with test data")
55
56 if force {
57 fmt.Println("Clearing existing data...")
58 if err := h.clearAllData(); err != nil {
59 return fmt.Errorf("failed to clear existing data: %w", err)
60 }
61 }
62
63 fmt.Println("Seeding database with test data...")
64
65 tasks := []struct {
66 description string
67 project string
68 priority string
69 status string
70 }{
71 {"Review quarterly report", "work", "high", "pending"},
72 {"Plan vacation itinerary", "personal", "medium", "pending"},
73 {"Fix bug in user authentication", "development", "high", "pending"},
74 {"Read \"Clean Code\" book", "learning", "low", "pending"},
75 {"Update project documentation", "work", "medium", "completed"},
76 }
77
78 for _, task := range tasks {
79 if err := h.seedTask(task.description, task.project, task.priority, task.status); err != nil {
80 logger.Warn("Failed to seed task", "description", task.description, "error", err)
81 }
82 }
83
84 books := []struct {
85 title string
86 author string
87 status string
88 progress int
89 }{
90 {"The Go Programming Language", "Alan Donovan", "reading", 45},
91 {"Clean Code", "Robert Martin", "queued", 0},
92 {"Design Patterns", "Gang of Four", "finished", 100},
93 {"The Pragmatic Programmer", "Andy Hunt", "queued", 0},
94 {"Effective Go", "Various", "reading", 75},
95 }
96
97 for _, book := range books {
98 if err := h.seedBook(book.title, book.author, book.status, book.progress); err != nil {
99 logger.Warn("Failed to seed book", "title", book.title, "error", err)
100 }
101 }
102
103 fmt.Printf("Successfully seeded database with %d tasks and %d books\n", len(tasks), len(books))
104 fmt.Printf("\n%s\n", ui.InfoStyle.Render("Example commands to try:"))
105 fmt.Printf(" %s\n", ui.SuccessStyle.Render("noteleaf todo list"))
106 fmt.Printf(" %s\n", ui.SuccessStyle.Render("noteleaf media book list"))
107 fmt.Printf(" %s\n", ui.SuccessStyle.Render("noteleaf todo view 1"))
108
109 return nil
110}
111
112func (h *SeedHandler) clearAllData() error {
113 queries := []string{
114 "DELETE FROM tasks",
115 "DELETE FROM books",
116 "DELETE FROM notes",
117 "DELETE FROM movies",
118 "DELETE FROM tv_shows",
119 "DELETE FROM sqlite_sequence WHERE name IN ('tasks', 'books', 'notes', 'movies', 'tv_shows')",
120 }
121
122 for _, query := range queries {
123 if _, err := h.db.Exec(query); err != nil {
124 return fmt.Errorf("failed to execute %s: %w", query, err)
125 }
126 }
127
128 return nil
129}
130
131func (h *SeedHandler) seedTask(description, project, priority, status string) error {
132 uuid := h.generateSimpleUUID()
133 query := `INSERT INTO tasks (uuid, description, project, priority, status, entry, modified)
134 VALUES (?, ?, ?, ?, ?, datetime('now'), datetime('now'))`
135 _, err := h.db.Exec(query, uuid, description, project, priority, status)
136 return err
137}
138
139func (h *SeedHandler) seedBook(title, author, status string, progress int) error {
140 query := `INSERT INTO books (title, author, status, progress, added)
141 VALUES (?, ?, ?, ?, datetime('now'))`
142 _, err := h.db.Exec(query, title, author, status, progress)
143 return err
144}
145
146// generateSimpleUUID creates a simple UUID for seeding (not cryptographically secure, but sufficient for test data)
147func (h *SeedHandler) generateSimpleUUID() string {
148 now := time.Now()
149 randomNum := rand.Intn(10000)
150 return fmt.Sprintf("seed-task-%d-%d-%d", now.Unix(), now.UnixNano()%1000000, randomNum)
151}