Esempio n. 1
0
  def __init__(
      self,
      *,
      upd=None,
      fstags=None,
      all_progress=None,
      ydl_opts=None,
      parallel=DEFAULT_PARALLEL,
  ):
    if upd is None:
      upd = Upd()
    if all_progress is None:
      all_progress = OverProgress()
    self.upd = upd
    self.sem = Semaphore(parallel)
    self.proxy0 = upd.insert(0)
    self.fstags = fstags
    self.all_progress = all_progress
    self.ydl_opts = ydl_opts
    self.Rs = []
    self.nfetches = 0
    self._lock = RLock()

    @logexc
    def update0():
      nfetches = self.nfetches
      if nfetches == 0:
        self.proxy0("Idle.")
      else:
        self.proxy0(
            self.all_progress.status(
                "%d %s" % (nfetches, "fetch" if nfetches == 1 else "fetches"),
                upd.columns - 1
            )
        )

    self.update0 = update0
    update0()
Esempio n. 2
0
    def iterbar(
        self,
        it,
        label=None,
        upd=None,
        proxy=None,
        itemlenfunc=None,
        statusfunc=None,
        incfirst=False,
        width=None,
        window=None,
        update_frequency=1,
        update_min_size=None,
        report_print=None,
        runstate=None,
    ):
        ''' An iterable progress bar: a generator yielding values
        from the iterable `it` while updating a progress bar.

        Parameters:
        * `it`: the iterable to consume and yield.
        * `itemlenfunc`: an optional function returning the "size" of each item
          from `it`, used to advance `self.position`.
          The default is to assume a size of `1`.
          A convenient alternative choice may be the builtin function `len`.
        * `incfirst`: whether to advance `self.position` before we
          `yield` an item from `it` or afterwards.
          This reflects whether it is considered that progress is
          made as items are obtained or only after items are processed
          by whatever is consuming this generator.
          The default is `False`, advancing after processing.
        * `label`: a label for the progress bar,
          default from `self.name`.
        * `width`: an optional width expressing how wide the progress bar
          text may be.
          The default comes from the `proxy.width` property.
        * `window`: optional timeframe to define "recent" in seconds;
          if the default `statusfunc` (`Progress.status`) is used
          this is passed to it
        * `statusfunc`: an optional function to compute the progress bar text
          accepting `(self,label,width)`.
        * `proxy`: an optional proxy for displaying the progress bar,
          a callable accepting the result of `statusfunc`.
          The default is a `cs.upd.UpdProxy` created from `upd`,
          which inserts a progress bar above the main status line.
        * `upd`: an optional `cs.upd.Upd` instance,
          used only to produce the default `proxy` if that is not supplied.
          The default `upd` is `cs.upd.Upd()`
          which uses `sys.stderr` for display.
        * `update_frequency`: optional update frequency, default `1`;
          only update the progress bar after this many iterations,
          useful if the iteration rate is quite high
        * `update_min_size`: optional update step size;
          only update the progress bar after an advance of this many units,
          useful if the iteration size increment is quite small
        * `report_print`: optional `print` compatible function
          with which to write a report on completion;
          this may also be a `bool`, which if true will use `Upd.print`
          in order to interoperate with `Upd`.
        * `runstate`: optional `RunState` whose `.cancelled` property can be consulted

        Example use:

            from cs.units import DECIMAL_SCALE
            rows = [some list of data]
            P = Progress(total=len(rows), units_scale=DECIMAL_SCALE)
            for row in P.iterbar(rows, incfirst=True):
                ... do something with each row ...

            f = open(data_filename, 'rb')
            datalen = os.stat(f).st_size
            def readfrom(f):
                while True:
                    bs = f.read(65536)
                    if not bs:
                        break
                    yield bs
            P = Progress(total=datalen)
            for bs in P.iterbar(readfrom(f), itemlenfunc=len):
                ... process the file data in bs ...
    '''
        if label is None:
            label = self.name
        delete_proxy = False
        if proxy is None:
            if upd is None:
                upd = Upd()
            proxy = upd.insert(1)
            delete_proxy = True
        if statusfunc is None:
            statusfunc = lambda P, label, width: P.status(
                label, width, window=window)
        iteration = 0
        last_update_iteration = 0
        last_update_pos = start_pos = self.position

        def update_status(force=False):
            nonlocal self, proxy, statusfunc, label, width
            nonlocal iteration, last_update_iteration, last_update_pos
            if (force or iteration - last_update_iteration >= update_frequency
                    or
                (update_min_size is not None
                 and self.position - last_update_pos >= update_min_size)):
                last_update_iteration = iteration
                last_update_pos = self.position
                proxy(statusfunc(self, label, width or proxy.width))

        update_status(True)
        for iteration, item in enumerate(it):
            length = itemlenfunc(item) if itemlenfunc else 1
            if incfirst:
                self += length
                update_status()
            yield item
            if not incfirst:
                self += length
                update_status()
            if runstate is not None and runstate.cancelled:
                break
        if delete_proxy:
            proxy.delete()
        else:
            update_status(True)
        if report_print:
            if isinstance(report_print, bool):
                report_print = print
            report_print(
                label + (': (cancelled)' if runstate is not None
                         and runstate.cancelled else ':'),
                self.format_counter(self.position - start_pos), 'in',
                transcribe(self.elapsed_time,
                           TIME_SCALE,
                           max_parts=2,
                           skip_zero=True))
