py3.12: more styling and linting
This commit is contained in:
parent
d193d07fd6
commit
b0e95af44e
9 changed files with 43 additions and 76 deletions
|
@ -9,9 +9,7 @@ from typing import Awaitable, Callable, TypeVar
|
||||||
RT = TypeVar("RT")
|
RT = TypeVar("RT")
|
||||||
|
|
||||||
|
|
||||||
def run_in_executor(
|
def run_in_executor(function: Callable[..., RT]) -> Callable[..., Awaitable[RT]]:
|
||||||
function: Callable[..., RT]
|
|
||||||
) -> Callable[..., Awaitable[RT]]:
|
|
||||||
"""
|
"""
|
||||||
Decorator to make blocking a function call asyncio compatible.
|
Decorator to make blocking a function call asyncio compatible.
|
||||||
https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/
|
https://stackoverflow.com/questions/41063331/how-to-use-asyncio-with-existing-blocking-library/
|
||||||
|
|
|
@ -22,17 +22,6 @@ from .dav_common import caldav_principal
|
||||||
from .settings import SETTINGS
|
from .settings import SETTINGS
|
||||||
|
|
||||||
_logger = getLogger(__name__)
|
_logger = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def _string_strip(in_str: str) -> str:
|
|
||||||
"""
|
|
||||||
Wrapper for str.strip().
|
|
||||||
|
|
||||||
Used to define `pydantic` validators.
|
|
||||||
"""
|
|
||||||
return in_str.strip()
|
|
||||||
|
|
||||||
|
|
||||||
StrippedStr = Annotated[str, AfterValidator(lambda s: s.strip())]
|
StrippedStr = Annotated[str, AfterValidator(lambda s: s.strip())]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,12 +18,14 @@ from . import __file__ as OVD_INIT
|
||||||
from .async_helpers import run_in_executor
|
from .async_helpers import run_in_executor
|
||||||
from .settings import SETTINGS
|
from .settings import SETTINGS
|
||||||
|
|
||||||
_WEBDAV_CLIENT = WebDAVclient({
|
_WEBDAV_CLIENT = WebDAVclient(
|
||||||
|
{
|
||||||
"webdav_hostname": SETTINGS.webdav.url,
|
"webdav_hostname": SETTINGS.webdav.url,
|
||||||
"webdav_login": SETTINGS.webdav.username,
|
"webdav_login": SETTINGS.webdav.username,
|
||||||
"webdav_password": SETTINGS.webdav.password,
|
"webdav_password": SETTINGS.webdav.password,
|
||||||
"disable_check": SETTINGS.webdav_disable_check,
|
"disable_check": SETTINGS.webdav_disable_check,
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
_logger = getLogger(__name__)
|
_logger = getLogger(__name__)
|
||||||
|
|
||||||
|
@ -113,11 +115,13 @@ def webdav_ensure_files(remote_path: str, *file_names: str) -> None:
|
||||||
missing_files = (
|
missing_files = (
|
||||||
file_name
|
file_name
|
||||||
for file_name in file_names
|
for file_name in file_names
|
||||||
if not _WEBDAV_CLIENT.check(path.join(
|
if not _WEBDAV_CLIENT.check(
|
||||||
|
path.join(
|
||||||
SETTINGS.webdav_prefix,
|
SETTINGS.webdav_prefix,
|
||||||
remote_path,
|
remote_path,
|
||||||
file_name,
|
file_name,
|
||||||
))
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
webdav_upload_skel(
|
webdav_upload_skel(
|
||||||
|
@ -132,9 +136,7 @@ def webdav_resource(remote_path: Any) -> WebDAVResource:
|
||||||
Gets a resource using the main WebDAV client.
|
Gets a resource using the main WebDAV client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _WEBDAV_CLIENT.resource(
|
return _WEBDAV_CLIENT.resource(f"{SETTINGS.webdav_prefix}/{remote_path}")
|
||||||
f"{SETTINGS.webdav_prefix}/{remote_path}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@run_in_executor
|
@run_in_executor
|
||||||
|
@ -143,9 +145,7 @@ def webdav_list(remote_path: str) -> list[str]:
|
||||||
Asynchronously lists a WebDAV path using the main WebDAV client.
|
Asynchronously lists a WebDAV path using the main WebDAV client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return _WEBDAV_CLIENT.list(
|
return _WEBDAV_CLIENT.list(f"{SETTINGS.webdav_prefix}/{remote_path}")
|
||||||
f"{SETTINGS.webdav_prefix}/{remote_path}"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
_CALDAV_CLIENT = CalDAVclient(
|
_CALDAV_CLIENT = CalDAVclient(
|
||||||
|
@ -169,7 +169,4 @@ def caldav_list() -> Iterator[str]:
|
||||||
Asynchronously lists all calendars using the main WebDAV client.
|
Asynchronously lists all calendars using the main WebDAV client.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (
|
return (str(cal.name) for cal in caldav_principal().calendars())
|
||||||
str(cal.name)
|
|
||||||
for cal in caldav_principal().calendars()
|
|
||||||
)
|
|
||||||
|
|
|
@ -63,11 +63,7 @@ class FileNameLister:
|
||||||
try:
|
try:
|
||||||
file_names = await webdav_list(await self.remote_path)
|
file_names = await webdav_list(await self.remote_path)
|
||||||
|
|
||||||
return (
|
return (name for name in file_names if self.re.search(name))
|
||||||
name
|
|
||||||
for name in file_names
|
|
||||||
if self.re.search(name)
|
|
||||||
)
|
|
||||||
|
|
||||||
except RemoteResourceNotFound:
|
except RemoteResourceNotFound:
|
||||||
_logger.error(
|
_logger.error(
|
||||||
|
@ -115,8 +111,7 @@ class PrefixFinder:
|
||||||
return {
|
return {
|
||||||
**_RESPONSE_OK,
|
**_RESPONSE_OK,
|
||||||
status.HTTP_404_NOT_FOUND: {
|
status.HTTP_404_NOT_FOUND: {
|
||||||
"description": "Failure in lister " +
|
"description": f"Failure in lister {self.lister.__class__.__name__!r}",
|
||||||
repr(self.lister.__class__.__name__),
|
|
||||||
"content": None,
|
"content": None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ from logging import getLogger
|
||||||
from typing import Iterator
|
from typing import Iterator
|
||||||
|
|
||||||
from fastapi import APIRouter, Depends
|
from fastapi import APIRouter, Depends
|
||||||
|
|
||||||
from ovdashboard_api.config import Config
|
from ovdashboard_api.config import Config
|
||||||
|
|
||||||
from ...dav_calendar import CalEvent, DavCalendar
|
from ...dav_calendar import CalEvent, DavCalendar
|
||||||
|
@ -52,12 +53,13 @@ async def get_aggregate_calendar(
|
||||||
aggregate = cfg.calendar.aggregates[name]
|
aggregate = cfg.calendar.aggregates[name]
|
||||||
|
|
||||||
calendars = (
|
calendars = (
|
||||||
DavCalendar(await calendar_unique(cal_prefix))
|
DavCalendar(await calendar_unique(cal_prefix)) for cal_prefix in aggregate
|
||||||
for cal_prefix in aggregate
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return sorted([
|
return sorted(
|
||||||
|
[
|
||||||
event
|
event
|
||||||
async for calendar in calendars # type: ignore
|
async for calendar in calendars # type: ignore
|
||||||
for event in (await calendar.events)
|
for event in (await calendar.events)
|
||||||
])
|
]
|
||||||
|
)
|
||||||
|
|
|
@ -88,7 +88,5 @@ async def get_file(
|
||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
content=buffer,
|
content=buffer,
|
||||||
media_type=mime,
|
media_type=mime,
|
||||||
headers={
|
headers={"Content-Disposition": f"filename={prefix}"},
|
||||||
"Content-Disposition": f"filename={prefix}"
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -83,11 +83,7 @@ async def get_image(
|
||||||
cfg = await Config.get()
|
cfg = await Config.get()
|
||||||
|
|
||||||
dav_file = DavFile(f"{await image_lister.remote_path}/{name}")
|
dav_file = DavFile(f"{await image_lister.remote_path}/{name}")
|
||||||
img = Image.open(
|
img = Image.open(BytesIO(await dav_file.as_bytes)).convert(cfg.image.mode)
|
||||||
BytesIO(await dav_file.as_bytes)
|
|
||||||
).convert(
|
|
||||||
cfg.image.mode
|
|
||||||
)
|
|
||||||
|
|
||||||
img_buffer = BytesIO()
|
img_buffer = BytesIO()
|
||||||
img.save(img_buffer, **cfg.image.save_params)
|
img.save(img_buffer, **cfg.image.save_params)
|
||||||
|
@ -96,9 +92,7 @@ async def get_image(
|
||||||
return StreamingResponse(
|
return StreamingResponse(
|
||||||
content=img_buffer,
|
content=img_buffer,
|
||||||
media_type="image/jpeg",
|
media_type="image/jpeg",
|
||||||
headers={
|
headers={"Content-Disposition": f"filename={prefix}.jpg"},
|
||||||
"Content-Disposition": f"filename={prefix}.jpg"
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,7 @@ async def get_ticker_lines() -> Iterator[str]:
|
||||||
f"{await text_lister.remote_path}/{file_name}",
|
f"{await text_lister.remote_path}/{file_name}",
|
||||||
).as_string
|
).as_string
|
||||||
|
|
||||||
return (
|
return (line.strip() for line in ticker.split("\n") if line.strip())
|
||||||
line.strip()
|
|
||||||
for line in ticker.split("\n")
|
|
||||||
if line.strip()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def get_ticker_content_lines(
|
async def get_ticker_content_lines(
|
||||||
|
@ -55,9 +51,7 @@ async def get_ticker_content_lines(
|
||||||
cfg = await Config.get()
|
cfg = await Config.get()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
line
|
line for line in ticker_lines if not line.startswith(cfg.ticker.comment_marker)
|
||||||
for line in ticker_lines
|
|
||||||
if not line.startswith(cfg.ticker.comment_marker)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ Converts per-run (environment) variables and config files into the
|
||||||
Pydantic models might have convenience methods attached.
|
Pydantic models might have convenience methods attached.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any
|
||||||
|
|
||||||
from pydantic import BaseModel, root_validator
|
from pydantic import BaseModel, root_validator
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings
|
||||||
|
@ -18,11 +18,11 @@ class DavSettings(BaseModel):
|
||||||
Connection to a DAV server.
|
Connection to a DAV server.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
protocol: Optional[str] = None
|
protocol: str | None = None
|
||||||
host: Optional[str] = None
|
host: str | None = None
|
||||||
username: Optional[str] = None
|
username: str | None = None
|
||||||
password: Optional[str] = None
|
password: str | None = None
|
||||||
path: Optional[str] = None
|
path: str | None = None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def url(self) -> str:
|
def url(self) -> str:
|
||||||
|
@ -57,8 +57,8 @@ class Settings(BaseSettings):
|
||||||
#####
|
#####
|
||||||
|
|
||||||
openapi_url: str = "/openapi.json"
|
openapi_url: str = "/openapi.json"
|
||||||
docs_url: Optional[str] = None if production_mode else "/docs"
|
docs_url: str | None = None if production_mode else "/docs"
|
||||||
redoc_url: Optional[str] = None if production_mode else "/redoc"
|
redoc_url: str | None = None if production_mode else "/redoc"
|
||||||
|
|
||||||
#####
|
#####
|
||||||
# webdav settings
|
# webdav settings
|
||||||
|
|
Loading…
Reference in a new issue