2022-09-02 13:22:35 +00:00
|
|
|
import re
|
|
|
|
from dataclasses import dataclass
|
|
|
|
from typing import Iterator
|
|
|
|
|
2022-09-02 14:51:11 +00:00
|
|
|
from fastapi import HTTPException, status
|
2022-09-02 13:22:35 +00:00
|
|
|
from webdav3.exceptions import RemoteResourceNotFound
|
|
|
|
|
2022-09-02 15:28:52 +00:00
|
|
|
from .. import webdav_list
|
2022-09-02 14:51:11 +00:00
|
|
|
from ..dav_file import DavFile
|
2022-09-02 13:22:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
class FileNameLister:
|
|
|
|
remote_path: str
|
|
|
|
re: re.Pattern[str]
|
|
|
|
|
|
|
|
def __call__(self) -> Iterator[str]:
|
|
|
|
try:
|
2022-09-02 15:28:52 +00:00
|
|
|
file_names = webdav_list(self.remote_path)
|
2022-09-02 13:22:35 +00:00
|
|
|
|
|
|
|
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())
|
|
|
|
)
|
2022-09-02 14:51:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
class FilePrefixLoader:
|
|
|
|
finder: FilePrefixFinder
|
|
|
|
|
|
|
|
@property
|
|
|
|
def responses(self) -> dict:
|
|
|
|
return {
|
|
|
|
status.HTTP_200_OK: {
|
|
|
|
"description": "Operation successful",
|
|
|
|
},
|
|
|
|
status.HTTP_404_NOT_FOUND: {
|
|
|
|
"description": "file not found in " +
|
|
|
|
repr(self.finder.lister.remote_path),
|
|
|
|
"content": None,
|
|
|
|
},
|
|
|
|
status.HTTP_409_CONFLICT: {
|
|
|
|
"description": "ambiguous file name for " +
|
|
|
|
repr(self.finder.lister.remote_path),
|
|
|
|
"content": None,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
def __call__(self, prefix: str) -> DavFile:
|
|
|
|
file_names = list(self.finder(prefix))
|
|
|
|
|
|
|
|
if not (file_names):
|
|
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
|
|
|
|
|
|
|
elif len(file_names) > 1:
|
|
|
|
raise HTTPException(status_code=status.HTTP_409_CONFLICT)
|
|
|
|
|
|
|
|
return DavFile(f"{self.finder.lister.remote_path}/{file_names[0]}")
|