Skip to content

Commit 9e3fa7f

Browse files
authored
v2.3.16: 修复zip插件在album模式下的一些bug; 调整获取APP_COOKIES的位置; 一些代码优化。 (#160)
1 parent 87ed6bc commit 9e3fa7f

File tree

8 files changed

+97
-67
lines changed

8 files changed

+97
-67
lines changed

.github/release.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def parse_body(body):
1818
e: str = e.strip()
1919
if e == '':
2020
continue
21-
points.append(f'{i}. {e}')
21+
points.append(f'{i + 1}. {e}')
2222

2323
return '\n'.join(points)
2424

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.3.15'
5+
__version__ = '2.3.16'
66

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

src/jmcomic/jm_client_impl.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -493,13 +493,13 @@ def fetch_scramble_id(self, photo_id):
493493
}
494494
)
495495

496-
match = JmcomicText.pattern_html_album_scramble_id.search(resp.text)
497-
498-
if match is not None:
499-
scramble_id = match[1]
500-
else:
501-
jm_debug('api.scramble', '未从响应中匹配到scramble_id,返回默认值220980')
502-
scramble_id = '220980'
496+
scramble_id = PatternTool.match_or_default(resp.text,
497+
JmcomicText.pattern_html_album_scramble_id,
498+
None,
499+
)
500+
if scramble_id is None:
501+
jm_debug('api.scramble', f'未匹配到scramble_id,响应文本:{resp.text}')
502+
scramble_id = str(JmModuleConfig.SCRAMBLE_220980)
503503

504504
return scramble_id
505505

@@ -610,15 +610,12 @@ def require_resp_success(cls, resp: JmApiResp, orig_req_url: str):
610610
# 2. 是否是特殊的内容
611611
# 暂无
612612

613-
@classmethod
614-
@field_cache('__init_cookies__')
615-
def fetch_init_cookies(cls, client: 'JmApiClient'):
616-
resp = client.setting()
617-
return dict(resp.resp.cookies)
618-
619613
def after_init(self):
620-
cookies = self.__class__.fetch_init_cookies(self)
621-
self.get_root_postman().get_meta_data()['cookies'] = cookies
614+
# cookies = self.__class__.fetch_init_cookies(self)
615+
# self.get_root_postman().get_meta_data()['cookies'] = cookies
616+
617+
self.get_root_postman().get_meta_data()['cookies'] = JmModuleConfig.get_cookies(self)
618+
pass
622619

623620

624621
class FutureClientProxy(JmcomicClient):

src/jmcomic/jm_config.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ def field_cache(*args, **kwargs):
33
return field_cache(*args, **kwargs)
44

55

6-
def default_jm_debug(topic: str, msg: str):
6+
def default_jm_debug_logging(topic: str, msg: str):
77
from common import format_ts
88
print(f'{format_ts()}:【{topic}{msg}')
99

@@ -62,13 +62,14 @@ class JmModuleConfig:
6262
SCRAMBLE_421926 = 421926 # 2023-02-08后改了图片切割算法
6363
SCRAMBLE_CACHE = {}
6464

65-
# 移动端API的相关配置
66-
# API密钥
67-
APP_SECRET = '18comicAPP'
65+
# 移动端API密钥
66+
APP_SECRET = '18comicAPPContent'
6867

