jmcomic 2.5.1__py3-none-any.whl → 2.5.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
jmcomic/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # 被依赖方 <--- 使用方
3
3
  # config <--- entity <--- toolkit <--- client <--- option <--- downloader
4
4
 
5
- __version__ = '2.5.1'
5
+ __version__ = '2.5.3'
6
6
 
7
7
  from .api import *
8
8
  from .jm_plugin import *
jmcomic/jm_client_impl.py CHANGED
@@ -78,8 +78,10 @@ class AbstractJmClient(
78
78
  :param kwargs: 请求方法的kwargs
79
79
  """
80
80
  if domain_index >= len(self.domain_list):
81
- self.fallback(request, url, domain_index, retry_count, **kwargs)
82
-
81
+ return self.fallback(request, url, domain_index, retry_count, **kwargs)
82
+
83
+ url_backup = url
84
+
83
85
  if url.startswith('/'):
84
86
  # path → url
85
87
  domain = self.domain_list[domain_index]
@@ -120,9 +122,9 @@ class AbstractJmClient(
120
122
  self.before_retry(e, kwargs, retry_count, url)
121
123
 
122
124
  if retry_count < self.retry_times:
123
- return self.request_with_retry(request, url, domain_index, retry_count + 1, callback, **kwargs)
125
+ return self.request_with_retry(request, url_backup, domain_index, retry_count + 1, callback, **kwargs)
124
126
  else:
125
- return self.request_with_retry(request, url, domain_index + 1, 0, callback, **kwargs)
127
+ return self.request_with_retry(request, url_backup, domain_index + 1, 0, callback, **kwargs)
126
128
 
127
129
  # noinspection PyMethodMayBeStatic
128
130
  def raise_if_resp_should_retry(self, resp):
@@ -209,7 +211,7 @@ class AbstractJmClient(
209
211
  def fallback(self, request, url, domain_index, retry_count, **kwargs):
210
212
  msg = f"请求重试全部失败: [{url}], {self.domain_list}"
211
213
  jm_log('req.fallback', msg)
212
- ExceptionTool.raises(msg)
214
+ ExceptionTool.raises(msg, {}, RequestRetryAllFailException)
213
215
 
214
216
  # noinspection PyMethodMayBeStatic
215
217
  def append_params_to_url(self, url, params):
jmcomic/jm_config.py CHANGED
@@ -117,10 +117,10 @@ class JmModuleConfig:
117
117
 
118
118
  # 移动端API域名
119
119
  DOMAIN_API_LIST = str_to_list('''
120
+ www.jmapinode.biz
120
121
  www.jmapinode1.top
121
122
  www.jmapinode2.top
122
123
  www.jmapinode3.top
123
- www.jmapinode.biz
124
124
  www.jmapinode.top
125
125
 
126
126
  ''')
@@ -144,8 +144,11 @@ class JmModuleConfig:
144
144
  REGISTRY_CLIENT = {}
145
145
  # 插件注册表
146
146
  REGISTRY_PLUGIN = {}
147
- # 异常处理器
148
- REGISTRY_EXCEPTION_ADVICE = {}
147
+ # 异常监听器
148
+ # key: 异常类
149
+ # value: 函数,参数只有异常对象,无需返回值
150
+ # 这个异常类(或者这个异常的子类)的实例将要被raise前,你的listener方法会被调用
151
+ REGISTRY_EXCEPTION_LISTENER = {}
149
152
 
150
153
  # 执行log的函数
151
154
  executor_log = default_jm_logging
@@ -311,7 +314,7 @@ class JmModuleConfig:
311
314
  # 而如果只想修改几个简单常用的配置,也可以下方的DEFAULT_XXX属性
312
315
  JM_OPTION_VER = '2.1'
313
316
  DEFAULT_CLIENT_IMPL = 'api' # 默认Client实现类型为网页端
314
- DEFAULT_CLIENT_CACHE = True # 默认开启Client缓存,缓存级别是level_option,详见CacheRegistry
317
+ DEFAULT_CLIENT_CACHE = None # 默认关闭Client缓存。缓存的配置详见 CacheRegistry
315
318
  DEFAULT_PROXIES = ProxyBuilder.system_proxy() # 默认使用系统代理
316
319
 
317
320
  default_option_dict: dict = {
@@ -404,8 +407,8 @@ class JmModuleConfig:
404
407
  cls.REGISTRY_CLIENT[client_class.client_key] = client_class
405
408
 
406
409
  @classmethod
407
- def register_exception_advice(cls, etype, eadvice):
408
- cls.REGISTRY_EXCEPTION_ADVICE[etype] = eadvice
410
+ def register_exception_listener(cls, etype, listener):
411
+ cls.REGISTRY_EXCEPTION_LISTENER[etype] = listener
409
412
 
410
413
 
411
414
  jm_log = JmModuleConfig.jm_log
jmcomic/jm_exception.py CHANGED
@@ -3,9 +3,7 @@ from .jm_entity import *
3
3
 
4
4
 
5
5
  class JmcomicException(Exception):
6
- """
7
- jmcomic 模块异常
8
- """
6
+ description = 'jmcomic 模块异常'
9
7
 
10
8
  def __init__(self, msg: str, context: dict):
11
9
  self.msg = msg
@@ -16,19 +14,22 @@ class JmcomicException(Exception):
16
14
 
17
15
 
18
16
  class ResponseUnexpectedException(JmcomicException):
19
- """
20
- 响应不符合预期异常
21
- """
17
+ description = '响应不符合预期异常'
22
18
 
23
19
  @property
24
20
  def resp(self):
25
21
  return self.from_context(ExceptionTool.CONTEXT_KEY_RESP)
26
22
 
27
23
 
28
- class RegularNotMatchException(ResponseUnexpectedException):
29
- """
30
- 正则表达式不匹配异常
31
- """
24
+ class RegularNotMatchException(JmcomicException):
25
+ description = '正则表达式不匹配异常'
26
+
27
+ @property
28
+ def resp(self):
29
+ """
30
+ 可能为None
31
+ """
32
+ return self.context.get(ExceptionTool.CONTEXT_KEY_RESP, None)
32
33
 
33
34
  @property
34
35
  def error_text(self):
@@ -40,19 +41,23 @@ class RegularNotMatchException(ResponseUnexpectedException):
40
41
 
41
42
 
42
43
  class JsonResolveFailException(ResponseUnexpectedException):
44
+ description = 'Json解析异常'
43
45
  pass
44
46
 
45
47
 
46
48
  class MissingAlbumPhotoException(ResponseUnexpectedException):
47
- """
48
- 缺少本子/章节异常
49
- """
49
+ description = '不存在本子或章节异常'
50
50
 
51
51
  @property
52
52
  def error_jmid(self) -> str:
53
53
  return self.from_context(ExceptionTool.CONTEXT_KEY_MISSING_JM_ID)
54
54
 
55
55
 
56
+ class RequestRetryAllFailException(JmcomicException):
57
+ description = '请求重试全部失败异常'
58
+ pass
59
+
60
+
56
61
  class ExceptionTool:
57
62
  """
58
63
  抛异常的工具
@@ -65,6 +70,13 @@ class ExceptionTool:
65
70
  CONTEXT_KEY_RE_PATTERN = 'pattern'
66
71
  CONTEXT_KEY_MISSING_JM_ID = 'missing_jm_id'
67
72
 
73
+ # 兼容旧版本
74
+
75
+ EXTRA_KEY_RESP = 'resp'
76
+ EXTRA_KEY_HTML = 'html'
77
+ EXTRA_KEY_RE_PATTERN = 'pattern'
78
+ EXTRA_KEY_MISSING_JM_ID = 'missing_jm_id'
79
+
68
80
  @classmethod
69
81
  def raises(cls,
70
82
  msg: str,
@@ -88,10 +100,7 @@ class ExceptionTool:
88
100
  e = etype(msg, context)
89
101
 
90
102
  # 异常处理建议
91
- advice = JmModuleConfig.REGISTRY_EXCEPTION_ADVICE.get(etype, None)
92
-
93
- if advice is not None:
94
- advice(e)
103
+ cls.notify_all_listeners(e)
95
104
 
96
105
  raise e
97
106
 
@@ -156,3 +165,24 @@ class ExceptionTool:
156
165
  return
157
166
 
158
167
  cls.raises(msg)
168
+
169
+ @classmethod
170
+ def replace_old_exception_executor(cls, raises: Callable[[Callable, str, dict], None]):
171
+ old = cls.raises
172
+
173
+ def new(msg, context=None, _etype=None):
174
+ if context is None:
175
+ context = {}
176
+ raises(old, msg, context)
177
+
178
+ cls.raises = new
179
+
180
+ @classmethod
181
+ def notify_all_listeners(cls, e):
182
+ registry: Dict[Type, Callable[Type]] = JmModuleConfig.REGISTRY_EXCEPTION_LISTENER
183
+ if not registry:
184
+ return None
185
+
186
+ for accept_type, listener in registry.items():
187
+ if isinstance(e, accept_type):
188
+ listener(e)
jmcomic/jm_option.py CHANGED
@@ -17,8 +17,11 @@ class CacheRegistry:
17
17
  return registry[client]
18
18
 
19
19
  @classmethod
20
- def enable_client_cache_on_condition(cls, option: 'JmOption', client: JmcomicClient,
21
- cache: Union[None, bool, str, Callable]):
20
+ def enable_client_cache_on_condition(cls,
21
+ option: 'JmOption',
22
+ client: JmcomicClient,
23
+ cache: Union[None, bool, str, Callable],
24
+ ):
22
25
  """
23
26
  cache parameter
24
27
 
@@ -539,7 +542,7 @@ class JmOption:
539
542
 
540
543
  pclass: Type[JmOptionPlugin]
541
544
  plugin: Optional[JmOptionPlugin] = None
542
-
545
+
543
546
  try:
544
547
  # 构建插件对象
545
548
  plugin: JmOptionPlugin = pclass.build(self)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jmcomic
3
- Version: 2.5.1
3
+ Version: 2.5.3
4
4
  Summary: Python API For JMComic (禁漫天堂)
5
5
  Home-page: https://github.com/hect0x7/JMComic-Crawler-Python
6
6
  Author: hect0x7
@@ -97,8 +97,8 @@ $ jmcomic 422866
97
97
  - **可扩展性强**
98
98
 
99
99
  - 支持自定义本子/章节/图片下载前后的回调函数
100
- - 支持自定义日志
101
100
  - 支持自定义类:`Downloader(负责调度)` `Option(负责配置)` `Client(负责请求)` `实体类`等
101
+ - 支持自定义日志、异常监听器
102
102
  - **支持Plugin插件,可以方便地扩展功能,以及使用别人的插件,目前内置插件有**:
103
103
  - `登录插件`
104
104
  - `硬件占用监控插件`
@@ -0,0 +1,18 @@
1
+ jmcomic/__init__.py,sha256=xop4fs0-joR7gysv1acbzuGmGirY58HaEE6oFv8uNJU,902
2
+ jmcomic/api.py,sha256=qOUG1B2hornxMykQp1y4E2qaRhQAg7KPBmXmptik3vM,3500
3
+ jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
4
+ jmcomic/jm_client_impl.py,sha256=mMkf9q2U3FCEwiWMwt_Sj97-WsqdE6UmKHE3LJsqEhA,37883
5
+ jmcomic/jm_client_interface.py,sha256=bBKwcXkEns8fNy5IsEaljph3E_pyER3RGLG_no6cidU,17164
6
+ jmcomic/jm_config.py,sha256=C_jfCwJ2T4sWIeyn5oRf6mPR62e-dHVwFCMqrE7Ff44,13792
7
+ jmcomic/jm_downloader.py,sha256=ADkgEOhb8ycHWqaM5knOIpNK8yJuN5J_BEvVnx0E0C0,8556
8
+ jmcomic/jm_entity.py,sha256=_gf8P3GDHkjUzZriQrQQ3-n_o5BZ7KZoh21qYXsQJ-0,18734
9
+ jmcomic/jm_exception.py,sha256=6qDnPo-O6wqNBVweW-rdvMpwnvGCj2hapcLlZqTtTlg,4847
10
+ jmcomic/jm_option.py,sha256=POfmjxJPbqo7IZhSF0lxHuKV1eKlBS7D2Z8Z0n8UQ6c,21182
11
+ jmcomic/jm_plugin.py,sha256=67zdKtn16-BTAyji3eG0wfRx1-fxQD3oL0VnG9t5Lrc,29196
12
+ jmcomic/jm_toolkit.py,sha256=SgVgyh-TyppL_RfeyyFjlTADF5kwjqNeNdofZHTm6Do,28360
13
+ jmcomic-2.5.3.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
14
+ jmcomic-2.5.3.dist-info/METADATA,sha256=Tu1Og-t9nU1hSqGnRIf3W3Vx0BQA3MeWfKYTP3dGIkI,5993
15
+ jmcomic-2.5.3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
16
+ jmcomic-2.5.3.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
17
+ jmcomic-2.5.3.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
18
+ jmcomic-2.5.3.dist-info/RECORD,,
@@ -1,18 +0,0 @@
1
- jmcomic/__init__.py,sha256=lPQKl9ByTk5UpUQSI1pLFdVukIV7xpiRs462fDK6nRI,902
2
- jmcomic/api.py,sha256=qOUG1B2hornxMykQp1y4E2qaRhQAg7KPBmXmptik3vM,3500
3
- jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
4
- jmcomic/jm_client_impl.py,sha256=WN2Ae5yED9VLeZRbaDXzepWWUDVQaQ5uU4ROaXuaKyg,37786
5
- jmcomic/jm_client_interface.py,sha256=bBKwcXkEns8fNy5IsEaljph3E_pyER3RGLG_no6cidU,17164
6
- jmcomic/jm_config.py,sha256=GfWSzG2uA-UtUNcCHFPE5sT9LbgnEGdJ9Kx7pIshkzg,13596
7
- jmcomic/jm_downloader.py,sha256=ADkgEOhb8ycHWqaM5knOIpNK8yJuN5J_BEvVnx0E0C0,8556
8
- jmcomic/jm_entity.py,sha256=_gf8P3GDHkjUzZriQrQQ3-n_o5BZ7KZoh21qYXsQJ-0,18734
9
- jmcomic/jm_exception.py,sha256=RraAWFP4zC7jhgLogOHzAF08yyimbiTrXHtUobs2ES8,3847
10
- jmcomic/jm_option.py,sha256=3vLN9qOWPUrt3oIbvJXzfmZCNhXIGmCIu5dOKJMNk3I,21065
11
- jmcomic/jm_plugin.py,sha256=67zdKtn16-BTAyji3eG0wfRx1-fxQD3oL0VnG9t5Lrc,29196
12
- jmcomic/jm_toolkit.py,sha256=SgVgyh-TyppL_RfeyyFjlTADF5kwjqNeNdofZHTm6Do,28360
13
- jmcomic-2.5.1.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
14
- jmcomic-2.5.1.dist-info/METADATA,sha256=aDz6ifAgIw7BZapWfUioLblR2RVMfPSmlPf-duVKcTM,5975
15
- jmcomic-2.5.1.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
16
- jmcomic-2.5.1.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
17
- jmcomic-2.5.1.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
18
- jmcomic-2.5.1.dist-info/RECORD,,