Skip to content

Commit

Permalink
feat: add cache_pool when transfer among Article/Dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
Nemo2011 committed Dec 19, 2024
1 parent 38d0f14 commit e97e8e0
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 36 deletions.
29 changes: 18 additions & 11 deletions bilibili_api/article.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from .utils.network import Api
from .exceptions.NetworkException import ApiException, NetworkException
from .video import get_cid_info_sync
from .utils import cache_pool

from . import dynamic
from .note import Note, NoteType
Expand Down Expand Up @@ -173,8 +174,17 @@ async def turn_to_dynamic(self) -> "dynamic.Dynamic":
Returns:
Dynamic: 动态实例
"""
if cache_pool.article2dynamic.get(self.get_cvid()) is None:
cache_pool.article2dynamic[self.get_cvid()] = (await self.get_all())[
"readInfo"
]["dyn_id_str"]
cache_pool.dynamic2article[cache_pool.article2dynamic[self.get_cvid()]] = (
self.get_cvid()
)
if cache_pool.dynamic_is_article.get(cache_pool.article2dynamic[self.get_cvid()]) is None:
cache_pool.dynamic_is_article[cache_pool.article2dynamic[self.get_cvid()]] = True
return dynamic.Dynamic(
dynamic_id=(await self.get_all())["readInfo"]["dyn_id_str"],
dynamic_id=cache_pool.article2dynamic[self.get_cvid()],
credential=self.credential,
)

Expand All @@ -185,22 +195,19 @@ async def is_note(self) -> bool:
Returns:
bool: 是否为笔记
"""
return (await self.get_all())["readInfo"]["category"]["id"] in [41, 42]
if cache_pool.article_is_note.get(self.get_cvid()) is None:
cache_pool.article_is_note[self.get_cvid()] = (await self.get_all())[
"readInfo"
]["category"]["id"] in [41, 42]
return cache_pool.article_is_note[self.get_cvid()]

async def turn_to_note(self) -> "Note":
def turn_to_note(self) -> "Note":
"""
将专栏转为笔记(需保证专栏是笔记,过程中会有核验,共产生一次请求)
如果希望避免核验专栏是否是笔记,可以手动转换以避免请求。
``` python
n = note.Note(cvid=ar.get_cvid(), note_type=note.NoteType.PUBLIC)
```
将专栏转为笔记,不会核验。如需核验使用 `await is_note()`
Returns:
Note: 笔记实例
"""
raise_for_statement(await self.is_note(), "此专栏不是笔记,无法转换。")
return Note(
cvid=self.get_cvid(), note_type=NoteType.PUBLIC, credential=self.credential
)
Expand Down
37 changes: 34 additions & 3 deletions bilibili_api/dynamic.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from .utils.network import Api
from .exceptions.DynamicExceedImagesException import DynamicExceedImagesException
from .article import Article
from .utils import cache_pool

API = utils.get_api("dynamic")
API_opus = utils.get_api("opus")
Expand Down Expand Up @@ -824,20 +825,50 @@ async def is_article(self) -> bool:
Returns:
bool: 是否为专栏
"""
return (await self.get_info())["item"]["basic"]["comment_type"] == 12
if cache_pool.dynamic_is_article.get(self.get_dynamic_id()) is None:
cache_pool.dynamic_is_article[self.get_dynamic_id()] = (
await self.get_info()
)["item"]["basic"]["comment_type"] == 12
return cache_pool.dynamic_is_article[self.get_dynamic_id()]

async def turn_to_article(self) -> "Article":
"""
将专栏发布动态转为对应专栏(评论、点赞等数据专栏/动态/图文共享)
不会核验。如需核验使用 `await is_article()`。
转换后可投币。
Returns:
Article: 专栏实例
"""
raise_for_statement(await self.is_article(), "此动态无对应专栏。")
if cache_pool.dynamic2article.get(self.get_dynamic_id()) is None:
# 此处使用 is_article 需要调用 get_info
# 而获取动态对应专栏也需要 get_info,且请求结果会缓存
# 因此最终只会请求一次,可以认为是提前请求
if not await self.is_article():
# 为防止 rid_str 字段其他的值匹配到对应专栏,
# 用动态的 id 覆盖
cache_pool.dynamic2article[self.get_dynamic_id()] = (
self.get_dynamic_id()
)
else:
cache_pool.dynamic2article[self.get_dynamic_id()] = (
await self.get_info()
)["item"]["basic"]["rid_str"]
# 所以为什么这里不设置核验呢,~~为了追求和 Article.turn_to_note 一样的对称美~~
# 考虑 article 和 note 转换,note 初始化可以瞎填,不能保证存在
# 而转换的时候无需网络请求,因此可能转换完 article 的 is_note 会被造假
# 因此 Note.turn_to_article 没有 cache_pool 缓存
# 同理 Article.turn_to_note 也没有缓存,缓存只存在于 await is_note(),有请求
# 如果在 Article.turn_to_note 中加入核验,某些情境下会多出请求,因此将核验剥离
# 这样既可以实现核验,也可以不核验。
# 这里这么做也是这个遵循目的,为此还需要保证将错就错不会造成其他逻辑问题。
cache_pool.article2dynamic[
cache_pool.dynamic2article[self.get_dynamic_id()]
] = self.get_dynamic_id()
return Article(
cvid=(await self.get_info())["item"]["basic"]["rid_str"],
cvid=cache_pool.dynamic2article[self.get_dynamic_id()],
credential=self.credential,
)

Expand Down
4 changes: 4 additions & 0 deletions bilibili_api/utils/cache_pool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
article2dynamic: dict = {}
dynamic2article: dict = {}
article_is_note: dict = {}
dynamic_is_article: dict = {}
2 changes: 1 addition & 1 deletion bilibili_api/utils/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ async def _prepare_request(self, **kwargs) -> dict:
cookies["buvid3"] = self.credential.buvid3
# cookies["Domain"] = ".bilibili.com"

cookies["opus-goback"] = 1
cookies["opus-goback"] = "1"

if self.bili_ticket:
cookies["bili_ticket"] = await get_bili_ticket()
Expand Down
21 changes: 0 additions & 21 deletions tests/test_opus.py

This file was deleted.

0 comments on commit e97e8e0

Please sign in to comment.