init
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
tea "charm.land/bubbletea/v2"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
Name string
|
||||
Desc string
|
||||
Active string
|
||||
}
|
||||
|
||||
type ServicesLoadedMsg struct {
|
||||
services []Service
|
||||
err error
|
||||
}
|
||||
|
||||
func LoadServices() tea.Msg {
|
||||
cmd := exec.Command("systemctl", "list-units", "--type=service", "--all", "--no-pager", "--plain")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return ServicesLoadedMsg{err: err}
|
||||
}
|
||||
|
||||
services := parseServices(out)
|
||||
return ServicesLoadedMsg{services: services}
|
||||
}
|
||||
|
||||
func parseServices(out []byte) []Service {
|
||||
lines := strings.Split(string(out), "\n")
|
||||
var services []Service
|
||||
|
||||
for i, line := range lines {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
line = strings.TrimSpace(line)
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(line, "Legend:") {
|
||||
return services
|
||||
}
|
||||
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) < 5 {
|
||||
continue
|
||||
}
|
||||
|
||||
services = append(services, Service{
|
||||
Name: fields[0],
|
||||
Active: fields[2],
|
||||
Desc: strings.Join(fields[4:], " "),
|
||||
})
|
||||
}
|
||||
|
||||
return services
|
||||
}
|
||||
|
||||
func (m *model) filterServices() {
|
||||
q := strings.ToLower(strings.TrimSpace(m.query.Value()))
|
||||
|
||||
if q == "" {
|
||||
m.filtered = slicesClone(m.services)
|
||||
} else {
|
||||
var filtered []Service
|
||||
for _, s := range m.services {
|
||||
if matchesService(s, q) {
|
||||
filtered = append(filtered, s)
|
||||
}
|
||||
}
|
||||
m.filtered = filtered
|
||||
}
|
||||
|
||||
if len(m.filtered) == 0 {
|
||||
m.cursor = 0
|
||||
m.offset = 0
|
||||
return
|
||||
}
|
||||
if m.cursor >= len(m.filtered) {
|
||||
m.cursor = len(m.filtered) - 1
|
||||
m.offset = max(0, m.cursor-m.amount)
|
||||
}
|
||||
}
|
||||
|
||||
func matchesService(s Service, q string) bool {
|
||||
return strings.Contains(strings.ToLower(s.Name), q) ||
|
||||
strings.Contains(strings.ToLower(s.Active), q) ||
|
||||
strings.Contains(strings.ToLower(s.Desc), q)
|
||||
}
|
||||
|
||||
func slicesClone(in []Service) []Service {
|
||||
out := make([]Service, len(in))
|
||||
copy(out, in)
|
||||
return out
|
||||
}
|
||||
|
||||
func (m *model) StopService() {
|
||||
s := m.filtered[m.cursor]
|
||||
|
||||
if s.Active != "active" {
|
||||
return
|
||||
}
|
||||
|
||||
cmd := exec.Command("systemctl", "stop", s.Name)
|
||||
cmd.Run()
|
||||
}
|
||||
|
||||
func (m *model) StartService() {
|
||||
s := m.filtered[m.cursor]
|
||||
|
||||
if s.Active != "active" {
|
||||
cmd := exec.Command("systemctl", "start", s.Name)
|
||||
cmd.Run()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user