nuclei/v2/internal/progress/progress.go

137 lines
2.8 KiB
Go
Raw Normal View History

2020-07-04 21:00:11 +00:00
package progress
import (
"fmt"
"github.com/logrusorgru/aurora"
"github.com/vbauerster/mpb/v5"
"github.com/vbauerster/mpb/v5/cwriter"
"github.com/vbauerster/mpb/v5/decor"
"io"
"os"
"regexp"
"strconv"
"strings"
"sync"
)
type Progress struct {
progress *mpb.Progress
progress_stdout *mpb.Progress
2020-07-05 21:38:58 +00:00
bar *mpb.Bar
total int64
initialTotal int64
2020-07-04 21:00:11 +00:00
captureData *captureData
termWidth int
2020-07-08 21:13:05 +00:00
mutex *sync.Mutex
2020-07-04 21:00:11 +00:00
}
func NewProgress(group *sync.WaitGroup) *Progress {
w := cwriter.New(os.Stdout)
tw, err := w.GetWidth()
if err != nil {
panic("Couldn't determine available terminal width.")
}
p := &Progress{
progress: mpb.New(
mpb.WithWaitGroup(group),
mpb.WithOutput(os.Stderr),
mpb.PopCompletedMode(),
),
progress_stdout: mpb.New(
mpb.WithWaitGroup(group),
mpb.WithOutput(os.Stdout),
//mpb.PopCompletedMode(),
),
2020-07-04 21:00:11 +00:00
termWidth: tw,
2020-07-08 21:13:05 +00:00
mutex: &sync.Mutex{},
2020-07-04 21:00:11 +00:00
}
return p
}
2020-07-05 21:38:58 +00:00
func (p *Progress) SetupProgressBar(name string, total int64) *mpb.Bar {
2020-07-05 15:22:21 +00:00
barname := "[" + aurora.Green(name).String() + "]"
2020-07-05 21:38:58 +00:00
bar := p.progress.AddBar(
2020-07-04 21:00:11 +00:00
total,
mpb.BarNoPop(),
2020-07-05 18:11:53 +00:00
mpb.BarRemoveOnComplete(),
2020-07-04 21:00:11 +00:00
mpb.PrependDecorators(
2020-07-05 15:22:21 +00:00
decor.Name(barname),
2020-07-04 21:00:11 +00:00
decor.CountersNoUnit(aurora.Blue(" %d/%d").String()),
decor.NewPercentage(aurora.Bold("%d").String(), decor.WCSyncSpace),
),
mpb.AppendDecorators(
decor.AverageSpeed(0, aurora.Yellow("%.2f req/s ").String()),
2020-07-04 21:00:11 +00:00
decor.OnComplete(
decor.AverageETA(decor.ET_STYLE_GO), aurora.Bold("done!").String(),
2020-07-04 21:00:11 +00:00
),
),
)
2020-07-05 21:38:58 +00:00
p.bar = bar
p.total = total
p.initialTotal = total
2020-07-05 21:38:58 +00:00
return bar
}
func (p *Progress) Update() {
p.bar.Increment()
2020-07-04 21:00:11 +00:00
}
func (p *Progress) Abort(remaining int64) {
p.total -= remaining
p.bar.SetTotal(p.total, false)
}
2020-07-04 21:00:11 +00:00
func (p *Progress) Wait() {
if p.initialTotal != p.total {
p.bar.SetTotal(p.total, true)
}
2020-07-04 21:00:11 +00:00
p.progress.Wait()
p.progress_stdout.Wait()
2020-07-04 21:00:11 +00:00
}
//
func (p *Progress) StartStdCapture() {
2020-07-08 21:13:05 +00:00
p.mutex.Lock()
2020-07-04 21:00:11 +00:00
p.captureData = startStdCapture()
}
func (p *Progress) StopStdCaptureAndShow() {
stopStdCapture(p.captureData)
// stdout
for _, captured := range p.captureData.DataStdOut {
var r = regexp.MustCompile("(.{" + strconv.Itoa(p.termWidth) + "})")
multiline := r.ReplaceAllString(captured, "$1\n")
arr := strings.Split(multiline, "\n")
for _, msg := range arr {
p.progress_stdout.Add(0, makeLogBar(msg)).SetTotal(0, true)
}
}
// stderr
for _, captured := range p.captureData.DataStdErr {
2020-07-04 21:00:11 +00:00
var r = regexp.MustCompile("(.{" + strconv.Itoa(p.termWidth) + "})")
multiline := r.ReplaceAllString(captured, "$1\n")
arr := strings.Split(multiline, "\n")
for _, msg := range arr {
p.progress.Add(0, makeLogBar(msg)).SetTotal(0, true)
}
}
2020-07-08 21:13:05 +00:00
p.mutex.Unlock()
2020-07-04 21:00:11 +00:00
}
func makeLogBar(msg string) mpb.BarFiller {
return mpb.BarFillerFunc(func(w io.Writer, _ int, st decor.Statistics) {
fmt.Fprintf(w, msg)
})
}