Skip to content

Commit ad9427a

Browse files
authored
v2.3.7: 优化代码,实现组件(Client、Plugin)的自动注册机制,支持dict类型的域名配置方便统一配置文件 (#148)
1 parent 8070951 commit ad9427a

File tree

9 files changed

+88
-57
lines changed

9 files changed

+88
-57
lines changed

assets/config/option_test_api.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
11
# GitHub Actions 测试用
22
# 移动端配置
3+
dir_rule:
4+
rule: Bd_Aauthor_Aid_Pindextitle
35

46
client:
57
impl: api
68
retry_times: 3
79
postman:
810
meta_data:
911
timeout: 7
12+
domain:
13+
html:
14+
- jmcomic1.me
15+
- jmcomic.me
1016

1117
# 插件配置
1218
plugin:

assets/config/option_test_html.yml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
# GitHub Actions 测试用
22
# 网页端配置
3+
dir_rule:
4+
rule: Bd_Aauthor_Aid_Pindextitle
35

46
client:
57
impl: html
68
retry_times: 3
79
postman:
810
meta_data:
9-
timeout: 5
11+
timeout: 7
1012
domain:
11-
- jmcomic1.me
12-
- jmcomic.me
13+
html:
14+
- jmcomic1.me
15+
- jmcomic.me
1316

1417
# 插件配置
1518
plugin:
@@ -18,3 +21,8 @@ plugin:
1821
kwargs:
1922
interval: 0.5 # 间隔时间
2023
enable_warning: false # 不告警
24+
25+
- plugin: client_proxy
26+
kwargs:
27+
proxy_client_key: cl_proxy_future
28+
whitelist: [ api, ]

src/jmcomic/__init__.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,28 @@
22
# 被依赖方 <--- 使用方
33
# config <--- entity <--- toolkit <--- client <--- option <--- downloader
44

5-
__version__ = '2.3.6'
5+
__version__ = '2.3.7'
66

77
from .api import *
88
from .jm_plugin import *
9+
10+
# 下面进行注册组件(客户端、插件)
11+
gb = dict(filter(lambda pair: isinstance(pair[1], type), globals().items()))
12+
13+
14+
def register_jmcomic_component(gb: dict, method, valid_interface: type):
15+
for v in gb.values():
16+
if v != valid_interface and issubclass(v, valid_interface):
17+
method(v)
18+
19+
20+
# 注册客户端
21+
register_jmcomic_component(gb,
22+
JmModuleConfig.register_client,
23+
JmcomicClient,
24+
)
25+
# 注册插件
26+
register_jmcomic_component(gb,
27+
JmModuleConfig.register_plugin,
28+
JmOptionPlugin,
29+
)

src/jmcomic/jm_client_impl.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ class AbstractJmClient(
66
JmcomicClient,
77
PostmanProxy,
88
):
9-
client_key = None
9+
client_key = '__just_for_placeholder_do_not_use_me__'
1010
func_to_cache = []
1111

1212
def __init__(self,
@@ -324,7 +324,7 @@ def album_comment(self,
324324
(f' to ({comment_id})' if comment_id is not None else '')
325325
)
326326

327-
resp = self.post('https://18comic.vip/ajax/album_comment',
327+
resp = self.post('/ajax/album_comment',
328328
headers=JmModuleConfig.album_comment_headers,
329329
data=data,
330330
)
@@ -679,8 +679,3 @@ def search(self, search_query: str, page: int, main_tag: int, order_by: str, tim
679679
cache_key = f'search_query_{search_query}_page_{page}_main_tag_{main_tag}_order_by_{order_by}_time_{time}'
680680
future = self.get_future(cache_key, task=lambda: self.client.search(search_query, page, main_tag, order_by, time))
681681
return future.result()
682-
683-
684-
JmModuleConfig.register_client(JmHtmlClient)
685-
JmModuleConfig.register_client(JmApiClient)
686-
JmModuleConfig.register_client(FutureClientProxy)

src/jmcomic/jm_config.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ class JmModuleConfig:
7878
CLASS_ALBUM = None
7979
CLASS_PHOTO = None
8080
CLASS_IMAGE = None
81-
CLASS_CLIENT_IMPL = {}
8281
CLASS_EXCEPTION = JmcomicException
83-
82+
# 客户端注册表
83+
REGISTRY_CLIENT = {}
8484
# 插件注册表
85-
PLUGIN_REGISTRY = {}
85+
REGISTRY_PLUGIN = {}
8686

8787
# 执行debug的函数
8888
debug_executor = default_jm_debug
@@ -140,7 +140,7 @@ def image_class(cls):
140140

141141
@classmethod
142142
def client_impl_class(cls, client_key: str):
143-
clazz_dict = cls.CLASS_CLIENT_IMPL
143+
clazz_dict = cls.REGISTRY_CLIENT
144144

145145
clazz = clazz_dict.get(client_key, None)
146146
if clazz is None:
@@ -320,16 +320,17 @@ def option_default_dict(cls) -> dict:
320320

321321
@classmethod
322322
def register_plugin(cls, plugin_class):
323-
cls.PLUGIN_REGISTRY[plugin_class.plugin_key] = plugin_class
323+
from .jm_toolkit import ExceptionTool
324+
ExceptionTool.require_true(getattr(plugin_class, 'plugin_key', None) is not None,
325+
f'未配置plugin_key, class: {plugin_class}')
326+
cls.REGISTRY_PLUGIN[plugin_class.plugin_key] = plugin_class
324327

325328
@classmethod
326329
def register_client(cls, client_class):
327-
client_key = getattr(client_class, 'client_key', None)
328-
if client_key is None:
329-
from .jm_toolkit import ExceptionTool
330-
ExceptionTool.raises(f'未配置client_key, class: {client_class}')
331-
332-
cls.CLASS_CLIENT_IMPL[client_key] = client_class
330+
from .jm_toolkit import ExceptionTool
331+
ExceptionTool.require_true(getattr(client_class, 'client_key', None) is not None,
332+
f'未配置client_key, class: {client_class}')
333+
cls.REGISTRY_CLIENT[client_class.client_key] = client_class
333334

334335

335336
jm_debug = JmModuleConfig.jm_debug

src/jmcomic/jm_entity.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def __init__(self,
8484
) -> None:
8585
if scramble_id is None or (isinstance(scramble_id, str) and scramble_id == ''):
8686
from .jm_toolkit import ExceptionTool
87-
ExceptionTool.raises(f'图片的scramble_id不能为空D')
87+
ExceptionTool.raises(f'图片的scramble_id不能为空')
8888

8989
self.aid: str = str(aid)
9090
self.scramble_id: str = str(scramble_id)

src/jmcomic/jm_option.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -298,21 +298,27 @@ def build_jm_client(self, **kwargs):
298298
"""
299299
return self.new_jm_client(**kwargs)
300300

301-
def new_jm_client(self, domain_list=None, impl=None, **kwargs) -> JmcomicClient:
302-
postman_conf: dict = self.client.postman.src_dict
303-
impl = impl or self.client.impl
301+
def new_jm_client(self, domain=None, impl=None, **kwargs) -> JmcomicClient:
302+
# 所有需要用到的 self.client 配置项如下
303+
postman_conf: dict = self.client.postman.src_dict # postman dsl 配置
304+
impl: str = impl or self.client.impl # client_key
305+
retry_times: int = self.client.retry_times # 重试次数
306+
cache: str = self.client.cache # 启用缓存
304307

305-
# domain_list
306-
if domain_list is None:
307-
domain_list = self.client.domain
308+
# domain
309+
def decide_domain():
310+
domain_list: Union[List[str], DictModel, dict] = domain if domain is not None \
311+
else self.client.domain # 域名
308312

309-
domain_list: Union[List[str], DictModel]
310-
if not isinstance(domain_list, list):
311-
domain_list_dict: DictModel = domain_list
312-
domain_list = domain_list_dict.get(impl, [])
313+
if not isinstance(domain_list, list):
314+
domain_list = domain_list.get(impl, [])
313315

314-
if len(domain_list) == 0:
315-
domain_list = self.decide_client_domain(impl)
316+
if len(domain_list) == 0:
317+
domain_list = self.decide_client_domain(impl)
318+
319+
return domain_list
320+
321+
domain: List[str] = decide_domain()
316322

317323
# support kwargs overwrite meta_data
318324
if len(kwargs) != 0:
@@ -321,20 +327,23 @@ def new_jm_client(self, domain_list=None, impl=None, **kwargs) -> JmcomicClient:
321327
# headers
322328
meta_data = postman_conf['meta_data']
323329
if meta_data['headers'] is None:
324-
meta_data['headers'] = JmModuleConfig.headers(domain_list[0])
330+
meta_data['headers'] = JmModuleConfig.headers(domain[0])
325331

326332
# postman
327333
postman = Postmans.create(data=postman_conf)
328334

329335
# client
330-
client = JmModuleConfig.client_impl_class(impl)(
336+
clazz = JmModuleConfig.client_impl_class(impl)
337+
if clazz == AbstractJmClient or not issubclass(clazz, AbstractJmClient):
338+
raise NotImplementedError(clazz)
339+
client = clazz(
331340
postman,
332-
self.client.retry_times,
333-
fallback_domain_list=domain_list,
341+
retry_times,
342+
fallback_domain_list=decide_domain(),
334343
)
335344

336345
# enable cache
337-
if self.client.cache is True:
346+
if cache is True:
338347
client.enable_cache()
339348

340349
return client
@@ -396,7 +405,7 @@ def call_all_plugin(self, group: str, **extra):
396405
# 保证 jm_plugin.py 被加载
397406
from .jm_plugin import JmOptionPlugin
398407

399-
plugin_registry = JmModuleConfig.PLUGIN_REGISTRY
408+
plugin_registry = JmModuleConfig.REGISTRY_PLUGIN
400409
for pinfo in plugin_list:
401410
key, kwargs = pinfo['plugin'], pinfo['kwargs']
402411
plugin_class: Optional[Type[JmOptionPlugin]] = plugin_registry.get(key, None)

src/jmcomic/jm_plugin.py

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
该文件存放的是option扩展功能类
2+
该文件存放的是option插件
33
"""
44

55
from .jm_option import *
@@ -335,9 +335,7 @@ def invoke(self,
335335
whitelist=None,
336336
**kwargs,
337337
) -> None:
338-
if whitelist is None:
339-
whitelist = set()
340-
else:
338+
if whitelist is not None:
341339
whitelist = set(whitelist)
342340

343341
clazz = JmModuleConfig.client_impl_class(proxy_client_key)
@@ -346,17 +344,10 @@ def invoke(self,
346344

347345
def hook_new_jm_client(*args, **kwargs):
348346
client = new_jm_client(*args, **kwargs)
349-
if client.client_key not in whitelist:
347+
if whitelist is not None and client.client_key not in whitelist:
350348
return client
351349

352-
jm_debug('plugin.client_proxy', f'proxy client {client} with {clazz}')
350+
jm_debug('plugin.client_proxy', f'proxy client {client} with {proxy_client_key}')
353351
return clazz(client, **clazz_init_kwargs)
354352

355353
self.option.new_jm_client = hook_new_jm_client
356-
357-
358-
JmModuleConfig.register_plugin(JmLoginPlugin)
359-
JmModuleConfig.register_plugin(UsageLogPlugin)
360-
JmModuleConfig.register_plugin(FindUpdatePlugin)
361-
JmModuleConfig.register_plugin(ZipPlugin)
362-
JmModuleConfig.register_plugin(ClientProxyPlugin)

tests/test_jmcomic/test_jm_custom.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class MyClient(JmApiClient):
4545

4646
self.assertListEqual(
4747
JmModuleConfig.DOMAIN_API_LIST,
48-
self.option.new_jm_client(domain_list=[], impl=MyClient.client_key).get_domain_list()
48+
self.option.new_jm_client(domain=[], impl=MyClient.client_key).get_domain_list()
4949
)
5050

5151
def test_extends_html_client(self):
@@ -57,7 +57,7 @@ class MyClient(JmHtmlClient):
5757
html_domain = self.client.get_html_domain()
5858
self.assertListEqual(
5959
[html_domain],
60-
self.option.new_jm_client(domain_list=[], impl=MyClient.client_key).get_domain_list()
60+
self.option.new_jm_client(domain=[], impl=MyClient.client_key).get_domain_list()
6161
)
6262

6363
def test_client_key_missing(self):
@@ -93,6 +93,6 @@ class MyClient(JmApiClient):
9393
JmModuleConfig.register_client(MyClient)
9494
self.assertListEqual(
9595
JmModuleConfig.DOMAIN_API_LIST,
96-
self.option.new_jm_client(domain_list=[], impl=MyClient.client_key).get_domain_list(),
96+
self.option.new_jm_client(domain=[], impl=MyClient.client_key).get_domain_list(),
9797
msg='继承client,不配置域名',
9898
)

0 commit comments

Comments
 (0)