270 lines
6.5 KiB
Go
270 lines
6.5 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
|
|
"github.com/evil7/hostsync/core"
|
|
"github.com/evil7/hostsync/utils"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
rawOutput bool
|
|
)
|
|
|
|
// listCmd 列表命令
|
|
var listCmd = &cobra.Command{
|
|
Use: "list [blockName]",
|
|
Short: "查看 Hosts 配置",
|
|
Long: `查看 Hosts 配置,可以列出所有块或指定块的配置。
|
|
|
|
示例:
|
|
hostsync list # 列出所有块配置
|
|
hostsync list github # 列出指定块配置
|
|
hostsync list --raw # 原始格式输出,便于导出`,
|
|
Run: runList,
|
|
}
|
|
|
|
func init() {
|
|
listCmd.Flags().BoolVar(&rawOutput, "raw", false, "原始格式输出")
|
|
}
|
|
|
|
func runList(cmd *cobra.Command, args []string) {
|
|
hm := core.NewHostsManager()
|
|
if err := hm.Load(); err != nil {
|
|
utils.LogError("加载hosts文件失败: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if len(args) == 0 {
|
|
// 列出所有块
|
|
listAllBlocks(hm)
|
|
} else {
|
|
// 列出指定块
|
|
blockName := args[0]
|
|
listBlock(hm, blockName)
|
|
}
|
|
}
|
|
|
|
func listAllBlocks(hm *core.HostsManager) {
|
|
if len(hm.Blocks) == 0 {
|
|
utils.LogInfo("没有找到任何配置块")
|
|
return
|
|
}
|
|
|
|
if rawOutput {
|
|
// 获取排序后的块名称列表用于原始输出
|
|
var blockNames []string
|
|
for name := range hm.Blocks {
|
|
blockNames = append(blockNames, name)
|
|
}
|
|
sort.Strings(blockNames)
|
|
|
|
// 原始格式输出
|
|
for _, name := range blockNames {
|
|
block := hm.Blocks[name]
|
|
utils.LogResult("# %s:\n", name)
|
|
for _, entry := range block.Entries {
|
|
prefix := ""
|
|
if !entry.Enabled {
|
|
prefix = "# "
|
|
}
|
|
if entry.Comment != "" {
|
|
utils.LogResult("%s%-16s %s # %s\n", prefix, entry.IP, entry.Domain, entry.Comment)
|
|
} else {
|
|
utils.LogResult("%s%-16s %s\n", prefix, entry.IP, entry.Domain)
|
|
}
|
|
}
|
|
if block.DNS != "" {
|
|
utils.LogResult("# useDns: %s\n", block.DNS)
|
|
}
|
|
if block.DoH != "" {
|
|
utils.LogResult("# useDoh: %s\n", block.DoH)
|
|
}
|
|
if block.Server != "" {
|
|
utils.LogResult("# useSrv: %s\n", block.Server)
|
|
}
|
|
if block.CronJob != "" {
|
|
utils.LogResult("# cronJob: %s\n", block.CronJob)
|
|
}
|
|
if !block.UpdateAt.IsZero() {
|
|
utils.LogResult("# updateAt: %s\n", block.UpdateAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
utils.LogResult("# %s;\n\n", name)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 表格格式输出
|
|
headers := []string{"块名称", "状态", "条目数", "DNS配置", "最后更新"}
|
|
var rows [][]string
|
|
|
|
// 获取排序后的块名称列表
|
|
var blockNames []string
|
|
for name := range hm.Blocks {
|
|
blockNames = append(blockNames, name)
|
|
}
|
|
sort.Strings(blockNames)
|
|
|
|
for _, name := range blockNames {
|
|
block := hm.Blocks[name]
|
|
|
|
// 计算启用的条目数
|
|
enabledCount := 0
|
|
for _, entry := range block.Entries {
|
|
if entry.Enabled {
|
|
enabledCount++
|
|
}
|
|
}
|
|
|
|
// 根据块状态和条目状态确定显示状态
|
|
var status string
|
|
if len(block.Entries) == 0 {
|
|
status = "空块"
|
|
} else if enabledCount == 0 {
|
|
status = "全部禁用"
|
|
} else if enabledCount == len(block.Entries) {
|
|
status = "全部启用"
|
|
} else {
|
|
status = "部分启用"
|
|
}
|
|
|
|
entryInfo := fmt.Sprintf("%d/%d", enabledCount, len(block.Entries))
|
|
|
|
dnsConfig := ""
|
|
if block.DNS != "" {
|
|
dnsConfig = fmt.Sprintf("DNS: %s", block.DNS)
|
|
} else if block.DoH != "" {
|
|
dnsConfig = fmt.Sprintf("DoH: %s", utils.TruncateWithWidth(block.DoH, 30))
|
|
} else if block.Server != "" {
|
|
dnsConfig = fmt.Sprintf("服务器: %s", block.Server)
|
|
} else {
|
|
dnsConfig = "系统默认"
|
|
}
|
|
|
|
updateTime := "从未更新"
|
|
if !block.UpdateAt.IsZero() {
|
|
updateTime = block.UpdateAt.Format("2006-01-02 15:04")
|
|
}
|
|
|
|
rows = append(rows, []string{name, status, entryInfo, dnsConfig, updateTime})
|
|
}
|
|
|
|
utils.LogInfo("Hosts 配置块列表 (%d 个块)\n", len(hm.Blocks))
|
|
|
|
// 设置合适的列宽
|
|
columnWidths := []int{12, 12, 8, 35, 17}
|
|
utils.FormatTable(headers, rows, columnWidths)
|
|
}
|
|
|
|
func listBlock(hm *core.HostsManager, blockName string) {
|
|
block := hm.GetBlock(blockName)
|
|
if block == nil {
|
|
utils.LogError("块不存在: %s", blockName)
|
|
os.Exit(1)
|
|
}
|
|
|
|
if rawOutput {
|
|
// 原始格式输出
|
|
fmt.Printf("# %s:\n", blockName)
|
|
for _, entry := range block.Entries {
|
|
prefix := ""
|
|
if !entry.Enabled {
|
|
prefix = "# "
|
|
}
|
|
if entry.Comment != "" {
|
|
fmt.Printf("%s%-16s %s # %s\n", prefix, entry.IP, entry.Domain, entry.Comment)
|
|
} else {
|
|
fmt.Printf("%s%-16s %s\n", prefix, entry.IP, entry.Domain)
|
|
}
|
|
}
|
|
if block.DNS != "" {
|
|
fmt.Printf("# useDns: %s\n", block.DNS)
|
|
}
|
|
if block.DoH != "" {
|
|
fmt.Printf("# useDoh: %s\n", block.DoH)
|
|
}
|
|
if block.Server != "" {
|
|
fmt.Printf("# useSrv: %s\n", block.Server)
|
|
}
|
|
if block.CronJob != "" {
|
|
fmt.Printf("# cronJob: %s\n", block.CronJob)
|
|
}
|
|
if !block.UpdateAt.IsZero() {
|
|
fmt.Printf("# updateAt: %s\n", block.UpdateAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
fmt.Printf("# %s;\n", blockName)
|
|
return
|
|
}
|
|
|
|
// 计算启用的条目数
|
|
enabledCount := 0
|
|
for _, entry := range block.Entries {
|
|
if entry.Enabled {
|
|
enabledCount++
|
|
}
|
|
}
|
|
|
|
// 详细信息显示
|
|
fmt.Printf("名称: %s\n", blockName)
|
|
|
|
// 根据块状态和条目状态确定显示状态
|
|
if !block.Enabled {
|
|
fmt.Printf("状态: 禁用\n")
|
|
} else if len(block.Entries) == 0 {
|
|
fmt.Printf("状态: 空块\n")
|
|
} else if enabledCount == 0 {
|
|
fmt.Printf("状态: 全部禁用 (0/%d)\n", len(block.Entries))
|
|
} else if enabledCount == len(block.Entries) {
|
|
fmt.Printf("状态: 全部启用 (%d/%d)\n", enabledCount, len(block.Entries))
|
|
} else {
|
|
fmt.Printf("状态: 部分启用 (%d/%d)\n", enabledCount, len(block.Entries))
|
|
}
|
|
|
|
if block.DNS != "" {
|
|
fmt.Printf("DNS服务器: %s\n", block.DNS)
|
|
}
|
|
if block.DoH != "" {
|
|
fmt.Printf("DoH服务器: %s\n", block.DoH)
|
|
}
|
|
if block.Server != "" {
|
|
fmt.Printf("预设服务器: %s\n", block.Server)
|
|
}
|
|
if block.CronJob != "" {
|
|
fmt.Printf("定时任务: %s\n", block.CronJob)
|
|
}
|
|
if !block.UpdateAt.IsZero() {
|
|
fmt.Printf("最后更新: %s\n", block.UpdateAt.Format("2006-01-02 15:04:05"))
|
|
}
|
|
|
|
if len(block.Entries) == 0 {
|
|
utils.LogInfo("\n没有域名记录")
|
|
return
|
|
}
|
|
utils.LogInfo("\n域名记录 (%d 个条目):\n", len(block.Entries))
|
|
|
|
// 域名记录表格
|
|
headers := []string{"状态", "IP地址", "域名", "备注"}
|
|
var rows [][]string
|
|
|
|
for _, entry := range block.Entries {
|
|
status := "启用"
|
|
if !entry.Enabled {
|
|
status = "禁用"
|
|
}
|
|
|
|
comment := entry.Comment
|
|
if comment == "" {
|
|
comment = "-"
|
|
}
|
|
|
|
rows = append(rows, []string{status, entry.IP, entry.Domain, comment})
|
|
}
|
|
|
|
// 设置合适的列宽
|
|
columnWidths := []int{8, 16, 30, 20}
|
|
utils.FormatTable(headers, rows, columnWidths)
|
|
}
|