dcuinfo.go 8.25 KB
Newer Older
liming6's avatar
liming6 committed
1
2
3
package tui

import (
liming6's avatar
liming6 committed
4
	"fmt"
5
	"get-container/utils"
6
	"regexp"
liming6's avatar
liming6 committed
7
8
	"strconv"
	"strings"
liming6's avatar
liming6 committed
9

liming6's avatar
liming6 committed
10
	"github.com/charmbracelet/bubbles/progress"
liming6's avatar
liming6 committed
11
	tea "github.com/charmbracelet/bubbletea"
liming6's avatar
liming6 committed
12
	"github.com/charmbracelet/lipgloss"
liming6's avatar
liming6 committed
13
14
	"github.com/lucasb-eyer/go-colorful"
	"github.com/muesli/gamut"
15
	"github.com/muesli/termenv"
liming6's avatar
liming6 committed
16
17
18
)

type ModelDCUInfo struct {
19
	pro           progress.Model // 进度条
liming6's avatar
liming6 committed
20
	proLowLeight  progress.Model // 低亮度进度条
21
22
23
	proWidth      int            // 进度条宽度
	modMsg        *ModelMsg
	width, height int
liming6's avatar
liming6 committed
24
	actionMsg     *ActionMsg
liming6's avatar
liming6 committed
25
26
}

liming6's avatar
liming6 committed
27
28
29
30
31
32
const (
	TopLine    = `╞═══════════════════════════════╪══════════════════════╪══════════════════════╪`
	MiddleLine = `├───────────────────────────────┼──────────────────────┼──────────────────────┼`
	BottomLine = `╞═══════════════════════════════╧══════════════════════╧══════════════════════╪`

	OtherWidth       = 8
liming6's avatar
liming6 committed
33
34
	StaticWidth      = 79 // 固定表格的宽度
	ProgressMinWidth = 15 // 进度条最小宽度
liming6's avatar
liming6 committed
35
36
)

37
38
39
40
var (
	ReDCUName = regexp.MustCompile(`(?i)^[A-Z0-9-_]*`)
)

41
42
func NewModelDCUInfo(w, h int) *ModelDCUInfo {
	return &ModelDCUInfo{width: w, height: h}
liming6's avatar
liming6 committed
43
44
}

liming6's avatar
liming6 committed
45
func (m *ModelDCUInfo) Init() tea.Cmd {
46
	if m.width < StaticWidth+ProgressMinWidth+OtherWidth {
liming6's avatar
liming6 committed
47
48
49
		return tea.Quit
	}
	m.proWidth = ProgressMinWidth
50
51
	if m.width > StaticWidth+ProgressMinWidth+OtherWidth {
		m.proWidth = m.width - OtherWidth - StaticWidth
liming6's avatar
liming6 committed
52
	}
liming6's avatar
liming6 committed
53
54
55
56
	m.pro = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient("#0000ffff", "#ff0000ff"), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
	c1, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#0000ffff"), 0.8))
	c2, _ := colorful.MakeColor(gamut.Darker(lipgloss.Color("#ff0000ff"), 0.8))
	m.proLowLeight = progress.New(progress.WithColorProfile(termenv.TrueColor), progress.WithGradient(c1.Hex(), c2.Hex()), progress.WithWidth(m.proWidth-5), progress.WithoutPercentage())
liming6's avatar
liming6 committed
57
58
59
	return nil
}

liming6's avatar
liming6 committed
60
61
62
func (m *ModelDCUInfo) Update(inputMsg tea.Msg) (tea.Model, tea.Cmd) {
	switch msg := inputMsg.(type) {
	case *ModelMsg:
63
64
65
66
67
		m.modMsg = msg
		return m, nil
	case tea.WindowSizeMsg:
		m.height = msg.Height
		m.width = msg.Width
liming6's avatar
liming6 committed
68
		return m, nil
liming6's avatar
liming6 committed
69
70
71
	case *ActionMsg:
		m.actionMsg = msg
		return m, nil
liming6's avatar
liming6 committed
72
	}
liming6's avatar
liming6 committed
73
74
75
76
	return m, nil
}

func (m *ModelDCUInfo) View() string {
77
78
79
	if m.modMsg == nil {
		return ""
	}
liming6's avatar
liming6 committed
80
	lineWidth := 0
81
82
83
84
	qmap, qlock := m.modMsg.DCUInfo.GetQuitInfo()
	smap, slock := m.modMsg.DCUInfo.GetSlowInfo()
	defer slock.Unlock()
	defer qlock.Unlock()
liming6's avatar
liming6 committed
85
	strBuilder := strings.Builder{}
liming6's avatar
liming6 committed
86
87
88
89
90
	strCache := strings.Builder{}
	var targetDCU int = -1
	if m.actionMsg != nil && m.actionMsg.TargetDCUIndex != nil {
		targetDCU = *m.actionMsg.TargetDCUIndex
	}
91
	infos := make([]string, 0)
liming6's avatar
liming6 committed
92
	for i := range 64 {
93
94
95
96
97
		qinfo, haveq := qmap[i]
		sinfo, haves := smap[i]
		if !(haveq || haves) {
			continue
		}
liming6's avatar
liming6 committed
98
		isLowStyle := (targetDCU != qinfo.Id && targetDCU != -1)
liming6's avatar
liming6 committed
99
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(strconv.Itoa(qinfo.Id), 4, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(ReDCUName.FindString(qinfo.Name), 8, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.PerformanceLevel, 15, lipgloss.Right))
		strCache.WriteByte(' ')

		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
		} else {
			strBuilder.WriteString(strCache.String())
		}
		strCache.Reset()
liming6's avatar
liming6 committed
116
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
117
118
119
120
121
122
123
124
125

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.BusId, 13, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr("Off", 6, lipgloss.Right))
		strCache.WriteByte(' ')
		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
