1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-06 03:50:04 +02:00
Daniel Neto 2024-03-05 19:22:51 -03:00
parent 7673eda07e
commit 330cdbe615
9054 changed files with 480487 additions and 41800 deletions

View file

@ -36,31 +36,33 @@ final class ProgressBar
private const FORMAT_DEBUG_NOMAX = 'debug_nomax';
private const FORMAT_NORMAL_NOMAX = 'normal_nomax';
private $barWidth = 28;
private $barChar;
private $emptyBarChar = '-';
private $progressChar = '>';
private $format;
private $internalFormat;
private $redrawFreq = 1;
private $writeCount;
private $lastWriteTime;
private $minSecondsBetweenRedraws = 0;
private $maxSecondsBetweenRedraws = 1;
private $output;
private $step = 0;
private $max;
private $startTime;
private $stepWidth;
private $percent = 0.0;
private $messages = [];
private $overwrite = true;
private $terminal;
private $previousMessage;
private $cursor;
private int $barWidth = 28;
private string $barChar;
private string $emptyBarChar = '-';
private string $progressChar = '>';
private ?string $format = null;
private ?string $internalFormat = null;
private ?int $redrawFreq = 1;
private int $writeCount = 0;
private float $lastWriteTime = 0;
private float $minSecondsBetweenRedraws = 0;
private float $maxSecondsBetweenRedraws = 1;
private OutputInterface $output;
private int $step = 0;
private int $startingStep = 0;
private ?int $max = null;
private int $startTime;
private int $stepWidth;
private float $percent = 0.0;
private array $messages = [];
private bool $overwrite = true;
private Terminal $terminal;
private ?string $previousMessage = null;
private Cursor $cursor;
private array $placeholders = [];
private static $formatters;
private static $formats;
private static array $formatters;
private static array $formats;
/**
* @param int $max Maximum steps (0 if unknown)
@ -93,18 +95,16 @@ final class ProgressBar
}
/**
* Sets a placeholder formatter for a given name.
* Sets a placeholder formatter for a given name, globally for all instances of ProgressBar.
*
* This method also allow you to override an existing placeholder.
*
* @param string $name The placeholder name (including the delimiter char like %)
* @param callable $callable A PHP callable
* @param string $name The placeholder name (including the delimiter char like %)
* @param callable(ProgressBar):string $callable A PHP callable
*/
public static function setPlaceholderFormatterDefinition(string $name, callable $callable): void
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}
self::$formatters ??= self::initPlaceholderFormatters();
self::$formatters[$name] = $callable;
}
@ -116,13 +116,31 @@ final class ProgressBar
*/
public static function getPlaceholderFormatterDefinition(string $name): ?callable
{
if (!self::$formatters) {
self::$formatters = self::initPlaceholderFormatters();
}
self::$formatters ??= self::initPlaceholderFormatters();
return self::$formatters[$name] ?? null;
}
/**
* Sets a placeholder formatter for a given name, for this instance only.
*
* @param callable(ProgressBar):string $callable A PHP callable
*/
public function setPlaceholderFormatter(string $name, callable $callable): void
{
$this->placeholders[$name] = $callable;
}
/**
* Gets the placeholder formatter for a given name.
*
* @param string $name The placeholder name (including the delimiter char like %)
*/
public function getPlaceholderFormatter(string $name): ?callable
{
return $this->placeholders[$name] ?? $this::getPlaceholderFormatterDefinition($name);
}
/**
* Sets a format for a given name.
*
@ -133,9 +151,7 @@ final class ProgressBar
*/
public static function setFormatDefinition(string $name, string $format): void
{
if (!self::$formats) {
self::$formats = self::initFormats();
}
self::$formats ??= self::initFormats();
self::$formats[$name] = $format;
}
@ -147,9 +163,7 @@ final class ProgressBar
*/
public static function getFormatDefinition(string $name): ?string
{
if (!self::$formats) {
self::$formats = self::initFormats();
}
self::$formats ??= self::initFormats();
return self::$formats[$name] ?? null;
}
@ -164,12 +178,12 @@ final class ProgressBar
* @param string $message The text to associate with the placeholder
* @param string $name The name of the placeholder
*/
public function setMessage(string $message, string $name = 'message')
public function setMessage(string $message, string $name = 'message'): void
{
$this->messages[$name] = $message;
}
public function getMessage(string $name = 'message')
public function getMessage(string $name = 'message'): string
{
return $this->messages[$name];
}
@ -206,11 +220,11 @@ final class ProgressBar
public function getEstimated(): float
{
if (!$this->step) {
if (0 === $this->step || $this->step === $this->startingStep) {
return 0;
}
return round((time() - $this->startTime) / $this->step * $this->max);
return round((time() - $this->startTime) / ($this->step - $this->startingStep) * $this->max);
}
public function getRemaining(): float
@ -219,10 +233,10 @@ final class ProgressBar
return 0;
}
return round((time() - $this->startTime) / $this->step * ($this->max - $this->step));
return round((time() - $this->startTime) / ($this->step - $this->startingStep) * ($this->max - $this->step));
}
public function setBarWidth(int $size)
public function setBarWidth(int $size): void
{
$this->barWidth = max(1, $size);
}
@ -232,7 +246,7 @@ final class ProgressBar
return $this->barWidth;
}
public function setBarCharacter(string $char)
public function setBarCharacter(string $char): void
{
$this->barChar = $char;
}
@ -242,7 +256,7 @@ final class ProgressBar
return $this->barChar ?? ($this->max ? '=' : $this->emptyBarChar);
}
public function setEmptyBarCharacter(string $char)
public function setEmptyBarCharacter(string $char): void
{
$this->emptyBarChar = $char;
}
@ -252,7 +266,7 @@ final class ProgressBar
return $this->emptyBarChar;
}
public function setProgressCharacter(string $char)
public function setProgressCharacter(string $char): void
{
$this->progressChar = $char;
}
@ -262,7 +276,7 @@ final class ProgressBar
return $this->progressChar;
}
public function setFormat(string $format)
public function setFormat(string $format): void
{
$this->format = null;
$this->internalFormat = $format;
@ -273,7 +287,7 @@ final class ProgressBar
*
* @param int|null $freq The frequency in steps
*/
public function setRedrawFrequency(?int $freq)
public function setRedrawFrequency(?int $freq): void
{
$this->redrawFreq = null !== $freq ? max(1, $freq) : null;
}
@ -291,9 +305,15 @@ final class ProgressBar
/**
* Returns an iterator that will automatically update the progress bar when iterated.
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
* @template TKey
* @template TValue
*
* @param iterable<TKey, TValue> $iterable
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), if null it will be inferred from $iterable
*
* @return iterable<TKey, TValue>
*/
public function iterate(iterable $iterable, int $max = null): iterable
public function iterate(iterable $iterable, ?int $max = null): iterable
{
$this->start($max ?? (is_countable($iterable) ? \count($iterable) : 0));
@ -309,13 +329,16 @@ final class ProgressBar
/**
* Starts the progress output.
*
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
* @param int|null $max Number of steps to complete the bar (0 if indeterminate), null to leave unchanged
* @param int $startAt The starting point of the bar (useful e.g. when resuming a previously started bar)
*/
public function start(int $max = null)
public function start(?int $max = null, int $startAt = 0): void
{
$this->startTime = time();
$this->step = 0;
$this->percent = 0.0;
$this->step = $startAt;
$this->startingStep = $startAt;
$startAt > 0 ? $this->setProgress($startAt) : $this->percent = 0.0;
if (null !== $max) {
$this->setMaxSteps($max);
@ -329,7 +352,7 @@ final class ProgressBar
*
* @param int $step Number of steps to advance
*/
public function advance(int $step = 1)
public function advance(int $step = 1): void
{
$this->setProgress($this->step + $step);
}
@ -337,12 +360,12 @@ final class ProgressBar
/**
* Sets whether to overwrite the progressbar, false for new line.
*/
public function setOverwrite(bool $overwrite)
public function setOverwrite(bool $overwrite): void
{
$this->overwrite = $overwrite;
}
public function setProgress(int $step)
public function setProgress(int $step): void
{
if ($this->max && $step > $this->max) {
$this->max = $step;
@ -375,7 +398,7 @@ final class ProgressBar
}
}
public function setMaxSteps(int $max)
public function setMaxSteps(int $max): void
{
$this->format = null;
$this->max = max(0, $max);
@ -435,7 +458,7 @@ final class ProgressBar
$this->overwrite('');
}
private function setRealFormat(string $format)
private function setRealFormat(string $format): void
{
// try to use the _nomax variant if available
if (!$this->max && null !== self::getFormatDefinition($format.'_nomax')) {
@ -495,17 +518,13 @@ final class ProgressBar
private function determineBestFormat(): string
{
switch ($this->output->getVerbosity()) {
return match ($this->output->getVerbosity()) {
// OutputInterface::VERBOSITY_QUIET: display is disabled anyway
case OutputInterface::VERBOSITY_VERBOSE:
return $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX;
case OutputInterface::VERBOSITY_VERY_VERBOSE:
return $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX;
case OutputInterface::VERBOSITY_DEBUG:
return $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX;
default:
return $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX;
}
OutputInterface::VERBOSITY_VERBOSE => $this->max ? self::FORMAT_VERBOSE : self::FORMAT_VERBOSE_NOMAX,
OutputInterface::VERBOSITY_VERY_VERBOSE => $this->max ? self::FORMAT_VERY_VERBOSE : self::FORMAT_VERY_VERBOSE_NOMAX,
OutputInterface::VERBOSITY_DEBUG => $this->max ? self::FORMAT_DEBUG : self::FORMAT_DEBUG_NOMAX,
default => $this->max ? self::FORMAT_NORMAL : self::FORMAT_NORMAL_NOMAX,
};
}
private static function initPlaceholderFormatters(): array
@ -521,35 +540,25 @@ final class ProgressBar
return $display;
},
'elapsed' => function (self $bar) {
return Helper::formatTime(time() - $bar->getStartTime());
},
'elapsed' => fn (self $bar) => Helper::formatTime(time() - $bar->getStartTime(), 2),
'remaining' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the remaining time if the maximum number of steps is not set.');
}
return Helper::formatTime($bar->getRemaining());
return Helper::formatTime($bar->getRemaining(), 2);
},
'estimated' => function (self $bar) {
if (!$bar->getMaxSteps()) {
throw new LogicException('Unable to display the estimated time if the maximum number of steps is not set.');
}
return Helper::formatTime($bar->getEstimated());
},
'memory' => function (self $bar) {
return Helper::formatMemory(memory_get_usage(true));
},
'current' => function (self $bar) {
return str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT);
},
'max' => function (self $bar) {
return $bar->getMaxSteps();
},
'percent' => function (self $bar) {
return floor($bar->getProgressPercent() * 100);
return Helper::formatTime($bar->getEstimated(), 2);
},
'memory' => fn (self $bar) => Helper::formatMemory(memory_get_usage(true)),
'current' => fn (self $bar) => str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT),
'max' => fn (self $bar) => $bar->getMaxSteps(),
'percent' => fn (self $bar) => floor($bar->getProgressPercent() * 100),
];
}
@ -572,9 +581,11 @@ final class ProgressBar
private function buildLine(): string
{
\assert(null !== $this->format);
$regex = "{%([a-z\-_]+)(?:\:([^%]+))?%}i";
$callback = function ($matches) {
if ($formatter = $this::getPlaceholderFormatterDefinition($matches[1])) {
if ($formatter = $this->getPlaceholderFormatter($matches[1])) {
$text = $formatter($this, $this->output);
} elseif (isset($this->messages[$matches[1]])) {
$text = $this->messages[$matches[1]];
@ -591,9 +602,7 @@ final class ProgressBar
$line = preg_replace_callback($regex, $callback, $this->format);
// gets string length for each sub line with multiline format
$linesLength = array_map(function ($subLine) {
return Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r")));
}, explode("\n", $line));
$linesLength = array_map(fn ($subLine) => Helper::width(Helper::removeDecoration($this->output->getFormatter(), rtrim($subLine, "\r"))), explode("\n", $line));
$linesWidth = max($linesLength);