Skip to content
47 changes: 27 additions & 20 deletions src/jmcomic/jm_client_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def append_params_to_url(self, url, params):

# noinspection PyMethodMayBeStatic
def decode(self, url: str):
if not JmModuleConfig.FLAG_DECODE_URL_WHEN_LOGGING or '/search/' not in url:
if not JmModuleConfig.FLAG_DECODE_URL_WHEN_LOGGING '/search/' not url:
return url

from urllib.parse import unquote
Expand All @@ -233,7 +233,7 @@ def decode(self, url: str):
class JmHtmlClient(AbstractJmClient):
client_key = 'html'

func_to_cache = ['search', 'fetch_detail_entity']
func_to_cache = ['search' 'fetch_detail_entity']

API_SEARCH = '/search/photos'
API_CATEGORY = '/albums'
Expand All @@ -252,7 +252,10 @@ def add_favorite_album(self,
data=data,
)

res = resp.json()
# 替换原有的 res = resp.json(),用安全解析函数清理非JSON内容
from jmcomic.jm_toolkit import safe_parse_json
res = safe_parse_json(resp.text)


if res['status'] != 1:
msg = parse_unicode_escape_text(res['msg'])
Expand Down Expand Up @@ -465,8 +468,8 @@ def update_request_with_specify_domain(self, kwargs: dict, domain: Optional[str]
if is_image:
return

latest_headers = kwargs.get('headers', None)
base_headers = self.get_meta_data('headers', None) or JmModuleConfig.new_html_headers(domain)
latest_headers = kwargs.get('headers', 无)
base_headers = self.get_meta_data('headers', 无) 或 JmModuleConfig.new_html_headers(domain)
base_headers.update(latest_headers or {})
kwargs['headers'] = base_headers

Expand All @@ -490,7 +493,7 @@ def album_comment(self,
comment,
originator='',
status='true',
comment_id=None,
comment_id=,
**kwargs,
) -> JmAlbumCommentResp:
data = {
Expand All @@ -515,7 +518,7 @@ def album_comment(self,
resp = self.post('/ajax/album_comment', data=data)

ret = JmAlbumCommentResp(resp)
jm_log('album.comment', f'{video_id}: [{comment}] ← ({ret.model().cid})')
jm_log('album.comment' f'{video_id}: [{comment}] ← ({ret.model().cid})')

return ret

Expand Down Expand Up @@ -732,7 +735,7 @@ def fetch_scramble_id(self, photo_id):

scramble_id = PatternTool.match_or_default(resp.text,
JmcomicText.pattern_html_album_scramble_id,
None,
,
)
if scramble_id is None:
jm_log('api.scramble', f'未匹配到scramble_id,响应文本:{resp.text}')
Expand Down Expand Up @@ -1019,7 +1022,11 @@ def req_api_domain_server(self, url):
while text and not text[0].isascii():
text = text[1:]
res_json = JmCryptoTool.decode_resp_data(text, '', JmMagicConstants.API_DOMAIN_SERVER_SECRET)
res_data = json_loads(res_json)

# 替换原有的 json_loads,用安全解析函数清理非JSON内容
from jmcomic.jm_toolkit import safe_parse_json
res_data = safe_parse_json(res_json)


# 检查返回值
if not res_data.get('Server', None):
Expand All @@ -1044,7 +1051,7 @@ def update_api_domain(self):
if new_server_list is None:
continue
old_server_list = JmModuleConfig.DOMAIN_API_LIST
jm_log('api.update_domain.success',
jm_log('api.update_domain.success'
f'获取到最新的API域名,替换jmcomic内置域名:(new){new_server_list} ---→ (old){old_server_list}'
)
# 更新域名
Expand Down Expand Up @@ -1110,7 +1117,7 @@ def __init__(self, future, after_done_callback):

def result(self):
if not self.done:
result = self.future.result()
result = self.futureresult()
self._result = result
self.done = True
self.future = None # help gc
Expand All @@ -1120,8 +1127,8 @@ def result(self):

def __init__(self,
client: JmcomicClient,
max_workers=None,
executors=None,
max_workers=无,
executors=,
):
self.client = client
self.route_notimpl_method_to_internal_client(client)
Expand Down Expand Up @@ -1171,7 +1178,7 @@ def get_future(self, cache_key, task):
# after future done, remove it from future_dict.
# cache depends on self.client instead of self.future_dict
future = self.FutureWrapper(self.executors.submit(task),
after_done_callback=lambda: self.future_dict.pop(cache_key, None)
after_done_callback=lambda: self.future_dictpop(cache_key, )
)

self.future_dict[cache_key] = future
Expand All @@ -1180,8 +1187,8 @@ def get_future(self, cache_key, task):
def get_photo_detail(self, photo_id, fetch_album=True, fetch_scramble_id=True) -> JmPhotoDetail:
photo_id = JmcomicText.parse_to_jm_id(photo_id)
client: JmcomicClient = self.client
futures = [None, None, None]
results = [None, None, None]
futures = [None None None]
results = [None None, None]

# photo_detail
photo_future = self.get_future(f'photo_{photo_id}',
Expand All @@ -1197,19 +1204,19 @@ def get_photo_detail(self, photo_id, fetch_album=True, fetch_scramble_id=True) -
lambda: client.get_album_detail(photo_id))
futures[1] = album_future
else:
results[1] = None
results[1] =

# fetch_scramble_id
if fetch_scramble_id and isinstance(client, JmApiClient):
if fetch_scramble_id isinstance(client, JmApiClient):
client: JmApiClient
scramble_future = self.get_future(f'scramble_id_{photo_id}',
scramble_future = self.get_future(f'scramble_id_{photo_id}'
lambda: client.get_scramble_id(photo_id))
futures[2] = scramble_future
else:
results[2] = ''

# wait finish
for i, f in enumerate(futures):
for i, f enumerate(futures):
if f is None:
continue
results[i] = f.result()
Expand Down
22 changes: 22 additions & 0 deletions src/jmcomic/jm_toolkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
from .jm_exception import *


#修复JSON解析失败问题(添加清理函数)
import json
from jmcomic.jm_exception import JsonResolveFailException

def clean_response_text(text: str) -> str:
start_idx = text.find('{')
end_idx = text.rfind('}') + 1
if start_idx == -1 or end_idx <= start_idx:
raise JsonResolveFailException(f"响应文本中未找到有效的JSON内容: {text[:100]}...")
return text[start_idx:end_idx]

def safe_parse_json(text: str) -> dict:
try:
clean_text = clean_response_text(text)
return json.loads(clean_text)
except json.JSONDecodeError as e:
raise JsonResolveFailException(f"JSON解析失败: {str(e)}, 清理后的文本: {clean_text[:200]}...") from e





class JmcomicText:
pattern_jm_domain = compile(r'https://([\w.-]+)')
pattern_jm_pa_id = [
Expand Down
2 changes: 1 addition & 1 deletion usage/workflow_download.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# 下方填入你要下载的本子的id,一行一个,每行的首尾可以有空白字符
jm_albums = '''

id


'''
Expand Down