Update readme

Begin logging
Account for fb2 books without covers
This commit is contained in:
BasioMeusPuga
2019-01-19 01:19:58 +05:30
parent 5e3987dc04
commit 506c458544
25 changed files with 138 additions and 27 deletions

View File

@@ -10,19 +10,30 @@ Currently supports:
* azw / azw3 / azw4 * azw / azw3 / azw4
* cbr / cbz * cbr / cbz
Support for a bunch of other formats is coming. Please see the TODO for additional information. ## Donate to support development
Bitcoin: 17jaxj26vFJNqQ2hEVerbBV5fpTusfqFro
## Requirements ## Requirements
### Needed
| Package | Version tested | | Package | Version tested |
| --- | --- | | --- | --- |
| Qt5 | 5.10.1 | | Qt5 | 5.10.1 |
| Python | 3.6 | | Python | 3.6 |
| PyQt5 | 5.10.1 | | PyQt5 | 5.10.1 |
| python-lxml | 4.3.0 |
| python-beautifulsoup4 | 4.6.0 | | python-beautifulsoup4 | 4.6.0 |
### Optional
| Package | Version tested |
| --- | --- |
| poppler-qt5 | 0.61.1 | | poppler-qt5 | 0.61.1 |
| python-poppler-qt5 | 0.24.2 | | python-poppler-qt5 | 0.24.2 |
poppler-qt5 and python-poppler-qt5 are optional. ## Support
When reporting issues:
* Include the log `~/.local/share/Lector/Lector.log` AND terminal output.
* If you're having trouble with a book while the rest of the application / other books work, please link to a copy of the book itself.
* If nothing is working, please make sure the requirements mentioned above are all installed, and are at least at the version mentioned.
## Installation ## Installation
### Manual ### Manual
@@ -85,12 +96,6 @@ Please keep the translations short. There's only so much space for UI elements.
### Settings window ### Settings window
![alt tag](https://i.imgur.com/l6zJXaH.png) ![alt tag](https://i.imgur.com/l6zJXaH.png)
## Reporting issues
When reporting issues:
* If you're having trouble with a book while the rest of the application / other books work, please link to a copy of the book itself.
* If nothing is working, please make sure the requirements mentioned above are all installed, and are at least at the version mentioned.
## Attributions ## Attributions
* [KindleUnpack](https://github.com/kevinhendricks/KindleUnpack) * [KindleUnpack](https://github.com/kevinhendricks/KindleUnpack)
* [rarfile](https://github.com/markokr/rarfile) * [rarfile](https://github.com/markokr/rarfile)

View File

@@ -19,9 +19,12 @@
import os import os
import gc import gc
import sys import sys
import logging
import hashlib import hashlib
import pathlib import pathlib
from PyQt5 import QtWidgets, QtGui, QtCore
# This allows for the program to be launched from the # This allows for the program to be launched from the
# dir where it's been copied instead of needing to be # dir where it's been copied instead of needing to be
# installed # installed
@@ -29,7 +32,20 @@ install_dir = os.path.realpath(__file__)
install_dir = pathlib.Path(install_dir).parents[1] install_dir = pathlib.Path(install_dir).parents[1]
sys.path.append(str(install_dir)) sys.path.append(str(install_dir))
from PyQt5 import QtWidgets, QtGui, QtCore # Initialize logging
# This is outside the UI declaration to allow sharing
# the object across modules without explicit redeclaration
logger_filename = os.path.join(
QtCore.QStandardPaths.writableLocation(QtCore.QStandardPaths.AppDataLocation),
'Lector',
'Lector.log')
logging.basicConfig(
filename=logger_filename,
filemode='a',
format='%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s',
datefmt='%H:%M:%S',
level=logging.ERROR)
logger = logging.getLogger('lector.main')
from lector import database from lector import database
from lector import sorter from lector import sorter
@@ -240,7 +256,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# Get list of available parsers # Get list of available parsers
self.available_parsers = '*.' + ' *.'.join(sorter.available_parsers) self.available_parsers = '*.' + ' *.'.join(sorter.available_parsers)
print('Available parsers: ' + self.available_parsers) logger.info('Available parsers: ' + self.available_parsers)
# The Library tab gets no button # The Library tab gets no button
self.tabWidget.tabBar().setTabButton( self.tabWidget.tabBar().setTabButton(
@@ -407,7 +423,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
if not file_paths: if not file_paths:
return return
print('Attempting to open: ' + ', '.join(file_paths)) logger.info(
'Attempting to open: ' + ', '.join(file_paths))
contents = sorter.BookSorter( contents = sorter.BookSorter(
file_paths, file_paths,
@@ -420,13 +437,18 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# Notification feedback in case all books return nothing # Notification feedback in case all books return nothing
if not contents: if not contents:
logger.error('No parseable files found')
return return
successfully_opened = []
for i in contents: for i in contents:
# New tabs are created here # New tabs are created here
# Initial position adjustment is carried out by the tab itself # Initial position adjustment is carried out by the tab itself
file_data = contents[i] file_data = contents[i]
Tab(file_data, self) Tab(file_data, self)
successfully_opened.append(file_data['path'])
logger.info(
'Successfully opened: ' + ', '.join(file_paths))
if self.settings['last_open_tab'] == 'library': if self.settings['last_open_tab'] == 'library':
self.tabWidget.setCurrentIndex(0) self.tabWidget.setCurrentIndex(0)
@@ -1041,7 +1063,8 @@ def main():
translations_out_string = '(Translations found)' translations_out_string = '(Translations found)'
if not translations_found: if not translations_found:
translations_out_string = '(No translations found)' translations_out_string = '(No translations found)'
print(f'Locale: {QtCore.QLocale.system().name()}', translations_out_string) log_string = f'Locale: {QtCore.QLocale.system().name()}' + translations_out_string
logger.info(log_string)
form = MainUI() form = MainUI()
form.show() form.show()
@@ -1050,4 +1073,5 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
logger.info('Application start')
main() main()

View File

@@ -14,10 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5 import QtWidgets, QtCore, QtGui
from lector.resources import annotationswindow from lector.resources import annotationswindow
logger = logging.getLogger(__name__)
class AnnotationsUI(QtWidgets.QDialog, annotationswindow.Ui_Dialog): class AnnotationsUI(QtWidgets.QDialog, annotationswindow.Ui_Dialog):
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@@ -16,6 +16,7 @@
import os import os
import zipfile import zipfile
import logging
import webbrowser import webbrowser
try: try:
@@ -29,6 +30,8 @@ from lector.rarfile import rarfile
from lector.threaded import BackGroundCacheRefill from lector.threaded import BackGroundCacheRefill
from lector.annotations import AnnotationPlacement from lector.annotations import AnnotationPlacement
logger = logging.getLogger(__name__)
class PliantQGraphicsView(QtWidgets.QGraphicsView): class PliantQGraphicsView(QtWidgets.QGraphicsView):
def __init__(self, filepath, main_window, parent=None): def __init__(self, filepath, main_window, parent=None):
@@ -124,7 +127,7 @@ class PliantQGraphicsView(QtWidgets.QGraphicsView):
return bigPixmap return bigPixmap
def generate_image_cache(current_page): def generate_image_cache(current_page):
print('Building image cache') logger.info('(Re)building image cache')
current_page_index = all_pages.index(current_page) current_page_index = all_pages.index(current_page)
# Image caching for single and double page views # Image caching for single and double page views
@@ -491,7 +494,7 @@ class PliantQTextBrowser(QtWidgets.QTextBrowser):
selected_index = self.parent.annotationListView.currentIndex() selected_index = self.parent.annotationListView.currentIndex()
self.current_annotation = self.parent.annotationModel.data( self.current_annotation = self.parent.annotationModel.data(
selected_index, QtCore.Qt.UserRole) selected_index, QtCore.Qt.UserRole)
print('Current annotation: ' + self.current_annotation['name']) logger.info('Selected annotation: ' + + self.current_annotation['name'])
def mouseReleaseEvent(self, event): def mouseReleaseEvent(self, event):
# This takes care of annotation placement # This takes care of annotation placement

View File

@@ -17,9 +17,12 @@
import os import os
import pickle import pickle
import sqlite3 import sqlite3
import logging
from PyQt5 import QtCore from PyQt5 import QtCore
logger = logging.getLogger(__name__)
class DatabaseInit: class DatabaseInit:
def __init__(self, location_prefix): def __init__(self, location_prefix):
@@ -81,7 +84,8 @@ class DatabaseInit:
for i in self.books_table_columns.items(): for i in self.books_table_columns.items():
if i[0] not in database_columns: if i[0] not in database_columns:
commit_required = True commit_required = True
print(f'Database: Adding column "{i[0]}"') info_string = f'Database: Adding column "{i[0]}"'
logger.info(info_string)
sql_command = f"ALTER TABLE books ADD COLUMN {i[0]} {i[1]}" sql_command = f"ALTER TABLE books ADD COLUMN {i[0]} {i[1]}"
self.database.execute(sql_command) self.database.execute(sql_command)
@@ -208,7 +212,7 @@ class DatabaseFunctions:
return None return None
except (KeyError, sqlite3.OperationalError): except (KeyError, sqlite3.OperationalError):
print('SQLite is in wretched rebellion @ data fetching handling') logger.critical('SQLite is in wretched rebellion @ data fetching handling')
def fetch_covers_only(self, hash_list): def fetch_covers_only(self, hash_list):
parameter_marks = ','.join(['?' for i in hash_list]) parameter_marks = ','.join(['?' for i in hash_list])
@@ -241,7 +245,7 @@ class DatabaseFunctions:
self.database.execute( self.database.execute(
sql_command, update_data) sql_command, update_data)
except sqlite3.OperationalError: except sqlite3.OperationalError:
print('SQLite is in wretched rebellion @ metadata handling') logger.critical('SQLite is in wretched rebellion @ metadata handling')
self.database.commit() self.database.commit()
self.database.close() self.database.close()

View File

@@ -15,14 +15,20 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import json import json
import logging
import urllib.request import urllib.request
from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5 import QtWidgets, QtCore, QtGui
logger = logging.getLogger(__name__)
try: try:
from PyQt5 import QtMultimedia from PyQt5 import QtMultimedia
multimedia_available = True multimedia_available = True
except ImportError: except ImportError:
print('QtMultimedia not found. Sounds will not play.') error_string = 'QtMultimedia not found. Sounds will not play.'
print(error_string)
logger.error(error_string)
multimedia_available = False multimedia_available = False
from lector.resources import definitions from lector.resources import definitions

View File

@@ -14,9 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5 import QtWidgets, QtGui, QtCore
from lector.resources import pie_chart from lector.resources import pie_chart
logger = logging.getLogger(__name__)
class LibraryDelegate(QtWidgets.QStyledItemDelegate): class LibraryDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self, temp_dir, parent=None): def __init__(self, temp_dir, parent=None):

View File

@@ -14,12 +14,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5 import QtCore, QtGui, QtWidgets
from lector import database from lector import database
from lector.settings import Settings from lector.settings import Settings
from lector.resources import resources from lector.resources import resources
logger = logging.getLogger(__name__)
class QImageFactory: class QImageFactory:
def __init__(self, parent): def __init__(self, parent):

View File

@@ -16,6 +16,7 @@
import os import os
import pickle import pickle
import logging
import pathlib import pathlib
from PyQt5 import QtGui, QtCore from PyQt5 import QtGui, QtCore
@@ -23,6 +24,8 @@ from PyQt5 import QtGui, QtCore
from lector import database from lector import database
from lector.models import TableProxyModel, ItemProxyModel from lector.models import TableProxyModel, ItemProxyModel
logger = logging.getLogger(__name__)
class Library: class Library:
def __init__(self, parent): def __init__(self, parent):
@@ -47,7 +50,7 @@ class Library:
'LIKE') 'LIKE')
if not books: if not books:
print('Database returned nothing') logger.error('Database returned nothing')
return return
elif mode == 'addition': elif mode == 'addition':
@@ -320,7 +323,7 @@ class Library:
addition_mode = item_metadata['addition_mode'] addition_mode = item_metadata['addition_mode']
except KeyError: except KeyError:
addition_mode = 'automatic' addition_mode = 'automatic'
print('Libary: Error setting addition mode for prune') logger.error('Libary: Error setting addition mode for prune')
if (book_path not in valid_paths and if (book_path not in valid_paths and
(addition_mode != 'manual' or addition_mode is None)): (addition_mode != 'manual' or addition_mode is None)):

View File

@@ -14,12 +14,16 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5 import QtWidgets, QtCore, QtGui
from lector import database from lector import database
from lector.widgets import PliantQGraphicsScene from lector.widgets import PliantQGraphicsScene
from lector.resources import metadata from lector.resources import metadata
logger = logging.getLogger(__name__)
class MetadataUI(QtWidgets.QDialog, metadata.Ui_Dialog): class MetadataUI(QtWidgets.QDialog, metadata.Ui_Dialog):
def __init__(self, parent): def __init__(self, parent):

View File

@@ -14,11 +14,14 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import pathlib import pathlib
from PyQt5 import QtCore, QtWidgets from PyQt5 import QtCore, QtWidgets
from lector.resources import pie_chart from lector.resources import pie_chart
logger = logging.getLogger(__name__)
class BookmarkProxyModel(QtCore.QSortFilterProxyModel): class BookmarkProxyModel(QtCore.QSortFilterProxyModel):
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@@ -19,10 +19,13 @@
import os import os
import time import time
import logging
import zipfile import zipfile
from lector.rarfile import rarfile from lector.rarfile import rarfile
logger = logging.getLogger(__name__)
class ParseCOMIC: class ParseCOMIC:
def __init__(self, filename, *args): def __init__(self, filename, *args):

View File

@@ -16,9 +16,12 @@
import os import os
import zipfile import zipfile
import logging
from lector.readers.read_epub import EPUB from lector.readers.read_epub import EPUB
logger = logging.getLogger(__name__)
class ParseEPUB: class ParseEPUB:
def __init__(self, filename, temp_dir, file_md5): def __init__(self, filename, temp_dir, file_md5):

View File

@@ -15,9 +15,12 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os import os
import logging
from lector.readers.read_fb2 import FB2 from lector.readers.read_fb2 import FB2
logger = logging.getLogger(__name__)
class ParseFB2: class ParseFB2:
def __init__(self, filename, temp_dir, file_md5): def __init__(self, filename, temp_dir, file_md5):

View File

@@ -21,10 +21,13 @@ import os
import sys import sys
import shutil import shutil
import zipfile import zipfile
import logging
from lector.readers.read_epub import EPUB from lector.readers.read_epub import EPUB
import lector.KindleUnpack.kindleunpack as KindleUnpack import lector.KindleUnpack.kindleunpack as KindleUnpack
logger = logging.getLogger(__name__)
class ParseMOBI: class ParseMOBI:
def __init__(self, filename, temp_dir, file_md5): def __init__(self, filename, temp_dir, file_md5):

View File

@@ -20,12 +20,15 @@
import io import io
import os import os
import logging
from PyQt5 import QtCore from PyQt5 import QtCore
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import popplerqt5 import popplerqt5
logger = logging.getLogger(__name__)
class ParsePDF: class ParsePDF:
def __init__(self, filename, *args): def __init__(self, filename, *args):

View File

@@ -15,11 +15,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import os import os
import logging
import zipfile import zipfile
from urllib.parse import unquote from urllib.parse import unquote
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
logger = logging.getLogger(__name__)
class EPUB: class EPUB:
def __init__(self, filename): def __init__(self, filename):
@@ -189,7 +192,7 @@ class EPUB:
if biggest_image: if biggest_image:
self.book['cover'] = self.read_from_zip(biggest_image) self.book['cover'] = self.read_from_zip(biggest_image)
else: else:
print('No cover found for: ' + self.filename) logger.error('No cover found for: ' + self.filename)
# Parse spine and arrange chapter paths acquired from the opf # Parse spine and arrange chapter paths acquired from the opf
# according to the order IN THE SPINE # according to the order IN THE SPINE

View File

@@ -17,9 +17,12 @@
import os import os
import base64 import base64
import zipfile import zipfile
import logging
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
logger = logging.getLogger(__name__)
class FB2: class FB2:
def __init__(self, filename): def __init__(self, filename):
@@ -83,7 +86,9 @@ class FB2:
for i in cover_image_data: for i in cover_image_data:
if cover_image_name.endswith(i.get('id')): if cover_image_name.endswith(i.get('id')):
self.book['cover'] = base64.decodebytes(i.text.encode()) self.book['cover'] = base64.decodebytes(i.text.encode())
except AttributeError: except (AttributeError, TypeError):
# Catch TypeError in case no images exist in the book
logger.error('No cover found for: ' + self.filename)
self.book['cover'] = None self.book['cover'] = None
def parse_chapters(self, temp_dir): def parse_chapters(self, temp_dir):

View File

@@ -10,5 +10,6 @@
<p>Author: BasioMeusPuga <a href="mailto:disgruntled.mob@gmail.com">disgruntled.mob@gmail.com</a></p> <p>Author: BasioMeusPuga <a href="mailto:disgruntled.mob@gmail.com">disgruntled.mob@gmail.com</a></p>
<p>Page:&nbsp;<a href="https://github.com/BasioMeusPuga/Lector">https://github.com/BasioMeusPuga/Lector</a></p> <p>Page:&nbsp;<a href="https://github.com/BasioMeusPuga/Lector">https://github.com/BasioMeusPuga/Lector</a></p>
<p>License: GPLv3&nbsp;<a href="https://www.gnu.org/licenses/gpl-3.0.en.html">https://www.gnu.org/licenses/gpl-3.0.en.html</a></p> <p>License: GPLv3&nbsp;<a href="https://www.gnu.org/licenses/gpl-3.0.en.html">https://www.gnu.org/licenses/gpl-3.0.en.html</a></p>
<p>Donate (Bitcoin): 17jaxj26vFJNqQ2hEVerbBV5fpTusfqFro</p>
<p>&nbsp;</p></body> <p>&nbsp;</p></body>
</html> </html>

View File

@@ -17,10 +17,13 @@
# Keep in mind that all integer / boolean settings are returned as strings # Keep in mind that all integer / boolean settings are returned as strings
import os import os
import logging
from ast import literal_eval from ast import literal_eval
from PyQt5 import QtCore, QtGui from PyQt5 import QtCore, QtGui
logger = logging.getLogger(__name__)
class Settings: class Settings:
def __init__(self, parent): def __init__(self, parent):

View File

@@ -19,6 +19,7 @@
import os import os
import copy import copy
import logging
import pathlib import pathlib
from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5 import QtWidgets, QtCore, QtGui
@@ -30,6 +31,8 @@ from lector.threaded import BackGroundBookSearch, BackGroundBookAddition
from lector.resources import settingswindow from lector.resources import settingswindow
from lector.settings import Settings from lector.settings import Settings
logger = logging.getLogger(__name__)
class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog): class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
def __init__(self, parent=None): def __init__(self, parent=None):
@@ -189,7 +192,7 @@ class SettingsUI(QtWidgets.QDialog, settingswindow.Ui_Dialog):
self.main_window.generate_library_filter_menu(paths) self.main_window.generate_library_filter_menu(paths)
directory_data = {} directory_data = {}
if not paths: if not paths:
print('Database: No paths for settings...') logger.error('Database: No paths for settings...')
else: else:
# Convert to the dictionary format that is # Convert to the dictionary format that is
# to be fed into the QFileSystemModel # to be fed into the QFileSystemModel

View File

@@ -36,6 +36,7 @@ import os
import sys import sys
import time import time
import pickle import pickle
import logging
import hashlib import hashlib
import threading import threading
@@ -53,6 +54,8 @@ from lector.parsers.mobi import ParseMOBI
from lector.parsers.fb2 import ParseFB2 from lector.parsers.fb2 import ParseFB2
from lector.parsers.comicbooks import ParseCOMIC from lector.parsers.comicbooks import ParseCOMIC
logger = logging.getLogger(__name__)
sorter = { sorter = {
'epub': ParseEPUB, 'epub': ParseEPUB,
'mobi': ParseMOBI, 'mobi': ParseMOBI,
@@ -70,7 +73,9 @@ try:
from lector.parsers.pdf import ParsePDF from lector.parsers.pdf import ParsePDF
sorter['pdf'] = ParsePDF sorter['pdf'] = ParsePDF
except ImportError: except ImportError:
print('python-poppler-qt5 is not installed. Pdf files will not work.') error_string = 'python-poppler-qt5 is not installed. Pdf files will not work.'
print(error_string)
logger.error(error_string)
available_parsers = [i for i in sorter] available_parsers = [i for i in sorter]
progressbar = None # This is populated by __main__ progressbar = None # This is populated by __main__
@@ -194,7 +199,7 @@ class BookSorter:
# None values are accounted for here # None values are accounted for here
is_valid = book_ref.read_book() is_valid = book_ref.read_book()
if not is_valid: if not is_valid:
print('Cannot parse: ' + filename) logger.error('Cannot parse:' + filename)
return return
if book_ref.book: if book_ref.book:
@@ -311,7 +316,8 @@ class BookSorter:
return_books[j] = i[j] return_books[j] = i[j]
del self.processed_books del self.processed_books
print('Finished processing in', time.time() - start_time) processing_time = str(time.time() - start_time)
logger.info('Finished processing in:' + processing_time)
return return_books return return_books

View File

@@ -16,6 +16,7 @@
import os import os
import re import re
import logging
import pathlib import pathlib
from multiprocessing.dummy import Pool from multiprocessing.dummy import Pool
@@ -24,6 +25,8 @@ from PyQt5 import QtCore, QtGui
from lector import sorter from lector import sorter
from lector import database from lector import database
logger = logging.getLogger(__name__)
class BackGroundTabUpdate(QtCore.QThread): class BackGroundTabUpdate(QtCore.QThread):
def __init__(self, database_path, all_metadata, parent=None): def __init__(self, database_path, all_metadata, parent=None):

View File

@@ -14,8 +14,12 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from PyQt5 import QtWidgets, QtCore from PyQt5 import QtWidgets, QtCore
logger = logging.getLogger(__name__)
class BookToolBar(QtWidgets.QToolBar): class BookToolBar(QtWidgets.QToolBar):
def __init__(self, parent=None): def __init__(self, parent=None):

View File

@@ -20,6 +20,7 @@
import os import os
import uuid import uuid
import logging
from PyQt5 import QtWidgets, QtGui, QtCore from PyQt5 import QtWidgets, QtGui, QtCore
@@ -28,6 +29,8 @@ from lector.sorter import resize_image
from lector.threaded import BackGroundTextSearch from lector.threaded import BackGroundTextSearch
from lector.contentwidgets import PliantQGraphicsView, PliantQTextBrowser from lector.contentwidgets import PliantQGraphicsView, PliantQTextBrowser
logger = logging.getLogger(__name__)
class Tab(QtWidgets.QWidget): class Tab(QtWidgets.QWidget):
def __init__(self, metadata, main_window, parent=None): def __init__(self, metadata, main_window, parent=None):