common "Iterator" stuff

This commit is contained in:
Jörn-Michael Miehe 2022-09-02 13:22:35 +00:00
parent 9a350f6a71
commit 749f56268c
3 changed files with 64 additions and 69 deletions

View file

@ -0,0 +1,38 @@
import re
from dataclasses import dataclass
from typing import Iterator
from webdav3.exceptions import RemoteResourceNotFound
from .. import CLIENT
@dataclass(frozen=True)
class FileNameLister:
remote_path: str
re: re.Pattern[str]
def __call__(self) -> Iterator[str]:
try:
file_names = CLIENT.list(self.remote_path)
return (
name
for name in file_names
if self.re.search(name)
)
except RemoteResourceNotFound:
return iter(())
@dataclass(frozen=True)
class FilePrefixFinder:
lister: FileNameLister
def __call__(self, prefix: str) -> Iterator[str]:
return (
file_name
for file_name in self.lister()
if file_name.lower().startswith(prefix.lower())
)

View file

@ -5,55 +5,33 @@ from typing import Iterator
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse from fastapi.responses import StreamingResponse
from PIL import Image from PIL import Image
from webdav3.exceptions import RemoteResourceNotFound
from .. import CLIENT
from ..dav_file import DavFile from ..dav_file import DavFile
from ._common import FileNameLister, FilePrefixFinder
router = APIRouter(prefix="/image", tags=["image"]) router = APIRouter(prefix="/image", tags=["image"])
_lister = FileNameLister(
_re_image_file = re.compile( remote_path="img",
re=re.compile(
r"\.(gif|jpe?g|tiff?|png|bmp)$", r"\.(gif|jpe?g|tiff?|png|bmp)$",
flags=re.IGNORECASE, flags=re.IGNORECASE,
),
) )
_finder = FilePrefixFinder(_lister)
async def get_image_file_names() -> Iterator[str]:
try:
file_names = CLIENT.list("img")
return (
name
for name in file_names
if _re_image_file.search(name)
)
except RemoteResourceNotFound:
return iter(())
@router.get("/list", response_model=list[str]) @router.get("/list", response_model=list[str])
async def list_images( async def list_images(
image_file_names: Iterator[str] = Depends(get_image_file_names), image_file_names: Iterator[str] = Depends(_lister),
) -> list[str]: ) -> list[str]:
return list(image_file_names) return list(image_file_names)
async def find_file_names(
prefix: str = "",
image_file_names: Iterator[str] = Depends(get_image_file_names),
) -> Iterator[str]:
return (
file_name
for file_name in image_file_names
if file_name.lower().startswith(prefix.lower())
)
@router.get("/find/{prefix}", response_model=list[str]) @router.get("/find/{prefix}", response_model=list[str])
async def find_images( async def find_images(
file_names: Iterator[str] = Depends(find_file_names), file_names: Iterator[str] = Depends(_finder),
) -> list[str]: ) -> list[str]:
return list(file_names) return list(file_names)
@ -77,7 +55,7 @@ async def find_images(
) )
async def get_image( async def get_image(
prefix: str, prefix: str,
file_names: Iterator[str] = Depends(find_file_names), file_names: Iterator[str] = Depends(_finder),
) -> StreamingResponse: ) -> StreamingResponse:
file_names = list(file_names) file_names = list(file_names)

View file

@ -3,14 +3,23 @@ from typing import Iterator
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from markdown import markdown from markdown import markdown
from webdav3.exceptions import RemoteResourceNotFound
from .. import CLIENT
from ..config import SETTINGS from ..config import SETTINGS
from ..dav_file import DavFile from ..dav_file import DavFile
from ._common import FileNameLister, FilePrefixFinder
router = APIRouter(prefix="/text", tags=["text"]) router = APIRouter(prefix="/text", tags=["text"])
_lister = FileNameLister(
remote_path="text",
re=re.compile(
r"\.(txt|md)$",
flags=re.IGNORECASE,
),
)
_finder = FilePrefixFinder(_lister)
async def get_ticker_lines() -> Iterator[str]: async def get_ticker_lines() -> Iterator[str]:
ticker = await DavFile("text/ticker.txt").string ticker = await DavFile("text/ticker.txt").string
@ -41,53 +50,23 @@ async def get_ticker_content(
) )
_re_text_file = re.compile(
r"\.(txt|md)$",
flags=re.IGNORECASE,
)
async def get_text_file_names() -> Iterator[str]:
try:
file_names = CLIENT.list("text")
return (
name
for name in file_names
if _re_text_file.search(name)
)
except RemoteResourceNotFound:
return iter(())
@router.get("/list", response_model=list[str]) @router.get("/list", response_model=list[str])
async def list_texts( async def list_texts(
text_file_names: Iterator[str] = Depends(get_text_file_names), text_file_names: Iterator[str] = Depends(_lister),
) -> list[str]: ) -> list[str]:
return list(text_file_names) 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("/find/{prefix}", response_model=list[str]) @router.get("/find/{prefix}", response_model=list[str])
async def find_texts( async def find_texts(
file_names: Iterator[str] = Depends(find_file_names), file_names: Iterator[str] = Depends(_finder),
) -> list[str]: ) -> list[str]:
return list(file_names) return list(file_names)
@router.get( @router.get(
"/get/{prefix}", "/get/{prefix}",
response_model=str,
responses={ responses={
status.HTTP_200_OK: { status.HTTP_200_OK: {
"description": "Operation successful", "description": "Operation successful",
@ -103,7 +82,7 @@ async def find_texts(
}, },
) )
async def get_text( async def get_text(
file_names: Iterator[str] = Depends(find_file_names), file_names: Iterator[str] = Depends(_finder),
) -> str: ) -> str:
file_names = list(file_names) file_names = list(file_names)