package fetchself import ( "fmt" "log" "os/exec" "strings" "git.lxtend.com/qqbot/constants" "git.lxtend.com/qqbot/handler" "git.lxtend.com/qqbot/model" ) func init() { handler.RegisterHelpInform("!fetch", "获取系统信息", "!fetch") handler.RegisterHandler("!fetch", fetchSelf, constants.LEVEL_USER) } var fetchCmd = []string{"fastfetch", "neofetch"} type SystemInfo struct { OS string Host string Kernel string Uptime string CPU string Memory string Disk string GPU string Resolution string Packages string Shell string DE string Network string Bluetooth string BIOS string } func (i *SystemInfo) String() string { var builder strings.Builder if i.OS != "" { builder.WriteString(fmt.Sprintf("OS: %s\n", i.OS)) } if i.Host != "" { builder.WriteString(fmt.Sprintf("Host: %s\n", i.Host)) } if i.Kernel != "" { builder.WriteString(fmt.Sprintf("Kernel: %s\n", i.Kernel)) } if i.Uptime != "" { builder.WriteString(fmt.Sprintf("Uptime: %s\n", i.Uptime)) } if i.Packages != "" { builder.WriteString(fmt.Sprintf("Packages: %s\n", i.Packages)) } if i.Shell != "" { builder.WriteString(fmt.Sprintf("Shell: %s\n", i.Shell)) } if i.Resolution != "" { builder.WriteString(fmt.Sprintf("Resolution: %s\n", i.Resolution)) } if i.CPU != "" { builder.WriteString(fmt.Sprintf("CPU: %s\n", i.CPU)) } if i.GPU != "" { builder.WriteString(fmt.Sprintf("GPU: %s\n", i.GPU)) } if i.Memory != "" { builder.WriteString(fmt.Sprintf("Memory: %s\n", i.Memory)) } if i.Disk != "" { builder.WriteString(fmt.Sprintf("Disk: %s\n", i.Disk)) } if i.Network != "" { builder.WriteString(fmt.Sprintf("Network: %s\n", i.Network)) } if i.Bluetooth != "" { builder.WriteString(fmt.Sprintf("Bluetooth: %s\n", i.Bluetooth)) } if i.BIOS != "" { builder.WriteString(fmt.Sprintf("BIOS: %s\n", i.BIOS)) } if i.DE != "" { builder.WriteString(fmt.Sprintf("DE: %s\n", i.DE)) } return builder.String() } func fetchSelf(msg model.Message) (reply *model.Reply) { //检测是否存在fetchCmd中的命令 for _, cmd := range fetchCmd { if _, err := exec.LookPath(cmd); err == nil { info, err := parseSystemInfo(cmd) if err != nil { log.Println("parseSystemInfo failed", err) return } reply = &model.Reply{} reply.FromMsg = msg reply.ReplyMsg = info.String() return } } return } func parseSystemInfo(cmd string) (SystemInfo, error) { switch cmd { case "fastfetch": fetcher := &fastdfetchParser{} return fetcher.Parse(cmd) case "neofetch": fetcher := &neofetchParser{} return fetcher.Parse(cmd) } return SystemInfo{}, fmt.Errorf("unsupported command: %s", cmd) } type Parser interface { Parse(cmd string) (SystemInfo, error) } type fastdfetchParser struct{} func (p *fastdfetchParser) Parse(cmd string) (SystemInfo, error) { output, err := exec.Command(cmd).Output() if err != nil { return SystemInfo{}, err } lines := strings.Split(string(output), "\n") info := SystemInfo{} for _, line := range lines { if strings.Contains(line, "OS:") { info.OS = strings.TrimSpace(strings.Split(line, "OS:")[1]) } if strings.Contains(line, "Host:") { info.Host = strings.TrimSpace(strings.Split(line, "Host:")[1]) } if strings.Contains(line, "Kernel:") { info.Kernel = strings.TrimSpace(strings.Split(line, "Kernel:")[1]) } if strings.Contains(line, "Uptime:") { info.Uptime = strings.TrimSpace(strings.Split(line, "Uptime:")[1]) } if strings.Contains(line, "Packages:") { info.Packages = strings.TrimSpace(strings.Split(line, "Packages:")[1]) } if strings.Contains(line, "Shell:") { info.Shell = strings.TrimSpace(strings.Split(line, "Shell:")[1]) } if strings.Contains(line, "Display (LGD041C):") { info.Resolution = strings.TrimSpace(strings.Split(line, "Display (LGD041C):")[1]) } if strings.Contains(line, "CPU:") { info.CPU = strings.TrimSpace(strings.Split(line, "CPU:")[1]) } if strings.Contains(line, "GPU:") { info.GPU = strings.TrimSpace(strings.Split(line, "GPU:")[1]) } if strings.Contains(line, "Memory:") { info.Memory = strings.TrimSpace(strings.Split(line, "Memory:")[1]) } if strings.Contains(line, "Disk (/):") { info.Disk = strings.TrimSpace(strings.Split(line, "Disk (/):")[1]) } if strings.Contains(line, "Local IP") { info.Network = strings.TrimSpace(strings.Split(line, "Local IP")[1]) } } return info, nil } type neofetchParser struct{} func (p *neofetchParser) Parse(cmd string) (SystemInfo, error) { output, err := exec.Command(cmd, "--color_blocks", "off").Output() if err != nil { return SystemInfo{}, err } lines := strings.Split(string(output), "\n") info := SystemInfo{} for _, line := range lines { if strings.Contains(line, "OS:") { info.OS = strings.TrimSpace(strings.Split(line, "OS:")[1]) } if strings.Contains(line, "Host:") { info.Host = strings.TrimSpace(strings.Split(line, "Host:")[1]) } if strings.Contains(line, "Kernel:") { info.Kernel = strings.TrimSpace(strings.Split(line, "Kernel:")[1]) } if strings.Contains(line, "Uptime:") { info.Uptime = strings.TrimSpace(strings.Split(line, "Uptime:")[1]) } if strings.Contains(line, "Packages:") { info.Packages = strings.TrimSpace(strings.Split(line, "Packages:")[1]) } if strings.Contains(line, "Shell:") { info.Shell = strings.TrimSpace(strings.Split(line, "Shell:")[1]) } if strings.Contains(line, "Resolution:") { info.Resolution = strings.TrimSpace(strings.Split(line, "Resolution:")[1]) } if strings.Contains(line, "CPU:") { info.CPU = strings.TrimSpace(strings.Split(line, "CPU:")[1]) } if strings.Contains(line, "GPU:") { info.GPU = strings.TrimSpace(strings.Split(line, "GPU:")[1]) } if strings.Contains(line, "Memory:") { info.Memory = strings.TrimSpace(strings.Split(line, "Memory:")[1]) } if strings.Contains(line, "Network:") { info.Network = strings.TrimSpace(strings.Split(line, "Network:")[1]) } if strings.Contains(line, "Bluetooth:") { info.Bluetooth = strings.TrimSpace(strings.Split(line, "Bluetooth:")[1]) } if strings.Contains(line, "BIOS:") { info.BIOS = strings.TrimSpace(strings.Split(line, "BIOS:")[1]) } } return info, nil }