diff --git a/__main__.py b/__main__.py index 71459b5..c63fe88 100755 --- a/__main__.py +++ b/__main__.py @@ -53,7 +53,6 @@ ? Include icons for emblems """ -import os import sys from PyQt5 import QtWidgets, QtGui, QtCore @@ -266,7 +265,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): tab_metadata = self.tabWidget.widget(tab_index).metadata self.thread = BackGroundTabUpdate( - self.database_path, tab_metadata) + self.database_path, [tab_metadata]) self.thread.start() self.tabWidget.removeTab(tab_index) @@ -331,7 +330,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): path = metadata['path'] contents = sorter.BookSorter( - [path], 'reading', self.database_path).initiate_threads() + [path], 'reading', self.database_path, self.temp_dir.path()).initiate_threads() tab_ref = Tab(contents, self.tabWidget) self.tabWidget.setCurrentWidget(tab_ref) @@ -440,17 +439,24 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow): font, font_size, foreground, background)) def closeEvent(self, event=None): - # All tabs must be iterated upon here - for i in range(1, self.tabWidget.count()): - tab_metadata = self.tabWidget.widget(i).metadata - self.thread = BackGroundTabUpdate( - self.database_path, tab_metadata) - self.thread.start() - self.thread.finished.connect(QtWidgets.qApp.exit) + self.temp_dir.remove() + self.hide() - Settings(self).save_settings() - QtWidgets.qApp.exit() + if self.tabWidget.count() > 1: + all_metadata = [] + + for i in range(1, self.tabWidget.count()): + tab_metadata = self.tabWidget.widget(i).metadata + all_metadata.append(tab_metadata) + + self.thread = BackGroundTabUpdate(self.database_path, all_metadata) + self.thread.finished.connect(QtWidgets.qApp.exit) + self.thread.start() + + else: + Settings(self).save_settings() + QtWidgets.qApp.exit() def main(): diff --git a/database.py b/database.py index af4b6d4..36b5114 100644 --- a/database.py +++ b/database.py @@ -115,11 +115,16 @@ class DatabaseFunctions: self.close_database() - def modify_position(self, file_hash, position): - pickled_position = pickle.dumps(position) + def modify_position(self, hash_position_pairs): + for i in hash_position_pairs: + file_hash = i[0] + position = i[1] + + pickled_position = pickle.dumps(position) + + sql_command = "UPDATE books SET Position = ? WHERE Hash = ?" + self.database.execute(sql_command, [sqlite3.Binary(pickled_position), file_hash]) - sql_command = "UPDATE books SET Position = ? WHERE Hash = ?" - self.database.execute(sql_command, [sqlite3.Binary(pickled_position), file_hash]) self.database.commit() self.close_database() diff --git a/parsers/cbz.py b/parsers/cbz.py index e491954..0a2642c 100644 --- a/parsers/cbz.py +++ b/parsers/cbz.py @@ -3,16 +3,17 @@ import os import time import zipfile -import tempfile import collections class ParseCBZ: - def __init__(self, filename): + def __init__(self, filename, temp_dir, file_md5): # TODO # Maybe also include book description self.filename = filename self.book = None + self.temp_dir = temp_dir + self.file_md5 = file_md5 def read_book(self): try: @@ -43,17 +44,17 @@ class ParseCBZ: return None def get_contents(self): + extract_path = os.path.join(self.temp_dir, self.file_md5) contents = collections.OrderedDict() # This is a brute force approach # Maybe try reading from the file as everything # matures a little bit more - temp_dir = tempfile.mkdtemp() contents = collections.OrderedDict() for count, i in enumerate(self.book.infolist()): - self.book.extract(i, path=temp_dir) + self.book.extract(i, path=extract_path) page_name = 'Page ' + str(count + 1) - image_path = os.path.join(temp_dir, i.filename) + image_path = os.path.join(extract_path, i.filename) # This does image returns. # TODO @@ -64,7 +65,7 @@ class ParseCBZ: contents[page_name] = "" % image_path file_settings = { - 'temp_dir': temp_dir, + 'temp_dir': self.temp_dir, 'images_only': True} return contents, file_settings diff --git a/parsers/epub.py b/parsers/epub.py index 3c66225..436ab20 100644 --- a/parsers/epub.py +++ b/parsers/epub.py @@ -10,17 +10,20 @@ import os import re +import zipfile import collections import ebooklib.epub class ParseEPUB: - def __init__(self, filename): + def __init__(self, filename, temp_dir, file_md5): # TODO # Maybe also include book description self.filename = filename self.book = None + self.temp_dir = temp_dir + self.file_md5 = file_md5 def read_book(self): try: @@ -103,6 +106,11 @@ class ParseEPUB: return None def get_contents(self): + # Extract all contents to a temporary directory + # for relative path lookup voodoo + extract_path = os.path.join(self.temp_dir, self.file_md5) + zipfile.ZipFile(self.filename).extractall(extract_path) + contents = collections.OrderedDict() def flatten_chapter(toc_element): @@ -141,7 +149,7 @@ class ParseEPUB: # Special settings that have to be returned with the file # Referenced in sorter.py file_settings = { - 'temp_dir': None, + 'temp_dir': extract_path, 'images_only': False} return contents, file_settings diff --git a/sorter.py b/sorter.py index 552b904..54e6918 100644 --- a/sorter.py +++ b/sorter.py @@ -25,7 +25,7 @@ from parsers.cbz import ParseCBZ class BookSorter: - def __init__(self, file_list, mode, database_path): + def __init__(self, file_list, mode, database_path, temp_dir=None): # Have the GUI pass a list of files straight to here # Then, on the basis of what is needed, pass the # filenames to the requisite functions @@ -35,10 +35,11 @@ class BookSorter: self.file_list = file_list self.statistics = [0, (len(file_list))] self.all_books = {} - self.database_path = database_path self.hashes = [] self.mode = mode - if database_path: + self.database_path = database_path + self.temp_dir = temp_dir + if database_path and self.mode == 'reading': self.database_hashes() def database_hashes(self): @@ -87,13 +88,13 @@ class BookSorter: and (file_md5 in self.all_books.items() or file_md5 in self.hashes)): return - # SORTING TAKES PLACE HERE + # ___________SORTING TAKES PLACE HERE___________ try: file_extension = os.path.splitext(filename)[1][1:] if file_extension == 'epub': - book_ref = ParseEPUB(filename) + book_ref = ParseEPUB(filename, self.temp_dir, file_md5) if file_extension == 'cbz': - book_ref = ParseCBZ(filename) + book_ref = ParseCBZ(filename, self.temp_dir, file_md5) except IndexError: return diff --git a/widgets.py b/widgets.py index 6a43571..7561d0f 100644 --- a/widgets.py +++ b/widgets.py @@ -284,6 +284,7 @@ class Tab(QtWidgets.QWidget): title = self.metadata['title'] position = self.metadata['position'] + relative_path_root = self.metadata['temp_dir'] # TODO # Chapter position and vertical scrollbar position @@ -295,6 +296,7 @@ class Tab(QtWidgets.QWidget): chapter_name = list(self.metadata['content'])[current_chapter - 1] chapter_content = self.metadata['content'][chapter_name] + self.contentView.setSearchPaths([relative_path_root]) self.contentView.setHtml(chapter_content) self.gridLayout.addWidget(self.contentView, 0, 0, 1, 1) @@ -378,20 +380,20 @@ class MyAbsModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel): class BackGroundTabUpdate(QtCore.QThread): - def __init__(self, database_path, tab_metadata, parent=None): + def __init__(self, database_path, all_metadata, parent=None): super(BackGroundTabUpdate, self).__init__(parent) self.database_path = database_path - self.tab_metadata = tab_metadata + self.all_metadata = all_metadata def run(self): - file_hash = self.tab_metadata['hash'] - position = self.tab_metadata['position'] - database.DatabaseFunctions( - self.database_path).modify_position(file_hash, position) + hash_position_pairs = [] + for i in self.all_metadata: + file_hash = i['hash'] + position = i['position'] + hash_position_pairs.append([file_hash, position]) - temp_dir = self.tab_metadata['temp_dir'] - if temp_dir: - shutil.rmtree(temp_dir) + database.DatabaseFunctions( + self.database_path).modify_position(hash_position_pairs) class BackGroundBookAddition(QtCore.QThread):