Improve fb2 parsing

Miscellaneous fixes to navigation
This commit is contained in:
BasioMeusPuga
2019-02-03 23:55:33 +05:30
parent d1662b47d9
commit 91ca1e2190
7 changed files with 67 additions and 32 deletions

12
TODO
View File

@@ -2,8 +2,9 @@ TODO
General:
✓ Internationalization
✓ Application icon
✓ .desktop file
Flatpak and AppImage support
✓ .desktop file
✓ Shift to logging instead of print statements
Flatpak and AppImage support
Options:
✓ Automatic library management
✓ Recursive file addition
@@ -93,9 +94,13 @@ TODO
Last line in QTextBrowser should never be cut off
Does image alignment need to be centered?
Bookmark name for a page that's not on the TOC or has nothing before
Screen position still keeps jumping when inside a paragraph
Better recursion needed for fb2 toc
Secondary:
The cover page needs to be marked separately
Special formatting for each chapter's title
Create covers for books without them
Signal end of chapter with some text
Graphical themes
Change focus rectangle dimensions
Universal Ctrl + Tab
@@ -103,7 +108,6 @@ TODO
Goodreads API: Ratings, Read, Recommendations
Get ISBN using python-isbnlib
Use embedded fonts + CSS
Shift to logging instead of print statements
txt, doc, chm support
Include icons for filetype emblems
Comic view modes

View File

@@ -724,7 +724,7 @@ class MainUI(QtWidgets.QMainWindow, mainwindow.Ui_MainWindow):
# The set_content method is universal
# It's going to do position tracking
current_tab = self.tabWidget.currentWidget()
current_tab.set_content(required_position)
current_tab.set_content(required_position, False, True)
def library_doubleclick(self, index):
sender = self.sender().objectName()

View File

@@ -737,7 +737,7 @@ class PliantWidgetsCommonFunctions:
return direction
current_tab.set_content(
current_position + direction + get_modifier(), True)
current_position + direction + get_modifier(), True, True)
# Set page position depending on if the chapter number is increasing or decreasing
if direction == 1 or was_button_pressed:
@@ -853,7 +853,7 @@ class PliantWidgetsCommonFunctions:
def set_toc_position(tocTree):
currentIndex = tocTree.currentIndex()
required_position = currentIndex.data(QtCore.Qt.UserRole)
self.pw.parent.set_content(required_position, True)
self.pw.parent.set_content(required_position, True, True)
# Create the Combobox / Treeview combination
tocComboBox = QtWidgets.QComboBox()

View File

