diff --git a/bigtext.py b/bigtext.py index a000274..30dd0ce 100644 --- a/bigtext.py +++ b/bigtext.py @@ -1,5 +1,7 @@ import math +import os import re +import time from typing import Optional, List import PyQt6.QtGui from PyQt6 import QtGui @@ -18,13 +20,60 @@ from logFileModel import LogFileModel import re from settings import Settings +from watchdog.observers import Observer +from watchdog.events import FileSystemEventHandler +import threading + + +class FileObserver(FileSystemEventHandler): + counter = 0 + def __init__(self, big_text): + super(FileObserver, self).__init__() + self.big_text = big_text + + def on_modified(self, event): + #print("file modified ", self.counter," ", time.time()) + self.counter+=1 + time.sleep(0.5) + self.big_text.update() + + +class FileWatchdogThread(QRunnable): + + observer = None + + def __init__(self, big_text, file: str): + super(FileWatchdogThread, self).__init__() + self.file = file + self.big_text = big_text + + def run(self) -> None: + print("observer started for file ", self.file) + if self.observer: + print("observer already exists") + self.observer = Observer() + self.observer.schedule(FileObserver(self.big_text), self.file) + self.observer.start() + + def destruct(self): + self.observer.stop() + try: + self.observer.join() + except: + # probably: RuntimeError: cannot join thread before it is started + pass class BigText(QWidget): + def __init__(self, model: LogFileModel): super(BigText, self).__init__() self.model = model + + self.watchdog = FileWatchdogThread(self, model.get_file()) + QThreadPool.globalInstance().start(self.watchdog) + self.grid = QGridLayout() self.grid.setContentsMargins(0, 0, 0, 0) self.grid.setHorizontalSpacing(0) @@ -51,7 +100,7 @@ class BigText(QWidget): return self.model.get_file() def destruct(self): - pass + self.watchdog.destruct() class InnerBigText(QWidget): @@ -82,7 +131,7 @@ class InnerBigText(QWidget): def keyPressEvent(self, e: QKeyEvent) -> None: - #print("%s + %s" % (e.keyCombination().keyboardModifiers(), e.key())) + # print("%s + %s" % (e.keyCombination().keyboardModifiers(), e.key())) if e.modifiers() == Qt.KeyboardModifier.NoModifier: lines_to_scroll = math.floor(self.lines_shown()) - 1 if e.key() == Qt.Key.Key_PageUp: @@ -186,6 +235,7 @@ class InnerBigText(QWidget): cb.setText(selected_text) def paintEvent(self, event: QPaintEvent) -> None: + #print("paintEvent") painter = QPainter(self) painter.setFont(self.model.settings.font()) painter.setPen(QColor(0, 0, 0)) diff --git a/filterwidget.py b/filterwidget.py index 2a1a833..8c1df33 100644 --- a/filterwidget.py +++ b/filterwidget.py @@ -1,12 +1,10 @@ -import multiprocessing import os import re -from re import Pattern import tempfile import time from typing import Optional -from PyQt6.QtCore import QRunnable, QThread, QThreadPool +from PyQt6.QtCore import QRunnable, QThreadPool from PyQt6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QCheckBox from bigtext import BigText @@ -14,9 +12,8 @@ from logFileModel import LogFileModel import asyncio class FilterTask(QRunnable): - aborted = False - future : asyncio.Future + future: asyncio.Future def __init__( self, @@ -28,20 +25,10 @@ class FilterTask(QRunnable): self.source_model = source_model self.filter_model = filter_model 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()) + # print("writing to tmp file", self.filter_model.get_file()) start = time.time() with open(self.source_model.get_file(), "rb") as source: with open(self.filter_model.get_file(), "w+b") as target: @@ -54,13 +41,14 @@ class FilterTask(QRunnable): if self.aborted or self.future.cancelled(): print("aborted") break - print("filtering for %s took %s" % (self.regex, time.time() - start) ) + #print("filtering for %s took %s" % (self.regex, time.time() - start)) self.future.done() + class FilterWidget(QWidget): future = None - filter_model : LogFileModel - filter_task :Optional[FilterTask] = None + filter_model: LogFileModel + filter_task: Optional[FilterTask] = None def __init__(self, source_model: LogFileModel): super(FilterWidget, self).__init__() @@ -120,9 +108,3 @@ class FilterWidget(QWidget): self.filter_task = FilterTask(self.source_model, self.filter_model, regex) QThreadPool.globalInstance().start(self.filter_task) - - - - - - diff --git a/main.py b/main.py index 66ff1d3..e1cd02b 100644 --- a/main.py +++ b/main.py @@ -95,7 +95,7 @@ def stop_signal(signum, _stackframe): log.info("Terminate signal received. %s", signum) QtCore.QCoreApplication.quit() except Exception: - log.exception("Exception occured while terminating") + log.exception("Exception occurred while terminating") sys.exit(1) sys.exit(0) diff --git a/requirements.txt b/requirements.txt index ad9f1f0..0441a57 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ PyQt6-Qt6==6.2.0 PyQt6-sip==13.1.0 six==1.16.0 urllib3==1.26.7 +watchdog==2.1.6 \ No newline at end of file