Begin fb2 support
Fix Chinese translation
This commit is contained in:
		
							
								
								
									
										2
									
								
								TODO
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								TODO
									
									
									
									
									
								
							| @@ -84,6 +84,7 @@ TODO | ||||
|         Clean up 'switch' page layout | ||||
|         Colors aren't loaded properly for annotation previews | ||||
|         Cover page shouldn't be scolled midway | ||||
|         It's possible the addition function is also parsing the whole book. | ||||
|  | ||||
|     Secondary: | ||||
|         Graphical themes | ||||
| @@ -106,3 +107,4 @@ TODO | ||||
|         ? Add only one file type if multiple are present | ||||
|         ? Create emblem per filetype | ||||
|         In application notifications | ||||
|         Notification in case the filter is filtering out all files with no option in place | ||||
|   | ||||
| @@ -1,5 +1,3 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017-18 BasioMeusPuga | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017 BasioMeusPuga | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| @@ -19,7 +17,7 @@ | ||||
| import os | ||||
| import zipfile | ||||
|  | ||||
| from lector.ePub.read_epub import EPUB | ||||
| from lector.readers.read_epub import EPUB | ||||
|  | ||||
|  | ||||
| class ParseEPUB: | ||||
|   | ||||
							
								
								
									
										67
									
								
								lector/parsers/fb2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lector/parsers/fb2.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
|  | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
|  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import os | ||||
| import zipfile | ||||
|  | ||||
| from lector.readers.read_fb2 import FB2 | ||||
|  | ||||
|  | ||||
| class ParseFB2: | ||||
|     def __init__(self, filename, temp_dir, file_md5): | ||||
|         # TODO | ||||
|         # Maybe also include book description | ||||
|         self.book_ref = None | ||||
|         self.book = None | ||||
|         self.filename = filename | ||||
|         self.extract_path = os.path.join(temp_dir, file_md5) | ||||
|  | ||||
|     def read_book(self): | ||||
|         self.book_ref = FB2(self.filename) | ||||
|         contents_found = self.book_ref.read_fb2() | ||||
|         if not contents_found: | ||||
|             print('Cannot process: ' + self.filename) | ||||
|             return | ||||
|         self.book = self.book_ref.book | ||||
|  | ||||
|     def get_title(self): | ||||
|         return self.book['title'] | ||||
|  | ||||
|     def get_author(self): | ||||
|         return self.book['author'] | ||||
|  | ||||
|     def get_year(self): | ||||
|         return self.book['year'] | ||||
|  | ||||
|     def get_cover_image(self): | ||||
|         return self.book['cover'] | ||||
|  | ||||
|     def get_isbn(self): | ||||
|         return self.book['isbn'] | ||||
|  | ||||
|     def get_tags(self): | ||||
|         return self.book['tags'] | ||||
|  | ||||
|     def get_contents(self): | ||||
|         # TODO | ||||
|         # Make this save images to the temp path | ||||
|         # Relative file paths should then point there | ||||
|         # zipfile.ZipFile(self.filename).extractall(self.extract_path) | ||||
|  | ||||
|         # self.book_ref.parse_chapters(temp_dir=self.extract_path) | ||||
|         file_settings = { | ||||
|             'images_only': False} | ||||
|         return self.book['book_list'], file_settings | ||||
| @@ -1,7 +1,5 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017 BasioMeusPuga | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| @@ -24,7 +22,7 @@ import sys | ||||
| import shutil | ||||
| import zipfile | ||||
|  | ||||
| from lector.ePub.read_epub import EPUB | ||||
| from lector.readers.read_epub import EPUB | ||||
| import lector.KindleUnpack.kindleunpack as KindleUnpack | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| #!/usr/bin/env python3 | ||||
|  | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2018 BasioMeusPuga | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| @@ -16,6 +14,10 @@ | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| # TODO | ||||
| # Error handling | ||||
| # TOC parsing | ||||
|  | ||||
| import io | ||||
| import os | ||||
|  | ||||
|   | ||||
| @@ -1,7 +1,5 @@ | ||||
| #!/usr/bin/env python3 | ||||
| 
 | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017 BasioMeusPuga | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
| 
 | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| @@ -33,15 +31,18 @@ class EPUB: | ||||
|     def read_epub(self): | ||||
|         # This is the function that should error out in | ||||
|         # case the module cannot process the file | ||||
|         self.load_zip() | ||||
|         contents_path = self.get_file_path( | ||||
|             None, True) | ||||
|         try: | ||||
|             self.load_zip() | ||||
|             contents_path = self.get_file_path( | ||||
|                 None, True) | ||||
| 
 | ||||
|         if not contents_path: | ||||
|             return False  # No (valid) opf was found so processing cannot continue | ||||
|             if not contents_path: | ||||
|                 return False  # No (valid) opf was found so processing cannot continue | ||||
| 
 | ||||
|         self.generate_book_metadata(contents_path) | ||||
|         self.parse_toc() | ||||
|             self.generate_book_metadata(contents_path) | ||||
|             self.parse_toc() | ||||
|         except:  # Not specifying an exception type here may be justified | ||||
|             return False | ||||
| 
 | ||||
