Thread file addition. Files added to model instead of rebuild. Check here if errors.
This commit is contained in:
37
__main__.py
37
__main__.py
@@ -55,7 +55,6 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
|
||||||
|
|
||||||
from PyQt5 import QtWidgets, QtGui, QtCore
|
from PyQt5 import QtWidgets, QtGui, QtCore
|
||||||
|
|
||||||
@@ -63,7 +62,8 @@ import mainwindow
|
|||||||
import database
|
import database
|
||||||
import sorter
|
import sorter
|
||||||
|
|
||||||
from widgets import LibraryToolBar, BookToolBar, Tab, LibraryDelegate, BackGroundTabUpdate
|
from widgets import LibraryToolBar, BookToolBar, Tab
|
||||||
|
from widgets import LibraryDelegate, BackGroundTabUpdate, BackGroundBookAddition
|
||||||
from library import Library
|
from library import Library
|
||||||
from settings import Settings
|
from settings import Settings
|
||||||
|
|
||||||
@@ -80,6 +80,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
# Create the database in case it doesn't exist
|
# Create the database in case it doesn't exist
|
||||||
database.DatabaseInit(self.database_path)
|
database.DatabaseInit(self.database_path)
|
||||||
|
|
||||||
|
# Background Thread
|
||||||
|
self.thread = None
|
||||||
|
|
||||||
# Create and right align the statusbar label widget
|
# Create and right align the statusbar label widget
|
||||||
self.statusMessage = QtWidgets.QLabel()
|
self.statusMessage = QtWidgets.QLabel()
|
||||||
self.statusMessage.setObjectName('statusMessage')
|
self.statusMessage.setObjectName('statusMessage')
|
||||||
@@ -96,8 +99,8 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.libraryToolBar = LibraryToolBar(self)
|
self.libraryToolBar = LibraryToolBar(self)
|
||||||
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
self.libraryToolBar.addButton.triggered.connect(self.add_books)
|
||||||
self.libraryToolBar.deleteButton.triggered.connect(self.delete_books)
|
self.libraryToolBar.deleteButton.triggered.connect(self.delete_books)
|
||||||
self.libraryToolBar.searchBar.textChanged.connect(self.only_update_listview)
|
self.libraryToolBar.searchBar.textChanged.connect(self.lib_ref.update_proxymodel)
|
||||||
self.libraryToolBar.sortingBox.activated.connect(self.only_update_listview)
|
self.libraryToolBar.sortingBox.activated.connect(self.lib_ref.update_proxymodel)
|
||||||
self.addToolBar(self.libraryToolBar)
|
self.addToolBar(self.libraryToolBar)
|
||||||
|
|
||||||
# Book toolbar
|
# Book toolbar
|
||||||
@@ -125,9 +128,6 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
self.tab_switch()
|
self.tab_switch()
|
||||||
self.tabWidget.currentChanged.connect(self.tab_switch)
|
self.tabWidget.currentChanged.connect(self.tab_switch)
|
||||||
|
|
||||||
# Background Thread
|
|
||||||
self.thread = None
|
|
||||||
|
|
||||||
# For fullscreening purposes
|
# For fullscreening purposes
|
||||||
self.current_contentView = None
|
self.current_contentView = None
|
||||||
|
|
||||||
@@ -188,22 +188,16 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
def add_books(self):
|
def add_books(self):
|
||||||
# TODO
|
# TODO
|
||||||
# Maybe expand this to traverse directories recursively
|
# Maybe expand this to traverse directories recursively
|
||||||
self.statusMessage.setText('Adding books...')
|
|
||||||
|
|
||||||
# TODO
|
|
||||||
# Generate list of available parsers
|
# Generate list of available parsers
|
||||||
|
|
||||||
my_file = QtWidgets.QFileDialog.getOpenFileNames(
|
my_file = QtWidgets.QFileDialog.getOpenFileNames(
|
||||||
self, 'Open file', self.last_open_path,
|
self, 'Open file', self.last_open_path,
|
||||||
"eBooks (*.epub *.mobi *.aws *.txt *.pdf *.fb2 *.djvu *.cbz)")
|
"eBooks (*.epub *.mobi *.aws *.txt *.pdf *.fb2 *.djvu *.cbz)")
|
||||||
|
|
||||||
if my_file[0]:
|
if my_file[0]:
|
||||||
self.listView.setEnabled(False)
|
self.thread = BackGroundBookAddition(self, my_file[0], self.database_path)
|
||||||
self.last_open_path = os.path.dirname(my_file[0][0])
|
self.thread.finished.connect(self.lib_ref.create_proxymodel)
|
||||||
books = sorter.BookSorter(my_file[0], 'addition', self.database_path)
|
self.thread.start()
|
||||||
parsed_books = books.initiate_threads()
|
|
||||||
database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)
|
|
||||||
self.listView.setEnabled(True)
|
|
||||||
self.viewModel = None
|
|
||||||
self.reload_listview()
|
|
||||||
|
|
||||||
def delete_books(self):
|
def delete_books(self):
|
||||||
selected_books = self.listView.selectedIndexes()
|
selected_books = self.listView.selectedIndexes()
|
||||||
@@ -233,14 +227,9 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
|
|||||||
msg_box.show()
|
msg_box.show()
|
||||||
msg_box.exec_()
|
msg_box.exec_()
|
||||||
|
|
||||||
def only_update_listview(self):
|
|
||||||
self.lib_ref.update_proxymodel()
|
|
||||||
|
|
||||||
def reload_listview(self):
|
def reload_listview(self):
|
||||||
if not self.viewModel:
|
if not self.viewModel:
|
||||||
self.lib_ref.generate_model()
|
self.lib_ref.generate_model('build')
|
||||||
self.lib_ref.create_proxymodel()
|
|
||||||
self.lib_ref.update_proxymodel()
|
|
||||||
|
|
||||||
def tab_switch(self):
|
def tab_switch(self):
|
||||||
if self.tabWidget.currentIndex() == 0:
|
if self.tabWidget.currentIndex() == 0:
|
||||||
|
39
library.py
39
library.py
@@ -13,10 +13,12 @@ class Library:
|
|||||||
self.parent_window = parent
|
self.parent_window = parent
|
||||||
self.proxy_model = None
|
self.proxy_model = None
|
||||||
|
|
||||||
def generate_model(self):
|
def generate_model(self, mode, parsed_books=None):
|
||||||
# The QlistView widget needs to be populated
|
# The QlistView widget needs to be populated
|
||||||
# with a model that inherits from QStandardItemModel
|
# with a model that inherits from QStandardItemModel
|
||||||
# self.parent_window.viewModel = QtGui.QStandardItemModel()
|
# self.parent_window.viewModel = QtGui.QStandardItemModel()
|
||||||
|
|
||||||
|
if mode == 'build':
|
||||||
self.parent_window.viewModel = MyAbsModel()
|
self.parent_window.viewModel = MyAbsModel()
|
||||||
|
|
||||||
books = database.DatabaseFunctions(
|
books = database.DatabaseFunctions(
|
||||||
@@ -30,8 +32,35 @@ class Library:
|
|||||||
print('Database returned nothing')
|
print('Database returned nothing')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
elif mode == 'addition':
|
||||||
|
# Assumes parent_window.viewModel already exists and may be extended
|
||||||
|
# Because any additional books have already been added to the
|
||||||
|
# database using background threads
|
||||||
|
|
||||||
|
books = []
|
||||||
|
for i in parsed_books:
|
||||||
|
parsed_title = parsed_books[i]['title']
|
||||||
|
parsed_author = parsed_books[i]['author']
|
||||||
|
parsed_year = parsed_books[i]['year']
|
||||||
|
parsed_path = parsed_books[i]['path']
|
||||||
|
parsed_position = None
|
||||||
|
parsed_isbn = parsed_books[i]['isbn']
|
||||||
|
parsed_tags = None
|
||||||
|
parsed_hash = i
|
||||||
|
parsed_cover = parsed_books[i]['cover_image']
|
||||||
|
|
||||||
|
books.append([
|
||||||
|
None, parsed_title, parsed_author, parsed_year, parsed_path,
|
||||||
|
parsed_position, parsed_isbn, parsed_tags, parsed_hash, parsed_cover])
|
||||||
|
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
for i in books:
|
for i in books:
|
||||||
# The database query returns a tuple with the following indices
|
# The database query returns (or the extension data is)
|
||||||
|
# an iterable with the following indices:
|
||||||
# Index 0 is the key ID is ignored
|
# Index 0 is the key ID is ignored
|
||||||
title = i[1]
|
title = i[1]
|
||||||
author = i[2]
|
author = i[2]
|
||||||
@@ -54,6 +83,9 @@ class Library:
|
|||||||
'tags': tags,
|
'tags': tags,
|
||||||
'hash': i[8]}
|
'hash': i[8]}
|
||||||
|
|
||||||
|
# import pprint
|
||||||
|
# pprint.pprint(all_metadata)
|
||||||
|
|
||||||
tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)
|
tooltip_string = title + '\nAuthor: ' + author + '\nYear: ' + str(year)
|
||||||
if tags:
|
if tags:
|
||||||
tooltip_string += ('\nTags: ' + tags)
|
tooltip_string += ('\nTags: ' + tags)
|
||||||
@@ -89,12 +121,15 @@ class Library:
|
|||||||
item.setIcon(QtGui.QIcon(img_pixmap))
|
item.setIcon(QtGui.QIcon(img_pixmap))
|
||||||
self.parent_window.viewModel.appendRow(item)
|
self.parent_window.viewModel.appendRow(item)
|
||||||
|
|
||||||
|
self.create_proxymodel()
|
||||||
|
|
||||||
def create_proxymodel(self):
|
def create_proxymodel(self):
|
||||||
self.proxy_model = QtCore.QSortFilterProxyModel()
|
self.proxy_model = QtCore.QSortFilterProxyModel()
|
||||||
self.proxy_model.setSourceModel(self.parent_window.viewModel)
|
self.proxy_model.setSourceModel(self.parent_window.viewModel)
|
||||||
s = QtCore.QSize(160, 250) # Set icon sizing here
|
s = QtCore.QSize(160, 250) # Set icon sizing here
|
||||||
self.parent_window.listView.setIconSize(s)
|
self.parent_window.listView.setIconSize(s)
|
||||||
self.parent_window.listView.setModel(self.proxy_model)
|
self.parent_window.listView.setModel(self.proxy_model)
|
||||||
|
self.update_proxymodel()
|
||||||
|
|
||||||
def update_proxymodel(self):
|
def update_proxymodel(self):
|
||||||
self.proxy_model.setFilterRole(QtCore.Qt.UserRole + 4)
|
self.proxy_model.setFilterRole(QtCore.Qt.UserRole + 4)
|
||||||
|
@@ -33,6 +33,7 @@ class BookSorter:
|
|||||||
# Parsing for the reader proper
|
# Parsing for the reader proper
|
||||||
# Caching upon closing
|
# Caching upon closing
|
||||||
self.file_list = file_list
|
self.file_list = file_list
|
||||||
|
self.statistics = [0, (len(file_list))]
|
||||||
self.all_books = {}
|
self.all_books = {}
|
||||||
self.database_path = database_path
|
self.database_path = database_path
|
||||||
self.hashes = []
|
self.hashes = []
|
||||||
@@ -73,6 +74,11 @@ class BookSorter:
|
|||||||
with open(filename, 'rb') as current_book:
|
with open(filename, 'rb') as current_book:
|
||||||
file_md5 = hashlib.md5(current_book.read()).hexdigest()
|
file_md5 = hashlib.md5(current_book.read()).hexdigest()
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
# Make use of this
|
||||||
|
# self.statistics[0] += 1
|
||||||
|
# print(self.statistics)
|
||||||
|
|
||||||
# IF the file is NOT being loaded into the reader,
|
# IF the file is NOT being loaded into the reader,
|
||||||
# Do not allow addition in case the file is dupicated in the directory
|
# Do not allow addition in case the file is dupicated in the directory
|
||||||
# OR is already in the database
|
# OR is already in the database
|
||||||
@@ -109,7 +115,8 @@ class BookSorter:
|
|||||||
cover_image = book_ref.get_cover_image()
|
cover_image = book_ref.get_cover_image()
|
||||||
# TODO
|
# TODO
|
||||||
if not cover_image:
|
if not cover_image:
|
||||||
pass
|
with open('resources/NotFound.png', 'rb') as stand_in:
|
||||||
|
cover_image = stand_in.read()
|
||||||
|
|
||||||
self.all_books[file_md5] = {
|
self.all_books[file_md5] = {
|
||||||
'title': title,
|
'title': title,
|
||||||
|
15
widgets.py
15
widgets.py
@@ -6,6 +6,7 @@ from PyQt5 import QtWidgets, QtGui, QtCore
|
|||||||
|
|
||||||
import pie_chart
|
import pie_chart
|
||||||
import database
|
import database
|
||||||
|
import sorter
|
||||||
|
|
||||||
|
|
||||||
class BookToolBar(QtWidgets.QToolBar):
|
class BookToolBar(QtWidgets.QToolBar):
|
||||||
@@ -391,3 +392,17 @@ class BackGroundTabUpdate(QtCore.QThread):
|
|||||||
temp_dir = self.tab_metadata['temp_dir']
|
temp_dir = self.tab_metadata['temp_dir']
|
||||||
if temp_dir:
|
if temp_dir:
|
||||||
shutil.rmtree(temp_dir)
|
shutil.rmtree(temp_dir)
|
||||||
|
|
||||||
|
|
||||||
|
class BackGroundBookAddition(QtCore.QThread):
|
||||||
|
def __init__(self, parent_window, file_list, database_path, parent=None):
|
||||||
|
super(BackGroundBookAddition, self).__init__(parent)
|
||||||
|
self.parent_window = parent_window
|
||||||
|
self.file_list = file_list
|
||||||
|
self.database_path = database_path
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
books = sorter.BookSorter(self.file_list, 'addition', self.database_path)
|
||||||
|
parsed_books = books.initiate_threads()
|
||||||
|
database.DatabaseFunctions(self.database_path).add_to_database(parsed_books)
|
||||||
|
self.parent_window.lib_ref.generate_model('addition', parsed_books)
|
||||||
|
Reference in New Issue
Block a user