mirror of
https://github.com/hect0x7/JMComic-Crawler-Python.git
synced 2025-11-04 14:49:43 +08:00
v1.2.0: 给JmPhotoDetail增加属性 章节序号(从1开始)、并增加相应测试、优化代码。 (#9)
This commit is contained in:
parent
b38ee83c27
commit
d8349d863d
@ -2,6 +2,6 @@
|
||||
# 被依赖方 <--- 使用方
|
||||
# config <--- entity <--- toolkit <--- client <--- service <--- option
|
||||
|
||||
__version__ = '1.1.0'
|
||||
__version__ = '1.2.0'
|
||||
|
||||
from .api import *
|
||||
|
||||
@ -98,7 +98,7 @@ def download_by_photo_detail(photo_detail: JmPhotoDetail,
|
||||
jm_client.update(photo_detail)
|
||||
|
||||
# 下载每个图片的函数
|
||||
def download_image(index,img_detail, debug_topic='download_images_of_photo'):
|
||||
def download_image(index, img_detail, debug_topic='download_images_of_photo'):
|
||||
img_save_path = option.decide_image_filepath(photo_detail, index)
|
||||
|
||||
# 已下载过,缓存命中
|
||||
|
||||
@ -38,7 +38,7 @@ class WorkEntity(JmBaseEntity, SaveableEntity, IterableEntity):
|
||||
def __len__(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def __getitem__(self, item):
|
||||
def __getitem__(self, item) -> Union['JmAlbumDetail', 'JmPhotoDetail']:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@ -99,6 +99,7 @@ class JmPhotoDetail(WorkEntity):
|
||||
title,
|
||||
keywords,
|
||||
series_id,
|
||||
sort,
|
||||
page_arr=None,
|
||||
data_original_domain=None,
|
||||
author=None,
|
||||
@ -107,6 +108,7 @@ class JmPhotoDetail(WorkEntity):
|
||||
self.photo_id: str = photo_id
|
||||
self.scramble_id: str = scramble_id
|
||||
self.title: str = title
|
||||
self.sort: int = int(sort)
|
||||
self._keywords: str = keywords
|
||||
self._series_id: int = int(series_id)
|
||||
|
||||
@ -120,8 +122,10 @@ class JmPhotoDetail(WorkEntity):
|
||||
|
||||
# 该photo的所有图片名 img_name
|
||||
self.page_arr: List[str] = page_arr
|
||||
self.data_original_domain = data_original_domain
|
||||
# 图片域名
|
||||
self.data_original_domain: StrNone = data_original_domain
|
||||
|
||||
@property
|
||||
def is_single_album(self) -> bool:
|
||||
return self._series_id == 0
|
||||
|
||||
@ -131,7 +135,20 @@ class JmPhotoDetail(WorkEntity):
|
||||
|
||||
@property
|
||||
def album_id(self) -> str:
|
||||
return self.photo_id if self.is_single_album() else self._series_id
|
||||
return self.photo_id if self.is_single_album else self._series_id
|
||||
|
||||
@property
|
||||
def album_index(self) -> int:
|
||||
"""
|
||||
返回这个章节在本子中的序号,从1开始
|
||||
"""
|
||||
|
||||
# 如果是单章本子,JM给的sort为2。
|
||||
# 这里返回1比较符合语义定义
|
||||
if self.is_single_album and self.sort == 2:
|
||||
return 1
|
||||
|
||||
return self.sort
|
||||
|
||||
@property
|
||||
def author(self) -> str:
|
||||
@ -167,7 +184,11 @@ class JmPhotoDetail(WorkEntity):
|
||||
例如:img_name = 01111.webp
|
||||
返回:https://cdn-msp2.18comic.org/media/photos/147643/01111.webp
|
||||
"""
|
||||
return f'https://{self.data_original_domain}/media/photos/{self.photo_id}/{img_name}'
|
||||
data_original_domain = self.data_original_domain
|
||||
if data_original_domain is None:
|
||||
raise AssertionError(f'图片域名为空: {self.__dict__}')
|
||||
|
||||
return f'https://{data_original_domain}/media/photos/{self.photo_id}/{img_name}'
|
||||
|
||||
def __getitem__(self, item) -> JmImageDetail:
|
||||
return self.create_image_detail(item)
|
||||
@ -224,6 +245,7 @@ class JmAlbumDetail(WorkEntity):
|
||||
title=photo_title,
|
||||
keywords='',
|
||||
series_id=self.album_id,
|
||||
sort=index + 1,
|
||||
author=self.author,
|
||||
from_album=self,
|
||||
page_arr=None,
|
||||
|
||||
@ -82,7 +82,10 @@ class DownloadDirTree:
|
||||
# 根目录 / Photo号 / 图片文件
|
||||
Bd_Id_Image = 5
|
||||
|
||||
AdditionalHandler = Callable[[Optional[JmAlbumDetail], JmPhotoDetail], str]
|
||||
AdditionalHandler = Callable[
|
||||
['DownloadDirTree', Optional[JmAlbumDetail], JmPhotoDetail],
|
||||
str
|
||||
]
|
||||
additional_tree_flag_handler_mapping: Dict[int, AdditionalHandler] = {}
|
||||
|
||||
dsl_support = {
|
||||
@ -164,7 +167,7 @@ class DownloadDirTree:
|
||||
|
||||
else:
|
||||
if flag in self.additional_tree_flag_handler_mapping:
|
||||
return self.additional_tree_flag_handler_mapping[flag](album, photo)
|
||||
return self.additional_tree_flag_handler_mapping[flag](self, album, photo)
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ class JmcomicText:
|
||||
pattern_html_photo_data_original_domain = compile('src="https://(.*?)/media/albums/blank')
|
||||
pattern_html_photo_keywords = compile('<meta name="keywords" content="(.*?)" />')
|
||||
pattern_html_photo_series_id = compile('var series_id = (\d+);')
|
||||
pattern_html_photo_sort = compile('var sort = (\d+);')
|
||||
pattern_html_photo_page_arr = compile('var page_arr = (.*?);')
|
||||
|
||||
pattern_html_album_album_id = compile('<span class="number">.*?:JM(\d+)</span>')
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
from test_jmcomic import *
|
||||
|
||||
|
||||
class Test_DirTree(JmTestConfigurable):
|
||||
|
||||
def test_dir_tree(self):
|
||||
album_detail = JmAlbumDetail(None, None, 'album-title', [], 0, ['album-author'], '')
|
||||
photo_detail = JmPhotoDetail('6666', None, 'photo-title', [], '0', [], 'domain', 'photo-author', None)
|
||||
|
||||
ans = {
|
||||
'Bd_Author_Title_Image': '/album-author/photo-title/',
|
||||
'Bd_Author_Id_Image': '/album-author/6666/',
|
||||
'Bd_Title_Title_Image': '/album-title/photo-title/',
|
||||
'Bd_Title_Id_Image': '/album-title/6666/',
|
||||
'Bd_Title_Image': '/photo-title/',
|
||||
'Bd_Id_Image': '/6666/'
|
||||
}
|
||||
|
||||
Bd = workspace()
|
||||
dic = {}
|
||||
for name, flag in DownloadDirTree.accept_flag_dict().items():
|
||||
image_save_dir = DownloadDirTree.of(
|
||||
Bd, flag
|
||||
).deside_image_save_dir(album_detail, photo_detail)
|
||||
|
||||
dic[name] = image_save_dir.replace(Bd, '/')
|
||||
print(f"{name:20s}\t|\t{image_save_dir.replace(Bd, '/')}")
|
||||
|
||||
self.assertDictEqual(ans, dic)
|
||||
@ -60,3 +60,56 @@ class Test_Api(JmTestConfigurable):
|
||||
option = JmOption.default()
|
||||
option.register_advice(MyAdvice())
|
||||
jmcomic.download_album('366867', option)
|
||||
|
||||
def test_photo_sort(self):
|
||||
client = JmOption.default().build_jm_client()
|
||||
|
||||
# 测试用例 - 单章本子
|
||||
single_photo_album_is = str_to_list('''
|
||||
430371
|
||||
438696
|
||||
432888
|
||||
''')
|
||||
|
||||
# 测试用例 - 多章本子
|
||||
multi_photo_album_is = str_to_list('''
|
||||
400222
|
||||
122061
|
||||
''')
|
||||
|
||||
photo_dict: Dict[str, JmPhotoDetail] = multi_call(client.get_photo_detail, single_photo_album_is)
|
||||
album_dict: Dict[str, JmAlbumDetail] = multi_call(client.get_album_detail, single_photo_album_is)
|
||||
|
||||
for each in photo_dict.values():
|
||||
each: JmPhotoDetail
|
||||
self.assertEqual(each.album_index, 1)
|
||||
|
||||
for each in album_dict.values():
|
||||
each: JmAlbumDetail
|
||||
self.assertEqual(each[0].album_index, 1)
|
||||
|
||||
print_eye_catching('【通过】测试用例 - 单章本子')
|
||||
multi_photo_album_dict: Dict[JmAlbumDetail, List[JmPhotoDetail]] = {}
|
||||
|
||||
def run(aid):
|
||||
album = client.get_album_detail(aid)
|
||||
|
||||
photo_dict = multi_call(
|
||||
client.get_photo_detail,
|
||||
(photo.photo_id for photo in album),
|
||||
launcher=thread_pool_executor,
|
||||
)
|
||||
|
||||
multi_photo_album_dict[album] = list(photo_dict.values())
|
||||
|
||||
multi_thread_launcher(
|
||||
iter_objs=multi_photo_album_is,
|
||||
apply_each_obj_func=run,
|
||||
)
|
||||
|
||||
for album, photo_ls in multi_photo_album_dict.items():
|
||||
self.assertListEqual(
|
||||
sorted([each.sort for each in album]),
|
||||
sorted([ans.sort for ans in photo_ls]),
|
||||
album.album_id
|
||||
)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user