Skip to content

Commit 89deeda

Browse files
authored
v2.3.0: 初步实现移动端API(JmApiClient),优化正则表达式并适配大陆直连域名,增加测试,优化工作流 (#137)
1 parent c5810d9 commit 89deeda

16 files changed

+347
-88
lines changed

.github/workflows/release_auto.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Release (auto)
2+
3+
4+
on:
5+
workflow_dispatch:
6+
7+
jobs:
8+
release:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- uses: actions/checkout@v3
13+
14+
- name: Set up Python 3.11
15+
uses: actions/setup-python@v4
16+
with:
17+
python-version: "3.11"
18+
19+
- name: Parse Tag & Body
20+
id: tb
21+
run: |
22+
commit_message=$(git log --format=%B -n 1 ${{ github.sha }})
23+
python release.py "$commit_message"
24+
25+
- name: Create Release
26+
uses: softprops/action-gh-release@v1
27+
env:
28+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
29+
with:
30+
tag_name: ${{ steps.tb.outputs.tag }}
31+
body: ${{ steps.tb.outputs.body }}
32+
33+
- name: Build Module
34+
run: |
35+
python -m pip install build
36+
python -m build
37+
38+
- name: Release PYPI
39+
uses: pypa/gh-action-pypi-publish@release/v1
40+
with:
41+
password: ${{ secrets.PYPI_JMCOMIC }}

TODO.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# 大版本更新内容计划
2+
3+
| 版本范围 | 更新内容 |
4+
|:--------:|:--------------------------------------:|
5+
| v2.3.* | 实现移动端API的基础功能,统一HTML和API的实现 |
6+
| v2.2.* | 新的插件体系,新的命令行调用,完善搜索功能。 |
7+
| v2.1.* | 拆分Downloader抽象调度,优化可扩展性、代码复用性、模块级别自定义。 |
8+
| v2.0.* | 重新设计合理的抽象层次,实现请求重试切换域名机制,新的option配置设计。 |
9+
| v1.\*.\* | 基于HTML实现基础功能。 |

release.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import os
2+
import sys
3+
import re
4+
5+
6+
def add_output(k, v):
7+
print(f'set {k} = {v}')
8+
print(os.system(f'echo {k}={v} >> $GITHUB_OUTPUT'))
9+
10+
11+
msg = sys.argv[1]
12+
print(f'msg: {msg}')
13+
p = re.compile('(.*?): ?(.*)')
14+
match = p.search(msg)
15+
assert match is not None, f'commit message format is wrong: {msg}'
16+
17+
tag, body = match[1], match[2]
18+
19+
add_output('tag', tag)
20+
add_output('body', body)

src/jmcomic/__init__.py

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

5-
__version__ = '2.2.11'
5+
__version__ = '2.3.0'
66

77
from .api import *
88
from .jm_plugin import *

src/jmcomic/cl.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ def parse_arg(self):
4242
parser.add_argument(
4343
'--option',
4444
help='path to the option file, you can also specify it by env `JM_OPTION_PATH`',
45-
default=get_env('JM_OPTION_PATH', None),
45+
default=get_env('JM_OPTION_PATH', ''),
4646
)
4747

4848
args = parser.parse_args()
49-
if args.option is not None:
49+
if len(args.option) != 0:
5050
self.option_path = os.path.abspath(args.option)
5151
else:
5252
self.option_path = None
@@ -88,7 +88,7 @@ def main(self):
8888
option = create_option(self.option_path)
8989
else:
9090
option = JmOption.default()
91-
91+
9292
self.run(option)
9393

9494
def run(self, option):

src/jmcomic/jm_client_impl.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,16 @@ def check_special_http_code(cls, resp):
398398
class JmApiClient(AbstractJmClient):
399399
client_key = 'api'
400400
API_SEARCH = '/search'
401+
API_ALBUM = '/album'
402+
API_CHAPTER = '/chapter'
403+
404+
def __init__(self,
405+
postman: Postman,
406+
retry_times: int,
407+
domain=None,
408+
fallback_domain_list=None,
409+
):
410+
super().__init__(postman, retry_times, domain, fallback_domain_list)
401411

402412
def search(self,
403413
search_query: str,
@@ -431,6 +441,30 @@ def search(self,
431441

432442
return JmcomicSearchTool.parse_api_resp_to_page(data)
433443

444+
def get_album_detail(self, album_id) -> JmAlbumDetail:
445+
return self.fetch_detail_entity(album_id,
446+
JmModuleConfig.album_class(),
447+
)
448+
449+
def get_photo_detail(self, photo_id, fetch_album=True) -> JmPhotoDetail:
450+
return self.fetch_detail_entity(photo_id,
451+
JmModuleConfig.photo_class(),
452+
)
453+
454+
def fetch_detail_entity(self, apid, clazz, **kwargs):
455+
url = self.API_ALBUM if issubclass(clazz, JmAlbumDetail) else self.API_CHAPTER
456+
resp = self.get(
457+
url,
458+
params={
459+
'id': JmcomicText.parse_to_album_id(apid),
460+
**kwargs,
461+
}
462+
)
463+
464+
self.require_resp_success(resp)
465+
466+
return JmApiAdaptTool.parse_entity(resp.res_data, clazz)
467+
434468
def get(self, url, **kwargs) -> JmApiResp:
435469
# set headers
436470
headers, key_ts = self.headers_key_ts
@@ -454,6 +488,10 @@ def headers_key_ts(self):
454488
def debug_topic_request(self):
455489
return 'api'
456490

491+
# noinspection PyMethodMayBeStatic
492+
def require_resp_success(self, resp: JmApiResp):
493+
resp.require_success()
494+
457495

458496
JmModuleConfig.register_client(JmHtmlClient)
459497
JmModuleConfig.register_client(JmApiClient)

src/jmcomic/jm_client_interface.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ def __init__(self, resp, key_ts):
8181
self.key_ts = key_ts
8282
self.cache_decode_data = None
8383

84+
@property
85+
def is_success(self) -> bool:
86+
return super().is_success and self.json()['code'] == 200
87+
8488
@staticmethod
8589
def parse_data(text, time) -> str:
8690
# 1. base64解码
@@ -102,11 +106,9 @@ def parse_data(text, time) -> str:
102106
return res
103107

104108
@property
109+
@field_cache('__cache_decoded_data__')
105110
def decoded_data(self) -> str:
106-
if self.cache_decode_data is None:
107-
self.cache_decode_data = self.parse_data(self.encoded_data, self.key_ts)
108-
109-
return self.cache_decode_data
111+
return self.parse_data(self.encoded_data, self.key_ts)
110112

111113
@property
112114
def encoded_data(self) -> str:
@@ -118,6 +120,7 @@ def res_data(self) -> Any:
118120
from json import loads
119121
return loads(self.decoded_data)
120122

123+
@field_cache('__cache_json__')
121124
def json(self, **kwargs) -> Dict:
122125
return self.resp.json()
123126

@@ -136,9 +139,6 @@ def is_success(self) -> bool:
136139
def json(self, **kwargs) -> Dict:
137140
return self.resp.json()
138141

139-
def model(self) -> DictModel:
140-
return DictModel(self.json())
141-
142142

143143
"""
144144

src/jmcomic/jm_config.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class JmModuleConfig:
6868
CLASS_CLIENT_IMPL = {}
6969
CLASS_EXCEPTION = None
7070

71+
# 插件注册表
72+
PLUGIN_REGISTRY = {}
73+
7174
# 执行debug的函数
7275
debug_executor = default_jm_debug
7376
# postman构造函数
@@ -80,9 +83,6 @@ class JmModuleConfig:
8083
# debug时解码url
8184
decode_url_when_debug = True
8285

83-
# 插件注册表
84-
plugin_registry = {}
85-
8686
@classmethod
8787
def downloader_class(cls):
8888
if cls.CLASS_DOWNLOADER is not None:
@@ -243,7 +243,7 @@ def new_postman(cls, session=False, **kwargs):
243243
default_option_dict: dict = {
244244
'version': '2.0',
245245
'debug': None,
246-
'dir_rule': {'rule': 'Bd_Ptitle', 'base_dir': None},
246+
'dir_rule': {'rule': 'Bd_Pname', 'base_dir': None},
247247
'download': {
248248
'cache': True,
249249
'image': {'decode': True, 'suffix': None},
@@ -299,7 +299,7 @@ def option_default_dict(cls) -> dict:
299299

300300
@classmethod
301301
def register_plugin(cls, plugin_class):
302-
cls.plugin_registry[plugin_class.plugin_key] = plugin_class
302+
cls.PLUGIN_REGISTRY[plugin_class.plugin_key] = plugin_class
303303

304304
@classmethod
305305
def register_client(cls, client_class):

src/jmcomic/jm_downloader.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ def before_album(self, album: JmAlbumDetail):
2222
f'作者: [{album.author}], '
2323
f'章节数: [{len(album)}], '
2424
f'总页数: [{album.page_count}], '
25-
f'标题: [{album.title}], '
26-
f'关键词: [{album.tag_list}]'
25+
f'标题: [{album.name}], '
26+
f'关键词: [{album.tags}]'
2727
)
2828

2929
def after_album(self, album: JmAlbumDetail):
@@ -32,7 +32,7 @@ def after_album(self, album: JmAlbumDetail):
3232
def before_photo(self, photo: JmPhotoDetail):
3333
jm_debug('photo.before',
3434
f'开始下载章节: {photo.id} ({photo.album_id}[{photo.index}/{len(photo.from_album)}]), '
35-
f'标题: [{photo.title}], '
35+
f'标题: [{photo.name}], '
3636
f'图片数为[{len(photo)}]'
3737
)
3838

0 commit comments

Comments
 (0)