anaconda/anaconda-40.22.3.13/pyanaconda/modules/common/task/progress.py

111 lines
3.6 KiB
Python
Raw Normal View History

2024-11-14 21:39:56 -08:00
#
# Copyright (C) 2018 Red Hat, Inc.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions of
# the GNU General Public License v.2, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY expressed or implied, including the implied warranties of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
# Public License for more details. You should have received a copy of the
# GNU General Public License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
# source code or documentation are not subject to the GNU General Public
# License and may only be used or replicated with the express permission of
# Red Hat, Inc.
#
from abc import ABC, abstractmethod
from threading import Lock
from pyanaconda.core.signal import Signal
from pyanaconda.core.async_utils import async_action_nowait
__all__ = ['ProgressReporter']
class ProgressReporter(ABC):
"""Abstract class that allows to report a progress of a task."""
def __init__(self):
super().__init__()
self._progress_changed_signal = Signal()
self._category_changed_signal = Signal()
self.__progress_lock = Lock()
self.__progress_step = 0
self.__progress_category = None
self.__progress_msg = ""
@property
def progress(self):
"""Current progress of the task.
:returns: tuple (step, description).
"""
with self.__progress_lock:
return self.__progress_step, self.__progress_msg
@property
@abstractmethod
def steps(self):
"""Number of progress steps in the task."""
return 0
@property
def progress_changed_signal(self):
"""Signal emits when the progress of the task changes."""
return self._progress_changed_signal
@property
def category_changed_signal(self):
"""Signal emits when the category of the task changes."""
return self._category_changed_signal
@async_action_nowait
def report_category(self, category):
if category is None:
return
else:
self._category_changed_signal.emit(category)
@async_action_nowait
def report_progress(self, message, step_number=None, step_size=None):
"""Report a progress change.
Update the progress and emit the progress changed signal. The next
step will never be higher then self.steps and lower then the current
step. By default, the step doesn't change.
This is a thread safe method.
:param message: Short description of the actual step.
:type message: str
:param step_number: The number of the next step.
:type step_number: int or None
:param step_size: The size of the next step.
:type step_size: int or None
"""
with self.__progress_lock:
current_step = self.__progress_step
max_step = self.steps
step = current_step
if step_number is not None:
step = step_number
if step_size is not None:
step += step_size
if step < current_step:
step = current_step
if step > max_step:
step = max_step
self.__progress_step = step
self.__progress_msg = message
self._progress_changed_signal.emit(step, message)