Improve logging

requirements.txt
Small UI fixes
This commit is contained in:
BasioMeusPuga
2019-01-19 22:29:56 +05:30
parent a45e183914
commit ca8ddd38a2
8 changed files with 109 additions and 45 deletions

View File

@@ -19,7 +19,6 @@
import os
import gc
import sys
import logging
import hashlib
import pathlib
@@ -30,6 +29,13 @@ install_dir = os.path.realpath(__file__)
install_dir = pathlib.Path(install_dir).parents[1]
sys.path.append(str(install_dir))
# Init logging
# Must be done first and at the module level
# or it won't work properly in case of the imports below
from lector.logger import init_logging
logger = init_logging(sys.argv)
logger.log(60, 'Application started')
from PyQt5 import QtWidgets, QtGui, QtCore
from lector import database
@@ -85,10 +91,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
Settings(self).read_settings() # This should populate all variables that need
# to be remembered across sessions
# Initialize logging
self.logger = init_logging(self.settings['log_level'])
self.logger.log(60, 'Application started')
# Initialize icon factory
self.QImageFactory = QImageFactory(self)
@@ -245,7 +247,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# Get list of available parsers
self.available_parsers = '*.' + ' *.'.join(sorter.available_parsers)
self.logger.info('Available parsers: ' + self.available_parsers)
logger.info('Available parsers: ' + self.available_parsers)
# The Library tab gets no button
self.tabWidget.tabBar().setTabButton(
@@ -412,7 +414,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
if not file_paths:
return
self.logger.info(
logger.info(
'Attempting to open: ' + ', '.join(file_paths))
contents = sorter.BookSorter(
@@ -426,7 +428,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# Notification feedback in case all books return nothing
if not contents:
self.logger.error('No parseable files found')
logger.error('No parseable files found')
return
successfully_opened = []
@@ -436,7 +438,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
file_data = contents[i]
Tab(file_data, self)
successfully_opened.append(file_data['path'])
self.logger.info(
logger.info(
'Successfully opened: ' + ', '.join(file_paths))
if self.settings['last_open_tab'] == 'library':
@@ -1038,21 +1040,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
QtWidgets.qApp.exit()
def init_logging(log_level):
location_prefix = QtCore.QStandardPaths.writableLocation(
QtCore.QStandardPaths.AppDataLocation)
os.makedirs(location_prefix, exist_ok=True)
logger_filename = os.path.join(location_prefix, 'Lector.log')
logging.basicConfig(
filename=logger_filename,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%Y/%M/%d %H:%M:%S',
level=log_level)
logging.addLevelName(60, 'HammerTime') ## Messages that MUST be logged
return logging.getLogger('lector.main')
def main():
app = QtWidgets.QApplication(sys.argv)
app.setApplicationName('Lector') # This is needed for QStandardPaths

54
lector/logger.py Normal file
View File

@@ -0,0 +1,54 @@
# This file is a part of Lector, a Qt based ebook reader
# Copyright (C) 2017-2019 BasioMeusPuga
# This program 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.
# This program 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 <http://www.gnu.org/licenses/>.
import os
import logging
from PyQt5 import QtCore
def init_logging(cli_arguments):
# This needs a separate 'Lector' in the os.path.join because
# application name isn't explicitly set in this module
location_prefix = os.path.join(
QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation),
'Lector')
os.makedirs(location_prefix, exist_ok=True)
logger_filename = os.path.join(location_prefix, 'Lector.log')
log_level = 30 # Warning and above
# Set log level according to command line arguments
try:
if cli_arguments[1] == 'debug':
log_level = 10 # Debug and above
print('Debug logging enabled')
try:
os.remove(logger_filename) # Remove old log for clarity
except FileNotFoundError:
pass
except IndexError:
pass
# Create logging object
logging.basicConfig(
filename=logger_filename,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%Y/%m/%d %H:%M:%S',
level=log_level)
logging.addLevelName(60, 'HAMMERTIME') ## Messages that MUST be logged
return logging.getLogger('lector.main')

View File

@@ -88,11 +88,6 @@ class Settings:
'currentProfileIndex', 0))
self.parent.comic_profile = self.settings.value(
'comicProfile', self.default_comic_profile)
try:
log_level = int(self.settings.value('logLevel', logging.WARNING))
except ValueError:
log_level = 30
self.parent.settings['log_level'] = log_level
self.settings.endGroup()
self.settings.beginGroup('lastOpen')
@@ -153,6 +148,8 @@ class Settings:
self.parent.settings['annotations'] = list()
self.settings.endGroup()
logger.info('Settings loaded')
def save_settings(self):
current_settings = self.parent.settings
@@ -187,7 +184,6 @@ class Settings:
current_profile3])
self.settings.setValue('currentProfileIndex', current_profile_index)
self.settings.setValue('comicProfile', self.parent.comic_profile)
self.settings.setValue('logLevel', self.parent.settings['log_level'])
self.settings.endGroup()
current_tab_index = self.parent.tabWidget.currentIndex()

