Files
krowlog/filterwidget.py

96 lines
3.0 KiB
Python

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):
future = None
filter_model : LogFileModel
filter_task :Optional[FilterTask] = None
def __init__(self, source_model: LogFileModel):
super(FilterWidget, self).__init__()
self.source_model = source_model
self.layout = QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0)
query_field = QLineEdit()
query_field.textChanged.connect(self.query_changed)
ignore_case = QCheckBox(self.tr("ignore case"))
ignore_case.setChecked(True)
is_regex = QCheckBox(self.tr("regex"))
is_regex.setChecked(True)
filter_bar = QWidget()
filter_bar.layout = QHBoxLayout(filter_bar)
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)
(_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):
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)