"""
Initialize a pipeline run from a pipeline and run it
"""

import time

from django.core.management.base import BaseCommand
from apps.pipeline.models import Pipeline


class PipelineDoesNotExist(Exception):
    pass


class Command(BaseCommand):
    help = __doc__

    def __print_status(self, program_run):
        pgruns = program_run.all_programs()
        for pgr in pgruns:
            print(pgr, pgr.run_time(), '\n')

    def add_arguments(self, parser):
            parser.add_argument(
                'pipeline_name',
                type=str,
                help='Name of the pipeline to test'
            )

            parser.add_argument(
                'update_rate',
                type=float,
                help='Rate to update status of program runs'
            )

    def handle(self, **kwargs):
        if 'update_rate' not in kwargs:
            update_rate = 1
        else:
            update_rate = kwargs['update_rate']

        pname = kwargs['pipeline_name']
        ps = Pipeline.objects.filter(name=pname)

        # TODO make exception more descriptive
        if not ps:
            raise PipelineDoesNotExist

        for pipeline in ps:
            prun = pipeline.run(for_test=True)

            # TODO see if this can update based on when program runs finish,
            # not on a clock
            # TODO more descriptive output
            while True:
                if prun.update_all():
                    self.__print_status(prun)

                    break

                self.__print_status(prun)

                # stop as soon as an error is found
                if prun.programs.filter(is_error=True).count() != 0:
                    break

                time.sleep(update_rate)

@@ -66,16 +66,32 @@
 ort time
+%0Aimport datetime
 %0A%0Afrom d
@@ -333,113 +333,1578 @@
     
-pgruns = program_run.all_programs()%0A        for pgr in pgruns:%0A            print(pgr, pgr.run_time(), '%5Cn
+labels = ('PROGRAM', 'TIME', 'TOTAL')%0A%0A        # data for each row%0A        rows = %5B%5D%0A%0A        # longest string in each column%0A        cmax = dict()%0A%0A        for l in labels:%0A            cmax%5Bl%5D = len(l)%0A%0A        prev_seconds = 0%0A%0A        pgruns = program_run.all_programs()%0A        for pgr in pgruns:%0A            pgr_name = str(pgr)%0A            pgr_total = pgr.run_time()%0A%0A            # convert time to seconds%0A            pgr_seconds = 0%0A            if pgr_total != '-':%0A                parts = map(int, pgr_total.split(':'))%0A                parts = map(lambda a, b: a * b, parts, %5B3600, 60, 1%5D)%0A                pgr_seconds = reduce(lambda a, b: a + b, parts, pgr_seconds)%0A%0A            # find delta from previous program's time%0A            pgr_delta = '-'%0A            if pgr_seconds %3E prev_seconds:%0A                pgr_delta = str(datetime.timedelta(seconds=pgr_seconds - prev_seconds))%0A%0A            prev_seconds = pgr_seconds%0A%0A            # max column lengths%0A            cmax%5B'PROGRAM'%5D = max(cmax%5B'PROGRAM'%5D, len(pgr_name))%0A            cmax%5B'TIME'%5D = max(cmax%5B'TIME'%5D, len(pgr_delta))%0A            cmax%5B'TOTAL'%5D = max(cmax%5B'TOTAL'%5D, len(pgr_total))%0A%0A            rows.append((pgr_name, pgr_delta, pgr_total))%0A%0A        # template widths defined by longest output per column%0A        template = ' '.join(%5B'%7B' + str(i) + ':%25d%7D' for i in range(len(labels))%5D)%0A        template = template %25 tuple(cmax%5Bl%5D + 1 for l in labels)%0A%0A        # print it all out%0A        print(template.format(*labels))%0A        for row in rows:%0A            print(template.format(*row))%0A        print('
 ')%0A%0A

Improves output format