Fix threading. Yeah. I've *fixed* threading.

This commit is contained in:
BasioMeusPuga
2017-11-14 19:34:42 +05:30
parent 390c33af62
commit 0ee39608c3
6 changed files with 62 additions and 39 deletions

View File

@@ -53,7 +53,6 @@
? Include icons for emblems ? Include icons for emblems
""" """
import os
import sys import sys
from PyQt5 import QtWidgets, QtGui, QtCore 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 tab_metadata = self.tabWidget.widget(tab_index).metadata
self.thread = BackGroundTabUpdate( self.thread = BackGroundTabUpdate(
self.database_path, tab_metadata) self.database_path, [tab_metadata])
self.thread.start() self.thread.start()
self.tabWidget.removeTab(tab_index) self.tabWidget.removeTab(tab_index)
@@ -331,7 +330,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
path = metadata['path'] path = metadata['path']
contents = sorter.BookSorter( 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) tab_ref = Tab(contents, self.tabWidget)
self.tabWidget.setCurrentWidget(tab_ref) self.tabWidget.setCurrentWidget(tab_ref)
@@ -440,15 +439,22 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
font, font_size, foreground, background)) font, font_size, foreground, background))
def closeEvent(self, event=None): def closeEvent(self, event=None):
# All tabs must be iterated upon here # All tabs must be iterated upon here
self.temp_dir.remove()
self.hide()
if self.tabWidget.count() > 1:
all_metadata = []
for i in range(1, self.tabWidget.count()): for i in range(1, self.tabWidget.count()):
tab_metadata = self.tabWidget.widget(i).metadata tab_metadata = self.tabWidget.widget(i).metadata
self.thread = BackGroundTabUpdate( all_metadata.append(tab_metadata)
self.database_path, tab_metadata)
self.thread.start()
self.thread.finished.connect(QtWidgets.qApp.exit)
self.thread = BackGroundTabUpdate(self.database_path, all_metadata)
self.thread.finished.connect(QtWidgets.qApp.exit)
self.thread.start()
else:
Settings(self).save_settings() Settings(self).save_settings()
QtWidgets.qApp.exit() QtWidgets.qApp.exit()

View File

@@ -115,11 +115,16 @@ class DatabaseFunctions:
self.close_database() self.close_database()
def modify_position(self, file_hash, 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) pickled_position = pickle.dumps(position)
sql_command = "UPDATE books SET Position = ? WHERE Hash = ?" sql_command = "UPDATE books SET Position = ? WHERE Hash = ?"
self.database.execute(sql_command, [sqlite3.Binary(pickled_position), file_hash]) self.database.execute(sql_command, [sqlite3.Binary(pickled_position), file_hash])
self.database.commit() self.database.commit()
self.close_database() self.close_database()

View File

@@ -3,16 +3,17 @@
import os import os
import time import time
import zipfile import zipfile
import tempfile
import collections import collections
class ParseCBZ: class ParseCBZ:
def __init__(self, filename): def __init__(self, filename, temp_dir, file_md5):
# TODO # TODO
# Maybe also include book description # Maybe also include book description
self.filename = filename self.filename = filename
self.book = None self.book = None
self.temp_dir = temp_dir
self.file_md5 = file_md5
def read_book(self): def read_book(self):
try: try:
@@ -43,17 +44,17 @@ class ParseCBZ:
return None return None
def get_contents(self): def get_contents(self):
extract_path = os.path.join(self.temp_dir, self.file_md5)
contents = collections.OrderedDict() contents = collections.OrderedDict()
# This is a brute force approach # This is a brute force approach
# Maybe try reading from the file as everything # Maybe try reading from the file as everything
# matures a little bit more # matures a little bit more
temp_dir = tempfile.mkdtemp()
contents = collections.OrderedDict() contents = collections.OrderedDict()
for count, i in enumerate(self.book.infolist()): 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) 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. # This does image returns.
# TODO # TODO
@@ -64,7 +65,7 @@ class ParseCBZ:
contents[page_name] = "<img src='%s' align='middle'/>" % image_path contents[page_name] = "<img src='%s' align='middle'/>" % image_path
file_settings = { file_settings = {
'temp_dir': temp_dir, 'temp_dir': self.temp_dir,
'images_only': True} 'images_only': True}
return contents, file_settings return contents, file_settings

View File

@@ -10,17 +10,20 @@
import os import os
import re import re
import zipfile
import collections import collections
import ebooklib.epub import ebooklib.epub
class ParseEPUB: class ParseEPUB:
def __init__(self, filename): def __init__(self, filename, temp_dir, file_md5):
# TODO # TODO
# Maybe also include book description # Maybe also include book description
self.filename = filename self.filename = filename
self.book = None self.book = None
self.temp_dir = temp_dir
self.file_md5 = file_md5
def read_book(self): def read_book(self):
try: try:
@@ -103,6 +106,11 @@ class ParseEPUB:
return None return None
def get_contents(self): 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() contents = collections.OrderedDict()
def flatten_chapter(toc_element): def flatten_chapter(toc_element):
@@ -141,7 +149,7 @@ class ParseEPUB:
# Special settings that have to be returned with the file # Special settings that have to be returned with the file
# Referenced in sorter.py # Referenced in sorter.py
file_settings = { file_settings = {
'temp_dir': None, 'temp_dir': extract_path,
'images_only': False} 'images_only': False}
return contents, file_settings return contents, file_settings

View File

@@ -25,7 +25,7 @@ from parsers.cbz import ParseCBZ
class BookSorter: 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 # Have the GUI pass a list of files straight to here
# Then, on the basis of what is needed, pass the # Then, on the basis of what is needed, pass the
# filenames to the requisite functions # filenames to the requisite functions
@@ -35,10 +35,11 @@ class BookSorter:
self.file_list = file_list self.file_list = file_list
self.statistics = [0, (len(file_list))] self.statistics = [0, (len(file_list))]
self.all_books = {} self.all_books = {}
self.database_path = database_path
self.hashes = [] self.hashes = []
self.mode = mode 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() self.database_hashes()
def database_hashes(self): def database_hashes(self):
@@ -87,13 +88,13 @@ class BookSorter:
and (file_md5 in self.all_books.items() or file_md5 in self.hashes)): and (file_md5 in self.all_books.items() or file_md5 in self.hashes)):
return return
# SORTING TAKES PLACE HERE # ___________SORTING TAKES PLACE HERE___________
try: try:
file_extension = os.path.splitext(filename)[1][1:] file_extension = os.path.splitext(filename)[1][1:]
if file_extension == 'epub': if file_extension == 'epub':
book_ref = ParseEPUB(filename) book_ref = ParseEPUB(filename, self.temp_dir, file_md5)
if file_extension == 'cbz': if file_extension == 'cbz':
book_ref = ParseCBZ(filename) book_ref = ParseCBZ(filename, self.temp_dir, file_md5)
except IndexError: except IndexError:
return return

View File

@@ -284,6 +284,7 @@ class Tab(QtWidgets.QWidget):
title = self.metadata['title'] title = self.metadata['title']
position = self.metadata['position'] position = self.metadata['position']
relative_path_root = self.metadata['temp_dir']
# TODO # TODO
# Chapter position and vertical scrollbar position # Chapter position and vertical scrollbar position
@@ -295,6 +296,7 @@ class Tab(QtWidgets.QWidget):
chapter_name = list(self.metadata['content'])[current_chapter - 1] chapter_name = list(self.metadata['content'])[current_chapter - 1]
chapter_content = self.metadata['content'][chapter_name] chapter_content = self.metadata['content'][chapter_name]
self.contentView.setSearchPaths([relative_path_root])
self.contentView.setHtml(chapter_content) self.contentView.setHtml(chapter_content)
self.gridLayout.addWidget(self.contentView, 0, 0, 1, 1) self.gridLayout.addWidget(self.contentView, 0, 0, 1, 1)
@@ -378,20 +380,20 @@ class MyAbsModel(QtGui.QStandardItemModel, QtCore.QAbstractItemModel):
class BackGroundTabUpdate(QtCore.QThread): 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) super(BackGroundTabUpdate, self).__init__(parent)
self.database_path = database_path self.database_path = database_path
self.tab_metadata = tab_metadata self.all_metadata = all_metadata
def run(self): def run(self):
file_hash = self.tab_metadata['hash'] hash_position_pairs = []
position = self.tab_metadata['position'] for i in self.all_metadata:
database.DatabaseFunctions( file_hash = i['hash']
self.database_path).modify_position(file_hash, position) position = i['position']
hash_position_pairs.append([file_hash, position])
temp_dir = self.tab_metadata['temp_dir'] database.DatabaseFunctions(
if temp_dir: self.database_path).modify_position(hash_position_pairs)
shutil.rmtree(temp_dir)
class BackGroundBookAddition(QtCore.QThread): class BackGroundBookAddition(QtCore.QThread):