ComicScrapy/Comics/pipelines.py
2023-10-05 04:58:36 +08:00

121 lines
5.2 KiB
Python

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
import os, scrapy,logging,time,random,shutil
from Comics import settings
from Comics.settings import CBZ_EXPORT_PATH,OUTPUT_DIR,PROJECT_KEY
from Comics.utils.Constant import ComicPath
from Comics.items import ComicItem
from scrapy.pipelines.images import ImagesPipeline
from Comics.exporters import ComicInfoXmlItemExporter,JsonExport,ItemExporter, ItemImport
from Comics.utils.FileUtils import CBZUtils
from Comics.utils.FileUtils import fileUtils as fu
from Comics.loader import ComicEntity
from Comics.utils.ComicUtils import checkUtils
class ComicsPipeline:
def open_spider(self, spider):
pass
# item就是yield后面的对象
def process_item(self, item, spider):
if isinstance(item, ComicItem):
# 'output/rm_comic/json/壞X/第1話 壞X'
if os.path.exists(ComicPath.CBZ(item=item)):
return ItemExporter().export_obj(item)
else:
file = os.path.join(OUTPUT_DIR, spider.name, "json", item['name'], item['chapter'])
return JsonExport(file=file).export_json(ComicEntity(item).item(), if_return=True)
# image解析
def close_spider(self, spider):
pass
class ImgDownloadPipeline(ImagesPipeline):
def get_file_path(self, item, file=None, result_type="image"):
return ComicPath.get_file_path(item=item, file=file, result_type= result_type)
def image_scramble_exits(self, item,image_path):
en_image_path = ComicPath().getFileScrambleImageSave(image_path, relative="fullpath")
return os.path.exists(os.path.join(settings.IMAGES_STORE, self.get_file_path(item, en_image_path)))
## Icon Path : CBZ/NAME/CHAPTER.jpg
def download_icon(self, item, result_type="download"):
icon_path = self.get_file_path(item, result_type="icon_cache")
if result_type == "fullpath":
return os.path.join(settings.IMAGES_STORE, icon_path)
if os.path.exists(icon_path):
return False
else:
self.image_urls.append(item['icon'])
self.images.append(icon_path)
return True
def file_path(self, request, response=None, info=None, *, item=None): return request.meta['path']
def get_media_requests(self, item, info):
comic = ComicEntity(item)
self.image_urls = comic.image_urls()
self.images = comic.images()
# 下载封面
self.download_icon(item)
for image_url,image in zip(self.image_urls,self.images):
is_down = True
image_path = self.get_file_path(item, image)
if self.image_scramble_exits(item, image_path):
if image_path == self.get_file_path(item, result_type="icon_cache"):
logging.info(f"icon file exists: IMAGE_STORE {image_path}")
else:
is_down = False
logging.info(f"file exists: IMAGE_STORE {image_path}")
if is_down:
logging.info(f"downloading {image_url} --> IMAGE_STORE {image_path}")
yield scrapy.Request(url=image_url, meta={'path': image_path})
# 打包cbz封面
def pack_icon(self, item):
cbz_icon = self.get_file_path(item=item, result_type="cbz_icon")
dwn_icon = self.get_file_path(item=item, result_type="down_icon")
base_dir = os.path.dirname(dwn_icon)
name = os.path.basename(dwn_icon).split(".")[0]
for dirname in os.listdir(base_dir):
path = os.path.join(base_dir, dirname)
if os.path.isfile(path) and dirname.startswith(name):
fu.update_icon(path, cbz_icon)
# 判断是否需要更新封面
def update_icon(self, item):
# 下载后的缓存封面路径
image_path = self.get_file_path(item, result_type="down_cache_icon")
# 最终封面保存路径
save_path = self.get_file_path(item=item, result_type="down_icon")
fu.update_icon(image_path, save_path)
def item_completed(self, results, item, info):
# return item
# 打包
cbz_path = self.get_file_path(item, result_type="cbz")
if os.path.exists(cbz_path):
self.update_icon(item)
self.pack_icon(item)
else:
# ComicInfoXml 生成
comic_info = ComicInfoXmlItemExporter(dir=self.get_file_path(item=item, result_type="comic_info")).export_xml(item)
if CBZUtils.packComicChapterCBZ(src_dir= self.get_file_path(item, result_type="images_dir"),
dts_path= cbz_path,
comic_info_images= comic_info['Pages'], remove=True):
self.update_icon(item)
self.pack_icon(item)
# CBZ校验失败
else:
checkUtils().export_error(item)
#sleep_time = random.randint(3,15)
#print(f'等待{sleep_time}秒后进行下一章节')
#time.sleep(int(sleep_time))