diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | internal/i3status/battery.go | 75 | ||||
| -rw-r--r-- | internal/i3status/main.go | 169 | ||||
| -rw-r--r-- | internal/i3status/net.go | 61 | ||||
| -rw-r--r-- | main.go | 3 |
6 files changed, 1 insertions, 313 deletions
@@ -1,7 +1,7 @@ PKG = github.com/majewsky/gofu PREFIX = /usr -APPLETS = i3status rtree prettyprompt +APPLETS = rtree prettyprompt all: build/gofu $(addprefix build/,$(APPLETS)) @@ -19,10 +19,6 @@ $ make && make install # List of applets -## `i3status` - -My own variant of [`i3status`](https://i3wm.org/i3status/). - ## `prettyprompt` This renders my shell prompt. Among other things, it identifies the current diff --git a/internal/i3status/battery.go b/internal/i3status/battery.go deleted file mode 100644 index e41f189..0000000 --- a/internal/i3status/battery.go +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* -* -* Copyright 2017 Stefan Majewsky <majewsky@gmx.net> -* -* This program is free software: you can redistribute it and/or modify it under -* the terms of the GNU General Public License as published by the Free Software -* Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -* A PARTICULAR PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see <http://www.gnu.org/licenses/>. -* -*******************************************************************************/ - -package i3status - -import ( - "fmt" - "io/ioutil" - "strconv" - "strings" -) - -const ( - batteryFullPath = "/sys/class/power_supply/BAT0/energy_full" - batteryNowPath = "/sys/class/power_supply/BAT0/energy_now" - powerOnlinePath = "/sys/class/power_supply/AC0/online" -) - -func getBatteryStatus() []Block { - //TODO: What's with /sys/class/power_supply/BAT0/uevent? Can this be used to - //remove all the polling overhead here? - - energyFull, err := readNumberFromFile(batteryFullPath) - if err != nil { - return nil - } - energyNow, err := readNumberFromFile(batteryNowPath) - if err != nil { - return nil - } - powerOnline, err := readNumberFromFile(powerOnlinePath) - if err != nil { - return nil - } - - energyPerc := energyNow * 100 / energyFull - charging := powerOnline > 0 - color := "#AAAA00" - if charging { - color = "#00AA00" - } else if energyPerc < 10 { - color = "#AA0000" - } - - return section("bat", Block{ - Name: "battery", - Position: PositionBattery, - FullText: fmt.Sprintf("%d%%", energyPerc), - Urgent: energyPerc < 10 && !charging, - Color: color, - }) -} - -func readNumberFromFile(path string) (int64, error) { - buf, err := ioutil.ReadFile(path) - if err != nil { - return 0, err - } - return strconv.ParseInt(strings.TrimSpace(string(buf)), 0, 64) -} diff --git a/internal/i3status/main.go b/internal/i3status/main.go deleted file mode 100644 index 4af726a..0000000 --- a/internal/i3status/main.go +++ /dev/null @@ -1,169 +0,0 @@ -/******************************************************************************* -* -* Copyright 2017 Stefan Majewsky <majewsky@gmx.net> -* -* This program is free software: you can redistribute it and/or modify it under -* the terms of the GNU General Public License as published by the Free Software -* Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -* A PARTICULAR PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see <http://www.gnu.org/licenses/>. -* -*******************************************************************************/ - -package i3status - -import ( - "encoding/json" - "fmt" - "os" - "sort" - "time" -) - -//Exec executes the i3status applet and returns an exit code (0 for -//success, >0 for error). -func Exec(args []string) int { - //start protocol (we handle errors here for once because if stdout is - //working, we have nothing left to do) - _, err := os.Stdout.Write([]byte("{\"version\":1}\n[\n")) - if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) - return 1 - } - - //main loop - currentBlocks := make(map[string][]Block) - for { - //prepare clock (this is inline instead of split into a separate function - //because the wallclock also drives the main loop's clock, see below) - now := time.Now() - currentBlocks["clock"] = []Block{ - { - Name: "clock", - Instance: "date", - Position: PositionClock, - FullText: now.Format("2006-01-02"), - ShortText: " ", - Color: "#AAAAAA", - SeparatorBlockWidth: 6, - }, - { - Name: "clock", - Instance: "time", - Position: PositionClock, - FullText: now.Format("15:04:05"), - }, - } - - //prepare other blocks - currentBlocks["battery"] = getBatteryStatus() - currentBlocks["network"] = getNetworkStatus() - - //put blocks in rendering order - var allBlocks []Block - for _, blocks := range currentBlocks { - allBlocks = append(allBlocks, blocks...) - } - sort.Sort(byPositionAndInstance(allBlocks)) - - //write output - buf, err := json.Marshal(allBlocks) - if err == nil { - os.Stdout.Write(append(buf, ',', '\n')) - } else { - //this should not happen, but if it does, fall back to just encoding the - //error string (which always works, otherwise wtf) - buf, _ = json.Marshal(err.Error()) - fmt.Printf( - `[{"name":"error","urgent":true,"color":"#FF0000","full_text":%s}],`, - string(buf), - ) - } - - //sleep until the next second starts, so that the clock is always on time - nsec := 1000000000 - now.Nanosecond() - time.Sleep(time.Duration(nsec) * time.Nanosecond) - } - - return 0 -} - -//Block is a block of text as used in the i3status protocol. -//(Not all attributes are represented.) -type Block struct { - Position Position `json:"-"` - Name string `json:"name"` //REQUIRED - Instance string `json:"instance,omitempty"` - FullText string `json:"full_text"` //REQUIRED - ShortText string `json:"short_text"` - Color string `json:"color,omitempty"` //CSS hex syntax, e.g. #123456 - BackgroundColor string `json:"background,omitempty"` - MinWidth uint `json:"min_width,omitempty"` - Alignment Alignment `json:"align,omitempty"` //only plausible with MinWidth - Urgent bool `json:"urgent,omitempty"` - Separator bool `json:"separator"` - SeparatorBlockWidth int `json:"separator_block_width,omitempty"` -} - -type byPositionAndInstance []Block - -func (b byPositionAndInstance) Len() int { return len(b) } -func (b byPositionAndInstance) Swap(i, j int) { b[i], b[j] = b[j], b[i] } -func (b byPositionAndInstance) Less(i, j int) bool { - if b[i].Position == b[j].Position { - if b[i].Instance == "_caption" { - return true - } - if b[j].Instance == "_caption" { - return false - } - return b[i].Instance < b[j].Instance - } - return b[i].Position < b[j].Position -} - -//Alignment is the alignment of a Block. -type Alignment string - -//Acceptable values for Alignment. -const ( - AlignmentLeft Alignment = "left" - AlignmentCenter Alignment = "center" - AlignmentRight Alignment = "right" -) - -//Position defines how blocks are ordered. -type Position int - -//Acceptable values for Position, from left to right. -const ( - PositionNone Position = iota - PositionNetwork - PositionBattery - PositionClock -) - -//Order the given blocks byPositionAndInstance, then add a separator to the last one, then add a caption block of the same style in front. -func section(caption string, blocks ...Block) []Block { - if len(blocks) == 0 { - return nil - } - sort.Sort(byPositionAndInstance(blocks)) - last := len(blocks) - 1 - blocks[last].Separator = true - blocks[last].SeparatorBlockWidth = 15 - - return append([]Block{{ - Name: blocks[0].Name, - Position: blocks[0].Position, - Instance: "_caption", - FullText: caption, - Color: blocks[0].Color, - }}, blocks...) -} diff --git a/internal/i3status/net.go b/internal/i3status/net.go deleted file mode 100644 index 7367b28..0000000 --- a/internal/i3status/net.go +++ /dev/null @@ -1,61 +0,0 @@ -/******************************************************************************* -* -* Copyright 2017 Stefan Majewsky <majewsky@gmx.net> -* -* This program is free software: you can redistribute it and/or modify it under -* the terms of the GNU General Public License as published by the Free Software -* Foundation, either version 3 of the License, or (at your option) any later -* version. -* -* This program is distributed in the hope that it will be useful, but WITHOUT ANY -* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -* A PARTICULAR PURPOSE. See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License along with -* this program. If not, see <http://www.gnu.org/licenses/>. -* -*******************************************************************************/ - -package i3status - -import ( - "net" - "regexp" - "strings" -) - -var networkPortRx = regexp.MustCompile(`:\d+$`) -var networkMaskRx = regexp.MustCompile(`/\d+$`) - -func getNetworkStatus() []Block { - addrs, err := net.InterfaceAddrs() - if err != nil { - return nil - } - addrStrs := make([]string, 0, len(addrs)) - for _, addr := range addrs { - str := addr.String() - //remove uninteresting parts - str = networkPortRx.ReplaceAllString(str, "") - str = networkMaskRx.ReplaceAllString(str, "") - //ignore IPv6 for now - if strings.ContainsRune(str, ':') { - continue - } - //ignore uninteresting addrs - if strings.HasPrefix(str, "127.") { - continue - } - addrStrs = append(addrStrs, str) - } - - if len(addrStrs) == 0 { - return nil - } - return section("ip", Block{ - Name: "network", - Position: PositionNetwork, - FullText: strings.Join(addrStrs, " "), - Color: "#00AAAA", - }) -} @@ -23,7 +23,6 @@ import ( "os" "path/filepath" - "github.com/majewsky/gofu/internal/i3status" "github.com/majewsky/gofu/internal/prompt" "github.com/majewsky/gofu/internal/rtree" ) @@ -47,8 +46,6 @@ func execApplet(applet string, args []string, allowGofu bool) int { return prompt.Exec(args) case "rtree": return rtree.Exec(args) - case "i3status": - return i3status.Exec(args) default: fmt.Fprintln(os.Stderr, "ERROR: unknown applet: "+applet) return 255 |
