-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
157 lines (129 loc) · 4.88 KB
/
main.go
File metadata and controls
157 lines (129 loc) · 4.88 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
146
147
148
149
150
151
152
153
154
155
156
157
package main
// NOTE: Location tracking desktop file id updated to io.github.rubiojr.whereami.desktop (actual InitLocationTracking call now lives in api.go)
import (
_ "embed"
"flag"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"sync"
qt "github.com/mappu/miqt/qt6"
"github.com/mappu/miqt/qt6/qml"
"github.com/rubiojr/whereami/pkg/logger"
)
//go:embed bookmarks.gpx
var embeddedBookmarks []byte
// Global application directories (resolved at startup).
// Set once in main() via command-line flags or XDG rules.
var dataDir string
var configDir string
var cacheDir string
// Global live waypoint store (bookmarks + other GPX waypoints).
// Waypoint type & persistence helpers now live in storage.go.
var allWaypoints []Waypoint
var allWaypointsMu sync.RWMutex
func main() {
// Command-line flags
debugFlag := flag.Bool("debug", false, "enable debug logging (verbose tile proxy requests)")
themeFlag := flag.String("theme", "", "theme variant (orange|green|purple|adwaita-dark|nord-polar|nord-frost)")
dataDirFlag := flag.String("data-dir", "", "custom data directory (overrides XDG_DATA_HOME)")
configDirFlag := flag.String("config-dir", "", "custom config directory (overrides XDG_CONFIG_HOME)")
cacheDirFlag := flag.String("cache-dir", "", "custom cache directory (overrides XDG_CACHE_HOME)")
flag.Parse()
debug := *debugFlag
themeVariant := *themeFlag
// Set debug logging
logger.SetDebug(debug)
// Hardcoded API port (as requested)
const apiPort = 43098
// Determine data directory for persistent app storage (bookmarks, imported GPX, databases).
// Precedence: --data-dir flag > $XDG_DATA_HOME > $HOME/.local/share/whereami > CWD fallback.
// Set global directory variables based on flags or XDG defaults
if *dataDirFlag != "" {
dataDir = *dataDirFlag
} else {
dataDir = filepath.Join(xdgDataDir(), "whereami")
}
if err := ensureDir(dataDir); err != nil {
logger.Error("Failed to create data dir %s: %v", dataDir, err)
}
if *configDirFlag != "" {
configDir = *configDirFlag
} else {
configDir = filepath.Join(xdgConfigDir(), "whereami")
}
if err := ensureDir(configDir); err != nil {
logger.Error("Failed to create config dir %s: %v", configDir, err)
}
if *cacheDirFlag != "" {
cacheDir = *cacheDirFlag
} else {
cacheDir = filepath.Join(xdgCacheDir(), "whereami")
}
if err := ensureDir(cacheDir); err != nil {
logger.Error("Failed to create cache dir %s: %v", cacheDir, err)
}
// Canonical bookmarks path (migrated from legacy per-flag directory location).
bookmarksPath := filepath.Join(dataDir, "bookmarks.gpx")
// Copy embedded bookmarks.gpx to data directory if it doesn't exist
if !fileExists(bookmarksPath) {
if err := copyEmbeddedBookmarks(bookmarksPath); err != nil {
logger.Error("Failed to copy default bookmarks to %s: %v", bookmarksPath, err)
} else {
logger.Debug("Copied default bookmarks to %s", bookmarksPath)
}
}
// Legacy bookmark migration removed; using only XDG dataDir location now.
// Register HTTP API handlers (moved to api.go)
RegisterAPI(http.DefaultServeMux, bookmarksPath, debug)
// /api/location endpoint moved to api.go (lazy initialization handled there)
// (Removed HTTP /qml/ handler — using local temp materialization instead)
// Start server on fixed port 43098
go func() {
addr := "127.0.0.1:43098"
if err := http.ListenAndServe(addr, nil); err != nil {
logger.Error("Bookmark API server error on %s: %v", addr, err)
}
}()
// Build initial waypoint list (bookmarks + imported GPX) using centralized dedupe helper.
initial := RebuildAllWaypoints(bookmarksPath, dataDir)
allWaypointsMu.Lock()
allWaypoints = initial
allWaypointsMu.Unlock()
// Prepare arguments for Qt; append a synthetic --theme=<variant> so QML can always detect it
qtArgs := os.Args
if themeVariant != "" {
qtArgs = append(qtArgs, "--theme="+themeVariant)
}
// Set Material theme to dark mode
os.Setenv("QT_QUICK_CONTROLS_STYLE", "Material")
os.Setenv("QT_QUICK_CONTROLS_MATERIAL_THEME", "Dark")
qt.QCoreApplication_SetApplicationName("io.github.rubiojr.whereami")
qt.NewQApplication(qtArgs)
engine := qml.NewQQmlApplicationEngine()
// Load QML from Qt resources (qrc:/)
engine.Load(qt.NewQUrl3("qrc:/components/MapView.qml"))
if len(engine.RootObjects()) == 0 {
logger.Fatal("QML load failed: no root objects (check QML errors / Qt Location).")
}
logger.Debug("Bookmark API fixed port: http://127.0.0.1:%d/api/bookmarks", apiPort)
qt.QApplication_Exec()
}
// copyEmbeddedBookmarks writes the embedded bookmarks.gpx to the specified path.
func copyEmbeddedBookmarks(destPath string) error {
// Ensure the parent directory exists
if err := ensureDir(filepath.Dir(destPath)); err != nil {
return err
}
// Create the destination file
file, err := os.Create(destPath)
if err != nil {
return err
}
defer file.Close()
// Copy the embedded content
_, err = io.Copy(file, strings.NewReader(string(embeddedBookmarks)))
return err
}