Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9ce425981 | ||
|
|
069b09e5ec | ||
|
|
8f2afa0441 | ||
|
|
8fa1c6d596 | ||
|
|
12f4dc75f0 | ||
|
|
913fcc34ee | ||
|
|
ac856f4174 | ||
|
|
a5d793926b | ||
|
|
40a94bd001 | ||
|
|
d19836b821 | ||
|
|
32d865e24e | ||
|
|
757fb5e57e | ||
|
|
6b81991ebb |
10
Makefile
10
Makefile
@@ -4,6 +4,7 @@ BUILDOPTS=-ldflags="-s -w" -a -gcflags=all=-l -trimpath -buildvcs=false
|
|||||||
|
|
||||||
BINARY=i3status-go
|
BINARY=i3status-go
|
||||||
TEST1=battery-test
|
TEST1=battery-test
|
||||||
|
TEST2=cmdrun-test
|
||||||
|
|
||||||
## Use calssic targets where first one is deafult target
|
## Use calssic targets where first one is deafult target
|
||||||
all: clean build
|
all: clean build
|
||||||
@@ -16,15 +17,18 @@ battery-test:
|
|||||||
rm -rf ${TEST1}
|
rm -rf ${TEST1}
|
||||||
go build ${BUILDOPTS} -o ${TEST1} ./cmd/${TEST1}
|
go build ${BUILDOPTS} -o ${TEST1} ./cmd/${TEST1}
|
||||||
|
|
||||||
|
cmdrun-test:
|
||||||
|
rm -rf ${TEST1}
|
||||||
|
go build ${BUILDOPTS} -o ${TEST2} ./cmd/${TEST2}
|
||||||
|
|
||||||
## Remove binary with golang compiler' means
|
## Remove binary with golang compiler' means
|
||||||
clean:
|
clean:
|
||||||
rm -rf ${BINARY} ${TEST1}
|
rm -rf ${BINARY} ${TEST1} ${TEST2}
|
||||||
|
|
||||||
|
|
||||||
## Misc target, for development purposes. Updates vendored libs, brutal way.
|
## Misc target, for development purposes. Updates vendored libs, brutal way.
|
||||||
upgrade:
|
upgrade:
|
||||||
$(RM) -r vendor
|
$(RM) -r vendor
|
||||||
go get -u -t -tool ./...
|
go get -u -t ./...
|
||||||
go mod tidy
|
go mod tidy
|
||||||
go mod vendor
|
go mod vendor
|
||||||
|
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ It is i3bar text generator.
|
|||||||
* PulseAudio volume indicator, can adjust master volume too
|
* PulseAudio volume indicator, can adjust master volume too
|
||||||
* Clock
|
* Clock
|
||||||
* Cron jobs (intended to use for show periodic desktop notifications but not limited to)
|
* Cron jobs (intended to use for show periodic desktop notifications but not limited to)
|
||||||
|
* Show output of one-shot system command
|
||||||
|
|
||||||
## How to build it
|
## How to build it
|
||||||
|
|
||||||
This appliction was tested to compile with go v1.21 but can be built with earlier versions (seems down to 1.18, not
|
This application was tested to compile with go v1.24.
|
||||||
sure).
|
|
||||||
All you need is go lang compiler and gnu make utility. Invoke
|
All you need is go lang compiler and gnu make utility. Invoke
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// Default text and *block* border colors. If not set #3e78fd is used.
|
// Default text and *block* border colors. If not set #3e78fd is used.
|
||||||
"color" : "#3e78fd",
|
"color" : "#3e78fd",
|
||||||
|
|
||||||
// Default backbround color. If not set value of #edeceb is used.
|
// Default background color. If not set value of #edeceb is used.
|
||||||
"background" : "#000000",
|
"background" : "#000000",
|
||||||
|
|
||||||
// Can be omitted, then Liberation Mono will be used.
|
// Can be omitted, then Liberation Mono will be used.
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
// ‘smaller’ or ‘larger’
|
// ‘smaller’ or ‘larger’
|
||||||
"font_size": "medium",
|
"font_size": "medium",
|
||||||
|
|
||||||
"separator" : {
|
"separator": {
|
||||||
"left": {
|
"left": {
|
||||||
// Set to false if omitted.
|
// Set to false if omitted.
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
@@ -518,6 +518,15 @@
|
|||||||
"battery": {
|
"battery": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
|
||||||
|
// Valid only on linux, where we have mounted sysfs and /sys/class/power_supply/BAT0/capacity available
|
||||||
|
"use_sysfs": false,
|
||||||
|
|
||||||
|
// it is possible to set files here, if none set, /sys/class/power_supply/BAT0/capacity will be taken.
|
||||||
|
"sysfs_files": [
|
||||||
|
"/sys/class/power_supply/BAT0/capacity",
|
||||||
|
"/sys/class/power_supply/HIDP0/capacity"
|
||||||
|
],
|
||||||
|
|
||||||
// If omitted set to default color defined up here.
|
// If omitted set to default color defined up here.
|
||||||
"color": "#3e78fd",
|
"color": "#3e78fd",
|
||||||
|
|
||||||
@@ -693,10 +702,95 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Prints stdout of command to panel.
|
||||||
|
"cmdrun" : {
|
||||||
|
"enabled": false,
|
||||||
|
|
||||||
|
// Delay between two consecutive command batch runs.
|
||||||
|
"delay": 3,
|
||||||
|
|
||||||
|
// command' binary.
|
||||||
|
"cmd": "/bin/bash",
|
||||||
|
|
||||||
|
// Arguments for command binary.
|
||||||
|
"args": ["-c", "echo 42"],
|
||||||
|
|
||||||
|
// If omitted set to default color defined up here.
|
||||||
|
"color": "#3e78fd",
|
||||||
|
|
||||||
|
// If omitted set to default background color defined up here.
|
||||||
|
"background": "#000000",
|
||||||
|
|
||||||
|
// If omitted set to default font defined up here.
|
||||||
|
"font": "Noto Sans",
|
||||||
|
|
||||||
|
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
|
||||||
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
|
||||||
|
"font_size": "medium",
|
||||||
|
|
||||||
|
// Re-define separator parameters for each command block here.
|
||||||
|
"separator": {
|
||||||
|
"left": {
|
||||||
|
// Set to false if omitted.
|
||||||
|
"enabled": true,
|
||||||
|
|
||||||
|
// If omitted set to default color defined for separator up here.
|
||||||
|
"color": "#3e78fd",
|
||||||
|
|
||||||
|
// If omitted set to default background color defined for separator up here.
|
||||||
|
"background": "#000000",
|
||||||
|
|
||||||
|
// If omitted set to default symbol defined for separator up here.
|
||||||
|
"symbol": "▶",
|
||||||
|
|
||||||
|
// If omitted set to default font defined for separator up here.
|
||||||
|
"font": "Noto Sans",
|
||||||
|
|
||||||
|
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
|
||||||
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
|
||||||
|
"font_size": "medium"
|
||||||
|
},
|
||||||
|
|
||||||
|
"right": {
|
||||||
|
// Set to false if omitted.
|
||||||
|
"enabled": true,
|
||||||
|
|
||||||
|
// If omitted set to default color defined for separator up here.
|
||||||
|
"color": "#3e78fd",
|
||||||
|
|
||||||
|
// If omitted set to default background color defined for separator up here.
|
||||||
|
"background": "#000000",
|
||||||
|
|
||||||
|
// If omitted set to default symbol defined for separator up here.
|
||||||
|
"symbol": "◀",
|
||||||
|
|
||||||
|
// If omitted set to default font defined for separator up here.
|
||||||
|
"font": "Noto Sans",
|
||||||
|
|
||||||
|
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
|
||||||
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
|
||||||
|
"font_size": "medium"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Whether to display Application Buttons.
|
// Whether to display Application Buttons.
|
||||||
"app_buttons": {
|
"app_buttons": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
|
||||||
|
// If omitted set to default color defined up here.
|
||||||
|
"color": "#3e78fd",
|
||||||
|
|
||||||
|
// If omitted set to default background color defined up here.
|
||||||
|
"background": "#000000",
|
||||||
|
|
||||||
|
// If omitted set to default font defined up here.
|
||||||
|
"font": "Noto Sans",
|
||||||
|
|
||||||
|
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
|
||||||
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined up here.
|
||||||
|
"font_size": "medium",
|
||||||
|
|
||||||
// Re-define separator parameters for net-if block here.
|
// Re-define separator parameters for net-if block here.
|
||||||
"separator": {
|
"separator": {
|
||||||
"left": {
|
"left": {
|
||||||
@@ -740,31 +834,36 @@
|
|||||||
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for separator up here.
|
||||||
"font_size": "medium"
|
"font_size": "medium"
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Buttons - application launch "buttons"
|
// Buttons - application launch "buttons"
|
||||||
"apps": [
|
"apps": [
|
||||||
{
|
{
|
||||||
// Text dispalyed on button
|
// Text displayed on button, pango markup supported.
|
||||||
"full_text" : "📂",
|
"full_text" : "📂",
|
||||||
// Internal name, can be any string, but unique for each app button
|
// Internal name, can be any string, but unique for each app button.
|
||||||
"name" : "thunar",
|
"name" : "thunar",
|
||||||
// Command itself
|
// Command itself.
|
||||||
"cmd" : "thunar",
|
"cmd" : "thunar",
|
||||||
// Array of command args, optional
|
// Array of command args, optional.
|
||||||
"args": [ "." ],
|
"args": [ "." ],
|
||||||
// Regexp that match with Instance component of WM_CLASS(STRING) of xprop output
|
// Regexp that match with Instance component of WM_CLASS(STRING) of xprop output.
|
||||||
"instance": "^thunar$",
|
"instance": "^thunar$",
|
||||||
// Regexp that match with Class component of WM_CLASS(STRING) of xprop output
|
// Regexp that match with Class component of WM_CLASS(STRING) of xprop output.
|
||||||
"class": "^Thunar$",
|
"class": "^Thunar$",
|
||||||
// text color in html notation
|
// Text color in html notation.
|
||||||
"color": "#ffa500",
|
"color": "#ffa500",
|
||||||
// background color in html notation
|
// background color in html notation.
|
||||||
"background" : "#000000",
|
"background" : "#000000",
|
||||||
// border color in html notation
|
// If omitted set to default font defined for app_buttons up here.
|
||||||
|
"font": "Noto Sans",
|
||||||
|
// ‘xx-small’, ‘x-small’, ‘small’, ‘medium’, ‘large’, ‘x-large’, ‘xx-large’, or one of relative sizes
|
||||||
|
// ‘smaller’ or ‘larger’. If omitted set to default font size defined for app_buttons up here.
|
||||||
|
"font_size": "medium",
|
||||||
|
// Border color in html notation.
|
||||||
"border": "#666666",
|
"border": "#666666",
|
||||||
// border color if there is at least one window with given Instance and/or Class exist
|
// Border color if there is at least one window with given Instance and/or Class exist.
|
||||||
"border_active": "#3e78fd",
|
"border_active": "#3e78fd",
|
||||||
// Vertical line between objects on bar - if omitted true value is assumed by i3bar, but we set it to false
|
// Vertical line between objects on bar - if omitted true value is assumed by i3bar, but we set it to false
|
||||||
// in that case. It is limitation of golang json parser.
|
// in that case. It is limitation of golang json parser.
|
||||||
|
|||||||
@@ -84,6 +84,14 @@ func main() {
|
|||||||
Conf.Clock.FontSize,
|
Conf.Clock.FontSize,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Conf.Values.RunCommandOutput = fmt.Sprintf(
|
||||||
|
"<span color='%s' background='%s' font='%s' size='%s'>?</span>",
|
||||||
|
Conf.CmdRun.Color,
|
||||||
|
Conf.CmdRun.Background,
|
||||||
|
Conf.CmdRun.Font,
|
||||||
|
Conf.CmdRun.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
go Conf.Spawner()
|
go Conf.Spawner()
|
||||||
go Conf.ParseStdin()
|
go Conf.ParseStdin()
|
||||||
go Conf.CleanZombies()
|
go Conf.CleanZombies()
|
||||||
@@ -143,6 +151,10 @@ func main() {
|
|||||||
go Conf.UpdateVPNStatus()
|
go Conf.UpdateVPNStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Conf.CmdRun.Enabled {
|
||||||
|
go Conf.RunCommand()
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
I3bar documentation pretends that message protocol must be valid json. In practice, we only have to print valid
|
I3bar documentation pretends that message protocol must be valid json. In practice, we only have to print valid
|
||||||
header, empty json array and (potentially infinite) json lines (line that is valid json by itself) that is
|
header, empty json array and (potentially infinite) json lines (line that is valid json by itself) that is
|
||||||
@@ -180,7 +192,14 @@ func main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.FullText = app.FullText
|
b.FullText = fmt.Sprintf(
|
||||||
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
|
app.Color,
|
||||||
|
app.Background,
|
||||||
|
app.Font,
|
||||||
|
app.FontSize,
|
||||||
|
app.FullText,
|
||||||
|
)
|
||||||
|
|
||||||
if num == len(Conf.Apps) {
|
if num == len(Conf.Apps) {
|
||||||
b.FullText = fmt.Sprintf(
|
b.FullText = fmt.Sprintf(
|
||||||
@@ -193,8 +212,6 @@ func main() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
b.Background = app.Background
|
|
||||||
b.Color = app.Color
|
|
||||||
b.Instance = app.Instance
|
b.Instance = app.Instance
|
||||||
b.Markup = `pango`
|
b.Markup = `pango`
|
||||||
b.Separator = app.Separator
|
b.Separator = app.Separator
|
||||||
@@ -519,6 +536,50 @@ func main() {
|
|||||||
j = append(j, b)
|
j = append(j, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Conf.CmdRun.Enabled {
|
||||||
|
var b lib.I3BarOutBlock
|
||||||
|
|
||||||
|
b.Name = `runcommandoutput`
|
||||||
|
b.Color = Conf.CmdRun.Color
|
||||||
|
b.Background = Conf.CmdRun.Background
|
||||||
|
|
||||||
|
if Conf.CmdRun.Separator.Left.Enabled {
|
||||||
|
b.FullText = fmt.Sprintf(
|
||||||
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
|
Conf.CmdRun.Separator.Left.Color,
|
||||||
|
Conf.CmdRun.Separator.Left.Background,
|
||||||
|
Conf.CmdRun.Separator.Left.Font,
|
||||||
|
Conf.CmdRun.Separator.Left.FontSize,
|
||||||
|
Conf.CmdRun.Separator.Left.Symbol,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.FullText += fmt.Sprintf(
|
||||||
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
|
Conf.CmdRun.Color,
|
||||||
|
Conf.CmdRun.Background,
|
||||||
|
Conf.CmdRun.Font,
|
||||||
|
Conf.CmdRun.FontSize,
|
||||||
|
Conf.Values.RunCommandOutput,
|
||||||
|
)
|
||||||
|
|
||||||
|
if Conf.CmdRun.Separator.Right.Enabled {
|
||||||
|
b.FullText += fmt.Sprintf(
|
||||||
|
"<span color='%s' background='%s' font='%s' size='%s'>%s</span>",
|
||||||
|
Conf.CmdRun.Separator.Right.Color,
|
||||||
|
Conf.CmdRun.Separator.Right.Background,
|
||||||
|
Conf.CmdRun.Separator.Right.Font,
|
||||||
|
Conf.CmdRun.Separator.Right.FontSize,
|
||||||
|
Conf.CmdRun.Separator.Right.Symbol,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
b.Markup = "pango"
|
||||||
|
b.Separator = false
|
||||||
|
|
||||||
|
j = append(j, b)
|
||||||
|
}
|
||||||
|
|
||||||
if Conf.Clock.Enabled {
|
if Conf.Clock.Enabled {
|
||||||
var b lib.I3BarOutBlock
|
var b lib.I3BarOutBlock
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
/home/eleksir/git/i3status-go/cmd/i3status-go/default-config.json
|
../cmd/i3status-go/default-config.json
|
||||||
@@ -2,7 +2,12 @@ package lib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"math"
|
"math"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/distatus/battery"
|
"github.com/distatus/battery"
|
||||||
@@ -11,9 +16,6 @@ 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
|
|
||||||
status string
|
|
||||||
Batts string
|
|
||||||
InitialDelay = 100 * time.Millisecond
|
InitialDelay = 100 * time.Millisecond
|
||||||
LoopIterationDelay = 5 * time.Second
|
LoopIterationDelay = 5 * time.Second
|
||||||
Delay = InitialDelay
|
Delay = InitialDelay
|
||||||
@@ -26,9 +28,85 @@ func (c *MyConfig) UpdateBatteryInfo() {
|
|||||||
ticker.Reset(Delay)
|
ticker.Reset(Delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
batteries, _ := battery.GetAll()
|
var (
|
||||||
// In theory, this module should give for each entry its separate err, but in practice it gives
|
batteries = []*battery.Battery{}
|
||||||
// one single err for all entries, so we cannot detemine whist exatly entry errored.
|
Batts string
|
||||||
|
ch int
|
||||||
|
status string
|
||||||
|
)
|
||||||
|
|
||||||
|
if c.Battery.UseSysfs {
|
||||||
|
for _, file := range c.Battery.SysfsFiles {
|
||||||
|
var batt battery.Battery
|
||||||
|
|
||||||
|
_, err := os.Stat(file)
|
||||||
|
|
||||||
|
// If file exists.
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
var (
|
||||||
|
myCharge string
|
||||||
|
myStatus string
|
||||||
|
)
|
||||||
|
|
||||||
|
b, err := os.ReadFile(file)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Unable to read file %s: %s", file, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
myCharge = strings.Trim(string(b), "\n")
|
||||||
|
|
||||||
|
statusFile := filepath.Dir(file) + "/status"
|
||||||
|
|
||||||
|
// If file exists.
|
||||||
|
if !os.IsNotExist(err) {
|
||||||
|
b, err := os.ReadFile(statusFile)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Unable to read file %s: %s", statusFile, err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
myStatus = strings.Trim(string(b), "\n")
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make stub battery class :) .
|
||||||
|
switch myStatus {
|
||||||
|
case "Charging":
|
||||||
|
batt.State.Raw = battery.Charging
|
||||||
|
case "Discharging":
|
||||||
|
batt.State.Raw = battery.Discharging
|
||||||
|
case "Empty":
|
||||||
|
batt.State.Raw = battery.Empty
|
||||||
|
case "Full":
|
||||||
|
batt.State.Raw = battery.Full
|
||||||
|
default:
|
||||||
|
batt.State.Raw = battery.Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := strconv.Atoi(myCharge)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Unable to convert string from file %s to integer", file)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
batt.Current = float64(ch)
|
||||||
|
|
||||||
|
batteries = append(batteries, &batt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// In theory, this module should give for each entry its separate err, but in practice it gives
|
||||||
|
// one single err for all entries, so we cannot detemine whist exatly entry errored.
|
||||||
|
batteries, _ = battery.GetAll()
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
battsInfo string
|
battsInfo string
|
||||||
@@ -49,7 +127,11 @@ func (c *MyConfig) UpdateBatteryInfo() {
|
|||||||
|
|
||||||
// N.B. there can be case when battery is overcharged and shows >100%. It also can indicate that
|
// N.B. there can be case when battery is overcharged and shows >100%. It also can indicate that
|
||||||
// calibration data is out of date and battery should be re-calibrated.
|
// calibration data is out of date and battery should be re-calibrated.
|
||||||
ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full)))
|
if c.Battery.UseSysfs {
|
||||||
|
ch = int(b.Current)
|
||||||
|
} else {
|
||||||
|
ch = int(math.Round((b.Full - (b.Full - b.Current)) * (100 / b.Full)))
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case ch <= 500 && ch >= 84:
|
case ch <= 500 && ch >= 84:
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ type I3BarOutBlock struct {
|
|||||||
ShortText string `json:"short_text,omitempty"`
|
ShortText string `json:"short_text,omitempty"`
|
||||||
Color string `json:"color,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
Background string `json:"background,omitempty"`
|
Background string `json:"background,omitempty"`
|
||||||
|
Font string `json:"font,omitempty"`
|
||||||
|
FontSize string `json:"font_size,omitempty"`
|
||||||
Border string `json:"border,omitempty"`
|
Border string `json:"border,omitempty"`
|
||||||
BorderTop int `json:"border_top"`
|
BorderTop int `json:"border_top"`
|
||||||
BorderRight int `json:"border_right"`
|
BorderRight int `json:"border_right"`
|
||||||
@@ -59,16 +61,17 @@ type Separator struct {
|
|||||||
|
|
||||||
type MyConfig struct {
|
type MyConfig struct {
|
||||||
Values struct {
|
Values struct {
|
||||||
PrintOutput bool
|
PrintOutput bool
|
||||||
CPUTemperature int64
|
CPUTemperature int64
|
||||||
BatteryString string
|
BatteryString string
|
||||||
ClockTime string
|
ClockTime string
|
||||||
IfStatus string
|
IfStatus string
|
||||||
VPNStatus string
|
VPNStatus string
|
||||||
Memory Mem
|
Memory Mem
|
||||||
La string
|
La string
|
||||||
PA *p.Client
|
PA *p.Client
|
||||||
SoundVolume string
|
SoundVolume string
|
||||||
|
RunCommandOutput string
|
||||||
}
|
}
|
||||||
|
|
||||||
Channels struct {
|
Channels struct {
|
||||||
@@ -134,14 +137,16 @@ type MyConfig struct {
|
|||||||
} `json:"clock,omitempty"`
|
} `json:"clock,omitempty"`
|
||||||
|
|
||||||
Battery struct {
|
Battery struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Color string `json:"color,omitempty"`
|
UseSysfs bool `json:"use_sysfs,omitempty"`
|
||||||
Background string `json:"background,omitempty"`
|
SysfsFiles []string `json:"sysfs_files,omitempty"`
|
||||||
Font string `json:"font,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
FontSize string `json:"font_size,omitempty"`
|
Background string `json:"background,omitempty"`
|
||||||
Symbol string `json:"symbol,omitempty"`
|
Font string `json:"font,omitempty"`
|
||||||
SymbolFont string `json:"symbol_font,omitempty"`
|
FontSize string `json:"font_size,omitempty"`
|
||||||
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
Symbol string `json:"symbol,omitempty"`
|
||||||
|
SymbolFont string `json:"symbol_font,omitempty"`
|
||||||
|
SymbolFontSize string `json:"symbol_font_size,omitempty"`
|
||||||
|
|
||||||
ChargeColor struct {
|
ChargeColor struct {
|
||||||
Full string `json:"full,omitempty"`
|
Full string `json:"full,omitempty"`
|
||||||
@@ -229,9 +234,25 @@ type MyConfig struct {
|
|||||||
} `json:"tasks,omitempty"`
|
} `json:"tasks,omitempty"`
|
||||||
} `json:"cron,omitempty"`
|
} `json:"cron,omitempty"`
|
||||||
|
|
||||||
|
CmdRun struct {
|
||||||
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
|
Color string `json:"color,omitempty"`
|
||||||
|
Background string `json:"background,omitempty"`
|
||||||
|
Font string `json:"font,omitempty"`
|
||||||
|
FontSize string `json:"font_size,omitempty"`
|
||||||
|
Separator Separator `json:"separator,omitempty"`
|
||||||
|
Cmd string `json:"cmd,omitempty"`
|
||||||
|
Delay int `json:"delay,omitempty"`
|
||||||
|
Args []string `json:"args,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
AppButtons struct {
|
AppButtons struct {
|
||||||
Enabled bool `json:"enabled,omitempty"`
|
Enabled bool `json:"enabled,omitempty"`
|
||||||
Separator Separator `json:"separator,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
|
Background string `json:"background,omitempty"`
|
||||||
|
Font string `json:"font,omitempty"`
|
||||||
|
FontSize string `json:"font_size,omitempty"`
|
||||||
|
Separator Separator `json:"separator,omitempty"`
|
||||||
} `json:"app_buttons,omitempty"`
|
} `json:"app_buttons,omitempty"`
|
||||||
|
|
||||||
Apps []struct {
|
Apps []struct {
|
||||||
@@ -243,6 +264,8 @@ type MyConfig struct {
|
|||||||
Class string `json:"class,omitempty"`
|
Class string `json:"class,omitempty"`
|
||||||
Color string `json:"color,omitempty"`
|
Color string `json:"color,omitempty"`
|
||||||
Background string `json:"background,omitempty"`
|
Background string `json:"background,omitempty"`
|
||||||
|
Font string `json:"font,omitempty"`
|
||||||
|
FontSize string `json:"font_size,omitempty"`
|
||||||
Border string `json:"border,omitempty"`
|
Border string `json:"border,omitempty"`
|
||||||
BorderActive string `json:"border_active,omitempty"`
|
BorderActive string `json:"border_active,omitempty"`
|
||||||
Separator bool `json:"separator,omitempty"`
|
Separator bool `json:"separator,omitempty"`
|
||||||
@@ -449,6 +472,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.LA.FontSize == "" {
|
if sampleConfig.LA.FontSize == "" {
|
||||||
sampleConfig.LA.FontSize = sampleConfig.FontSize
|
sampleConfig.LA.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.LA.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.LA.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.LA.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.LA.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.LA.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Left.Color == "" {
|
if sampleConfig.LA.Separator.Left.Color == "" {
|
||||||
@@ -503,22 +550,6 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
sampleConfig.LA.Separator.Right.Background = sampleConfig.Separator.Right.Background
|
sampleConfig.LA.Separator.Right.Background = sampleConfig.Separator.Right.Background
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Right.Font == "" {
|
|
||||||
sampleConfig.LA.Separator.Right.Font = sampleConfig.Separator.Right.Font
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Right.FontSize == "" {
|
|
||||||
sampleConfig.LA.Separator.Right.FontSize = sampleConfig.Separator.Right.FontSize
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Right.Color == "" {
|
|
||||||
sampleConfig.LA.Separator.Right.Color = sampleConfig.Separator.Right.Color
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Right.Background == "" {
|
|
||||||
sampleConfig.LA.Separator.Right.Background = sampleConfig.Separator.Right.Background
|
|
||||||
}
|
|
||||||
|
|
||||||
if sampleConfig.LA.Separator.Right.Symbol == "" {
|
if sampleConfig.LA.Separator.Right.Symbol == "" {
|
||||||
sampleConfig.LA.Separator.Right.Symbol = sampleConfig.Separator.Right.Symbol
|
sampleConfig.LA.Separator.Right.Symbol = sampleConfig.Separator.Right.Symbol
|
||||||
}
|
}
|
||||||
@@ -569,6 +600,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.Mem.FontSize == "" {
|
if sampleConfig.Mem.FontSize == "" {
|
||||||
sampleConfig.Mem.FontSize = sampleConfig.FontSize
|
sampleConfig.Mem.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.Mem.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Mem.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Mem.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Mem.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Mem.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Mem.Separator.Left.Color == "" {
|
if sampleConfig.Mem.Separator.Left.Color == "" {
|
||||||
@@ -673,6 +728,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.Clock.FontSize == "" {
|
if sampleConfig.Clock.FontSize == "" {
|
||||||
sampleConfig.Clock.FontSize = sampleConfig.FontSize
|
sampleConfig.Clock.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.Clock.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Clock.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Clock.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Clock.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Clock.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Clock.Separator.Left.Enabled {
|
if sampleConfig.Clock.Separator.Left.Enabled {
|
||||||
@@ -778,6 +857,15 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sampleConfig.Battery.Enabled will be false if not set in config
|
// sampleConfig.Battery.Enabled will be false if not set in config
|
||||||
|
// sampleConfig.Battery.UseSysfs will be false if not set in config
|
||||||
|
|
||||||
|
if len(sampleConfig.Battery.SysfsFiles) == 0 {
|
||||||
|
sampleConfig.Battery.SysfsFiles = append(
|
||||||
|
sampleConfig.Battery.SysfsFiles,
|
||||||
|
"/sys/class/power_supply/BAT0/capacity",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if sampleConfig.Battery.Color == "" {
|
if sampleConfig.Battery.Color == "" {
|
||||||
sampleConfig.Battery.Color = sampleConfig.Color
|
sampleConfig.Battery.Color = sampleConfig.Color
|
||||||
}
|
}
|
||||||
@@ -792,6 +880,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.Battery.FontSize == "" {
|
if sampleConfig.Battery.FontSize == "" {
|
||||||
sampleConfig.Battery.FontSize = sampleConfig.FontSize
|
sampleConfig.Battery.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.Battery.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Battery.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Battery.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Battery.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Battery.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Battery.Symbol == "" {
|
if sampleConfig.Battery.Symbol == "" {
|
||||||
@@ -804,6 +916,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.Battery.SymbolFontSize == "" {
|
if sampleConfig.Battery.SymbolFontSize == "" {
|
||||||
sampleConfig.Battery.SymbolFontSize = sampleConfig.Battery.FontSize
|
sampleConfig.Battery.SymbolFontSize = sampleConfig.Battery.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.Battery.SymbolFontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Battery.SymbolFontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.Battery.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Battery.SymbolFontSize = sampleConfig.Battery.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Battery.SymbolFontSize, fallback to %s",
|
||||||
|
sampleConfig.Battery.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Battery.SymbolFontSize = sampleConfig.Battery.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sampleConfig.Battery.ChargeColor.Full will be empty string if not set
|
// sampleConfig.Battery.ChargeColor.Full will be empty string if not set
|
||||||
@@ -919,6 +1055,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.CPUTemp.FontSize == "" {
|
if sampleConfig.CPUTemp.FontSize == "" {
|
||||||
sampleConfig.CPUTemp.FontSize = sampleConfig.FontSize
|
sampleConfig.CPUTemp.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.CPUTemp.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CPUTemp.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CPUTemp.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CPUTemp.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CPUTemp.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.CPUTemp.Separator.Left.Enabled {
|
if sampleConfig.CPUTemp.Separator.Left.Enabled {
|
||||||
@@ -1025,11 +1185,35 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Vpn.Font == "" {
|
if sampleConfig.Vpn.Font == "" {
|
||||||
sampleConfig.Vpn.FontSize = sampleConfig.Font
|
sampleConfig.Vpn.Font = sampleConfig.Font
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.Vpn.FontSize == "" {
|
if sampleConfig.Vpn.FontSize == "" {
|
||||||
sampleConfig.Vpn.FontSize = sampleConfig.FontSize
|
sampleConfig.Vpn.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.Vpn.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Vpn.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Vpn.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.Vpn.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Vpn.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check status file at least once per 3 seconds
|
// Check status file at least once per 3 seconds
|
||||||
@@ -1174,6 +1358,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.SimpleVolumePa.FontSize == "" {
|
if sampleConfig.SimpleVolumePa.FontSize == "" {
|
||||||
sampleConfig.SimpleVolumePa.FontSize = sampleConfig.FontSize
|
sampleConfig.SimpleVolumePa.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.SimpleVolumePa.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.SimpleVolumePa.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.SimpleVolumePa.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.SimpleVolumePa.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.SimpleVolumePa.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.SimpleVolumePa.Symbol == "" {
|
if sampleConfig.SimpleVolumePa.Symbol == "" {
|
||||||
@@ -1186,6 +1394,30 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.SimpleVolumePa.SymbolFontSize == "" {
|
if sampleConfig.SimpleVolumePa.SymbolFontSize == "" {
|
||||||
sampleConfig.SimpleVolumePa.SymbolFontSize = sampleConfig.SimpleVolumePa.FontSize
|
sampleConfig.SimpleVolumePa.SymbolFontSize = sampleConfig.SimpleVolumePa.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.SimpleVolumePa.SymbolFontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.SimpleVolumePa.SymbolFontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.SimpleVolumePa.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.SimpleVolumePa.SymbolFontSize = sampleConfig.SimpleVolumePa.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.SimpleVolumePa.SymbolFontSize, fallback to %s",
|
||||||
|
sampleConfig.SimpleVolumePa.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.SimpleVolumePa.SymbolFontSize = sampleConfig.SimpleVolumePa.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.SimpleVolumePa.Step == 0 {
|
if sampleConfig.SimpleVolumePa.Step == 0 {
|
||||||
@@ -1346,6 +1578,29 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
|
|
||||||
if sampleConfig.NetIf.FontSize == "" {
|
if sampleConfig.NetIf.FontSize == "" {
|
||||||
sampleConfig.NetIf.FontSize = sampleConfig.FontSize
|
sampleConfig.NetIf.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.NetIf.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.NetIf.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.NetIf.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf("Unable to set sampleConfig.NetIf.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.NetIf.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if sampleConfig.NetIf.Separator.Left.Color == "" {
|
if sampleConfig.NetIf.Separator.Left.Color == "" {
|
||||||
@@ -1435,7 +1690,186 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sampleConfig.CmdRun.Enabled will false if not set in config
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Cmd == "" && sampleConfig.CmdRun.Enabled {
|
||||||
|
sampleConfig.CmdRun.Enabled = false
|
||||||
|
|
||||||
|
log.Print(
|
||||||
|
"Setting sampleConfig.CmdRun.Enabled to false because sampleConfig.CmdRun.Cmd is not set",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sampleConfig.CmdRun.Args can be empty
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Color == "" {
|
||||||
|
sampleConfig.CmdRun.Color = sampleConfig.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Background == "" {
|
||||||
|
sampleConfig.CmdRun.Background = sampleConfig.Background
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Font == "" {
|
||||||
|
sampleConfig.CmdRun.Font = sampleConfig.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.FontSize == "" {
|
||||||
|
sampleConfig.CmdRun.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.CmdRun.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Left.Color == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Left.Color = sampleConfig.Separator.Left.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Left.Background == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Left.Background = sampleConfig.Separator.Left.Background
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Left.Symbol == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Left.Symbol = sampleConfig.Separator.Left.Symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Left.Font == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Left.Font = sampleConfig.Separator.Left.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Left.FontSize == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Left.FontSize = sampleConfig.Separator.Left.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.CmdRun.Separator.Left.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.Separator.Left.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.Separator.Left.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.Separator.Left.FontSize = sampleConfig.Separator.Left.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.Separator.Left.FontSize, fallback to %s",
|
||||||
|
sampleConfig.Separator.Left.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.Separator.Left.FontSize = sampleConfig.Separator.Left.FontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Right.Color == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Right.Color = sampleConfig.Separator.Right.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Right.Background == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Right.Background = sampleConfig.Separator.Right.Background
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Right.Symbol == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Right.Symbol = sampleConfig.Separator.Right.Symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Right.Font == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Right.Font = sampleConfig.Separator.Right.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.CmdRun.Separator.Right.FontSize == "" {
|
||||||
|
sampleConfig.CmdRun.Separator.Right.FontSize = sampleConfig.Separator.Right.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.CmdRun.Separator.Right.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.Separator.Right.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.Separator.Right.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.Separator.Right.FontSize = sampleConfig.Separator.Right.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.CmdRun.Separator.Right.FontSize, fallback to %s",
|
||||||
|
sampleConfig.Separator.Right.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.CmdRun.Separator.Right.FontSize = sampleConfig.Separator.Right.FontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sampleConfig.AppButtons.Enabled will false if not set in config
|
// sampleConfig.AppButtons.Enabled will false if not set in config
|
||||||
|
if sampleConfig.AppButtons.Color == "" {
|
||||||
|
sampleConfig.AppButtons.Color = sampleConfig.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.AppButtons.Background == "" {
|
||||||
|
sampleConfig.AppButtons.Background = sampleConfig.Background
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.AppButtons.Font == "" {
|
||||||
|
sampleConfig.AppButtons.Font = sampleConfig.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
if sampleConfig.AppButtons.FontSize == "" {
|
||||||
|
sampleConfig.AppButtons.FontSize = sampleConfig.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
sampleConfig.AppButtons.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.AppButtons.FontSize: %s, fallback to %s",
|
||||||
|
err,
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.AppButtons.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set sampleConfig.AppButtons.FontSize, fallback to %s",
|
||||||
|
sampleConfig.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.AppButtons.FontSize = sampleConfig.FontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if sampleConfig.AppButtons.Separator.Left.Color == "" {
|
if sampleConfig.AppButtons.Separator.Left.Color == "" {
|
||||||
sampleConfig.AppButtons.Separator.Left.Color = sampleConfig.Separator.Left.Color
|
sampleConfig.AppButtons.Separator.Left.Color = sampleConfig.Separator.Left.Color
|
||||||
@@ -1531,34 +1965,68 @@ func ReadConf(defaultConfig []byte) (*MyConfig, error) {
|
|||||||
// app.Instance can be missing.
|
// app.Instance can be missing.
|
||||||
// app.Class can be missing.
|
// app.Class can be missing.
|
||||||
if app.Name == "" {
|
if app.Name == "" {
|
||||||
app.Name = fmt.Sprintf("app%d", num)
|
sampleConfig.Apps[num].Name = fmt.Sprintf("app%d", num)
|
||||||
}
|
}
|
||||||
|
|
||||||
// app.Args can be empty slice. In that case command will be run without aruments.
|
// app.Args can be empty slice. In that case command will be run without aruments.
|
||||||
if app.Cmd == "" {
|
if app.Cmd == "" {
|
||||||
app.Cmd = "true"
|
// If command omitted it will be just /usr/bin/true.
|
||||||
|
sampleConfig.Apps[num].Cmd = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Color == "" {
|
if app.Color == "" {
|
||||||
app.Color = sampleConfig.Color
|
sampleConfig.Apps[num].Color = sampleConfig.AppButtons.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Background == "" {
|
if app.Background == "" {
|
||||||
app.Background = sampleConfig.Background
|
sampleConfig.Apps[num].Background = sampleConfig.AppButtons.Background
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.Font == "" {
|
||||||
|
sampleConfig.Apps[num].Font = sampleConfig.AppButtons.Font
|
||||||
|
}
|
||||||
|
|
||||||
|
if app.FontSize == "" {
|
||||||
|
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
|
||||||
|
} else {
|
||||||
|
matched, err := regexp.MatchString(
|
||||||
|
`^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger)$`,
|
||||||
|
app.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Printf(
|
||||||
|
"Unable to set %s.FontSize: %s, fallback to %s",
|
||||||
|
app.Name,
|
||||||
|
err,
|
||||||
|
sampleConfig.AppButtons.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
|
||||||
|
}
|
||||||
|
|
||||||
|
if !matched {
|
||||||
|
log.Printf("Unable to set %s.FontSize, fallback to %s",
|
||||||
|
app.Name,
|
||||||
|
sampleConfig.AppButtons.FontSize,
|
||||||
|
)
|
||||||
|
|
||||||
|
sampleConfig.Apps[num].FontSize = sampleConfig.AppButtons.FontSize
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.Border == "" {
|
if app.Border == "" {
|
||||||
app.Border = sampleConfig.Color
|
sampleConfig.Apps[num].Border = sampleConfig.AppButtons.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
if app.BorderActive == "" {
|
if app.BorderActive == "" {
|
||||||
app.BorderActive = sampleConfig.Color
|
sampleConfig.Apps[num].BorderActive = sampleConfig.AppButtons.Color
|
||||||
}
|
}
|
||||||
|
|
||||||
// app.Separator can be omitted, in that case it is false
|
// app.Separator can be omitted, in that case it is false
|
||||||
// app.SeparatorBlockWidth can be missing
|
// app.SeparatorBlockWidth can be missing
|
||||||
if app.FullText == "" {
|
if app.FullText == "" {
|
||||||
app.FullText = fmt.Sprintf(" %d ", num)
|
sampleConfig.Apps[num].FullText = fmt.Sprintf(" %d ", num)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ func (c *MyConfig) UpdateMemStats() {
|
|||||||
if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 || c.Values.Memory.Swap != v.SwapTotal-v.SwapFree {
|
if c.Values.Memory.Usedpct != uint64(v.UsedPercent) || c.Values.Memory.Shared != v.Shared/1024/1024 || c.Values.Memory.Swap != v.SwapTotal-v.SwapFree {
|
||||||
c.Values.Memory.Usedpct = uint64(v.UsedPercent)
|
c.Values.Memory.Usedpct = uint64(v.UsedPercent)
|
||||||
c.Values.Memory.Shared = v.Shared / 1024 / 1024
|
c.Values.Memory.Shared = v.Shared / 1024 / 1024
|
||||||
c.Values.Memory.Swap = sw.Used
|
c.Values.Memory.Swap = sw.Used / 1024 / 1024
|
||||||
c.Channels.UpdateReady <- true
|
c.Channels.UpdateReady <- true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
41
internal/lib/runcommand.go
Normal file
41
internal/lib/runcommand.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RunCommands gets list of commands runs them sequentally and conacatenates their output.
|
||||||
|
func (c *MyConfig) RunCommand() {
|
||||||
|
var (
|
||||||
|
InitialDelay = 100 * time.Millisecond
|
||||||
|
LoopIterationDelay = time.Duration(c.CmdRun.Delay) * time.Second
|
||||||
|
Delay = InitialDelay
|
||||||
|
ticker = time.NewTicker(Delay)
|
||||||
|
)
|
||||||
|
|
||||||
|
for range ticker.C {
|
||||||
|
if Delay == InitialDelay {
|
||||||
|
Delay = LoopIterationDelay
|
||||||
|
ticker.Reset(Delay)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
outputString string
|
||||||
|
command = []string{c.CmdRun.Cmd}
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(c.CmdRun.Args) > 0 {
|
||||||
|
command = append(command, c.CmdRun.Args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
outputString += RunProcess(command)
|
||||||
|
|
||||||
|
log.Println(c.Values.RunCommandOutput)
|
||||||
|
|
||||||
|
if c.Values.RunCommandOutput != outputString {
|
||||||
|
c.Values.RunCommandOutput = outputString
|
||||||
|
c.Channels.UpdateReady <- true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package lib
|
package lib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -11,6 +13,8 @@ import (
|
|||||||
// 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 c.Channels.RunChan {
|
for prg := range c.Channels.RunChan {
|
||||||
|
<-time.After(25 * time.Millisecond)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -54,3 +58,41 @@ func (c *MyConfig) CleanZombies() {
|
|||||||
time.Sleep(1 * time.Minute)
|
time.Sleep(1 * time.Minute)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RunProcess runs given command and returns contens of command stdout. On error prints error on stderr and returns
|
||||||
|
// empty syting.
|
||||||
|
func RunProcess(command []string) string {
|
||||||
|
var (
|
||||||
|
cmd *exec.Cmd
|
||||||
|
stdout, stderr bytes.Buffer
|
||||||
|
)
|
||||||
|
|
||||||
|
switch len(command) {
|
||||||
|
case 1:
|
||||||
|
cmd = exec.Command(command[0], "") //nolint: gosec
|
||||||
|
default:
|
||||||
|
cmd = exec.Command(command[0], command[1:]...) //nolint: gosec
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.Dir = "/"
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
|
||||||
|
err := cmd.Run()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if stdout.String() != "" {
|
||||||
|
log.Printf("Unable to run '%s': %s, %s", strings.Join(command, " "), err, stdout.String())
|
||||||
|
} else {
|
||||||
|
log.Printf("Unable to run '%s': %s", strings.Join(command, " "), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if stderr.String() != "" {
|
||||||
|
log.Printf("%s: %s", strings.Join(command, " "), stderr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.TrimRight(stdout.String(), "\n")
|
||||||
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ func (c *MyConfig) UpdateVPNStatus() {
|
|||||||
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), //nolint: hostport
|
||||||
time.Second*time.Duration(c.Vpn.TCPCheck.Timeout),
|
time.Second*time.Duration(c.Vpn.TCPCheck.Timeout),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user