Changed response format and added its schema, fixed some errors

This commit is contained in:
Dmitriy Shishkov 2021-07-02 03:58:12 +05:00
parent 4eae488f45
commit e5ade4b81e
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
4 changed files with 51 additions and 25 deletions

View File

@ -1,5 +1,6 @@
import aiofiles as aiof import aiofiles as aiof
from base64 import b64encode from base64 import b64encode
from fastapi import HTTPException
import ebooklib import ebooklib
from ebooklib import epub from ebooklib import epub
@ -8,6 +9,7 @@ from tempfile import SpooledTemporaryFile
from .utils import Document_Tokens from .utils import Document_Tokens
async def epub2html(file: SpooledTemporaryFile) -> str: async def epub2html(file: SpooledTemporaryFile) -> str:
""" """
@ -22,10 +24,12 @@ async def epub2html(file: SpooledTemporaryFile) -> str:
# TODO: join tokens to HTML # TODO: join tokens to HTML
html_content = "" html_content = ""
... ...
return html_content return {**(tokens["metadata"]), "content": html_content}
except Exception as e: except Exception as e:
return "Error! Wrong epub file format: " + str(e) raise HTTPException(
status_code=500, detail="Error! Wrong epub file format: " + str(e)
)
async def epub_to_tokens(file: SpooledTemporaryFile) -> Document_Tokens: async def epub_to_tokens(file: SpooledTemporaryFile) -> Document_Tokens:
@ -89,4 +93,4 @@ def convert_list(titles_list: list[tuple[str, dict[str, str]]]):
for title_obj in titles_list: for title_obj in titles_list:
res.append(title_obj[0]) res.append(title_obj[0])
return "; ".join(res) return "; ".join(res)

View File

@ -1,7 +1,8 @@
from tempfile import SpooledTemporaryFile from tempfile import SpooledTemporaryFile
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element from xml.etree.ElementTree import Element
from typing import Optional from typing import Optional, Union
from fastapi import HTTPException
from .utils import Document_Tokens from .utils import Document_Tokens
@ -13,21 +14,23 @@ namespaces = {
HREF = f"{{{namespaces['xlink']}}}href" HREF = f"{{{namespaces['xlink']}}}href"
async def fb22html(file: SpooledTemporaryFile) -> str: async def fb22html(file: SpooledTemporaryFile) -> dict[str, str]:
""" """
Splits fb2 to tokens and joins them to one html file Splits fb2 to tokens and joins them to one html file
""" """
try: try:
tokens = fb22tokens(file) tokens = fb22tokens(file)
set_cover(tokens)
html_content = fb2body2html(tokens) html_content = fb2body2html(tokens)
return html_content return {**(tokens["metadata"]), "content": html_content}
except Exception as e: except Exception as e:
return "Error! Wrong FB2 file format: " + str(e) raise HTTPException(
status_code=500, detail="Error! Wrong fb2 file format: " + str(e)
)
def fb22tokens(file: SpooledTemporaryFile) -> Document_Tokens: def fb22tokens(file: SpooledTemporaryFile) -> Document_Tokens:
@ -46,7 +49,10 @@ def fb22tokens(file: SpooledTemporaryFile) -> Document_Tokens:
""" """
tokens = { tokens = {
"metadata": {}, "metadata": {
"title": "",
"author": "",
},
"content": b"<root>", "content": b"<root>",
} }
@ -59,13 +65,13 @@ def fb22tokens(file: SpooledTemporaryFile) -> Document_Tokens:
# Reading book metadata # Reading book metadata
book_info = description.find("title-info") book_info = description.find("./title-info", namespaces)
if book_info: if book_info:
metadata = {} metadata = {}
metadata["title"] = book_info.find("book-title", namespaces).text metadata["title"] = book_info.find("./book-title", namespaces).text
metadata["author"] = get_author(book_info.find("author", namespaces)) metadata["author"] = get_author(book_info.find("./author", namespaces))
metadata["cover"] = get_cover(book_info.find("coverpage", namespaces)) metadata["cover"] = get_cover(book_info.find("./coverpage", namespaces))
if metadata["cover"] is None: if not 'cover' in metadata.keys():
metadata.pop("cover") metadata.pop("cover")
if len(metadata.keys()): if len(metadata.keys()):
@ -101,11 +107,11 @@ def get_author(author: Element) -> str:
"middle-name", "middle-name",
"last-name", "last-name",
): ):
el = author.find(tag_name, namespaces) el = author.find("./" + tag_name, namespaces)
if not el is None: if not el is None:
res.append(el.text) res.append(el.text)
if len(res) == 0: if len(res) == 0:
res = author.find("nickname", namespaces).text res = author.find("./nickname", namespaces).text
else: else:
res = " ".join(res) res = " ".join(res)
@ -119,7 +125,15 @@ def get_cover(coverpage: Optional[Element]) -> Optional[str]:
""" """
if coverpage: if coverpage:
return coverpage.find("image", namespaces).get(HREF) return coverpage.find("./image", namespaces).get(HREF)
def set_cover(tokens: Document_Tokens) -> None:
cover = tokens["metadata"]["cover"]
if cover is None:
tokens["metadata"]["cover"] = "none"
elif cover[0] == "#":
tokens["metadata"]["cover"] = tokens[cover[1:]]
def fb2body2html(tokens: Document_Tokens) -> str: def fb2body2html(tokens: Document_Tokens) -> str:

View File

@ -1,8 +1,10 @@
from fastapi import FastAPI, File, UploadFile from fastapi import FastAPI, File, UploadFile, HTTPException
from fastapi.responses import HTMLResponse from fastapi.responses import HTMLResponse
from typing import Union
from .epub import epub2html from .epub import epub2html
from .fb2 import fb22html from .fb2 import fb22html
from .utils import HTMLBook
app = FastAPI() app = FastAPI()
@ -12,14 +14,12 @@ def root():
return "Hello, World!" return "Hello, World!"
@app.post( @app.post("/uploadfile/", response_model=HTMLBook)
"/uploadfile/",
)
async def create_upload_file(file: UploadFile = File(...)): async def create_upload_file(file: UploadFile = File(...)):
if file.filename.endswith(".epub"): if file.filename.endswith(".epub"):
content = await epub2html(file.file) content = await epub2html(file.file)
elif file.filename.endswith(".fb2"): elif file.filename.endswith(".fb2"):
content = await fb22html(file.file) content = await fb22html(file.file)
else: else:
content = "Error! Unsupported file type" raise HTTPException(status_code=415, detail="Error! Unsupported file type")
return HTMLResponse(content=content) return content

View File

@ -1,3 +1,11 @@
from typing import Union from typing import Union, Optional
from pydantic import BaseModel
Document_Tokens = dict[str, Union[str, dict[str, str]]] Document_Tokens = dict[str, Union[str, dict[str, str]]]
class HTMLBook(BaseModel):
title: str
author: str
cover: Optional[str]
content: str