Files
bearhub/bauh/gems/arch/output.py
2022-02-09 11:01:21 -03:00

131 lines
5.7 KiB
Python

import logging
import time
from threading import Thread
from typing import Optional, Collection
from bauh.api.abstract.handler import ProcessWatcher
from bauh.commons.html import bold
from bauh.view.util.translation import I18n
class TransactionStatusHandler(Thread):
def __init__(self, watcher: ProcessWatcher, i18n: I18n, names: Optional[Collection[str]], logger: logging.Logger,
percentage: bool = True, downloading: int = 0, pkgs_to_remove: int = 0):
super(TransactionStatusHandler, self).__init__(daemon=True)
self.watcher = watcher
self.i18n = i18n
self.names = names
self.pkgs_to_sync = len(names) if names else 0
self.pkgs_to_remove = pkgs_to_remove
self.downloading = downloading
self.upgrading = 0
self.installing = 0
self.removing = 0
self.outputs = []
self.work = True
self.logger = logger
self.percentage = percentage
self.accepted = {'checking keyring': 'keyring',
'checking package integrity': 'integrity',
'loading package files': 'loading_files',
'checking for file conflicts': 'conflicts',
'checking available disk space': 'disk_space',
':: running pre-transaction hooks': 'pre_hooks',
':: retrieving packages': 'retrieve_pkgs'}
def gen_percentage(self) -> str:
if self.percentage:
performed = self.downloading + self.upgrading + self.installing
return f'({(performed / (2 * self.pkgs_to_sync)) * 100:.2f}%) '
else:
return ''
def get_performed(self) -> int:
return self.upgrading + self.installing
def _handle(self, output: str) -> bool:
if output:
output_split = output.split(' ')
if output_split[0].lower() == 'removing' and (not self.names or output_split[1].split('.')[0] in self.names):
if self.pkgs_to_remove > 0:
self.removing += 1
self.watcher.change_substatus(f"[{self.removing}/{self.pkgs_to_remove}] "
f"{self.i18n['uninstalling'].capitalize()} {output.split(' ')[1].strip()}")
else:
self.watcher.change_substatus(f"{self.i18n['uninstalling'].capitalize()} {output_split[1].strip()}")
elif len(output_split) >= 2 and output_split[1].lower().startswith('downloading') and (not self.names or (n for n in self.names if output_split[0].startswith(n))):
if self.downloading < self.pkgs_to_sync:
perc = self.gen_percentage()
self.downloading += 1
self.watcher.change_substatus(f"{perc}[{self.downloading}/{self.pkgs_to_sync}] {bold('[pacman]')} "
f"{self.i18n['downloading'].capitalize()} {output_split[0].strip()}")
elif output_split[0].lower() == 'upgrading' and (not self.names or output_split[1].split('.')[0] in self.names):
if self.get_performed() < self.pkgs_to_sync:
perc = self.gen_percentage()
self.upgrading += 1
performed = self.upgrading + self.installing
if performed <= self.pkgs_to_sync:
self.watcher.change_substatus(f"{perc}[{performed}/{self.pkgs_to_sync}] "
f"{self.i18n['manage_window.status.upgrading'].capitalize()} {output_split[1].strip()}")
elif output_split[0].lower() == 'installing' and (not self.names or output_split[1].split('.')[0] in self.names):
if self.get_performed() < self.pkgs_to_sync:
perc = self.gen_percentage()
self.installing += 1
performed = self.upgrading + self.installing
if performed <= self.pkgs_to_sync:
self.watcher.change_substatus(f"{perc}[{performed}/{self.pkgs_to_sync}] "
f"{self.i18n['manage_window.status.installing'].capitalize()} {output_split[1].strip()}")
else:
substatus_found = False
lower_output = output.lower().strip()
for msg, key in self.accepted.items():
if lower_output.startswith(msg):
self.watcher.change_substatus(self.i18n[f'arch.substatus.{key}'].capitalize())
substatus_found = True
break
if not substatus_found:
if self.pkgs_to_remove > 0:
if self.pkgs_to_remove == self.removing:
self.watcher.change_substatus('')
return False
else:
performed = self.get_performed()
if performed == self.pkgs_to_sync:
self.watcher.change_substatus(self.i18n['finishing'].capitalize())
return False
else:
self.watcher.change_substatus('')
return True
def handle(self, output: str):
self.outputs.insert(0, output)
def stop_working(self):
self.work = False
def run(self):
self.logger.info("Starting")
while self.work:
if self.outputs:
output = self.outputs.pop()
if not self._handle(output):
break
else:
time.sleep(0.005)
self.logger.info("Finished")