Skip to content

Commit

Permalink
add now to popups, no poller when no api key, windows console logs, M…
Browse files Browse the repository at this point in the history
…ac temps (#768)
  • Loading branch information
davidnewhall authored Jul 18, 2024
2 parents 457118d + 856f2bc commit e2cf496
Show file tree
Hide file tree
Showing 16 changed files with 110 additions and 57 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ include /tmp/.metadata.make
# Travis CI passes the version in. Local builds get it from the current git tag.
ifneq ($(_VERSION),)
VERSION:=$(_VERSION)
endif

ifneq ($(_ITERATION),)
ITERATION:=$(_ITERATION)
endif

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ require (
golift.io/nzbget v0.1.5
golift.io/qbit v0.0.0-20240715191156-11930ac2546e
golift.io/rotatorr v0.0.0-20230911015553-cd2abbd726c7
golift.io/starr v1.0.1-0.20240315164714-247399771c46
golift.io/starr v1.0.1-0.20240717055349-aa3e015cc8a4
golift.io/version v0.0.2
golift.io/xtractr v0.2.2
modernc.org/sqlite v1.30.2
Expand Down
10 changes: 2 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,6 @@ golift.io/cache v0.0.2 h1:759rPK+EOy6UX7HkqsesOToSQ3CWN4UN3b5BiehfpeY=
golift.io/cache v0.0.2/go.mod h1:wT61rGyiP50Rg243x5UF8dWBEKSr1RpB0GpgIF5kOGE=
golift.io/cnfg v0.2.3 h1:cQsC4JS20njJyu5drtGefNmgN7M4HrLaRDNBPLit3pQ=
golift.io/cnfg v0.2.3/go.mod h1:T4t8MFa8aZilCdIk1qQrN4mOGaFVPZ/qHQBBMbCIZJ0=
golift.io/cnfgfile v0.0.0-20240704165116-48378d0c6c38 h1:euXQUUWtsi2M+Bf6Do4+yG3YrVj88WyN0WJdv/abeW0=
golift.io/cnfgfile v0.0.0-20240704165116-48378d0c6c38/go.mod h1:zHm9o8SkZ6Mm5DfGahsrEJPsogyR0qItP59s5lJ98/I=
golift.io/cnfgfile v0.0.0-20240713024420-a5436d84eb48 h1:c7cJWRr0cUnFHKtq072esKzhQHKlFA5YRY/hPzQrdko=
golift.io/cnfgfile v0.0.0-20240713024420-a5436d84eb48/go.mod h1:zHm9o8SkZ6Mm5DfGahsrEJPsogyR0qItP59s5lJ98/I=
golift.io/datacounter v1.0.4 h1:b2gLQCs8WYRtKjOMG0qM82rF1o0+oKUXB9QH7kjmxZ4=
Expand All @@ -438,14 +436,12 @@ golift.io/mulery v0.0.8 h1:0D57orumzv9QORLLfTi4ao7uIACSyXkGSze32xLc04Q=
golift.io/mulery v0.0.8/go.mod h1:4qn4yK/A4GdSKjl4pKBK0ORVHTF466Zfsy8YI0+9dps=
golift.io/nzbget v0.1.5 h1:TE/TPldaLr/Qy5wy+7R4Lvur1SosOpjTLs6BLK3TMrU=
golift.io/nzbget v0.1.5/go.mod h1:YYGQsadsgvadzM6qlVBS21gz8DBhfbxexGMndsGelj8=
golift.io/qbit v0.0.0-20240407164833-5de994cfd55e h1:MUKqgMVV3RuXrWXQoDUD2sqWX6kAL3qHa/7nZpL5mGc=
golift.io/qbit v0.0.0-20240407164833-5de994cfd55e/go.mod h1:8fUXWdcWtuqnfJg/Z9yWbrOxovyhH0V9jE0eK7pFffA=
golift.io/qbit v0.0.0-20240715191156-11930ac2546e h1:JtgHLTF8YPH9fuyHxUYvteJMKyDtxCIbTA9KkbtwsgI=
golift.io/qbit v0.0.0-20240715191156-11930ac2546e/go.mod h1:rW0J8ruEeqTiICfWSk54gja8WLqUjNkbcsFN3wVdO94=
golift.io/rotatorr v0.0.0-20230911015553-cd2abbd726c7 h1:8reg8mRdLxCz168FaGPf/kVxmDRDc92/Dhub54trdOc=
golift.io/rotatorr v0.0.0-20230911015553-cd2abbd726c7/go.mod h1:59bC4ue06MetIY4iiHu3PCqVbzW0leGoCONZhH8dPZ8=
golift.io/starr v1.0.1-0.20240315164714-247399771c46 h1:RpNfYz8V2EZGF52U+RpurYDKFMpQYXW6VxIOVlHBbr0=
golift.io/starr v1.0.1-0.20240315164714-247399771c46/go.mod h1:XdwHrSBkAbcEfqOOXJGg5QQQ2sE/PVo1PMY/WMhzd8s=
golift.io/starr v1.0.1-0.20240717055349-aa3e015cc8a4 h1:8ijJymuEKA2xvSuRh3/k6G1esCGQxL6RiuFQ4jjN5Kk=
golift.io/starr v1.0.1-0.20240717055349-aa3e015cc8a4/go.mod h1:hoY+g9EudDC7lbpJxdSjfdxfFMeEtU3ko9BKon0qUrs=
golift.io/version v0.0.2 h1:i0gXRuSDHKs4O0sVDUg4+vNIuOxYoXhaxspftu2FRTE=
golift.io/version v0.0.2/go.mod h1:76aHNz8/Pm7CbuxIsDi97jABL5Zui3f2uZxDm4vB6hU=
golift.io/xtractr v0.2.2 h1:MvujxeuX629d1rQs2VJbbcvYMvMmN5SzIkEflU5ryOc=
Expand Down Expand Up @@ -524,8 +520,6 @@ modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
modernc.org/sqlite v1.30.1 h1:YFhPVfu2iIgUf9kuA1CR7iiHdcEEsI2i+yjRYHscyxk=
modernc.org/sqlite v1.30.1/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU=
modernc.org/sqlite v1.30.2 h1:IPVVkhLu5mMVnS1dQgh3h0SAACRWcVk7aoLP9Us3UCk=
modernc.org/sqlite v1.30.2/go.mod h1:DUmsiWQDaAvU4abhc/N+djlom/L2o8f7gZ95RCvyoLU=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
Expand Down
2 changes: 1 addition & 1 deletion pkg/apps/radarr.go
Original file line number Diff line number Diff line change
Expand Up @@ -980,7 +980,7 @@ func radarrAddImportList(req *http.Request) (int, interface{}) {
return apiError(http.StatusBadRequest, "decoding payload", err)
}

output, err := getRadarr(req).CreateImportListContext(req.Context(), &ilist)
output, err := getRadarr(req).AddImportListContext(req.Context(), &ilist)
if err != nil {
return apiError(http.StatusInternalServerError, "creating import list", err)
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/client/client_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ func (f *fakeMenu) Uncheck() {}
func (f *fakeMenu) Check() {}
func (f *fakeMenu) SetTooltip(interface{}) {}

func (c *Client) printUpdateMessage() {}
func (c *Client) setupMenus(interface{}) {}
func (c *Client) startTray(_, _, _ interface{}) {}
func (c *Client) printUpdateMessage() {}
func (c *Client) setupMenus(interface{}) {}
func (c *Client) startTray(_, _ interface{}) {}
func (c *Client) handleAptHook(_ context.Context) error {
return fmt.Errorf("this feature is not supported on this platform") //nolint:goerr113
}
Expand Down
19 changes: 14 additions & 5 deletions pkg/client/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package client

import (
"context"
"os"
"path"

"github.com/Notifiarr/notifiarr/pkg/mnd"
Expand Down Expand Up @@ -42,8 +43,10 @@ func (c *Client) PrintStartupInfo(ctx context.Context, clientInfo *clientinfo.Cl
c.Printf("==> Unique Host ID: %s (%s)", hi.HostID, hi.Hostname)
}

hostname, _ := os.Hostname()

c.Printf("==> %s <==", mnd.HelpLink)
c.Printf("==> Startup Settings <==")
c.Printf("==> %s Startup Settings <==", hostname)
c.printLidarr(&clientInfo.Actions.Apps.Lidarr)
c.printProwlarr(&clientInfo.Actions.Apps.Prowlarr)
c.printRadarr(&clientInfo.Actions.Apps.Radarr)
Expand Down Expand Up @@ -83,15 +86,21 @@ func (c *Client) printVersionChangeInfo(ctx context.Context) {
c.Errorf("XX> Getting version from database: %v", err)
}

currentVersion := version.Version + "-" + version.Revision
previousVersion := string(values[clientVersion])
if previousVersion == version.Version ||
version.Version == "" {

if previousVersion == currentVersion || version.Version == "" {
return
}

c.Printf("==> Detected application version change! %s => %s", previousVersion, version.Version)
if previousVersion == "" {
hostname, _ := os.Hostname()
c.Printf("==> Detected a new client, %s. Welcome to Notifiarr!", hostname)
} else {
c.Printf("==> Detected application version change! %s => %s", previousVersion, currentVersion)
}

err = c.website.SetState(ctx, clientVersion, []byte(version.Version))
err = c.website.SetState(ctx, clientVersion, []byte(currentVersion))
if err != nil {
c.Errorf("Updating version in database: %v", err)
}
Expand Down
30 changes: 17 additions & 13 deletions pkg/client/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func Start() error {
_, err := fmt.Println(client.Flags.Name() + " " + version.Version + "-" + version.Revision)
return err
case client.Flags.PSlist: // print process list and exit.
ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()

return printProcessList(ctx)
Expand All @@ -113,11 +113,11 @@ func Start() error {
case client.Flags.Curl != "": // curl a URL and exit.
return curlURL(client.Flags.Curl, client.Flags.Headers)
default:
return client.start(ctx)
return client.checkFlags(ctx)
}
}

func (c *Client) start(ctx context.Context) error { //nolint:cyclop
func (c *Client) checkFlags(ctx context.Context) error { //nolint:cyclop
msg, newPassword, err := c.loadConfiguration(ctx)

ctx, cancel := context.WithCancel(ctx)
Expand All @@ -131,14 +131,14 @@ func (c *Client) start(ctx context.Context) error { //nolint:cyclop
return fmt.Errorf("cannot reset admin password, got error reading configuration file: %w", err)
}

ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()

return c.resetAdminPassword(ctx)
case c.Flags.Write != "" && (err == nil || strings.Contains(err.Error(), "ip:port")):
c.Printf("==> %s", msg)

ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()

return c.forceWriteWithExit(ctx, c.Flags.Write)
Expand All @@ -148,12 +148,17 @@ func (c *Client) start(ctx context.Context) error { //nolint:cyclop
return nil
case c.Config.APIKey == "":
return fmt.Errorf("%s: %w %s_API_KEY", msg, ErrNilAPIKey, c.Flags.EnvPrefix)
default:
return c.start(ctx, msg, newPassword)
}
}

func (c *Client) start(ctx context.Context, msg, newPassword string) error {
c.Logger.SetupLogging(c.Config.LogConfig)
c.Printf(" %s %s v%s-%s Starting! [PID: %v] %s",
mnd.TodaysEmoji(), c.Flags.Name(), version.Version, version.Revision, os.Getpid(),
version.Started.Format("Monday, January 2, 2006 @ 3:04:05 PM MST -0700"))
c.Printf(" %s %s v%s-%s Starting! [PID: %v, UID: %d, GID: %d] %s",
mnd.TodaysEmoji(), mnd.Title, version.Version, version.Revision,
os.Getpid(), os.Getuid(), os.Getgid(),
version.Started.Format("Mon, Jan 2, 2006 @ 3:04:05 PM MST -0700"))
c.Printf("==> %s", msg)
c.printUpdateMessage()

Expand All @@ -173,15 +178,15 @@ func (c *Client) start(ctx context.Context) error { //nolint:cyclop

if ui.HasGUI() {
// This starts the web server and calls os.Exit() when done.
c.startTray(ctx, cancel, clientInfo)
c.startTray(ctx, clientInfo)
return nil
}

return c.Exit(ctx, cancel)
return c.Exit(ctx)
}

func (c *Client) makeNewConfigFile(ctx context.Context, newPassword string) {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()

_, _ = c.Config.Write(ctx, c.Flags.ConfigFile, false)
Expand Down Expand Up @@ -278,10 +283,9 @@ func (c *Client) triggerConfigReload(event website.EventType, source string) {
}

// Exit stops the web server and logs our exit messages. Start() calls this.
func (c *Client) Exit(ctx context.Context, cancel context.CancelFunc) error {
func (c *Client) Exit(ctx context.Context) error {
defer func() {
defer c.CapturePanic()
cancel()
c.Print(" ❌ Good bye! Exiting" + mnd.DurationAge(version.Started))
}()

Expand Down
7 changes: 3 additions & 4 deletions pkg/client/tray.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"fmt"
"os"
"strings"
"time"

"github.com/Notifiarr/notifiarr/pkg/bindata"
"github.com/Notifiarr/notifiarr/pkg/mnd"
Expand All @@ -29,7 +28,7 @@ const timerPrefix = "TimErr"
var menu = make(map[string]*systray.MenuItem) //nolint:gochecknoglobals

// startTray Run()s readyTray to bring up the web server and the GUI app.
func (c *Client) startTray(ctx context.Context, cancel context.CancelFunc, clientInfo *clientinfo.ClientInfo) {
func (c *Client) startTray(ctx context.Context, clientInfo *clientinfo.ClientInfo) {
systray.Run(func() {
defer os.Exit(0)
defer c.CapturePanic()
Expand All @@ -44,7 +43,7 @@ func (c *Client) startTray(ctx context.Context, cancel context.CancelFunc, clien
c.setupMenus(clientInfo) // code that runs on reload, too.

// This starts the web server, and waits for reload/exit signals.
if err := c.Exit(ctx, cancel); err != nil {
if err := c.Exit(ctx); err != nil {
c.Errorf("Server: %v", err)
os.Exit(1) // web server problem
}
Expand Down Expand Up @@ -164,7 +163,7 @@ func (c *Client) configMenu(ctx context.Context) {

menu["write"] = conf.AddSubMenuItem("Write", "write config file")
menu["write"].Click(func() {
ctx, cancel := context.WithTimeout(ctx, time.Minute)
ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()
c.writeConfigFile(ctx)
})
Expand Down
3 changes: 1 addition & 2 deletions pkg/client/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"net/http"
"os"
"path"
"time"

"github.com/Notifiarr/notifiarr/pkg/mnd"
"github.com/gorilla/mux"
Expand Down Expand Up @@ -42,7 +41,7 @@ func (c *Client) StartWebServer(ctx context.Context) {
c.server = &http.Server{ //nolint: exhaustivestruct
Handler: smx,
Addr: c.Config.BindAddr,
IdleTimeout: time.Minute,
IdleTimeout: mnd.DefaultTimeout,
WriteTimeout: c.Config.Timeout.Duration,
ReadTimeout: c.Config.Timeout.Duration,
ReadHeaderTimeout: c.Config.Timeout.Duration,
Expand Down
3 changes: 3 additions & 0 deletions pkg/configfile/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,9 @@ func (c *Config) Write(ctx context.Context, file string, encode bool) (string, e
}
defer newFile.Close()

ctx, cancel := context.WithTimeout(ctx, mnd.DefaultTimeout)
defer cancel()

if c.HostID == "" {
c.HostID, _ = host.HostIDWithContext(ctx)
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/logs/logfile_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,7 @@ func getFileOwner(fileInfo os.FileInfo) string {

return uid + ":" + gid
}

func hasConsoleWindow() bool {
return true
}
26 changes: 26 additions & 0 deletions pkg/logs/logfiles_windows.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,35 @@
package logs

import (
"debug/pe"
"os"
)

func getFileOwner(_ os.FileInfo) string {
return ""
}

// Sometimes we compile with -H=windowsgui and sometimes without.
// Having this function allows us to detect which, so we can turn on/off console logging.
func hasConsoleWindow() bool {
exe, err := os.Executable()
if err != nil {
return false
}

file, err := pe.Open(exe)
if err != nil {
return false
}
defer file.Close()

const windowsTerminal = 3

if header, ok := file.OptionalHeader.(*pe.OptionalHeader64); ok {
return header.Subsystem == windowsTerminal
} else if header, ok := file.OptionalHeader.(*pe.OptionalHeader32); ok {
return header.Subsystem == windowsTerminal
}

return false
}
5 changes: 1 addition & 4 deletions pkg/logs/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,7 @@ func (l *Logger) SetupLogging(config *LogConfig) {
logFiles = config.LogFiles
logFileMb = config.LogFileMb
l.LogConfig = config

if mnd.IsWindows {
config.Quiet = true
}
config.Quiet = !hasConsoleWindow() || config.Quiet

l.setDefaultLogPaths()
l.setAppLogPath()
Expand Down
23 changes: 15 additions & 8 deletions pkg/triggers/crontimer/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/Notifiarr/notifiarr/pkg/triggers/common"
"github.com/Notifiarr/notifiarr/pkg/website"
"github.com/Notifiarr/notifiarr/pkg/website/clientinfo"
"github.com/hako/durafmt"
"golift.io/cnfg"
)

Expand Down Expand Up @@ -82,14 +83,7 @@ func (c *cmd) create() {
ci := clientinfo.Get()
// This poller is sorta shoehorned in here for lack of a better place to put it.
if ci == nil {
c.Printf("==> Started Notifiarr Poller, have_clientinfo:%v interval:%s",
ci != nil, cnfg.Duration{Duration: pollDur.Round(time.Second)})
c.Add(&common.Action{
Name: TrigPollSite,
Fn: c.PollForReload,
D: cnfg.Duration{Duration: pollDur + time.Duration(c.Config.Rand().Intn(randomSeconds))*time.Second},
})

c.startWebsitePoller()
return
}

Expand Down Expand Up @@ -123,6 +117,19 @@ func (c *cmd) create() {
c.Printf("==> Custom Timers Enabled: %d timers provided", len(ci.Actions.Custom))
}

func (c *cmd) startWebsitePoller() {
if c.ValidAPIKey() != nil {
return // only poll if the api key length is valid.
}

c.Printf("==> Started Notifiarr Website Poller, interval: %s", durafmt.Parse(pollDur))
c.Add(&common.Action{
Name: TrigPollSite,
Fn: c.PollForReload,
D: cnfg.Duration{Duration: pollDur + time.Duration(c.Config.Rand().Intn(randomSeconds))*time.Second},
})
}

// PollForReload is only started if the initial connection to the website failed.
// This will keep checking until it works, then reload to grab settings and start properly.
func (c *cmd) PollForReload(ctx context.Context, input *common.ActionInput) {
Expand Down
Loading

0 comments on commit e2cf496

Please sign in to comment.