def custom_download_callback():
"""
该函数演示自定义下载时的回调函数
"""
# jmcomic的下载功能由 JmModuleConfig.CLASS_DOWNLOADER 这个类来负责执行
# 这个类默认是 JmDownloader,继承了DownloadCallback
# 你可以写一个自定义类,继承JmDownloader,覆盖属于DownloadCallback的方法,来实现自定义回调
class MyDownloader(JmDownloader):
# 覆盖 album 下载完成后的回调
def after_album(self, album: JmAlbumDetail):
print(f'album下载完毕: {album}')
pass
# 最后,让你的自定义类生效
JmModuleConfig.CLASS_DOWNLOADER = MyDownloader
def custom_option_class():
"""
该函数演示自定义option类
"""
# jmcomic模块支持自定义Option类,
# 你可以写一个自己的类,继承JmOption,然后覆盖其中的一些方法。
class MyOption(JmOption):
def __init__(self, *args, **kwargs):
print('MyOption 初始化开始')
super().__init__(*args, **kwargs)
@classmethod
def default(cls):
print('调用了MyOption.default()')
return super().default()
# 最后,替换默认Option类即可
JmModuleConfig.CLASS_OPTION = MyOption
def custom_client_class():
"""
该文件演示自定义client类
"""
# 默认情况下,JmOption使用client类是根据配置项 `client.impl` 决定的
# JmOption会根据`client.impl`到 JmModuleConfig.CLASS_CLIENT_IMPL 中查找
# 自定义client的步骤如下
# 1. 自定义Client类
class MyClient(JmHtmlClient):
client_key = 'myclient'
pass
# 2. 让MyClient生效
JmModuleConfig.register_client(MyClient)
# 3. 在配置文件中使用你定义的client.impl,后续使用这个option即可
"""
client:
impl: myclient
"""
def custom_album_photo_image_detail_class():
"""
该函数演示自定义实体类(本子/章节/图片)
在使用路径规则 DirRule 时,可能会遇到需要自定义实体类属性的情况,例如:
dir_rule:
base_dir: ${workspace}
rule: Bd_Acustom_Pcustom
# 可选:对目录名进行繁/简体规范化(None/zh-cn/zh-tw),默认不启用
# normalize_zh: zh-cn
上面的Acustom,Pcustom都是自定义字段
如果你想要使用这种自定义字段,你就需要替换默认的实体类,方式如下
"""
# 自定义本子实体类
class MyAlbum(JmAlbumDetail):
# 自定义 custom 属性
@property
def custom(self):
return f'custom_{self.title}'
# 自定义章节实体类
class MyPhoto(JmPhotoDetail):
# 自定义 custom 属性
@property
def custom(self):
return f'custom_{self.title}'
"""
v2.3.3: 支持更灵活的自定义方式,可以使用函数,效果同上,示例见下
"""
class MyAlbum2(JmAlbumDetail):
def get_dirname(self, ref: str) -> str:
if ref == 'custom':
return f'custom_{self.name}'
return super().get_dirname(ref)
# 最后,替换默认实体类来让你的自定义类生效
JmModuleConfig.CLASS_ALBUM = MyAlbum
JmModuleConfig.CLASS_PHOTO = MyPhoto
def custom_jm_log():
"""
该函数演示如何接管和自定义日志输出
"""
# jmcomic 项目默认使用内置的 Python logging 模块
# 其日志记录器的名字固定为 "jmcomic"
# 【推荐方式】直接配置原生的 logging logger
import logging
jm_logger = logging.getLogger("jmcomic")
# 例如,取消默认往下游控制台打印的 Handler,转存到文件中
jm_logger.handlers.clear()
jm_logger.addHandler(logging.FileHandler("jm_download.log", encoding="utf-8"))
# 【向后兼容方式/遗留用法】
# 你依然可以通过替换全局配置类的 EXECUTOR_LOG 函数暴力接管日志
def my_custom_log(topic: str, msg, e: Exception = None):
"""
@param topic: log主题,例如 'album.before', 'req.error', 'plugin.error'
@param msg: 具体log的信息,也可以直接传入 Exception 对象(底层会自动适配)
@param e: 可选,异常对象(当 msg 本身就是 Exception 时无需传)
"""
pass
# 生效自定义的 log 打印函数
JmModuleConfig.EXECUTOR_LOG = my_custom_log
def custom_exception_listener():
"""
该函数演示jmcomic的异常监听器机制
"""
# 1. 选一个可能会发生的、你感兴趣的异常
etype = ResponseUnexpectedException
def listener(e):
"""
你的监听器方法
该方法无需返回值
:param e: 异常实例
"""
print(f'my exception listener invoke !!! exception happened: {e}')
# 注册监听器/回调
# 这个异常类(或者这个异常的子类)的实例将要被raise前,你的listener方法会被调用
JmModuleConfig.register_exception_listener(etype, listener)