# -*- coding: utf-8 -*- """按账号角色提供 B 站客户端,并在凭据变化时自动重建。""" from __future__ import annotations from typing import Any, Callable from ..config import ConfigStore from .client import BilibiliClient class ClientProvider: """缓存客户端;仅当 ``mid`` / ``cookie`` / ``csrf`` 变化时重建。 ``factory`` 负责固化该角色的限速与重试策略,因此重建不会丢失这些设置。 """ def __init__( self, store: ConfigStore, role: str, factory: Callable[[Any], BilibiliClient], ) -> None: if role not in {"read", "write"}: raise ValueError(f"未知账号角色: {role}") self.store = store self.role = role self.factory = factory self._key: tuple[int, str, str] | None = None self._client: BilibiliClient | None = None def get(self) -> BilibiliClient: credentials = getattr(self.store.get().bilibili, self.role) key = (credentials.mid, credentials.cookie, credentials.csrf) if self._client is None or key != self._key: if self._client is not None: close = getattr(self._client, "close", None) if callable(close): close() self._client = self.factory(credentials) self._key = key return self._client