backend: prepare to adding posts to database

This commit is contained in:
OleSTEEP 2025-10-05 22:07:45 +03:00
parent 59d092c9d0
commit c95aed01b5
4 changed files with 65 additions and 39 deletions

View file

@ -67,4 +67,4 @@ async def upload_screenshot(scrshot: Annotated[bytes, File()], filename: str):
@app.post("/api/file")
async def upload_file(file: Annotated[bytes, File()], filename: str):
return {"file_size": save_file(file, "files", filename)}
return {"file_size": save_file(file, "files", filename)}

View file

@ -1,7 +1,9 @@
from datetime import datetime
import sqlite3
import json
from utils import asset
from vntypes import Mark
from vntypes import *
class VNDB:
@ -14,7 +16,8 @@ class VNDB:
CREATE TABLE IF NOT EXISTS marks (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL,
value TEXT NOT NULL
value TEXT NOT NULL,
UNIQUE(id, value)
);
''')
@ -23,7 +26,8 @@ class VNDB:
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
description TEXT NOT NULL,
thumbnail TEXT NOT NULL
thumbnail TEXT NOT NULL,
UNIQUE(id, title, description, thumbnail)
);
''')
@ -31,58 +35,77 @@ class VNDB:
CREATE TABLE IF NOT EXISTS novels (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
author INTEGER NOT NULL
author INTEGER NOT NULL,
UNIQUE(id, title, author)
);
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS posts_log (
novel INTEGER NOT NULL,
channel INTEGER NOT NULL,
marks JSON NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
author INTEGER NOT NULL,
files_on_disk JSON NOT NULL,
post_info JSON,
post_at INTEGER NOT NULL,
created_at INTEGER NOT NULL
novel INTEGER NOT NULL,
channel INTEGER NOT NULL,
marks JSON NOT NULL,
title TEXT NOT NULL,
description TEXT NOT NULL,
author INTEGER NOT NULL,
files_on_disk JSON NOT NULL,
post_info JSON,
post_at INTEGER NOT NULL,
created_at INTEGER NOT NULL
);
''')
connection.commit()
def __execute(self, sql: str, params: tuple):
def __execute(self, sql: str, params: tuple = ()):
with sqlite3.connect(self.__db_name) as connection:
connection.cursor().execute(sql, params)
connection.commit()
def __fetch(self, sql: str, params: tuple):
def __fetch(self, sql: str, params: tuple = ()):
with sqlite3.connect(self.__db_name) as connection:
cursor = connection.cursor()
cursor.execute(sql, params)
return cursor.fetchall()
def insert_mark(self, type: str, value: str):
self.__execute("INSERT INTO marks (type, value) "
"VALUES (?, ?)", (type, value))
def search_mark(self, query: Mark):
return self.__fetch("SELECT type, value FROM marks "
def search_author(self, title: str):
return self.__fetch("SELECT * FROM authors "
"WHERE title LIKE ?", (title,))
def search_mark(self, mark: Mark):
return self.__fetch("SELECT * FROM marks "
"WHERE value LIKE ? "
"AND type = ?", ('%'+query.value+'%',query.type))
def insert_novel(self, title: str, author_id: int):
self.__execute("INSERT INTO novels (title, author) "
"VALUES (?, ?)", (title, author_id))
"AND type = ?", ('%'+mark.value+'%',mark.type))
def search_novel(self, title: str):
return self.__fetch("SELECT * FROM novels "
"WHERE title LIKE ? ", (title,))
def insert_author(self, title: str, desc: str, thumb: str):
self.__execute("INSERT INTO authors (title, description, thumbnail) "
"VALUES (?, ?, ?)", (title, desc, thumb))
def insert_mark(self, type: str, value: str):
self.__execute("INSERT INTO marks (type, value) "
"VALUES (?, ?)", (type, value))
def insert_novel(self, novel: Novel):
self.__execute("INSERT INTO novels (title, author) "
f"SELECT {novel.title}, {novel.author_id} "
f"WHERE NOT EXISTS(SELECT 1 FROM novels WHERE title = {novel.title} AND author = {novel.author_id});")
# FIXME: SQL Types
def insert_post(self, full_novel: FullNovel):
self.insert_novel(full_novel.data)
self.__execute("INSERT INTO posts_log (novel, channel, marks, title, description, author, files_on_disk, post_at, created_at) "
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
(self.search_novel(full_novel.data.title)[0],
full_novel.data.tg_channel,
json.dumps(full_novel.data.marks),
full_novel.data.title,
full_novel.data.description,
full_novel.data.author_id,
json.dumps(full_novel.files),
full_novel.data.post_at,
datetime.now()))

View file

@ -14,14 +14,14 @@ class NovelFile(BaseModel):
class Novel(BaseModel):
title: str
description: str
author_id: int
vndb: int | None = None
hours_to_read: int
tags: list[str]
genres: list[str]
badges: list[str]
marks: list[Mark]
tg_channel: int # maybe not here
tg_post: str | None = None #url::Url
post_at: datetime | None = None

View file

@ -53,11 +53,14 @@ CREATE TABLE IF NOT EXISTS posts_log (
-- <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
);