Skip to content

Commit 1ca9da5

Browse files
committed
🚧 施工中,卡在platform的注册
1 parent af4286d commit 1ca9da5

19 files changed

Lines changed: 963 additions & 79 deletions

File tree

bot.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
# 加载插件
1515
nonebot.load_from_toml("pyproject.toml")
16-
nonebot.load_plugin(Path(__file__) / "for_test_plugin.py")
16+
# FIXME
17+
# nonebot.load_plugin(Path(__file__) / "for_test_plugin.py")
1718

1819
if __name__ == "__main__":
1920
logger.warning("Always use `nb run` to start the bot instead of manually running!")

for_test_plugin.py

Lines changed: 62 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
from nonebot_bison import core, utils
1+
import anyio
2+
from nonebot import logger, require
3+
4+
require("nonebot_plugin_saa")
5+
require("nonebot_bison")
6+
from nonebot_plugin_saa import TargetQQGroup
7+
8+
from nonebot_bison import core
9+
from nonebot_bison.core.courier import Courier, Parcel, post_to_courier
210
from nonebot_bison.core.platform import FetchMixin, FilterMixin, Platform, PlatformConfig
311
from nonebot_bison.core.site import SiteConfig
12+
from nonebot_bison.typing import SubUnit, SubUnits, Target, UserSubInfo
13+
from nonebot_bison.utils.client_mgr import DefaultClientManager
14+
from nonebot_bison.utils.store import MemoryStore
415

516

617
class TestPlatform(Platform, FetchMixin, FilterMixin):
@@ -16,16 +27,63 @@ class TestPlatform(Platform, FetchMixin, FilterMixin):
1627
schedule_setting={"seconds": 60},
1728
client_mgr=DefaultClientManager,
1829
require_browser=False,
30+
store_cls=MemoryStore,
1931
)
2032

2133
def parse(self, raw_post: str) -> core.post.Post:
2234
return core.post.Post(
23-
platform=self,
35+
platform=self.platform_config,
2436
content=raw_post,
2537
)
2638

2739
async def fetch(self, sub_unit: core.platform.SubUnit) -> core.platform.TargetedPosts:
2840
# Simulate fetching posts
29-
posts = [self.parse(f"Test post {i} from {sub_unit.target}") for i in range(3)]
30-
return [(core.platform.PlatformTarget(self.platform_config.display_name, sub_unit.target), posts)]
41+
posts = [self.parse(f"Test post {i} from {sub_unit.sub_target}") for i in range(3)]
42+
return [(TargetQQGroup(group_id=114514), posts)]
43+
44+
45+
# ----
46+
47+
48+
def create_schedule_parcel(
49+
sub_units: SubUnits,
50+
platform_name: str,
51+
cmgr,
52+
store,
53+
) -> Parcel:
54+
return Parcel(
55+
tag="schedule",
56+
payload=sub_units,
57+
metadata={"platform_name": platform_name, "client_mgr": cmgr, "store": store},
58+
)
59+
60+
61+
async def test_send_schedule_parcel():
62+
cmgr = DefaultClientManager()
63+
store = MemoryStore()
64+
65+
66+
while True:
67+
if Courier._instance is None:
68+
logger.warning("courier not run")
69+
await anyio.sleep(2)
70+
continue
71+
await post_to_courier(
72+
create_schedule_parcel(
73+
SubUnit(Target("111"), [UserSubInfo(TargetQQGroup(group_id=114514), [], [])]),
74+
"TestPlatform",
75+
cmgr,
76+
store,
77+
)
78+
)
79+
logger.success("send a parcel")
80+
await anyio.sleep(5)
81+
82+
83+
from nonebot import get_driver
84+
85+
d = get_driver()
3186

87+
@d.on_startup
88+
async def a():
89+
d.task_group.start_soon(test_send_schedule_parcel, name="test")

nonebot_bison/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
import nonebot_plugin_saa
88

9+
from . import bootstrap as bootstrap
910
from . import core as core
11+
from . import inbox as inbox
1012
from .setting import BisonConfig, plugin_config
1113

1214
__help__version__ = "1.0.0"

