breto

A status bar written in Go.
git clone git://git.swab.dev/breto.git
Log | Files | Refs | README | LICENSE

commit 0cd0912afd3a5d54cf4381c25c8943940a1aeb13
parent 53e59f60b97e999ac2ed0a70640af1b092553de1
Author: Jaron Swab <jaron@swab.dev>
Date:   Mon, 12 Jul 2021 21:13:35 -0400

Add cpu data and changed directory structure

Diffstat:
M.gitignore | 1+
MCHANGELOG.md | 8++++++--
MREADME.md | 7+++++++
Mblocks/volume.go | 9++++-----
Mblocks/volume_test.go | 2+-
Mblocks/wttr.go | 11++++++++++-
Mformat/format.go | 39++++++++++++++++++++++++++++-----------
Mgo.mod | 2++
Micons/icons.go | 35+++++++++++++++++++++++++----------
Micons/icons_test.go | 8--------
Mmain.go | 22+++++++++++++++++-----
Mstats/stats.go | 6++++--
Mui/ui.go | 8++++----
13 files changed, 109 insertions(+), 49 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -9,6 +9,7 @@ *.so *.dylib breto +breto.git # Test binary, built with `go test -c` *.test diff --git a/CHANGELOG.md b/CHANGELOG.md @@ -5,12 +5,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] -### Changed -- switch from github to repo for imports +## [0.13.0] - July 12, 2021 ### Added - stats package for info struct - format package for formatting text and defining flags +- CPU MHz and tempurature data blocks + +### Changed +- switch from github to custom repo for imports. +- Battery update time from every 5 minutes to every minute. ## [0.12.0] - January 12, 2020 diff --git a/README.md b/README.md @@ -3,9 +3,15 @@ A status bar written in Go. Currently tested with DWM, i3wm, tmux, and Polybar. +## Dependencies: +- pulsemixer +- lm_sensors +- bc + ## Current Features: ### Master Branch: #### Blocks: +- CPU MHz & tempurature - Date & Time - Weather via wttr.in - Total RAM not used @@ -13,6 +19,7 @@ Currently tested with DWM, i3wm, tmux, and Polybar. - Audio volume percentage (pamixer needs installed) - Total battery percentage (off by default) - Icons + #### Current UIs Tested: - DWM - i3wm diff --git a/blocks/volume.go b/blocks/volume.go @@ -6,14 +6,13 @@ import ( "strings" ) -// VolumeText sends back the current volume percent. -func VolumeText() (string, error) { - volCmd := "amixer -D pulse sget Master | awk '/Front Right:/ {print $5}' | grep -o '[0-9].'" +// Volume sends back the current volume percent. +func Volume(emoji bool) (string, error) { + volCmd := "pulsemixer --get-volume | awk '{print $1}'" runVol, err := exec.Command("sh", "-c", volCmd).Output() if err != nil { return "", err } - percent := "%" - return fmt.Sprintf("%s%s", strings.TrimSpace(string(runVol)), percent), nil + return fmt.Sprintf("%s%s", strings.TrimSpace(string(runVol)), "%"), nil } diff --git a/blocks/volume_test.go b/blocks/volume_test.go @@ -6,7 +6,7 @@ import ( ) func TestVolumeText(t *testing.T) { - vol, err := VolumeText() + vol, err := Volume(false) if err != nil { t.Error(err) } diff --git a/blocks/wttr.go b/blocks/wttr.go @@ -11,7 +11,7 @@ import ( // Wttr gets the weather of the computer's general location. // Specify city or area code: "wttr.in/~15222" or "wttr.in/~Pittsburgh" -func Wttr(cWttr chan string, eWttr chan error) { +func Wttr(cWttr chan string, eWttr chan error) { //, useOWM bool) { var passed, hour float64 var data, weather string @@ -45,3 +45,12 @@ func Wttr(cWttr chan string, eWttr chan error) { } } } + +/* +func openWeatherMap(apikey string) string { + resp, err := http.Get("") + if err != nil { + eWtter <- err + } +} +*/ diff --git a/format/format.go b/format/format.go @@ -3,6 +3,7 @@ package format import ( "flag" "fmt" + "log" "git.swab.dev/breto.git/blocks" "git.swab.dev/breto.git/icons" @@ -11,20 +12,26 @@ import ( // CLI flag variables type Options struct { - Dwm, Battery, Clock, Audio, Memory, DiskSpace, Temperature, Tray, Emoji bool + Dwm, Battery, Clock, Audio, CPU, Memory, DiskSpace, Temperature, Tray, Emoji, DynamicVol bool } func (o *Options) ParseFlags() *Options { // Setup and define cli flags - flag.BoolVar(&o.Dwm, "dwm", false, "Used to enable output for DWM's status bar.\n Example: --dwm=true") - flag.BoolVar(&o.Battery, "battery", false, "Used to enable battery module.\n Example: --battery=true") flag.BoolVar(&o.Clock, "dateTime", true, "Used to disable the date and time module.\n Example: --dateTime=false") - flag.BoolVar(&o.Audio, "volume", true, "Used to disable the volume module.\n Example: --volume=false") + flag.BoolVar(&o.Audio, "volume", true, "Used to disable the volume-text module.\n Example: --volume=false") flag.BoolVar(&o.Memory, "ram", true, "Used to disable the RAM module.\n Example: --ram=false") - flag.BoolVar(&o.DiskSpace, "storage", true, "Used to disable the home directory storage module.\n Example: --storage=false") - flag.BoolVar(&o.Temperature, "temp", true, "Used to disable the temperature module.\n Example: --temp=false") - flag.BoolVar(&o.Tray, "tray", true, "Used to disable the custom tray module.\n Example: --tray=false") + flag.BoolVar(&o.CPU, "cpu", true, "Used to disable the CPU module.\n Example: --cpu=false") + + // Flags disabled by default: + flag.BoolVar(&o.DiskSpace, "storage", false, "Used to enable the home directory storage module.\n Example: --storage=true") + flag.BoolVar(&o.Temperature, "temp", false, "Used to enable the temperature module.\n Example: --temp=true") + flag.BoolVar(&o.Tray, "tray", false, "Used to enable the custom tray module.\n Example: --tray=true") flag.BoolVar(&o.Emoji, "emoji", false, "Used to enable Openmoji icons instead of Awesome Font.\n Example: --emoji=true") + flag.BoolVar(&o.Battery, "battery", false, "Used to enable battery module.\n Example: --battery=true") + flag.BoolVar(&o.DynamicVol, "volume-icon-only", false, "Used to enable the dynamic volume icon module. (This disables the volume text.)\n Example: --volume-icon-only=false") + + // UI flags: + flag.BoolVar(&o.Dwm, "dwm", false, "Used to enable output for DWM's status bar.\n Example: --dwm=true") flag.Parse() @@ -35,6 +42,9 @@ func (o *Options) Output(status string, info *stats.Info, ico *icons.Symbols, ba if o.Temperature { status = fmt.Sprintf("%s %s%s ", status, icons.Temp(o.Emoji), info.Weather) } + if o.CPU { + status = fmt.Sprintf("%s %s%s %s ", status, icons.CPU(o.Emoji), info.CPUMHz, info.CPUTemp) + } if o.DiskSpace { status = fmt.Sprintf("%s %s%s ", status, icons.Dir(o.Emoji), info.HomeSpace) } @@ -42,12 +52,19 @@ func (o *Options) Output(status string, info *stats.Info, ico *icons.Symbols, ba status = fmt.Sprintf("%s %s%s ", status, icons.Mem(o.Emoji), info.RamFree) } if o.Audio { - info.VolText, _ = blocks.VolumeText() - ico.VolIcon, _ = icons.Volume(o.Emoji) - status = fmt.Sprintf("%s %s%s ", status, ico.VolIcon, info.VolText) + info.VolText, _ = blocks.Volume(o.Emoji) + volumeIcon := icons.VolumeSingleIcon(o.Emoji) + var err error + if o.DynamicVol { + volumeIcon, err = icons.VolumeDynamic(o.Emoji) + if err != nil { + log.Printf("dynamic volume icon encountered an error: %s\n", err) + } + } + status = fmt.Sprintf("%s %s%s ", status, volumeIcon, info.VolText) } if o.Battery { - if bat.FiveMins == 0 || bat.Passed < 10 { + if bat.Minute == 0 || bat.Passed < 10 { info.Power, _ = blocks.Battery() } status = fmt.Sprintf("%s %s%s ", status, icons.Power(o.Emoji), info.Power) diff --git a/go.mod b/go.mod @@ -1,3 +1,5 @@ module git.swab.dev/breto.git go 1.12 + +require github.com/vektra/mockery/v2 v2.9.0 // indirect diff --git a/icons/icons.go b/icons/icons.go @@ -35,7 +35,7 @@ func Dropbox(emoji bool) (string, error) { return "", err } if string(runDbCmd) != "" { - return fmt.Sprintf("%s", dbIcon), nil + return dbIcon, nil } return "", nil } @@ -53,7 +53,7 @@ func Redshift(emoji bool) (string, error) { return "", err } if string(runRsCmd) != "" { - return fmt.Sprintf("%s", rsIcon), nil + return rsIcon, nil } return "", nil } @@ -71,13 +71,13 @@ func Syncthing(emoji bool) (string, error) { return "", err } if string(runSyncCmd) != "" { - return fmt.Sprintf("%s", syncIcon), nil + return syncIcon, nil } return "", nil } // Volume sends the icon when the app is running. -func Volume(emoji bool) (string, error) { +func VolumeDynamic(emoji bool) (string, error) { // Font Awesome: volIconMute := " " volIconLow := " " @@ -91,7 +91,7 @@ func Volume(emoji bool) (string, error) { volIconHigh = encodeEmoji("00001F50A") } - volCmd := "pamixer --get-volume | tr -d '\n'" + volCmd := "pulsemixer --get-volume | awk '{print $1}'" runVolCmd, err := exec.Command("sh", "-c", volCmd).Output() if err != nil && err.Error() != "exit status 1" { return "", err @@ -104,19 +104,26 @@ func Volume(emoji bool) (string, error) { switch { case volValue == 0: - return fmt.Sprintf("%s", volIconMute), nil + return volIconMute, nil case volValue < 50: - return fmt.Sprintf("%s", volIconLow), nil + return volIconLow, nil case volValue >= 50 && volValue <= 74: - return fmt.Sprintf("%s", volIconMid), nil + return volIconMid, nil case volValue >= 75: - return fmt.Sprintf("%s", volIconHigh), nil + return volIconHigh, nil default: return "", nil } } // The following have no checks that need to be made +func VolumeSingleIcon(emoji bool) string { + if emoji { + return encodeEmoji("00001F50A") + } + // Font Awesome: + return " " +} // Dir sends the icon when the app is running. func Dir(emoji bool) string { @@ -131,7 +138,7 @@ func Mem(emoji bool) string { if emoji { return encodeEmoji("00001F4BE") } - return " " + return "︁ " } // Temp sends the icon when the app is running. @@ -149,3 +156,11 @@ func Power(emoji bool) string { } return " " } + +// CPU sends the icon when the app is running. +func CPU(emoji bool) string { + if emoji { + return encodeEmoji("00001F4BB") + } + return "︁ " +} diff --git a/icons/icons_test.go b/icons/icons_test.go @@ -24,14 +24,6 @@ func TestRedshift(t *testing.T) { fmt.Println(rs, err) } -func TestVolume(t *testing.T) { - vi, err := Volume(false) - if err != nil { - t.Error(err) - } - fmt.Println(vi) -} - func TestSyncthing(t *testing.T) { sync, err := Syncthing(false) if err != nil { diff --git a/main.go b/main.go @@ -1,12 +1,12 @@ package main import ( + "fmt" "log" "math" "os" "sync" "time" - "fmt" "git.swab.dev/breto.git/blocks" "git.swab.dev/breto.git/format" @@ -53,9 +53,22 @@ func main() { // add year & seconds with "Jan 02, 2006 15:04:05" info.HTime = time.Now().Format("Jan 02 15:04") + if o.CPU { + var err error + info.CPUMHz, err = blocks.CPUMHz() + if err != nil { + writeToLog(fmt.Sprintf("%s", err), mutex) + } + + info.CPUTemp, err = blocks.CPUTemp() + if err != nil { + writeToLog(fmt.Sprintf("%s", err), mutex) + } + } + if o.Battery { bat.Passed = time.Since(start).Seconds() - bat.FiveMins = math.Floor(math.Remainder(bat.Passed, 300)) + bat.Minute = math.Floor(math.Remainder(bat.Passed, 60)) } select { // updates the go routine channels as they send data @@ -76,10 +89,9 @@ func main() { status := o.Output("", info, ico, bat) // Output methods as specified by CLI flags. + ui.Default(status) if o.Dwm { ui.Dwm(status) - } else { - ui.Default(status) } } } @@ -100,6 +112,6 @@ func writeToLog(errMsg string, mutex *sync.Mutex) { } defer f.Close() - logger := log.New(f, "prefix", log.LstdFlags) + logger := log.New(f, "[breto] ", log.LstdFlags) logger.Println(errMsg) } diff --git a/stats/stats.go b/stats/stats.go @@ -3,6 +3,8 @@ package stats type Info struct { HTime string Weather string + CPUMHz string + CPUTemp string RamFree string HomeSpace string VolText string @@ -14,6 +16,6 @@ type Info struct { } type Battery struct { - Passed float64 - FiveMins float64 + Passed float64 + Minute float64 } diff --git a/ui/ui.go b/ui/ui.go @@ -18,14 +18,14 @@ func Dwm(status string) error { // // For tmux: // Add the following to your tmux config: -// set -g status-right "#($HOME/PATHTO/go-status)" -// where `go-status` is the compiled binary +// set -g status-right "#($HOME/PATH/TO/breto)" +// where `breto` is the compiled binary // // For i3wm: // Make sure to update the `bar {}` section in your i3wm // config file to the following: -// status_command $HOME/PATH/TO/go-status -// where `go-status` is the compiled binary +// status_command $HOME/PATH/TO/breto +// where `breto` is the compiled binary // // For Polybar: // [module/breto]