Skip to content

Commit

Permalink
Support basic logging, closes #1299
Browse files Browse the repository at this point in the history
  • Loading branch information
zkovari committed Sep 11, 2024
1 parent 4b2ca95 commit a9886ba
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/main/python/plotlyst/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging

from plotlyst.service.log import setup_logging

try:
import argparse
Expand Down Expand Up @@ -89,8 +92,11 @@ def dialog_exception_handler(self):
args = parser.parse_args()
app_env.mode = args.mode

setup_logging()

if platform.is_linux():
font = QFont('Helvetica', max(QApplication.font().pointSize(), 12))
logging.info(f'Linux OS was detected. Set font to Helvetica, {font.pointSize()}pt')
QApplication.setFont(font)
elif QApplication.font().pointSize() < 12:
font = QApplication.font()
Expand Down
87 changes: 87 additions & 0 deletions src/main/python/plotlyst/model/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"""
Plotlyst
Copyright (C) 2021-2024 Zsolt Kovari
This file is part of Plotlyst.
Plotlyst is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plotlyst is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
from logging import LogRecord

from PyQt6.QtCore import QAbstractTableModel, Qt
from overrides import overrides

from plotlyst.common import RED_COLOR
from plotlyst.view.icons import IconRegistry


class LogTableModel(QAbstractTableModel):
def __init__(self):
super().__init__()
self.log_records = []
self.max_logs = 1000
self.errorIcon = IconRegistry.from_name('msc.error', RED_COLOR)
self.warningIcon = IconRegistry.from_name('msc.warning', '#e9c46a')
self.infoIcon = IconRegistry.from_name('msc.info')

@overrides
def rowCount(self, parent=None):
return len(self.log_records)

@overrides
def columnCount(self, parent=None):
return 2

@overrides
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.ItemDataRole.ToolTipRole:
row = index.row()
col = index.column()
log_record = self.log_records[row]

if col == 1:
return log_record.msg
elif col == 2:
return log_record.asctime
if role == Qt.ItemDataRole.DecorationRole and index.column() == 0:
log_record = self.log_records[index.row()]
if log_record.levelname == 'INFO':
return self.infoIcon
elif log_record.levelname == 'WARNING':
return self.warningIcon
elif log_record.levelname == 'ERROR':
return self.errorIcon

def addLogRecord(self, log_record: LogRecord):
if len(self.log_records) >= self.max_logs:
self.beginRemoveRows(self.index(0, 0), 0, 0)
self.log_records.pop(0) # Remove the oldest log (at the front of the list)
self.endRemoveRows()

# Add the new log record at the end
self.beginInsertRows(self.index(self.rowCount(), 0), self.rowCount(), self.rowCount())
self.log_records.append(log_record)
self.endInsertRows()

@overrides
def headerData(self, section, orientation, role=Qt.ItemDataRole.DisplayRole):
if role == Qt.ItemDataRole.DisplayRole:
if orientation == Qt.Orientation.Horizontal:
if section == 0:
return ""
elif section == 1:
return "Message"
elif section == 2:
return "Timestamp"
return None
3 changes: 3 additions & 0 deletions src/main/python/plotlyst/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
import os
from dataclasses import dataclass, field
from datetime import date
Expand Down Expand Up @@ -63,6 +64,8 @@ def __get_resource(self, name: str):
if app_env.is_windows():
resource_url = resource_url.replace('\\', '/')

logging.info(f'Local resource ({name}) was found: {resource_url}')

return resource_url

@property
Expand Down
46 changes: 46 additions & 0 deletions src/main/python/plotlyst/service/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""
Plotlyst
Copyright (C) 2021-2024 Zsolt Kovari
This file is part of Plotlyst.
Plotlyst is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plotlyst is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging

from overrides import overrides

from plotlyst.model.log import LogTableModel


class LogHandler(logging.Handler):
def __init__(self, model: LogTableModel):
super().__init__()
self.model = model
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
self.setFormatter(formatter)

@overrides
def emit(self, record):
self.format(record)
self.model.addLogRecord(record)


def setup_logging():
logger = logging.getLogger()
logger.setLevel(logging.INFO)

model = LogTableModel()
log_handler = LogHandler(model)
logger.addHandler(log_handler)
3 changes: 2 additions & 1 deletion src/main/python/plotlyst/view/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@
from plotlyst.view.characters_view import CharactersView
from plotlyst.view.comments_view import CommentsView
from plotlyst.view.common import TooltipPositionEventFilter, ButtonPressResizeEventFilter
from plotlyst.view.dialog.about import AboutDialog
from plotlyst.view.dialog.manuscript import ManuscriptPreviewDialog
from plotlyst.view.docs_view import DocumentsView
from plotlyst.view.generated.main_window_ui import Ui_MainWindow
Expand All @@ -71,6 +70,7 @@
from plotlyst.view.scenes_view import ScenesOutlineView
from plotlyst.view.widget.button import ToolbarButton, NovelSyncButton
from plotlyst.view.widget.input import CapitalizationEventFilter
from plotlyst.view.widget.log import LogsPopup
from plotlyst.view.widget.settings import NovelQuickPanelCustomizationButton
from plotlyst.view.widget.tour.core import TutorialNovelOpenTourEvent, tutorial_novel, \
TutorialNovelCloseTourEvent, NovelTopLevelButtonTourEvent, HomeTopLevelButtonTourEvent, NovelEditorDisplayTourEvent, \
Expand Down Expand Up @@ -449,6 +449,7 @@ def _init_menubar(self):

self.actionAbout.setVisible(False)
# self.actionAbout.triggered.connect(lambda: AboutDialog.popup())
self.actionLogs.triggered.connect(lambda: LogsPopup.popup())
self.actionPreview.triggered.connect(lambda: ManuscriptPreviewDialog().display(app_env.novel))
self.actionCut.setIcon(IconRegistry.cut_icon())
self.actionCut.triggered.connect(self._cut_text)
Expand Down
52 changes: 52 additions & 0 deletions src/main/python/plotlyst/view/widget/log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""
Plotlyst
Copyright (C) 2021-2024 Zsolt Kovari
This file is part of Plotlyst.
Plotlyst is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Plotlyst is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging

from PyQt6.QtCore import Qt
from PyQt6.QtWidgets import QTableView

from plotlyst.service.log import LogHandler
from plotlyst.view.common import stretch_col
from plotlyst.view.widget.display import PopupDialog


class LogsPopup(PopupDialog):
def __init__(self, parent=None):
super().__init__(parent)

self.tblView = QTableView()
self.tblView.setWordWrap(True)
self.tblView.setMinimumSize(700, 400)

logger = logging.getLogger()
for handler in logger.handlers:
if isinstance(handler, LogHandler):
self.tblView.setModel(handler.model)
break

stretch_col(self.tblView, 1)
self.tblView.setColumnWidth(0, 30)
self.tblView.setColumnWidth(2, 200)

self.frame.layout().addWidget(self.btnReset, alignment=Qt.AlignmentFlag.AlignRight)
self.frame.layout().addWidget(self.tblView)

def display(self):
self.exec()
6 changes: 6 additions & 0 deletions ui/main_window.ui
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,7 @@
</property>
<addaction name="separator"/>
<addaction name="actionAbout"/>
<addaction name="actionLogs"/>
</widget>
<widget class="QMenu" name="menuEdit">
<property name="title">
Expand Down Expand Up @@ -1050,6 +1051,11 @@
<string>Display quick panel customization in the toolbar</string>
</property>
</action>
<action name="actionLogs">
<property name="text">
<string>Logs</string>
</property>
</action>
</widget>
<resources/>
<connections/>
Expand Down

0 comments on commit a9886ba

Please sign in to comment.