11"""
22该文件存放的是option插件
33"""
4- import os .path
54
65from .jm_option import *
76
@@ -76,6 +75,9 @@ def execute_deletion(self, paths: List[str]):
7675 continue
7776
7877 if os .path .isdir (p ):
78+ if os .listdir (p ):
79+ self .log (f'文件夹中存在非本次下载的文件,请手动删除文件夹内的文件: { p } ' , 'remove.ignore' )
80+ continue
7981 os .rmdir (p )
8082 self .log (f'删除文件夹: { p } ' , 'remove' )
8183 else :
@@ -104,6 +106,33 @@ def leave_wait_list(self):
104106 def wait_until_finish (self ):
105107 pass
106108
109+ # noinspection PyMethodMayBeStatic
110+ def decide_filepath (self ,
111+ album : Optional [JmAlbumDetail ],
112+ photo : Optional [JmPhotoDetail ],
113+ filename_rule : str , suffix : str , base_dir : Optional [str ],
114+ dir_rule_dict : Optional [dict ]
115+ ):
116+ """
117+ 根据规则计算一个文件的全路径
118+
119+ 参数 dir_rule_dict 优先级最高,
120+ 如果 dir_rule_dict 不为空,优先用 dir_rule_dict
121+ 否则使用 base_dir + filename_rule + suffix
122+ """
123+ filepath : str
124+ base_dir : str
125+ if dir_rule_dict is not None :
126+ dir_rule = DirRule (** dir_rule_dict )
127+ filepath = dir_rule .apply_rule_to_path (album , photo )
128+ base_dir = os .path .dirname (filepath )
129+ else :
130+ base_dir = base_dir or os .getcwd ()
131+ filepath = os .path .join (base_dir , DirRule .apply_rule_to_filename (album , photo , filename_rule ) + fix_suffix (suffix ))
132+
133+ mkdir_if_not_exists (base_dir )
134+ return filepath
135+
107136
108137class JmLoginPlugin (JmOptionPlugin ):
109138 """
@@ -285,7 +314,8 @@ def invoke(self,
285314 level = 'photo' ,
286315 filename_rule = 'Ptitle' ,
287316 suffix = 'zip' ,
288- zip_dir = './'
317+ zip_dir = './' ,
318+ dir_rule = None ,
289319 ) -> None :
290320
291321 from .jm_downloader import JmDownloader
@@ -302,12 +332,12 @@ def invoke(self,
302332 photo_dict = self .get_downloaded_photo (downloader , album , photo )
303333
304334 if level == 'album' :
305- zip_path = self .get_zip_path (album , None , filename_rule , suffix , zip_dir )
335+ zip_path = self .decide_filepath (album , None , filename_rule , suffix , zip_dir , dir_rule )
306336 self .zip_album (album , photo_dict , zip_path , path_to_delete )
307337
308338 elif level == 'photo' :
309339 for photo , image_list in photo_dict .items ():
310- zip_path = self .get_zip_path (photo .from_album , photo , filename_rule , suffix , zip_dir )
340+ zip_path = self .decide_filepath (photo .from_album , photo , filename_rule , suffix , zip_dir , dir_rule )
311341 self .zip_photo (photo , image_list , zip_path , path_to_delete )
312342
313343 else :
@@ -371,18 +401,6 @@ def after_zip(self, path_to_delete: List[str]):
371401 self .execute_deletion (image_paths )
372402 self .execute_deletion (dirs )
373403
374- # noinspection PyMethodMayBeStatic
375- def get_zip_path (self , album , photo , filename_rule , suffix , zip_dir ):
376- """
377- 计算zip文件的路径
378- """
379- filename = DirRule .apply_rule_directly (album , photo , filename_rule )
380- from os .path import join
381- return join (
382- zip_dir ,
383- filename + fix_suffix (suffix ),
384- )
385-
386404
387405class ClientProxyPlugin (JmOptionPlugin ):
388406 plugin_key = 'client_proxy'
@@ -649,95 +667,6 @@ def zip_with_password(self):
649667 self .execute_multi_line_cmd (cmd_list )
650668
651669
652- class ConvertJpgToPdfPlugin (JmOptionPlugin ):
653- plugin_key = 'j2p'
654-
655- def check_image_suffix_is_valid (self , std_suffix ):
656- """
657- 检查option配置的图片后缀转换,目前限制使用Magick时只能搭配jpg
658- 暂不探究Magick是否支持更多图片格式
659- """
660- cur_suffix : Optional [str ] = self .option .download .image .suffix
661-
662- ExceptionTool .require_true (
663- cur_suffix is not None and cur_suffix .endswith (std_suffix ),
664- '请把图片的后缀转换配置为jpg,不然无法使用Magick!'
665- f'(当前配置是[{ cur_suffix } ])\n '
666- f'配置模板如下: \n '
667- f'```\n '
668- f'download:\n '
669- f' image:\n '
670- f' suffix: { std_suffix } # 当前配置是{ cur_suffix } \n '
671- f'```'
672- )
673-
674- def invoke (self ,
675- photo : JmPhotoDetail ,
676- downloader = None ,
677- pdf_dir = None ,
678- filename_rule = 'Pid' ,
679- quality = 100 ,
680- delete_original_file = False ,
681- override_cmd = None ,
682- override_jpg = None ,
683- ** kwargs ,
684- ):
685- self .delete_original_file = delete_original_file
686-
687- # 检查图片后缀配置
688- suffix = override_jpg or '.jpg'
689- self .check_image_suffix_is_valid (suffix )
690-
691- # 处理文件夹配置
692- filename = DirRule .apply_rule_directly (None , photo , filename_rule )
693- photo_dir = self .option .decide_image_save_dir (photo )
694-
695- # 处理生成的pdf文件的路径
696- if pdf_dir is None :
697- pdf_dir = photo_dir
698- else :
699- pdf_dir = fix_filepath (pdf_dir , True )
700- mkdir_if_not_exists (pdf_dir )
701-
702- pdf_filepath = os .path .join (pdf_dir , f'{ filename } .pdf' )
703-
704- # 生成命令
705- def generate_cmd ():
706- return (
707- override_cmd or
708- 'magick convert -quality {quality} "{photo_dir}*{suffix}" "{pdf_filepath}"'
709- ).format (
710- quality = quality ,
711- photo_dir = photo_dir ,
712- suffix = suffix ,
713- pdf_filepath = pdf_filepath ,
714- )
715-
716- cmd = generate_cmd ()
717- self .log (f'Execute Command: [{ cmd } ]' )
718- code = self .execute_cmd (cmd )
719-
720- ExceptionTool .require_true (
721- code == 0 ,
722- 'jpg图片合并为pdf失败!'
723- '请确认你是否安装了magick,安装网站: [https://www.imagemagick.org/]' ,
724- )
725-
726- self .log (f'Convert Successfully: JM{ photo .id } → { pdf_filepath } ' )
727-
728- if downloader is not None :
729- from .jm_downloader import JmDownloader
730- downloader : JmDownloader
731-
732- paths = [
733- path
734- for path , image in downloader .download_success_dict [photo .from_album ][photo ]
735- ]
736-
737- paths .append (self .option .decide_image_save_dir (photo , ensure_exists = False ))
738- self .execute_deletion (paths )
739-
740-
741670class Img2pdfPlugin (JmOptionPlugin ):
742671 plugin_key = 'img2pdf'
743672
@@ -747,6 +676,7 @@ def invoke(self,
747676 downloader = None ,
748677 pdf_dir = None ,
749678 filename_rule = 'Pid' ,
679+ dir_rule = None ,
750680 delete_original_file = False ,
751681 ** kwargs ,
752682 ):
@@ -762,13 +692,7 @@ def invoke(self,
762692 self .delete_original_file = delete_original_file
763693
764694 # 处理生成的pdf文件的路径
765- pdf_dir = self .ensure_make_pdf_dir (pdf_dir )
766-
767- # 处理pdf文件名
768- filename = DirRule .apply_rule_directly (album , photo , filename_rule )
769-
770- # pdf路径
771- pdf_filepath = os .path .join (pdf_dir , f'{ filename } .pdf' )
695+ pdf_filepath = self .decide_filepath (album , photo , filename_rule , 'pdf' , pdf_dir , dir_rule )
772696
773697 # 调用 img2pdf 把 photo_dir 下的所有图片转为pdf
774698 img_path_ls , img_dir_ls = self .write_img_2_pdf (pdf_filepath , album , photo )
@@ -794,18 +718,14 @@ def write_img_2_pdf(self, pdf_filepath, album: JmAlbumDetail, photo: JmPhotoDeta
794718 continue
795719 img_path_ls += imgs
796720
721+ if len (img_path_ls ) == 0 :
722+ self .log (f'所有文件夹都不存在图片,无法生成pdf:{ img_dir_ls } ' , 'error' )
723+
797724 with open (pdf_filepath , 'wb' ) as f :
798725 f .write (img2pdf .convert (img_path_ls ))
799726
800727 return img_path_ls , img_dir_ls
801728
802- @staticmethod
803- def ensure_make_pdf_dir (pdf_dir : str ):
804- pdf_dir = pdf_dir or os .getcwd ()
805- pdf_dir = fix_filepath (pdf_dir , True )
806- mkdir_if_not_exists (pdf_dir )
807- return pdf_dir
808-
809729
810730class LongImgPlugin (JmOptionPlugin ):
811731 plugin_key = 'long_img'
@@ -817,6 +737,7 @@ def invoke(self,
817737 img_dir = None ,
818738 filename_rule = 'Pid' ,
819739 delete_original_file = False ,
740+ dir_rule = None ,
820741 ** kwargs ,
821742 ):
822743 if photo is None and album is None :
@@ -830,14 +751,8 @@ def invoke(self,
830751
831752 self .delete_original_file = delete_original_file
832753
833- # 处理文件夹配置
834- img_dir = self .get_img_dir (img_dir )
835-
836754 # 处理生成的长图文件的路径
837- filename = DirRule .apply_rule_directly (album , photo , filename_rule )
838-
839- # 长图路径
840- long_img_path = os .path .join (img_dir , f'{ filename } .png' )
755+ long_img_path = self .decide_filepath (album , photo , filename_rule , 'png' , img_dir , dir_rule )
841756
842757 # 调用 PIL 把 photo_dir 下的所有图片合并为长图
843758 img_path_ls = self .write_img_2_long_img (long_img_path , album , photo )
@@ -856,7 +771,7 @@ def write_img_2_long_img(self, long_img_path, album: JmAlbumDetail, photo: JmPho
856771 img_dir_items = [self .option .decide_image_save_dir (photo ) for photo in album ]
857772
858773 img_paths = itertools .chain (* map (files_of_dir , img_dir_items ))
859- img_paths = filter (lambda x : not x .startswith ('.' ), img_paths ) # 过滤系统文件
774+ img_paths = list ( filter (lambda x : not x .startswith ('.' ), img_paths ) ) # 过滤系统文件
860775
861776 images = self .open_images (img_paths )
862777
@@ -895,12 +810,6 @@ def open_images(self, img_paths: List[str]):
895810 self .log (f"Failed to open image { img_path } : { e } " , 'error' )
896811 return images
897812
898- @staticmethod
899- def get_img_dir (img_dir : Optional [str ]) -> str :
900- img_dir = fix_filepath (img_dir or os .getcwd ())
901- mkdir_if_not_exists (img_dir )
902- return img_dir
903-
904813
905814class JmServerPlugin (JmOptionPlugin ):
906815 plugin_key = 'jm_server'
0 commit comments