Skip to content

Commit f4fcd27

Browse files
committed
Wire up slog to most of init
Signed-off-by: Marcus Crane <[email protected]>
1 parent 99b59b9 commit f4fcd27

File tree

3 files changed

+134
-19
lines changed

3 files changed

+134
-19
lines changed

backend/init.go

+85-12
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ import (
1313
"runtime"
1414
"strings"
1515

16-
"github.com/sirupsen/logrus"
17-
1816
"github.com/pgaskin/koboutils/v2/kobo"
1917

2018
wailsRuntime "github.com/wailsapp/wails/v2/pkg/runtime"
@@ -34,10 +32,18 @@ type Backend struct {
3432
portable bool
3533
}
3634

37-
func StartBackend(ctx *context.Context, version string, portable bool, logger *slog.Logger) *Backend {
38-
settings, err := LoadSettings(portable)
35+
func StartBackend(ctx *context.Context, version string, portable bool, logger *slog.Logger) (*Backend, error) {
36+
settings, err := LoadSettings(portable, logger)
37+
logger.Info("Successfully parsed settings file",
38+
slog.String("path", settings.path),
39+
slog.Bool("upload_store_highlights", settings.UploadStoreHighlights),
40+
slog.Bool("upload_covers", settings.UploadCovers),
41+
)
3942
if err != nil {
40-
logrus.WithContext(*ctx).WithError(err).Error("Failed to load settings")
43+
logger.Error("Failed to load settings",
44+
slog.String("error", err.Error()),
45+
)
46+
return &Backend{}, err
4147
}
4248
return &Backend{
4349
SelectedKobo: Kobo{},
@@ -50,9 +56,10 @@ func StartBackend(ctx *context.Context, version string, portable bool, logger *s
5056
Kobo: &Kobo{},
5157
Content: &Content{},
5258
Bookmark: &Bookmark{},
59+
logger: logger,
5360
version: version,
5461
portable: portable,
55-
}
62+
}, nil
5663
}
5764

5865
func (b *Backend) GetSettings() *Settings {
@@ -90,10 +97,20 @@ func (b *Backend) NavigateExplorerToLogLocation() {
9097
if runtime.GOOS == "linux" {
9198
explorerCommand = "xdg-open"
9299
}
100+
b.logger.Info("Opening logs in system file explorer",
101+
slog.String("command", explorerCommand),
102+
slog.String("os", runtime.GOOS),
103+
)
93104
logLocation, err := LocateDataFile("october/logs", b.portable)
94105
if err != nil {
95-
logrus.WithError(err).Error("Failed to determine XDG data location for opening log location in explorer")
106+
b.logger.Error("Failed to determine XDG data location for opening log location in explorer",
107+
slog.String("error", err.Error()),
108+
)
96109
}
110+
b.logger.Debug("Executing command to open system file explorer",
111+
slog.String("command", explorerCommand),
112+
slog.String("os", runtime.GOOS),
113+
)
97114
// We will always get an error because the file explorer doesn't exit so it is unable to
98115
// return a 0 successful exit code until y'know, the user exits the window
99116
_ = exec.Command(explorerCommand, logLocation).Run()
@@ -102,10 +119,21 @@ func (b *Backend) NavigateExplorerToLogLocation() {
102119
func (b *Backend) DetectKobos() []Kobo {
103120
connectedKobos, err := kobo.Find()
104121
if err != nil {
122+
b.logger.Error("Failed to detect any connected Kobos")
105123
panic(err)
106124
}
107125
kobos := GetKoboMetadata(connectedKobos)
126+
b.logger.Info("Found one or more kobos",
127+
"count", len(kobos),
128+
)
108129
for _, kb := range kobos {
130+
b.logger.Info("Found connected device",
131+
slog.String("mount_path", kb.MntPath),
132+
slog.String("database_path", kb.DbPath),
133+
slog.String("name", kb.Name),
134+
slog.Int("display_ppi", kb.DisplayPPI),
135+
slog.Int("storage", kb.Storage),
136+
)
109137
b.ConnectedKobos[kb.MntPath] = kb
110138
}
111139
return kobos
@@ -119,6 +147,9 @@ func (b *Backend) SelectKobo(devicePath string) error {
119147
if val, ok := b.ConnectedKobos[devicePath]; ok {
120148
b.SelectedKobo = val
121149
} else {
150+
b.logger.Info("No device found at path. Selecting local database",
151+
slog.String("device_path", devicePath),
152+
)
122153
b.SelectedKobo = Kobo{
123154
Name: "Local Database",
124155
Storage: 0,
@@ -155,46 +186,81 @@ func (b *Backend) PromptForLocalDBPath() error {
155186

156187
func (b *Backend) ForwardToReadwise() (int, error) {
157188
highlightBreakdown := b.Kobo.CountDeviceBookmarks()
189+
slog.Info("Got highlight counts from device",
190+
slog.Int("highlight_count_sideload", int(highlightBreakdown.Sideloaded)),
191+
slog.Int("highlight_count_official", int(highlightBreakdown.Official)),
192+
slog.Int("highlight_count_total", int(highlightBreakdown.Total)),
193+
)
158194
if highlightBreakdown.Total == 0 {
159-
logrus.Error("Tried to submit highlights when there are none on device.")
195+
slog.Error("Tried to submit highlights when there are none on device.")
160196
return 0, fmt.Errorf("Your device doesn't seem to have any highlights so there is nothing left to sync.")
161197
}
162198
includeStoreBought := b.Settings.UploadStoreHighlights
163199
if !includeStoreBought && highlightBreakdown.Sideloaded == 0 {
164-
logrus.Error("Tried to submit highlights with no sideloaded highlights + store-bought syncing disabled. Result is that no highlights would be fetched.")
200+
slog.Error("Tried to submit highlights with no sideloaded highlights + store-bought syncing disabled. Result is that no highlights would be fetched.")
165201
return 0, fmt.Errorf("You have disabled store-bought syncing but you don't have any sideloaded highlights either. This combination means there are no highlights left to be synced.")
166202
}
167203
content, err := b.Kobo.ListDeviceContent(includeStoreBought)
168204
if err != nil {
205+
slog.Error("Received an error trying to list content from device",
206+
slog.String("error", err.Error()),
207+
)
169208
return 0, err
170209
}
171210
contentIndex := b.Kobo.BuildContentIndex(content)
172211
bookmarks, err := b.Kobo.ListDeviceBookmarks(includeStoreBought)
173212
if err != nil {
213+
slog.Error("Received an error trying to list bookmarks from device",
214+
slog.String("error", err.Error()),
215+
)
174216
return 0, err
175217
}
176218
payload, err := BuildPayload(bookmarks, contentIndex)
177219
if err != nil {
220+
slog.Error("Received an error trying to build Readwise payload",
221+
slog.String("error", err.Error()),
222+
)
178223
return 0, err
179224
}
180225
numUploads, err := b.Readwise.SendBookmarks(payload, b.Settings.ReadwiseToken)
181226
if err != nil {
227+
slog.Error("Received an error trying to send bookmarks to Readwise",
228+
slog.String("error", err.Error()),
229+
)
182230
return 0, err
183231
}
232+
slog.Info("Successfully uploaded bookmarks to Readwise",
233+
slog.Int("payload_count", numUploads),
234+
)
184235
if b.Settings.UploadCovers {
185236
uploadedBooks, err := b.Readwise.RetrieveUploadedBooks(b.Settings.ReadwiseToken)
186237
if err != nil {
238+
slog.Error("Failed to retrieve uploaded titles from Readwise",
239+
slog.String("error", err.Error()),
240+
)
187241
return numUploads, fmt.Errorf("Successfully uploaded %d bookmarks", numUploads)
188242
}
243+
slog.Info("Retrieved uploaded books from Readwise for cover insertion",
244+
slog.Int("book_count", uploadedBooks.Count),
245+
)
189246
for _, book := range uploadedBooks.Results {
247+
slog.Info("Checking cover status for book",
248+
slog.Int("book_id", book.ID),
249+
slog.String("book_title", book.Title),
250+
)
190251
// We don't want to overwrite user uploaded covers or covers already present
191252
if !strings.Contains(book.CoverURL, "uploaded_book_covers") {
192253
coverID := kobo.ContentIDToImageID(book.SourceURL)
193254
coverPath := kobo.CoverTypeLibFull.GeneratePath(false, coverID)
194255
absCoverPath := path.Join(b.SelectedKobo.MntPath, "/", coverPath)
195256
coverBytes, err := os.ReadFile(absCoverPath)
196257
if err != nil {
197-
logrus.WithError(err).WithFields(logrus.Fields{"cover": book.SourceURL, "location": absCoverPath}).Warn("Failed to load cover. Carrying on")
258+
slog.Warn("Failed to load cover from disc. Skipping to next book.",
259+
slog.String("error", err.Error()),
260+
slog.String("cover_path", absCoverPath),
261+
slog.String("cover_id", book.SourceURL),
262+
)
263+
continue
198264
}
199265
var base64Encoding string
200266
mimeType := http.DetectContentType(coverBytes)
@@ -207,10 +273,17 @@ func (b *Backend) ForwardToReadwise() (int, error) {
207273
base64Encoding += base64.StdEncoding.EncodeToString(coverBytes)
208274
err = b.Readwise.UploadCover(base64Encoding, book.ID, b.Settings.ReadwiseToken)
209275
if err != nil {
210-
logrus.WithError(err).WithField("cover", book.SourceURL).Error("Failed to upload cover to Readwise")
276+
slog.Error("Failed to upload cover to Readwise. Skipping to next book.",
277+
slog.String("error", err.Error()),
278+
slog.String("cover_url", book.SourceURL),
279+
)
280+
continue
211281
}
212-
logrus.WithField("cover", book.SourceURL).Debug("Successfully uploaded cover to Readwise")
282+
slog.Debug("Successfully uploaded cover to Readwise",
283+
slog.String("cover_url", book.SourceURL),
284+
)
213285
}
286+
slog.Info("Cover already exists for book. Skipping as we don't know if this was us prior or a user upload.")
214287
}
215288
}
216289
return numUploads, nil

backend/settings.go

+37-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package backend
22

33
import (
44
"encoding/json"
5+
"log/slog"
56
"os"
67
"path/filepath"
78
"strings"
@@ -16,11 +17,17 @@ type Settings struct {
1617
UploadStoreHighlights bool `json:"upload_store_highlights"`
1718
}
1819

19-
func LoadSettings(portable bool) (*Settings, error) {
20+
func LoadSettings(portable bool, logger *slog.Logger) (*Settings, error) {
2021
settingsPath, err := LocateConfigFile(configFilename, portable)
2122
if err != nil {
22-
return nil, errors.Wrap(err, "Failed to create settings directory. Do you have proper permissions?")
23+
logger.Error("Failed to create settings directory. Do you have proper permissions?",
24+
slog.String("error", err.Error()),
25+
)
26+
return nil, err
2327
}
28+
logger.Debug("Located settings path",
29+
slog.String("path", settingsPath),
30+
)
2431
s := &Settings{
2532
path: settingsPath,
2633
UploadStoreHighlights: true, // default on as users with only store purchased books are blocked from usage otherwise but give ample warning during setup
@@ -29,31 +36,56 @@ func LoadSettings(portable bool) (*Settings, error) {
2936
b, err := os.ReadFile(settingsPath)
3037
if err != nil {
3138
if os.IsNotExist(err) {
39+
logger.Info("Settings file at path does not exist. Reinitialising with default values.",
40+
slog.String("path", settingsPath),
41+
slog.Bool("upload_store_highlights", s.UploadStoreHighlights),
42+
slog.Bool("upload_covers", s.UploadCovers),
43+
)
3244
// We should always have settings but if they have been deleted, just use the defaults
3345
return s, nil
3446
}
35-
return nil, errors.Wrap(err, "Failed to read settings file. Is it corrupted?")
47+
logger.Error("Failed to read settings file. Perhaps it was corrupted?",
48+
slog.String("path", settingsPath),
49+
)
50+
return nil, err
3651
}
3752
err = json.Unmarshal(b, s)
3853
if err != nil {
54+
logger.Warn("Failed to unmarshal settings file. Attempting to repair as v1.6.0 and earlier had known issues.")
3955
// v1.6.0 and prior may have caused settings files to have an extra `}` so we check for common issues
4056
// We're not gonna go overboard here though, just basic text checking
4157
plainSettings := strings.TrimSpace(string(b))
4258
if strings.HasPrefix(plainSettings, "{{") {
59+
logger.Debug("Stripped duplicate opening braces from corrupted settings file")
4360
plainSettings = strings.Replace(plainSettings, "{{", "{", 1)
4461
}
4562
if strings.HasSuffix(plainSettings, "}}") {
63+
logger.Debug("Stripped duplicate closing braces from corrupted settings file")
4664
plainSettings = strings.Replace(plainSettings, "}}", "}", 1)
4765
}
4866
err := json.Unmarshal([]byte(plainSettings), s)
4967
if err != nil {
50-
return nil, errors.Wrap(err, "Failed to parse settings file. Is it valid?")
68+
logger.Error("Failed to parse settings file after trying brace stripping hack. Can't continue.",
69+
slog.String("path", settingsPath),
70+
)
71+
return nil, err
5172
}
73+
logger.Info("Successfully fixed up corrupted settings file",
74+
slog.String("path", settingsPath),
75+
slog.Bool("upload_store_highlights", s.UploadStoreHighlights),
76+
slog.Bool("upload_covers", s.UploadCovers),
77+
)
5278
// We managed to fix the settings file so we'll persist it to disc
5379
err = s.Save()
5480
if err != nil {
55-
return nil, errors.Wrap(err, "Failed to persist fixed up settings file!")
81+
logger.Error("Failed to persist uncorrupted settings file to disc",
82+
slog.String("path", settingsPath),
83+
)
84+
return nil, err
5685
}
86+
logger.Info("Successfully persisted uncorrupted settings file to disc",
87+
slog.String("path", settingsPath),
88+
)
5789
return s, nil
5890
}
5991
return s, nil

main.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package main
33
import (
44
"embed"
55
"fmt"
6-
slog "log/slog"
6+
"log/slog"
77
"os"
8+
"runtime"
89
"strconv"
910
"strings"
1011

@@ -51,6 +52,9 @@ func main() {
5152
slog.Bool("portable", isPortable),
5253
slog.String("user_cache_dir", usr_cache_dir),
5354
slog.String("user_config_dir", usr_config_dir),
55+
slog.String("goarch", runtime.GOARCH),
56+
slog.String("goos", runtime.GOOS),
57+
slog.String("goversion", runtime.Version()),
5458
)
5559

5660
if cli.IsCLIInvokedExplicitly(os.Args) {
@@ -64,7 +68,13 @@ func main() {
6468
// Create an instance of the app structure
6569
app := NewApp(isPortable, logger)
6670

67-
backend := backend.StartBackend(&app.ctx, version, isPortable, logger)
71+
backend, err := backend.StartBackend(&app.ctx, version, isPortable, logger)
72+
if err != nil {
73+
logger.Error("Backend failed to start up",
74+
slog.String("error", err.Error()),
75+
)
76+
panic("Failed to start backend")
77+
}
6878

6979
// Create application with options
7080
err = wails.Run(&options.App{

0 commit comments

Comments
 (0)