refactor: many changes
- Add missing actions and make a clear boundary between actions, services and nfra (i.e: actions shouldn't use stuff from infra/) - Delete stuff not in use: tts, gtts, etc - Add a ton of tests
This commit is contained in:
parent
b2185f4174
commit
152546982c
46 changed files with 2328 additions and 700 deletions
|
|
@ -1,17 +1,31 @@
|
|||
from litestar import Request
|
||||
from litestar.exceptions import HTTPException
|
||||
|
||||
from huesoporro.actions.authenticate import AuthenticateAction
|
||||
from huesoporro.actions.get_user_by_jwt import GetUserByJWTAction
|
||||
from huesoporro.actions.chatbot.create_or_update_chatbot import (
|
||||
CreateOrUpdateChatbotAction,
|
||||
)
|
||||
from huesoporro.actions.chatbot.get_chatbot_by_user_id import GetChatbotByUserIdAction
|
||||
from huesoporro.actions.users.authenticate_user import AuthenticateUserAction
|
||||
from huesoporro.actions.users.get_user_by_jwt import GetUserByJWTAction
|
||||
from huesoporro.infra.authenticator import TwitchAuthenticator
|
||||
from huesoporro.infra.db import Database
|
||||
from huesoporro.infra.repos import UserRepo
|
||||
from huesoporro.infra.repos import ChatbotRepo, UserRepo
|
||||
from huesoporro.libs.db import MarkovDatabase
|
||||
from huesoporro.models import User
|
||||
from huesoporro.models import Chatbot, User
|
||||
from huesoporro.settings import Settings
|
||||
from huesoporro.svc.get_chatbot_settings import ChatbotSettingsGetterSvc
|
||||
from huesoporro.svc.chatbot_svcs import (
|
||||
CreateChatbotSvc,
|
||||
GetChatbotByUserIdSvc,
|
||||
UpdateChatbotSvc,
|
||||
)
|
||||
from huesoporro.svc.store import SentenceStorerSvc
|
||||
from huesoporro.svc.store_settings import ChatbotSettingsStorerSvc
|
||||
from huesoporro.svc.users_svcs import (
|
||||
CreateUserSvc,
|
||||
GetTwitchAuthByAuthCodeSvc,
|
||||
GetUserByUsernameSvc,
|
||||
IsValidTokenSvc,
|
||||
RefreshTokenSvc,
|
||||
UpdateUserSvc,
|
||||
)
|
||||
|
||||
|
||||
def get_settings() -> Settings:
|
||||
|
|
@ -22,14 +36,62 @@ def get_authenticator(s: Settings) -> TwitchAuthenticator:
|
|||
return TwitchAuthenticator(s=s)
|
||||
|
||||
|
||||
def get_db(s: Settings):
|
||||
return Database(s=s)
|
||||
def get_chatbot_repo(s: Settings):
|
||||
return ChatbotRepo(s=s)
|
||||
|
||||
|
||||
def get_get_chatbot_by_user_id_svc(chatbot_repo: ChatbotRepo):
|
||||
return GetChatbotByUserIdSvc(repo=chatbot_repo)
|
||||
|
||||
|
||||
def get_get_tokens_by_auth_code_svc(
|
||||
twitch_authenticator: TwitchAuthenticator, s: Settings
|
||||
):
|
||||
return GetTwitchAuthByAuthCodeSvc(s=s, authenticator=twitch_authenticator)
|
||||
|
||||
|
||||
def get_create_chatbot_svc(chatbot_repo: ChatbotRepo):
|
||||
return CreateChatbotSvc(repo=chatbot_repo)
|
||||
|
||||
|
||||
async def get_user_repo(s: Settings):
|
||||
return UserRepo(s=s)
|
||||
|
||||
|
||||
def get_create_user_svc(user_repo: UserRepo):
|
||||
return CreateUserSvc(user_repo=user_repo)
|
||||
|
||||
|
||||
def get_update_user_svc(user_repo: UserRepo):
|
||||
return UpdateUserSvc(user_repo=user_repo)
|
||||
|
||||
|
||||
def get_refresh_token_svc(twitch_authenticator: TwitchAuthenticator):
|
||||
return RefreshTokenSvc(twitch_authenticator=twitch_authenticator)
|
||||
|
||||
|
||||
def get_is_valid_token_svc(twitch_authenticator: TwitchAuthenticator):
|
||||
return IsValidTokenSvc(authenticator=twitch_authenticator)
|
||||
|
||||
|
||||
async def get_get_user_by_username_svc(user_repo: UserRepo):
|
||||
return GetUserByUsernameSvc(user_repo=user_repo)
|
||||
|
||||
|
||||
async def get_get_user_by_jwt_action(
|
||||
user_repo: UserRepo, authenticator: TwitchAuthenticator, s: Settings
|
||||
get_user_by_username_svc: GetUserByUsernameSvc,
|
||||
update_user_svc: UpdateUserSvc,
|
||||
is_valid_token_svc: IsValidTokenSvc,
|
||||
refresh_token_svc: RefreshTokenSvc,
|
||||
s: Settings,
|
||||
):
|
||||
return GetUserByJWTAction(user_repo=user_repo, authenticator=authenticator, s=s)
|
||||
return GetUserByJWTAction(
|
||||
get_user_by_username_svc=get_user_by_username_svc,
|
||||
update_user_svc=update_user_svc,
|
||||
refresh_token_svc=refresh_token_svc,
|
||||
is_valid_token_svc=is_valid_token_svc,
|
||||
s=s,
|
||||
)
|
||||
|
||||
|
||||
async def authenticate(
|
||||
|
|
@ -37,32 +99,73 @@ async def authenticate(
|
|||
) -> User:
|
||||
token = request.query_params.get("huesoporro_token")
|
||||
if token:
|
||||
return await get_user_by_jwt_action.run(token)
|
||||
user = await get_user_by_jwt_action.run(token)
|
||||
if not user:
|
||||
raise HTTPException(detail="User does not exist", status_code=404)
|
||||
return user
|
||||
|
||||
cookies = request.cookies.get("huesoporroAuth")
|
||||
if cookies:
|
||||
return await get_user_by_jwt_action.run(cookies)
|
||||
user = await get_user_by_jwt_action.run(cookies)
|
||||
if not user:
|
||||
raise HTTPException(detail="User does not exist", status_code=404)
|
||||
return user
|
||||
|
||||
raise HTTPException(status_code=401, detail="Unauthorized")
|
||||
|
||||
|
||||
async def get_chatbot_settings_svc(db: Database):
|
||||
return ChatbotSettingsGetterSvc(db=db)
|
||||
|
||||
|
||||
async def store_chatbot_settings_svc(db: Database):
|
||||
return ChatbotSettingsStorerSvc(db=db)
|
||||
|
||||
|
||||
async def get_sentences_storer_svc(db: MarkovDatabase):
|
||||
return SentenceStorerSvc(db=db)
|
||||
|
||||
|
||||
async def get_user_repo(s: Settings):
|
||||
return UserRepo(s=s)
|
||||
def get_update_chatbot_svc(chatbot_repo: ChatbotRepo):
|
||||
return UpdateChatbotSvc(repo=chatbot_repo)
|
||||
|
||||
|
||||
def get_create_or_update_chatbot_action(
|
||||
create_chatbot_svc: CreateChatbotSvc,
|
||||
update_chatbot_svc: UpdateChatbotSvc,
|
||||
get_chatbot_by_user_id_svc: GetChatbotByUserIdSvc,
|
||||
):
|
||||
return CreateOrUpdateChatbotAction(
|
||||
create_chatbot_svc=create_chatbot_svc,
|
||||
update_chatbot_svc=update_chatbot_svc,
|
||||
get_chatbot_by_user_id_svc=get_chatbot_by_user_id_svc,
|
||||
)
|
||||
|
||||
|
||||
def get_get_chatbot_by_user_id_action(
|
||||
get_chatbot_by_user_id_svc: GetChatbotByUserIdSvc,
|
||||
):
|
||||
return GetChatbotByUserIdAction(
|
||||
get_chatbot_by_user_id_svc=get_chatbot_by_user_id_svc
|
||||
)
|
||||
|
||||
|
||||
async def get_authenticate_action(
|
||||
user_repo: UserRepo, authenticator: TwitchAuthenticator, s: Settings
|
||||
s: Settings,
|
||||
get_tokens_by_auth_code_svc: GetTwitchAuthByAuthCodeSvc,
|
||||
get_user_by_username_svc: GetUserByUsernameSvc,
|
||||
create_user_svc: CreateUserSvc,
|
||||
update_user_svc: UpdateUserSvc,
|
||||
):
|
||||
return AuthenticateAction(user_repo=user_repo, authenticator=authenticator, s=s)
|
||||
return AuthenticateUserAction(
|
||||
s=s,
|
||||
get_tokens_by_auth_code_svc=get_tokens_by_auth_code_svc,
|
||||
get_user_by_username_svc=get_user_by_username_svc,
|
||||
create_user_svc=create_user_svc,
|
||||
update_user_svc=update_user_svc,
|
||||
)
|
||||
|
||||
|
||||
async def chatbot(
|
||||
get_chatbot_by_user_id_action: GetChatbotByUserIdAction,
|
||||
create_or_update_chatbot_action: CreateOrUpdateChatbotAction,
|
||||
user: User,
|
||||
) -> Chatbot:
|
||||
cb = await get_chatbot_by_user_id_action.run(user_id=user.id)
|
||||
if cb:
|
||||
return cb
|
||||
return await create_or_update_chatbot_action.run(
|
||||
user_id=user.id,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,22 @@ from apps.httpapi.litestar.dependencies import (
|
|||
authenticate,
|
||||
get_authenticate_action,
|
||||
get_authenticator,
|
||||
get_chatbot_settings_svc,
|
||||
get_db,
|
||||
get_chatbot_repo,
|
||||
get_create_chatbot_svc,
|
||||
get_create_or_update_chatbot_action,
|
||||
get_create_user_svc,
|
||||
get_get_chatbot_by_user_id_action,
|
||||
get_get_chatbot_by_user_id_svc,
|
||||
get_get_tokens_by_auth_code_svc,
|
||||
get_get_user_by_jwt_action,
|
||||
get_get_user_by_username_svc,
|
||||
get_is_valid_token_svc,
|
||||
get_refresh_token_svc,
|
||||
get_sentences_storer_svc,
|
||||
get_settings,
|
||||
get_update_chatbot_svc,
|
||||
get_update_user_svc,
|
||||
get_user_repo,
|
||||
store_chatbot_settings_svc,
|
||||
)
|
||||
from apps.httpapi.litestar.errors import (
|
||||
after_exception_handler,
|
||||
|
|
@ -79,15 +88,26 @@ def create_app():
|
|||
"s": Provide(get_settings, use_cache=True),
|
||||
"a": Provide(get_authenticator, use_cache=True),
|
||||
"user": Provide(authenticate),
|
||||
"db": Provide(get_db, use_cache=True),
|
||||
"bm": Provide(BotsManager, use_cache=True),
|
||||
"gbs": Provide(get_chatbot_settings_svc),
|
||||
"sbs": Provide(store_chatbot_settings_svc),
|
||||
"sss": Provide(get_sentences_storer_svc),
|
||||
"authenticator": Provide(get_authenticator),
|
||||
"twitch_authenticator": Provide(get_authenticator),
|
||||
"authenticate_action": Provide(get_authenticate_action),
|
||||
"user_repo": Provide(get_user_repo),
|
||||
"chatbot_repo": Provide(get_chatbot_repo),
|
||||
"create_user_svc": Provide(get_create_user_svc),
|
||||
"update_chatbot_svc": Provide(get_update_chatbot_svc),
|
||||
"update_user_svc": Provide(get_update_user_svc),
|
||||
"create_chatbot_svc": Provide(get_create_chatbot_svc),
|
||||
"refresh_token_svc": Provide(get_refresh_token_svc),
|
||||
"is_valid_token_svc": Provide(get_is_valid_token_svc),
|
||||
"get_user_by_username_svc": Provide(get_get_user_by_username_svc),
|
||||
"get_chatbot_by_user_id_svc": Provide(get_get_chatbot_by_user_id_svc),
|
||||
"get_tokens_by_auth_code_svc": Provide(get_get_tokens_by_auth_code_svc),
|
||||
"get_user_by_jwt_action": Provide(get_get_user_by_jwt_action),
|
||||
"get_chatbot_by_user_id_action": Provide(get_get_chatbot_by_user_id_action),
|
||||
"create_or_update_chatbot_action": Provide(
|
||||
get_create_or_update_chatbot_action
|
||||
),
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ from litestar.datastructures import UploadFile
|
|||
from litestar.response import Template
|
||||
from pydantic import BaseModel, ConfigDict
|
||||
|
||||
from huesoporro.actions.chatbot.create_or_update_chatbot import (
|
||||
CreateOrUpdateChatbotAction,
|
||||
)
|
||||
from huesoporro.actions.chatbot.get_chatbot_by_user_id import GetChatbotByUserIdAction
|
||||
from huesoporro.bot import BotsManager
|
||||
from huesoporro.models import ChatbotSettings, User
|
||||
from huesoporro.svc.get_chatbot_settings import ChatbotSettingsGetterSvc
|
||||
from huesoporro.svc.store_settings import ChatbotSettingsStorerSvc
|
||||
from huesoporro.models import Chatbot, User
|
||||
|
||||
|
||||
class ManageBotDTO(BaseModel):
|
||||
|
|
@ -23,6 +25,12 @@ class ImportTextFileDTO(BaseModel):
|
|||
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||
|
||||
|
||||
class UpdateChatbotDTO(BaseModel):
|
||||
automatic_generation_timer: int = 300
|
||||
automatic_quote_timer: int = 500
|
||||
mods: list[str]
|
||||
|
||||
|
||||
@get(
|
||||
"/tts",
|
||||
media_type=MediaType.HTML,
|
||||
|
|
@ -48,8 +56,10 @@ async def get_tts_permalink(access_token: str) -> Template:
|
|||
"/",
|
||||
media_type=MediaType.HTML,
|
||||
)
|
||||
async def get_index(user: User, gbs: ChatbotSettingsGetterSvc) -> Template:
|
||||
chatbot_settings = await gbs.run(user=user)
|
||||
async def get_index(
|
||||
user: User, get_chatbot_by_user_id_action: GetChatbotByUserIdAction
|
||||
) -> Template:
|
||||
chatbot_settings = await get_chatbot_by_user_id_action.run(user_id=user.id)
|
||||
return Template(
|
||||
template_name="index.html",
|
||||
context=chatbot_settings.model_dump() if chatbot_settings else {},
|
||||
|
|
@ -60,22 +70,24 @@ async def get_index(user: User, gbs: ChatbotSettingsGetterSvc) -> Template:
|
|||
async def manage_bot(
|
||||
user: User,
|
||||
data: ManageBotDTO,
|
||||
gbs: ChatbotSettingsGetterSvc,
|
||||
sbs: ChatbotSettingsStorerSvc,
|
||||
create_or_update_chatbot_action: CreateOrUpdateChatbotAction,
|
||||
get_chatbot_by_user_id_action: GetChatbotByUserIdAction,
|
||||
bm: BotsManager,
|
||||
) -> Response:
|
||||
chatbot_settings = await gbs.run(user=user)
|
||||
if not chatbot_settings:
|
||||
await sbs.run(user=user, bot_settings=ChatbotSettings())
|
||||
chatbot_settings = await gbs.run(user=user)
|
||||
chatbot = await get_chatbot_by_user_id_action.run(
|
||||
user_id=user.id
|
||||
) or await create_or_update_chatbot_action.run(
|
||||
user_id=user.id,
|
||||
)
|
||||
|
||||
if data.command == "start":
|
||||
if not data.channel_name:
|
||||
return Response({"message": "Channel name is required"}, status_code=400)
|
||||
bm.add_bot(user, data.channel_name, chatbot_settings=chatbot_settings) # type: ignore[arg-type]
|
||||
if user.user in bm.bots:
|
||||
bm.add_bot(user, data.channel_name, chatbot=chatbot) # type: ignore[arg-type]
|
||||
if user.username in bm.bots:
|
||||
await bm.run_user_bot(user)
|
||||
return Response({"message": "Bot started"})
|
||||
if data.command == "stop" and user.user in bm.bots:
|
||||
if data.command == "stop" and user.username in bm.bots:
|
||||
await bm.stop_user_bot(user)
|
||||
return Response({"message": "Bot stopped"})
|
||||
return Response({"message": "Invalid command"}, status_code=400)
|
||||
|
|
@ -83,24 +95,26 @@ async def manage_bot(
|
|||
|
||||
@get("/api/v1/bot")
|
||||
async def get_bot_status(user: User, bm: BotsManager) -> dict:
|
||||
if user.user not in bm.bots:
|
||||
if user.username not in bm.bots:
|
||||
return {"status": "ko"}
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@get("/api/v1/bot/settings")
|
||||
async def get_bot_settings(
|
||||
user: User, gbs: ChatbotSettingsGetterSvc
|
||||
) -> ChatbotSettings | dict:
|
||||
cbs = await gbs.run(user=user)
|
||||
if not cbs:
|
||||
return {"status": "Not found"}
|
||||
return cbs
|
||||
async def get_bot_settings(chatbot: Chatbot) -> Chatbot:
|
||||
return chatbot
|
||||
|
||||
|
||||
@put("/api/v1/bot/settings")
|
||||
async def save_bot_settings(
|
||||
user: User, data: ChatbotSettings, sbs: ChatbotSettingsStorerSvc
|
||||
user: User,
|
||||
data: UpdateChatbotDTO,
|
||||
create_or_update_chatbot_action: CreateOrUpdateChatbotAction,
|
||||
) -> dict:
|
||||
await sbs.run(user=user, bot_settings=data)
|
||||
await create_or_update_chatbot_action.run(
|
||||
user_id=user.id,
|
||||
automatic_generation_timer=data.automatic_generation_timer,
|
||||
automatic_quote_timer=data.automatic_quote_timer,
|
||||
mods=data.mods,
|
||||
)
|
||||
return {"status": "ok"}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,14 @@ from litestar import MediaType, get
|
|||
from litestar.datastructures.cookie import Cookie
|
||||
from litestar.response import Redirect, Template
|
||||
|
||||
from huesoporro.actions.authenticate import AuthenticateAction
|
||||
from huesoporro.actions.users.authenticate_user import AuthenticateUserAction
|
||||
from huesoporro.settings import Settings
|
||||
|
||||
|
||||
@get(path="/o/code")
|
||||
async def get_code(code: str, authenticate_action: AuthenticateAction) -> Redirect:
|
||||
token = await authenticate_action.run(code)
|
||||
async def get_code(code: str, authenticate_action: AuthenticateUserAction) -> Redirect:
|
||||
user = await authenticate_action.run(code)
|
||||
token = user.encode()
|
||||
return Redirect(
|
||||
"/",
|
||||
cookies=[
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue