package main import ( "encoding/gob" "errors" "fmt" "log" "os" "path" "strconv" "strings" "time" "git.ophivana.moe/cat/rpcfetch" ) var ( pidS = strconv.Itoa(os.Getpid()) hostname string launchTime = time.Now().Unix() ) var substitute = map[string]func(s *applyState) string{ "pid": func(_ *applyState) string { return pidS }, "hostname": func(_ *applyState) string { return hostname }, "1min": func(s *applyState) string { s.populateLoadavg() return s.loadavg[0] }, "5min": func(s *applyState) string { s.populateLoadavg() return s.loadavg[1] }, "15min": func(s *applyState) string { s.populateLoadavg() return s.loadavg[2] }, "used": func(s *applyState) string { s.populateMem() return fmt.Sprintf("%.1f GiB", float64(s.mem[1]-s.mem[0])/(1<<20)) }, "total": func(s *applyState) string { s.populateMem() return fmt.Sprintf("%.1f GiB", float64(s.mem[1])/(1<<20)) }, } type applyState struct { loadavg *[3]string mem *[2]int } func (s *applyState) replace(t string) string { for k, f := range substitute { t = strings.ReplaceAll(t, "%"+k, f(s)) } return t } func apply() { act := *conf.Activity s := &applyState{} act.State = s.replace(act.State) act.Details = s.replace(act.Details) act.Assets = &rpcfetch.ActivityAssets{ LargeImage: act.Assets.LargeImage, LargeText: s.replace(act.Assets.LargeText), SmallImage: act.Assets.SmallImage, SmallText: s.replace(act.Assets.SmallText), } if nonce, err := retry(&act); err != nil { log.Fatalf("error setting activity: %s", err) } else { log.Printf("activity updated with nonce %s", nonce) } } func save() { nf, err := os.CreateTemp(path.Dir(confPath), ".rpcfetch.conf.*") if err != nil { log.Fatalf("error creating temporary configuration file: %s", err) } if err = gob.NewEncoder(nf).Encode(defaultConfig); err != nil { fmt.Printf("error writing configuration file: %s\n", err) os.Exit(1) } if err = nf.Close(); err != nil { log.Fatalf("error closing temporary configuration file: %s", err) } if err = os.Rename(nf.Name(), confPath); err != nil { log.Fatalf("error renaming configuration file: %s", err) } log.Printf("saved configuration to %s", confPath) } func retry(act *rpcfetch.Activity) (string, error) { try: nonce, err := d.SetActivity(act) if errors.Is(err, rpcfetch.ErrAgain) { log.Println("retrying in 5 seconds...") time.Sleep(5 * time.Second) goto try } return nonce, err }