liming6's avatar
liming6 committed
126
		} else {
liming6's avatar
liming6 committed
127
			strBuilder.WriteString(strCache.String())
liming6's avatar
liming6 committed
128
		}
liming6's avatar
liming6 committed
129
130
131
132
133
134
		strCache.Reset()

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr("Off", 16, lipgloss.Left))
		strBuilder.WriteString(myBorder.Left)
		strCache.WriteByte(' ')
135
		if sinfo.Ecc.Load() {
liming6's avatar
liming6 committed
136
137
138
139
140
141
142
143
			strCache.WriteString(FormatStr("On", 3, lipgloss.Right))
		} else {
			strCache.WriteString(FormatStr("Off", 3, lipgloss.Right))
		}
		strCache.WriteByte(' ')
		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
liming6's avatar
liming6 committed
144
		} else {
liming6's avatar
liming6 committed
145
			strBuilder.WriteString(strCache.String())
liming6's avatar
liming6 committed
146
		}
liming6's avatar
liming6 committed
147
		strCache.Reset()
liming6's avatar
liming6 committed
148
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
149
150
151
152
153
154
155
156
157
158

		if isLowStyle {
			strBuilder.WriteString(LowLeightStyle.Render(" DCU: "))
			strBuilder.WriteString(m.proLowLeight.ViewAs(float64(qinfo.DCUUTil / 100)))
			strBuilder.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil))))
		} else {
			strBuilder.WriteString(" DCU: ")
			strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.DCUUTil / 100)))
			strBuilder.WriteString(fmt.Sprintf(" %3d%% ", int(qinfo.DCUUTil)))
		}
liming6's avatar
liming6 committed
159
160
161
		strBuilder.WriteString(myBorder.Left)
		strBuilder.WriteByte('\n')
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177

		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(qinfo.Fan, 4, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(fmt.Sprintf("%.1fC", qinfo.Temp), 6, lipgloss.Left))
		strCache.WriteByte(' ')
		strCache.WriteString(FormatStr(fmt.Sprintf("%.1fW / %.1fW", qinfo.PwrAvg, qinfo.PwrCap), 17, lipgloss.Right))
		strCache.WriteByte(' ')

		if isLowStyle {
			str := strCache.String()
			strBuilder.WriteString(LowLeightStyle.Render(str))
		} else {
			strBuilder.WriteString(strCache.String())
		}
		strCache.Reset()
liming6's avatar
liming6 committed
178
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
179
180
181
182
183
184
185
186
187
188
189
190
191

		if isLowStyle {
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
			strCache.WriteByte(' ')
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(fmt.Sprintf("%dMiB / %dMiB", qinfo.MemUsed/uint64(utils.MiB), qinfo.MemTotal/uint64(utils.MiB)), 20, lipgloss.Right))
			strBuilder.WriteByte(' ')
		}

liming6's avatar
liming6 committed
192
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

		if isLowStyle {
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
			strCache.WriteByte(' ')
			strCache.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
			strCache.WriteByte(' ')
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(fmt.Sprintf("%.1f%%", qinfo.DCUUTil), 6, lipgloss.Left))
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(FormatStr(sinfo.PwrMode.Load().(string), 13, lipgloss.Right))
			strBuilder.WriteByte(' ')
		}

liming6's avatar
liming6 committed
210
		strBuilder.WriteString(myBorder.Left)
liming6's avatar
liming6 committed
211
212
213
214
215
216
217
218
219
220
221
222
223
224

		if isLowStyle {
			strCache.WriteString(" Mem: ")
			strCache.WriteString(m.proLowLeight.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
			strCache.WriteString(LowLeightStyle.Render(fmt.Sprintf(" %3d%% ", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal)))))
			strBuilder.WriteString(LowLeightStyle.Render(strCache.String()))
			strCache.Reset()
		} else {
			strBuilder.WriteString(" Mem: ")
			strBuilder.WriteString(m.pro.ViewAs(float64(qinfo.MemUsed) / float64(qinfo.MemTotal)))
			strBuilder.WriteByte(' ')
			strBuilder.WriteString(fmt.Sprintf("%3d%%", int(100*float64(qinfo.MemUsed)/float64(qinfo.MemTotal))))
			strBuilder.WriteByte(' ')
		}
liming6's avatar
liming6 committed
225
		strBuilder.WriteString(myBorder.Left)
226
		infos = append(infos, strBuilder.String())
liming6's avatar
liming6 committed
227
228
229
230
231
		strBuilder.Reset()
	}
	if len(infos) > 0 {
		lineWidth = lipgloss.Width(infos[0])
	}
liming6's avatar
liming6 committed
232
	subLen := lineWidth - StaticWidth - 1
liming6's avatar
liming6 committed
233
234
235
236
237
238
239
	if subLen <= 0 {
		subLen = 0
	}
	top := TopLine + strings.Repeat("═", subLen) + "╕\n"
	middle := "\n" + MiddleLine + strings.Repeat("─", subLen) + "┤\n"
	bottom := "\n" + BottomLine + strings.Repeat("═", subLen) + "╡\n"
	return top + strings.Join(infos, middle) + bottom
liming6's avatar
liming6 committed
240
}