-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwnlPrinter.go
128 lines (120 loc) · 4.48 KB
/
wnlPrinter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package main
import (
"net/url"
"os"
"strings"
)
type WnlPrinter struct {
wnl *WebNodeList
outputFormat OutputFormat
outputWriter *PbwStdout
colorOption ColorOption
colorCodes map[string]string
treeLines []bool
lastDepth int
printIndex int
}
func CreateWnlPrinter(wnl *WebNodeList, pbwo *PbwStdout, of OutputFormat, colorOption ColorOption) (wp WnlPrinter) {
wp.wnl = wnl
wp.outputFormat = of
wp.colorOption = colorOption
wp.outputWriter = pbwo
cc, ccExists := os.LookupEnv("LS_COLORS")
if !ccExists {
// I know this is kinda bad and it would be better for this to be a compile time constant map, but this only takes up one line and is less work. If you've got the time and inclination to do it "properly" without taking up a hundred lines, please open a PR.
cc = "rs=0:su=37;41:di=01;34:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36"
}
ccl := strings.Split(cc, ":")
wp.colorCodes = make(map[string]string, len(ccl))
for i := range ccl {
splitcc := strings.Split(ccl[i], "=")
if len(splitcc) != 2 {
continue
}
wp.colorCodes[splitcc[0]] = splitcc[1]
}
return
}
func (wp *WnlPrinter) treePrintNode(index int) {
if index < 0 || index >= len(wp.wnl.list) {
return
// TODO: Proper error return
}
node := wp.wnl.list[index]
if node.nodeDepth >= len(wp.treeLines) {
wp.treeLines = append(wp.treeLines, false)
}
for i := 0; i < node.nodeDepth-1; i++ {
if i < len(wp.treeLines) && wp.treeLines[i] {
wp.outputWriter.Write([]byte("│ "))
} else {
wp.outputWriter.Write([]byte(" "))
}
}
if node.nodeDepth > 0 {
if node.nodeLastSibling {
wp.outputWriter.Write([]byte("└── "))
wp.treeLines[node.nodeDepth-1] = false
} else {
wp.outputWriter.Write([]byte("├── "))
wp.treeLines[node.nodeDepth-1] = true
}
}
if wp.colorOption == on {
wp.setSgr(wp.getSgrCode(&wp.wnl.list[wp.printIndex]))
}
wp.outputWriter.Write([]byte(node.name))
}
func (wp *WnlPrinter) setSgr(sgrCode string) {
wp.outputWriter.Write([]byte("\u001b[" + sgrCode + "m"))
}
func (wp *WnlPrinter) resetSgr() {
wp.setSgr(wp.colorCodes["rs"])
}
func (wp *WnlPrinter) getSgrCode(node *WebNode) (sgrCode string) {
if node.nodeFail {
return wp.colorCodes["su"]
}
if node.nodeType == directory {
return wp.colorCodes["di"]
} else {
split := strings.Split(node.path, ".")
ext := split[len(split)-1]
sgr, valid := wp.colorCodes["*."+ext]
if !valid {
sgr = wp.colorCodes["rs"]
}
return sgr
}
}
func (wp *WnlPrinter) PrintDone() {
l := wp.wnl
l.mux.Lock()
defer l.mux.Unlock()
defer wp.outputWriter.Flush()
for ; wp.printIndex < len(l.list); wp.printIndex++ {
if l.list[wp.printIndex].nodeStatus == done {
switch wp.outputFormat {
case tree:
wp.treePrintNode(wp.printIndex)
case urlencoded:
if wp.colorOption == on {
wp.setSgr(wp.getSgrCode(&l.list[wp.printIndex]))
}
wp.outputWriter.Write([]byte(wp.wnl.list[wp.printIndex].path))
case list:
if wp.colorOption == on {
wp.setSgr(wp.getSgrCode(&l.list[wp.printIndex]))
}
path, _ := url.PathUnescape(wp.wnl.list[wp.printIndex].path)
wp.outputWriter.Write([]byte(path))
}
if wp.colorOption == on {
wp.resetSgr()
}
wp.outputWriter.Write([]byte{'\n'})
} else {
return
}
}
}