Now all indicator updates properly

This commit is contained in:
eleksir
2024-09-23 19:05:45 +03:00
parent 1a4ab136dc
commit 5bb259a30c
15 changed files with 228 additions and 231 deletions

View File

@@ -25,20 +25,25 @@ func main() {
log.Panicf("Unable to read config: %s", err) log.Panicf("Unable to read config: %s", err)
} }
Conf.UpdateReady = make(chan bool) Conf.Channels.UpdateReady = make(chan bool)
Conf.MsgChan = make(chan []lib.I3BarOutBlock, 64) Conf.Channels.SVPAHandlerChan = make(chan lib.ClickEvent, 256)
Conf.SigChan = make(chan os.Signal, 1) Conf.Channels.MsgChan = make(chan []lib.I3BarOutBlock, 64)
Conf.BatteryString = "<big>⚡</big> ??% •" Conf.Channels.SigChan = make(chan os.Signal, 1)
Conf.ClockTime = "Thu, 1 Jan 1970 1:00" Conf.Channels.RunChan = make(chan []string, 128)
Conf.IfStatus = "" Conf.Values.PrintOutput = true
Conf.VPNStatus = "" Conf.Values.BatteryString = "<big>⚡</big> ??% •"
Conf.Memory.Shared = 0 Conf.Values.ClockTime = "Thu, 1 Jan 1970 1:00"
Conf.Memory.Usedpct = 0 Conf.Values.IfStatus = ""
Conf.Memory.Swap = 0 Conf.Values.VPNStatus = ""
Conf.La = "-1" Conf.Values.Memory.Shared = 0
Conf.Values.Memory.Usedpct = 0
Conf.Values.Memory.Swap = 0
Conf.Values.La = "-1"
// Conf.Values.PA
Conf.Values.SoundVolume = "🔊:0%"
// TODO: Проставить дефолтные значения для глобальных переменных модулей. // TODO: Проставить дефолтные значения для глобальных переменных модулей.
Batt := fmt.Sprintf( Conf.Values.BatteryString = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>", "<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
Conf.Battery.Color, Conf.Battery.Color,
Conf.Battery.Background, Conf.Battery.Background,
@@ -47,7 +52,7 @@ func main() {
Conf.Battery.Symbol, Conf.Battery.Symbol,
) )
Batt += fmt.Sprintf( Conf.Values.BatteryString += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'> ??%% •</span>", "<span color='%s' background='%s' font='%s' size='%s'> ??%% •</span>",
Conf.Battery.Color, Conf.Battery.Color,
Conf.Battery.Background, Conf.Battery.Background,
@@ -55,7 +60,7 @@ func main() {
Conf.Battery.FontSize, Conf.Battery.FontSize,
) )
SoundVolume := fmt.Sprintf( Conf.Values.SoundVolume = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>🔊</span>", "<span color='%s' background='%s' font='%s' size='%s'>🔊</span>",
Conf.SimpleVolumePa.Color, Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background, Conf.SimpleVolumePa.Background,
@@ -63,7 +68,7 @@ func main() {
Conf.SimpleVolumePa.SymbolFontSize, Conf.SimpleVolumePa.SymbolFontSize,
) )
SoundVolume += fmt.Sprintf( Conf.Values.SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:0%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>:0%%</span>",
Conf.SimpleVolumePa.Color, Conf.SimpleVolumePa.Color,
Conf.SimpleVolumePa.Background, Conf.SimpleVolumePa.Background,
@@ -71,7 +76,7 @@ func main() {
Conf.SimpleVolumePa.FontSize, Conf.SimpleVolumePa.FontSize,
) )
Clock := fmt.Sprintf( Conf.Values.ClockTime = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>Thu, 1 Jan 1970 1:00</span>", "<span color='%s' background='%s' font='%s' size='%s'>Thu, 1 Jan 1970 1:00</span>",
Conf.Clock.Color, Conf.Clock.Color,
Conf.Clock.Background, Conf.Clock.Background,
@@ -91,7 +96,7 @@ func main() {
// Kick signal handler // Kick signal handler
go Conf.SigHandler() go Conf.SigHandler()
signal.Notify(Conf.SigChan, signal.Notify(Conf.Channels.SigChan,
syscall.SIGUSR1, syscall.SIGUSR1,
syscall.SIGUSR2, syscall.SIGUSR2,
syscall.SIGQUIT, syscall.SIGQUIT,
@@ -131,7 +136,7 @@ func main() {
} }
if Conf.Cron.Enabled { if Conf.Cron.Enabled {
go lib.RunCron() go Conf.RunCron()
} }
if Conf.Vpn.Enabled { if Conf.Vpn.Enabled {
@@ -156,7 +161,7 @@ func main() {
fmt.Println("[ [],") fmt.Println("[ [],")
for { for {
if <-Conf.UpdateReady { if <-Conf.Channels.UpdateReady {
// Actually build json struct, marshal it and print result // Actually build json struct, marshal it and print result
var j []lib.I3BarOutBlock var j []lib.I3BarOutBlock
@@ -235,7 +240,7 @@ func main() {
Conf.CPUTemp.Background, Conf.CPUTemp.Background,
Conf.CPUTemp.Font, Conf.CPUTemp.Font,
Conf.CPUTemp.FontSize, Conf.CPUTemp.FontSize,
Conf.CPUTemperature, Conf.Values.CPUTemperature,
) )
if Conf.CPUTemp.Separator.Right.Enabled { if Conf.CPUTemp.Separator.Right.Enabled {
@@ -279,9 +284,9 @@ func main() {
Conf.Mem.Background, Conf.Mem.Background,
Conf.Mem.Font, Conf.Mem.Font,
Conf.Mem.FontSize, Conf.Mem.FontSize,
Conf.Memory.Usedpct, Conf.Values.Memory.Usedpct,
Conf.Memory.Shared, Conf.Values.Memory.Shared,
Conf.Memory.Swap, Conf.Values.Memory.Swap,
) )
} else { } else {
b.FullText += fmt.Sprintf( b.FullText += fmt.Sprintf(
@@ -290,8 +295,8 @@ func main() {
Conf.Mem.Background, Conf.Mem.Background,
Conf.Mem.Font, Conf.Mem.Font,
Conf.Mem.FontSize, Conf.Mem.FontSize,
Conf.Memory.Usedpct, Conf.Values.Memory.Usedpct,
Conf.Memory.Shared, Conf.Values.Memory.Shared,
) )
} }
@@ -335,7 +340,7 @@ func main() {
Conf.LA.Background, Conf.LA.Background,
Conf.LA.Font, Conf.LA.Font,
Conf.LA.FontSize, Conf.LA.FontSize,
Conf.La, Conf.Values.La,
) )
if Conf.LA.Separator.Right.Enabled { if Conf.LA.Separator.Right.Enabled {
@@ -378,7 +383,7 @@ func main() {
Conf.NetIf.Background, Conf.NetIf.Background,
Conf.NetIf.Font, Conf.NetIf.Font,
Conf.NetIf.FontSize, Conf.NetIf.FontSize,
Conf.IfStatus, Conf.Values.IfStatus,
) )
if Conf.NetIf.Separator.Right.Enabled { if Conf.NetIf.Separator.Right.Enabled {
@@ -421,7 +426,7 @@ func main() {
Conf.Vpn.Background, Conf.Vpn.Background,
Conf.Vpn.Font, Conf.Vpn.Font,
Conf.Vpn.FontSize, Conf.Vpn.FontSize,
Conf.VPNStatus, Conf.Values.VPNStatus,
) )
if Conf.Vpn.Separator.Right.Enabled { if Conf.Vpn.Separator.Right.Enabled {
@@ -458,7 +463,7 @@ func main() {
) )
} }
b.FullText += Conf.BatteryString b.FullText += Conf.Values.BatteryString
if Conf.Battery.Separator.Right.Enabled { if Conf.Battery.Separator.Right.Enabled {
b.FullText += fmt.Sprintf( b.FullText += fmt.Sprintf(
@@ -496,7 +501,7 @@ func main() {
} }
// Pango format is already applied in plugin src. // Pango format is already applied in plugin src.
b.FullText += SoundVolume b.FullText += Conf.Values.SoundVolume
if Conf.SimpleVolumePa.Separator.Right.Enabled { if Conf.SimpleVolumePa.Separator.Right.Enabled {
b.FullText += fmt.Sprintf( b.FullText += fmt.Sprintf(
@@ -539,7 +544,7 @@ func main() {
Conf.Clock.Background, Conf.Clock.Background,
Conf.Clock.Font, Conf.Clock.Font,
Conf.Clock.FontSize, Conf.Clock.FontSize,
Clock, Conf.Values.ClockTime,
) )
if Conf.Clock.Separator.Right.Enabled { if Conf.Clock.Separator.Right.Enabled {
@@ -559,16 +564,16 @@ func main() {
j = append(j, b) j = append(j, b)
} }
if Conf.PrintOutput && len(j) > 0 { if Conf.Values.PrintOutput && len(j) > 0 {
Conf.MsgChan <- j Conf.Channels.MsgChan <- j
} }
} }
} }
} }
// PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html) // PrintToI3bar prints info to stdout according to ipc docs (https://i3wm.org/docs/i3bar-protocol.html)
func PrintToI3bar(c lib.MyConfig) { func PrintToI3bar(c *lib.MyConfig) {
for message := range c.MsgChan { for message := range c.Channels.MsgChan {
// we do not need to html-encode output, json.Marshal does this forcefully, so invent our own Marshal // we do not need to html-encode output, json.Marshal does this forcefully, so invent our own Marshal
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
encoder := json.NewEncoder(buf) encoder := json.NewEncoder(buf)

View File

@@ -9,7 +9,7 @@ import (
) )
// UpdateBatteryInfo updates info about battery charge. // UpdateBatteryInfo updates info about battery charge.
func (c MyConfig) UpdateBatteryInfo() { func (c *MyConfig) UpdateBatteryInfo() {
var ( var (
ch int ch int
status string status string
@@ -22,11 +22,11 @@ func (c MyConfig) UpdateBatteryInfo() {
if err != nil { if err != nil {
Batts = fmt.Sprintf( Batts = fmt.Sprintf(
"<span font='%s' size='%s'>%s</span><span font='%s' size='%s'> no batt</span>", "<span font='%s' size='%s'>%s</span><span font='%s' size='%s'> no batt</span>",
Conf.Battery.SymbolFont, c.Battery.SymbolFont,
Conf.Battery.SymbolFontSize, c.Battery.SymbolFontSize,
Conf.Battery.Symbol, c.Battery.Symbol,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
) )
} else { } else {
var ( var (
@@ -52,85 +52,85 @@ func (c MyConfig) UpdateBatteryInfo() {
switch { switch {
case ch > 85: case ch > 85:
if Conf.Battery.ChargeColor.Full == "" { if c.Battery.ChargeColor.Full == "" {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} else { } else {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`, `<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.Full, c.Battery.ChargeColor.Full,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} }
case ch < 85 && ch > 40: case ch < 85 && ch > 40:
if Conf.Battery.ChargeColor.AlmostFull == "" { if c.Battery.ChargeColor.AlmostFull == "" {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} else { } else {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`, `<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.AlmostFull, c.Battery.ChargeColor.AlmostFull,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} }
case ch <= 40 && ch >= 10: case ch <= 40 && ch >= 10:
if Conf.Battery.ChargeColor.AlmostEmpty == "" { if c.Battery.ChargeColor.AlmostEmpty == "" {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} else { } else {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`, `<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.AlmostEmpty, c.Battery.ChargeColor.AlmostEmpty,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} }
case ch < 10: case ch < 10:
if Conf.Battery.ChargeColor.Empty == "" { if c.Battery.ChargeColor.Empty == "" {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>",
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} else { } else {
chStr = fmt.Sprintf( chStr = fmt.Sprintf(
`<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`, `<span color='%s' background='%s' font='%s' size='%s'>% 3d%%</span>`,
Conf.Battery.ChargeColor.Empty, c.Battery.ChargeColor.Empty,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
ch, ch,
) )
} }
@@ -138,21 +138,21 @@ func (c MyConfig) UpdateBatteryInfo() {
battsInfo += fmt.Sprintf( battsInfo += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>%s</span><span color='%s' background='%s' font='%s' size='%s'>B%d </span>%s<span color='%s' background='%s' font='%s' size='%s'> %s</span>", "<span color='%s' background='%s' font='%s' size='%s'>%s</span><span color='%s' background='%s' font='%s' size='%s'>B%d </span>%s<span color='%s' background='%s' font='%s' size='%s'> %s</span>",
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.SymbolFont, c.Battery.SymbolFont,
Conf.Battery.SymbolFontSize, c.Battery.SymbolFontSize,
Conf.Battery.Symbol, c.Battery.Symbol,
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
i, i,
chStr, chStr,
Conf.Battery.Color, c.Battery.Color,
Conf.Battery.Background, c.Battery.Background,
Conf.Battery.Font, c.Battery.Font,
Conf.Battery.FontSize, c.Battery.FontSize,
status, status,
) )
} }
@@ -162,9 +162,9 @@ func (c MyConfig) UpdateBatteryInfo() {
} }
} }
if c.BatteryString == Batts { if c.Values.BatteryString == Batts {
c.BatteryString = Batts c.Values.BatteryString = Batts
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)

View File

@@ -6,7 +6,7 @@ import (
) )
// UpdateClock get and updates (on i3bar) info about system clock. // UpdateClock get and updates (on i3bar) info about system clock.
func (c MyConfig) UpdateClock() { func (c *MyConfig) UpdateClock() {
for { for {
currentTime := time.Now() currentTime := time.Now()
hours, minutes, _ := currentTime.Clock() hours, minutes, _ := currentTime.Clock()
@@ -17,9 +17,9 @@ func (c MyConfig) UpdateClock() {
myclock := fmt.Sprintf(" %s, %d %s %d % 2d:%02d ", rdow[dow], day, rmonth[month-1], year, hours, minutes) myclock := fmt.Sprintf(" %s, %d %s %d % 2d:%02d ", rdow[dow], day, rmonth[month-1], year, hours, minutes)
if myclock != c.ClockTime { if myclock != c.Values.ClockTime {
c.ClockTime = myclock c.Values.ClockTime = myclock
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)

View File

@@ -11,6 +11,7 @@ import (
"github.com/adrg/xdg" "github.com/adrg/xdg"
"github.com/hjson/hjson-go" "github.com/hjson/hjson-go"
p "github.com/mafik/pulseaudio"
) )
// I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format. // I3BarOutBlock is structure element for I3BarOut, it represents i3bar output json block format.
@@ -57,17 +58,26 @@ type Separator struct {
} }
type MyConfig struct { type MyConfig struct {
UpdateReady chan bool Values struct {
PrintOutput bool PrintOutput bool
MsgChan chan []I3BarOutBlock CPUTemperature int64
SigChan chan os.Signal BatteryString string
CPUTemperature int64 ClockTime string
BatteryString string IfStatus string
ClockTime string VPNStatus string
IfStatus string Memory Mem
VPNStatus string La string
Memory Mem PA *p.Client
La string SoundVolume string
}
Channels struct {
UpdateReady chan bool
MsgChan chan []I3BarOutBlock
SigChan chan os.Signal
SVPAHandlerChan chan ClickEvent
RunChan chan []string
}
// Default text color // Default text color
Color string `json:"color,omitempty"` Color string `json:"color,omitempty"`
@@ -240,15 +250,12 @@ type MyConfig struct {
} `json:"apps,omitempty"` } `json:"apps,omitempty"`
} }
// Conf global variable with application config.
var Conf MyConfig
// readConf reads and validates config if config does not exist, it puts default config to the same dir where i3 config // readConf reads and validates config if config does not exist, it puts default config to the same dir where i3 config
// is located. // is located.
func ReadConf(DefaultConfig []byte) (MyConfig, error) { func ReadConf(DefaultConfig []byte) (*MyConfig, error) {
var ( var (
path string path string
config MyConfig config *MyConfig
err error err error
buf []byte buf []byte
) )
@@ -294,7 +301,7 @@ func ReadConf(DefaultConfig []byte) (MyConfig, error) {
// We interested in struct as output product: so we parse config to intermediate map then marshal it to json and // We interested in struct as output product: so we parse config to intermediate map then marshal it to json and
// then produced json unmarshal to struct. Not very effective way, but in app lifetime it happens only once. // then produced json unmarshal to struct. Not very effective way, but in app lifetime it happens only once.
var ( var (
sampleConfig MyConfig sampleConfig *MyConfig
tmp map[string]interface{} tmp map[string]interface{}
) )
@@ -1527,19 +1534,19 @@ func ReadConf(DefaultConfig []byte) (MyConfig, error) {
} }
if app.Color == "" { if app.Color == "" {
app.Color = Conf.Color app.Color = sampleConfig.Color
} }
if app.Background == "" { if app.Background == "" {
app.Background = Conf.Background app.Background = sampleConfig.Background
} }
if app.Border == "" { if app.Border == "" {
app.Border = Conf.Color app.Border = sampleConfig.Color
} }
if app.BorderActive == "" { if app.BorderActive == "" {
app.BorderActive = Conf.Color app.BorderActive = sampleConfig.Color
} }
if app.FullText == "" { if app.FullText == "" {

View File

@@ -9,8 +9,8 @@ import (
) )
// UpdateCPUTemperature gets and updates average CPU cores temperature. // UpdateCPUTemperature gets and updates average CPU cores temperature.
func (c MyConfig) UpdateCPUTemperature() { func (c *MyConfig) UpdateCPUTemperature() {
n := len(Conf.CPUTemp.File) n := len(c.CPUTemp.File)
for { for {
var ( var (
@@ -19,7 +19,7 @@ func (c MyConfig) UpdateCPUTemperature() {
tAvg int64 tAvg int64
) )
for i, filename := range Conf.CPUTemp.File { for i, filename := range c.CPUTemp.File {
file, err := os.Open(filename) file, err := os.Open(filename)
if err != nil { if err != nil {
@@ -67,9 +67,9 @@ func (c MyConfig) UpdateCPUTemperature() {
tAvg = tSum / int64(len(temperature)) tAvg = tSum / int64(len(temperature))
} }
if c.CPUTemperature != tAvg { if c.Values.CPUTemperature != tAvg {
c.CPUTemperature = tAvg c.Values.CPUTemperature = tAvg
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)

View File

@@ -10,7 +10,7 @@ import (
var myCron gocron.Scheduler var myCron gocron.Scheduler
// RunCron parses config part, related to cron tasks and kicks cron to run. // RunCron parses config part, related to cron tasks and kicks cron to run.
func RunCron() { func (c MyConfig) RunCron() {
var err error var err error
myCron, err = gocron.NewScheduler() myCron, err = gocron.NewScheduler()
@@ -21,14 +21,14 @@ func RunCron() {
return return
} }
for _, job := range Conf.Cron.Tasks { for _, job := range c.Cron.Tasks {
_, err := myCron.NewJob( _, err := myCron.NewJob(
gocron.CronJob(job.Time, false), gocron.CronJob(job.Time, false),
gocron.NewTask( gocron.NewTask(
// Сука, просто заспавнить бинарь, ну почему это надо делать через жопу-то? // Сука, просто заспавнить бинарь, ну почему это надо делать через жопу-то?
any( any(
func() bool { func() bool {
RunChan <- job.Cmd c.Channels.RunChan <- job.Cmd
return true return true
}, },

View File

@@ -18,7 +18,7 @@ type WinList struct {
var WL WinList var WL WinList
// UpdateI3WinList subsribes to all window-related events and send them to I3EventParser() for more detailed parsing. // UpdateI3WinList subsribes to all window-related events and send them to I3EventParser() for more detailed parsing.
func (c MyConfig) UpdateI3WinList() { func (c *MyConfig) UpdateI3WinList() {
// TODO: Здесь получить начальный список окон, управляемых i3wm (через GetTree()) и сложить их атрибутику в переменную WL // TODO: Здесь получить начальный список окон, управляемых i3wm (через GetTree()) и сложить их атрибутику в переменную WL
Tree, err := i3.GetTree() Tree, err := i3.GetTree()
@@ -39,7 +39,7 @@ func (c MyConfig) UpdateI3WinList() {
} }
// I3EventParser parses i3wm events and updates WL (aka Windows List). // I3EventParser parses i3wm events and updates WL (aka Windows List).
func (c MyConfig) I3EventParser(e *i3.WindowEvent) { func (c *MyConfig) I3EventParser(e *i3.WindowEvent) {
switch e.Change { switch e.Change {
case "new": case "new":
var ( var (
@@ -68,7 +68,7 @@ func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
count++ count++
WL.Instance.Set(e.Container.WindowProperties.Instance, count) WL.Instance.Set(e.Container.WindowProperties.Instance, count)
c.UpdateReady <- true c.Channels.UpdateReady <- true
case "close": case "close":
countI, exist := WL.Class.Get(e.Container.WindowProperties.Class) countI, exist := WL.Class.Get(e.Container.WindowProperties.Class)
@@ -99,7 +99,7 @@ func (c MyConfig) I3EventParser(e *i3.WindowEvent) {
} }
} }
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
} }
@@ -210,7 +210,7 @@ func FindWindowClass(regexpStr string) bool {
} }
// ExtractProps fills WL stricture collections with instance name and class name of given node (x11, that is). // ExtractProps fills WL stricture collections with instance name and class name of given node (x11, that is).
func (c MyConfig) ExtractProps(n *i3.Node) { func (c *MyConfig) ExtractProps(n *i3.Node) {
var e i3.WindowEvent var e i3.WindowEvent
e.Change = "new" e.Change = "new"
e.Container = *n e.Container = *n

View File

@@ -9,15 +9,12 @@ import (
"time" "time"
) )
// IfStatus global var conaining cumulative status of all monitored net intefaces.
var IfStatus string
// UpdateIfStatus updates network interfaces status for i3bar. // UpdateIfStatus updates network interfaces status for i3bar.
func (c MyConfig) UpdateIfStatus() { func (c *MyConfig) UpdateIfStatus() {
for { for {
var statusSum string var statusSum string
for _, item := range Conf.NetIf.If { for _, item := range c.NetIf.If {
var ( var (
name = item.Name name = item.Name
) )
@@ -35,10 +32,10 @@ func (c MyConfig) UpdateIfStatus() {
} else { } else {
switch strings.TrimSpace(string(operstate)) { switch strings.TrimSpace(string(operstate)) {
case "up": case "up":
StatusStr := fmt.Sprintf("<span foreground=\"%s\">⍋</span>", Conf.NetIf.UpColor) StatusStr := fmt.Sprintf("<span foreground=\"%s\">⍋</span>", c.NetIf.UpColor)
operstate = []byte(StatusStr) operstate = []byte(StatusStr)
case "down": case "down":
statusStr := fmt.Sprintf("<span foreground=\"%s\">⍒</span>", Conf.NetIf.DownColor) statusStr := fmt.Sprintf("<span foreground=\"%s\">⍒</span>", c.NetIf.DownColor)
operstate = []byte(statusStr) operstate = []byte(statusStr)
default: default:
operstate = []byte(`?`) operstate = []byte(`?`)
@@ -52,9 +49,9 @@ func (c MyConfig) UpdateIfStatus() {
statusSum += fmt.Sprintf("%s:%s", name, operstate) statusSum += fmt.Sprintf("%s:%s", name, operstate)
} }
if c.IfStatus != statusSum { if c.Values.IfStatus != statusSum {
c.IfStatus = statusSum c.Values.IfStatus = statusSum
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)

View File

@@ -8,15 +8,15 @@ import (
) )
// UpdateLaStats вытаскивает показание LA за последнюю минуту. // UpdateLaStats вытаскивает показание LA за последнюю минуту.
func (c MyConfig) UpdateLaStats() { func (c *MyConfig) UpdateLaStats() {
for { for {
l, _ := load.Avg() l, _ := load.Avg()
lav := fmt.Sprintf("%.2f", l.Load1) lav := fmt.Sprintf("%.2f", l.Load1)
if c.La != lav { if c.Values.La != lav {
c.La = lav c.Values.La = lav
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)

View File

@@ -14,11 +14,8 @@ type Mem struct {
Swap uint64 Swap uint64
} }
// Memory stores string with mem stats for i3bar.
var Memory Mem
// UpdateMemStats parses mem info stats. // UpdateMemStats parses mem info stats.
func (c MyConfig) UpdateMemStats() { func (c *MyConfig) UpdateMemStats() {
for { for {
v, err := mem.VirtualMemory() v, err := mem.VirtualMemory()
@@ -38,19 +35,18 @@ func (c MyConfig) UpdateMemStats() {
continue continue
} }
if Conf.Mem.ShowSwap { if c.Mem.ShowSwap {
if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 || if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 || c.Values.Memory.Swap != v.SwapTotal-v.SwapFree {
Memory.Swap != v.SwapTotal-v.SwapFree { c.Values.Memory.Usedpct = uint64(v.UsedPercent)
Memory.Usedpct = uint64(v.UsedPercent) c.Values.Memory.Shared = v.Shared / 1024 / 1024
Memory.Shared = v.Shared / 1024 / 1024 c.Values.Memory.Swap = sw.Used
Memory.Swap = sw.Used c.Channels.UpdateReady <- true
c.UpdateReady <- true
} }
} else { } else {
if Memory.Usedpct != uint64(v.UsedPercent) || Memory.Shared != v.Shared/1024/1024 { if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 {
Memory.Usedpct = uint64(v.UsedPercent) c.Values.Memory.Usedpct = uint64(v.UsedPercent)
Memory.Shared = v.Shared / 1024 / 1024 c.Values.Memory.Shared = v.Shared / 1024 / 1024
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
} }

View File

@@ -10,30 +10,25 @@ import (
p "github.com/mafik/pulseaudio" p "github.com/mafik/pulseaudio"
) )
var SoundVolume = "🔊:0%"
var pa *p.Client
var SVPAHandlerChan = make(chan ClickEvent, 256)
// TODO: https://twin.sh/articles/44/add-a-timeout-to-any-function-in-go timeout pulseaudio calls // TODO: https://twin.sh/articles/44/add-a-timeout-to-any-function-in-go timeout pulseaudio calls
// UpdateVolumeInfo updates info about current Sound Volume. // UpdateVolumeInfo updates info about current Sound Volume.
func (c MyConfig) UpdateVolumeInfo() { func (c *MyConfig) UpdateVolumeInfo() {
var err error var err error
pa, err = p.NewClient() c.Values.PA, err = p.NewClient()
// It can happen if no pulseaudio server running for current user. // It can happen if no pulseaudio server running for current user.
// If no server running we have to run one. // If no server running we have to run one.
if err != nil { if err != nil {
if err := PaReinit(); err != nil { if err := c.PaReinit(); err != nil {
log.Print(err) log.Print(err)
return return
} }
} }
vol, err := pa.Volume() vol, err := c.Values.PA.Volume()
if err != nil { if err != nil {
log.Printf("Unable get volume from pulseaudio server: %s", err) log.Printf("Unable get volume from pulseaudio server: %s", err)
@@ -41,7 +36,7 @@ func (c MyConfig) UpdateVolumeInfo() {
return return
} }
SoundVolume = fmt.Sprintf( c.Values.SoundVolume = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>", "<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
c.SimpleVolumePa.Color, c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background, c.SimpleVolumePa.Background,
@@ -50,7 +45,7 @@ func (c MyConfig) UpdateVolumeInfo() {
c.SimpleVolumePa.Symbol, c.SimpleVolumePa.Symbol,
) )
SoundVolume += fmt.Sprintf( c.Values.SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
c.SimpleVolumePa.Color, c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background, c.SimpleVolumePa.Background,
@@ -59,11 +54,11 @@ func (c MyConfig) UpdateVolumeInfo() {
int64(vol*100), int64(vol*100),
) )
c.UpdateReady <- true c.Channels.UpdateReady <- true
for { for {
// Subscribe to update notification channel, to get info that volume changed. // Subscribe to update notification channel, to get info that volume changed.
pulseUpdate, err := pa.Updates() pulseUpdate, err := c.Values.PA.Updates()
if err != nil { if err != nil {
log.Printf("Unable to subscribe to pulseaudio updates: %s", err) log.Printf("Unable to subscribe to pulseaudio updates: %s", err)
@@ -73,7 +68,7 @@ func (c MyConfig) UpdateVolumeInfo() {
// Rake update events. // Rake update events.
for range pulseUpdate { for range pulseUpdate {
vol, err = pa.Volume() vol, err = c.Values.PA.Volume()
if err != nil { if err != nil {
log.Printf("Unable get volume from pulseaudio server: %s", err) log.Printf("Unable get volume from pulseaudio server: %s", err)
@@ -81,7 +76,7 @@ func (c MyConfig) UpdateVolumeInfo() {
return return
} }
SoundVolume = fmt.Sprintf( c.Values.SoundVolume = fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>", "<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
c.SimpleVolumePa.Color, c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background, c.SimpleVolumePa.Background,
@@ -90,7 +85,7 @@ func (c MyConfig) UpdateVolumeInfo() {
c.SimpleVolumePa.Symbol, c.SimpleVolumePa.Symbol,
) )
SoundVolume += fmt.Sprintf( c.Values.SoundVolume += fmt.Sprintf(
"<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>", "<span color='%s' background='%s' font='%s' size='%s'>:%d%%</span>",
c.SimpleVolumePa.Color, c.SimpleVolumePa.Color,
c.SimpleVolumePa.Background, c.SimpleVolumePa.Background,
@@ -99,10 +94,10 @@ func (c MyConfig) UpdateVolumeInfo() {
int64(vol*100), int64(vol*100),
) )
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
if err := PaReinit(); err != nil { if err := c.PaReinit(); err != nil {
log.Print(err) log.Print(err)
return return
@@ -110,11 +105,11 @@ func (c MyConfig) UpdateVolumeInfo() {
} }
// This code is unreachable :( // This code is unreachable :(
pa.Close() //nolint:govet c.Values.PA.Close() //nolint:govet
} }
// PaReinit re-inits pulseaudio and connection to it. // PaReinit re-inits pulseaudio and connection to it.
func PaReinit() error { func (c *MyConfig) PaReinit() error {
var err error var err error
// If we out of updates, seems someone killed pulseaudio server. Restart it. // If we out of updates, seems someone killed pulseaudio server. Restart it.
@@ -157,7 +152,7 @@ func PaReinit() error {
// This setting defines if pulseaudio will be run in manner that allows it to exit is other login detected (how // This setting defines if pulseaudio will be run in manner that allows it to exit is other login detected (how
// they guess it - I do not know). In general case we do not want to allow pa to exit and leave our session without // they guess it - I do not know). In general case we do not want to allow pa to exit and leave our session without
// audio. // audio.
if Conf.SimpleVolumePa.DontExitOnLogin { if c.SimpleVolumePa.DontExitOnLogin {
// Do not exit on any kind of login/logout events. // Do not exit on any kind of login/logout events.
cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start") cmd = exec.Command("pulseaudio", "--exit-idle-time=-1", "--start")
} else { } else {
@@ -169,7 +164,7 @@ func PaReinit() error {
return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err) return fmt.Errorf("unable to initialize pulseaudio server instance: %w", err)
} }
pa, err = p.NewClient() c.Values.PA, err = p.NewClient()
if err != nil { if err != nil {
return fmt.Errorf("unable to make client connection to pulseaudio: %w", err) return fmt.Errorf("unable to make client connection to pulseaudio: %w", err)
@@ -178,21 +173,21 @@ func PaReinit() error {
return err return err
} }
func (c MyConfig) SVPAHandler() { func (c *MyConfig) SVPAHandler() {
for e := range SVPAHandlerChan { for e := range c.Channels.SVPAHandlerChan {
if e.Button == 3 { if e.Button == 3 {
RunChan <- Conf.SimpleVolumePa.RightClickCmd c.Channels.RunChan <- c.SimpleVolumePa.RightClickCmd
continue continue
} }
vol, err := pa.Volume() vol, err := c.Values.PA.Volume()
if err != nil { if err != nil {
if err := PaReinit(); err != nil { if err := c.PaReinit(); err != nil {
log.Printf("Unable to get pulseaudio volume: %s", err) log.Printf("Unable to get pulseaudio volume: %s", err)
} else { } else {
vol, err = pa.Volume() vol, err = c.Values.PA.Volume()
if err != nil { if err != nil {
log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err) log.Printf("Unable to get volume pulseaudio server behaves weirdly: %s", err)
@@ -201,25 +196,25 @@ func (c MyConfig) SVPAHandler() {
} }
switch e.Button { switch e.Button {
case Conf.SimpleVolumePa.WheelUp: case c.SimpleVolumePa.WheelUp:
vol += float32(Conf.SimpleVolumePa.Step) / 100 vol += float32(c.SimpleVolumePa.Step) / 100
if vol > (float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100) { if vol > (float32(c.SimpleVolumePa.MaxVolumeLimit) / 100) {
vol = float32(Conf.SimpleVolumePa.MaxVolumeLimit) / 100 vol = float32(c.SimpleVolumePa.MaxVolumeLimit) / 100
} }
if err := pa.SetVolume(vol); err != nil { if err := c.Values.PA.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err) log.Printf("Unable to set pulseaudio volume: %s", err)
} }
case Conf.SimpleVolumePa.WheelDown: case c.SimpleVolumePa.WheelDown:
vol -= float32(Conf.SimpleVolumePa.Step) / 100 vol -= float32(c.SimpleVolumePa.Step) / 100
if vol < 0 { if vol < 0 {
vol = 0 vol = 0
} }
if err := pa.SetVolume(vol); err != nil { if err := c.Values.PA.SetVolume(vol); err != nil {
log.Printf("Unable to set pulseaudio volume: %s", err) log.Printf("Unable to set pulseaudio volume: %s", err)
} }
} }

View File

@@ -9,20 +9,20 @@ import (
var PrintOutput = true var PrintOutput = true
// SigHandler OS signal handler. // SigHandler OS signal handler.
func (c MyConfig) SigHandler() { func (c *MyConfig) SigHandler() {
for s := range c.SigChan { for s := range c.Channels.SigChan {
switch s { switch s {
case syscall.SIGUSR1: case syscall.SIGUSR1:
log.Print("Got SIGUSR1, stopping output") log.Print("Got SIGUSR1, stopping output")
PrintOutput = false c.Values.PrintOutput = false
case syscall.SIGUSR2: case syscall.SIGUSR2:
log.Print("Got SIGUSR2, resuming output") log.Print("Got SIGUSR2, resuming output")
PrintOutput = true c.Values.PrintOutput = true
c.UpdateReady <- true c.Channels.UpdateReady <- true
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT: case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
os.Exit(0) os.Exit(0)

View File

@@ -8,12 +8,9 @@ import (
"time" "time"
) )
// RunChan to this channel we send command and its argv to execute as separate process.
var RunChan = make(chan []string, 128)
// Spawner forks and execs given program, and also detaches form its control tty. // Spawner forks and execs given program, and also detaches form its control tty.
func (c MyConfig) Spawner() { func (c *MyConfig) Spawner() {
for prg := range RunChan { for prg := range c.Channels.RunChan {
devnullR, _ := os.Open(os.DevNull) devnullR, _ := os.Open(os.DevNull)
devnullW, _ := os.OpenFile(os.DevNull, os.O_WRONLY|os.O_APPEND, 0644) devnullW, _ := os.OpenFile(os.DevNull, os.O_WRONLY|os.O_APPEND, 0644)
@@ -48,7 +45,7 @@ func (c MyConfig) Spawner() {
} }
// CleanZombies reaps processes spawned by Spawner() and already exited. // CleanZombies reaps processes spawned by Spawner() and already exited.
func (c MyConfig) CleanZombies() { func (c *MyConfig) CleanZombies() {
r := syscall.Rusage{} r := syscall.Rusage{}
for { for {

View File

@@ -26,7 +26,7 @@ type ClickEvent struct {
// ParseStdin tries to parse text that i3bar prints to our stdin. Currently - it is mouse click events on different // ParseStdin tries to parse text that i3bar prints to our stdin. Currently - it is mouse click events on different
// area names of i3bar. // area names of i3bar.
func (c MyConfig) ParseStdin() { func (c *MyConfig) ParseStdin() {
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
// De-facto it is jsonl, except first line is garbage. Also, first symbol in each strint garbage too. // De-facto it is jsonl, except first line is garbage. Also, first symbol in each strint garbage too.
@@ -84,35 +84,35 @@ func (c MyConfig) ParseStdin() {
// Clock clicks parse. // Clock clicks parse.
if e.Name == "wallclock" { if e.Name == "wallclock" {
if Conf.Clock.LeftClick.Enabled && e.Button == 1 { if c.Clock.LeftClick.Enabled && e.Button == 1 {
RunChan <- Conf.Clock.LeftClick.Cmd c.Channels.RunChan <- c.Clock.LeftClick.Cmd
} else if Conf.Clock.RightClick.Enabled && e.Button == 3 { } else if c.Clock.RightClick.Enabled && e.Button == 3 {
RunChan <- Conf.Clock.RightClick.Cmd c.Channels.RunChan <- c.Clock.RightClick.Cmd
} }
continue continue
} }
if e.Name == "simple-volume-pa" { if e.Name == "simple-volume-pa" {
if Conf.SimpleVolumePa.Enabled { if c.SimpleVolumePa.Enabled {
SVPAHandlerChan <- e c.Channels.SVPAHandlerChan <- e
} }
continue continue
} }
if !Conf.AppButtons.Enabled { if !c.AppButtons.Enabled {
continue continue
} }
for _, app := range Conf.Apps { for _, app := range c.Apps {
switch { switch {
case app.Name != "" && app.Instance != "": case app.Name != "" && app.Instance != "":
if app.Name == e.Name && app.Instance == e.Instance { if app.Name == e.Name && app.Instance == e.Instance {
prg := append([]string{}, app.Cmd) prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...) prg = append(prg, app.Args...)
RunChan <- prg c.Channels.RunChan <- prg
break break
} }
@@ -120,13 +120,13 @@ func (c MyConfig) ParseStdin() {
prg := append([]string{}, app.Cmd) prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...) prg = append(prg, app.Args...)
RunChan <- prg c.Channels.RunChan <- prg
case app.Instance != "" && e.Instance == app.Instance: case app.Instance != "" && e.Instance == app.Instance:
prg := append([]string{}, app.Cmd) prg := append([]string{}, app.Cmd)
prg = append(prg, app.Args...) prg = append(prg, app.Args...)
RunChan <- prg c.Channels.RunChan <- prg
} }
} }
} }

View File

@@ -8,7 +8,7 @@ import (
) )
// UpdateVPNStatus periodically update status of openvpn daemon. // UpdateVPNStatus periodically update status of openvpn daemon.
func (c MyConfig) UpdateVPNStatus() { func (c *MyConfig) UpdateVPNStatus() {
var ( var (
vpnCStatus string vpnCStatus string
tcpCheck string tcpCheck string
@@ -17,28 +17,28 @@ func (c MyConfig) UpdateVPNStatus() {
for { for {
if c.VPNFileCheck() { if c.VPNFileCheck() {
if Conf.Vpn.UpColor == "" { if c.Vpn.UpColor == "" {
vpnCheck = `⍋` vpnCheck = `⍋`
} else { } else {
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍋</span>`, c.Vpn.UpColor) vpnCheck = fmt.Sprintf(`<span foreground="%s">⍋</span>`, c.Vpn.UpColor)
} }
} else { } else {
if Conf.Vpn.DownColor == "" { if c.Vpn.DownColor == "" {
vpnCheck = `⍒` vpnCheck = `⍒`
} else { } else {
vpnCheck = fmt.Sprintf(`<span foreground="%s">⍒</span>`, c.Vpn.DownColor) vpnCheck = fmt.Sprintf(`<span foreground="%s">⍒</span>`, c.Vpn.DownColor)
} }
} }
if Conf.Vpn.TCPCheck.Enabled { if c.Vpn.TCPCheck.Enabled {
if c.VPNTCPCheck() { if c.VPNTCPCheck() {
if Conf.Vpn.UpColor == "" { if c.Vpn.UpColor == "" {
tcpCheck = `✔` tcpCheck = `✔`
} else { } else {
tcpCheck = fmt.Sprintf(`<span foreground="%s">✔</span>`, c.Vpn.UpColor) tcpCheck = fmt.Sprintf(`<span foreground="%s">✔</span>`, c.Vpn.UpColor)
} }
} else { } else {
if Conf.Vpn.DownColor == "" { if c.Vpn.DownColor == "" {
tcpCheck = `✘` tcpCheck = `✘`
} else { } else {
tcpCheck = fmt.Sprintf(`<span foreground="%s">✘</span>`, c.Vpn.DownColor) tcpCheck = fmt.Sprintf(`<span foreground="%s">✘</span>`, c.Vpn.DownColor)
@@ -50,9 +50,9 @@ func (c MyConfig) UpdateVPNStatus() {
vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck) vpnCStatus = fmt.Sprintf("VPN:%s", vpnCheck)
} }
if c.VPNStatus != vpnCStatus { if c.Values.VPNStatus != vpnCStatus {
c.VPNStatus = vpnCStatus c.Values.VPNStatus = vpnCStatus
c.UpdateReady <- true c.Channels.UpdateReady <- true
} }
time.Sleep(3 * time.Second) time.Sleep(3 * time.Second)
@@ -60,7 +60,7 @@ func (c MyConfig) UpdateVPNStatus() {
} }
// VPNTCPCheck intended to check arbitrary service inside vpn segment, to indicate that openvpn sevice not stoned. // VPNTCPCheck intended to check arbitrary service inside vpn segment, to indicate that openvpn sevice not stoned.
func (c MyConfig) VPNTCPCheck() bool { func (c *MyConfig) VPNTCPCheck() bool {
conn, err := net.DialTimeout( conn, err := net.DialTimeout(
"tcp", "tcp",
fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port), fmt.Sprintf("%s:%d", c.Vpn.TCPCheck.Host, c.Vpn.TCPCheck.Port),
@@ -76,7 +76,7 @@ func (c MyConfig) VPNTCPCheck() bool {
} }
// VPNFileCheck checks modification time of openvpn-status file. // VPNFileCheck checks modification time of openvpn-status file.
func (c MyConfig) VPNFileCheck() bool { func (c *MyConfig) VPNFileCheck() bool {
var ( var (
fi os.FileInfo fi os.FileInfo
err error err error