diff --git a/filterwidget.py b/filterwidget.py index 3952922..2db114b 100644 --- a/filterwidget.py +++ b/filterwidget.py @@ -1,13 +1,53 @@ +import multiprocessing +import os +import tempfile +import time +from typing import Optional + +from PyQt6.QtCore import QRunnable, QThread, QThreadPool from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QCheckBox from bigtext import BigText from logFileModel import LogFileModel +import asyncio +class FilterTask(QRunnable): + + aborted = False + future : asyncio.Future + + def __init__(self, source_model: LogFileModel, filter_model: LogFileModel, query: str): + super(FilterTask, self).__init__() + self.source_model = source_model + self.filter_model = filter_model + self.query = query + self.future = asyncio.Future() + + def run(self): + #print("writing to tmp file", self.filter_model.get_file()) + start = time.time() + self.filter_model.truncate() + with open(self.source_model.get_file(), "rb") as source: + while l := source.readline(): + line = l.decode("utf8", errors="ignore") + #print(line) + if line.find(self.query) >= 0: + self.filter_model.write_line(line) + + if self.aborted or self.future.cancelled(): + print("aborted") + break + print("filtering for %s took %s" % (self.query, time.time() - start) ) + self.future.done() class FilterWidget(QWidget): - def __init__(self, model: LogFileModel): + future = None + filter_model : LogFileModel + filter_task :Optional[FilterTask] = None + + def __init__(self, source_model: LogFileModel): super(FilterWidget, self).__init__() - self.model = model + self.source_model = source_model self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) @@ -23,15 +63,33 @@ class FilterWidget(QWidget): filter_bar = QWidget() filter_bar.layout = QHBoxLayout(filter_bar) - filter_bar.layout.setContentsMargins(0,0,0,0) + filter_bar.layout.setContentsMargins(0, 0, 0, 0) filter_bar.layout.addWidget(query_field) filter_bar.layout.addWidget(ignore_case) filter_bar.layout.addWidget(is_regex) - self.hits_view = BigText(model) + (_handle, self.tmpfilename) = tempfile.mkstemp() + self.filter_model = LogFileModel(self.tmpfilename, self.source_model.settings) + self.hits_view = BigText(self.filter_model) self.layout.addWidget(filter_bar) self.layout.addWidget(self.hits_view) def query_changed(self, query: str): - print(query) \ No newline at end of file + if len(query) == 0: + return + + print("start function") + if self.filter_task: + print("abort started ", time.time()) + self.filter_task.aborted = True + print("abort done ", time.time()) + + self.filter_task = FilterTask(self.source_model, self.filter_model, query) + # QThreadPool takes ownership and deletes 'hello' automatically + QThreadPool.globalInstance().start(self.filter_task) + + + + + diff --git a/logFileModel.py b/logFileModel.py index 7947d99..b3ae4fe 100644 --- a/logFileModel.py +++ b/logFileModel.py @@ -74,4 +74,15 @@ class LogFileModel: return result def byte_count(self) -> int: - return os.stat(self._file).st_size \ No newline at end of file + return os.stat(self._file).st_size + + def write_line(self, line: str): + with open(self._file, 'a+b') as f: + f.write(line.encode("utf8")) + if not line.endswith("\n"): + f.write("\n".encode("utf8")) + + def truncate(self): + with open(self._file, 'a') as f: + print("truncating") + f.truncate(0) \ No newline at end of file