Make code compatible with python 3.7, removed unused imports, change static methods.

This commit is contained in:
Vaso Peras-Likodric 2022-09-14 17:45:48 +02:00
parent 4a6d9d8b2b
commit ca45bcaaf5
10 changed files with 68 additions and 52 deletions

View File

@ -2,6 +2,8 @@ __license__ = 'GPL v3'
__copyright__ = '2011, John Schember <john at nachtimwald.com>, refactored: 2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from typing import Optional, Dict
'''
Generates and writes an APNX page mapping file.
'''
@ -17,8 +19,6 @@ from polyglot.builtins import as_unicode, as_bytes
from calibre.devices.kindle.apnx_page_generator.generators.accurate_page_generator import AccuratePageGenerator
from calibre.devices.kindle.apnx_page_generator.generators.pagebreak_page_generator import PagebreakPageGenerator
from calibre.devices.kindle.apnx_page_generator.generators.aria_pagebreak_page_generator import \
AriaPagebreakPageGenerator
from calibre.devices.kindle.apnx_page_generator.generators.exact_page_generator import ExactPageGenerator
from calibre.devices.kindle.apnx_page_generator.generators.fast_page_generator import FastPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator
@ -30,14 +30,14 @@ class APNXBuilder:
Create an APNX file using a pseudo page mapping.
"""
generators: dict[str, IPageGenerator] = {
generators: Dict[str, IPageGenerator] = {
FastPageGenerator.instance.name(): FastPageGenerator.instance,
AccuratePageGenerator.instance.name(): AccuratePageGenerator.instance,
PagebreakPageGenerator.instance.name(): PagebreakPageGenerator.instance,
# ExactPageGenerator.instance.name(): ExactPageGenerator.instance,
}
def write_apnx(self, mobi_file_path: str, apnx_path: str, method: str | None = None, page_count: int = 0):
def write_apnx(self, mobi_file_path: str, apnx_path: str, method: Optional[str] = None, page_count: int = 0):
"""
If you want a fixed number of pages (such as from a custom column) then
pass in a value to page_count, otherwise a count will be estimated
@ -62,7 +62,7 @@ class APNXBuilder:
fsync(apnxf)
@staticmethod
def get_apnx_meta(mobi_file_path) -> dict[str, str]:
def get_apnx_meta(mobi_file_path) -> Dict[str, str]:
import uuid
apnx_meta = {
'guid': str(uuid.uuid4()).replace('-', '')[:8],

View File

@ -2,20 +2,24 @@ __license__ = 'GPL v3'
__copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from typing import Optional
from calibre.devices.kindle.apnx_page_generator.generators.fast_page_generator import FastPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator, mobi_html
from calibre.devices.kindle.apnx_page_generator.pages import Pages
class AccuratePageGenerator(IPageGenerator):
instance = None
def name(self) -> str:
return "accurate"
def _generate_fallback(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate_fallback(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
return FastPageGenerator.instance.generate(mobi_file_path, real_count)
def _generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
"""
A more accurate but much more resource intensive and slower
method to calculate the page length.
@ -35,7 +39,7 @@ class AccuratePageGenerator(IPageGenerator):
"""
pages = []
html = self.mobi_html(mobi_file_path)
html = mobi_html(mobi_file_path)
# States
in_tag = False
@ -54,7 +58,7 @@ class AccuratePageGenerator(IPageGenerator):
# and string functions will parse the text each
# time they are called.
#
# We can can use .lower() here because we are
# We can use .lower() here because we are
# not modifying the text. In this case the case
# doesn't matter just the absolute character and
# the position within the stream.

View File

@ -2,20 +2,24 @@ __license__ = 'GPL v3'
__copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from typing import Optional
from calibre.devices.kindle.apnx_page_generator.generators.fast_page_generator import FastPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator, mobi_html_length
from calibre.devices.kindle.apnx_page_generator.pages import Pages
class ExactPageGenerator(IPageGenerator):
instance = None
def name(self) -> str:
return "exact"
def _generate_fallback(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate_fallback(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
return FastPageGenerator.instance.generate(mobi_file_path, real_count)
def _generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
"""
Given a specified page count (such as from a custom column),
create our array of pages for the apnx file by dividing by
@ -24,7 +28,7 @@ class ExactPageGenerator(IPageGenerator):
pages = []
count = 0
text_length = self.mobi_html_length(mobi_file_path)
text_length = mobi_html_length(mobi_file_path)
chars_per_page = int(text_length // real_count)
while count < text_length:

View File

@ -2,7 +2,9 @@ __license__ = 'GPL v3'
__copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator
from typing import Optional
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator, mobi_html_length
from calibre.devices.kindle.apnx_page_generator.pages import Pages
@ -11,10 +13,10 @@ class FastPageGenerator(IPageGenerator):
def name(self) -> str:
return "fast"
def _generate_fallback(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate_fallback(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
raise Exception("Fast calculation impossible.")
def _generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
"""
2300 characters of uncompressed text per page. This is
not meant to map 1 to 1 to a print book but to be a
@ -34,7 +36,7 @@ class FastPageGenerator(IPageGenerator):
pages = []
count = 0
text_length = self.mobi_html_length(mobi_file_path)
text_length = mobi_html_length(mobi_file_path)
while count < text_length:
pages.append(count)

View File

@ -2,8 +2,10 @@ __license__ = 'GPL v3'
__copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from typing import Optional
from calibre.devices.kindle.apnx_page_generator.generators.fast_page_generator import FastPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator
from calibre.devices.kindle.apnx_page_generator.i_page_generator import IPageGenerator, mobi_html
from calibre.devices.kindle.apnx_page_generator.pages import Pages
import re
@ -13,12 +15,12 @@ class PagebreakPageGenerator(IPageGenerator):
def name(self) -> str:
return "pagebreak"
def _generate_fallback(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate_fallback(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
return FastPageGenerator.instance.generate(mobi_file_path, real_count)
def _generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
""" Determine pages based on the presence of <*pagebreak*/>. """
html = self.mobi_html(mobi_file_path)
html = mobi_html(mobi_file_path)
pages = []
for m in re.finditer(b'<[^>]*pagebreak[^>]*>', html):
pages.append(m.end())

View File

@ -4,6 +4,8 @@ __docformat__ = 'restructuredtext en'
import struct
from abc import abstractmethod, ABCMeta
from typing import Optional
from calibre.devices.kindle.apnx_page_generator.pages import Pages
from calibre.ebooks.mobi.reader.mobi6 import MobiReader
from calibre.utils.logging import default_log
@ -14,14 +16,14 @@ from calibre.ebooks.pdb.header import PdbHeaderReader
class IPageGenerator(metaclass=ABCMeta):
@abstractmethod
def _generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
pass
@abstractmethod
def _generate_fallback(self, mobi_file_path: str, real_count: int | None) -> Pages:
def _generate_fallback(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
pass
def generate(self, mobi_file_path: str, real_count: int | None) -> Pages:
def generate(self, mobi_file_path: str, real_count: Optional[int]) -> Pages:
try:
result = self._generate(mobi_file_path, real_count)
if result.number_of_pages > 0:
@ -36,18 +38,17 @@ class IPageGenerator(metaclass=ABCMeta):
def name(self) -> str:
pass
@staticmethod
def mobi_html(mobi_file_path: str) -> bytes:
def mobi_html(mobi_file_path: str) -> bytes:
mr = MobiReader(mobi_file_path, default_log)
if mr.book_header.encryption_type != 0:
raise Exception("DRMed book")
mr.extract_text()
return as_bytes(mr.mobi_html.lower())
@staticmethod
def mobi_html_length(mobi_file_path: str) -> int:
def mobi_html_length(mobi_file_path: str) -> int:
with lopen(mobi_file_path, 'rb') as mf:
pdb_header = PdbHeaderReader(mf)
r0 = pdb_header.section_data(0)
return struct.unpack('>I', r0[4:8])[0]

View File

@ -2,30 +2,32 @@ __license__ = 'GPL v3'
__copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
from typing import Union, List, Tuple
from calibre.devices.kindle.apnx_page_generator.page_number_type import PageNumberTypes
class PageGroup:
"""Simulate constructor overloading"""
def __init__(self, page_locations: int | list[int], page_number_type: PageNumberTypes, first_value: int,
page_labels: str | list[str] | None = None):
def __init__(self, page_locations: Union[int, List[int]], page_number_type: PageNumberTypes, first_value: int,
page_labels: Union[str, List[str], None] = None):
if page_locations.__class__ == int:
self.page_locations: list[int] = [page_locations]
self.page_locations: List[int] = [page_locations]
else:
self.page_locations: list[int] = page_locations
self.page_locations: List[int] = page_locations
self.__page_number_type: PageNumberTypes = page_number_type
self.__first_value = first_value
if page_number_type == PageNumberTypes.Custom:
assert(page_labels is not None)
if page_labels.__class__ == str:
assert (1 == len(self.page_locations) and len(page_labels) > 0)
self.__page_number_labels: list[str] = [page_labels]
self.__page_number_labels: List[str] = [page_labels]
else:
assert (len(page_labels) == len(self.page_locations))
assert(all(len(label) > 0 for label in page_labels))
self.__page_number_labels: list[str] = page_labels
self.__page_number_labels: List[str] = page_labels
def append(self, page_location: int | tuple[int, str]) -> None:
def append(self, page_location: Union[int, Tuple[int, str]]) -> None:
if page_location.__class__ == int:
assert (self.__page_number_type != PageNumberTypes.Custom)
self.page_locations.append(page_location)

View File

@ -5,7 +5,7 @@ __docformat__ = 'restructuredtext en'
import enum
class PageNumberTypes(str, enum.Enum):
class PageNumberTypes(enum.Enum):
Arabic = "a"
Roman = "r"
Custom = 'c'
Custom = "c"

View File

@ -3,17 +3,18 @@ __copyright__ = '2022, Vaso Peras-Likodric <vaso at vipl.in.rs>'
__docformat__ = 'restructuredtext en'
import itertools
from typing import Optional, List
from calibre.devices.kindle.apnx_page_generator.page_group import PageGroup
from calibre.devices.kindle.apnx_page_generator.page_number_type import PageNumberTypes
class Pages:
def __init__(self, page_locations: list[int] | None = None):
def __init__(self, page_locations: Optional[List[int]] = None):
if page_locations.__class__ == list:
self.__pages_groups: list[PageGroup] = [PageGroup(page_locations, PageNumberTypes.Arabic, 1)]
self.__pages_groups: List[PageGroup] = [PageGroup(page_locations, PageNumberTypes.Arabic, 1)]
else:
self.__pages_groups: list[PageGroup] = []
self.__pages_groups: List[PageGroup] = []
def append(self, page_location: PageGroup) -> None:
self.__pages_groups.append(page_location)
@ -33,7 +34,7 @@ class Pages:
return ",".join(result)
@property
def page_locations(self) -> list[int]:
def page_locations(self) -> List[int]:
return list(itertools.chain.from_iterable(list(map(lambda pg: pg.page_locations, self.__pages_groups))))
@property

View File

@ -411,7 +411,7 @@ class KINDLE2(KINDLE):
OPT_APNX_CUST_COL = 2
OPT_APNX_METHOD_COL = 3
OPT_APNX_OVERWRITE = 4
EXTRA_CUSTOMIZATION_CHOICES = {OPT_APNX_METHOD: APNXBuilder.generators.keys()}
EXTRA_CUSTOMIZATION_CHOICES = {OPT_APNX_METHOD: set(APNXBuilder.generators.keys())}
# x330 on the PaperWhite
# x262 on the Touch. Doesn't choke on x330, though.