move the log file viewer to its own plugin
We plan to have multiple different types of tabs.
This commit is contained in:
@@ -5,12 +5,14 @@ from bigtext import BigText
|
|||||||
from filterviewsyncer import FilterViewSyncer
|
from filterviewsyncer import FilterViewSyncer
|
||||||
from filterwidget import FilterWidget
|
from filterwidget import FilterWidget
|
||||||
from logFileModel import LogFileModel
|
from logFileModel import LogFileModel
|
||||||
|
from raven.plugins.ravenlog.Tab import Tab
|
||||||
|
from conversion import humanbytes
|
||||||
|
|
||||||
|
|
||||||
class FullTabWidget(QWidget):
|
class FullTabWidget(Tab):
|
||||||
|
|
||||||
def __init__(self, model: LogFileModel):
|
def __init__(self, model: LogFileModel, unique_id: str, title: str):
|
||||||
super(FullTabWidget, self).__init__()
|
super(FullTabWidget, self).__init__(unique_id, title)
|
||||||
self._model = model
|
self._model = model
|
||||||
self.file_view = BigText(model)
|
self.file_view = BigText(model)
|
||||||
self.filter_hit_view = FilterWidget(self._model)
|
self.filter_hit_view = FilterWidget(self._model)
|
||||||
@@ -33,6 +35,13 @@ class FullTabWidget(QWidget):
|
|||||||
def get_file(self) -> str:
|
def get_file(self) -> str:
|
||||||
return self.file_view.get_file()
|
return self.file_view.get_file()
|
||||||
|
|
||||||
|
# overriding abstract method
|
||||||
def destruct(self):
|
def destruct(self):
|
||||||
self.file_view.destruct()
|
self.file_view.destruct()
|
||||||
self.filter_hit_view.destruct()
|
self.filter_hit_view.destruct()
|
||||||
|
|
||||||
|
# overriding abstract method
|
||||||
|
def get_status_text(self) -> str:
|
||||||
|
file = self._model.get_file()
|
||||||
|
file_size = humanbytes(self._model.byte_count())
|
||||||
|
return "%s - %s" % (file_size, file)
|
||||||
|
|||||||
3
main.py
3
main.py
@@ -53,8 +53,9 @@ if __name__ == "__main__":
|
|||||||
# init plugins
|
# init plugins
|
||||||
PluginRegistry.load_plugin("RavenLogPlugin")
|
PluginRegistry.load_plugin("RavenLogPlugin")
|
||||||
PluginRegistry.load_plugin("OpenFilePlugin")
|
PluginRegistry.load_plugin("OpenFilePlugin")
|
||||||
|
PluginRegistry.load_plugin("LogFilePlugin")
|
||||||
|
|
||||||
window = PluginRegistry.executeSingle("create_main_window")
|
window = PluginRegistry.execute_single("create_main_window")
|
||||||
RavenUI.window = window
|
RavenUI.window = window
|
||||||
window.show()
|
window.show()
|
||||||
# window.open_file("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv")
|
# window.open_file("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv")
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import Dict
|
from typing import Dict, Optional
|
||||||
from inspect import isclass
|
from inspect import isclass
|
||||||
from pkgutil import iter_modules
|
from pkgutil import iter_modules
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -46,11 +46,11 @@ class PluginRegistry():
|
|||||||
return PluginRegistry.modules.copy()
|
return PluginRegistry.modules.copy()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def executeSingle(function_name: str, *args):
|
def execute_single(function_name: str, *args) -> Optional[any]:
|
||||||
return PluginRegistry._execute(function_name, True, *args)
|
return PluginRegistry._execute(function_name, True, *args)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def execute(function_name: str, *args) -> []:
|
def execute(function_name: str, *args) -> [any]:
|
||||||
return PluginRegistry._execute(function_name, False, *args)
|
return PluginRegistry._execute(function_name, False, *args)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|||||||
38
raven/plugins/logfileplugin.py
Normal file
38
raven/plugins/logfileplugin.py
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import os.path
|
||||||
|
from typing import Callable, Optional
|
||||||
|
|
||||||
|
from PyQt6.QtWidgets import QMessageBox
|
||||||
|
|
||||||
|
from fulltabwidget import FullTabWidget
|
||||||
|
from logFileModel import LogFileModel
|
||||||
|
from raven.pluginbase import PluginBase
|
||||||
|
from raven.plugins.ravenlog.Tab import Tab
|
||||||
|
from settings import Settings
|
||||||
|
|
||||||
|
|
||||||
|
class LogFilePlugin(PluginBase):
|
||||||
|
def __init__(self):
|
||||||
|
super(LogFilePlugin, self).__init__()
|
||||||
|
self.settings = None
|
||||||
|
self.tr = None
|
||||||
|
|
||||||
|
def set_settings(self, settings: Settings):
|
||||||
|
self.settings = settings
|
||||||
|
|
||||||
|
def set_translator(self, tr: Callable[[str], str]):
|
||||||
|
self.tr = tr
|
||||||
|
|
||||||
|
def create_tab(self, file: str) -> Optional[Tab]:
|
||||||
|
if not os.path.isfile(file):
|
||||||
|
message = QMessageBox(QMessageBox.Icon.Warning, "File not found",
|
||||||
|
"'%s' is not a file or cannot be opened" % file)
|
||||||
|
message.exec()
|
||||||
|
return None
|
||||||
|
|
||||||
|
realpath = os.path.realpath(file)
|
||||||
|
filename = os.path.basename(realpath)
|
||||||
|
|
||||||
|
model = LogFileModel(file, self.settings)
|
||||||
|
tab = FullTabWidget(model, unique_id=realpath, title=filename)
|
||||||
|
|
||||||
|
return tab
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
from pathlib import Path
|
||||||
from PyQt6.QtGui import QAction, QIcon
|
from PyQt6.QtGui import QAction, QIcon
|
||||||
from PyQt6.QtWidgets import QMenu, QFileDialog
|
from PyQt6.QtWidgets import QMenu, QFileDialog
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ class OpenFilePlugin(PluginBase):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def _open_file_dialog(self) -> None:
|
def _open_file_dialog(self) -> None:
|
||||||
current_file = PluginRegistry.executeSingle("current_file")
|
current_file = PluginRegistry.execute_single("current_file")
|
||||||
directory = os.path.dirname(current_file) if current_file else ''
|
directory = os.path.dirname(current_file) if current_file else os.path.join(Path.home())
|
||||||
|
|
||||||
dialog = QFileDialog()
|
dialog = QFileDialog()
|
||||||
(selected_file, _filter) = dialog.getOpenFileName(
|
(selected_file, _filter) = dialog.getOpenFileName(
|
||||||
@@ -53,12 +53,14 @@ class OpenFilePlugin(PluginBase):
|
|||||||
self._open_file(selected_file)
|
self._open_file(selected_file)
|
||||||
|
|
||||||
def _open_file(self, selected_file: str):
|
def _open_file(self, selected_file: str):
|
||||||
PluginRegistry.executeSingle("create_tab", selected_file)
|
tab = PluginRegistry.execute_single("create_tab", selected_file)
|
||||||
self._remember_recent_file(selected_file)
|
if tab:
|
||||||
|
PluginRegistry.execute_single("add_tab", tab)
|
||||||
|
PluginRegistry.execute("after_open_file", selected_file)
|
||||||
|
|
||||||
def _get_recent_files(self) -> [str]:
|
def _get_recent_files(self) -> [str]:
|
||||||
recent_files = self.settings.session.get('general', 'recent_files', fallback='')
|
recent_files = self.settings.session.get('general', 'recent_files', fallback='')
|
||||||
print(recent_files)
|
# print(recent_files)
|
||||||
files = recent_files.split(os.pathsep)
|
files = recent_files.split(os.pathsep)
|
||||||
if "" in files:
|
if "" in files:
|
||||||
files.remove("")
|
files.remove("")
|
||||||
|
|||||||
23
raven/plugins/ravenlog/Tab.py
Normal file
23
raven/plugins/ravenlog/Tab.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from PyQt6.QtWidgets import QWidget
|
||||||
|
|
||||||
|
|
||||||
|
class Tab(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, unique_id: str, title: str):
|
||||||
|
super(Tab, self).__init__()
|
||||||
|
self.unique_id = unique_id
|
||||||
|
self.title = title
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_status_text(self) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def get_file(self) -> str:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def destruct(self):
|
||||||
|
pass
|
||||||
0
raven/plugins/ravenlog/__init__.py
Normal file
0
raven/plugins/ravenlog/__init__.py
Normal file
@@ -8,6 +8,7 @@ from raven.pluginbase import PluginBase
|
|||||||
from raven.pluginregistry import PluginRegistry
|
from raven.pluginregistry import PluginRegistry
|
||||||
from raven.plugins.domain.menucontribution import MenuContribution
|
from raven.plugins.domain.menucontribution import MenuContribution
|
||||||
from raven.plugins.domain.raction import RAction
|
from raven.plugins.domain.raction import RAction
|
||||||
|
from raven.plugins.ravenlog.Tab import Tab
|
||||||
|
|
||||||
|
|
||||||
class RavenLogPlugin(PluginBase):
|
class RavenLogPlugin(PluginBase):
|
||||||
@@ -29,9 +30,8 @@ class RavenLogPlugin(PluginBase):
|
|||||||
def current_file(self) -> Optional[str]:
|
def current_file(self) -> Optional[str]:
|
||||||
return self.main_window.tabs.current_file()
|
return self.main_window.tabs.current_file()
|
||||||
|
|
||||||
def create_tab(self, file: str):
|
def add_tab(self, tab: Tab):
|
||||||
self.main_window.tabs.create_tab(file)
|
self.main_window.tabs.add_tab(tab)
|
||||||
PluginRegistry.execute("after_open_file", file)
|
|
||||||
|
|
||||||
def _action_about(self) -> RAction:
|
def _action_about(self) -> RAction:
|
||||||
about_action = RAction(
|
about_action = RAction(
|
||||||
|
|||||||
53
tabs.py
53
tabs.py
@@ -6,16 +6,14 @@ from PyQt6.QtCore import *
|
|||||||
from PyQt6.QtGui import *
|
from PyQt6.QtGui import *
|
||||||
|
|
||||||
from bigtext import BigText
|
from bigtext import BigText
|
||||||
from conversion import humanbytes
|
|
||||||
from fulltabwidget import FullTabWidget
|
from fulltabwidget import FullTabWidget
|
||||||
from logFileModel import LogFileModel
|
from logFileModel import LogFileModel
|
||||||
|
from raven.plugins.ravenlog.Tab import Tab
|
||||||
from ravenui import RavenUI
|
from ravenui import RavenUI
|
||||||
from settings import Settings
|
from settings import Settings
|
||||||
|
|
||||||
|
|
||||||
class Tabs(QWidget):
|
class Tabs(QWidget):
|
||||||
tabs_by_filename = {}
|
|
||||||
|
|
||||||
def __init__(self, settings: Settings):
|
def __init__(self, settings: Settings):
|
||||||
super(Tabs, self).__init__()
|
super(Tabs, self).__init__()
|
||||||
|
|
||||||
@@ -32,46 +30,29 @@ class Tabs(QWidget):
|
|||||||
|
|
||||||
self.layout.addWidget(self.tabs)
|
self.layout.addWidget(self.tabs)
|
||||||
|
|
||||||
def create_tab(self, file: str):
|
def add_tab(self, tab: Tab):
|
||||||
if not os.path.isfile(file):
|
# if tab already exists then open it
|
||||||
message = QMessageBox(QMessageBox.Icon.Warning, "File not found",
|
for tab_index in range(0, self.tabs.count()):
|
||||||
"'%s' is not a file or cannot be opened" % (file))
|
widget: Tab = self.tabs.widget(tab_index)
|
||||||
message.exec()
|
if widget.unique_id == tab.unique_id:
|
||||||
return
|
self.tabs.setCurrentIndex(tab_index)
|
||||||
|
return
|
||||||
|
|
||||||
model = LogFileModel(file, self.settings)
|
tab_index = self.tabs.addTab(tab, tab.title)
|
||||||
full_tab = FullTabWidget(model)
|
self.tabs.setCurrentIndex(tab_index)
|
||||||
|
|
||||||
if model.get_file() in self.tabs_by_filename:
|
|
||||||
for tab_index in range(0, self.tabs.count()):
|
|
||||||
widget: FullTabWidget = self.tabs.widget(tab_index)
|
|
||||||
if widget.get_file() == model.get_file():
|
|
||||||
self.tabs.setCurrentIndex(tab_index)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
tab_index = self.tabs.addTab(full_tab, model.get_tab_name())
|
|
||||||
self.tabs_by_filename[model.get_file()] = full_tab
|
|
||||||
self.tabs.setCurrentIndex(tab_index)
|
|
||||||
|
|
||||||
def _current_tab_changed(self, tab_index: int):
|
def _current_tab_changed(self, tab_index: int):
|
||||||
full_tab: FullTabWidget = self.tabs.widget(tab_index)
|
tab: Tab = self.tabs.widget(tab_index)
|
||||||
if full_tab:
|
if tab:
|
||||||
# window title
|
RavenUI.update_window_title(tab.title)
|
||||||
file = full_tab.file_view.get_file()
|
RavenUI.update_status_bar(tab.get_status_text())
|
||||||
file_name = os.path.basename(file)
|
|
||||||
RavenUI.update_window_title(file_name)
|
|
||||||
|
|
||||||
# status bar text
|
|
||||||
status_text = "%s - %s" % (humanbytes(full_tab.file_view.model.byte_count()), file)
|
|
||||||
RavenUI.update_status_bar(status_text)
|
|
||||||
else:
|
else:
|
||||||
RavenUI.update_window_title("")
|
RavenUI.update_window_title("")
|
||||||
RavenUI.update_status_bar("")
|
RavenUI.update_status_bar("")
|
||||||
|
|
||||||
def _close_tab(self, tab_index: int):
|
def _close_tab(self, tab_index: int):
|
||||||
full_tab: FullTabWidget = self.tabs.widget(tab_index)
|
full_tab: Tab = self.tabs.widget(tab_index)
|
||||||
full_tab.destruct()
|
full_tab.destruct()
|
||||||
del self.tabs_by_filename[full_tab.file_view.get_file()]
|
|
||||||
self.tabs.removeTab(tab_index)
|
self.tabs.removeTab(tab_index)
|
||||||
|
|
||||||
def destruct(self):
|
def destruct(self):
|
||||||
@@ -85,5 +66,5 @@ class Tabs(QWidget):
|
|||||||
if self.tabs.currentIndex() < 0:
|
if self.tabs.currentIndex() < 0:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
full_tab: FullTabWidget = self.tabs.widget(self.tabs.currentIndex())
|
tab: Tab = self.tabs.widget(self.tabs.currentIndex())
|
||||||
return full_tab.get_file()
|
return tab.get_file()
|
||||||
|
|||||||
Reference in New Issue
Block a user