jmcomic 2.5.9__py3-none-any.whl → 2.5.11__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 +1 -1
- jmcomic/jm_client_interface.py +12 -0
- jmcomic/jm_config.py +1 -1
- jmcomic/jm_option.py +0 -22
- jmcomic/jm_plugin.py +82 -39
- {jmcomic-2.5.9.dist-info → jmcomic-2.5.11.dist-info}/METADATA +1 -1
- jmcomic-2.5.11.dist-info/RECORD +18 -0
- jmcomic-2.5.9.dist-info/RECORD +0 -18
- {jmcomic-2.5.9.dist-info → jmcomic-2.5.11.dist-info}/LICENSE +0 -0
- {jmcomic-2.5.9.dist-info → jmcomic-2.5.11.dist-info}/WHEEL +0 -0
- {jmcomic-2.5.9.dist-info → jmcomic-2.5.11.dist-info}/entry_points.txt +0 -0
- {jmcomic-2.5.9.dist-info → jmcomic-2.5.11.dist-info}/top_level.txt +0 -0
jmcomic/__init__.py
CHANGED
jmcomic/jm_client_interface.py
CHANGED
|
@@ -572,3 +572,15 @@ class JmcomicClient(
|
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
yield from self.do_page_iter(params, page, self.categories_filter)
|
|
575
|
+
|
|
576
|
+
def is_given_type(self, ctype: Type['JmcomicClient']) -> bool:
|
|
577
|
+
"""
|
|
578
|
+
Client代理的此方法会被路由到内部client的方法
|
|
579
|
+
即:ClientProxy(AClient()).is_given_type(AClient) is True
|
|
580
|
+
但是: ClientProxy(AClient()).client_key != AClient.client_key
|
|
581
|
+
"""
|
|
582
|
+
if isinstance(self, ctype):
|
|
583
|
+
return True
|
|
584
|
+
if self.client_key == instance.client_key:
|
|
585
|
+
return True
|
|
586
|
+
return False
|
jmcomic/jm_config.py
CHANGED
jmcomic/jm_option.py
CHANGED
|
@@ -236,28 +236,6 @@ class JmOption:
|
|
|
236
236
|
def decide_photo_batch_count(self, album: JmAlbumDetail):
|
|
237
237
|
return self.download.threading.photo
|
|
238
238
|
|
|
239
|
-
def decide_album_dir(self, album: JmAlbumDetail) -> str:
|
|
240
|
-
"""
|
|
241
|
-
该方法目前仅在 plugin-zip 中使用,不建议外部调用
|
|
242
|
-
"""
|
|
243
|
-
dir_layer = []
|
|
244
|
-
dir_rule = self.dir_rule
|
|
245
|
-
for rule in dir_rule.rule_dsl.split('_'):
|
|
246
|
-
if rule == 'Bd':
|
|
247
|
-
dir_layer.append(dir_rule.base_dir)
|
|
248
|
-
continue
|
|
249
|
-
|
|
250
|
-
if rule[0] == 'A':
|
|
251
|
-
name = dir_rule.apply_rule_directly(album, None, rule)
|
|
252
|
-
dir_layer.append(name)
|
|
253
|
-
|
|
254
|
-
if rule[0] == 'P':
|
|
255
|
-
break
|
|
256
|
-
|
|
257
|
-
from os.path import join
|
|
258
|
-
# noinspection PyTypeChecker
|
|
259
|
-
return join(*dir_layer)
|
|
260
|
-
|
|
261
239
|
# noinspection PyMethodMayBeStatic
|
|
262
240
|
def decide_image_filename(self, image: JmImageDetail) -> str:
|
|
263
241
|
"""
|
jmcomic/jm_plugin.py
CHANGED
|
@@ -302,27 +302,19 @@ class ZipPlugin(JmOptionPlugin):
|
|
|
302
302
|
|
|
303
303
|
if level == 'album':
|
|
304
304
|
zip_path = self.get_zip_path(album, None, filename_rule, suffix, zip_dir)
|
|
305
|
-
|
|
306
|
-
if dir_path is not None:
|
|
307
|
-
# 要删除这个album文件夹
|
|
308
|
-
dir_zip_dict[dir_path] = zip_path
|
|
309
|
-
# 也要删除album下的photo文件夹
|
|
310
|
-
for d in files_of_dir(dir_path):
|
|
311
|
-
dir_zip_dict[d] = None
|
|
305
|
+
self.zip_album(album, photo_dict, zip_path, dir_zip_dict)
|
|
312
306
|
|
|
313
307
|
elif level == 'photo':
|
|
314
308
|
for photo, image_list in photo_dict.items():
|
|
315
309
|
zip_path = self.get_zip_path(None, photo, filename_rule, suffix, zip_dir)
|
|
316
|
-
|
|
317
|
-
if dir_path is not None:
|
|
318
|
-
dir_zip_dict[dir_path] = zip_path
|
|
310
|
+
self.zip_photo(photo, image_list, zip_path, dir_zip_dict)
|
|
319
311
|
|
|
320
312
|
else:
|
|
321
313
|
ExceptionTool.raises(f'Not Implemented Zip Level: {level}')
|
|
322
314
|
|
|
323
315
|
self.after_zip(dir_zip_dict)
|
|
324
316
|
|
|
325
|
-
def zip_photo(self, photo, image_list: list, zip_path: str) -> Optional[str]:
|
|
317
|
+
def zip_photo(self, photo, image_list: list, zip_path: str, dir_zip_dict) -> Optional[str]:
|
|
326
318
|
"""
|
|
327
319
|
压缩photo文件夹
|
|
328
320
|
:returns: photo文件夹路径
|
|
@@ -333,50 +325,58 @@ class ZipPlugin(JmOptionPlugin):
|
|
|
333
325
|
|
|
334
326
|
all_filepath = set(map(lambda t: self.unified_path(t[0]), image_list))
|
|
335
327
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
328
|
+
if len(all_filepath) == 0:
|
|
329
|
+
self.log('无下载文件,无需压缩', 'skip')
|
|
330
|
+
return None
|
|
331
|
+
|
|
332
|
+
from common import backup_dir_to_zip
|
|
333
|
+
backup_dir_to_zip(
|
|
334
|
+
photo_dir,
|
|
335
|
+
zip_path,
|
|
336
|
+
acceptor=lambda f: os.path.isdir(f) or self.unified_path(f) in all_filepath
|
|
337
|
+
).close()
|
|
338
|
+
|
|
339
|
+
self.log(f'压缩章节[{photo.photo_id}]成功 → {zip_path}', 'finish')
|
|
340
|
+
dir_zip_dict[self.unified_path(photo_dir)] = zip_path
|
|
341
341
|
|
|
342
342
|
@staticmethod
|
|
343
343
|
def unified_path(f):
|
|
344
344
|
return fix_filepath(f, os.path.isdir(f))
|
|
345
345
|
|
|
346
|
-
def zip_album(self, album, photo_dict: dict, zip_path) -> Optional[str]:
|
|
346
|
+
def zip_album(self, album, photo_dict: dict, zip_path, dir_zip_dict) -> Optional[str]:
|
|
347
347
|
"""
|
|
348
348
|
压缩album文件夹
|
|
349
349
|
:returns: album文件夹路径
|
|
350
350
|
"""
|
|
351
|
-
all_filepath: Set[str] = set()
|
|
352
|
-
|
|
353
|
-
def addpath(f):
|
|
354
|
-
all_filepath.update(set(f))
|
|
355
351
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
addpath(path for ls in photo_dict.values() for path, _ in ls)
|
|
352
|
+
# 所有下载了的图片文件的路径
|
|
353
|
+
all_filepath: Set[str] = set(path for ls in photo_dict.values() for path, _ in ls)
|
|
359
354
|
|
|
360
|
-
return self.do_zip(album_dir,
|
|
361
|
-
zip_path,
|
|
362
|
-
all_filepath,
|
|
363
|
-
msg=f'压缩本子[{album.album_id}]成功 → {zip_path}',
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
def do_zip(self, source_dir, zip_path, all_filepath, msg):
|
|
367
355
|
if len(all_filepath) == 0:
|
|
368
356
|
self.log('无下载文件,无需压缩', 'skip')
|
|
369
|
-
return
|
|
357
|
+
return
|
|
370
358
|
|
|
359
|
+
# 该本子的所有章节的图片所在文件夹
|
|
360
|
+
photo_dir_list = [self.option.decide_image_save_dir(photo) for photo in photo_dict.keys()]
|
|
361
|
+
|
|
362
|
+
# 压缩文件对象
|
|
371
363
|
from common import backup_dir_to_zip
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
364
|
+
import zipfile
|
|
365
|
+
zfile = zipfile.ZipFile(zip_path, 'w')
|
|
366
|
+
|
|
367
|
+
for photo_dir in photo_dir_list:
|
|
368
|
+
photo_dir = self.unified_path(photo_dir)
|
|
369
|
+
backup_dir_to_zip(
|
|
370
|
+
photo_dir,
|
|
371
|
+
zip_path,
|
|
372
|
+
zfile=zfile,
|
|
373
|
+
prefix=os.path.basename(photo_dir.rstrip('/')),
|
|
374
|
+
acceptor=lambda f: os.path.isdir(f) or self.unified_path(f) in all_filepath
|
|
375
|
+
)
|
|
376
|
+
dir_zip_dict[photo_dir] = zip_path
|
|
377
377
|
|
|
378
|
-
|
|
379
|
-
|
|
378
|
+
zfile.close()
|
|
379
|
+
self.log(f'压缩本子[{album.album_id}]成功 → {zip_path}', 'finish')
|
|
380
380
|
|
|
381
381
|
def after_zip(self, dir_zip_dict: Dict[str, Optional[str]]):
|
|
382
382
|
# 删除所有原文件
|
|
@@ -757,6 +757,49 @@ class ConvertJpgToPdfPlugin(JmOptionPlugin):
|
|
|
757
757
|
self.execute_deletion(paths)
|
|
758
758
|
|
|
759
759
|
|
|
760
|
+
class Img2pdfPlugin(JmOptionPlugin):
|
|
761
|
+
plugin_key = 'img2pdf'
|
|
762
|
+
|
|
763
|
+
def invoke(self,
|
|
764
|
+
photo: JmPhotoDetail,
|
|
765
|
+
downloader=None,
|
|
766
|
+
pdf_dir=None,
|
|
767
|
+
filename_rule='Pid',
|
|
768
|
+
delete_original_file=False,
|
|
769
|
+
**kwargs,
|
|
770
|
+
):
|
|
771
|
+
try:
|
|
772
|
+
import img2pdf
|
|
773
|
+
except ImportError:
|
|
774
|
+
self.warning_lib_not_install('img2pdf')
|
|
775
|
+
return
|
|
776
|
+
|
|
777
|
+
self.delete_original_file = delete_original_file
|
|
778
|
+
|
|
779
|
+
# 处理文件夹配置
|
|
780
|
+
filename = DirRule.apply_rule_directly(None, photo, filename_rule)
|
|
781
|
+
photo_dir = self.option.decide_image_save_dir(photo)
|
|
782
|
+
|
|
783
|
+
# 处理生成的pdf文件的路径
|
|
784
|
+
if pdf_dir is None:
|
|
785
|
+
pdf_dir = photo_dir
|
|
786
|
+
else:
|
|
787
|
+
pdf_dir = fix_filepath(pdf_dir, True)
|
|
788
|
+
mkdir_if_not_exists(pdf_dir)
|
|
789
|
+
|
|
790
|
+
pdf_filepath = os.path.join(pdf_dir, f'{filename}.pdf')
|
|
791
|
+
|
|
792
|
+
# 调用 img2pdf 把 photo_dir 下的所有图片转为pdf
|
|
793
|
+
all_img = files_of_dir(photo_dir)
|
|
794
|
+
with open(pdf_filepath, 'wb') as f:
|
|
795
|
+
f.write(img2pdf.convert(all_img))
|
|
796
|
+
|
|
797
|
+
# 执行删除
|
|
798
|
+
self.log(f'Convert Successfully: JM{photo.id} → {pdf_filepath}')
|
|
799
|
+
all_img.append(self.option.decide_image_save_dir(photo, ensure_exists=False))
|
|
800
|
+
self.execute_deletion(all_img)
|
|
801
|
+
|
|
802
|
+
|
|
760
803
|
class JmServerPlugin(JmOptionPlugin):
|
|
761
804
|
plugin_key = 'jm_server'
|
|
762
805
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
jmcomic/__init__.py,sha256=Hjp1Q6tJ5zCFkSqh2ETXJuh_Rgpx5OKEjMhSbrU3dTs,903
|
|
2
|
+
jmcomic/api.py,sha256=uLHtSof7ZaiWZcNDDAz6grD1NYs4VxsoCOrsge3G7v8,3864
|
|
3
|
+
jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
|
|
4
|
+
jmcomic/jm_client_impl.py,sha256=Oszkw7dKfg8DHzmjyBVD1DrHp9OlvLK33IQHB7uXo48,37811
|
|
5
|
+
jmcomic/jm_client_interface.py,sha256=vP36T2OI5MQdmfdYEnoFGRpHZRTE9LnBetDUFCOnMg4,17691
|
|
6
|
+
jmcomic/jm_config.py,sha256=I08aDW1WH9uVnbyiUvy4lfI8cAU8NNK96cEA5kGYcoM,15252
|
|
7
|
+
jmcomic/jm_downloader.py,sha256=0r4z7FRnow6xkRy_WTv7nLQOhYdtZmoouw0BNrhngco,10397
|
|
8
|
+
jmcomic/jm_entity.py,sha256=-WUKYGkNToQv5Hja3RkI5abHF1g46WpLyVjoyXMs-wI,18974
|
|
9
|
+
jmcomic/jm_exception.py,sha256=B9APE1jw23JBzCT12eV_imCZny3mNrSXju1p2IquaHA,4801
|
|
10
|
+
jmcomic/jm_option.py,sha256=s16w8uZYfCBUgsxCjegnLoAqHF69rJicVZKQTZlQTJA,21723
|
|
11
|
+
jmcomic/jm_plugin.py,sha256=21bd71tmsKyli73skMx0ozcqBM5saHzICEicjRQ98-Q,33606
|
|
12
|
+
jmcomic/jm_toolkit.py,sha256=WLHaigCN03Z4b5swGTRTTSWzZsa0uFxGAnw4xKhbh1U,28649
|
|
13
|
+
jmcomic-2.5.11.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
|
|
14
|
+
jmcomic-2.5.11.dist-info/METADATA,sha256=2vGTgKwdQwztHQ8eIQ9cMOdHb5FTKYCPRZ_uWP6qP0E,6123
|
|
15
|
+
jmcomic-2.5.11.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
16
|
+
jmcomic-2.5.11.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
|
|
17
|
+
jmcomic-2.5.11.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
|
|
18
|
+
jmcomic-2.5.11.dist-info/RECORD,,
|
jmcomic-2.5.9.dist-info/RECORD
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
jmcomic/__init__.py,sha256=WAC5HDkp2E-1HtrXfYzNJf9HWoCXqZx5wyLRUdFsFKI,902
|
|
2
|
-
jmcomic/api.py,sha256=uLHtSof7ZaiWZcNDDAz6grD1NYs4VxsoCOrsge3G7v8,3864
|
|
3
|
-
jmcomic/cl.py,sha256=PBSh0JndNFZw3B7WJPj5Y8SeFdKzHE00jIwYo9An-K0,3475
|
|
4
|
-
jmcomic/jm_client_impl.py,sha256=Oszkw7dKfg8DHzmjyBVD1DrHp9OlvLK33IQHB7uXo48,37811
|
|
5
|
-
jmcomic/jm_client_interface.py,sha256=f-2pFwJUzEdH4GVG8ExbR0dSoIP4w5M6CjX_Mlbxglc,17234
|
|
6
|
-
jmcomic/jm_config.py,sha256=zVyxJrB-KpSwrVCEooglIdC2fT6St08P2ycK3GrqDTE,15249
|
|
7
|
-
jmcomic/jm_downloader.py,sha256=0r4z7FRnow6xkRy_WTv7nLQOhYdtZmoouw0BNrhngco,10397
|
|
8
|
-
jmcomic/jm_entity.py,sha256=-WUKYGkNToQv5Hja3RkI5abHF1g46WpLyVjoyXMs-wI,18974
|
|
9
|
-
jmcomic/jm_exception.py,sha256=B9APE1jw23JBzCT12eV_imCZny3mNrSXju1p2IquaHA,4801
|
|
10
|
-
jmcomic/jm_option.py,sha256=Y_ckE9xa6y0oqjG6CbKR3QX4TWvLuHK2ue_RzQkMxHM,22395
|
|
11
|
-
jmcomic/jm_plugin.py,sha256=YWt7MAWuy2zOsHEARDKf4ZFE3pDmHPqM1M0vwnoNgVg,32262
|
|
12
|
-
jmcomic/jm_toolkit.py,sha256=WLHaigCN03Z4b5swGTRTTSWzZsa0uFxGAnw4xKhbh1U,28649
|
|
13
|
-
jmcomic-2.5.9.dist-info/LICENSE,sha256=kz4coTxZxuGxisK3W00tjK57Zh3RcMGq-EnbXrK7-xA,1064
|
|
14
|
-
jmcomic-2.5.9.dist-info/METADATA,sha256=317JlniKqNOIcwLCBrxP5hUpMCBIoiCECPM9poW_OHs,6122
|
|
15
|
-
jmcomic-2.5.9.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
16
|
-
jmcomic-2.5.9.dist-info/entry_points.txt,sha256=tRbQltaGSBjejI0c9jYt-4SXQMd5nSDHcMvHmuTy4ow,44
|
|
17
|
-
jmcomic-2.5.9.dist-info/top_level.txt,sha256=puvVMFYJqIbd6NOTMEvOyugMTT8woBfSQyxEBan3zY4,8
|
|
18
|
-
jmcomic-2.5.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|