mirror of
https://github.com/DrizzleTime/Foxel.git
synced 2026-07-10 23:12:01 +08:00
refactor: split virtual fs mapping and search modules
This commit is contained in:
66
domain/virtual_fs/resolver.py
Normal file
66
domain/virtual_fs/resolver.py
Normal file
@@ -0,0 +1,66 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Tuple
|
||||
|
||||
from fastapi import HTTPException
|
||||
from fastapi.responses import Response
|
||||
|
||||
from domain.adapters.registry import runtime_registry
|
||||
from models import StorageAdapter
|
||||
|
||||
from .common import VirtualFSCommonMixin
|
||||
|
||||
|
||||
class VirtualFSResolverMixin(VirtualFSCommonMixin):
|
||||
@classmethod
|
||||
async def resolve_adapter_by_path(cls, path: str) -> Tuple[StorageAdapter, str]:
|
||||
norm = cls._normalize_path(path)
|
||||
adapters = await StorageAdapter.filter(enabled=True)
|
||||
best = None
|
||||
for adapter in adapters:
|
||||
if norm == adapter.path or norm.startswith(adapter.path.rstrip("/") + "/"):
|
||||
if best is None or len(adapter.path) > len(best.path):
|
||||
best = adapter
|
||||
if not best:
|
||||
raise HTTPException(404, detail="No storage adapter for path")
|
||||
rel = norm[len(best.path) :].lstrip("/")
|
||||
return best, rel
|
||||
|
||||
@classmethod
|
||||
async def resolve_adapter_and_rel(cls, path: str):
|
||||
norm = cls._normalize_path(path)
|
||||
adapter_model, rel = await cls.resolve_adapter_by_path(norm)
|
||||
adapter_instance = runtime_registry.get(adapter_model.id)
|
||||
if not adapter_instance:
|
||||
await runtime_registry.refresh()
|
||||
adapter_instance = runtime_registry.get(adapter_model.id)
|
||||
if not adapter_instance:
|
||||
raise HTTPException(
|
||||
404, detail=f"Adapter instance for ID {adapter_model.id} not found or failed to load."
|
||||
)
|
||||
effective_root = adapter_instance.get_effective_root(adapter_model.sub_path)
|
||||
return adapter_instance, adapter_model, effective_root, rel
|
||||
|
||||
@classmethod
|
||||
async def maybe_redirect_download(cls, adapter_instance, adapter_model, root: str, rel: str):
|
||||
if not rel or rel.endswith("/"):
|
||||
return None
|
||||
|
||||
config = getattr(adapter_model, "config", {}) or {}
|
||||
if not config.get(cls.DIRECT_REDIRECT_CONFIG_KEY):
|
||||
return None
|
||||
|
||||
handler = getattr(adapter_instance, "get_direct_download_response", None)
|
||||
if not callable(handler):
|
||||
return None
|
||||
|
||||
try:
|
||||
response = await handler(root, rel)
|
||||
except FileNotFoundError:
|
||||
raise
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
if isinstance(response, Response):
|
||||
return response
|
||||
return None
|
||||
Reference in New Issue
Block a user