|         return True | ||||
| 
 | ||||
							
								
								
									
										82
									
								
								lector/readers/read_fb2.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								lector/readers/read_fb2.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| # This file is a part of Lector, a Qt based ebook reader | ||||
| # Copyright (C) 2017-2018 BasioMeusPuga | ||||
|  | ||||
| # This program is free software: you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | ||||
| # the Free Software Foundation, either version 3 of the License, or | ||||
| # (at your option) any later version. | ||||
|  | ||||
| # This program is distributed in the hope that it will be useful, | ||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
| # GNU General Public License for more details. | ||||
|  | ||||
| # You should have received a copy of the GNU General Public License | ||||
| # along with this program.  If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
| import os | ||||
| import base64 | ||||
| import zipfile | ||||
|  | ||||
| from bs4 import BeautifulSoup | ||||
|  | ||||
|  | ||||
| class FB2: | ||||
|     def __init__(self, filename): | ||||
|         self.filename = filename | ||||
|         self.zip_file = None | ||||
|         self.book = {} | ||||
|         self.xml = None | ||||
|  | ||||
|     def read_fb2(self): | ||||
|         try: | ||||
|             if self.filename.endswith('.fb2.zip'): | ||||
|                 this_book = zipfile.ZipFile(self.filename, mode='r', allowZip64=True) | ||||
|                 for i in this_book.filelist: | ||||
|                     if os.path.splitext(i.filename)[1] == '.fb2': | ||||
|                         book_text = this_book.read(i.filename) | ||||
|                         break | ||||
|             else: | ||||
|                 with open(self.filename, 'r') as book_file: | ||||
|                     book_text = book_file.read() | ||||
|  | ||||
|             self.xml = BeautifulSoup(book_text, 'lxml') | ||||
|             self.generate_book_metadata() | ||||
|         except:  # Not specifying an exception type here may be justified | ||||
|             return False | ||||
|  | ||||
|         return True | ||||
|  | ||||
|     def generate_book_metadata(self): | ||||
|         self.book['title'] = os.path.splitext( | ||||
|             os.path.basename(self.filename))[0] | ||||
|         self.book['author'] = 'Unknown' | ||||
|         self.book['isbn'] = None | ||||
|         self.book['tags'] = None | ||||
|         self.book['cover'] = None | ||||
|         self.book['year'] = 9999 | ||||
|         self.book['book_list'] = [] | ||||
|  | ||||
|         # TODO | ||||
|         # Look for other components of book metadata here | ||||
|         for i in self.xml.find_all(): | ||||
|  | ||||
|             if i.name == 'section': | ||||
|                 for j in i: | ||||
|                     if j.name == 'title': | ||||
|                         this_title = j.text | ||||
|                 self.book['book_list'].append( | ||||
|                     (this_title, str(i))) | ||||
|  | ||||
|         # Cover Image | ||||
|         cover_image_xml = self.xml.find('coverpage') | ||||
|         for i in cover_image_xml: | ||||
|             cover_image_name = i.get('l:href') | ||||
|  | ||||
|         cover_image_data = self.xml.find_all('binary') | ||||
|         for i in cover_image_data: | ||||
|  | ||||
|             # TODO | ||||
|             # Account for other images as well | ||||
|             if cover_image_name.endswith(i.get('id')): | ||||
|                 self.book['cover'] = base64.decodebytes(i.text.encode()) | ||||
| @@ -406,7 +406,7 @@ Reopen book to see changes</source> | ||||
|     <message> | ||||
|         <location filename="../../library.py" line="292"/> | ||||
|         <source>manually added</source> | ||||
|         <translation>手动添加</translation> | ||||
|         <translation>手动添加的</translation> | ||||
|     </message> | ||||
|     <message> | ||||
|         <location filename="../../library.py" line="215"/> | ||||
|   | ||||
| @@ -50,6 +50,7 @@ from lector import database | ||||
|  | ||||
| from lector.parsers.epub import ParseEPUB | ||||
| from lector.parsers.mobi import ParseMOBI | ||||
| from lector.parsers.fb2 import ParseFB2 | ||||
| from lector.parsers.comicbooks import ParseCOMIC | ||||
|  | ||||
| sorter = { | ||||
| @@ -59,6 +60,8 @@ sorter = { | ||||
|     'azw3': ParseMOBI, | ||||
|     'azw4': ParseMOBI, | ||||
|     'prc': ParseMOBI, | ||||
|     'fb2': ParseFB2, | ||||
|     'fb2.zip': ParseFB2, | ||||
|     'cbz': ParseCOMIC, | ||||
|     'cbr': ParseCOMIC} | ||||
|  | ||||
| @@ -172,7 +175,8 @@ class BookSorter: | ||||
|                     print(f'{os.path.basename(filename)} is already in database') | ||||
|                 return | ||||
|  | ||||
|         file_extension = os.path.splitext(filename)[1][1:] | ||||
|         # Using os.extsep like so allows for file extensions with multiple dots | ||||
|         file_extension = os.path.basename(filename).split(os.extsep, 1)[1] | ||||
|         try: | ||||
|             # Get the requisite parser from the sorter dict | ||||
|             book_ref = sorter[file_extension](filename, self.temp_dir, file_md5) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user