nonebot_bison/bootstrap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async def post():
5858

5959
driver = get_driver()
6060
courier = create_courier(driver.task_group)
61-
61+
logger.info("start courier...")
6262
driver.task_group.start_soon(courier.run)
6363
driver.on_shutdown(courier.close)
6464

nonebot_bison/core/courier/courier.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import anyio
77
from anyio import create_memory_object_stream
8-
from loguru import logger
8+
from nonebot import logger
99
from nonebot.dependencies import Dependent, Param
1010
from nonebot.utils import flatten_exception_group
1111

@@ -68,6 +68,7 @@ def __new__(cls, *args, **kwargs) -> Self:
6868
@classmethod
6969
def get_instance(cls) -> Self:
7070
if cls._instance is None:
71+
logger.critical("Courier instance is not created yet, please call Courier() and .run() first")
7172
raise ValueError(
7273
"Courier instance is not created yet, please call Courier() and .run() first"
7374
)
@@ -108,6 +109,7 @@ def wrapper[R](
108109
receiver=dependentable,
109110
)
110111
cls.plan_channels.add(channel)
112+
logger.success(f"register courier channel [{channel}]")
111113
return receiver
112114

113115
return wrapper
@@ -174,7 +176,11 @@ async def _run_parcel_forwarding(channel: ChannelName):
174176
continue
175177

176178
try:
177-
match await send_road.receiver(parcel=parcel):
179+
# courier common receiver dependency inject on here
180+
match await send_road.receiver(
181+
parcel=parcel,
182+
task_group=tg,
183+
):
178184
case None:
179185
pass
180186
case Parcel(tag) if tag == parcel.tag:
@@ -236,6 +242,7 @@ async def _run_dead_letter_receiver():
236242
async with self.dead_letter_channel.outlet as rx:
237243
async for dead_letter in rx:
238244
exception = dead_letter.metadata.pop(__EXCEPTION_KEY__)
245+
# courier dead letter receiver dependency inject on here
239246
await self.dead_letter_receiver(
240247
parcel=dead_letter, exception=exception, task_group=self.task_group
241248
)

nonebot_bison/core/platform/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing_extensions import TypeIs
22

3-
from nonebot_bison.core.schedule import SubUnit, SubUnits
3+
from nonebot_bison.typing import SubUnit, SubUnits
44

55
from .config import PlatformConfig as PlatformConfig
66
from .platform import BatchFetchMixin as BatchFetchMixin

nonebot_bison/core/platform/platform.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55
from nonebot_plugin_saa import PlatformTarget
66

77
from nonebot_bison.core.post import Post
8-
from nonebot_bison.core.schedule import SubUnit
98
from nonebot_bison.core.site import ProcessContext, SiteConfig
10-
from nonebot_bison.typing import Category, Tag, Target
9+
from nonebot_bison.typing import Category, SubUnit, Tag, Target
1110
from nonebot_bison.utils.classproperty import classproperty
1211
from nonebot_bison.utils.meta import RegistryMeta
1312

nonebot_bison/core/post/post.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from dataclasses import dataclass
55
from io import BytesIO
66
from pathlib import Path
7+
from typing import override
78

89
from nonebot_bison.core.platform import PlatformConfig
910

@@ -38,3 +39,7 @@ class Post(PlainContentSupport):
3839
"""发布者个性签名等"""
3940
repost: "Post | None" = None
4041
"""转发的Post"""
42+
43+
@override
44+
async def get_plain_content(self) -> str:
45+
return self.content
Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
11
from .manager import handle_delete_target as handle_delete_target
22
from .manager import handle_insert_new_target as handle_insert_new_target
33
from .manager import init_scheduler as init_scheduler
4-
from .model import SubUnit as SubUnit
5-
from .model import SubUnits as SubUnits
6-
from .model import UserSubInfo as UserSubInfo

nonebot_bison/core/schedule/manager.py

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from dataclasses import dataclass, field
12
from typing import TYPE_CHECKING
23

34
from nonebot.log import logger
@@ -13,31 +14,70 @@
1314
if TYPE_CHECKING:
1415
from nonebot_bison.db.db_model import Target
1516

