Symfony/Console: How to use multiple progress bars?
Asked Answered
K

4

9

I have a command for Symfony/Console which downloads several files at once using Guzzle Pool. I already have Guzzle reporting the download progress for each file, that works fine.

Now I'd like to improve it using the ProgressBar helper from Symfony/Console.The problem is that all examples I found for the ProgressBar only use a single progress bar. I need several independent progress bars - one for each of the downloads. Can you give me some hint how to achieve that?

Kessinger answered 15/4, 2017 at 9:50 Comment(1)
FYI when using console output sections like the below answers do, it'll then send the progress bars to stdout instead of stderr. I haven't found a clean way of sending progress bar sections to stderr and regular log messages to stdoutCritic
V
20

I found something here: [Console] A better progress bar #10356

use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

$output = new ConsoleOutput();

$bar1 = new ProgressBar($output, 10);
$bar2 = new ProgressBar($output, 20);
$bar2->setProgressCharacter('#');
$bar1->start();
print "\n";
$bar2->start();

for ($i = 1; $i <= 20; $i++) {
    // up one line
    $output->write("\033[1A");
    usleep(100000);
    if ($i <= 10) {
        $bar1->advance();
    }
    print "\n";
    $bar2->advance();
}

Effect:

ProgressBar

You must move the console cursor to the appropriate line (up and down) before updating the bar. But it works. I confirm.

Victuals answered 15/4, 2017 at 11:22 Comment(0)
A
10

With Symfony 4.1 this is supported without manual cursor-control, see https://symfony.com/doc/current/components/console/helpers/progressbar.html#console-multiple-progress-bars:

$section1 = $output->section();
$section2 = $output->section();

$progress1 = new ProgressBar($section1);
$progress2 = new ProgressBar($section2);

$progress1->start(100);
$progress2->start(100);

$i = 0;
while (++$i < 100) {
    $progress1->advance();

    if ($i % 2 === 0) {
         $progress2->advance(4);
    }

    usleep(50000);
}
Ardel answered 29/8, 2018 at 9:37 Comment(0)
M
0

Laravel 5.6 / linux

use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Output\ConsoleOutput;

$output = new ConsoleOutput();

$bar1 = new ProgressBar($output->section(), 10);
$bar2 = new ProgressBar($output->section(), 20);
$bar2->setProgressCharacter('#');
$bar1->start();
print "\n";
$bar2->start();

for ($i = 1; $i <= 20; $i++) {
    // up one line
    $output->write("\033[1A");
    usleep(100000);
    if ($i <= 10) {
        $bar1->advance();
    }
    print "\n";
    $bar2->advance();
}
Molasses answered 4/7, 2018 at 9:7 Comment(0)
N
-4

In Laravel, you can do this to create multiple progress bars.

    use Symfony\Component\Console\Output\ConsoleOutput;
    use Symfony\Component\Console\Helper\ProgressBar;


    $output = new ConsoleOutput();
    
    $totalUsers->chunk(100, function($users) use($output) {
        $bar = new ProgressBar($output, count($users));
        $bar->start();

        $users->each(function($user) use($bar) {
            $this->performTask($user);
            $bar->advance();
        });

        $bar->finish();
        print "\n";
    });
Neidaneidhardt answered 17/9, 2022 at 8:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.