package main import ( "fmt" "log" "strconv" "strings" "time" "fyne.io/fyne/v2" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/widget" ) func createInstalledPkgsTab(server outputStruct) *fyne.Container { searchPkgEntry := widget.NewEntry() searchPkgEntry.SetPlaceHolder("Поиск пакетов ...") filteredPackages := server.InstalledPackages installedPackagesList := widget.NewList( func() int { return len(filteredPackages) }, func() fyne.CanvasObject { return container.NewHBox( widget.NewLabel("Пакет"), widget.NewLabel("Версия"), ) }, func(id widget.ListItemID, obj fyne.CanvasObject) { hbox := obj.(*fyne.Container) pkg := filteredPackages[id] nameLabel := hbox.Objects[0].(*widget.Label) versionLabel := hbox.Objects[1].(*widget.Label) nameLabel.SetText(pkg.Name) versionLabel.SetText(pkg.Version) versionLabel.TextStyle = fyne.TextStyle{Monospace: true} }, ) searchPkgEntry.OnChanged = func(text string) { if text == "" { filteredPackages = server.InstalledPackages } else { filtered := []installedPackage{} lowerText := strings.ToLower(text) for _, pkg := range server.InstalledPackages { if strings.Contains(strings.ToLower(pkg.Name), lowerText) || strings.Contains(strings.ToLower(pkg.Version), lowerText) { filtered = append(filtered, pkg) } } filteredPackages = filtered } installedPackagesList.Refresh() } installedPkgsTab := container.NewBorder( container.NewVBox( searchPkgEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(installedPackagesList), ) return installedPkgsTab } func createFsInfoTab(server outputStruct) *fyne.Container { searchFsInfoEntry := widget.NewEntry() searchFsInfoEntry.SetPlaceHolder("Поиск монтирований...") filteredFs := server.FsInformations fsInfoList := widget.NewList( func() int { return len(filteredFs) }, func() fyne.CanvasObject { return container.NewHBox( widget.NewLabel("Устройство"), widget.NewLabel("Путь монтирования"), widget.NewLabel("Размер"), widget.NewLabel("Свободно"), ) }, func(id widget.ListItemID, obj fyne.CanvasObject) { hbox := obj.(*fyne.Container) fs := filteredFs[id] deviceLabel := hbox.Objects[0].(*widget.Label) pathLabel := hbox.Objects[1].(*widget.Label) sizeLabel := hbox.Objects[2].(*widget.Label) freeLabel := hbox.Objects[3].(*widget.Label) deviceLabel.SetText(fs.MountPointDevice) pathLabel.SetText(fs.MountPointOsPath) sizeLabel.SetText(strconv.Itoa(int(fs.MountPointSize))) freeLabel.SetText(strconv.Itoa(int(fs.MountPointFree))) freeLabel.TextStyle.Bold = true }, ) searchFsInfoEntry.OnChanged = func(text string) { if text == "" { filteredFs = server.FsInformations } else { filtered := []fsInfo{} lowerText := strings.ToLower(text) for _, fs := range server.FsInformations { if strings.Contains(strings.ToLower(fs.MountPointDevice), lowerText) || strings.Contains(strings.ToLower(fs.MountPointOsPath), lowerText) { filtered = append(filtered, fs) } } filteredFs = filtered } fsInfoList.Refresh() } fsInfoTab := container.NewBorder( container.NewVBox( searchFsInfoEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(fsInfoList), ) return fsInfoTab } // func createCpuTab(server outputStruct) *fyne.Container { // searchCpuEntry := widget.NewEntry() // searchCpuEntry.SetPlaceHolder("ЦПУ...") // filteredCpu := server.Cpu.Model // cpuList := widget.NewList( // func() int { // return len(filteredCpu) // }, // func() fyne.CanvasObject { // return container.NewHBox( // widget.NewLabel("Модель"), // ) // }, // func(id widget.ListItemID, obj fyne.CanvasObject) { // hbox := obj.(*fyne.Container) // cpu := filteredCpu[id] // modelLabel := hbox.Objects[0].(*widget.Label) // modelLabel.SetText(cpu) // }, // ) // searchCpuEntry.OnChanged = func(text string) { // if text == "" { // filteredCpu = server.Cpu.Model // } else { // filtered := cpu{} // lowerText := strings.ToLower(text) // for _, c := range server.Cpu.Model { // if strings.Contains(strings.ToLower(c), lowerText) { // filtered.Model = append(filtered.Model, c) // } // } // filteredCpu = filtered.Model // } // cpuList.Refresh() // } // cpuTab := container.NewBorder( // container.NewVBox( // searchCpuEntry, // widget.NewSeparator(), // ), nil, nil, nil, // container.NewScroll(cpuList), // ) // return cpuTab // } func createCpuTab(server outputStruct) *fyne.Container { searchEntry := widget.NewEntry() searchEntry.SetPlaceHolder("Поиск ...") filteredEntries := server.Cpus list := widget.NewList( func() int { return len(filteredEntries) }, func() fyne.CanvasObject { return container.NewVBox( widget.NewLabel("VendorID,CpuFamily,Model,ModelName"), widget.NewLabel("Stepping,Microcode,CpuMhz,CacheSize"), widget.NewLabel("PhysicalId,CpuCores,Fpu,FpuException,Wp"), widget.NewLabel("Flags"), widget.NewLabel("Bugs"), widget.NewLabel("Bogomips,TlbSize,ClflushSize"), widget.NewLabel("CacheAlignment,AddressSize,PowerManagement"), ) }, func(id widget.ListItemID, obj fyne.CanvasObject) { box := obj.(*fyne.Container) e := filteredEntries[id] label0 := box.Objects[0].(*widget.Label) label1 := box.Objects[1].(*widget.Label) label2 := box.Objects[2].(*widget.Label) label3 := box.Objects[3].(*widget.Label) label4 := box.Objects[4].(*widget.Label) label5 := box.Objects[5].(*widget.Label) label6 := box.Objects[6].(*widget.Label) label0.SetText(fmt.Sprintf("VendorId: %s, CpuFamily: %s, Model: %s, ModelName: %s", e.VendorId, e.CpuFamily, e.Model, e.ModelName)) label1.SetText(fmt.Sprintf("Stepping: %s, Microcode: %s, CpuMhz: %s, CacheSize: %s", e.Stepping, e.Microcode, e.CpuMhz, e.CacheSize)) label2.SetText(fmt.Sprintf("PhysicalId: %s, CpuCores: %s", e.PhysicalId, e.CpuCores)) label3.SetText(fmt.Sprintf("Flags: %s", e.Flags)) label4.SetText(fmt.Sprintf("Bugs: %s", e.Bugs)) label5.SetText(fmt.Sprintf("Bogomips: %s, TlbSize: %s, ClflushSize: %s", e.Bogomips, e.TlbSize, e.ClflushSize)) label6.SetText(fmt.Sprintf("CacheAlignment: %s, AddressSize: %s, PowerManagement: %s", e.CacheAlignment, e.AddressSize, e.PowerManagement)) }, ) searchEntry.OnChanged = func(textRaw string) { if textRaw == "" { filteredEntries = server.Cpus } else { filtered := []cpu{} text := strings.ToLower(textRaw) for _, elem := range server.Cpus { if strings.Contains(strings.ToLower(elem.Flags), text) { filtered = append(filtered, elem) } } filteredEntries = filtered } list.Refresh() } tab := container.NewBorder( container.NewVBox( searchEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(list), ) return tab } func createInternetRequiredTab(server outputStruct) *fyne.Container { searchEntry := widget.NewEntry() searchEntry.SetPlaceHolder("Поиск ...") filteredEntries := server.InternetRequired list := widget.NewList( func() int { return len(filteredEntries) }, func() fyne.CanvasObject { return container.NewVBox( // widget.NewCard("Title", "Subtitle", widget.NewLabel("content")), widget.NewLabel("name"), widget.NewLabel("ip_list"), widget.NewLabel("http+https"), ) }, func(id widget.ListItemID, obj fyne.CanvasObject) { box := obj.(*fyne.Container) e := filteredEntries[id] label0 := box.Objects[0].(*widget.Label) label1 := box.Objects[1].(*widget.Label) label2 := box.Objects[2].(*widget.Label) label0.SetText(e.Name) label0.TextStyle.Bold = true label1.SetText(e.IpList) label1.Selectable = true label2.SetText(fmt.Sprintf("HTTP: %s HTTPS: %s", e.Http, e.Https)) label2.Selectable = true // card := box.Objects[0].(*widget.Card) // card.SetTitle(e.Name) // card.SetSubTitle(e.IpList) // card.SetContent(widget.NewLabel(fmt.Sprintf("HTTP: %s HTTPS: %s", e.Http, e.Https))) }, ) searchEntry.OnChanged = func(textRaw string) { if textRaw == "" { filteredEntries = server.InternetRequired } else { filtered := []internetResource{} text := strings.ToLower(textRaw) for _, elem := range server.InternetRequired { if strings.Contains(strings.ToLower(elem.Name), text) { filtered = append(filtered, elem) } } filteredEntries = filtered } list.Refresh() } tab := container.NewBorder( container.NewVBox( searchEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(list), ) return tab } func createSecSetTab(server outputStruct) *widget.Label { if strings.Contains(server.OperatingSystem.OsRelease, "Alma") { return widget.NewLabel(fmt.Sprintf("Selinux :: %s", server.SecSetAlma.Selinux)) } else if strings.Contains(server.OperatingSystem.OsRelease, "Ubuntu") { return widget.NewLabel(fmt.Sprintf("Apparmor :: %s", server.SecSetUbuntu.Apparmor)) } else { return widget.NewLabel(fmt.Sprintf("Apparmor\t%s\nAstraAdmin\t%s\nDigsig\t%s\nИнтерпретаторы\t%s\nmac\t%s\nmic\t%s\nnochmodx\t%s\nparsec\t%s\nselinux\t%s\nsudo control\t%s\nsudoers astra admin\t%s\nsudoers sudo\t%s", server.SecSetALSE.Apparmor, server.SecSetALSE.AstraAdmin, server.SecSetALSE.Digsig, server.SecSetALSE.Interpret, server.SecSetALSE.Mac, server.SecSetALSE.Mic, server.SecSetALSE.Nochmodx, server.SecSetALSE.Parsec, server.SecSetALSE.Selinux, server.SecSetALSE.Sudo, server.SecSetALSE.SudoersAstraAdmin, server.SecSetALSE.SudoersSudo)) } } // Это делал DeepSeek оно криво, но работает. Оставлю это так, потому что всё равно планирую не использовать больше fyne func createJournalTab(server outputStruct) *fyne.Container { searchJrlEntry := widget.NewEntry() searchJrlEntry.SetPlaceHolder("Поиск событий ...") filteredEvents := server.JournalctlEntries // Создаем список journalctlEntriesList := widget.NewList( func() int { return len(filteredEvents) }, func() fyne.CanvasObject { // Возвращаем кастомный виджет return NewJournalListItem(journalctlEntry{}) }, func(id widget.ListItemID, obj fyne.CanvasObject) { // Обновляем виджет widget := obj.(*JournalListItem) widget.Update(filteredEvents[id]) }, ) searchJrlEntry.OnChanged = func(text string) { if text == "" { filteredEvents = server.JournalctlEntries } else { filtered := []journalctlEntry{} lowerText := strings.ToLower(text) for _, ev := range server.JournalctlEntries { if strings.Contains(strings.ToLower(ev.CommandLine), lowerText) || strings.Contains(strings.ToLower(ev.CommandName), lowerText) || strings.Contains(strings.ToLower(ev.SyslogIdentifier), lowerText) || strings.Contains(strings.ToLower(ev.Message), lowerText) { filtered = append(filtered, ev) } } filteredEvents = filtered } journalctlEntriesList.Refresh() } journalctlEntriesTab := container.NewBorder( container.NewVBox( searchJrlEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(journalctlEntriesList), ) return journalctlEntriesTab } // func createJournalTab(server outputStruct) *fyne.Container { // searchJrlEntry := widget.NewEntry() // searchJrlEntry.SetPlaceHolder("Поиск событий ...") // filteredEvents := server.JournalctlEntries // journalctlEntriesList := widget.NewList( // func() int { // return len(filteredEvents) // }, // func() fyne.CanvasObject { // label := widget.NewLabel("entry") // label.Wrapping = fyne.TextWrapBreak // // label.Resize(fyne.Size{Height: 50}) // return container.NewVBox( // label, // // widget.NewSeparator(), // ) // }, // func(id widget.ListItemID, obj fyne.CanvasObject) { // vbox := obj.(*fyne.Container) // event := filteredEvents[id] // eventEntry := vbox.Objects[0].(*widget.Label) // eventEntry.SetText(fmt.Sprintf("%s :: %s :: %s :: %s :: %s", event.Timestamp, event.CommandLine, event.CommandName, event.SyslogIdentifier, event.Message)) // eventEntry.Selectable = true // eventEntry.Wrapping = fyne.TextWrapBreak // var doubleHeight fyne.Size // doubleHeight.Height = 72.0 // if eventEntry.Size().Height >= 36.0 { // eventEntry.Resize(doubleHeight) // } // // eventEntry.Truncation = fyne.TextTruncateClip // }, // ) // searchJrlEntry.OnChanged = func(text string) { // if text == "" { // filteredEvents = server.JournalctlEntries // } else { // filtered := []journalctlEntry{} // lowerText := strings.ToLower(text) // for _, ev := range server.JournalctlEntries { // if strings.Contains(strings.ToLower(ev.CommandLine), lowerText) || strings.Contains(strings.ToLower(ev.CommandName), lowerText) || strings.Contains(strings.ToLower(ev.SyslogIdentifier), lowerText) || strings.Contains(strings.ToLower(ev.Message), lowerText) { // filtered = append(filtered, ev) // } // } // filteredEvents = filtered // } // journalctlEntriesList.Refresh() // } // journalctlEntriesTab := container.NewBorder( // container.NewVBox( // searchJrlEntry, // widget.NewSeparator(), // ), nil, nil, nil, // container.NewScroll(journalctlEntriesList), // ) // return journalctlEntriesTab // } func createRootHistoryTab(server outputStruct) *fyne.Container { searchEntry := widget.NewEntry() searchEntry.SetPlaceHolder("Поиск ...") filteredEntries := server.RootHistory list := widget.NewList( func() int { return len(filteredEntries) }, func() fyne.CanvasObject { return container.NewVBox( widget.NewLabel("template"), ) }, func(id widget.ListItemID, obj fyne.CanvasObject) { box := obj.(*fyne.Container) e := filteredEntries[id] fileName := box.Objects[0].(*widget.Label) timeExec := "" if len(e.ExecutionTime) != 0 { timeInt64, err := strconv.ParseInt(e.ExecutionTime, 10, 64) if err != nil { log.Println(err) timeExec = e.ExecutionTime } else { timeExec = time.Unix(timeInt64, 0).String() } } fileName.SetText(fmt.Sprintf("%d %s %s", e.Id, timeExec, e.Command)) fileName.Selectable = true }, ) searchEntry.OnChanged = func(text string) { if text == "" { filteredEntries = server.RootHistory } else { var filtered []rootHistoryCommand lText := strings.ToLower(text) for _, elem := range server.RootHistory { if strings.Contains(strings.ToLower(elem.Command), lText) { filtered = append(filtered, elem) } } filteredEntries = filtered } list.Refresh() } tab := container.NewBorder( container.NewVBox( searchEntry, widget.NewSeparator(), ), nil, nil, nil, container.NewScroll(list), ) return tab }