pbar

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 17, 2020 License: MIT Imports: 18 Imported by: 0

README

pbar

a fancy progress bar in console

Documentation

Index

Constants

View Source
const (
	// Bytes means we're working with byte sizes. Numbers will print as Kb, Mb, etc
	// bar.Set(pb.Bytes, true)
	Bytes key = 1 << iota

	// Use SI bytes prefix names (kB, MB, etc) instead of IEC prefix names (KiB, MiB, etc)
	SIBytesPrefix
)

Variables

View Source
var (
	// Wheel created with pipes and slashes
	Wheel = `{{cycle . "|" "/" "-" "\\" | rndcolor}}`
	// Bouncing dots
	Bouncing = `{{cycle . "⠁" "⠂" "⠄" "⠂"| rndcolor}}`
	// Clock that spins two hours per step
	Clock = `{{cycle . "🕐" "🕑" "🕒" "🕓" "🕔" "🕕" "🕖" "🕗" "🕘" "🕙" "🕚"}}`
	// Dots that spin around a rectangle
	Dots = `{{cycle . "⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏" | rndcolor}}`

	Emoji = `{{cycle . "😀" "😂" "😁️" "😝"}}`

	Result = `{{string . "success"|green}}{{string . "fail"|red}}`
)
View Source
var (
	// Full - preset with all default available elements
	// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
	Full ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }} {{rtime . "ETA %s"}}{{string . "suffix"}}`

	// Default - preset like Full but without elapsed time
	// Example: 'Prefix 20/100 [-->______] 20% 1 p/s ETA 1m Suffix'
	Default ProgressBarTemplate = `{{string . "prefix"}}{{counters . }} {{bar . }} {{percent . }} {{speed . }}{{string . "suffix"}}`

	Building        = ProgressBarTemplate(Dots + ` {{cyan "building"}} {{bar .}} {{counters . "%.3s/%s"}} ` + Result)
	InkWalkTemplate = ProgressBarTemplate(`{{string . "doing" | cyan}}. [` + Wheel + Result + `]`)
)

Functions

func CellCount

func CellCount(s string) int

func FinishAll

func FinishAll()

Stop stops listening

func RegisterElement

func RegisterElement(name string, el Element, adaptive bool)

RegisterElement give you a chance to use custom elements

func Start

func Start()

Start starts the rendering the progress of progress bars using the DefaultProgress. It listens for updates using `bar.Set(n)` and new bars when added using `AddBar`

func StripString

func StripString(s string, w int) string

func StripStringToBuffer

func StripStringToBuffer(s string, w int, buf *bytes.Buffer)

Types

type Bar

type Bar struct {
	// contains filtered or unexported fields
}

Bar is the main object of bar

func AddBar

func AddBar(total int) *Bar

AddBar creates a new progress bar and adds it to the default progress container

func NewBar

func NewBar(total int) *Bar

New creates new Bar object

func NewBar64

func NewBar64(total int64) *Bar

New64 creates new Bar object using int64 as total

func Start64

func Start64(total int64) *Bar

Start64 starts new Bar with Default template. Using int64 as total.

func StartNew

func StartNew(total int) *Bar

StartNew starts new Bar with Default template

func (*Bar) Add

func (pb *Bar) Add(value int) *Bar

Add adding given int value to bar value

func (*Bar) Add64

func (pb *Bar) Add64(value int64) *Bar

Add adding given int64 value to bar value

func (*Bar) Current

func (pb *Bar) Current() int64

Current return current bar value

func (*Bar) Err

func (pb *Bar) Err() error

Err return possible error When all ok - will be nil May contain template.Execute errors

func (*Bar) Finish

func (pb *Bar) Finish() *Bar

FinishAll stops the bar

func (*Bar) Format

func (pb *Bar) Format(v int64) string

Format convert int64 to string according to the current settings

func (*Bar) Get

func (pb *Bar) Get(key interface{}) interface{}

Get return value by key

func (*Bar) GetBool

func (pb *Bar) GetBool(key interface{}) bool

GetBool return value by key and try to convert there to boolean If value doesn't set or not boolean - return false

func (*Bar) Inc

func (pb *Bar) Inc() *Bar

Inc atomically increments the progress

func (*Bar) IsStarted

func (pb *Bar) IsStarted() bool

IsStarted indicates progress bar state

func (*Bar) NewProxyReader

func (pb *Bar) NewProxyReader(r io.Reader) *Reader

NewProxyReader creates a wrapper for given reader, but with progress handle Takes io.Reader or io.ReadCloser Also, it automatically switches progress bar to handle units as bytes

func (*Bar) NewProxyWriter

func (pb *Bar) NewProxyWriter(r io.Writer) *Writer

NewProxyWriter creates a wrapper for given writer, but with progress handle Takes io.Writer or io.WriteCloser Also, it automatically switches progress bar to handle units as bytes

func (*Bar) ProgressElement

func (pb *Bar) ProgressElement(s *State, args ...string) string

ProgressElement implements Element interface

func (*Bar) Set

func (pb *Bar) Set(key, value interface{}) *Bar

Set sets any value by any key

func (*Bar) SetCurrent

func (pb *Bar) SetCurrent(value int64) *Bar

SetCurrent sets the current bar value

func (*Bar) SetErr

func (pb *Bar) SetErr(err error) *Bar

SetErr sets error to the Bar Error will be available over Err()

func (*Bar) SetMaxWidth

func (pb *Bar) SetMaxWidth(maxWidth int) *Bar

SetMaxWidth sets the bar maximum width When given value <= 0 would be using the terminal width (if possible) or default value.

func (*Bar) SetTemplate

func (pb *Bar) SetTemplate(tmpl ProgressBarTemplate) *Bar

SetTemplateString sets ProgressBarTempate and parse it

func (*Bar) SetTemplateString

func (pb *Bar) SetTemplateString(tmpl string) *Bar

SetTemplateString sets Bar tempate string and parse it

func (*Bar) SetTotal

func (pb *Bar) SetTotal(value int64) *Bar

SetTotal sets the total bar value

func (*Bar) SetWidth

func (pb *Bar) SetWidth(width int) *Bar

SetWidth sets the bar width When given value <= 0 would be using the terminal width (if possible) or default value.

func (*Bar) Start

func (pb *Bar) Start() *Bar

Start starts the bar

func (*Bar) StartTime

func (pb *Bar) StartTime() time.Time

StartTime return the time when bar started

func (*Bar) String

func (pb *Bar) String() string

String return currrent string representation of Bar

func (*Bar) Total

func (pb *Bar) Total() int64

Total return current total bar value

func (*Bar) Width

func (pb *Bar) Width() (width int)

Width return the bar width It's current terminal width or settled over 'SetWidth' value.

type Element

type Element interface {
	ProgressElement(state *State, args ...string) string
}

Element is an interface for bar elements

type ElementFunc

type ElementFunc func(state *State, args ...string) string

ElementFunc type implements Element interface and created for simplify elements

var ElementBar ElementFunc = func(state *State, args ...string) string {
	// init
	var p = getProgressObj(state, args...)

	total, value := state.Total(), state.Value()
	if total < 0 {
		total = -total
	}
	if value < 0 {
		value = -value
	}

	if total != 0 && value > total {
		total = value
	}

	p.buf.Reset()

	var widthLeft = state.AdaptiveElWidth()
	if widthLeft <= 0 || !state.IsAdaptiveWidth() {
		widthLeft = 30
	}

	if p.cc[0] < widthLeft {
		widthLeft -= p.write(state, 0, p.cc[0])
	} else {
		p.write(state, 0, widthLeft)
		return p.buf.String()
	}

	if p.cc[4] < widthLeft {

		widthLeft -= p.cc[4]
	} else {
		p.write(state, 4, widthLeft)
		return p.buf.String()
	}

	var curCount int

	if total > 0 {

		curCount = int(math.Ceil((float64(value) / float64(total)) * float64(widthLeft)))
	}

	if total == value && state.IsFinished() {
		widthLeft -= p.write(state, 1, curCount)
	} else if toWrite := curCount - p.cc[2]; toWrite > 0 {
		widthLeft -= p.write(state, 1, toWrite)
		widthLeft -= p.write(state, 2, p.cc[2])
	} else if curCount > 0 {
		widthLeft -= p.write(state, 2, curCount)
	}
	if widthLeft > 0 {
		widthLeft -= p.write(state, 3, widthLeft)
	}

	p.write(state, 4, p.cc[4])

	return p.buf.String()
}

ElementBar make progress bar view [-->__] Optionally can take up to 5 string arguments. Defaults is "[", "-", ">", "_", "]" In template use as follows: {{bar . }} or {{bar . "<" "oOo" "|" "~" ">"}} Color args: {{bar . (red "[") (green "-") ...

var ElementCounters ElementFunc = func(state *State, args ...string) string {
	var f string
	if state.Total() > 0 {
		f = argsHelper(args).getNotEmptyOr(0, "%s / %s")
	} else {
		f = argsHelper(args).getNotEmptyOr(1, "%[1]s")
	}
	return fmt.Sprintf(f, state.Format(state.Value()), state.Format(state.Total()))
}

ElementCounters shows current and total values. Optionally can take one or two string arguments. First string will be used as format value when Total is present (>0). Default is "%s / %s" Second string will be used when total <= 0. Default is "%[1]s" In template use as follows: {{counters .}} or {{counters . "%s/%s"}} or {{counters . "%s/%s" "%s/?"}}

var ElementCycle ElementFunc = func(state *State, args ...string) string {
	if len(args) == 0 {
		return ""
	}
	if state.finished {
		return ""
	}
	n, _ := state.Get(cycleObj).(int)
	if n >= len(args) {
		n = 0
	}
	state.Set(cycleObj, n+1)
	return args[n]
}

ElementCycle return next argument for every call In template use as follows: {{cycle . "1" "2" "3"}} Or mix width other elements: {{ bar . "" "" (cycle . "↖" "↗" "↘" "↙" )}}

var ElementElapsedTime ElementFunc = func(state *State, args ...string) string {
	etm := state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second))
	return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), etm.String())
}

ElementElapsedTime shows elapsed time Optionally cat take one argument - it's format for time string. In template use as follows: {{etime .}} or {{etime . "%s elapsed"}}

var ElementPercent ElementFunc = func(state *State, args ...string) string {
	argsh := argsHelper(args)
	if state.Total() > 0 {
		return fmt.Sprintf(
			argsh.getNotEmptyOr(0, "%.02f%%"),
			float64(state.Value())/(float64(state.Total())/float64(100)),
		)
	}
	return argsh.getOr(1, "?%")
}

ElementPercent shows current percent of progress. Optionally can take one or two string arguments. First string will be used as value for format float64, default is "%.02f%%". Second string will be used when percent can't be calculated, default is "?%" In template use as follows: {{percent .}} or {{percent . "%.03f%%"}} or {{percent . "%.03f%%" "?"}}

var ElementRemainingTime ElementFunc = func(state *State, args ...string) string {
	var rts string
	sp := getSpeedObj(state).value(state)
	if !state.IsFinished() {
		if sp > 0 {
			remain := float64(state.Total() - state.Value())
			remainDur := time.Duration(remain/sp) * time.Second
			rts = remainDur.String()
		} else {
			return argsHelper(args).getOr(2, "?")
		}
	} else {
		rts = state.Time().Truncate(time.Second).Sub(state.StartTime().Truncate(time.Second)).String()
		return fmt.Sprintf(argsHelper(args).getOr(1, "%s"), rts)
	}
	return fmt.Sprintf(argsHelper(args).getOr(0, "%s"), rts)
}

ElementRemainingTime calculates remaining time based on speed (EWMA) Optionally can take one or two string arguments. First string will be used as value for format time duration string, default is "%s". Second string will be used when bar finished and value indicates elapsed time, default is "%s" Third string will be used when value not available, default is "?" In template use as follows: {{rtime .}} or {{rtime . "%s remain"}} or {{rtime . "%s remain" "%s total" "???"}}

var ElementSpeed ElementFunc = func(state *State, args ...string) string {
	sp := getSpeedObj(state).value(state)
	if sp == 0 {
		return argsHelper(args).getNotEmptyOr(1, "? p/s")
	}
	return fmt.Sprintf(argsHelper(args).getNotEmptyOr(0, "%s p/s"), state.Format(int64(round(sp))))
}

ElementSpeed calculates current speed by EWMA Optionally can take one or two string arguments. First string will be used as value for format speed, default is "%s p/s". Second string will be used when speed not available, default is "? p/s" In template use as follows: {{speed .}} or {{speed . "%s per second"}} or {{speed . "%s ps" "..."}

var ElementString ElementFunc = func(state *State, args ...string) string {
	if len(args) == 0 {
		return ""
	}
	v := state.Get(args[0])
	if v == nil {
		return ""
	}
	return fmt.Sprint(v)
}

ElementString get value from bar by given key and print them bar.Set("myKey", "string to print") In template use as follows: {{string . "myKey"}}

func (ElementFunc) ProgressElement

func (e ElementFunc) ProgressElement(state *State, args ...string) string

ProgressElement just call self func

type Progress

type Progress struct {

	// Width is the width of the progress bars
	Width int

	// Bars is the collection of progress bars
	Bars []*Bar
	// contains filtered or unexported fields
}

Progress represents the container that renders progress bars

func NewProgress

func NewProgress() *Progress

New returns a new progress bar with defaults

func (*Progress) AddBar

func (p *Progress) AddBar(total int) *Bar

AddBar creates a new progress bar and adds to the container

func (*Progress) FinishAll

func (p *Progress) FinishAll()

Stop stops listening

func (*Progress) SetOut

func (p *Progress) SetOut(o io.Writer)

func (*Progress) SetRefreshInterval

func (p *Progress) SetRefreshInterval(interval time.Duration)

func (*Progress) Start

func (p *Progress) Start()

Start starts the rendering the progress of progress bars. It listens for updates using `bar.Set(n)` and new bars when added using `AddBar`

type ProgressBarTemplate

type ProgressBarTemplate string

ProgressBarTemplate that template string

func (ProgressBarTemplate) New

func (pbt ProgressBarTemplate) New(total int) *Bar

New creates new bar from template

func (ProgressBarTemplate) Start

func (pbt ProgressBarTemplate) Start(total int) *Bar

Start create and start new bar with given int total value

func (ProgressBarTemplate) Start64

func (pbt ProgressBarTemplate) Start64(total int64) *Bar

Start64 create and start new bar with given int64 total value

type Reader

type Reader struct {
	io.Reader
	// contains filtered or unexported fields
}

Reader it's a wrapper for given reader, but with progress handle

func (*Reader) Close

func (r *Reader) Close() (err error)

Close the wrapped reader when it implements io.Closer

func (*Reader) Read

func (r *Reader) Read(p []byte) (n int, err error)

Read reads bytes from wrapped reader and add amount of bytes to progress bar

type State

type State struct {
	*Bar
	// contains filtered or unexported fields
}

State represents the current state of bar Need for bar elements

func (*State) AdaptiveElWidth

func (s *State) AdaptiveElWidth() int

AdaptiveElWidth - adaptive elements must return string with given cell count (when AdaptiveElWidth > 0)

func (*State) Id

func (s *State) Id() uint64

Id it's the current state identifier - incremental - starts with 1 - resets after finish/start

func (*State) IsAdaptiveWidth

func (s *State) IsAdaptiveWidth() bool

IsAdaptiveWidth returns true when element must be shown as adaptive

func (*State) IsFinished

func (s *State) IsFinished() bool

IsFinished return true when bar is finished

func (*State) IsFirst

func (s *State) IsFirst() bool

IsFirst return true only in first render

func (*State) Time

func (s *State) Time() time.Time

Time when state was created

func (*State) Total

func (s *State) Total() int64

Total it's bar int64 total

func (*State) Value

func (s *State) Value() int64

Value it's current value

func (*State) Width

func (s *State) Width() int

Width of bar

type Writer

type Writer struct {
	io.Writer
	// contains filtered or unexported fields
}

Writer it's a wrapper for given writer, but with progress handle

func (*Writer) Close

func (r *Writer) Close() (err error)

Close the wrapped reader when it implements io.Closer

func (*Writer) Write

func (r *Writer) Write(p []byte) (n int, err error)

Write writes bytes to wrapped writer and add amount of bytes to progress bar

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL