
    j5j#                        d Z ddlmZ ddlmZ ddlmZ ddlmZm	Z	m
Z
mZmZmZ ddlmZ  G d de      Z G d	 d
      Z G d d      Zy)zDefines progress bar API.    )annotations)Protocol)Console)	BarColumnMofNCompleteColumnProgressTaskProgressColumn
TextColumnTimeRemainingColumn)Columnc                  H    e Zd ZdZdd	 	 	 	 	 	 	 d
dZd Zd Zddddd	Zy)ProgressBara  The protocol that OCRmyPDF expects progress bar classes to be compatible with.

    In practice this could be used for any time of monitoring, not just a progress bar.

    Calling the class should return a new progress bar object, which is activated
    with ``__enter__`` and terminated with ``__exit__``. An update method is called
    whenever the progress bar is updated. Progress bar objects will not be reused;
    a new one will be created for each group of tasks.

    The progress bar is held in the main process/thread and not updated by child
    process/threads. When a child notifies the parent of completed work, the
    parent updates the progress bar.
    Progress bars should never write to ``sys.stdout``, or they will corrupt the
    output if OCRmyPDF writes a PDF to standard output.

    Note:
        The type of events that OCRmyPDF reports to a progress bar may change in
    minor releases.

    Args:
        total (int | float | None):
            The total number of work units expected. If ``None``, the total is unknown.
            For example, if you are processing pages, this might be the number of pages,
            or if you are measuring overall progress in percent, this might be 100.
        desc (str | None):
            A brief description of the current step (e.g. "Scanning contents",
            "OCR", "PDF/A conversion"). OCRmyPDF updates this before each major step.
        unit (str | None):
            A short label for the type of work being tracked
            (e.g. "page", "%", "image").
        disable (bool):
            If ``True``, progress updates are suppressed (no output).
            Defaults to ``False``.
        **kwargs:
            Future or extra parameters that OCRmyPDF might pass. Implementations
            should accept and ignore unrecognized keywords gracefully.

    Example:
        A simple plugin implementation could look like this:

        .. code-block:: python

            from ocrmypdf.pluginspec import ProgressBar
            from ocrmypdf import hookimpl

            class ConsoleProgressBar(ProgressBar):
                def __init__(self, *, total=None, desc=None, unit=None, disable=False,
                             **kwargs):
                    self.total = total
                    self.desc = desc
                    self.unit = unit
                    self.disable = disable
                    self.current = 0

                def __enter__(self):
                    if not self.disable:
                        print(f"Starting {self.desc or 'an OCR task'} "
                              f"(total={self.total} {self.unit})"
                        )
                    return self

                def __exit__(self, exc_type, exc_value, traceback):
                    if not self.disable:
                        if exc_type is None:
                            print("Completed successfully.")
                        else:
                            print(f"Task ended with error: {exc_value}")
                    return False  # Let OCRmyPDF raise any exceptions

                def update(self, n=1, *, completed=None):
                    if completed is not None:
                        # If 'completed' is given, set self.current
                        # but let's just read it to show usage
                        print(f"Absolute completion reported: {completed}")
                    # Otherwise, we increment by 'n'
                    self.current += n
                    if not self.disable:
                        if self.total:
                            percent = (self.current / self.total) * 100
                            print(
                                f"{self.desc}: {self.current}"
                                f"/{self.total} ({percent:.1f}%)"
                            )
                        else:
                            print(f"{self.desc}: {self.current} units done")

            @hookimpl
            def get_progressbar_class():
                return MyProgressBar

    F)disablec                    y)at  Initialize a progress bar.

        This is called once before any work is done. OCRmyPDF supplies the total
        number of units (or None if unknown), a description of the work, and the
        type of units. The ``disable`` parameter can be used to turn off progress
        reporting. Unrecognized keyword arguments should be ignored.

        Args:
            total (int | float | None):
                The total amount of work. If ``None``, the total is unknown.
            desc (str | None):
                A description of the current task. May change for different stages.
            unit (str | None):
                A short label for the unit of work.
            disable (bool):
                If ``True``, no output or logging should be displayed.
            **kwargs:
                Extra parameters that may be passed by OCRmyPDF in future versions.
        N )selftotaldescunitr   kwargss         K/var/www/html/qr/venv/lib/python3.12/site-packages/ocrmypdf/_progressbar.py__init__zProgressBar.__init__s           c                     y)zEnter a progress bar context.Nr   r   s    r   	__enter__zProgressBar.__enter__   r   r   c                     y)zExit a progress bar context.Nr   )r   argss     r   __exit__zProgressBar.__exit__   r   r   N	completedc                    y)a  Increment the progress bar by ``n`` units, or set an absolute completion.

        OCRmyPDF calls this method repeatedly while processing pages or other tasks.
        If your total is known and you track it, you might do something like:

        .. code-block:: python

            self.current += n
            percent = (self.current / total) * 100

        The ``completed`` argument can indicate an absolute position, which is
        particularly helpful if you're tracking a percentage of work (e.g., 0 to 100)
        and want precise updates. In contrast, the incremental parameter ``n`` is
        often more useful for page-based increments.

        Args:
            n (float, optional):
                The amount to increment the progress by. Defaults to 1. May be
                fractional if OCRmyPDF performs partial steps. If you are tracking
                pages, this is typically how many pages have been processed in the
                most recent step.
            completed (float | None, optional):
                The absolute amount of work completed so far. This can override or
                supplement the simple increment logic. It's particularly useful
                for percentage-based tracking (e.g., when ``total`` is 100).
        Nr   )r   nr"   s      r   updatezProgressBar.update   r   r   )r   zint | float | Noner   
str | Noner   r&   r   bool   )r$   floatr"   float | None__name__
__module____qualname____doc__r   r   r    r%   r   r   r   r   r      sQ    ZD  " 	
  :,+ r   r   c                  0    e Zd ZdZd Zd Zd ZddddZy)	NullProgressBarz'Progress bar API that takes no actions.c                     y Nr   )r   r   s     r   r   zNullProgressBar.__init__   s    r   c                    | S r4   r   r   s    r   r   zNullProgressBar.__enter__   s    r   c                     yNFr   r   exc_type	exc_value	tracebacks       r   r    zNullProgressBar.__exit__   s    r   Nr!   c                    y r4   r   )r   _argr"   s      r   r%   zNullProgressBar.update   s    r   r4   r,   r   r   r   r2   r2      s     1T r   r2   c                  T    e Zd ZdZddddd	 	 	 	 	 	 	 	 	 	 	 ddZd Zd Zddd	d
Zy)RichProgressBarz Display progress bar using rich.Ng      ?F)r   r   
unit_scaler   c          	     @   d| _         t        t        dt        d            t	               t               t               t               f|ddd|d|| _        || _	        | j                  j                  ||| j                  || j                  z  nd |      | _        y )	NFz([progress.description]{task.description}   )	min_width)table_columnT)consoleauto_refreshredirect_stderrredirect_stdoutr   )r   r   )_enteredr   r
   r   r   r	   r   r   progressr@   add_taskprogress_bar)r   rE   r   r   r   r@   r   r   s           r   r   zRichProgressBar.__init__   s      :#b1 K  !
  !
 
  % MM22 T__%@ $//) 3 
r   c                H    | j                   j                          d| _        | S )NT)rJ   startrI   r   s    r   r   zRichProgressBar.__enter__   s    r   c                l    | j                   j                          | j                   j                          yr7   )rJ   refreshstopr8   s       r   r    zRichProgressBar.__exit__   s%    r   r!   c                   | j                   sJ d       |8|| j                  n|}| j                  j                  | j                  |       y | j                  j                  | j                  |       y )Nz,Progress bar must be entered before updating)advancer!   )rI   r@   rJ   r%   rL   )r   r$   r"   rS   s       r   r%   zRichProgressBar.update   sc    }}LLL})*dooGMM  !2!2G DMM  !2!2i Hr   )rE   r   r   strr   r+   r   r&   r@   r+   r   r'   r(   r,   r   r   r   r?   r?      sm    * ##&#
 #
 	#

 #
 #
 !#
 #
J

It Ir   r?   N)r0   
__future__r   typingr   rich.consoler   rich.progressr   r   r   r	   r
   r   
rich.tabler   r   r2   r?   r   r   r   <module>rZ      sG      "     Z( Zz  8I 8Ir   