jmcomic 0.0.2__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 +29 -0
- jmcomic/api.py +131 -0
- jmcomic/cl.py +121 -0
- jmcomic/jm_client_impl.py +1217 -0
- jmcomic/jm_client_interface.py +609 -0
- jmcomic/jm_config.py +505 -0
- jmcomic/jm_downloader.py +350 -0
- jmcomic/jm_entity.py +695 -0
- jmcomic/jm_exception.py +191 -0
- jmcomic/jm_option.py +647 -0
- jmcomic/jm_plugin.py +1203 -0
- jmcomic/jm_toolkit.py +937 -0
- jmcomic-0.0.2.dist-info/METADATA +229 -0
- jmcomic-0.0.2.dist-info/RECORD +18 -0
- jmcomic-0.0.2.dist-info/WHEEL +5 -0
- jmcomic-0.0.2.dist-info/entry_points.txt +2 -0
- jmcomic-0.0.2.dist-info/licenses/LICENSE +21 -0
- jmcomic-0.0.2.dist-info/top_level.txt +1 -0
jmcomic/jm_exception.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# 该文件存放jmcomic的异常机制设计和实现
|
|
2
|
+
from .jm_entity import *
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class JmcomicException(Exception):
|
|
6
|
+
description = 'jmcomic 模块异常'
|
|
7
|
+
|
|
8
|
+
def __init__(self, msg: str, context: dict):
|
|
9
|
+
self.msg = msg
|
|
10
|
+
self.context = context
|
|
11
|
+
|
|
12
|
+
def from_context(self, key):
|
|
13
|
+
return self.context[key]
|
|
14
|
+
|
|
15
|
+
def __str__(self):
|
|
16
|
+
return self.msg
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class ResponseUnexpectedException(JmcomicException):
|
|
20
|
+
description = '响应不符合预期异常'
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def resp(self):
|
|
24
|
+
return self.from_context(ExceptionTool.CONTEXT_KEY_RESP)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class RegularNotMatchException(JmcomicException):
|
|
28
|
+
description = '正则表达式不匹配异常'
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def resp(self):
|
|
32
|
+
"""
|
|
33
|
+
可能为None
|
|
34
|
+
"""
|
|
35
|
+
return self.context.get(ExceptionTool.CONTEXT_KEY_RESP, None)
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def error_text(self):
|
|
39
|
+
return self.from_context(ExceptionTool.CONTEXT_KEY_HTML)
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def pattern(self):
|
|
43
|
+
return self.from_context(ExceptionTool.CONTEXT_KEY_RE_PATTERN)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class JsonResolveFailException(ResponseUnexpectedException):
|
|
47
|
+
description = 'Json解析异常'
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
class MissingAlbumPhotoException(ResponseUnexpectedException):
|
|
51
|
+
description = '不存在本子或章节异常'
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def error_jmid(self) -> str:
|
|
55
|
+
return self.from_context(ExceptionTool.CONTEXT_KEY_MISSING_JM_ID)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class RequestRetryAllFailException(JmcomicException):
|
|
59
|
+
description = '请求重试全部失败异常'
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class PartialDownloadFailedException(JmcomicException):
|
|
63
|
+
description = '部分章节或图片下载失败异常'
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def downloader(self):
|
|
67
|
+
return self.from_context(ExceptionTool.CONTEXT_KEY_DOWNLOADER)
|
|
68
|
+
|
|
69
|
+
class ExceptionTool:
|
|
70
|
+
"""
|
|
71
|
+
抛异常的工具
|
|
72
|
+
1: 能简化 if-raise 语句的编写
|
|
73
|
+
2: 有更好的上下文信息传递方式
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
CONTEXT_KEY_RESP = 'resp'
|
|
77
|
+
CONTEXT_KEY_HTML = 'html'
|
|
78
|
+
CONTEXT_KEY_RE_PATTERN = 'pattern'
|
|
79
|
+
CONTEXT_KEY_MISSING_JM_ID = 'missing_jm_id'
|
|
80
|
+
CONTEXT_KEY_DOWNLOADER = 'downloader'
|
|
81
|
+
|
|
82
|
+
@classmethod
|
|
83
|
+
def raises(cls,
|
|
84
|
+
msg: str,
|
|
85
|
+
context: dict = None,
|
|
86
|
+
etype: Optional[Type[Exception]] = None,
|
|
87
|
+
):
|
|
88
|
+
"""
|
|
89
|
+
抛出异常
|
|
90
|
+
|
|
91
|
+
:param msg: 异常消息
|
|
92
|
+
:param context: 异常上下文数据
|
|
93
|
+
:param etype: 异常类型,默认使用 JmcomicException
|
|
94
|
+
"""
|
|
95
|
+
if context is None:
|
|
96
|
+
context = {}
|
|
97
|
+
|
|
98
|
+
if etype is None:
|
|
99
|
+
etype = JmcomicException
|
|
100
|
+
|
|
101
|
+
# 异常对象
|
|
102
|
+
e = etype(msg, context)
|
|
103
|
+
|
|
104
|
+
# 异常处理建议
|
|
105
|
+
cls.notify_all_listeners(e)
|
|
106
|
+
|
|
107
|
+
raise e
|
|
108
|
+
|
|
109
|
+
@classmethod
|
|
110
|
+
def raises_regex(cls,
|
|
111
|
+
msg: str,
|
|
112
|
+
html: str,
|
|
113
|
+
pattern: Pattern,
|
|
114
|
+
):
|
|
115
|
+
cls.raises(
|
|
116
|
+
msg,
|
|
117
|
+
{
|
|
118
|
+
cls.CONTEXT_KEY_HTML: html,
|
|
119
|
+
cls.CONTEXT_KEY_RE_PATTERN: pattern,
|
|
120
|
+
},
|
|
121
|
+
RegularNotMatchException,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def raises_resp(cls,
|
|
126
|
+
msg: str,
|
|
127
|
+
resp,
|
|
128
|
+
etype=ResponseUnexpectedException
|
|
129
|
+
):
|
|
130
|
+
cls.raises(
|
|
131
|
+
msg, {
|
|
132
|
+
cls.CONTEXT_KEY_RESP: resp
|
|
133
|
+
},
|
|
134
|
+
etype,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
@classmethod
|
|
138
|
+
def raise_missing(cls,
|
|
139
|
+
resp,
|
|
140
|
+
jmid: str,
|
|
141
|
+
):
|
|
142
|
+
"""
|
|
143
|
+
抛出本子/章节的异常
|
|
144
|
+
:param resp: 响应对象
|
|
145
|
+
:param jmid: 禁漫本子/章节id
|
|
146
|
+
"""
|
|
147
|
+
from .jm_toolkit import JmcomicText
|
|
148
|
+
url = JmcomicText.format_album_url(jmid)
|
|
149
|
+
|
|
150
|
+
req_type = "本子" if "album" in url else "章节"
|
|
151
|
+
cls.raises(
|
|
152
|
+
(
|
|
153
|
+
f'请求的{req_type}不存在!({url})\n'
|
|
154
|
+
'原因可能为:\n'
|
|
155
|
+
f'1. id有误,检查你的{req_type}id\n'
|
|
156
|
+
'2. 该漫画只对登录用户可见,请配置你的cookies,或者使用移动端Client(api)\n'
|
|
157
|
+
),
|
|
158
|
+
{
|
|
159
|
+
cls.CONTEXT_KEY_RESP: resp,
|
|
160
|
+
cls.CONTEXT_KEY_MISSING_JM_ID: jmid,
|
|
161
|
+
},
|
|
162
|
+
MissingAlbumPhotoException,
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
@classmethod
|
|
166
|
+
def require_true(cls, case: bool, msg: str):
|
|
167
|
+
if case:
|
|
168
|
+
return
|
|
169
|
+
|
|
170
|
+
cls.raises(msg)
|
|
171
|
+
|
|
172
|
+
@classmethod
|
|
173
|
+
def replace_old_exception_executor(cls, raises: Callable[[Callable, str, dict], None]):
|
|
174
|
+
old = cls.raises
|
|
175
|
+
|
|
176
|
+
def new(msg, context=None, _etype=None):
|
|
177
|
+
if context is None:
|
|
178
|
+
context = {}
|
|
179
|
+
raises(old, msg, context)
|
|
180
|
+
|
|
181
|
+
cls.raises = new
|
|
182
|
+
|
|
183
|
+
@classmethod
|
|
184
|
+
def notify_all_listeners(cls, e):
|
|
185
|
+
registry: Dict[Type, Callable[Type]] = JmModuleConfig.REGISTRY_EXCEPTION_LISTENER
|
|
186
|
+
if not registry:
|
|
187
|
+
return None
|
|
188
|
+
|
|
189
|
+
for accept_type, listener in registry.items():
|
|
190
|
+
if isinstance(e, accept_type):
|
|
191
|
+
listener(e)
|