ovdashboard/api/ovdashboard_api/core/dav/helpers.py

65 lines
1.6 KiB
Python
Raw Permalink Normal View History

2023-11-09 11:16:25 +00:00
import pickle
from typing import Callable, Hashable
2023-11-09 11:13:48 +00:00
import requests
from cachetools.keys import hashkey
from CacheToolsUtils import RedisCache as __RedisCache
2023-11-09 11:16:25 +00:00
from redis import Redis
2023-11-09 11:13:48 +00:00
from redis.commands.core import ResponseT
from redis.typing import EncodableT
from webdav3.client import Client as __WebDAVclient
2023-11-09 11:16:25 +00:00
from ..settings import SETTINGS
2023-11-09 11:13:48 +00:00
2023-11-09 11:16:25 +00:00
def davkey(
name: str,
slice: slice = slice(1, None),
) -> Callable[..., tuple[Hashable, ...]]:
def func(*args, **kwargs) -> tuple[Hashable, ...]:
"""Return a cache key for use with cached methods."""
key = hashkey(name, *args[slice], **kwargs)
return hashkey(*(str(key_item) for key_item in key))
return func
2023-11-09 11:13:48 +00:00
class WebDAVclient(__WebDAVclient):
def execute_request(
self,
action,
path,
data=None,
headers_ext=None,
) -> requests.Response:
res = super().execute_request(action, path, data, headers_ext)
# the "Content-Length" header can randomly be missing on txt files,
# this should fix that (probably serverside bug)
if action == "download" and "Content-Length" not in res.headers:
res.headers["Content-Length"] = str(len(res.text))
return res
class RedisCache(__RedisCache):
"""
Redis handles <bytes>, so ...
"""
def _serialize(self, s) -> EncodableT:
2023-11-09 11:16:25 +00:00
return pickle.dumps(s)
2023-11-09 11:13:48 +00:00
def _deserialize(self, s: ResponseT):
2023-11-09 11:16:25 +00:00
assert isinstance(s, bytes)
return pickle.loads(s)
2023-11-09 11:13:48 +00:00
2023-11-09 11:16:25 +00:00
REDIS = Redis(
host=SETTINGS.redis.host,
port=SETTINGS.redis.port,
db=SETTINGS.redis.db,
protocol=SETTINGS.redis.protocol,
)