98 lines
2.5 KiB
PHP
98 lines
2.5 KiB
PHP
<?php
|
|
|
|
namespace Spark\Pipe\Filters;
|
|
|
|
class ProgressFilter implements FilterInterface
|
|
{
|
|
private array $args = [];
|
|
|
|
private static $defaultArgs = [
|
|
'max' => null,
|
|
];
|
|
|
|
private ?int $max = null;
|
|
|
|
private int $current = 0;
|
|
|
|
private int $lastCurrent = 0;
|
|
|
|
private ?int $nextRefresh = null;
|
|
|
|
private array $deltas = [];
|
|
|
|
private array $times = [];
|
|
|
|
public function setArguments(array $args)
|
|
{
|
|
$this->args = array_merge(self::$defaultArgs, $args);
|
|
$max = $this->args['max'];
|
|
if (str_starts_with($max, '@')) {
|
|
$this->max = filesize(substr($max,1));
|
|
} else {
|
|
$this->max = $max;
|
|
}
|
|
}
|
|
|
|
public function pipe(?string $chunk)
|
|
{
|
|
if ($chunk === null) {
|
|
$this->nextRefresh = 0;
|
|
$this->refresh();
|
|
fwrite(STDERR, "\n");
|
|
return;
|
|
}
|
|
$this->current += strlen($chunk);
|
|
$this->refresh();
|
|
return $chunk;
|
|
}
|
|
|
|
private function refresh()
|
|
{
|
|
if (microtime(true) < $this->nextRefresh) {
|
|
return;
|
|
}
|
|
|
|
$now = microtime(true);
|
|
$delta = $this->current - $this->lastCurrent;
|
|
array_push($this->deltas, $delta);
|
|
array_push($this->times, $now);
|
|
while (count($this->deltas) > 10) {
|
|
array_shift($this->deltas);
|
|
array_shift($this->times);
|
|
}
|
|
|
|
$deltaTime = end($this->times) - reset($this->times);
|
|
|
|
if ($deltaTime > 0) {
|
|
$rate = array_sum($this->deltas) / $deltaTime;
|
|
$rateu = "b/s";
|
|
if ($rate > 1024) {
|
|
$rate /= 1024;
|
|
$rateu = "KiB/s";
|
|
if ($rate > 1024) {
|
|
$rate /= 1024;
|
|
$rateu = "MiB/s";
|
|
if ($rate > 1024) {
|
|
$rate /= 1024;
|
|
$rateu = "GiB/s";
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
$rate = null;
|
|
}
|
|
|
|
if ($this->max) {
|
|
fprintf(STDERR, "\r%.1fMiB/%.1fMiB (%.1f%%) ", $this->current/1024/1024, $this->max/1024/1024, 100/$this->max*$this->current);
|
|
} else {
|
|
fprintf(STDERR, "\r%.1fMiB ", $this->current/1024/1024);
|
|
}
|
|
if ($rate) {
|
|
fprintf(STDERR, "(%.1f%s)", $rate, $rateu);
|
|
}
|
|
fprintf(STDERR, "\e[K");
|
|
|
|
$this->lastCurrent = $this->current;
|
|
$this->nextRefresh = $now + .1;
|
|
}
|
|
} |