Esempio n. 3
0
    def bar(
        self,
        label=None,
        *,
        upd=None,
        proxy=None,
        statusfunc=None,
        width=None,
        window=None,
        report_print=None,
        insert_pos=1,
        deferred=False,
    ):
        ''' A context manager to create and withdraw a progress bar.
        It returns the `UpdProxy` which displays the progress bar.

        Parameters:
        * `label`: a label for the progress bar,
          default from `self.name`.
        * `proxy`: an optional `UpdProxy` to display the progress bar
        * `upd`: an optional `cs.upd.Upd` instance,
          used to produce the progress bar status line if not supplied.
          The default `upd` is `cs.upd.Upd()`
          which uses `sys.stderr` for display.
        * `statusfunc`: an optional function to compute the progress bar text
          accepting `(self,label,width)`.
        * `width`: an optional width expressing how wide the progress bar
          text may be.
          The default comes from the `proxy.width` property.
        * `window`: optional timeframe to define "recent" in seconds;
          if the default `statusfunc` (`Progress.status`) is used
          this is passed to it
        * `report_print`: optional `print` compatible function
          with which to write a report on completion;
          this may also be a `bool`, which if true will use `Upd.print`
          in order to interoperate with `Upd`.
        * `insert_pos`: where to insert the progress bar, default `1`
        * `deferred`: optional flag; if true do not create the
          progress bar until the first update occurs.

        Example use:

            # display progress reporting during upload_filename()
            # which updates the supplied Progress instance
            # during its operation
            P = Progress(name=label)
            with P.bar(report_print=True):
                upload_filename(src, progress=P)

    '''
        if label is None:
            label = self.name
        if upd is None:
            upd = Upd()
        if statusfunc is None:
            statusfunc = lambda P, label, width: P.status(
                label, width, window=window)
        pproxy = [proxy]
        proxy_delete = proxy is None

        def update(P, _):
            proxy = pproxy[0]
            if proxy is None:
                proxy = pproxy[0] = upd.insert(insert_pos, 'LABEL=' + label)
            proxy(statusfunc(P, label, width or proxy.width))

        try:
            if not deferred:
                if proxy is None:
                    proxy = pproxy[0] = upd.insert(insert_pos)
                status = statusfunc(self, label, width or proxy.width)
                proxy(status)
            self.notify_update.add(update)
            start_pos = self.position
            yield pproxy[0]
        finally:
            self.notify_update.remove(update)
            if proxy and proxy_delete:
                proxy.delete()
        if report_print:
            if isinstance(report_print, bool):
                report_print = print
            report_print(
                label + ':', self.format_counter(self.position - start_pos),
                'in',
                transcribe(self.elapsed_time,
                           TIME_SCALE,
                           max_parts=2,
                           skip_zero=True))