backend: convert input images to webp
This commit is contained in:
parent
d786d7f7af
commit
4921d4bd6f
5 changed files with 32 additions and 7 deletions
|
@ -4,6 +4,7 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||
from pathlib import Path
|
||||
|
||||
from vntypes import Novel, Mark
|
||||
from utils import *
|
||||
from db import VNDB
|
||||
|
||||
app = FastAPI()
|
||||
|
@ -42,7 +43,4 @@ async def novel_thumb(thumb: Annotated[bytes, File()], filename: str):
|
|||
|
||||
@app.post("/api/screenshot")
|
||||
async def screenshot(scrshot: Annotated[bytes, File()], filename: str):
|
||||
Path("screens/").mkdir(exist_ok=True)
|
||||
with open(Path("screens", filename), "wb") as file:
|
||||
file.write(scrshot)
|
||||
return {"file_size": len(scrshot)}
|
||||
return {"file_size": save_image(scrshot, "screens", filename)}
|
|
@ -1,8 +1,10 @@
|
|||
import sqlite3
|
||||
|
||||
from utils import asset
|
||||
|
||||
class VNDB:
|
||||
|
||||
def __init__(self, db_name='vn_database.db'):
|
||||
def __init__(self, db_name=asset('vn_database.db')):
|
||||
self.__db_name = db_name
|
||||
connection = sqlite3.connect(self.__db_name)
|
||||
cursor = connection.cursor()
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
-- Эта таблица нужна, чтобы когда человек набирает в поле ввода тег или жанр или бадж,
|
||||
-- ему подсказывало уже существующие теги/жанры/баджи
|
||||
CREATE TABLE IF NOT EXISTS mark (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
-- "genre" or "tag" or "badge"
|
||||
tag TEXT NOT NULL,
|
||||
-- value, "romance", "Хохлы", as an example
|
||||
value TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Таблица с авторами, для того же - чтобы подсказывало существующего автора.
|
||||
CREATE TABLE IF NOT EXISTS authors (
|
||||
-- ID автора, для кросс-референсов.
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
-- Имя автора.
|
||||
title TEXT NOT NULL,
|
||||
-- Описание автора.
|
||||
description TEXT NOT NULL,
|
||||
-- Путь к файлу обложки автора.
|
||||
thumbnail TEXT NOT NULL
|
||||
);
|
||||
|
||||
-- Сами новеллы. Нужно, поскольку несколько постов могут отсылаться к одной игре.
|
||||
CREATE TABLE IF NOT EXISTS novels (
|
||||
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
-- Название. Используется исключительно для поиска.
|
||||
title TEXT NOT NULL,
|
||||
author INTEGER NOT NULL
|
||||
);
|
||||
|
||||
-- Таблица с **постами**.
|
||||
CREATE TABLE IF NOT EXISTS posts_log (
|
||||
-- Кросс-референс на id в novels.
|
||||
novel INTEGER NOT NULL,
|
||||
|
||||
-- ID канала, в который пост будет запощен.
|
||||
channel INTEGER NOT NULL,
|
||||
|
||||
-- массив idшников на записи в marks.
|
||||
marks JSON NOT NULL,
|
||||
|
||||
-- Название внки.
|
||||
title TEXT NOT NULL,
|
||||
|
||||
-- Описание ВНки.
|
||||
description TEXT NOT NULL,
|
||||
|
||||
-- id автора на момент планирования поста.
|
||||
author INTEGER NOT NULL,
|
||||
|
||||
-- Мапа, ключ - путь к файлу в фс, значение -
|
||||
-- `{"post": <POST_LINK>, "description": "описание файла"}`
|
||||
-- <POST_LINK> - ссылка на пост в соответствующем канале с файлами, может
|
||||
-- быть null. Не должно быть null, если post_info != NULL (то есть если уже запостили).
|
||||
files_on_disk JSON NOT NULL,
|
||||
-- не NULL, если пост успешно запостили.
|
||||
-- {"link": <ссылка на пост>}
|
||||
post_info JSON,
|
||||
-- Когда ВН должна быть запощена, second-precise unix timestamp.
|
||||
post_at INTEGER NOT NULL,
|
||||
-- Когда запись в бд была создана, second-precise unix timestamp.
|
||||
created_at INTEGER NOT NULL
|
||||
);
|
25
backend/utils.py
Normal file
25
backend/utils.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from PIL import Image, UnidentifiedImageError
|
||||
from pathlib import Path
|
||||
import io
|
||||
|
||||
def asset(path: str) -> Path:
|
||||
return Path("store", path)
|
||||
|
||||
|
||||
def image_normalize(img: bytes) -> bytes:
|
||||
try:
|
||||
byte_arr = io.BytesIO()
|
||||
img = Image.open(io.BytesIO(img))
|
||||
img.save(byte_arr, format='WEBP')
|
||||
return byte_arr.getvalue()
|
||||
except UnidentifiedImageError:
|
||||
return 0
|
||||
|
||||
def save_image(img: bytes, dir: str, name: str) -> int:
|
||||
path = asset(dir)
|
||||
path.mkdir(exist_ok=True)
|
||||
img = image_normalize(img)
|
||||
if img:
|
||||
with open(Path(path, name+'.webp'), "wb") as file:
|
||||
file.write(img)
|
||||
return len(img)
|
Loading…
Add table
Add a link
Reference in a new issue