apol: move queries to common updater thread class

Move logger to main tab class and have the result class send the result
count back on the finished signal.
This commit is contained in:
Chris PeBenito 2016-03-30 10:26:38 -04:00
parent 69332d4e64
commit 945a6548e0
10 changed files with 119 additions and 468 deletions

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import BoolQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..boolmodel import BooleanTableModel, boolean_detail
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class BoolQueryTab(SEToolsWidget, QScrollArea):
@ -68,7 +69,7 @@ class BoolQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -148,7 +149,9 @@ class BoolQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} Boolean(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -166,52 +169,3 @@ class BoolQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(item.statement())
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} Boolean(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import FSUseQuery
@ -27,6 +27,7 @@ from setools import FSUseQuery
from ..logtosignal import LogHandlerToSignal
from ..fsusemodel import FSUseTableModel
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class FSUseQueryTab(SEToolsWidget, QScrollArea):
@ -90,7 +91,7 @@ class FSUseQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -272,7 +273,9 @@ class FSUseQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} fs_use_* statment(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -290,52 +293,3 @@ class FSUseQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(str(item))
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} fs_use_* rule(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import MLSRuleQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..rulemodels import MLSRuleListModel
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class MLSRuleQueryTab(SEToolsWidget, QScrollArea):
@ -80,7 +81,7 @@ class MLSRuleQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -225,7 +226,9 @@ class MLSRuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} MLS rule(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -243,52 +246,3 @@ class MLSRuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(str(item))
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} MLS rule(s) found.".format(counter))
self.finished.emit()

View File

@ -0,0 +1,65 @@
# Copyright 2016, Tresys Technology, LLC
#
# This file is part of SETools.
#
# SETools is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 2.1 of
# the License, or (at your option) any later version.
#
# SETools is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with SETools. If not, see
# <http://www.gnu.org/licenses/>.
#
from PyQt5.QtCore import pyqtSignal, QObject, QThread
class QueryResultsUpdater(QObject):
"""
Thread for processing basic queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished (int) The update has completed, with the number of results.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal(int)
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(QueryResultsUpdater, self).__init__()
self.query = query
self.model = model
def update(self):
"""Run the query and update results."""
self.model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(str(item))
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.model.resultlist = results
self.model.endResetModel()
self.finished.emit(counter)

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import RBACRuleQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..rulemodels import RBACRuleListModel
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class RBACRuleQueryTab(SEToolsWidget, QScrollArea):
@ -90,7 +91,7 @@ class RBACRuleQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -251,7 +252,9 @@ class RBACRuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} RBAC rule(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -269,52 +272,3 @@ class RBACRuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(str(item))
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} RBAC rule(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import RoleQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..rolemodel import RoleTableModel, role_detail
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class RoleQueryTab(SEToolsWidget, QScrollArea):
@ -73,7 +74,7 @@ class RoleQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -165,7 +166,9 @@ class RoleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} role(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -188,52 +191,3 @@ class RoleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(item.statement())
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} role(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import TERuleQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import PermListModel, SEToolsListModel, invert_list_selection
from ..rulemodels import TERuleListModel
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class TERuleQueryTab(SEToolsWidget, QScrollArea):
@ -98,7 +99,7 @@ class TERuleQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -390,7 +391,9 @@ class TERuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} type enforcement rule(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -413,52 +416,3 @@ class TERuleQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(str(item))
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} type enforcement rule(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import TypeAttributeQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..typeattrmodel import TypeAttributeTableModel, typeattr_detail
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class TypeAttributeQueryTab(SEToolsWidget, QScrollArea):
@ -73,7 +74,7 @@ class TypeAttributeQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -165,7 +166,9 @@ class TypeAttributeQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} attribute(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -188,52 +191,3 @@ class TypeAttributeQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(item.statement())
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} attribute(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import TypeQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..typemodel import TypeTableModel, type_detail
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class TypeQueryTab(SEToolsWidget, QScrollArea):
@ -73,7 +74,7 @@ class TypeQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -167,7 +168,9 @@ class TypeQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} type(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -192,52 +195,3 @@ class TypeQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(item.statement())
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} type(s) found.".format(counter))
self.finished.emit()

View File

@ -19,7 +19,7 @@
import logging
from PyQt5.QtCore import pyqtSignal, Qt, QObject, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QStringListModel, QThread
from PyQt5.QtGui import QPalette, QTextCursor
from PyQt5.QtWidgets import QCompleter, QHeaderView, QMessageBox, QProgressDialog, QScrollArea
from setools import UserQuery
@ -28,6 +28,7 @@ from ..logtosignal import LogHandlerToSignal
from ..models import SEToolsListModel, invert_list_selection
from ..usermodel import UserTableModel, user_detail
from ..widget import SEToolsWidget
from .queryupdater import QueryResultsUpdater
class UserQueryTab(SEToolsWidget, QScrollArea):
@ -81,7 +82,7 @@ class UserQueryTab(SEToolsWidget, QScrollArea):
# set up processing thread
self.thread = QThread()
self.worker = ResultsUpdater(self.query, self.table_results_model)
self.worker = QueryResultsUpdater(self.query, self.table_results_model)
self.worker.moveToThread(self.thread)
self.worker.raw_line.connect(self.raw_results.appendPlainText)
self.worker.finished.connect(self.update_complete)
@ -212,7 +213,9 @@ class UserQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.clear()
self.thread.start()
def update_complete(self):
def update_complete(self, count):
self.log.info("{0} user(s) found.".format(count))
# update sizes/location of result displays
if not self.busy.wasCanceled():
self.busy.setLabelText("Resizing the result table's columns; GUI may be unresponsive")
@ -230,52 +233,3 @@ class UserQueryTab(SEToolsWidget, QScrollArea):
self.raw_results.moveCursor(QTextCursor.Start)
self.busy.reset()
class ResultsUpdater(QObject):
"""
Thread for processing queries and updating result widgets.
Parameters:
query The query object
model The model for the results
Qt signals:
finished The update has completed.
raw_line (str) A string to be appended to the raw results.
"""
finished = pyqtSignal()
raw_line = pyqtSignal(str)
def __init__(self, query, model):
super(ResultsUpdater, self).__init__()
self.query = query
self.log = logging.getLogger(__name__)
self.table_results_model = model
def update(self):
"""Run the query and update results."""
self.table_results_model.beginResetModel()
results = []
counter = 0
for counter, item in enumerate(self.query.results(), start=1):
results.append(item)
self.raw_line.emit(item.statement())
if QThread.currentThread().isInterruptionRequested():
break
elif not counter % 10:
# yield execution every 10 rules
QThread.yieldCurrentThread()
self.table_results_model.resultlist = results
self.table_results_model.endResetModel()
self.log.info("{0} user(s) found.".format(counter))
self.finished.emit()