-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
145 lines (132 loc) · 4.01 KB
/
main.go
File metadata and controls
145 lines (132 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package main
import (
"fmt"
"os"
"path/filepath"
"strings"
"hashigo/lib"
)
func main() {
// Determine executable path and related directories
exePath, err := os.Executable()
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get executable path: %v\n", err)
os.Exit(1)
}
exeDir := filepath.Dir(exePath)
exeName := filepath.Base(exePath)
// Assume project root structure:
// root/
// bin/exe
// data/db
// Check if we are in a 'bin' directory to decide where 'data' is
var dataDir string
if strings.EqualFold(filepath.Base(exeDir), "bin") {
// If in bin/, assume data/ is sibling to bin/
dataDir = filepath.Join(filepath.Dir(exeDir), "data")
} else {
// Otherwise, assume data/ is in current executable directory
dataDir = filepath.Join(exeDir, "data")
}
// Ensure data directory exists
if err := os.MkdirAll(dataDir, 0755); err != nil {
fmt.Fprintf(os.Stderr, "Failed to create data directory: %v\n", err)
os.Exit(1)
}
// Derive DB name from executable name
// e.g. "123456-0120-2026-hashigo.exe" -> "123456-0120-2026-hashigo.db"
// If name doesn't have extension, just append .db
ext := filepath.Ext(exeName)
baseName := strings.TrimSuffix(exeName, ext)
dbName := baseName + ".db"
dbPath := filepath.Join(dataDir, dbName)
if err := lib.InitDB(dbPath); err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize DB: %v\n", err)
os.Exit(1)
}
defer lib.CloseDB()
args := os.Args[1:]
if len(args) == 0 {
printHelp()
return
}
command := args[0]
switch command {
case "add":
if len(args) < 2 {
fmt.Println("Usage: hashigo add <url>")
return
}
url := args[1]
if err := lib.AddFeed(url); err != nil {
fmt.Fprintf(os.Stderr, "Error adding feed: %v\n", err)
}
case "import":
if len(args) < 2 {
fmt.Println("Usage: hashigo import <file_path>")
return
}
filePath := args[1]
if err := lib.ImportFeeds(filePath); err != nil {
fmt.Fprintf(os.Stderr, "Error importing feeds: %v\n", err)
}
case "sync":
if err := lib.SyncAllFeeds(); err != nil {
fmt.Fprintf(os.Stderr, "Error syncing feeds: %v\n", err)
}
case "export":
filename := "starred.html"
if len(args) >= 2 {
filename = args[1]
}
if err := lib.ExportStarredItems(filename); err != nil {
fmt.Fprintf(os.Stderr, "Error exporting items: %v\n", err)
} else {
fmt.Printf("Successfully exported starred items to %s\n", filename)
}
case "tui":
lib.StartTUI(0) // Default to Unread mode
case "loop", "start":
if len(args) >= 2 {
// If file path is provided, import and sync first
filePath := args[1]
fmt.Printf("Importing from %s...\n", filePath)
if err := lib.ImportFeeds(filePath); err != nil {
fmt.Fprintf(os.Stderr, "Error importing feeds: %v\n", err)
// Continue anyway? Maybe better to stop if import fails completely.
// But ImportFeeds logs individual errors and continues.
}
// ImportFeeds does SyncFeed for each new feed, but let's ensure SyncAllFeeds if needed
// Actually ImportFeeds calls AddFeed which calls SyncFeed.
// So explicit sync might be redundant but harmless.
}
// Start TUI in All/Loop mode (2)
lib.StartTUI(2)
case "help", "--help", "-h":
printHelp()
default:
fmt.Printf("Unknown command: %s\n", command)
printHelp()
}
}
func printHelp() {
fmt.Println(`Hashigo - A minimalist CLI Feed Reader
Usage:
hashigo <command> [arguments]
Commands:
add <url> Add a new RSS/Atom feed URL
import <file> Import feeds from a text file (one URL per line)
sync Update all feeds manually
export [file] Export starred items to HTML (default: starred.html)
tui Start the Terminal User Interface (Unread mode)
loop <file> Import feeds from file and start TUI in Loop Mode (All items)
start <file> Alias for loop
help Show this help message
TUI Controls:
Up/Down / j/k Navigate items
Enter Open item in browser (marks as read)
s Toggle star
Tab Switch View Mode (Unread -> Starred -> Loop/All)
Ctrl+C Quit
`)
}