/core/table.go

https://github.com/kgretzky/evilginx2 · Go · 164 lines · 129 code · 26 blank · 9 comment · 26 complexity · 9f37d5537e514151e6aa2c1ae7d09a30 MD5 · raw file

  1. /*
  2. This source file is a modified version of what was taken from the amazing bettercap (https://github.com/bettercap/bettercap) project.
  3. Credits go to Simone Margaritelli (@evilsocket) for providing awesome piece of code!
  4. */
  5. package core
  6. import (
  7. "fmt"
  8. "regexp"
  9. "strings"
  10. "unicode/utf8"
  11. "github.com/fatih/color"
  12. )
  13. func viewLen(s string) int {
  14. var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]")
  15. for _, m := range ansi.FindAllString(s, -1) {
  16. s = strings.Replace(s, m, "", -1)
  17. }
  18. return utf8.RuneCountInString(s)
  19. }
  20. func truncString(s string, maxLen int) string {
  21. var ansi = regexp.MustCompile("\033\\[(?:[0-9]{1,3}(?:;[0-9]{1,3})*)?[m|K]")
  22. sm := s
  23. for _, m := range ansi.FindAllString(sm, -1) {
  24. sm = strings.Replace(sm, m, "", -1)
  25. }
  26. nsm := sm
  27. if utf8.RuneCountInString(sm) > maxLen {
  28. if maxLen > 3 {
  29. nsm = nsm[:maxLen-3] + "..."
  30. } else {
  31. nsm = nsm[:maxLen]
  32. }
  33. s = strings.Replace(s, sm, nsm, -1)
  34. }
  35. return s
  36. }
  37. func maxLen(strings []string) int {
  38. maxLen := 0
  39. for _, s := range strings {
  40. len := viewLen(s)
  41. if len > maxLen {
  42. maxLen = len
  43. }
  44. }
  45. return maxLen
  46. }
  47. type Alignment int
  48. const (
  49. AlignLeft = Alignment(0)
  50. AlignCenter = Alignment(1)
  51. AlignRight = Alignment(2)
  52. )
  53. const minColLen = 16
  54. func getPads(s string, maxLen int, align Alignment) (lPad int, rPad int) {
  55. len := viewLen(s)
  56. diff := maxLen - len
  57. if align == AlignLeft {
  58. lPad = 0
  59. rPad = diff - lPad + 1
  60. } else if align == AlignCenter {
  61. lPad = diff / 2
  62. rPad = diff - lPad + 1
  63. } else if align == AlignRight {
  64. lPad = diff + 1
  65. rPad = 0
  66. }
  67. return
  68. }
  69. func padded(s string, maxLen int, align Alignment) string {
  70. lPad, rPad := getPads(s, maxLen, align)
  71. return fmt.Sprintf("%s%s%s", strings.Repeat(" ", lPad), s, strings.Repeat(" ", rPad))
  72. }
  73. func AsTable(columns []string, rows [][]string) string {
  74. colMaxLens := make([]int, 0)
  75. dg := color.New(color.FgHiBlack)
  76. for i, col := range columns {
  77. clen := viewLen(col) + 4
  78. if clen < minColLen {
  79. clen = minColLen
  80. }
  81. colMaxLens = append(colMaxLens, clen)
  82. columns[i] = fmt.Sprintf(" %s ", col)
  83. }
  84. for i, row := range rows {
  85. for j, cell := range row {
  86. rows[i][j] = fmt.Sprintf(" %s ", truncString(cell, colMaxLens[j])) //cell)
  87. }
  88. }
  89. colPaddings := make([]int, 0)
  90. lineSep := ""
  91. for colIndex, colHeader := range columns {
  92. column := []string{colHeader}
  93. for _, row := range rows {
  94. column = append(column, row[colIndex])
  95. }
  96. mLen := maxLen(column)
  97. colPaddings = append(colPaddings, mLen)
  98. lineSep += fmt.Sprintf("+%s", strings.Repeat("-", mLen+1))
  99. }
  100. lineSep += "+"
  101. table := ""
  102. // header
  103. table += dg.Sprintf("%s\n", lineSep)
  104. for colIndex, colHeader := range columns {
  105. table += dg.Sprintf("|") + fmt.Sprintf("%s", padded(colHeader, colPaddings[colIndex], AlignCenter))
  106. }
  107. table += dg.Sprintf("|\n")
  108. table += dg.Sprintf("%s\n", lineSep)
  109. // rows
  110. for _, row := range rows {
  111. for colIndex, cell := range row {
  112. table += dg.Sprintf("|") + fmt.Sprintf("%s", padded(cell, colPaddings[colIndex], AlignLeft))
  113. }
  114. table += dg.Sprintf("|\n")
  115. }
  116. // footer
  117. table += dg.Sprintf(lineSep) + "\n"
  118. return table
  119. }
  120. func AsRows(keys []string, vals []string) string {
  121. clr := color.New(color.FgHiBlack)
  122. mLen := maxLen(keys)
  123. var table string
  124. for i, _ := range keys {
  125. table += clr.Sprintf(" %s : ", padded(keys[i], mLen, AlignLeft)) + fmt.Sprintf("%s\n", vals[i])
  126. }
  127. return table
  128. }
  129. func AsDescription(keys []string, vals []string) string {
  130. clr := color.New(color.FgHiBlack)
  131. var table string
  132. for i, _ := range keys {
  133. table += clr.Sprintf(" %s", keys[i]) + fmt.Sprintf("\n %s\n", vals[i])
  134. }
  135. return table
  136. }