Skip to content

Commit 4ed3b60

Browse files
committed
fix(#11): compatibility with other plugins
1 parent 9f6c350 commit 4ed3b60

File tree

2 files changed

+71
-45
lines changed

2 files changed

+71
-45
lines changed

src/handle.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type { IPicGo } from 'picgo'
22
import type { SFTPLoaderUserConfig } from './config'
3+
import Client from './client'
34
import { getPcigoConfig } from './config'
45
import { PLUGINS_ID } from './constants'
5-
import { upload } from './upload'
6+
import { useUploader } from './upload'
67

78
export async function handle(ctx: IPicGo): Promise<any> {
89
const userConfig: SFTPLoaderUserConfig = ctx.getConfig(
@@ -20,12 +21,21 @@ export async function handle(ctx: IPicGo): Promise<any> {
2021
const input = ctx.input
2122
const output = ctx.output
2223

24+
// 初始化 SFTP 客户端
25+
const client = Client.instance
26+
await client.init(config)
27+
const { upload, uploadBuffer } = useUploader(ctx, client, config)
28+
2329
// 循环所有图片信息 上传
24-
for (const i in input) {
30+
for (let i = 0; i < input.length; i++) {
2531
const localPath = input[i]
32+
const buffer = output[i].buffer
33+
34+
const uploadPromise = buffer
35+
? uploadBuffer(buffer, i, output)
36+
: upload(localPath, i, output)
2637

27-
// 上传
28-
await upload(ctx, output[i], localPath)
38+
await uploadPromise
2939
.then((path) => {
3040
const imgUrl = `${
3141
/\/$/.test(config.url)
@@ -47,5 +57,8 @@ export async function handle(ctx: IPicGo): Promise<any> {
4757
})
4858
}
4959

60+
// 关闭连接
61+
client.close()
62+
5063
return ctx
5164
}

src/upload.ts

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,64 @@
1+
import type { Buffer } from 'node:buffer'
12
import type { IImgInfo, IPicGo } from 'picgo'
2-
import type { SFTPLoaderUserConfig } from './config'
3-
import Client from './client'
4-
import { getPcigoConfig } from './config'
5-
3+
import type Client from './client'
4+
import type { SFTPLoaderPathInfo, SFTPLoaderUserConfigItem } from './config'
5+
import fs from 'node:fs'
66
import { formatPath } from './util'
77

8-
export async function upload(
8+
export function useUploader(
99
ctx: IPicGo,
10-
output: IImgInfo,
11-
localPath: string
12-
): Promise<string> {
13-
const userConfig: SFTPLoaderUserConfig = ctx.getConfig('picBed.sftp-uploader')
14-
15-
if (!userConfig) {
16-
throw new Error('Can\'t find uploader config')
17-
}
18-
19-
const configItem = await getPcigoConfig(userConfig)
20-
const config = configItem[userConfig.site]
21-
22-
// 格式化路径
23-
const pathInfo = formatPath(output, config)
24-
25-
return new Promise((resolve, reject) => {
26-
const executeAsync = async () => {
10+
client: typeof Client.instance,
11+
config: SFTPLoaderUserConfigItem
12+
) {
13+
// 公共上传逻辑
14+
const doUpload = async (
15+
fileOrBuffer: string | Buffer,
16+
pathInfo: SFTPLoaderPathInfo
17+
) => {
18+
let uploadPath = fileOrBuffer
19+
let tmpFile: string | undefined
20+
if (typeof fileOrBuffer !== 'string') {
21+
tmpFile = await bufferToTempFile(fileOrBuffer)
22+
uploadPath = tmpFile
23+
}
24+
await client.upload(uploadPath as string, pathInfo.uploadPath)
25+
if (tmpFile) {
2726
try {
28-
// 连接
29-
await Client.instance.init(config)
30-
31-
// 上传
32-
await Client.instance.upload(localPath, pathInfo.uploadPath)
33-
34-
// 修改用户、用户组
35-
if (config.fileUser) {
36-
await Client.instance.chown(pathInfo.uploadPath, config.fileUser)
37-
}
38-
39-
// 关闭
40-
Client.instance.close()
41-
42-
resolve(pathInfo.path)
27+
fs.unlinkSync(tmpFile)
4328
}
44-
catch (err) {
45-
reject(err)
29+
catch (e) {
30+
ctx.log?.warn?.('临时文件删除失败: %o', e)
4631
}
4732
}
33+
if (config.fileUser) {
34+
await client.chown(pathInfo.uploadPath, config.fileUser)
35+
}
36+
return pathInfo.path
37+
}
38+
39+
// 处理本地路径上传
40+
const upload = async (localPath: string, idx: number, output: IImgInfo[]) => {
41+
const pathInfo = formatPath(output[idx], config)
42+
return doUpload(localPath, pathInfo)
43+
}
4844

49-
executeAsync()
50-
})
45+
// 处理 Buffer 上传
46+
const uploadBuffer = async (buffer: Buffer, idx: number, output: IImgInfo[]) => {
47+
const pathInfo = formatPath(output[idx], config)
48+
return doUpload(buffer, pathInfo)
49+
}
50+
51+
// Buffer 转临时文件
52+
async function bufferToTempFile(buffer: Buffer): Promise<string> {
53+
// 只在必须时用临时文件
54+
const tmpDir = fs.mkdtempSync('picgo-sftp-')
55+
const tmpFile = `${tmpDir}/${Date.now()}`
56+
fs.writeFileSync(tmpFile, buffer)
57+
return tmpFile
58+
}
59+
60+
return {
61+
upload,
62+
uploadBuffer
63+
}
5164
}

0 commit comments

Comments
 (0)