Skip to content

脚本系统

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的操作系统模块
  • 定时器函数:setTimeoutsetIntervalclearTimeoutclearInterval
  • 编码函数:base64Decodebase64Encode

额外的,对于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
}

Released under the MIT License.