summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCaleb Bassi <calebjbassi@gmail.com>2018-05-21 16:02:31 -0700
committerCaleb Bassi <calebjbassi@gmail.com>2018-05-21 16:02:31 -0700
commit00e866c104d43de613ea0ba0b1882d1c931f3ca7 (patch)
tree8a7ad94e8dda881a27fc4256a249516a04234848
parentee1c57c6fe364457c2461c8f18848480779712bb (diff)
Change disk widget into a table1.3.0
-rw-r--r--Gopkg.lock2
-rw-r--r--src/utils/utils.go19
-rw-r--r--src/widgets/disk.go125
-rw-r--r--src/widgets/net.go22
-rw-r--r--src/widgets/proc.go47
-rw-r--r--src/widgets/temp.go1
-rw-r--r--vendor/github.com/cjbassi/termui/table.go58
7 files changed, 183 insertions, 91 deletions
diff --git a/Gopkg.lock b/Gopkg.lock
index 1486eef..63c504c 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -17,7 +17,7 @@
branch = "master"
name = "github.com/cjbassi/termui"
packages = ["."]
- revision = "50e37fc8a80ca08ddca62be4537c7d49261994a3"
+ revision = "87dbce7f69558bede7c7c7a51324ce4d8cfcb87b"
[[projects]]
branch = "master"
diff --git a/src/utils/utils.go b/src/utils/utils.go
index ef38162..2acdb7d 100644
--- a/src/utils/utils.go
+++ b/src/utils/utils.go
@@ -19,6 +19,25 @@ func BytesToGB(b uint64) float64 {
return float64(b) / math.Pow10(9)
}
+func ConvertBytes(b uint64) (float64, string) {
+ if b >= 1000000000 {
+ return BytesToGB(uint64(b)), "GB"
+ } else if b >= 1000000 {
+ return BytesToMB(uint64(b)), "MB"
+ } else if b >= 1000 {
+ return BytesToKB(uint64(b)), "KB"
+ } else {
+ return float64(b), "B"
+ }
+}
+
+func Max(a, b int) int {
+ if a > b {
+ return a
+ }
+ return b
+}
+
func Error(issue, diagnostics string) {
ui.Close()
fmt.Println("Error caught. Exiting program.")
diff --git a/src/widgets/disk.go b/src/widgets/disk.go
index 06f2bff..94bbaba 100644
--- a/src/widgets/disk.go
+++ b/src/widgets/disk.go
@@ -2,6 +2,8 @@ package widgets
import (
"fmt"
+ "sort"
+ "strings"
"time"
"github.com/cjbassi/gotop/src/utils"
@@ -9,19 +11,33 @@ import (
psDisk "github.com/shirou/gopsutil/disk"
)
+type Partition struct {
+ Device string
+ Mount string
+ TotalRead uint64
+ TotalWrite uint64
+ CurRead string
+ CurWrite string
+ UsedPercent int
+ Free string
+}
+
type Disk struct {
- *ui.Gauge
- fs string // which filesystem to get the disk usage of
- interval time.Duration
+ *ui.Table
+ interval time.Duration
+ Partitions map[string]*Partition
}
func NewDisk() *Disk {
self := &Disk{
- Gauge: ui.NewGauge(),
- fs: "/",
- interval: time.Second * 5,
+ Table: ui.NewTable(),
+ interval: time.Second,
+ Partitions: make(map[string]*Partition),
}
self.Label = "Disk Usage"
+ self.Header = []string{"Disk", "Mount", "Used", "Free", "R/s", "W/s"}
+ self.Gap = 2
+ self.ColResizer = self.ColResize
self.update()
@@ -36,7 +52,98 @@ func NewDisk() *Disk {
}
func (self *Disk) update() {
- usage, _ := psDisk.Usage(self.fs)
- self.Percent = int(usage.UsedPercent)
- self.Description = fmt.Sprintf(" (%dGB free)", int(utils.BytesToGB(usage.Free)))
+ Partitions, _ := psDisk.Partitions(false)
+
+ // add partition if it's new
+ for _, Part := range Partitions {
+ device := strings.Replace(Part.Device, "/dev/", "", -1)
+ if _, ok := self.Partitions[device]; !ok {
+ self.Partitions[device] = &Partition{
+ Device: device,
+ Mount: Part.Mountpoint,
+ }
+ }
+ }
+
+ // delete a partition if it no longer exists
+ todelete := []string{}
+ for key, _ := range self.Partitions {
+ exists := false
+ for _, Part := range Partitions {
+ device := strings.Replace(Part.Device, "/dev/", "", -1)
+ if key == device {
+ exists = true
+ break
+ }
+ }
+ if !exists {
+ todelete = append(todelete, key)
+ }
+ }
+ for _, val := range todelete {
+ delete(self.Partitions, val)
+ }
+
+ // updates partition info
+ for _, Part := range self.Partitions {
+ usage, _ := psDisk.Usage(Part.Mount)
+ Part.UsedPercent = int(usage.UsedPercent)
+
+ Free, Mag := utils.ConvertBytes(usage.Free)
+ Part.Free = fmt.Sprintf("%3d%s", uint64(Free), Mag)
+
+ ret, _ := psDisk.IOCounters("/dev/" + Part.Device)
+ data := ret[Part.Device]
+ curRead, curWrite := data.ReadBytes, data.WriteBytes
+ if Part.TotalRead != 0 { // if this isn't the first update
+ readRecent := curRead - Part.TotalRead
+ writeRecent := curWrite - Part.TotalWrite
+
+ readFloat, unitRead := utils.ConvertBytes(readRecent)
+ writeFloat, unitWrite := utils.ConvertBytes(writeRecent)
+ readRecent, writeRecent = uint64(readFloat), uint64(writeFloat)
+ Part.CurRead = fmt.Sprintf("%d%s", readRecent, unitRead)
+ Part.CurWrite = fmt.Sprintf("%d%s", writeRecent, unitWrite)
+ } else {
+ Part.CurRead = fmt.Sprintf("%d%s", 0, "B")
+ Part.CurWrite = fmt.Sprintf("%d%s", 0, "B")
+ }
+ Part.TotalRead, Part.TotalWrite = curRead, curWrite
+ }
+
+ // converts self.Partitions into self.Rows which is a [][]String
+ sortedPartitions := []string{}
+ for seriesName := range self.Partitions {
+ sortedPartitions = append(sortedPartitions, seriesName)
+ }
+ sort.Strings(sortedPartitions)
+
+ self.Rows = make([][]string, len(self.Partitions))
+ for i, key := range sortedPartitions {
+ Part := self.Partitions[key]
+ self.Rows[i] = make([]string, 6)
+ self.Rows[i][0] = Part.Device
+ self.Rows[i][1] = Part.Mount
+ self.Rows[i][2] = fmt.Sprintf("%d%%", Part.UsedPercent)
+ self.Rows[i][3] = Part.Free
+ self.Rows[i][4] = Part.CurRead
+ self.Rows[i][5] = Part.CurWrite
+ }
+}
+
+// ColResize overrides the default ColResize in the termui table.
+func (self *Disk) ColResize() {
+ self.ColWidths = []int{
+ 4,
+ utils.Max(5, self.X-33),
+ 4, 5, 5, 5,
+ }
+
+ self.CellXPos = []int{}
+ cur := 1
+ for _, w := range self.ColWidths {
+ self.CellXPos = append(self.CellXPos, cur)
+ cur += w
+ cur += self.Gap
+ }
}
diff --git a/src/widgets/net.go b/src/widgets/net.go
index eba1f88..14b1522 100644
--- a/src/widgets/net.go
+++ b/src/widgets/net.go
@@ -75,13 +75,11 @@ func (self *Net) update() {
self.prevRecvTotal = curRecvTotal
self.prevSentTotal = curSentTotal
- // net widget titles
+ // render widget titles
for i := 0; i < 2; i++ {
var method string // either 'Rx' or 'Tx'
var total float64
recent := self.Lines[i].Data[len(self.Lines[i].Data)-1]
- unitTotal := "B"
- unitRecent := "B"
if i == 0 {
total = float64(curRecvTotal)
@@ -91,21 +89,9 @@ func (self *Net) update() {
method = "Tx"
}
- if recent >= 1000000 {
- recent = int(utils.BytesToMB(uint64(recent)))
- unitRecent = "MB"
- } else if recent >= 1000 {
- recent = int(utils.BytesToKB(uint64(recent)))
- unitRecent = "kB"
- }
-
- if total >= 1000000000 {
- total = utils.BytesToGB(uint64(total))
- unitTotal = "GB"
- } else if total >= 1000000 {
- total = utils.BytesToMB(uint64(total))
- unitTotal = "MB"
- }
+ recentFloat, unitRecent := utils.ConvertBytes(uint64(recent))
+ recent = int(recentFloat)
+ total, unitTotal := utils.ConvertBytes(uint64(total))
self.Lines[i].Title1 = fmt.Sprintf(" Total %s: %5.1f %s", method, total, unitTotal)
self.Lines[i].Title2 = fmt.Sprintf(" %s/s: %9d %2s/s", method, recent, unitRecent)
diff --git a/src/widgets/proc.go b/src/widgets/proc.go
index 8a47709..566f01a 100644
--- a/src/widgets/proc.go
+++ b/src/widgets/proc.go
@@ -7,6 +7,7 @@ import (
"strconv"
"time"
+ "github.com/cjbassi/gotop/src/utils"
ui "github.com/cjbassi/termui"
psCPU "github.com/shirou/gopsutil/cpu"
)
@@ -27,14 +28,13 @@ type Process struct {
type Proc struct {
*ui.Table
- cpuCount float64
- interval time.Duration
- sortMethod string
- groupedProcs []Process
- ungroupedProcs []Process
- group bool
- KeyPressed chan bool
- DefaultColWidths []int
+ cpuCount float64
+ interval time.Duration
+ sortMethod string
+ groupedProcs []Process
+ ungroupedProcs []Process
+ group bool
+ KeyPressed chan bool
}
func NewProc(keyPressed chan bool) *Proc {
@@ -49,8 +49,9 @@ func NewProc(keyPressed chan bool) *Proc {
}
self.Label = "Processes"
self.ColResizer = self.ColResize
- self.DefaultColWidths = []int{5, 10, 4, 4}
- self.ColWidths = make([]int, 4)
+ self.Cursor = true
+ self.Gap = 3
+ self.PadLeft = 2
self.UniqueCol = 0
if self.group {
@@ -106,30 +107,8 @@ func (self *Proc) Sort() {
// ColResize overrides the default ColResize in the termui table.
func (self *Proc) ColResize() {
- copy(self.ColWidths, self.DefaultColWidths)
-
- self.Gap = 3
-
- self.CellXPos = []int{
- self.Gap,
- self.Gap + self.ColWidths[0] + self.Gap,
- (self.X + 2) - self.Gap - self.ColWidths[3] - self.Gap - self.ColWidths[2],
- (self.X + 2) - self.Gap - self.ColWidths[3],
- }
-
- rowWidth := self.Gap +
- self.ColWidths[0] + self.Gap +
- self.ColWidths[1] + self.Gap +
- self.ColWidths[2] + self.Gap +
- self.ColWidths[3] + self.Gap
-
- // only renders a column if it fits
- if self.X < (rowWidth - self.Gap - self.ColWidths[3]) {
- self.ColWidths[2] = 0
- self.ColWidths[3] = 0
- } else if self.X < rowWidth {
- self.CellXPos[2] = self.CellXPos[3]
- self.ColWidths[3] = 0
+ self.ColWidths = []int{
+ 5, utils.Max(self.X-26, 10), 4, 4,
}
}
diff --git a/src/widgets/temp.go b/src/widgets/temp.go
index 2759c1a..0c1406a 100644
--- a/src/widgets/temp.go
+++ b/src/widgets/temp.go
@@ -78,7 +78,6 @@ func (self *Temp) Buffer() *ui.Buffer {
s := ui.MaxString(key, (self.X - 4))
buf.SetString(1, y+1, s, self.Fg, self.Bg)
buf.SetString(self.X-2, y+1, fmt.Sprintf("%2dC", self.Data[key]), fg, self.Bg)
-
}
return buf
diff --git a/vendor/github.com/cjbassi/termui/table.go b/vendor/github.com/cjbassi/termui/table.go
index b9b7bfb..5d9879b 100644
--- a/vendor/github.com/cjbassi/termui/table.go
+++ b/vendor/github.com/cjbassi/termui/table.go
@@ -16,8 +16,10 @@ type Table struct {
CellXPos []int // column position
ColResizer func() // for widgets that inherit a Table and want to overload the ColResize method
Gap int // gap between columns
+ PadLeft int
- Cursor Color
+ Cursor bool
+ CursorColor Color
UniqueCol int // the column used to identify the selected item
SelectedItem string // used to keep the cursor on the correct item if the data changes
@@ -29,7 +31,7 @@ type Table struct {
func NewTable() *Table {
self := &Table{
Block: NewBlock(),
- Cursor: Theme.TableCursor,
+ CursorColor: Theme.TableCursor,
SelectedRow: 0,
TopRow: 0,
UniqueCol: 0,
@@ -41,20 +43,6 @@ func NewTable() *Table {
// ColResize is the default column resizer, but can be overriden.
// ColResize calculates the width of each column.
func (self *Table) ColResize() {
- // calculate gap size based on total width
- self.Gap = 3
- if self.X < 50 {
- self.Gap = 1
- } else if self.X < 75 {
- self.Gap = 2
- }
-
- cur := 0
- for _, w := range self.ColWidths {
- cur += self.Gap
- self.CellXPos = append(self.CellXPos, cur)
- cur += w
- }
}
// Buffer implements the Bufferer interface.
@@ -63,13 +51,25 @@ func (self *Table) Buffer() *Buffer {
self.ColResizer()
+ // finds exact column starting position
+ self.CellXPos = []int{}
+ cur := 1 + self.PadLeft
+ for _, w := range self.ColWidths {
+ self.CellXPos = append(self.CellXPos, cur)
+ cur += w
+ cur += self.Gap
+ }
+
// prints header
for i, h := range self.Header {
width := self.ColWidths[i]
if width == 0 {
continue
}
- h = MaxString(h, self.X-self.CellXPos[i])
+ // don't render column if it doesn't fit in widget
+ if width > (self.X-self.CellXPos[i])+1 {
+ continue
+ }
buf.SetString(self.CellXPos[i], 1, h, self.Fg|AttrBold, self.Bg)
}
@@ -89,16 +89,18 @@ func (self *Table) Buffer() *Buffer {
// prints cursor
bg := self.Bg
- if (self.SelectedItem == "" && rowNum == self.SelectedRow) || (self.SelectedItem != "" && self.SelectedItem == row[self.UniqueCol]) {
- bg = self.Cursor
- for _, width := range self.ColWidths {
- if width == 0 {
- continue
+ if self.Cursor {
+ if (self.SelectedItem == "" && rowNum == self.SelectedRow) || (self.SelectedItem != "" && self.SelectedItem == row[self.UniqueCol]) {
+ bg = self.CursorColor
+ for _, width := range self.ColWidths {
+ if width == 0 {
+ continue
+ }
+ buf.SetString(1, y, strings.Repeat(" ", self.X), self.Fg, bg)
}
- buf.SetString(1, y, strings.Repeat(" ", self.X), self.Fg, bg)
+ self.SelectedItem = row[self.UniqueCol]
+ self.SelectedRow = rowNum
}
- self.SelectedItem = row[self.UniqueCol]
- self.SelectedRow = rowNum
}
// prints each col of the row
@@ -106,9 +108,9 @@ func (self *Table) Buffer() *Buffer {
if width == 0 {
continue
}
- width = self.X - self.CellXPos[i]
- if len(self.CellXPos) > i+1 {
- width -= self.X - self.CellXPos[i+1]
+ // don't render column if width is greater than distance to end of widget
+ if width > (self.X-self.CellXPos[i])+1 {
+ continue
}
r := MaxString(row[i], width)
buf.SetString(self.CellXPos[i], y, r, self.Fg, bg)