# -*- coding: utf-8 -*- """B 站收藏夹写客户端(``sort``)。 收藏夹重排序是本项目**唯一**使用 ``bilibili.write`` 凭据的写操作,且频率极低。 加入收藏夹(``deal``)等写操作已移除,收藏夹由人工维护。 只应使用 ``bilibili.write`` 凭据构造。 """ from __future__ import annotations import urllib.parse from typing import Any, Mapping from .client import ( BASE, BilibiliClient, BilibiliHTTPError, BilibiliProtocolError, ) class BilibiliWriteClient(BilibiliClient): def post_form( self, url: str, data: Mapping[str, Any], *, referer: str | None = None ) -> dict[str, Any]: self.pacer.wait() headers = self._headers(auth=True, referer=referer) headers["content-type"] = "application/x-www-form-urlencoded" body = urllib.parse.urlencode(data).encode("utf-8") response = self.transport.request( "POST", url, headers, data=body, timeout=self.timeout ) if response.status >= 400: raise BilibiliHTTPError( response.status, response.body.decode("utf-8", "replace")[:200] ) payload = response.json() if not isinstance(payload, dict): raise BilibiliProtocolError("写接口响应顶层不是 JSON 对象") if payload.get("code") != 0: raise self._api_error(payload) return payload def sort(self, media_id: int, sort_spec: str) -> dict[str, Any]: return self.post_form( f"{BASE}/x/v3/fav/resource/sort", { "media_id": int(media_id), "sort": sort_spec, "csrf": self.csrf, }, referer=( f"https://space.bilibili.com/{self.mid}/favlist" f"?fid={int(media_id)}&ftype=create" ), )