69-
# 域名配置 - 移动端
70-
# 图片域名
71-
DOMAIN_API_IMAGE_LIST = str_to_list('''
68+
# cookies,目前只在移动端使用,因为移动端请求接口须携带,但不会校验cookies的内容。
69+
APP_COOKIES = None
70+
71+
# 移动端图片域名
72+
DOMAIN_IMAGE_LIST = str_to_list('''
7273
cdn-msp.jmapiproxy1.monster
7374
cdn-msp2.jmapiproxy1.monster
7475
cdn-msp.jmapiproxy1.cc
@@ -78,7 +79,7 @@ class JmModuleConfig:
7879
7980
''')
8081

81-
# API域名
82+
# 移动端API域名
8283
DOMAIN_API_LIST = str_to_list('''
8384
www.jmapinode1.top
8485
www.jmapinode2.top
@@ -88,8 +89,11 @@ class JmModuleConfig:
8889
8990
''')
9091

91-
# 域名配置 - 网页端
92+
# 网页端域名配置
9293
# 无需配置,默认为None,需要的时候会发起请求获得
94+
# 使用优先级:
95+
# 1. DOMAIN_HTML_LIST
96+
# 2. [DOMAIN_HTML]
9397
DOMAIN_HTML = None
9498
DOMAIN_HTML_LIST = None
9599

@@ -106,7 +110,7 @@ class JmModuleConfig:
106110
REGISTRY_PLUGIN = {}
107111

108112
# 执行debug的函数
109-
debug_executor = default_jm_debug
113+
debug_executor = default_jm_debug_logging
110114
# postman构造函数
111115
postman_constructor = default_postman_constructor
112116
# 网页正则表达式解析失败时,执行抛出异常的函数,可以替换掉用于debug
@@ -190,7 +194,7 @@ def get_html_url(cls, postman=None):
190194
postman = postman or cls.new_postman(session=True)
191195

192196
url = postman.with_redirect_catching().get(cls.JM_REDIRECT_URL)
193-
cls.jm_debug('获取禁漫网页URL', f'[{cls.JM_REDIRECT_URL}] → [{url}]')
197+
cls.jm_debug('module.html_url', f'获取禁漫网页URL: [{cls.JM_REDIRECT_URL}] → [{url}]')
194198
return url
195199

196200
@classmethod
@@ -211,9 +215,22 @@ def get_html_domain_all(cls, postman=None):
211215
from .jm_toolkit import JmcomicText
212216
domain_list = JmcomicText.analyse_jm_pub_html(resp.text)
213217

214-
cls.jm_debug('获取禁漫网页全部域名', f'[{resp.url}] → {domain_list}')
218+
cls.jm_debug('module.html_domain_all', f'获取禁漫网页全部域名: [{resp.url}] → {domain_list}')
215219
return domain_list
216220

221+
@classmethod
222+
@field_cache("APP_COOKIES")
223+
def get_cookies(cls, postman=None):
224+
from .jm_toolkit import JmcomicText
225+
url = JmcomicText.format_url('/setting', cls.DOMAIN_API_LIST[0])
226+
postman = postman or cls.new_postman()
227+
228+
resp = postman.get(url)
229+
cookies = dict(resp.cookies)
230+
231+
cls.jm_debug('module.cookies', f'获取cookies: [{url}] → {cookies}')
232+
return cookies
233+
217234
@classmethod
218235
def new_html_headers(cls, domain='18comic.vip'):
219236
"""
@@ -247,7 +264,7 @@ def new_api_headers(cls, key_ts):
247264
key_ts = time_stamp()
248265

249266
import hashlib
250-
token = hashlib.md5(f"{key_ts}{cls.APP_SECRET}".encode()).hexdigest()
267+
token = hashlib.md5(f"{key_ts}{cls.APP_SECRET}".encode("utf-8")).hexdigest()
251268

252269
return {
253270
'token': token,

src/jmcomic/jm_option.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ def build_jm_client(self, **kwargs):
314314
def new_jm_client(self, domain=None, impl=None, cache=None, **kwargs) -> JmcomicClient:
315315
# 所有需要用到的 self.client 配置项如下
316316
postman_conf: dict = self.client.postman.src_dict # postman dsl 配置
317+
meta_data: dict = postman_conf['meta_data'] # 请求元信息
317318
impl: str = impl or self.client.impl # client_key
318319
retry_times: int = self.client.retry_times # 重试次数
319320
cache: str = cache or self.client.cache # 启用缓存
@@ -335,15 +336,11 @@ def decide_domain():
335336

336337
# support kwargs overwrite meta_data
337338
if len(kwargs) != 0:
338-
postman_conf['meta_data'].update(kwargs)
339+
meta_data.update(kwargs)
339340

340341
# headers
341-
meta_data = postman_conf['meta_data']
342342
if meta_data['headers'] is None:
343-
headers = self.decide_postman_headers(impl, domain[0])
344-
# if headers is None:
345-
# postman_conf['type'] = 'requests'
346-
meta_data['headers'] = headers
343+
meta_data['headers'] = self.decide_postman_headers(impl, domain[0])
347344

348345
# postman
349346
postman = Postmans.create(data=postman_conf)
@@ -375,6 +372,9 @@ def decide_client_domain(self, client_key: str) -> List[str]:
375372

376373
if is_client_type(JmHtmlClient):
377374
# 网页端
375+
domain_list = JmModuleConfig.DOMAIN_HTML_LIST
376+
if domain_list is not None:
377+
return domain_list
378378
return [JmModuleConfig.get_html_domain()]
379379

380380
ExceptionTool.raises(f'没有配置域名,且是无法识别的client类型: {client_key}')

src/jmcomic/jm_plugin.py

Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -249,26 +249,32 @@ def invoke(self,
249249
mkdir_if_not_exists(zip_dir)
250250

251251
# 原文件夹 -> zip文件
252-
dir_zip_dict = {}
252+
dir_zip_dict: Dict[str, Optional[str]] = {}
253253
photo_dict = downloader.all_downloaded[album]
254254

255255
if level == 'album':
256256
zip_path = self.get_zip_path(album, None, filename_rule, suffix, zip_dir)
257257
dir_path = self.zip_album(album, photo_dict, zip_path)
258-
dir_zip_dict[dir_path] = zip_path
258+
if dir_path is not None:
259+
# 要删除这个album文件夹
260+
dir_zip_dict[dir_path] = zip_path
261+
# 也要删除album下的photo文件夹
262+
for d in files_of_dir(dir_path):
263+
dir_zip_dict[d] = None
259264

260265
elif level == 'photo':
261266
for photo, image_list in photo_dict.items():
262267
zip_path = self.get_zip_path(None, photo, filename_rule, suffix, zip_dir)
263268
dir_path = self.zip_photo(photo, image_list, zip_path)
264-
dir_zip_dict[dir_path] = zip_path
269+
if dir_path is not None:
270+
dir_zip_dict[dir_path] = zip_path
265271

266272
else:
267273
ExceptionTool.raises(f'Not Implemented Zip Level: {level}')
268274

269275
self.after_zip(dir_zip_dict)
270276

271-
def zip_photo(self, photo, image_list: list, zip_path: str):
277+
def zip_photo(self, photo, image_list: list, zip_path: str) -> Optional[str]:
272278
"""
273279
压缩photo文件夹
274280
:returns: photo文件夹路径
@@ -277,46 +283,54 @@ def zip_photo(self, photo, image_list: list, zip_path: str):
277283
if len(image_list) == 0 \
278284
else os.path.dirname(image_list[0][0])
279285

280-
all_filepath = set(map(lambda t: t[0], image_list))
286+
all_filepath = set(map(lambda t: self.unified_path(t[0]), image_list))
281287

282-
if len(all_filepath) == 0:
283-
self.debug('无下载文件,无需压缩', 'skip')
284-
return
285-
286-
from common import backup_dir_to_zip
287-
backup_dir_to_zip(photo_dir, zip_path, acceptor=lambda f: f in all_filepath)
288-
self.debug(f'压缩章节[{photo.photo_id}]成功 → {zip_path}', 'finish')
288+
return self.do_zip(photo_dir,
289+
zip_path,
290+
all_filepath,
291+
f'压缩章节[{photo.photo_id}]成功 → {zip_path}',
292+
)
289293

290-
return photo_dir
294+
@staticmethod
295+
def unified_path(f):
296+
return fix_filepath(f, os.path.isdir(f))
291297

292-
def zip_album(self, album, photo_dict: dict, zip_path):
298+
def zip_album(self, album, photo_dict: dict, zip_path) -> Optional[str]:
293299
"""
294300
压缩album文件夹
295301
:returns: album文件夹路径
296302
"""
297-
album_dir = self.option.decide_album_dir(album)
298303
all_filepath: Set[str] = set()
299304

300-
for image_list in photo_dict.values():
301-
image_list: List[Tuple[str, JmImageDetail]]
302-
for path, _ in image_list:
303-
all_filepath.add(path)
305+
def addpath(f):
306+
all_filepath.update(set(f))
307+
308+
album_dir = self.option.decide_album_dir(album)
309+
# addpath(self.option.decide_image_save_dir(photo) for photo in photo_dict.keys())
310+
addpath(path for ls in photo_dict.values() for path, _ in ls)
311+
312+
return self.do_zip(album_dir,
313+
zip_path,
314+
all_filepath,
315+
msg=f'压缩本子[{album.album_id}]成功 → {zip_path}',
316+
)
304317

318+
def do_zip(self, source_dir, zip_path, all_filepath, msg):
305319
if len(all_filepath) == 0:
306320
self.debug('无下载文件,无需压缩', 'skip')
307-
return
321+
return None
308322

309323
from common import backup_dir_to_zip
310324
backup_dir_to_zip(
311-
album_dir,
325+
source_dir,
312326
zip_path,
313-
acceptor=lambda f: f in all_filepath
314-
)
327+
acceptor=lambda f: os.path.isdir(f) or self.unified_path(f) in all_filepath
328+
).close()
315329

316-
self.debug(f'压缩本子[{album.album_id}]成功 → {zip_path}', 'finish')
317-
return album_dir
330+
self.debug(msg, 'finish')
331+
return self.unified_path(source_dir)
318332

319-
def after_zip(self, dir_zip_dict: Dict[str, str]):
333+
def after_zip(self, dir_zip_dict: Dict[str, Optional[str]]):
320334
# 是否要删除所有原文件
321335
if self.delete_original_file is True:
322336
self.delete_all_files_and_empty_dir(
@@ -352,10 +366,10 @@ def delete_all_files_and_empty_dir(self, all_downloaded: dict, dir_list: List[st
352366
os.remove(f)
353367
self.debug(f'删除原文件: {f}', 'remove')
354368

355-
for d in dir_list:
369+
for d in sorted(dir_list, reverse=True):
356370
# check exist
357-
if file_exists(d) and len(os.listdir(d)) == 0:
358-
os.removedirs(d)
371+
if file_exists(d):
372+
os.rmdir(d)
359373
self.debug(f'删除文件夹: {d}', 'remove')
360374

361375

src/jmcomic/jm_toolkit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ def post_adapt_photo(cls, data: dict, _clazz: type, fields: dict):
489489

490490
fields['sort'] = sort
491491
import random
492-
fields['data_original_domain'] = random.choice(JmModuleConfig.DOMAIN_API_IMAGE_LIST)
492+
fields['data_original_domain'] = random.choice(JmModuleConfig.DOMAIN_IMAGE_LIST)
493493

494494

495495
class JmImageTool:

tests/test_jmcomic/test_jm_custom.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,10 @@ class MyClient(JmHtmlClient):
5555
JmModuleConfig.register_client(MyClient)
5656

5757
html_domain = self.client.get_html_domain()
58+
JmModuleConfig.DOMAIN_HTML_LIST = [html_domain]
59+
5860
self.assertListEqual(
59-
[html_domain],
61+
JmModuleConfig.DOMAIN_HTML_LIST,
6062
self.option.new_jm_client(domain=[], impl=MyClient.client_key).get_domain_list()
6163
)
6264

0 commit comments

Comments
 (0)