View File

@@ -192,7 +192,7 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
self.main_window.generate_library_filter_menu(paths)
directory_data = {}
if not paths:
logger.warning('No paths saved for books')
logger.warning('No book paths saved')
else:
# Convert to the dictionary format that is
# to be fed into the QFileSystemModel
@@ -264,9 +264,14 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
self.database_path).set_library_paths(data_pairs)
if not data_pairs:
logger.error('Can\'t scan - No book paths saved')
try:
if self.sender().objectName() == 'reloadLibrary':
self.show()
treeViewIndex = self.listModel.index(0, 0)
self.listView.setCurrentIndex(treeViewIndex)
self.page_switch(treeViewIndex)
return
except AttributeError:
pass

View File

@@ -39,6 +39,7 @@ import pickle
import logging
import hashlib
import threading
import importlib
# The multiprocessing module does not work correctly on Windows
if sys.platform.startswith('win'):
@@ -57,26 +58,38 @@ from lector.parsers.comicbooks import ParseCOMIC
logger = logging.getLogger(__name__)
sorter = {
'epub': ParseEPUB,
'mobi': ParseMOBI,
'azw': ParseMOBI,
'azw3': ParseMOBI,
'azw4': ParseMOBI,
'prc': ParseMOBI,
'fb2': ParseFB2,
'fb2.zip': ParseFB2,
'cbz': ParseCOMIC,
'cbr': ParseCOMIC}
# The following imports are for optional dependencies
try:
# Check what dependencies are installed
# python-poppler-qt5 - Optional
poppler_check = importlib.util.find_spec('popplerqt5')
if poppler_check:
from lector.parsers.pdf import ParsePDF
sorter['pdf'] = ParsePDF
except ImportError:
error_string = 'python-poppler-qt5 is not installed. Pdf files will not work.'
else:
error_string = 'python-poppler-qt5 is not installed. Will be unable to load PDFs.'
print(error_string)
logger.error(error_string)
# python-lxml - Required for everything except comics
lxml_check = importlib.util.find_spec('lxml')
if lxml_check:
lxml_dependent = {
'epub': ParseEPUB,
'mobi': ParseMOBI,
'azw': ParseMOBI,
'azw3': ParseMOBI,
'azw4': ParseMOBI,
'prc': ParseMOBI,
'fb2': ParseFB2,
'fb2.zip': ParseFB2}
sorter.update(lxml_dependent)
else:
critical_sting = 'python-lxml is not installed. Only comics will load.'
print(critical_sting)
logger.critical(critical_sting)
available_parsers = [i for i in sorter]
progressbar = None # This is populated by __main__
progress_emitter = None # This is to be made into a global variable

View File

@@ -124,8 +124,11 @@ class BackGroundBookSearch(QtCore.QThread):
if self.valid_directories:
initiate_threads()
info_string = str(len(self.valid_files)) + ' books found'
logger.info(info_string)
if self.valid_files:
info_string = str(len(self.valid_files)) + ' books found'
logger.info(info_string)
else:
logger.error('No books found on scan')
else:
logger.error('No valid directories')

View File

@@ -407,6 +407,7 @@ class LibraryToolBar(QtWidgets.QToolBar):
image_factory.get_image('reload'),
self._translate('LibraryToolBar', 'Scan Library'),
self)
self.reloadLibraryButton.setObjectName('reloadLibrary')
self.libraryFilterButton = QtWidgets.QToolButton(self)
self.libraryFilterButton.setIcon(image_factory.get_image('view-readermode'))

5
requirements.txt Normal file
View File

@@ -0,0 +1,5 @@
beautifulsoup4==4.7.1
lxml==4.3.0
PyQt5==5.11.3
PyQt5-sip==4.19.13
soupsieve==1.7.2