streamformatter.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package utils
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. )
  7. type StreamFormatter struct {
  8. json bool
  9. used bool
  10. }
  11. func NewStreamFormatter(json bool) *StreamFormatter {
  12. return &StreamFormatter{json, false}
  13. }
  14. const streamNewline = "\r\n"
  15. var streamNewlineBytes = []byte(streamNewline)
  16. func (sf *StreamFormatter) FormatStream(str string) []byte {
  17. sf.used = true
  18. if sf.json {
  19. b, err := json.Marshal(&JSONMessage{Stream: str})
  20. if err != nil {
  21. return sf.FormatError(err)
  22. }
  23. return append(b, streamNewlineBytes...)
  24. }
  25. return []byte(str + "\r")
  26. }
  27. func (sf *StreamFormatter) FormatStatus(id, format string, a ...interface{}) []byte {
  28. sf.used = true
  29. str := fmt.Sprintf(format, a...)
  30. if sf.json {
  31. b, err := json.Marshal(&JSONMessage{ID: id, Status: str})
  32. if err != nil {
  33. return sf.FormatError(err)
  34. }
  35. return append(b, streamNewlineBytes...)
  36. }
  37. return []byte(str + streamNewline)
  38. }
  39. func (sf *StreamFormatter) FormatError(err error) []byte {
  40. sf.used = true
  41. if sf.json {
  42. jsonError, ok := err.(*JSONError)
  43. if !ok {
  44. jsonError = &JSONError{Message: err.Error()}
  45. }
  46. if b, err := json.Marshal(&JSONMessage{Error: jsonError, ErrorMessage: err.Error()}); err == nil {
  47. return append(b, streamNewlineBytes...)
  48. }
  49. return []byte("{\"error\":\"format error\"}" + streamNewline)
  50. }
  51. return []byte("Error: " + err.Error() + streamNewline)
  52. }
  53. func (sf *StreamFormatter) FormatProgress(id, action string, progress *JSONProgress) []byte {
  54. if progress == nil {
  55. progress = &JSONProgress{}
  56. }
  57. sf.used = true
  58. if sf.json {
  59. b, err := json.Marshal(&JSONMessage{
  60. Status: action,
  61. ProgressMessage: progress.String(),
  62. Progress: progress,
  63. ID: id,
  64. })
  65. if err != nil {
  66. return nil
  67. }
  68. return b
  69. }
  70. endl := "\r"
  71. if progress.String() == "" {
  72. endl += "\n"
  73. }
  74. return []byte(action + " " + progress.String() + endl)
  75. }
  76. func (sf *StreamFormatter) Used() bool {
  77. return sf.used
  78. }
  79. func (sf *StreamFormatter) Json() bool {
  80. return sf.json
  81. }
  82. type StdoutFormater struct {
  83. io.Writer
  84. *StreamFormatter
  85. }
  86. func (sf *StdoutFormater) Write(buf []byte) (int, error) {
  87. formattedBuf := sf.StreamFormatter.FormatStream(string(buf))
  88. n, err := sf.Writer.Write(formattedBuf)
  89. if n != len(formattedBuf) {
  90. return n, io.ErrShortWrite
  91. }
  92. return len(buf), err
  93. }
  94. type StderrFormater struct {
  95. io.Writer
  96. *StreamFormatter
  97. }
  98. func (sf *StderrFormater) Write(buf []byte) (int, error) {
  99. formattedBuf := sf.StreamFormatter.FormatStream("\033[91m" + string(buf) + "\033[0m")
  100. n, err := sf.Writer.Write(formattedBuf)
  101. if n != len(formattedBuf) {
  102. return n, io.ErrShortWrite
  103. }
  104. return len(buf), err
  105. }