forked from LiveCarta/BookConverter
92 lines
2.7 KiB
Python
92 lines
2.7 KiB
Python
import re
|
|
from typing import List, Dict, Union
|
|
|
|
from ebooklib.epub import Section, Link
|
|
from src.livecarta_config import LiveCartaConfig
|
|
|
|
|
|
class NavPoint:
|
|
"""
|
|
Class - Navigation Point, - every html|xhtml from epub
|
|
These are data structures which form mapping from NCX to python data structures.
|
|
"""
|
|
|
|
def __init__(self, obj: Union[Link, Section] = None):
|
|
self.href, self.id = self.parse_href_id(obj)
|
|
self.title = obj.title
|
|
|
|
@staticmethod
|
|
def parse_href_id(item: Union[Link, Section]):
|
|
"""Function parses href & id from item.href"""
|
|
reg = r'(.+\..+\#)(.+)'
|
|
match = re.search(reg, item.href)
|
|
href, div_id = None, None
|
|
if match:
|
|
div_id = match.group(2)
|
|
if match.group(1):
|
|
href = match.group(1)[:-1]
|
|
else:
|
|
reg2 = r'(.+\..+)'
|
|
match2 = re.search(reg2, item.href)
|
|
if match2 and match2.group(1):
|
|
href = match2.group(1)
|
|
|
|
return href, div_id
|
|
|
|
def __str__(self):
|
|
return '<NavPoint: %s, %s>' % (self.href, self.id)
|
|
|
|
|
|
def flatten(x):
|
|
"""Magic function from stackoverflow for list flattening"""
|
|
atom = lambda i: not isinstance(i, list)
|
|
nil = lambda i: not i
|
|
car = lambda i: i[0]
|
|
cdr = lambda i: i[1:]
|
|
cons = lambda i, y: i + y
|
|
|
|
res = [x] if atom(x) else x if nil(x) else cons(*map(flatten, [car(x), cdr(x)]))
|
|
return res
|
|
|
|
|
|
class ChapterItem:
|
|
"""
|
|
Class of Chapter that could have subchapters
|
|
These are data structures which form mapping to LiveCarta json structure.
|
|
"""
|
|
|
|
def __init__(self, title: str, content: str, sub_items: List):
|
|
self.title = title
|
|
self.content = content
|
|
self.sub_items = sub_items
|
|
|
|
def to_dict(self, lvl: int = 1) -> Dict[str, Union[str, List]]:
|
|
"""Function returns dictionary of chapter"""
|
|
sub_dicts = []
|
|
if self.sub_items:
|
|
for i in self.sub_items:
|
|
sub_dicts.append(i.to_dict(lvl + 1))
|
|
|
|
if lvl > LiveCartaConfig.SUPPORTED_LEVELS:
|
|
return {
|
|
"title": self.title,
|
|
"contents": [self.content] + [x['contents'] for x in sub_dicts],
|
|
"sub_items": []
|
|
}
|
|
|
|
if (lvl == LiveCartaConfig.SUPPORTED_LEVELS) and sub_dicts:
|
|
return {
|
|
"title": self.title,
|
|
"contents": [self.content] + flatten([x['contents'] for x in sub_dicts]),
|
|
"sub_items": []
|
|
}
|
|
|
|
return {
|
|
"title": self.title,
|
|
"contents": [self.content],
|
|
"sub_items": sub_dicts
|
|
}
|
|
|
|
def __str__(self):
|
|
return '<Chapter: %s>' % self.title
|