commit d7376d4c62b8fc5de88e5c61a569bf641c93fd1a Author: Joren Date: Fri Jun 28 23:53:01 2024 +0200 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..15e8cb9 --- /dev/null +++ b/go.mod @@ -0,0 +1,19 @@ +module ChannelBrowser + +go 1.22.4 + +require ( + github.com/gdamore/tcell v1.4.0 + github.com/rivo/tview v0.0.0-20240625185742-b0a7293b8130 +) + +require ( + github.com/gdamore/encoding v1.0.0 // indirect + github.com/gdamore/tcell/v2 v2.7.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/rivo/uniseg v0.4.7 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect +) diff --git a/main.go b/main.go new file mode 100644 index 0000000..f79d1ec --- /dev/null +++ b/main.go @@ -0,0 +1,128 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "strings" + + "github.com/gdamore/tcell/v2" + "github.com/rivo/tview" +) + +type GuildData map[string]GuildInfo +type GuildInfo map[string]CategoryInfo +type CategoryInfo struct { + Channels map[string]ChannelInfo `json:"channels"` +} + +type ChannelInfo struct { + Channelname string `json:"channelname"` + Channeltype string `json:"channeltype"` + Access bool `json:"access"` +} + +func loadJSONFiles(outputDir string) (map[string]GuildData, error) { + allData := make(map[string]GuildData) + + files, err := ioutil.ReadDir(outputDir) + if err != nil { + return nil, err + } + + for _, fileInfo := range files { + if !fileInfo.IsDir() && strings.HasSuffix(fileInfo.Name(), ".json") { + filePath := fmt.Sprintf("%s/%s", outputDir, fileInfo.Name()) + data, err := ioutil.ReadFile(filePath) + if err != nil { + return nil, err + } + + var fileGuildData GuildData + if err := json.Unmarshal(data, &fileGuildData); err != nil { + return nil, err + } + + allData[fileInfo.Name()] = fileGuildData + } + } + + return allData, nil +} + +func main() { + outputDir := "output" + allData, err := loadJSONFiles(outputDir) + if err != nil { + fmt.Println("Error loading JSON files:", err) + return + } + + app := tview.NewApplication() + treeView := tview.NewTreeView().SetRoot(createTreeRoot(allData)).SetCurrentNode(createTreeRoot(allData)) + treeView.SetBorder(true).SetTitle("Files, Guilds, Categories and Channels").SetTitleAlign(tview.AlignLeft) + + treeView.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + node := treeView.GetCurrentNode() + if node == nil { + return event + } + + switch event.Key() { + case tcell.KeyRight: + node.SetExpanded(true) + case tcell.KeyLeft: + node.SetExpanded(false) + } + return event + }) + + instructions := tview.NewTextView(). + SetText("Navigate with Up/Down arrows. Expand with Right arrow, Collapse with Left arrow."). + SetDynamicColors(true). + SetRegions(true). + SetWrap(true) + + flex := tview.NewFlex(). + SetDirection(tview.FlexRow). + AddItem(instructions, 1, 1, false). + AddItem(treeView, 0, 1, true) + + if err := app.SetRoot(flex, true).Run(); err != nil { + panic(err) + } +} + +func createTreeRoot(allData map[string]GuildData) *tview.TreeNode { + root := tview.NewTreeNode("Files") + + for fileName, guildData := range allData { + fileNode := tview.NewTreeNode(fileName).SetReference(fileName).SetColor(tview.Styles.SecondaryTextColor) + + for guildName, categories := range guildData { + guildNode := tview.NewTreeNode(guildName).SetReference(guildName).SetColor(tview.Styles.PrimaryTextColor) + for categoryName, categoryInfo := range categories { + categoryNode := tview.NewTreeNode(categoryName).SetReference(categoryName).SetColor(tview.Styles.TertiaryTextColor) + for _, channelInfo := range categoryInfo.Channels { + access := "No" + if channelInfo.Access { + access = "Yes" + } + channelNode := tview.NewTreeNode(fmt.Sprintf("%s (Type: %s, Access: %s)", channelInfo.Channelname, channelInfo.Channeltype, access)). + SetReference(channelInfo.Channelname). + SetColor(tview.Styles.ContrastSecondaryTextColor) + categoryNode.AddChild(channelNode) + } + categoryNode.SetExpanded(false) + guildNode.AddChild(categoryNode) + } + guildNode.SetExpanded(false) + fileNode.AddChild(guildNode) + } + fileNode.SetExpanded(false) + root.AddChild(fileNode) + } + + return root +} +