From aa1ead0787837f367d9fe3fc6e46bfaab56d641a Mon Sep 17 00:00:00 2001 From: "bozo.kopic" Date: Wed, 27 Apr 2022 00:52:11 +0200 Subject: message thread depth bugfix --- mbgui/executor.py | 10 ++++---- mbgui/main.py | 71 +++++++++++++++++++++++++++++-------------------------- mbgui/mblaze.py | 49 ++++++++++++++++++++++---------------- setup.py | 2 +- 4 files changed, 73 insertions(+), 59 deletions(-) diff --git a/mbgui/executor.py b/mbgui/executor.py index 9f3b420..d9efd58 100644 --- a/mbgui/executor.py +++ b/mbgui/executor.py @@ -3,10 +3,10 @@ import concurrent.futures import threading import typing -import PySide6.QtCore +from PySide6 import QtCore -class Executor(PySide6.QtCore.QObject): +class Executor(QtCore.QObject): def __init__(self): super().__init__() @@ -20,8 +20,8 @@ class Executor(PySide6.QtCore.QObject): with self._call_main_lock: self._call_main_queue.append((fn, args)) - PySide6.QtCore.QMetaObject.invokeMethod( - self, "_on_main_call", PySide6.QtCore.Qt.QueuedConnection) + QtCore.QMetaObject.invokeMethod(self, "_on_main_call", + QtCore.Qt.QueuedConnection) def call_worker(self, fn: typing.Callable, @@ -36,7 +36,7 @@ class Executor(PySide6.QtCore.QObject): return future - @PySide6.QtCore.Slot() + @QtCore.Slot() def _on_main_call(self): with self._call_main_lock: if not self._call_main_queue: diff --git a/mbgui/main.py b/mbgui/main.py index f6263c2..a5908d9 100644 --- a/mbgui/main.py +++ b/mbgui/main.py @@ -1,10 +1,11 @@ from pathlib import Path import sys +import typing -import PySide6.QtCore -import PySide6.QtGui -import PySide6.QtUiTools -import PySide6.QtWidgets +from PySide6 import QtCore +from PySide6 import QtGui +from PySide6 import QtUiTools +from PySide6 import QtWidgets from mbgui import mblaze from mbgui.executor import Executor @@ -32,21 +33,20 @@ def main(): if path: print(path) - app = PySide6.QtWidgets.QApplication(sys.argv) + app = QtWidgets.QApplication(sys.argv) executor = Executor() - icons = {i.stem: PySide6.QtGui.QIcon(str(i)) + icons = {i.stem: QtGui.QIcon(str(i)) for i in icons_path.glob('*.png')} directories = Directories(executor, icons, sys.argv[1:]) messages = Messages(executor, icons) message = Message(executor) - loader = PySide6.QtUiTools.QUiLoader() - window = loader.load(main_ui_path) + loader = QtUiTools.QUiLoader() + window = loader.load(str(main_ui_path)) - font = PySide6.QtGui.QFontDatabase.systemFont( - PySide6.QtGui.QFontDatabase.FixedFont) + font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont) window.message.setFont(font) window.vsplitter.setStretchFactor(0, 1) @@ -57,9 +57,9 @@ def main(): model.currentChanged.connect(on_directories_changed) header = window.directories.header() - header.setSectionResizeMode(0, PySide6.QtWidgets.QHeaderView.Stretch) - header.setSectionResizeMode(1, PySide6.QtWidgets.QHeaderView.Interactive) - header.setSectionResizeMode(2, PySide6.QtWidgets.QHeaderView.Interactive) + header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) + header.setSectionResizeMode(1, QtWidgets.QHeaderView.Interactive) + header.setSectionResizeMode(2, QtWidgets.QHeaderView.Interactive) window.messages.setModel(messages.model) model = window.messages.selectionModel() @@ -67,28 +67,31 @@ def main(): window.messages.doubleClicked.connect(on_messages_double_clicked) header = window.messages.header() - header.setSectionResizeMode(0, PySide6.QtWidgets.QHeaderView.Stretch) - header.setSectionResizeMode(1, PySide6.QtWidgets.QHeaderView.Interactive) - header.setSectionResizeMode(2, PySide6.QtWidgets.QHeaderView.Interactive) + header.setSectionResizeMode(0, QtWidgets.QHeaderView.Stretch) + header.setSectionResizeMode(1, QtWidgets.QHeaderView.Interactive) + header.setSectionResizeMode(2, QtWidgets.QHeaderView.Interactive) message.change.connect(window.message.setText) window.show() - sys.exit(app.exec()) + sys.exit(app.exec_()) class Directories: - def __init__(self, executor, icons, paths): + def __init__(self, + executor: Executor, + icons: typing.Dict[str, QtGui.QIcon], + paths: typing.Iterable[str]): self._executor = executor self._icons = icons - self._model = PySide6.QtGui.QStandardItemModel() + self._model = QtGui.QStandardItemModel() self._model.setHorizontalHeaderLabels(['Directory', 'Unseed', 'Total']) self._get_directories(paths) @property - def model(self) -> PySide6.QtCore.QAbstractItemModel: + def model(self) -> QtCore.QAbstractItemModel: return self._model def _get_directories(self, paths): @@ -101,9 +104,9 @@ class Directories: icon = self._icons['inbox-16' if directory.path else 'folder-16'] - items = [PySide6.QtGui.QStandardItem(icon, directory.name), - PySide6.QtGui.QStandardItem(''), - PySide6.QtGui.QStandardItem('')] + items = [QtGui.QStandardItem(icon, directory.name), + QtGui.QStandardItem(''), + QtGui.QStandardItem('')] for item in items: item.setData(directory.path) @@ -139,15 +142,17 @@ class Directories: class Messages: - def __init__(self, executor: Executor, icons): + def __init__(self, + executor: Executor, + icons: typing.Dict[str, QtGui.QIcon]): self._executor = executor self._icons = icons - self._model = PySide6.QtGui.QStandardItemModel() + self._model = QtGui.QStandardItemModel() self._model.setHorizontalHeaderLabels(['Subject', 'Sender', 'Date']) self._directory = None @property - def model(self) -> PySide6.QtCore.QAbstractItemModel: + def model(self) -> QtCore.QAbstractItemModel: return self._model def set_directory(self, directory: str): @@ -173,9 +178,9 @@ class Messages: icon = _status_icon(message.status) icon = self._icons[f'{icon}-16'] if icon else None - items = [PySide6.QtGui.QStandardItem(icon, message.subject), - PySide6.QtGui.QStandardItem(message.sender), - PySide6.QtGui.QStandardItem(message.date)] + items = [QtGui.QStandardItem(icon, message.subject), + QtGui.QStandardItem(message.sender), + QtGui.QStandardItem(message.date)] for item in items: item.setData(message.path) @@ -193,16 +198,16 @@ class Messages: return -class Message(PySide6.QtCore.QObject): +class Message(QtCore.QObject): - change = PySide6.QtCore.Signal(str) + change = QtCore.Signal(str) - def __init__(self, executor): + def __init__(self, executor: Executor): super().__init__() self._executor = executor self._path = None - def set_path(self, path): + def set_path(self, path: str): if self._path == path: return diff --git a/mbgui/mblaze.py b/mbgui/mblaze.py index 4dae52c..f93f6a0 100644 --- a/mbgui/mblaze.py +++ b/mbgui/mblaze.py @@ -1,8 +1,9 @@ from pathlib import Path +import enum +import io import itertools import subprocess import typing -import enum class Status(enum.Enum): @@ -38,18 +39,18 @@ def get_directories(roots: typing.Iterable[str]) -> typing.List[Directory]: def get_directory_total(dir_path: str) -> int: paths = _cmd(['mlist', dir_path]) - return len(paths) + return sum(1 for i in paths) def get_directory_unseen(dir_path: str) -> int: paths = _cmd(['mlist', '-s', dir_path]) - return len(paths) + return sum(1 for i in paths) def get_messages(dir_path: str) -> typing.List[Message]: paths = _cmd(['mlist', dir_path]) paths = _cmd(['mthread', '-r'], paths) - lines = _cmd(['mscan', '-f', r'%i%R\n%u\n%s\n%f\n%D'], paths) + lines = _cmd(['mscan', '-f', r'%i\n%R\n%u\n%s\n%f\n%D'], paths) messages = _parse_messages(lines) return messages @@ -67,10 +68,12 @@ def _cmd(args, stdin_lines=[]): stdout=subprocess.PIPE, encoding='utf-8', check=True) - stdout = p.stdout.removesuffix('\n') - if not stdout: - return [] - return stdout.split('\n') + stdout = io.StringIO(p.stdout) + while True: + line = stdout.readline() + if not line: + break + yield line[:-1] def _get_directory(path, path_parts): @@ -106,24 +109,30 @@ def _reduce_directory(directory): def _parse_messages(lines): messages = [] - while lines: - path = lines[0] - depth = 0 - while path[0] == ' ': - depth += 1 - path = path[1:] - - status = Status(lines[1]) + + while True: + try: + line = next(lines) + except StopIteration: + break + + if line.startswith('..'): + depth = int(line[2:].split('.', 1)[0]) - 1 + else: + depth = line.count(' ') + + path = next(lines) + + status = Status(next(lines)) if not Path(path).exists(): status = Status.VIRTUAL message = Message(path=path, status=status, - subject=lines[2], - sender=lines[3], - date=lines[4], + subject=next(lines), + sender=next(lines), + date=next(lines), children=[]) - lines = lines[5:] children = messages while depth: diff --git a/setup.py b/setup.py index d521fae..6c5683e 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ readme = (Path(__file__).parent / 'README.rst').read_text() setup( name='mbgui', - version='0.1.2', + version='0.1.3', description='Maildir GUI based on mblaze', long_description=readme, long_description_content_type='text/x-rst', -- cgit v1.2.3-70-g09d2