16-
scheduler_dict: dict[SiteConfig, Scheduler] = {}
17+
type SiteName = str
18+
19+
20+
@dataclass
21+
class SchedulerDict:
22+
schedulers: dict[SiteName, Scheduler] = field(default_factory=dict)
23+
24+
def __getitem__(self, key: str | SiteConfig, /) -> Scheduler:
25+
match key:
26+
case str():
27+
return self.schedulers[key]
28+
case SiteConfig():
29+
return self.schedulers[key.name]
30+
case _:
31+
raise TypeError(f"Unsupport SchedulerDict key type: {type(key)}")
32+
33+
def __setitem__(self, key: str | SiteConfig, value: Scheduler, /):
34+
match key:
35+
case str():
36+
self.schedulers[key] = value
37+
case SiteConfig():
38+
self.schedulers[key.name] = value
39+
case _:
40+
raise TypeError(f"Unsupport SchedulerDict key type: {type(key)}")
41+
42+
def __contains__(self, key: str | SiteConfig) -> bool:
43+
match key:
44+
case str():
45+
return key in self.schedulers
46+
case SiteConfig():
47+
return key.name in self.schedulers
48+
case _:
49+
raise TypeError(f"Unsupport SchedulerDict key type: {type(key)}")
50+
51+
52+
scheduler_dict = SchedulerDict()
1753

1854

1955
async def init_scheduler():
20-
_schedule_class_dict: dict[SiteConfig, list[Target]] = {}
21-
_schedule_class_platform_dict: dict[SiteConfig, list[str]] = {}
56+
_schedule_class_name: dict[SiteName, SiteConfig] = {}
57+
_schedule_class_dict: dict[SiteName, list[Target]] = {}
58+
_schedule_class_platform_dict: dict[SiteName, list[str]] = {}
2259
for platform in Platform.registry.values():
2360
platform: Platform = platform
2461
site = platform.site_config
2562
if not hasattr(site, "name") or not site.name:
2663
site.name = f"AnonymousScheduleConfig[{platform.platform_config.display_name}]"
2764

65+
site_name = site.name
2866
platform_name = platform.platform_config.display_name
2967
targets = await data_access.get_platform_target(platform_name)
30-
if site not in _schedule_class_dict:
31-
_schedule_class_dict[site] = list(targets)
68+
if site_name not in _schedule_class_dict:
69+
_schedule_class_name[site_name] = site
70+
_schedule_class_dict[site_name] = list(targets)
3271
else:
33-
_schedule_class_dict[site].extend(targets)
34-
if site not in _schedule_class_platform_dict:
35-
_schedule_class_platform_dict[site] = [platform_name]
72+
_schedule_class_dict[site_name].extend(targets)
73+
if site_name not in _schedule_class_platform_dict:
74+
_schedule_class_platform_dict[site_name] = [platform_name]
3675
else:
37-
_schedule_class_platform_dict[site].append(platform_name)
76+
_schedule_class_platform_dict[site_name].append(platform_name)
77+
3878
for site, target_list in _schedule_class_dict.items():
39-
if not plugin_config.bison_use_browser and site.require_browser:
40-
logger.warning(f"{site.name} requires browser, it will not schedule.")
79+
if not plugin_config.bison_use_browser and _schedule_class_name[site].require_browser:
80+
logger.warning(f"{site} requires browser, it will not schedule.")
4181
continue
4282

4383
schedulable_args = []
@@ -46,7 +86,7 @@ async def init_scheduler():
4686
(target.platform_name, T_Target(target.target), Platform.registry[target.platform_name].use_batch)
4787
)
4888
platform_name_list = _schedule_class_platform_dict[site]
49-
scheduler_dict[site] = Scheduler(site, schedulable_args, platform_name_list)
89+
scheduler_dict[site] = Scheduler(_schedule_class_name[site], schedulable_args, platform_name_list)
5090
# if is_cookie_client_manager(site.client_mgr):
5191
# client_mgr = cast("CookieClientManager", scheduler_dict[site].client_mgr)
5292
# await client_mgr.refresh_client()

0 commit comments

Comments
 (0)