diff --git a/api/ovdashboard_api/routers/text.py b/api/ovdashboard_api/routers/text.py index b23208c..c7aad0a 100644 --- a/api/ovdashboard_api/routers/text.py +++ b/api/ovdashboard_api/routers/text.py @@ -1,27 +1,19 @@ import re from typing import Iterator -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, HTTPException, status from markdown import markdown -from pydantic import BaseModel +from webdav3.exceptions import RemoteResourceNotFound +from .. import CLIENT from ..config import SETTINGS from ..dav_file import DavFile router = APIRouter(prefix="/text", tags=["text"]) -@router.get("/message") -async def get_message() -> str: - message = await DavFile("message.txt").string - - return markdown( - message - ) - - async def get_ticker_lines() -> Iterator[str]: - ticker = await DavFile("ticker.txt").string + ticker = await DavFile("text/ticker.txt").string return ( line.strip() @@ -36,11 +28,11 @@ async def get_ticker_content_lines( return ( line for line in ticker_lines - if not line.startswith(".") + if not line.startswith("#") ) -@router.get("/ticker/content") +@router.get("/get/ticker") async def get_ticker_content( ticker_content_lines: Iterator[str] = Depends(get_ticker_content_lines), ) -> str: @@ -48,41 +40,81 @@ async def get_ticker_content( SETTINGS.ticker_separator.join(ticker_content_lines) ) -_re_ticker_command_line = re.compile( - r"^\.([a-z]+)\s+(.*)$", + +_re_text_file = re.compile( + r"\.(txt|md)$", flags=re.IGNORECASE, ) -class TickerCommand(BaseModel): - command: str - argument: str +async def get_text_file_names() -> Iterator[str]: + try: + file_names = CLIENT.list("text") - -async def get_ticker_commands( - ticker_lines: Iterator[str] = Depends(get_ticker_lines), -) -> Iterator[TickerCommand]: - return ( - TickerCommand( - command=match.group(1), - argument=match.group(2), + return ( + name + for name in file_names + if _re_text_file.search(name) ) - for line in ticker_lines - if (match := _re_ticker_command_line.match(line)) + + except RemoteResourceNotFound: + return iter(()) + + +@router.get("/list", response_model=list[str]) +async def list_texts( + text_file_names: Iterator[str] = Depends(get_text_file_names), +) -> list[str]: + return list(text_file_names) + + +async def find_file_names( + prefix: str = "", + text_file_names: Iterator[str] = Depends(get_text_file_names), +) -> Iterator[str]: + return ( + file_name + for file_name in text_file_names + if file_name.lower().startswith(prefix.lower()) ) -@router.get("/ticker/commands", response_model=list[TickerCommand]) -async def get_ticker_commands( - ticker_commands: Iterator[str] = Depends(get_ticker_commands) -) -> list[TickerCommand]: - return list(ticker_commands) +@router.get("/find/{prefix}", response_model=list[str]) +async def find_texts( + file_names: Iterator[str] = Depends(find_file_names), +) -> list[str]: + return list(file_names) -@router.get("/title") -async def get_title() -> str: - title = await DavFile("title.txt").string +@router.get( + "/get/{prefix}", + responses={ + status.HTTP_200_OK: { + "description": "Operation successful", + }, + status.HTTP_404_NOT_FOUND: { + "description": "text file not found", + "content": None, + }, + status.HTTP_409_CONFLICT: { + "description": "ambiguous text file name", + "content": None, + }, + }, +) +async def get_text( + file_names: Iterator[str] = Depends(find_file_names), +) -> str: + file_names = list(file_names) + + if not (file_names := list(file_names)): + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND) + + elif len(file_names) > 1: + raise HTTPException(status_code=status.HTTP_409_CONFLICT) + + text = await DavFile(f"text/{file_names[0]}").string return markdown( - title + text )