@@ -220,7 +220,7 @@ class Bookmarks:
if is_parent:
chapter_number = self.parent.bookmarkProxyModel.data(
index, QtCore.Qt.UserRole)
self.parentTab.set_content(chapter_number, True)
self.parentTab.set_content(chapter_number, True, True)
return
chapter = self.parent.bookmarkProxyModel.data(
@@ -228,7 +228,7 @@ class Bookmarks:
cursor_position = self.parent.bookmarkProxyModel.data(
index, QtCore.Qt.UserRole + 1)
self.parentTab.set_content(chapter, True)
self.parentTab.set_content(chapter, True, True)
if not self.parentTab.are_we_doing_images_only:
self.parentTab.set_cursor_position(cursor_position)
@@ -500,7 +500,7 @@ class Search:
cursor_position = self.parent.searchResultsModel.data(index, QtCore.Qt.UserRole + 2)
search_term = self.parent.searchResultsModel.data(index, QtCore.Qt.UserRole + 4)
self.parentTab.set_content(chapter_number, True)
self.parentTab.set_content(chapter_number, True, True)
if not self.parentTab.are_we_doing_images_only:
self.parentTab.set_cursor_position(
cursor_position, len(search_term))

View File

@@ -64,8 +64,8 @@ class ParseFB2:
toc = []
content = []
for count, i in enumerate(self.book['book_list']):
toc.append((1, i[0], count + 1))
content.append(i[1])
toc.append((i[0], i[1], count + 1))
content.append(i[2])
# Return toc, content, images_only
return toc, content, False

View File

@@ -92,18 +92,50 @@ class FB2:
self.book['cover'] = None
def parse_chapters(self, temp_dir):
for i in self.xml.find_all('section'):
this_title = '<No title>'
for j in i:
if j.name == 'title':
this_title = j.getText(separator=' ')
this_title = this_title.replace('\n', '').strip()
# This comes later because the tag is changed in place
title_xml = j.unwrap()
break
# TODO
# Check what's up with recursion levels
# Why is the TypeError happening in get_title
self.book['book_list'].append(
[this_title, str(title_xml) + str(i)])
def get_title(element):
this_title = '<No title>'
title_xml = '<No title xml>'
try:
for i in element:
if i.name == 'title':
this_title = i.getText(separator=' ')
this_title = this_title.replace('\n', '').strip()
title_xml = str(i.unwrap())
break
except TypeError:
return None, None
return this_title, title_xml
def recursor(level, element):
children = element.findChildren('section', recursive=False)
if not children and level != 1:
this_title, title_xml = get_title(element)
self.book['book_list'].append(
[level, this_title, title_xml + str(element)])
else:
for i in children:
recursor(level + 1, i)
first_element = self.xml.find('section') # Recursive find
siblings = list(first_element.findNextSiblings('section', recursive=False))
siblings.insert(0, first_element)
for this_element in siblings:
this_title, title_xml = get_title(this_element)
# Do not add chapter content in case it has sections
# inside it. This prevents having large Book sections that
# have duplicated content
section_children = this_element.findChildren('section')
chapter_text = str(this_element)
if section_children:
chapter_text = this_title
self.book['book_list'].append([1, this_title, chapter_text])
recursor(1, this_element)
# Extract all images to the temp_dir
for i in self.xml.find_all('binary'):
@@ -113,7 +145,7 @@ class FB2:
replacement_string = f'<p></p><img src=\"{image_path}\"'
for j in self.book['book_list']:
j[1] = j[1].replace(
j[2] = j[2].replace(
image_string, replacement_string)
try:
image_data = base64.decodebytes(i.text.encode())
@@ -128,4 +160,4 @@ class FB2:
with open(cover_path, 'wb') as outimage:
outimage.write(self.book['cover'])
self.book['book_list'].insert(
0, ('Cover', f'<center><img src="{cover_path}" alt="Cover"></center>'))
0, (1, 'Cover', f'<center><img src="{cover_path}" alt="Cover"></center>'))

View File

@@ -109,7 +109,7 @@ class Tab(QtWidgets.QWidget):
self.hiddenButton.clicked.connect(self.set_cursor_position)
# All content must be set through this function
self.set_content(current_chapter, True)
self.set_content(current_chapter, True, False)
if not self.are_we_doing_images_only:
# Setting this later breaks cursor positioning for search results
self.hiddenButton.animateClick(50)
@@ -249,7 +249,7 @@ class Tab(QtWidgets.QWidget):
# Finally, to make sure the cover image isn't
# scrolled halfway through on first open,
if self.main_window.bookToolBar.tocBox.currentIndex() == 0:
if self.metadata['position']['current_chapter'] == 1:
self.contentView.verticalScrollBar().setValue(0)
def generate_position(self, is_read=False):
@@ -266,10 +266,8 @@ class Tab(QtWidgets.QWidget):
if not self.are_we_doing_images_only:
for i in self.metadata['content']:
chapter_html = i[1]
textDocument = QtGui.QTextDocument(None)
textDocument.setHtml(chapter_html)
textDocument.setHtml(i)
block_count = textDocument.blockCount()
blocks_per_chapter.append(block_count)
@@ -418,7 +416,7 @@ class Tab(QtWidgets.QWidget):
self.mouse_hide_timer.start(2000)
self.contentView.setFocus()
def set_content(self, required_position, tocBox_readjust=False):
def set_content(self, required_position, tocBox_readjust=False, record_position=False):
# All content changes must come through here
# This function will decide how to relate
# entries in the toc to the actual content
@@ -433,7 +431,8 @@ class Tab(QtWidgets.QWidget):
# Update the metadata dictionary to save position
self.metadata['position']['current_chapter'] = required_position
self.metadata['position']['is_read'] = False
if record_position:
self.contentView.record_position()
if self.are_we_doing_images_only:
self.contentView.loadImage(required_content)