From 1d8cd3dce5e0dda47da5117dd685fa28e529ebb6 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 27 Oct 2021 08:44:20 +0200 Subject: [PATCH] support ignore case and regex filters --- filterwidget.py | 83 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/filterwidget.py b/filterwidget.py index 2db114b..a01f3d4 100644 --- a/filterwidget.py +++ b/filterwidget.py @@ -1,5 +1,7 @@ import multiprocessing import os +import re +from re import Pattern import tempfile import time from typing import Optional @@ -16,28 +18,43 @@ class FilterTask(QRunnable): aborted = False future : asyncio.Future - def __init__(self, source_model: LogFileModel, filter_model: LogFileModel, query: str): + def __init__( + self, + source_model: LogFileModel, + filter_model: LogFileModel, + regex: re.Pattern + ): super(FilterTask, self).__init__() self.source_model = source_model self.filter_model = filter_model - self.query = query + self.regex = regex + #self.query = query.lower() if ignore_case and not is_regex else query + #self.ignore_case = ignore_case + #self.is_regex = is_regex self.future = asyncio.Future() + #flags = re.IGNORECASE if ignore_case else 0 + + #if is_regex: + # self.regex = re.compile(query, flags=flags) + #else: + # self.regex = re.compile(re.escape(query),flags=flags) + 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) + with open(self.filter_model.get_file(), "w+b") as target: + while l := source.readline(): + line = l.decode("utf8", errors="ignore") - if self.aborted or self.future.cancelled(): - print("aborted") - break - print("filtering for %s took %s" % (self.query, time.time() - start) ) + if self.regex.findall(line): + target.write(line.encode("utf8")) + + if self.aborted or self.future.cancelled(): + print("aborted") + break + print("filtering for %s took %s" % (self.regex, time.time() - start) ) self.future.done() class FilterWidget(QWidget): @@ -52,21 +69,23 @@ class FilterWidget(QWidget): self.layout = QVBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) - query_field = QLineEdit() - query_field.textChanged.connect(self.query_changed) + self.query_field = QLineEdit() + self.query_field.textChanged.connect(self.filter_changed) - ignore_case = QCheckBox(self.tr("ignore case")) - ignore_case.setChecked(True) + self.ignore_case = QCheckBox(self.tr("ignore case")) + self.ignore_case.setChecked(True) + self.ignore_case.stateChanged.connect(self.filter_changed) - is_regex = QCheckBox(self.tr("regex")) - is_regex.setChecked(True) + self.is_regex = QCheckBox(self.tr("regex")) + self.is_regex.setChecked(True) + self.is_regex.stateChanged.connect(self.filter_changed) 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) + filter_bar.layout.addWidget(self.query_field) + filter_bar.layout.addWidget(self.ignore_case) + filter_bar.layout.addWidget(self.is_regex) (_handle, self.tmpfilename) = tempfile.mkstemp() self.filter_model = LogFileModel(self.tmpfilename, self.source_model.settings) @@ -75,21 +94,31 @@ class FilterWidget(QWidget): self.layout.addWidget(filter_bar) self.layout.addWidget(self.hits_view) - def query_changed(self, query: str): + def filter_changed(self): + query = self.query_field.text() + ignore_case = self.ignore_case.isChecked() + is_regex = self.is_regex.isChecked() 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 + try: + flags = re.IGNORECASE if ignore_case else 0 + if is_regex: + regex = re.compile(query, flags=flags) + else: + regex = re.compile(re.escape(query), flags=flags) + except: + # query was not a valid regex -> abort + return + + self.filter_task = FilterTask(self.source_model, self.filter_model, regex) QThreadPool.globalInstance().start(self.filter_task) +