脚本系统
从v3.3.0版本开始,PicList引入了脚本系统,允许用户通过自定义脚本扩展和定制PicList的功能。
介绍
不同于源自PicGo的插件系统,PicList的脚本系统设计为轻量级且易于使用。插件系统使用时需要用户本机安装Node.js环境,且插件需要经过打包和发布流程,安装也受限于网络环境且需要下载非常多的依赖包。
在脚本系统中,用户可以直接在软件内编写JavaScript脚本来实现特定功能,而无需安装Node.js环境。脚本可以访问PicList的核心API以及一些内置模块,从而实现文件上传、处理和管理等操作。
脚本系统适合以下场景:
- 自定义上传流程:根据特定需求定制文件上传逻辑
- 批量处理文件:实现批量重命名、分类等功能
- 集成第三方服务:通过脚本调用外部API,实现与其他服务的集成
- 自动化任务:定时执行某些操作,如定期清理文件等
- 定制化需求:满足个人的特殊需求
使用脚本
脚本的创建与管理
打开PicList,导航到脚本界面,在这里可以创建、编辑和管理脚本。默认情况下,PicList会在用户数据目录下的scripts文件夹中存储脚本文件。

编写脚本
PicList的脚本按照执行时机分为以下几类:
- 软件启动时: 在PicList启动时执行,适合初始化操作
- 软件关闭时: 在PicList关闭前执行,适合清理操作
- 上传处理前:在文件上传的水印、压缩等操作执行之后立即执行,适合对上传文件进行最后处理
- 图片变换前:对应插件中的
beforeTransformer钩子 - 图片变换时:对应插件中的
transformer钩子 - 上传前:对应插件中的
beforeUpload钩子 - 上传时:对应插件中的
uploader钩子 - 上传后:对应插件中的
afterUpload钩子 - 上传成功时:执行时机在上传完成,图片插入相册后
- 相册删除时:在相册删除图片时执行,适合同步删除第三方存储的文件
- 手动触发:通过脚本界面手动执行
另外,高级自定义图床脚本对应高级自定义图床使用,可以编写上传脚本实现对任意图床的支持。
脚本API
默认的脚本模板如下:
javascript
// ctx 为 核心PicList实例, extra为额外参数, 其中extra.galleryItem为当前删除的相册对象
// 可用额外API: axios, crypto, fs, path, os, setTimeout, setInterval, clearTimeout, clearInterval, base64Decode, base64Encode
// 图床上传脚本必须返回 ctx 对象, 其它脚本可根据需求返回任意数据
async function main(ctx, extra) {
return ctx
}脚本可以访问以下API和模块:
ctx:PicList的核心实例,包含配置、上传器、变换器等属性和方法extra:额外参数对象,其中extra.galleryItem为当前删除的相册对象(仅在相册删除脚本中可用)axios:用于发送HTTP请求的库crypto:Node.js的加密模块fs:Node.js的文件系统模块path:Node.js的路径模块os:Node.js的操作系统模块- 定时器函数:
setTimeout、setInterval、clearTimeout、clearInterval - 编码函数:
base64Decode、base64Encode
额外的,对于ctx对象,常用属性和方法包括:
getConfig(key):获取配置项saveConfig(key, value):保存配置项input:当前上传的文件列表,类型为string[]output:上传结果列表,类型为IImgInfo[]log:日志记录器request(options):发送HTTP请求,基于axios封装,可以使用axios替代
脚本示例
一个通过上传脚本将图片上传到SM.MS图床的示例:
javascript
const postOptions = (fileName, image, apiToken, domain = '') => {
return {
method: 'POST',
url: `https://${domain}/api/v2/upload`,
headers: {
contentType: 'multipart/form-data',
'User-Agent': 'PicList',
Authorization: apiToken,
},
formData: {
smfile: {
value: image,
options: { filename: fileName },
},
ssl: 'true',
},
}
}
async function main(ctx){
const domain = 'smms.app'
const imgList = ctx.output
for (const img of imgList) {
if (!img.fileName) continue
const imageBuffer = img.buffer || (img.base64Image ? Buffer.from(img.base64Image, 'base64') : undefined)
if (!imageBuffer) continue
const postConfig = postOptions(img.fileName, imageBuffer, 'xxxxxxx', domain)
const res = await ctx.request(postConfig)
const body = JSON.parse(res)
if (body.code === 'success') {
img.imgUrl = body.data.url
img.hash = body.data.hash
}
delete img.base64Image
delete img.buffer
}
return ctx
}