add a "/file" router (static serve from WebDAV)
This commit is contained in:
parent
8bd87fb6f1
commit
8ef9d4ad2e
6 changed files with 108 additions and 3 deletions
|
@ -22,6 +22,7 @@ RUN set -ex; \
|
||||||
export DEBIAN_FRONTEND=noninteractive; \
|
export DEBIAN_FRONTEND=noninteractive; \
|
||||||
apt-get update; apt-get -y install --no-install-recommends \
|
apt-get update; apt-get -y install --no-install-recommends \
|
||||||
git-flow \
|
git-flow \
|
||||||
|
libmagic1 \
|
||||||
; rm -rf /var/lib/apt/lists/*;
|
; rm -rf /var/lib/apt/lists/*;
|
||||||
|
|
||||||
# [Optional] Uncomment this line to install global node packages.
|
# [Optional] Uncomment this line to install global node packages.
|
||||||
|
|
|
@ -102,6 +102,7 @@ class Config(BaseModel):
|
||||||
|
|
||||||
image_dir: str = "image"
|
image_dir: str = "image"
|
||||||
text_dir: str = "text"
|
text_dir: str = "text"
|
||||||
|
file_dir: str = "file"
|
||||||
|
|
||||||
logo: LogoUIConfig = LogoUIConfig()
|
logo: LogoUIConfig = LogoUIConfig()
|
||||||
image: ImageConfig = ImageConfig()
|
image: ImageConfig = ImageConfig()
|
||||||
|
|
|
@ -6,7 +6,7 @@ This file: Main API router definition.
|
||||||
|
|
||||||
from fastapi import APIRouter
|
from fastapi import APIRouter
|
||||||
|
|
||||||
from . import aggregate, calendar, image, misc, text, ticker
|
from . import aggregate, calendar, file, image, misc, text, ticker
|
||||||
|
|
||||||
router = APIRouter(prefix="/api/v1")
|
router = APIRouter(prefix="/api/v1")
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ router.include_router(misc.router)
|
||||||
router.include_router(text.router)
|
router.include_router(text.router)
|
||||||
router.include_router(ticker.router)
|
router.include_router(ticker.router)
|
||||||
router.include_router(image.router)
|
router.include_router(image.router)
|
||||||
|
router.include_router(file.router)
|
||||||
|
|
||||||
router.include_router(calendar.router)
|
router.include_router(calendar.router)
|
||||||
router.include_router(aggregate.router)
|
router.include_router(aggregate.router)
|
||||||
|
|
89
api/ovdashboard_api/routers/v1/file.py
Normal file
89
api/ovdashboard_api/routers/v1/file.py
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
"""
|
||||||
|
Router "file" provides:
|
||||||
|
|
||||||
|
- listing files
|
||||||
|
- finding files by name prefix
|
||||||
|
- getting files by name prefix
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
from io import BytesIO
|
||||||
|
from logging import getLogger
|
||||||
|
from typing import Iterator
|
||||||
|
|
||||||
|
from fastapi import APIRouter, Depends
|
||||||
|
from fastapi.responses import StreamingResponse
|
||||||
|
from magic import Magic
|
||||||
|
|
||||||
|
from ...dav_common import webdav_ensure_path
|
||||||
|
from ...dav_file import DavFile
|
||||||
|
from ._common import FileNameLister, PrefixFinder, PrefixUnique
|
||||||
|
|
||||||
|
_logger = getLogger(__name__)
|
||||||
|
_magic = Magic(mime=True)
|
||||||
|
|
||||||
|
router = APIRouter(prefix="/file", tags=["file"])
|
||||||
|
|
||||||
|
file_lister = FileNameLister(
|
||||||
|
path_name="file_dir",
|
||||||
|
re=re.compile(
|
||||||
|
r"[^/]$",
|
||||||
|
flags=re.IGNORECASE,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
file_finder = PrefixFinder(file_lister)
|
||||||
|
file_unique = PrefixUnique(file_finder)
|
||||||
|
|
||||||
|
|
||||||
|
@router.on_event("startup")
|
||||||
|
async def start_router() -> None:
|
||||||
|
_logger.debug(f"{router.prefix} router starting.")
|
||||||
|
|
||||||
|
webdav_ensure_path(await file_lister.remote_path)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/list",
|
||||||
|
response_model=list[str],
|
||||||
|
responses=file_lister.responses,
|
||||||
|
)
|
||||||
|
async def list_files(
|
||||||
|
names: Iterator[str] = Depends(file_lister),
|
||||||
|
) -> list[str]:
|
||||||
|
return list(names)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/find/{prefix}",
|
||||||
|
response_model=list[str],
|
||||||
|
responses=file_finder.responses,
|
||||||
|
)
|
||||||
|
async def find_files(
|
||||||
|
names: Iterator[str] = Depends(file_finder),
|
||||||
|
) -> list[str]:
|
||||||
|
return list(names)
|
||||||
|
|
||||||
|
|
||||||
|
@router.get(
|
||||||
|
"/get/{prefix}",
|
||||||
|
response_class=StreamingResponse,
|
||||||
|
responses=file_unique.responses,
|
||||||
|
)
|
||||||
|
async def get_file(
|
||||||
|
prefix: str,
|
||||||
|
name: str = Depends(file_unique),
|
||||||
|
) -> StreamingResponse:
|
||||||
|
dav_file = DavFile(f"{await file_lister.remote_path}/{name}")
|
||||||
|
buffer = BytesIO(await dav_file.as_bytes)
|
||||||
|
|
||||||
|
mime = _magic.from_buffer(buffer.read(2048))
|
||||||
|
buffer.seek(0)
|
||||||
|
|
||||||
|
return StreamingResponse(
|
||||||
|
content=buffer,
|
||||||
|
media_type=mime,
|
||||||
|
headers={
|
||||||
|
"Content-Disposition": f"filename={prefix}"
|
||||||
|
},
|
||||||
|
)
|
16
api/poetry.lock
generated
16
api/poetry.lock
generated
|
@ -138,7 +138,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cssselect = ["cssselect (>=0.7)"]
|
cssselect = ["cssselect (>=0.7)"]
|
||||||
html5 = ["html5lib"]
|
html5 = ["html5lib"]
|
||||||
htmlsoup = ["beautifulsoup4"]
|
htmlsoup = ["BeautifulSoup4"]
|
||||||
source = ["Cython (>=0.29.7)"]
|
source = ["Cython (>=0.29.7)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -205,6 +205,14 @@ python-versions = ">=3.7"
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["click (>=5.0)"]
|
cli = ["click (>=5.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "python-magic"
|
||||||
|
version = "0.4.27"
|
||||||
|
description = "File type identification using libmagic"
|
||||||
|
category = "main"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytz"
|
name = "pytz"
|
||||||
version = "2022.2.1"
|
version = "2022.2.1"
|
||||||
|
@ -388,7 +396,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = "^3.9"
|
python-versions = "^3.9"
|
||||||
content-hash = "f31c08e6b5aabf05d1d144a083abbfb76c8708ef23f6d99122c646126c9f7bcd"
|
content-hash = "b25d37c0bf9187d599709a66e05d21c0df7da2b140373f6cd50b070ae2f073ab"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
anyio = [
|
anyio = [
|
||||||
|
@ -617,6 +625,10 @@ python-dotenv = [
|
||||||
{file = "python-dotenv-0.21.0.tar.gz", hash = "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045"},
|
{file = "python-dotenv-0.21.0.tar.gz", hash = "sha256:b77d08274639e3d34145dfa6c7008e66df0f04b7be7a75fd0d5292c191d79045"},
|
||||||
{file = "python_dotenv-0.21.0-py3-none-any.whl", hash = "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5"},
|
{file = "python_dotenv-0.21.0-py3-none-any.whl", hash = "sha256:1684eb44636dd462b66c3ee016599815514527ad99965de77f43e0944634a7e5"},
|
||||||
]
|
]
|
||||||
|
python-magic = [
|
||||||
|
{file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"},
|
||||||
|
{file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"},
|
||||||
|
]
|
||||||
pytz = [
|
pytz = [
|
||||||
{file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
|
{file = "pytz-2022.2.1-py2.py3-none-any.whl", hash = "sha256:220f481bdafa09c3955dfbdddb7b57780e9a94f5127e35456a48589b9e0c0197"},
|
||||||
{file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
|
{file = "pytz-2022.2.1.tar.gz", hash = "sha256:cea221417204f2d1a2aa03ddae3e867921971d0d76f14d87abb4414415bbdcf5"},
|
||||||
|
|
|
@ -16,6 +16,7 @@ tomli = "^2.0.1"
|
||||||
tomli-w = "^1.0.0"
|
tomli-w = "^1.0.0"
|
||||||
uvicorn = "^0.18.3"
|
uvicorn = "^0.18.3"
|
||||||
webdavclient3 = "3.14.5"
|
webdavclient3 = "3.14.5"
|
||||||
|
python-magic = "^0.4.27"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
# pytest = "^5.2"
|
# pytest = "^5.2"
|
||||||
|
|
Loading…
Reference in a new issue